-
Notifications
You must be signed in to change notification settings - Fork 22
/
adapters.go
148 lines (132 loc) · 4.84 KB
/
adapters.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package monomer
import (
"errors"
"fmt"
"time"
bfttypes "github.com/cometbft/cometbft/types"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum/go-ethereum/common/hexutil"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/polymerdao/monomer/utils"
rolluptypes "github.com/polymerdao/monomer/x/rollup/types"
)
// AdaptPayloadTxsToCosmosTxs assumes the deposit transactions come first.
func AdaptPayloadTxsToCosmosTxs(ethTxs []hexutil.Bytes) (bfttypes.Txs, error) {
// L1 Attributes transaction.
if len(ethTxs) == 0 {
return nil, errors.New("l1 attributes transaction not found")
}
l1AttributesTxBytes := ethTxs[0]
ethTxs = ethTxs[1:]
var ethL1AttributesTx ethtypes.Transaction
if err := ethL1AttributesTx.UnmarshalBinary(l1AttributesTxBytes); err != nil {
return nil, fmt.Errorf("unmarshal binary: %v", err)
}
if ethL1AttributesTx.Type() != ethtypes.DepositTxType {
return nil, errors.New("first transaction is not a deposit transaction")
}
l1BlockInfo, err := derive.L1BlockInfoFromBytes(&rollup.Config{
EcotoneTime: utils.Ptr(uint64(0)), // TODO: this is a hack, but it works for now.
}, uint64(time.Now().Unix()), ethL1AttributesTx.Data())
if err != nil {
return nil, fmt.Errorf("l1 block info from bytes: %v", err)
}
l1Attributes := &rolluptypes.MsgSetL1Attributes{
L1BlockInfo: &rolluptypes.L1BlockInfo{
Number: l1BlockInfo.Number,
Time: l1BlockInfo.Time,
BlockHash: l1BlockInfo.BlockHash[:],
SequenceNumber: l1BlockInfo.SequenceNumber,
BatcherAddr: l1BlockInfo.BatcherAddr[:],
L1FeeOverhead: l1BlockInfo.L1FeeOverhead[:],
L1FeeScalar: l1BlockInfo.L1FeeScalar[:],
BaseFeeScalar: l1BlockInfo.BaseFeeScalar,
BlobBaseFeeScalar: l1BlockInfo.BlobBaseFeeScalar,
},
EthTx: l1AttributesTxBytes,
}
if l1BlockInfo.BaseFee != nil {
l1Attributes.L1BlockInfo.BaseFee = l1BlockInfo.BaseFee.Bytes()
}
if l1BlockInfo.BlobBaseFee != nil {
l1Attributes.L1BlockInfo.BlobBaseFee = l1BlockInfo.BlobBaseFee.Bytes()
}
// User deposit transactions.
depositTxs := make([]*rolluptypes.MsgApplyUserDeposit, 0)
for _, ethDepositTxBytes := range ethTxs {
var ethDepositTx ethtypes.Transaction
if err := ethDepositTx.UnmarshalBinary(ethDepositTxBytes); err != nil {
return nil, fmt.Errorf("unmarshal binary eth deposit tx bytes: %v", err)
}
if !ethDepositTx.IsDepositTx() {
break // We have reached the end of the deposit txs.
}
depositTxs = append(depositTxs, &rolluptypes.MsgApplyUserDeposit{
Tx: ethDepositTxBytes,
})
}
ethTxs = ethTxs[len(depositTxs):]
cosmosTxs := make(bfttypes.Txs, 0, 1+len(ethTxs))
depositTxBytes, err := (&rolluptypes.DepositsTx{
L1Attributes: l1Attributes,
UserDeposits: depositTxs,
}).Marshal()
if err != nil {
return nil, fmt.Errorf("marshal tx: %v", err)
}
cosmosTxs = append(cosmosTxs, depositTxBytes)
// Non-deposit transactions.
for _, cosmosTx := range ethTxs {
var tx ethtypes.Transaction
if err := tx.UnmarshalBinary(cosmosTx); err != nil {
return nil, fmt.Errorf("unmarshal binary tx: %v", err)
}
if tx.IsDepositTx() {
return nil, errors.New("found a deposit tx after a non-deposit tx")
}
cosmosTxs = append(cosmosTxs, tx.Data())
}
return cosmosTxs, nil
}
func AdaptCosmosTxsToEthTxs(cosmosTxs bfttypes.Txs) (ethtypes.Transactions, error) {
if cosmosTxs.Len() == 0 {
return ethtypes.Transactions{}, nil
}
txsBytes := cosmosTxs.ToSliceOfBytes()
cosmosDepositTxBytes := txsBytes[0]
txsBytes = txsBytes[1:]
cosmosDepositTx := new(rolluptypes.DepositsTx)
if err := cosmosDepositTx.Unmarshal(cosmosDepositTxBytes); err != nil {
return nil, fmt.Errorf("unmarshal MsgL1Txs msg: %v", err)
}
// L1 Attributes.
var ethL1AttributesTx ethtypes.Transaction
if err := ethL1AttributesTx.UnmarshalBinary(cosmosDepositTx.L1Attributes.EthTx); err != nil {
return nil, fmt.Errorf("unmarshal binary l1 attributes tx: %v", err)
}
ethTxs := ethtypes.Transactions{ðL1AttributesTx}
// User Deposits.
cosmosUserDepositTxs := cosmosDepositTx.GetUserDeposits()
for _, cosmosUserDepositTx := range cosmosUserDepositTxs {
var ethUserDepositTx ethtypes.Transaction
if err := ethUserDepositTx.UnmarshalBinary(cosmosUserDepositTx.Tx); err != nil {
return nil, fmt.Errorf("unmarshal binary user deposit tx: %v", err)
}
if !ethUserDepositTx.IsDepositTx() {
return nil, errors.New("cosmos deposit tx contains non-deposit tx")
}
ethTxs = append(ethTxs, ðUserDepositTx)
}
// Non-deposit transactions.
for _, txBytes := range txsBytes {
ethTxs = append(ethTxs, AdaptNonDepositCosmosTxToEthTx(txBytes))
}
return ethTxs, nil
}
func AdaptNonDepositCosmosTxToEthTx(cosmosTx bfttypes.Tx) *ethtypes.Transaction {
return ethtypes.NewTx(ðtypes.DynamicFeeTx{
// TODO maybe fill in other fields?
Data: cosmosTx,
})
}