hermez-node/eth/rollup.go
eth/rollup.goRaw
1package eth
2
3import (
4 "context"
5 "math/big"
6 "strings"
7
8 "github.com/ethereum/go-ethereum"
9 "github.com/ethereum/go-ethereum/accounts/abi"
10 ethCommon "github.com/ethereum/go-ethereum/common"
11 "github.com/ethereum/go-ethereum/core/types"
12 "github.com/ethereum/go-ethereum/crypto"
13 "github.com/ethereum/go-ethereum/ethclient"
14 "github.com/hermeznetwork/hermez-node/common"
15 Hermez "github.com/hermeznetwork/hermez-node/eth/contracts/hermez"
16 "github.com/hermeznetwork/hermez-node/log"
17 "github.com/iden3/go-iden3-crypto/babyjub"
18)
19
20const (
21 // RollupConstFeeIdxCoordinatorLen is the number of tokens the coordinator can use
22 // to collect fees (determines the number of tokens that the
23 // coordinator can collect fees from). This value is determined by the
24 // circuit.
25 RollupConstFeeIdxCoordinatorLen = 64
26 // RollupConstReservedIDx First 256 indexes reserved, first user index will be the 256
27 RollupConstReservedIDx = 255
28 // RollupConstExitIDx IDX 1 is reserved for exits
29 RollupConstExitIDx = 1
30 // RollupConstLimitLoadAmount Max load amount allowed (loadAmount: L1 --> L2)
31 RollupConstLimitLoadAmount = (1 << 128)
32 // RollupConstLimitL2TransferAmount Max amount allowed (amount L2 --> L2)
33 RollupConstLimitL2TransferAmount = (1 << 192)
34 // RollupConstLimitTokens Max number of tokens allowed to be registered inside the rollup
35 RollupConstLimitTokens = (1 << 32)
36 // RollupConstL1CoordinatorTotalBytes [4 bytes] token + [32 bytes] babyjub + [65 bytes] compressedSignature
37 RollupConstL1CoordinatorTotalBytes = 101
38 // RollupConstL1UserTotalBytes [20 bytes] fromEthAddr + [32 bytes] fromBjj-compressed + [6 bytes] fromIdx +
39 // [2 bytes] loadAmountFloat16 + [2 bytes] amountFloat16 + [4 bytes] tokenId + [6 bytes] toIdx
40 RollupConstL1UserTotalBytes = 72
41 // RollupConstMaxL1UserTx Maximum L1-user transactions allowed to be queued in a batch
42 RollupConstMaxL1UserTx = 128
43 // RollupConstMaxL1Tx Maximum L1 transactions allowed to be queued in a batch
44 RollupConstMaxL1Tx = 256
45 // RollupConstInputSHAConstantBytes [6 bytes] lastIdx + [6 bytes] newLastIdx + [32 bytes] stateRoot + [32 bytes] newStRoot + [32 bytes] newExitRoot +
46 // [_MAX_L1_TX * _L1_USER_TOTALBYTES bytes] l1TxsData + totalL2TxsDataLength + feeIdxCoordinatorLength + [2 bytes] chainID =
47 // 18542 bytes + totalL2TxsDataLength + feeIdxCoordinatorLength
48 RollupConstInputSHAConstantBytes = 18542
49 // RollupConstNumBuckets Number of buckets
50 RollupConstNumBuckets = 5
51 // RollupConstMaxWithdrawalDelay max withdrawal delay in seconds
52 RollupConstMaxWithdrawalDelay = 2 * 7 * 24 * 60 * 60
53 // RollupConstExchangeMultiplier exchange multiplier
54 RollupConstExchangeMultiplier = 1e14
55 // LenVerifiers number of Rollup Smart Contract Verifiers
56 LenVerifiers = 1
57)
58
59var (
60 // RollupConstEthAddressInternalOnly This ethereum address is used internally for rollup accounts that don't have ethereum address, only Babyjubjub
61 // This non-ethereum accounts can be created by the coordinator and allow users to have a rollup
62 // account without needing an ethereum address
63 RollupConstEthAddressInternalOnly = ethCommon.HexToAddress("0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF")
64 // RollupConstRfield Modulus zkSNARK
65 RollupConstRfield, _ = new(big.Int).SetString(
66 "21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
67
68 // RollupConstERC1820 ERC1820Registry address
69 RollupConstERC1820 = ethCommon.HexToAddress("0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24")
70
71 // ERC777 tokens signatures
72
73 // RollupConstRecipientInterfaceHash ERC777 recipient interface hash
74 RollupConstRecipientInterfaceHash = crypto.Keccak256([]byte("ERC777TokensRecipient"))
75 // RollupConstPerformL1UserTxSignature the signature of the function that can be called thru an ERC777 `send`
76 RollupConstPerformL1UserTxSignature = crypto.Keccak256([]byte("addL1Transaction(uint256,uint48,uint16,uint16,uint32,uint48)"))
77 // RollupConstAddTokenSignature the signature of the function that can be called thru an ERC777 `send`
78 RollupConstAddTokenSignature = crypto.Keccak256([]byte("addToken(address)"))
79 // RollupConstSendSignature ERC777 Signature
80 RollupConstSendSignature = crypto.Keccak256([]byte("send(address,uint256,bytes)"))
81 // RollupConstERC777Granularity ERC777 Signature
82 RollupConstERC777Granularity = crypto.Keccak256([]byte("granularity()"))
83 // RollupConstWithdrawalDelayerDeposit This constant are used to deposit tokens from ERC77 tokens into withdrawal delayer
84 RollupConstWithdrawalDelayerDeposit = crypto.Keccak256([]byte("deposit(address,address,uint192)"))
85
86 // ERC20 signature
87
88 // RollupConstTransferSignature This constant is used in the _safeTransfer internal method in order to safe GAS.
89 RollupConstTransferSignature = crypto.Keccak256([]byte("transfer(address,uint256)"))
90 // RollupConstTransferFromSignature This constant is used in the _safeTransfer internal method in order to safe GAS.
91 RollupConstTransferFromSignature = crypto.Keccak256([]byte("transferFrom(address,address,uint256)"))
92 // RollupConstApproveSignature This constant is used in the _safeTransfer internal method in order to safe GAS.
93 RollupConstApproveSignature = crypto.Keccak256([]byte("approve(address,uint256)"))
94 // RollupConstERC20Signature ERC20 decimals signature
95 RollupConstERC20Signature = crypto.Keccak256([]byte("decimals()"))
96)
97
98// RollupConstants are the constants of the Rollup Smart Contract
99/* type RollupConstants struct {
100 // Maxim Deposit allowed
101 MaxAmountDeposit *big.Int
102 MaxAmountL2 *big.Int
103 MaxTokens int64
104 // maximum L1 transactions allowed to be queued for a batch
105 MaxL1Tx int
106 // maximum L1 user transactions allowed to be queued for a batch
107 MaxL1UserTx int
108 Rfield *big.Int
109 L1CoordinatorBytes int
110 L1UserBytes int
111 L2Bytes int
112 MaxTxVerifiers []int
113 TokenHEZ ethCommon.Address
114 // Only test
115 GovernanceAddress ethCommon.Address
116 // Only test
117 SafetyBot ethCommon.Address
118 // Only test
119 ConsensusContract ethCommon.Address
120 // Only test
121 WithdrawalContract ethCommon.Address
122 ReservedIDx uint32
123 LastIDx uint32
124 ExitIDx uint32
125 NoLimitToken int
126 NumBuckets int
127 MaxWDelay int64
128}*/
129
130// RollupPublicConstants are the constants of the Rollup Smart Contract
131type RollupPublicConstants struct {
132 AbsoluteMaxL1L2BatchTimeout int64
133 TokenHEZ ethCommon.Address
134 Verifiers []RollupVerifierStruct
135 HermezAuctionContract ethCommon.Address
136 HermezGovernanceDAOAddress ethCommon.Address
137 SafetyAddress ethCommon.Address
138 WithdrawDelayerContract ethCommon.Address
139}
140
141// RollupVariables are the variables of the Rollup Smart Contract
142type RollupVariables struct {
143 FeeAddToken *big.Int
144 ForgeL1L2BatchTimeout int64
145 WithdrawalDelay uint64
146}
147
148// QueueStruct is the queue of L1Txs for a batch
149//nolint:structcheck
150type QueueStruct struct {
151 L1TxQueue []common.L1Tx
152 TotalL1TxFee *big.Int
153}
154
155// NewQueueStruct creates a new clear QueueStruct.
156func NewQueueStruct() *QueueStruct {
157 return &QueueStruct{
158 L1TxQueue: make([]common.L1Tx, 0),
159 TotalL1TxFee: big.NewInt(0),
160 }
161}
162
163// RollupVerifierStruct is the information about verifiers of the Rollup Smart Contract
164type RollupVerifierStruct struct {
165 MaxTx int64
166 NLevels int64
167}
168
169// RollupState represents the state of the Rollup in the Smart Contract
170//nolint:structcheck,unused
171type RollupState struct {
172 StateRoot *big.Int
173 ExitRoots []*big.Int
174 ExitNullifierMap map[[256 / 8]byte]bool
175 TokenList []ethCommon.Address
176 TokenMap map[ethCommon.Address]bool
177 MapL1TxQueue map[int64]*QueueStruct
178 LastL1L2Batch int64
179 CurrentToForgeL1TxsNum int64
180 LastToForgeL1TxsNum int64
181 CurrentIdx int64
182}
183
184// RollupEventL1UserTx is an event of the Rollup Smart Contract
185type RollupEventL1UserTx struct {
186 ToForgeL1TxsNum int64 // QueueIndex *big.Int
187 Position int // TransactionIndex *big.Int
188 L1Tx common.L1Tx
189}
190
191// RollupEventL1UserTxAux is an event of the Rollup Smart Contract
192type RollupEventL1UserTxAux struct {
193 ToForgeL1TxsNum uint64 // QueueIndex *big.Int
194 Position uint8 // TransactionIndex *big.Int
195 L1Tx []byte
196}
197
198// RollupEventAddToken is an event of the Rollup Smart Contract
199type RollupEventAddToken struct {
200 Address ethCommon.Address
201 TokenID uint32
202}
203
204// RollupEventForgeBatch is an event of the Rollup Smart Contract
205type RollupEventForgeBatch struct {
206 BatchNum int64
207 EthTxHash ethCommon.Hash
208}
209
210// RollupEventUpdateForgeL1L2BatchTimeout is an event of the Rollup Smart Contract
211type RollupEventUpdateForgeL1L2BatchTimeout struct {
212 ForgeL1L2BatchTimeout uint8
213}
214
215// RollupEventUpdateFeeAddToken is an event of the Rollup Smart Contract
216type RollupEventUpdateFeeAddToken struct {
217 FeeAddToken *big.Int
218}
219
220// RollupEventWithdrawEvent is an event of the Rollup Smart Contract
221type RollupEventWithdrawEvent struct {
222 Idx uint64
223 NumExitRoot uint64
224 InstantWithdraw bool
225}
226
227// RollupEvents is the list of events in a block of the Rollup Smart Contract
228type RollupEvents struct { //nolint:structcheck
229 L1UserTx []RollupEventL1UserTx
230 AddToken []RollupEventAddToken
231 ForgeBatch []RollupEventForgeBatch
232 UpdateForgeL1L2BatchTimeout []RollupEventUpdateForgeL1L2BatchTimeout
233 UpdateFeeAddToken []RollupEventUpdateFeeAddToken
234 WithdrawEvent []RollupEventWithdrawEvent
235}
236
237// NewRollupEvents creates an empty RollupEvents with the slices initialized.
238func NewRollupEvents() RollupEvents {
239 return RollupEvents{
240 L1UserTx: make([]RollupEventL1UserTx, 0),
241 AddToken: make([]RollupEventAddToken, 0),
242 ForgeBatch: make([]RollupEventForgeBatch, 0),
243 UpdateForgeL1L2BatchTimeout: make([]RollupEventUpdateForgeL1L2BatchTimeout, 0),
244 UpdateFeeAddToken: make([]RollupEventUpdateFeeAddToken, 0),
245 WithdrawEvent: make([]RollupEventWithdrawEvent, 0),
246 }
247}
248
249// RollupForgeBatchArgs are the arguments to the ForgeBatch function in the Rollup Smart Contract
250//nolint:structcheck,unused
251type RollupForgeBatchArgs struct {
252 NewLastIdx int64
253 NewStRoot *big.Int
254 NewExitRoot *big.Int
255 L1CoordinatorTxs []*common.L1Tx
256 L2TxsData []*common.L2Tx
257 FeeIdxCoordinator []common.Idx
258 // Circuit selector
259 VerifierIdx uint8
260 L1Batch bool
261 ProofA [2]*big.Int
262 ProofB [2][2]*big.Int
263 ProofC [2]*big.Int
264}
265
266// RollupForgeBatchArgsAux are the arguments to the ForgeBatch function in the Rollup Smart Contract
267//nolint:structcheck,unused
268type RollupForgeBatchArgsAux struct {
269 NewLastIdx uint64
270 NewStRoot *big.Int
271 NewExitRoot *big.Int
272 L1CoordinatorTxs []byte
273 L2TxsData []byte
274 FeeIdxCoordinator []byte
275 // Circuit selector
276 VerifierIdx uint8
277 L1Batch bool
278 ProofA [2]*big.Int
279 ProofB [2][2]*big.Int
280 ProofC [2]*big.Int
281}
282
283// RollupInterface is the inteface to to Rollup Smart Contract
284type RollupInterface interface {
285 //
286 // Smart Contract Methods
287 //
288
289 // Public Functions
290
291 RollupForgeBatch(*RollupForgeBatchArgs) (*types.Transaction, error)
292 RollupAddToken(tokenAddress ethCommon.Address) (*types.Transaction, error)
293 RollupWithdraw(tokenID int64, balance *big.Int, babyPubKey *babyjub.PublicKey,
294 numExitRoot int64, siblings []*big.Int, idx int64, instantWithdraw bool) (*types.Transaction, error)
295 RollupForceExit(fromIdx int64, amountF common.Float16, tokenID int64) (*types.Transaction, error)
296 RollupForceTransfer(fromIdx int64, amountF common.Float16, tokenID, toIdx int64) (*types.Transaction, error)
297 RollupCreateAccountDepositTransfer(babyPubKey babyjub.PublicKey,
298 loadAmountF, amountF common.Float16, tokenID int64, toIdx int64) (*types.Transaction, error)
299 RollupDepositTransfer(fromIdx int64, loadAmountF, amountF common.Float16,
300 tokenID int64, toIdx int64) (*types.Transaction, error)
301 RollupDeposit(fromIdx int64, loadAmountF common.Float16, tokenID int64) (*types.Transaction, error)
302 RollupCreateAccountDepositFromRelayer(accountCreationAuthSig []byte,
303 babyPubKey babyjub.PublicKey, loadAmountF common.Float16) (*types.Transaction, error)
304 RollupCreateAccountDeposit(babyPubKey babyjub.PublicKey, loadAmountF common.Float16,
305 tokenID int64) (*types.Transaction, error)
306
307 RollupGetCurrentTokens() (*big.Int, error)
308 // RollupGetTokenAddress(tokenID int64) (*ethCommon.Address, error)
309 // RollupGetL1TxFromQueue(queue int64, position int64) ([]byte, error)
310 // RollupGetQueue(queue int64) ([]byte, error)
311
312 // Governance Public Functions
313 RollupUpdateForgeL1L2BatchTimeout(newForgeL1Timeout int64) (*types.Transaction, error)
314 RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (*types.Transaction, error)
315
316 //
317 // Smart Contract Status
318 //
319
320 RollupConstants() (*RollupPublicConstants, error)
321 RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethCommon.Hash, error)
322 RollupForgeBatchArgs(ethCommon.Hash) (*RollupForgeBatchArgs, error)
323}
324
325//
326// Implementation
327//
328
329// RollupClient is the implementation of the interface to the Rollup Smart Contract in ethereum.
330type RollupClient struct {
331 client *EthereumClient
332 address ethCommon.Address
333 contractAbi abi.ABI
334}
335
336// NewRollupClient creates a new RollupClient
337func NewRollupClient(client *EthereumClient, address ethCommon.Address) (*RollupClient, error) {
338 contractAbi, err := abi.JSON(strings.NewReader(string(Hermez.HermezABI)))
339 if err != nil {
340 return nil, err
341 }
342 return &RollupClient{
343 client: client,
344 address: address,
345 contractAbi: contractAbi,
346 }, nil
347}
348
349// RollupForgeBatch is the interface to call the smart contract function
350func (c *RollupClient) RollupForgeBatch(args *RollupForgeBatchArgs) (*types.Transaction, error) {
351 log.Error("TODO")
352 return nil, errTODO
353}
354
355// RollupAddToken is the interface to call the smart contract function
356func (c *RollupClient) RollupAddToken(tokenAddress ethCommon.Address) (*types.Transaction, error) {
357 log.Error("TODO")
358 return nil, errTODO
359}
360
361// RollupWithdrawSNARK is the interface to call the smart contract function
362// func (c *RollupClient) RollupWithdrawSNARK() (*types.Transaction, error) { // TODO (Not defined in Hermez.sol)
363// return nil, errTODO
364// }
365
366// RollupWithdraw is the interface to call the smart contract function
367func (c *RollupClient) RollupWithdraw(tokenID int64, balance *big.Int, babyPubKey *babyjub.PublicKey, numExitRoot int64, siblings []*big.Int, idx int64, instantWithdraw bool) (*types.Transaction, error) {
368 log.Error("TODO")
369 return nil, errTODO
370}
371
372// RollupForceExit is the interface to call the smart contract function
373func (c *RollupClient) RollupForceExit(fromIdx int64, amountF common.Float16, tokenID int64) (*types.Transaction, error) {
374 log.Error("TODO")
375 return nil, errTODO
376}
377
378// RollupForceTransfer is the interface to call the smart contract function
379func (c *RollupClient) RollupForceTransfer(fromIdx int64, amountF common.Float16, tokenID, toIdx int64) (*types.Transaction, error) {
380 log.Error("TODO")
381 return nil, errTODO
382}
383
384// RollupCreateAccountDepositTransfer is the interface to call the smart contract function
385func (c *RollupClient) RollupCreateAccountDepositTransfer(babyPubKey babyjub.PublicKey, loadAmountF, amountF common.Float16, tokenID int64, toIdx int64) (*types.Transaction, error) {
386 log.Error("TODO")
387 return nil, errTODO
388}
389
390// RollupDepositTransfer is the interface to call the smart contract function
391func (c *RollupClient) RollupDepositTransfer(fromIdx int64, loadAmountF, amountF common.Float16, tokenID int64, toIdx int64) (*types.Transaction, error) {
392 log.Error("TODO")
393 return nil, errTODO
394}
395
396// RollupDeposit is the interface to call the smart contract function
397func (c *RollupClient) RollupDeposit(fromIdx int64, loadAmountF common.Float16, tokenID int64) (*types.Transaction, error) {
398 log.Error("TODO")
399 return nil, errTODO
400}
401
402// RollupCreateAccountDepositFromRelayer is the interface to call the smart contract function
403func (c *RollupClient) RollupCreateAccountDepositFromRelayer(accountCreationAuthSig []byte, babyPubKey babyjub.PublicKey, loadAmountF common.Float16) (*types.Transaction, error) {
404 log.Error("TODO")
405 return nil, errTODO
406}
407
408// RollupCreateAccountDeposit is the interface to call the smart contract function
409func (c *RollupClient) RollupCreateAccountDeposit(babyPubKey babyjub.PublicKey, loadAmountF common.Float16, tokenID int64) (*types.Transaction, error) {
410 log.Error("TODO")
411 return nil, errTODO
412}
413
414// RollupGetTokenAddress is the interface to call the smart contract function
415/* func (c *RollupClient) RollupGetTokenAddress(tokenID int64) (*ethCommon.Address, error) {
416 return nil, errTODO
417} */
418
419// RollupGetCurrentTokens is the interface to call the smart contract function
420func (c *RollupClient) RollupGetCurrentTokens() (*big.Int, error) {
421 log.Error("TODO")
422 return nil, errTODO
423}
424
425// RollupGetL1TxFromQueue is the interface to call the smart contract function
426/* func (c *RollupClient) RollupGetL1TxFromQueue(queue int64, position int64) ([]byte, error) {
427 return nil, errTODO
428} */
429
430// RollupGetQueue is the interface to call the smart contract function
431/* func (c *RollupClient) RollupGetQueue(queue int64) ([]byte, error) {
432 return nil, errTODO
433}*/
434
435// RollupUpdateForgeL1L2BatchTimeout is the interface to call the smart contract function
436func (c *RollupClient) RollupUpdateForgeL1L2BatchTimeout(newForgeL1Timeout int64) (*types.Transaction, error) {
437 log.Error("TODO")
438 return nil, errTODO
439}
440
441// RollupUpdateFeeAddToken is the interface to call the smart contract function
442func (c *RollupClient) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (*types.Transaction, error) {
443 log.Error("TODO")
444 return nil, errTODO
445}
446
447// RollupConstants returns the Constants of the Rollup Smart Contract
448func (c *RollupClient) RollupConstants() (*RollupPublicConstants, error) {
449 rollupConstants := new(RollupPublicConstants)
450 if err := c.client.Call(func(ec *ethclient.Client) error {
451 hermez, err := Hermez.NewHermez(c.address, ec)
452 if err != nil {
453 return err
454 }
455 absoluteMaxL1L2BatchTimeout, err := hermez.ABSOLUTEMAXL1L2BATCHTIMEOUT(nil)
456 if err != nil {
457 return err
458 }
459 rollupConstants.AbsoluteMaxL1L2BatchTimeout = int64(absoluteMaxL1L2BatchTimeout)
460 rollupConstants.TokenHEZ, err = hermez.TokenHEZ(nil)
461 if err != nil {
462 return err
463 }
464 for i := int64(0); i < int64(LenVerifiers); i++ {
465 var newRollupVerifier RollupVerifierStruct
466 rollupVerifier, err := hermez.RollupVerifiers(nil, big.NewInt(i))
467 if err != nil {
468 return err
469 }
470 newRollupVerifier.MaxTx = rollupVerifier.MaxTx.Int64()
471 newRollupVerifier.NLevels = rollupVerifier.NLevels.Int64()
472 rollupConstants.Verifiers = append(rollupConstants.Verifiers, newRollupVerifier)
473 }
474 rollupConstants.HermezAuctionContract, err = hermez.HermezAuctionContract(nil)
475 if err != nil {
476 return err
477 }
478 rollupConstants.HermezGovernanceDAOAddress, err = hermez.HermezGovernanceDAOAddress(nil)
479 if err != nil {
480 return err
481 }
482 rollupConstants.SafetyAddress, err = hermez.SafetyAddress(nil)
483 if err != nil {
484 return err
485 }
486 rollupConstants.WithdrawDelayerContract, err = hermez.WithdrawDelayerContract(nil)
487 return err
488 }); err != nil {
489 return nil, err
490 }
491 return rollupConstants, nil
492}
493
494var (
495 logHermezL1UserTxEvent = crypto.Keccak256Hash([]byte("L1UserTxEvent(uint64,uint8,bytes)"))
496 logHermezAddToken = crypto.Keccak256Hash([]byte("AddToken(address,uint32)"))
497 logHermezForgeBatch = crypto.Keccak256Hash([]byte("ForgeBatch(uint64)"))
498 logHermezUpdateForgeL1L2BatchTimeout = crypto.Keccak256Hash([]byte("UpdateForgeL1L2BatchTimeout(uint8)"))
499 logHermezUpdateFeeAddToken = crypto.Keccak256Hash([]byte("UpdateFeeAddToken(uint256)"))
500 logHermezWithdrawEvent = crypto.Keccak256Hash([]byte("WithdrawEvent(uint48,uint48,bool)"))
501)
502
503// RollupEventsByBlock returns the events in a block that happened in the Rollup Smart Contract
504func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethCommon.Hash, error) {
505 var rollupEvents RollupEvents
506 var blockHash ethCommon.Hash
507
508 query := ethereum.FilterQuery{
509 FromBlock: big.NewInt(blockNum),
510 ToBlock: big.NewInt(blockNum),
511 Addresses: []ethCommon.Address{
512 c.address,
513 },
514 BlockHash: nil,
515 Topics: [][]ethCommon.Hash{},
516 }
517 logs, err := c.client.client.FilterLogs(context.Background(), query)
518 if err != nil {
519 return nil, nil, err
520 }
521 if len(logs) > 0 {
522 blockHash = logs[0].BlockHash
523 }
524 for _, vLog := range logs {
525 if vLog.BlockHash != blockHash {
526 return nil, nil, ErrBlockHashMismatchEvent
527 }
528 switch vLog.Topics[0] {
529 case logHermezL1UserTxEvent:
530 var L1UserTxAux RollupEventL1UserTxAux
531 var L1UserTx RollupEventL1UserTx
532 err := c.contractAbi.Unpack(&L1UserTxAux, "L1UserTxEvent", vLog.Data)
533 if err != nil {
534 return nil, nil, err
535 }
536 L1Tx, err := common.L1TxFromBytes(L1UserTxAux.L1Tx)
537 if err != nil {
538 return nil, nil, err
539 }
540 L1UserTx.ToForgeL1TxsNum = new(big.Int).SetBytes(vLog.Topics[1][:]).Int64()
541 L1UserTx.Position = int(new(big.Int).SetBytes(vLog.Topics[2][:]).Int64())
542 L1UserTx.L1Tx = *L1Tx
543 rollupEvents.L1UserTx = append(rollupEvents.L1UserTx, L1UserTx)
544 case logHermezAddToken:
545 var addToken RollupEventAddToken
546 err := c.contractAbi.Unpack(&addToken, "AddToken", vLog.Data)
547 if err != nil {
548 return nil, nil, err
549 }
550 addToken.Address = ethCommon.BytesToAddress(vLog.Topics[1].Bytes())
551 rollupEvents.AddToken = append(rollupEvents.AddToken, addToken)
552 case logHermezForgeBatch:
553 var forgeBatch RollupEventForgeBatch
554 forgeBatch.BatchNum = new(big.Int).SetBytes(vLog.Topics[1][:]).Int64()
555 forgeBatch.EthTxHash = vLog.TxHash
556 rollupEvents.ForgeBatch = append(rollupEvents.ForgeBatch, forgeBatch)
557 case logHermezUpdateForgeL1L2BatchTimeout:
558 var updateForgeL1L2BatchTimeout RollupEventUpdateForgeL1L2BatchTimeout
559 err := c.contractAbi.Unpack(&updateForgeL1L2BatchTimeout, "UpdateForgeL1L2BatchTimeout", vLog.Data)
560 if err != nil {
561 return nil, nil, err
562 }
563 rollupEvents.UpdateForgeL1L2BatchTimeout = append(rollupEvents.UpdateForgeL1L2BatchTimeout, updateForgeL1L2BatchTimeout)
564 case logHermezUpdateFeeAddToken:
565 var updateFeeAddToken RollupEventUpdateFeeAddToken
566 err := c.contractAbi.Unpack(&updateFeeAddToken, "UpdateFeeAddToken", vLog.Data)
567 if err != nil {
568 return nil, nil, err
569 }
570 rollupEvents.UpdateFeeAddToken = append(rollupEvents.UpdateFeeAddToken, updateFeeAddToken)
571 case logHermezWithdrawEvent:
572 var withdraw RollupEventWithdrawEvent
573 err := c.contractAbi.Unpack(&withdraw, "WithdrawEvent", vLog.Data)
574 if err != nil {
575 return nil, nil, err
576 }
577 withdraw.Idx = new(big.Int).SetBytes(vLog.Topics[1][:]).Uint64()
578 withdraw.NumExitRoot = new(big.Int).SetBytes(vLog.Topics[2][:]).Uint64()
579 rollupEvents.WithdrawEvent = append(rollupEvents.WithdrawEvent, withdraw)
580 }
581 }
582 return &rollupEvents, &blockHash, nil
583}
584
585// RollupForgeBatchArgs returns the arguments used in a ForgeBatch call in the Rollup Smart Contract in the given transaction
586func (c *RollupClient) RollupForgeBatchArgs(ethTxHash ethCommon.Hash) (*RollupForgeBatchArgs, error) {
587 tx, _, err := c.client.client.TransactionByHash(context.Background(), ethTxHash)
588 if err != nil {
589 return nil, err
590 }
591 txData := tx.Data()
592 method, err := c.contractAbi.MethodById(txData)
593 if err != nil {
594 return nil, err
595 }
596 var aux RollupForgeBatchArgsAux
597 if err := method.Inputs.Unpack(&aux, txData); err != nil {
598 return nil, err
599 }
600 var rollupForgeBatchArgs RollupForgeBatchArgs
601 rollupForgeBatchArgs.L1Batch = aux.L1Batch
602 rollupForgeBatchArgs.NewExitRoot = aux.NewExitRoot
603 rollupForgeBatchArgs.NewLastIdx = int64(aux.NewLastIdx)
604 rollupForgeBatchArgs.NewStRoot = aux.NewStRoot
605 rollupForgeBatchArgs.ProofA = aux.ProofA
606 rollupForgeBatchArgs.ProofB = aux.ProofB
607 rollupForgeBatchArgs.ProofC = aux.ProofC
608 rollupForgeBatchArgs.VerifierIdx = aux.VerifierIdx
609
610 numTxsL1 := len(aux.L1CoordinatorTxs) / common.L1TxBytesLen
611 for i := 0; i < numTxsL1; i++ {
612 l1Tx, err := common.L1TxFromCoordinatorBytes(aux.L1CoordinatorTxs[i*common.L1CoordinatorTxBytesLen : (i+1)*common.L1CoordinatorTxBytesLen])
613 if err != nil {
614 return nil, err
615 }
616 rollupForgeBatchArgs.L1CoordinatorTxs = append(rollupForgeBatchArgs.L1CoordinatorTxs, l1Tx)
617 }
618 rollupConsts, err := c.RollupConstants()
619 if err != nil {
620 return nil, err
621 }
622 nLevels := rollupConsts.Verifiers[rollupForgeBatchArgs.VerifierIdx].NLevels
623 lenL2TxsBytes := int((nLevels/8)*2 + 2 + 1)
624 numTxsL2 := len(aux.L2TxsData) / lenL2TxsBytes
625 for i := 0; i < numTxsL2; i++ {
626 l2Tx, err := common.L2TxFromBytes(aux.L2TxsData[i*lenL2TxsBytes:(i+1)*lenL2TxsBytes], int(nLevels))
627 if err != nil {
628 return nil, err
629 }
630 rollupForgeBatchArgs.L2TxsData = append(rollupForgeBatchArgs.L2TxsData, l2Tx)
631 }
632 lenFeeIdxCoordinatorBytes := int(nLevels / 8) //nolint:gomnd
633 numFeeIdxCoordinator := len(aux.FeeIdxCoordinator) / lenFeeIdxCoordinatorBytes
634 for i := 0; i < numFeeIdxCoordinator; i++ {
635 var paddedFeeIdx [6]byte
636 // TODO: This check is not necessary: the first case will always work. Test it before removing the if.
637 if lenFeeIdxCoordinatorBytes < common.IdxBytesLen {
638 copy(paddedFeeIdx[6-lenFeeIdxCoordinatorBytes:], aux.FeeIdxCoordinator[i*lenFeeIdxCoordinatorBytes:(i+1)*lenFeeIdxCoordinatorBytes])
639 } else {
640 copy(paddedFeeIdx[:], aux.FeeIdxCoordinator[i*lenFeeIdxCoordinatorBytes:(i+1)*lenFeeIdxCoordinatorBytes])
641 }
642 FeeIdxCoordinator, err := common.IdxFromBytes(paddedFeeIdx[:])
643 if err != nil {
644 return nil, err
645 }
646 rollupForgeBatchArgs.FeeIdxCoordinator = append(rollupForgeBatchArgs.FeeIdxCoordinator, FeeIdxCoordinator)
647 }
648 return &rollupForgeBatchArgs, nil
649 // tx := client.TransactionByHash(ethTxHash) -> types.Transaction
650 // txData := types.Transaction -> Data()
651 // m := abi.MethodById(txData) -> Method
652 // m.Inputs.Unpack(txData) -> Args
653 // client.TransactionReceipt()?
654}