arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
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}