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