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