arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
hermez-node/test/ethclient.go
test/ethclient.goRaw
   1package test
   2
   3import (
   4	"context"
   5	"encoding/binary"
   6	"encoding/json"
   7	"fmt"
   8	"math/big"
   9	"reflect"
  10	"sync"
  11	"time"
  12
  13	"github.com/ethereum/go-ethereum"
  14	"github.com/ethereum/go-ethereum/accounts/abi/bind"
  15	ethKeystore "github.com/ethereum/go-ethereum/accounts/keystore"
  16	ethCommon "github.com/ethereum/go-ethereum/common"
  17	"github.com/ethereum/go-ethereum/core/types"
  18	"github.com/hermeznetwork/hermez-node/common"
  19	"github.com/hermeznetwork/hermez-node/eth"
  20	"github.com/hermeznetwork/hermez-node/log"
  21	"github.com/hermeznetwork/tracerr"
  22	"github.com/iden3/go-iden3-crypto/babyjub"
  23	"github.com/mitchellh/copystructure"
  24)
  25
  26func init() {
  27	copystructure.Copiers[reflect.TypeOf(big.Int{})] =
  28		func(raw interface{}) (interface{}, error) {
  29			in := raw.(big.Int)
  30			out := new(big.Int).Set(&in)
  31			return *out, nil
  32		}
  33}
  34
  35// WDelayerBlock stores all the data related to the WDelayer SC from an ethereum block
  36type WDelayerBlock struct {
  37	// State     eth.WDelayerState // TODO
  38	Vars      common.WDelayerVariables
  39	Events    eth.WDelayerEvents
  40	Txs       map[ethCommon.Hash]*types.Transaction
  41	Constants *common.WDelayerConstants
  42	Eth       *EthereumBlock
  43}
  44
  45func (w *WDelayerBlock) addTransaction(tx *types.Transaction) *types.Transaction {
  46	txHash := tx.Hash()
  47	w.Txs[txHash] = tx
  48	return tx
  49}
  50
  51func (w *WDelayerBlock) deposit(txHash ethCommon.Hash, owner, token ethCommon.Address, amount *big.Int) {
  52	w.Events.Deposit = append(w.Events.Deposit, eth.WDelayerEventDeposit{
  53		Owner:            owner,
  54		Token:            token,
  55		Amount:           amount,
  56		DepositTimestamp: uint64(w.Eth.Time),
  57		TxHash:           txHash,
  58	})
  59}
  60
  61// RollupBlock stores all the data related to the Rollup SC from an ethereum block
  62type RollupBlock struct {
  63	State     eth.RollupState
  64	Vars      common.RollupVariables
  65	Events    eth.RollupEvents
  66	Txs       map[ethCommon.Hash]*types.Transaction
  67	Constants *common.RollupConstants
  68	Eth       *EthereumBlock
  69}
  70
  71func (r *RollupBlock) addTransaction(tx *types.Transaction) *types.Transaction {
  72	txHash := tx.Hash()
  73	r.Txs[txHash] = tx
  74	return tx
  75}
  76
  77var (
  78	errBidClosed   = fmt.Errorf("Bid has already been closed")
  79	errBidNotOpen  = fmt.Errorf("Bid has not been opened yet")
  80	errBidBelowMin = fmt.Errorf("Bid below minimum")
  81	errCoordNotReg = fmt.Errorf("Coordinator not registered")
  82)
  83
  84// AuctionBlock stores all the data related to the Auction SC from an ethereum block
  85type AuctionBlock struct {
  86	State     eth.AuctionState
  87	Vars      common.AuctionVariables
  88	Events    eth.AuctionEvents
  89	Txs       map[ethCommon.Hash]*types.Transaction
  90	Constants *common.AuctionConstants
  91	Eth       *EthereumBlock
  92}
  93
  94func (a *AuctionBlock) addTransaction(tx *types.Transaction) *types.Transaction {
  95	txHash := tx.Hash()
  96	a.Txs[txHash] = tx
  97	return tx
  98}
  99
 100func (a *AuctionBlock) getSlotNumber(blockNumber int64) int64 {
 101	if a.Eth.BlockNum >= a.Constants.GenesisBlockNum {
 102		return (blockNumber - a.Constants.GenesisBlockNum) / int64(a.Constants.BlocksPerSlot)
 103	}
 104	return 0
 105}
 106
 107func (a *AuctionBlock) getCurrentSlotNumber() int64 {
 108	return a.getSlotNumber(a.Eth.BlockNum)
 109}
 110
 111func (a *AuctionBlock) getSlotSet(slot int64) int64 {
 112	return slot % int64(len(a.Vars.DefaultSlotSetBid))
 113}
 114
 115func (a *AuctionBlock) getMinBidBySlot(slot int64) (*big.Int, error) {
 116	if slot < a.getCurrentSlotNumber()+int64(a.Vars.ClosedAuctionSlots) {
 117		return nil, tracerr.Wrap(errBidClosed)
 118	}
 119
 120	slotSet := a.getSlotSet(slot)
 121	// fmt.Println("slot:", slot, "slotSet:", slotSet)
 122	var prevBid *big.Int
 123	slotState, ok := a.State.Slots[slot]
 124	if !ok {
 125		slotState = eth.NewSlotState()
 126		a.State.Slots[slot] = slotState
 127	}
 128	// If the bidAmount for a slot is 0 it means that it has not yet been
 129	// bid, so the midBid will be the minimum bid for the slot time plus
 130	// the outbidding set, otherwise it will be the bidAmount plus the
 131	// outbidding
 132	if slotState.BidAmount.Cmp(big.NewInt(0)) == 0 {
 133		prevBid = a.Vars.DefaultSlotSetBid[slotSet]
 134	} else {
 135		prevBid = slotState.BidAmount
 136	}
 137	outBid := new(big.Int).Set(prevBid)
 138	// fmt.Println("outBid:", outBid)
 139	outBid.Mul(outBid, big.NewInt(int64(a.Vars.Outbidding)))
 140	outBid.Div(outBid, big.NewInt(10000)) //nolint:gomnd
 141	outBid.Add(prevBid, outBid)
 142	// fmt.Println("minBid:", outBid)
 143	return outBid, nil
 144}
 145
 146func (a *AuctionBlock) forge(forger ethCommon.Address) error {
 147	if ok, err := a.canForge(forger, a.Eth.BlockNum); err != nil {
 148		return tracerr.Wrap(err)
 149	} else if !ok {
 150		return tracerr.Wrap(fmt.Errorf("Can't forge"))
 151	}
 152
 153	slotToForge := a.getSlotNumber(a.Eth.BlockNum)
 154	slotState, ok := a.State.Slots[slotToForge]
 155	if !ok {
 156		slotState = eth.NewSlotState()
 157		a.State.Slots[slotToForge] = slotState
 158	}
 159
 160	if !slotState.ForgerCommitment {
 161		// Get the relativeBlock to check if the slotDeadline has been exceeded
 162		relativeBlock := a.Eth.BlockNum - (a.Constants.GenesisBlockNum +
 163			(slotToForge * int64(a.Constants.BlocksPerSlot)))
 164		if relativeBlock < int64(a.Vars.SlotDeadline) {
 165			slotState.ForgerCommitment = true
 166		}
 167	}
 168
 169	slotState.Fulfilled = true
 170
 171	a.Events.NewForge = append(a.Events.NewForge, eth.AuctionEventNewForge{
 172		Forger:      forger,
 173		SlotToForge: slotToForge,
 174	})
 175	return nil
 176}
 177
 178func (a *AuctionBlock) canForge(forger ethCommon.Address, blockNum int64) (bool, error) {
 179	if blockNum < a.Constants.GenesisBlockNum {
 180		return false, tracerr.Wrap(fmt.Errorf("Auction has not started yet"))
 181	}
 182
 183	slotToForge := a.getSlotNumber(blockNum)
 184	// Get the relativeBlock to check if the slotDeadline has been exceeded
 185	relativeBlock := blockNum - (a.Constants.GenesisBlockNum + (slotToForge * int64(a.Constants.BlocksPerSlot)))
 186
 187	// If the closedMinBid is 0 it means that we have to take as minBid the
 188	// one that is set for this slot set, otherwise the one that has been
 189	// saved will be used
 190	var minBid *big.Int
 191	slotState, ok := a.State.Slots[slotToForge]
 192	if !ok {
 193		slotState = eth.NewSlotState()
 194		a.State.Slots[slotToForge] = slotState
 195	}
 196	if slotState.ClosedMinBid.Cmp(big.NewInt(0)) == 0 {
 197		minBid = a.Vars.DefaultSlotSetBid[a.getSlotSet(slotToForge)]
 198	} else {
 199		minBid = slotState.ClosedMinBid
 200	}
 201
 202	if !slotState.ForgerCommitment && (relativeBlock >= int64(a.Vars.SlotDeadline)) {
 203		// if the relative block has exceeded the slotDeadline and no
 204		// batch has been forged, anyone can forge
 205		return true, nil
 206	} else if coord, ok := a.State.Coordinators[slotState.Bidder]; ok &&
 207		coord.Forger == forger && slotState.BidAmount.Cmp(minBid) >= 0 {
 208		// if forger bidAmount has exceeded the minBid it can forge
 209		return true, nil
 210	} else if a.Vars.BootCoordinator == forger && slotState.BidAmount.Cmp(minBid) == -1 {
 211		// if it's the boot coordinator and it has not been bid or the
 212		// bid is below the minimum it can forge
 213		return true, nil
 214	} else {
 215		return false, nil
 216	}
 217}
 218
 219// EthereumBlock stores all the generic data related to the an ethereum block
 220type EthereumBlock struct {
 221	BlockNum   int64
 222	Time       int64
 223	Hash       ethCommon.Hash
 224	ParentHash ethCommon.Hash
 225	Tokens     map[ethCommon.Address]eth.ERC20Consts
 226	Nonce      uint64
 227	// state      ethState
 228}
 229
 230// Block represents a ethereum block
 231type Block struct {
 232	Rollup   *RollupBlock
 233	Auction  *AuctionBlock
 234	WDelayer *WDelayerBlock
 235	Eth      *EthereumBlock
 236}
 237
 238func (b *Block) copy() *Block {
 239	bCopyRaw, err := copystructure.Copy(b)
 240	if err != nil {
 241		panic(err)
 242	}
 243	bCopy := bCopyRaw.(*Block)
 244	return bCopy
 245}
 246
 247// Next prepares the successive block.
 248func (b *Block) Next() *Block {
 249	blockNext := b.copy()
 250	blockNext.Rollup.Events = eth.NewRollupEvents()
 251	blockNext.Auction.Events = eth.NewAuctionEvents()
 252
 253	blockNext.Eth.BlockNum = b.Eth.BlockNum + 1
 254	blockNext.Eth.ParentHash = b.Eth.Hash
 255
 256	blockNext.Rollup.Constants = b.Rollup.Constants
 257	blockNext.Auction.Constants = b.Auction.Constants
 258	blockNext.WDelayer.Constants = b.WDelayer.Constants
 259	blockNext.Rollup.Eth = blockNext.Eth
 260	blockNext.Auction.Eth = blockNext.Eth
 261	blockNext.WDelayer.Eth = blockNext.Eth
 262
 263	return blockNext
 264}
 265
 266// ClientSetup is used to initialize the constants of the Smart Contracts and
 267// other details of the test Client
 268type ClientSetup struct {
 269	RollupConstants   *common.RollupConstants
 270	RollupVariables   *common.RollupVariables
 271	AuctionConstants  *common.AuctionConstants
 272	AuctionVariables  *common.AuctionVariables
 273	WDelayerConstants *common.WDelayerConstants
 274	WDelayerVariables *common.WDelayerVariables
 275	VerifyProof       bool
 276	ChainID           *big.Int
 277}
 278
 279// NewClientSetupExample returns a ClientSetup example with hardcoded realistic
 280// values.  With this setup, the rollup genesis will be block 1, and block 0
 281// and 1 will be premined.
 282//nolint:gomnd
 283func NewClientSetupExample() *ClientSetup {
 284	// rfield, ok := new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
 285	// if !ok {
 286	// 	panic("bad rfield")
 287	// }
 288	initialMinimalBidding, ok := new(big.Int).SetString("10000000000000000000", 10) // 10 * (1e18)
 289	if !ok {
 290		panic("bad initialMinimalBidding")
 291	}
 292	tokenHEZ := ethCommon.HexToAddress("0x51D243D62852Bba334DD5cc33f242BAc8c698074")
 293	governanceAddress := ethCommon.HexToAddress("0x688EfD95BA4391f93717CF02A9aED9DBD2855cDd")
 294	rollupConstants := &common.RollupConstants{
 295		Verifiers: []common.RollupVerifierStruct{
 296			{
 297				MaxTx:   2048,
 298				NLevels: 32,
 299			},
 300		},
 301		TokenHEZ:                tokenHEZ,
 302		HermezGovernanceAddress: governanceAddress,
 303		HermezAuctionContract:   ethCommon.HexToAddress("0x8E442975805fb1908f43050c9C1A522cB0e28D7b"),
 304		WithdrawDelayerContract: ethCommon.HexToAddress("0x5CB7979cBdbf65719BEE92e4D15b7b7Ed3D79114"),
 305	}
 306	var buckets [common.RollupConstNumBuckets]common.BucketParams
 307	for i := range buckets {
 308		buckets[i] = common.BucketParams{
 309			CeilUSD:             big.NewInt(0),
 310			Withdrawals:         big.NewInt(0),
 311			BlockWithdrawalRate: big.NewInt(0),
 312			MaxWithdrawals:      big.NewInt(0),
 313		}
 314	}
 315	rollupVariables := &common.RollupVariables{
 316		FeeAddToken:           big.NewInt(11),
 317		ForgeL1L2BatchTimeout: 10,
 318		WithdrawalDelay:       80,
 319		Buckets:               buckets,
 320	}
 321	auctionConstants := &common.AuctionConstants{
 322		BlocksPerSlot:         40,
 323		InitialMinimalBidding: initialMinimalBidding,
 324		GenesisBlockNum:       1,
 325		GovernanceAddress:     governanceAddress,
 326		TokenHEZ:              tokenHEZ,
 327		HermezRollup:          ethCommon.HexToAddress("0x474B6e29852257491cf283EfB1A9C61eBFe48369"),
 328	}
 329	auctionVariables := &common.AuctionVariables{
 330		DonationAddress:    ethCommon.HexToAddress("0x61Ed87CF0A1496b49A420DA6D84B58196b98f2e7"),
 331		BootCoordinator:    ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"),
 332		BootCoordinatorURL: "https://boot.coordinator.com",
 333		DefaultSlotSetBid: [6]*big.Int{
 334			initialMinimalBidding, initialMinimalBidding, initialMinimalBidding,
 335			initialMinimalBidding, initialMinimalBidding, initialMinimalBidding,
 336		},
 337		ClosedAuctionSlots: 2,
 338		OpenAuctionSlots:   4320,
 339		AllocationRatio:    [3]uint16{4000, 4000, 2000},
 340		Outbidding:         1000,
 341		SlotDeadline:       20,
 342	}
 343	wDelayerConstants := &common.WDelayerConstants{
 344		MaxWithdrawalDelay:   60 * 60 * 24 * 7 * 2,  // 2 weeks
 345		MaxEmergencyModeTime: 60 * 60 * 24 * 7 * 26, // 26 weeks
 346		HermezRollup:         auctionConstants.HermezRollup,
 347	}
 348	wDelayerVariables := &common.WDelayerVariables{
 349		HermezGovernanceAddress:    ethCommon.HexToAddress("0xcfD0d163AE6432a72682323E2C3A5a69e6B37D12"),
 350		EmergencyCouncilAddress:    ethCommon.HexToAddress("0x2730700932a4FDB97B9268A3Ca29f97Ea5fd7EA0"),
 351		WithdrawalDelay:            60,
 352		EmergencyModeStartingBlock: 0,
 353		EmergencyMode:              false,
 354	}
 355	return &ClientSetup{
 356		RollupConstants:   rollupConstants,
 357		RollupVariables:   rollupVariables,
 358		AuctionConstants:  auctionConstants,
 359		AuctionVariables:  auctionVariables,
 360		WDelayerConstants: wDelayerConstants,
 361		WDelayerVariables: wDelayerVariables,
 362		VerifyProof:       false,
 363		ChainID:           big.NewInt(0),
 364	}
 365}
 366
 367// Timer is an interface to simulate a source of time, useful to advance time
 368// virtually.
 369type Timer interface {
 370	Time() int64
 371}
 372
 373// type forgeBatchArgs struct {
 374// 	ethTx     *types.Transaction
 375// 	blockNum  int64
 376// 	blockHash ethCommon.Hash
 377// }
 378
 379type batch struct {
 380	ForgeBatchArgs eth.RollupForgeBatchArgs
 381	Sender         ethCommon.Address
 382}
 383
 384// Client implements the eth.ClientInterface interface, allowing to manipulate the
 385// values for testing, working with deterministic results.
 386type Client struct {
 387	rw                *sync.RWMutex
 388	log               bool
 389	addr              *ethCommon.Address
 390	chainID           *big.Int
 391	rollupConstants   *common.RollupConstants
 392	auctionConstants  *common.AuctionConstants
 393	wDelayerConstants *common.WDelayerConstants
 394	blocks            map[int64]*Block
 395	// state            state
 396	blockNum    int64 // last mined block num
 397	maxBlockNum int64 // highest block num calculated
 398	timer       Timer
 399	hasher      hasher
 400
 401	forgeBatchArgsPending map[ethCommon.Hash]*batch
 402	forgeBatchArgs        map[ethCommon.Hash]*batch
 403
 404	startBlock int64
 405}
 406
 407// NewClient returns a new test Client that implements the eth.IClient
 408// interface, at the given initialBlockNumber.
 409func NewClient(l bool, timer Timer, addr *ethCommon.Address, setup *ClientSetup) *Client {
 410	blocks := make(map[int64]*Block)
 411	blockNum := int64(0)
 412
 413	hasher := hasher{}
 414	// Add ethereum genesis block
 415	mapL1TxQueue := make(map[int64]*eth.QueueStruct)
 416	mapL1TxQueue[0] = eth.NewQueueStruct()
 417	mapL1TxQueue[1] = eth.NewQueueStruct()
 418	blockCurrent := &Block{
 419		Rollup: &RollupBlock{
 420			State: eth.RollupState{
 421				StateRoot:        big.NewInt(0),
 422				ExitRoots:        make([]*big.Int, 1),
 423				ExitNullifierMap: make(map[int64]map[int64]bool),
 424				// TokenID = 0 is ETH.  Set first entry in TokenList with 0x0 address for ETH.
 425				TokenList:              []ethCommon.Address{{}},
 426				TokenMap:               make(map[ethCommon.Address]bool),
 427				MapL1TxQueue:           mapL1TxQueue,
 428				LastL1L2Batch:          0,
 429				CurrentToForgeL1TxsNum: 0,
 430				LastToForgeL1TxsNum:    1,
 431				CurrentIdx:             0,
 432			},
 433			Vars:      *setup.RollupVariables,
 434			Txs:       make(map[ethCommon.Hash]*types.Transaction),
 435			Events:    eth.NewRollupEvents(),
 436			Constants: setup.RollupConstants,
 437		},
 438		Auction: &AuctionBlock{
 439			State: eth.AuctionState{
 440				Slots:           make(map[int64]*eth.SlotState),
 441				PendingBalances: make(map[ethCommon.Address]*big.Int),
 442				Coordinators:    make(map[ethCommon.Address]*eth.Coordinator),
 443			},
 444			Vars:      *setup.AuctionVariables,
 445			Txs:       make(map[ethCommon.Hash]*types.Transaction),
 446			Events:    eth.NewAuctionEvents(),
 447			Constants: setup.AuctionConstants,
 448		},
 449		WDelayer: &WDelayerBlock{
 450			// State: TODO
 451			Vars:      *setup.WDelayerVariables,
 452			Txs:       make(map[ethCommon.Hash]*types.Transaction),
 453			Events:    eth.NewWDelayerEvents(),
 454			Constants: setup.WDelayerConstants,
 455		},
 456		Eth: &EthereumBlock{
 457			BlockNum:   blockNum,
 458			Time:       timer.Time(),
 459			Hash:       hasher.Next(),
 460			ParentHash: ethCommon.Hash{},
 461			Tokens:     make(map[ethCommon.Address]eth.ERC20Consts),
 462		},
 463	}
 464	blockCurrent.Rollup.Eth = blockCurrent.Eth
 465	blockCurrent.Auction.Eth = blockCurrent.Eth
 466	blocks[blockNum] = blockCurrent
 467	blockNext := blockCurrent.Next()
 468	blocks[blockNum+1] = blockNext
 469
 470	c := Client{
 471		rw:                    &sync.RWMutex{},
 472		log:                   l,
 473		addr:                  addr,
 474		rollupConstants:       setup.RollupConstants,
 475		auctionConstants:      setup.AuctionConstants,
 476		wDelayerConstants:     setup.WDelayerConstants,
 477		blocks:                blocks,
 478		timer:                 timer,
 479		hasher:                hasher,
 480		forgeBatchArgsPending: make(map[ethCommon.Hash]*batch),
 481		forgeBatchArgs:        make(map[ethCommon.Hash]*batch),
 482		blockNum:              blockNum,
 483		maxBlockNum:           blockNum,
 484	}
 485
 486	if c.startBlock == 0 {
 487		c.startBlock = 2
 488	}
 489	for i := int64(1); i < c.startBlock; i++ {
 490		c.CtlMineBlock()
 491	}
 492
 493	return &c
 494}
 495
 496//
 497// Mock Control
 498//
 499
 500func (c *Client) setNextBlock(block *Block) {
 501	c.blocks[c.blockNum+1] = block
 502}
 503
 504func (c *Client) revertIfErr(err error, block *Block) {
 505	if err != nil {
 506		log.Infow("TestClient revert", "block", block.Eth.BlockNum, "err", err)
 507		c.setNextBlock(block)
 508	}
 509}
 510
 511// Debugf calls log.Debugf if c.log is true
 512func (c *Client) Debugf(template string, args ...interface{}) {
 513	if c.log {
 514		log.Debugf(template, args...)
 515	}
 516}
 517
 518// Debugw calls log.Debugw if c.log is true
 519func (c *Client) Debugw(template string, kv ...interface{}) {
 520	if c.log {
 521		log.Debugw(template, kv...)
 522	}
 523}
 524
 525type hasher struct {
 526	counter uint64
 527}
 528
 529// Next returns the next hash
 530func (h *hasher) Next() ethCommon.Hash {
 531	var hash ethCommon.Hash
 532	binary.LittleEndian.PutUint64(hash[:], h.counter)
 533	h.counter++
 534	return hash
 535}
 536
 537func (c *Client) nextBlock() *Block {
 538	return c.blocks[c.blockNum+1]
 539}
 540
 541func (c *Client) currentBlock() *Block {
 542	return c.blocks[c.blockNum]
 543}
 544
 545// CtlSetAddr sets the address of the client
 546func (c *Client) CtlSetAddr(addr ethCommon.Address) {
 547	c.addr = &addr
 548}
 549
 550// CtlMineBlock moves one block forward
 551func (c *Client) CtlMineBlock() {
 552	c.rw.Lock()
 553	defer c.rw.Unlock()
 554
 555	blockCurrent := c.nextBlock()
 556	c.blockNum++
 557	c.maxBlockNum = c.blockNum
 558	blockCurrent.Eth.Time = c.timer.Time()
 559	blockCurrent.Eth.Hash = c.hasher.Next()
 560	for ethTxHash, forgeBatchArgs := range c.forgeBatchArgsPending {
 561		c.forgeBatchArgs[ethTxHash] = forgeBatchArgs
 562	}
 563	c.forgeBatchArgsPending = make(map[ethCommon.Hash]*batch)
 564
 565	blockNext := blockCurrent.Next()
 566	c.blocks[c.blockNum+1] = blockNext
 567	c.Debugw("TestClient mined block", "blockNum", c.blockNum)
 568}
 569
 570// CtlRollback discards the last mined block.  Use this to replace a mined
 571// block to simulate reorgs.
 572func (c *Client) CtlRollback() {
 573	c.rw.Lock()
 574	defer c.rw.Unlock()
 575
 576	if c.blockNum == 0 {
 577		panic("Can't rollback at blockNum = 0")
 578	}
 579	delete(c.blocks, c.blockNum+1) // delete next block
 580	delete(c.blocks, c.blockNum)   // delete current block
 581	c.blockNum--
 582	blockCurrent := c.blocks[c.blockNum]
 583	blockNext := blockCurrent.Next()
 584	c.blocks[c.blockNum+1] = blockNext
 585}
 586
 587//
 588// Ethereum
 589//
 590
 591// CtlLastBlock returns the last blockNum without checks
 592func (c *Client) CtlLastBlock() *common.Block {
 593	c.rw.RLock()
 594	defer c.rw.RUnlock()
 595
 596	block := c.blocks[c.blockNum]
 597	return &common.Block{
 598		Num:        c.blockNum,
 599		Timestamp:  time.Unix(block.Eth.Time, 0),
 600		Hash:       block.Eth.Hash,
 601		ParentHash: block.Eth.ParentHash,
 602	}
 603}
 604
 605// CtlLastForgedBatch returns the last batchNum without checks
 606func (c *Client) CtlLastForgedBatch() int64 {
 607	c.rw.RLock()
 608	defer c.rw.RUnlock()
 609
 610	currentBlock := c.currentBlock()
 611	e := currentBlock.Rollup
 612	return int64(len(e.State.ExitRoots)) - 1
 613}
 614
 615// EthChainID returns the ChainID of the ethereum network
 616func (c *Client) EthChainID() (*big.Int, error) {
 617	return c.chainID, nil
 618}
 619
 620// EthPendingNonceAt returns the account nonce of the given account in the pending
 621// state. This is the nonce that should be used for the next transaction.
 622func (c *Client) EthPendingNonceAt(ctx context.Context, account ethCommon.Address) (uint64, error) {
 623	// NOTE: For now Client doesn't simulate nonces
 624	return 0, nil
 625}
 626
 627// EthNonceAt returns the account nonce of the given account. The block number can
 628// be nil, in which case the nonce is taken from the latest known block.
 629func (c *Client) EthNonceAt(ctx context.Context, account ethCommon.Address, blockNumber *big.Int) (uint64, error) {
 630	// NOTE: For now Client doesn't simulate nonces
 631	return 0, nil
 632}
 633
 634// EthSuggestGasPrice retrieves the currently suggested gas price to allow a
 635// timely execution of a transaction.
 636func (c *Client) EthSuggestGasPrice(ctx context.Context) (*big.Int, error) {
 637	// NOTE: For now Client doesn't simulate gasPrice
 638	return big.NewInt(0), nil
 639}
 640
 641// EthKeyStore returns the keystore in the Client
 642func (c *Client) EthKeyStore() *ethKeystore.KeyStore {
 643	return nil
 644}
 645
 646// EthCall runs the transaction as a call (without paying) in the local node at
 647// blockNum.
 648func (c *Client) EthCall(ctx context.Context, tx *types.Transaction, blockNum *big.Int) ([]byte, error) {
 649	return nil, tracerr.Wrap(common.ErrTODO)
 650}
 651
 652// EthLastBlock returns the last blockNum
 653func (c *Client) EthLastBlock() (int64, error) {
 654	c.rw.RLock()
 655	defer c.rw.RUnlock()
 656
 657	if c.blockNum < c.maxBlockNum {
 658		panic("blockNum has decreased.  " +
 659			"After a rollback you must mine to reach the same or higher blockNum")
 660	}
 661	return c.blockNum, nil
 662}
 663
 664// EthTransactionReceipt returns the transaction receipt of the given txHash
 665func (c *Client) EthTransactionReceipt(ctx context.Context, txHash ethCommon.Hash) (*types.Receipt, error) {
 666	c.rw.RLock()
 667	defer c.rw.RUnlock()
 668
 669	for i := int64(0); i < c.blockNum; i++ {
 670		b := c.blocks[i]
 671		_, ok := b.Rollup.Txs[txHash]
 672		if !ok {
 673			_, ok = b.Auction.Txs[txHash]
 674		}
 675		if ok {
 676			return &types.Receipt{
 677				TxHash:      txHash,
 678				Status:      types.ReceiptStatusSuccessful,
 679				BlockHash:   b.Eth.Hash,
 680				BlockNumber: big.NewInt(b.Eth.BlockNum),
 681			}, nil
 682		}
 683	}
 684
 685	return nil, nil
 686}
 687
 688// CtlAddERC20 adds an ERC20 token to the blockchain.
 689func (c *Client) CtlAddERC20(tokenAddr ethCommon.Address, constants eth.ERC20Consts) {
 690	nextBlock := c.nextBlock()
 691	e := nextBlock.Eth
 692	e.Tokens[tokenAddr] = constants
 693}
 694
 695// EthERC20Consts returns the constants defined for a particular ERC20 Token instance.
 696func (c *Client) EthERC20Consts(tokenAddr ethCommon.Address) (*eth.ERC20Consts, error) {
 697	currentBlock := c.currentBlock()
 698	e := currentBlock.Eth
 699	if constants, ok := e.Tokens[tokenAddr]; ok {
 700		return &constants, nil
 701	}
 702	return nil, tracerr.Wrap(fmt.Errorf("tokenAddr not found"))
 703}
 704
 705// func newHeader(number *big.Int) *types.Header {
 706// 	return &types.Header{
 707// 		Number: number,
 708// 		Time:   uint64(number.Int64()),
 709// 	}
 710// }
 711
 712// EthHeaderByNumber returns the *types.Header for the given block number in a
 713// deterministic way.
 714// func (c *Client) EthHeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
 715// 	return newHeader(number), nil
 716// }
 717
 718// EthBlockByNumber returns the *common.Block for the given block number in a
 719// deterministic way.  If number == -1, the latests known block is returned.
 720func (c *Client) EthBlockByNumber(ctx context.Context, blockNum int64) (*common.Block, error) {
 721	c.rw.RLock()
 722	defer c.rw.RUnlock()
 723
 724	if blockNum > c.blockNum {
 725		return nil, ethereum.NotFound
 726	}
 727	if blockNum == -1 {
 728		blockNum = c.blockNum
 729	}
 730	block := c.blocks[blockNum]
 731	return &common.Block{
 732		Num:        blockNum,
 733		Timestamp:  time.Unix(block.Eth.Time, 0),
 734		Hash:       block.Eth.Hash,
 735		ParentHash: block.Eth.ParentHash,
 736	}, nil
 737}
 738
 739// EthAddress returns the ethereum address of the account loaded into the Client
 740func (c *Client) EthAddress() (*ethCommon.Address, error) {
 741	if c.addr == nil {
 742		return nil, tracerr.Wrap(eth.ErrAccountNil)
 743	}
 744	return c.addr, nil
 745}
 746
 747var errTODO = fmt.Errorf("TODO: Not implemented yet")
 748
 749//
 750// Rollup
 751//
 752
 753// CtlAddL1TxUser adds an L1TxUser to the L1UserTxs queue of the Rollup
 754// func (c *Client) CtlAddL1TxUser(l1Tx *common.L1Tx) {
 755// 	c.rw.Lock()
 756// 	defer c.rw.Unlock()
 757//
 758// 	nextBlock := c.nextBlock()
 759// 	r := nextBlock.Rollup
 760// 	queue := r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum]
 761// 	if len(queue.L1TxQueue) >= eth.RollupConstMaxL1UserTx {
 762// 		r.State.LastToForgeL1TxsNum++
 763// 		r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum] = eth.NewQueueStruct()
 764// 		queue = r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum]
 765// 	}
 766// 	if int64(l1Tx.FromIdx) > r.State.CurrentIdx {
 767// 		panic("l1Tx.FromIdx > r.State.CurrentIdx")
 768// 	}
 769// 	if int(l1Tx.TokenID)+1 > len(r.State.TokenList) {
 770// 		panic("l1Tx.TokenID + 1 > len(r.State.TokenList)")
 771// 	}
 772// 	queue.L1TxQueue = append(queue.L1TxQueue, *l1Tx)
 773// 	r.Events.L1UserTx = append(r.Events.L1UserTx, eth.RollupEventL1UserTx{
 774// 		L1Tx:            *l1Tx,
 775// 		ToForgeL1TxsNum: r.State.LastToForgeL1TxsNum,
 776// 		Position:        len(queue.L1TxQueue) - 1,
 777// 	})
 778// }
 779
 780// RollupL1UserTxERC20Permit is the interface to call the smart contract function
 781func (c *Client) RollupL1UserTxERC20Permit(fromBJJ babyjub.PublicKeyComp, fromIdx int64, depositAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64, deadline *big.Int) (tx *types.Transaction, err error) {
 782	log.Error("TODO")
 783	return nil, tracerr.Wrap(errTODO)
 784}
 785
 786// RollupL1UserTxERC20ETH sends an L1UserTx to the Rollup.
 787func (c *Client) RollupL1UserTxERC20ETH(
 788	fromBJJ babyjub.PublicKeyComp,
 789	fromIdx int64,
 790	depositAmount *big.Int,
 791	amount *big.Int,
 792	tokenID uint32,
 793	toIdx int64,
 794) (tx *types.Transaction, err error) {
 795	c.rw.Lock()
 796	defer c.rw.Unlock()
 797	cpy := c.nextBlock().copy()
 798	defer func() { c.revertIfErr(err, cpy) }()
 799
 800	_, err = common.NewFloat40(amount)
 801	if err != nil {
 802		return nil, tracerr.Wrap(err)
 803	}
 804	_, err = common.NewFloat40(depositAmount)
 805	if err != nil {
 806		return nil, tracerr.Wrap(err)
 807	}
 808
 809	nextBlock := c.nextBlock()
 810	r := nextBlock.Rollup
 811	queue := r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum]
 812	if len(queue.L1TxQueue) >= common.RollupConstMaxL1UserTx {
 813		r.State.LastToForgeL1TxsNum++
 814		r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum] = eth.NewQueueStruct()
 815		queue = r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum]
 816	}
 817	if fromIdx > r.State.CurrentIdx {
 818		panic("l1Tx.FromIdx > r.State.CurrentIdx")
 819	}
 820	if int(tokenID)+1 > len(r.State.TokenList) {
 821		panic("l1Tx.TokenID + 1 > len(r.State.TokenList)")
 822	}
 823	toForgeL1TxsNum := r.State.LastToForgeL1TxsNum
 824	l1Tx, err := common.NewL1Tx(&common.L1Tx{
 825		FromIdx:         common.Idx(fromIdx),
 826		FromEthAddr:     *c.addr,
 827		FromBJJ:         fromBJJ,
 828		Amount:          amount,
 829		DepositAmount:   depositAmount,
 830		TokenID:         common.TokenID(tokenID),
 831		ToIdx:           common.Idx(toIdx),
 832		ToForgeL1TxsNum: &toForgeL1TxsNum,
 833		Position:        len(queue.L1TxQueue),
 834		UserOrigin:      true,
 835	})
 836	if err != nil {
 837		return nil, tracerr.Wrap(err)
 838	}
 839
 840	queue.L1TxQueue = append(queue.L1TxQueue, *l1Tx)
 841	r.Events.L1UserTx = append(r.Events.L1UserTx, eth.RollupEventL1UserTx{
 842		L1UserTx: *l1Tx,
 843	})
 844	return r.addTransaction(c.newTransaction("l1UserTxERC20ETH", l1Tx)), nil
 845}
 846
 847// RollupL1UserTxERC777 is the interface to call the smart contract function
 848// func (c *Client) RollupL1UserTxERC777(fromBJJ *babyjub.PublicKey, fromIdx int64, depositAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64) (*types.Transaction, error) {
 849// 	log.Error("TODO")
 850// 	return nil, errTODO
 851// }
 852
 853// RollupRegisterTokensCount is the interface to call the smart contract function
 854func (c *Client) RollupRegisterTokensCount() (*big.Int, error) {
 855	log.Error("TODO")
 856	return nil, tracerr.Wrap(errTODO)
 857}
 858
 859// RollupLastForgedBatch is the interface to call the smart contract function
 860func (c *Client) RollupLastForgedBatch() (int64, error) {
 861	c.rw.RLock()
 862	defer c.rw.RUnlock()
 863
 864	currentBlock := c.currentBlock()
 865	e := currentBlock.Rollup
 866	return int64(len(e.State.ExitRoots)) - 1, nil
 867}
 868
 869// RollupWithdrawCircuit is the interface to call the smart contract function
 870func (c *Client) RollupWithdrawCircuit(proofA, proofC [2]*big.Int, proofB [2][2]*big.Int, tokenID uint32, numExitRoot, idx int64, amount *big.Int, instantWithdraw bool) (*types.Transaction, error) {
 871	log.Error("TODO")
 872	return nil, tracerr.Wrap(errTODO)
 873}
 874
 875// RollupWithdrawMerkleProof is the interface to call the smart contract function
 876func (c *Client) RollupWithdrawMerkleProof(babyPubKey babyjub.PublicKeyComp, tokenID uint32, numExitRoot, idx int64, amount *big.Int, siblings []*big.Int, instantWithdraw bool) (tx *types.Transaction, err error) {
 877	c.rw.Lock()
 878	defer c.rw.Unlock()
 879	cpy := c.nextBlock().copy()
 880	defer func() { c.revertIfErr(err, cpy) }()
 881
 882	nextBlock := c.nextBlock()
 883	r := nextBlock.Rollup
 884
 885	if int(numExitRoot) >= len(r.State.ExitRoots) {
 886		return nil, tracerr.Wrap(fmt.Errorf("numExitRoot >= len(r.State.ExitRoots)"))
 887	}
 888	if _, ok := r.State.ExitNullifierMap[numExitRoot][idx]; ok {
 889		return nil, tracerr.Wrap(fmt.Errorf("exit already withdrawn"))
 890	}
 891	r.State.ExitNullifierMap[numExitRoot][idx] = true
 892
 893	babyPubKeyDecomp, err := babyPubKey.Decompress()
 894	if err != nil {
 895		return nil, tracerr.Wrap(err)
 896	}
 897
 898	type data struct {
 899		BabyPubKey      *babyjub.PublicKey
 900		TokenID         uint32
 901		NumExitRoot     int64
 902		Idx             int64
 903		Amount          *big.Int
 904		Siblings        []*big.Int
 905		InstantWithdraw bool
 906	}
 907	tx = r.addTransaction(c.newTransaction("withdrawMerkleProof", data{
 908		BabyPubKey:      babyPubKeyDecomp,
 909		TokenID:         tokenID,
 910		NumExitRoot:     numExitRoot,
 911		Idx:             idx,
 912		Amount:          amount,
 913		Siblings:        siblings,
 914		InstantWithdraw: instantWithdraw,
 915	}))
 916	r.Events.Withdraw = append(r.Events.Withdraw, eth.RollupEventWithdraw{
 917		Idx:             uint64(idx),
 918		NumExitRoot:     uint64(numExitRoot),
 919		InstantWithdraw: instantWithdraw,
 920		TxHash:          tx.Hash(),
 921	})
 922
 923	if !instantWithdraw {
 924		w := nextBlock.WDelayer
 925		w.deposit(tx.Hash(), *c.addr, r.State.TokenList[int(tokenID)], amount)
 926	}
 927	return tx, nil
 928}
 929
 930type transactionData struct {
 931	Name  string
 932	Value interface{}
 933}
 934
 935func (c *Client) newTransaction(name string, value interface{}) *types.Transaction {
 936	eth := c.nextBlock().Eth
 937	nonce := eth.Nonce
 938	eth.Nonce++
 939	data, err := json.Marshal(transactionData{name, value})
 940	if err != nil {
 941		panic(err)
 942	}
 943	return types.NewTransaction(nonce, ethCommon.Address{}, nil, 0, nil,
 944		data)
 945}
 946
 947// RollupForgeBatch is the interface to call the smart contract function
 948func (c *Client) RollupForgeBatch(args *eth.RollupForgeBatchArgs, auth *bind.TransactOpts) (tx *types.Transaction, err error) {
 949	c.rw.Lock()
 950	defer c.rw.Unlock()
 951	cpy := c.nextBlock().copy()
 952	defer func() { c.revertIfErr(err, cpy) }()
 953	if c.addr == nil {
 954		return nil, tracerr.Wrap(eth.ErrAccountNil)
 955	}
 956
 957	a := c.nextBlock().Auction
 958	ok, err := a.canForge(*c.addr, a.Eth.BlockNum)
 959	if err != nil {
 960		return nil, tracerr.Wrap(err)
 961	}
 962	if !ok {
 963		return nil, tracerr.Wrap(fmt.Errorf(common.AuctionErrMsgCannotForge))
 964	}
 965
 966	// TODO: Verify proof
 967
 968	// Auction
 969	err = a.forge(*c.addr)
 970	if err != nil {
 971		return nil, tracerr.Wrap(err)
 972	}
 973
 974	// TODO: If successful, store the tx in a successful array.
 975	// TODO: If failed, store the tx in a failed array.
 976	// TODO: Add method to move the tx to another block, reapply it there, and possibly go from successful to failed.
 977
 978	return c.addBatch(args)
 979}
 980
 981// CtlAddBatch adds forged batch to the Rollup, without checking any ZKProof
 982func (c *Client) CtlAddBatch(args *eth.RollupForgeBatchArgs) {
 983	c.rw.Lock()
 984	defer c.rw.Unlock()
 985
 986	if _, err := c.addBatch(args); err != nil {
 987		panic(err)
 988	}
 989}
 990
 991func (c *Client) addBatch(args *eth.RollupForgeBatchArgs) (*types.Transaction, error) {
 992	nextBlock := c.nextBlock()
 993	r := nextBlock.Rollup
 994	r.State.StateRoot = args.NewStRoot
 995	if args.NewLastIdx < r.State.CurrentIdx {
 996		return nil, tracerr.Wrap(fmt.Errorf("args.NewLastIdx < r.State.CurrentIdx"))
 997	}
 998	r.State.CurrentIdx = args.NewLastIdx
 999	r.State.ExitNullifierMap[int64(len(r.State.ExitRoots))] = make(map[int64]bool)
1000	r.State.ExitRoots = append(r.State.ExitRoots, args.NewExitRoot)
1001	if args.L1Batch {
1002		r.State.CurrentToForgeL1TxsNum++
1003		if r.State.CurrentToForgeL1TxsNum == r.State.LastToForgeL1TxsNum {
1004			r.State.LastToForgeL1TxsNum++
1005			r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum] = eth.NewQueueStruct()
1006		}
1007	}
1008	ethTx := r.addTransaction(c.newTransaction("forgebatch", args))
1009	c.forgeBatchArgsPending[ethTx.Hash()] = &batch{*args, *c.addr}
1010	r.Events.ForgeBatch = append(r.Events.ForgeBatch, eth.RollupEventForgeBatch{
1011		BatchNum:     int64(len(r.State.ExitRoots)) - 1,
1012		EthTxHash:    ethTx.Hash(),
1013		L1UserTxsLen: uint16(len(args.L1UserTxs)),
1014	})
1015
1016	return ethTx, nil
1017}
1018
1019// RollupAddTokenSimple is a wrapper around RollupAddToken that automatically
1020// sets `deadlie`.
1021func (c *Client) RollupAddTokenSimple(tokenAddress ethCommon.Address, feeAddToken *big.Int) (tx *types.Transaction, err error) {
1022	return c.RollupAddToken(tokenAddress, feeAddToken, big.NewInt(9999)) //nolint:gomnd
1023}
1024
1025// RollupAddToken is the interface to call the smart contract function
1026func (c *Client) RollupAddToken(tokenAddress ethCommon.Address, feeAddToken *big.Int,
1027	deadline *big.Int) (tx *types.Transaction, err error) {
1028	c.rw.Lock()
1029	defer c.rw.Unlock()
1030	cpy := c.nextBlock().copy()
1031	defer func() { c.revertIfErr(err, cpy) }()
1032	if c.addr == nil {
1033		return nil, tracerr.Wrap(eth.ErrAccountNil)
1034	}
1035
1036	nextBlock := c.nextBlock()
1037	r := nextBlock.Rollup
1038	if _, ok := r.State.TokenMap[tokenAddress]; ok {
1039		return nil, tracerr.Wrap(fmt.Errorf("Token %v already registered", tokenAddress))
1040	}
1041	if feeAddToken.Cmp(r.Vars.FeeAddToken) != 0 {
1042		return nil, tracerr.Wrap(fmt.Errorf("Expected fee: %v but got: %v", r.Vars.FeeAddToken, feeAddToken))
1043	}
1044
1045	r.State.TokenMap[tokenAddress] = true
1046	r.State.TokenList = append(r.State.TokenList, tokenAddress)
1047	r.Events.AddToken = append(r.Events.AddToken, eth.RollupEventAddToken{TokenAddress: tokenAddress,
1048		TokenID: uint32(len(r.State.TokenList) - 1)})
1049	return r.addTransaction(c.newTransaction("addtoken", tokenAddress)), nil
1050}
1051
1052// RollupGetCurrentTokens is the interface to call the smart contract function
1053func (c *Client) RollupGetCurrentTokens() (*big.Int, error) {
1054	c.rw.RLock()
1055	defer c.rw.RUnlock()
1056
1057	log.Error("TODO")
1058	return nil, tracerr.Wrap(errTODO)
1059}
1060
1061// RollupUpdateForgeL1L2BatchTimeout is the interface to call the smart contract function
1062func (c *Client) RollupUpdateForgeL1L2BatchTimeout(newForgeL1Timeout int64) (tx *types.Transaction, err error) {
1063	c.rw.Lock()
1064	defer c.rw.Unlock()
1065	cpy := c.nextBlock().copy()
1066	defer func() { c.revertIfErr(err, cpy) }()
1067	if c.addr == nil {
1068		return nil, tracerr.Wrap(eth.ErrAccountNil)
1069	}
1070
1071	nextBlock := c.nextBlock()
1072	r := nextBlock.Rollup
1073	r.Vars.ForgeL1L2BatchTimeout = newForgeL1Timeout
1074	r.Events.UpdateForgeL1L2BatchTimeout = append(r.Events.UpdateForgeL1L2BatchTimeout,
1075		eth.RollupEventUpdateForgeL1L2BatchTimeout{NewForgeL1L2BatchTimeout: newForgeL1Timeout})
1076
1077	return r.addTransaction(c.newTransaction("updateForgeL1L2BatchTimeout", newForgeL1Timeout)), nil
1078}
1079
1080// RollupUpdateFeeAddToken is the interface to call the smart contract function
1081func (c *Client) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (tx *types.Transaction, err error) {
1082	c.rw.Lock()
1083	defer c.rw.Unlock()
1084	cpy := c.nextBlock().copy()
1085	defer func() { c.revertIfErr(err, cpy) }()
1086	if c.addr == nil {
1087		return nil, tracerr.Wrap(eth.ErrAccountNil)
1088	}
1089
1090	log.Error("TODO")
1091	return nil, tracerr.Wrap(errTODO)
1092}
1093
1094// RollupUpdateTokensHEZ is the interface to call the smart contract function
1095// func (c *Client) RollupUpdateTokensHEZ(newTokenHEZ ethCommon.Address) (tx *types.Transaction, err error) {
1096// 	c.rw.Lock()
1097// 	defer c.rw.Unlock()
1098// 	cpy := c.nextBlock().copy()
1099// 	defer func() { c.revertIfErr(err, cpy) }()
1100//
1101// 	log.Error("TODO")
1102// 	return nil, errTODO
1103// }
1104
1105// RollupUpdateGovernance is the interface to call the smart contract function
1106// func (c *Client) RollupUpdateGovernance() (*types.Transaction, error) { // TODO (Not defined in Hermez.sol)
1107// 	return nil, errTODO
1108// }
1109
1110// RollupConstants returns the Constants of the Rollup Smart Contract
1111func (c *Client) RollupConstants() (*common.RollupConstants, error) {
1112	c.rw.RLock()
1113	defer c.rw.RUnlock()
1114
1115	return c.rollupConstants, nil
1116}
1117
1118// RollupEventsByBlock returns the events in a block that happened in the Rollup Smart Contract
1119func (c *Client) RollupEventsByBlock(blockNum int64,
1120	blockHash *ethCommon.Hash) (*eth.RollupEvents, error) {
1121	c.rw.RLock()
1122	defer c.rw.RUnlock()
1123
1124	block, ok := c.blocks[blockNum]
1125	if !ok {
1126		return nil, tracerr.Wrap(fmt.Errorf("Block %v doesn't exist", blockNum))
1127	}
1128	if blockHash != nil && *blockHash != block.Eth.Hash {
1129		return nil, tracerr.Wrap(fmt.Errorf("Hash mismatch, requested %v got %v",
1130			blockHash, block.Eth.Hash))
1131	}
1132	return &block.Rollup.Events, nil
1133}
1134
1135// RollupEventInit returns the initialize event with its corresponding block number
1136func (c *Client) RollupEventInit() (*eth.RollupEventInitialize, int64, error) {
1137	vars := c.blocks[0].Rollup.Vars
1138	return &eth.RollupEventInitialize{
1139		ForgeL1L2BatchTimeout: uint8(vars.ForgeL1L2BatchTimeout),
1140		FeeAddToken:           vars.FeeAddToken,
1141		WithdrawalDelay:       vars.WithdrawalDelay,
1142	}, 1, nil
1143}
1144
1145// RollupForgeBatchArgs returns the arguments used in a ForgeBatch call in the Rollup Smart Contract in the given transaction
1146func (c *Client) RollupForgeBatchArgs(ethTxHash ethCommon.Hash, l1UserTxsLen uint16) (*eth.RollupForgeBatchArgs, *ethCommon.Address, error) {
1147	c.rw.RLock()
1148	defer c.rw.RUnlock()
1149
1150	batch, ok := c.forgeBatchArgs[ethTxHash]
1151	if !ok {
1152		return nil, nil, tracerr.Wrap(fmt.Errorf("transaction not found"))
1153	}
1154	return &batch.ForgeBatchArgs, &batch.Sender, nil
1155}
1156
1157//
1158// Auction
1159//
1160
1161// AuctionSetSlotDeadline is the interface to call the smart contract function
1162func (c *Client) AuctionSetSlotDeadline(newDeadline uint8) (tx *types.Transaction, err error) {
1163	c.rw.Lock()
1164	defer c.rw.Unlock()
1165	cpy := c.nextBlock().copy()
1166	defer func() { c.revertIfErr(err, cpy) }()
1167	if c.addr == nil {
1168		return nil, tracerr.Wrap(eth.ErrAccountNil)
1169	}
1170
1171	log.Error("TODO")
1172	return nil, tracerr.Wrap(errTODO)
1173}
1174
1175// AuctionGetSlotDeadline is the interface to call the smart contract function
1176func (c *Client) AuctionGetSlotDeadline() (uint8, error) {
1177	c.rw.RLock()
1178	defer c.rw.RUnlock()
1179
1180	log.Error("TODO")
1181	return 0, tracerr.Wrap(errTODO)
1182}
1183
1184// AuctionSetOpenAuctionSlots is the interface to call the smart contract function
1185func (c *Client) AuctionSetOpenAuctionSlots(newOpenAuctionSlots uint16) (tx *types.Transaction, err error) {
1186	c.rw.Lock()
1187	defer c.rw.Unlock()
1188	cpy := c.nextBlock().copy()
1189	defer func() { c.revertIfErr(err, cpy) }()
1190	if c.addr == nil {
1191		return nil, tracerr.Wrap(eth.ErrAccountNil)
1192	}
1193
1194	nextBlock := c.nextBlock()
1195	a := nextBlock.Auction
1196	a.Vars.OpenAuctionSlots = newOpenAuctionSlots
1197	a.Events.NewOpenAuctionSlots = append(a.Events.NewOpenAuctionSlots,
1198		eth.AuctionEventNewOpenAuctionSlots{NewOpenAuctionSlots: newOpenAuctionSlots})
1199
1200	return a.addTransaction(c.newTransaction("setOpenAuctionSlots", newOpenAuctionSlots)), nil
1201}
1202
1203// AuctionGetOpenAuctionSlots is the interface to call the smart contract function
1204func (c *Client) AuctionGetOpenAuctionSlots() (uint16, error) {
1205	c.rw.RLock()
1206	defer c.rw.RUnlock()
1207
1208	log.Error("TODO")
1209	return 0, tracerr.Wrap(errTODO)
1210}
1211
1212// AuctionSetClosedAuctionSlots is the interface to call the smart contract function
1213func (c *Client) AuctionSetClosedAuctionSlots(newClosedAuctionSlots uint16) (tx *types.Transaction, err error) {
1214	c.rw.Lock()
1215	defer c.rw.Unlock()
1216	cpy := c.nextBlock().copy()
1217	defer func() { c.revertIfErr(err, cpy) }()
1218	if c.addr == nil {
1219		return nil, tracerr.Wrap(eth.ErrAccountNil)
1220	}
1221
1222	log.Error("TODO")
1223	return nil, tracerr.Wrap(errTODO)
1224}
1225
1226// AuctionGetClosedAuctionSlots is the interface to call the smart contract function
1227func (c *Client) AuctionGetClosedAuctionSlots() (uint16, error) {
1228	c.rw.RLock()
1229	defer c.rw.RUnlock()
1230
1231	log.Error("TODO")
1232	return 0, tracerr.Wrap(errTODO)
1233}
1234
1235// AuctionSetOutbidding is the interface to call the smart contract function
1236func (c *Client) AuctionSetOutbidding(newOutbidding uint16) (tx *types.Transaction, err error) {
1237	c.rw.Lock()
1238	defer c.rw.Unlock()
1239	cpy := c.nextBlock().copy()
1240	defer func() { c.revertIfErr(err, cpy) }()
1241	if c.addr == nil {
1242		return nil, tracerr.Wrap(eth.ErrAccountNil)
1243	}
1244
1245	log.Error("TODO")
1246	return nil, tracerr.Wrap(errTODO)
1247}
1248
1249// AuctionGetOutbidding is the interface to call the smart contract function
1250func (c *Client) AuctionGetOutbidding() (uint16, error) {
1251	c.rw.RLock()
1252	defer c.rw.RUnlock()
1253
1254	log.Error("TODO")
1255	return 0, tracerr.Wrap(errTODO)
1256}
1257
1258// AuctionSetAllocationRatio is the interface to call the smart contract function
1259func (c *Client) AuctionSetAllocationRatio(newAllocationRatio [3]uint16) (tx *types.Transaction, err error) {
1260	c.rw.Lock()
1261	defer c.rw.Unlock()
1262	cpy := c.nextBlock().copy()
1263	defer func() { c.revertIfErr(err, cpy) }()
1264	if c.addr == nil {
1265		return nil, tracerr.Wrap(eth.ErrAccountNil)
1266	}
1267
1268	log.Error("TODO")
1269	return nil, tracerr.Wrap(errTODO)
1270}
1271
1272// AuctionGetAllocationRatio is the interface to call the smart contract function
1273func (c *Client) AuctionGetAllocationRatio() ([3]uint16, error) {
1274	c.rw.RLock()
1275	defer c.rw.RUnlock()
1276
1277	log.Error("TODO")
1278	return [3]uint16{}, tracerr.Wrap(errTODO)
1279}
1280
1281// AuctionSetDonationAddress is the interface to call the smart contract function
1282func (c *Client) AuctionSetDonationAddress(newDonationAddress ethCommon.Address) (tx *types.Transaction, err error) {
1283	c.rw.Lock()
1284	defer c.rw.Unlock()
1285	cpy := c.nextBlock().copy()
1286	defer func() { c.revertIfErr(err, cpy) }()
1287	if c.addr == nil {
1288		return nil, tracerr.Wrap(eth.ErrAccountNil)
1289	}
1290
1291	log.Error("TODO")
1292	return nil, tracerr.Wrap(errTODO)
1293}
1294
1295// AuctionGetDonationAddress is the interface to call the smart contract function
1296func (c *Client) AuctionGetDonationAddress() (*ethCommon.Address, error) {
1297	c.rw.RLock()
1298	defer c.rw.RUnlock()
1299
1300	log.Error("TODO")
1301	return nil, tracerr.Wrap(errTODO)
1302}
1303
1304// AuctionSetBootCoordinator is the interface to call the smart contract function
1305func (c *Client) AuctionSetBootCoordinator(newBootCoordinator ethCommon.Address, newBootCoordinatorURL string) (tx *types.Transaction, err error) {
1306	c.rw.Lock()
1307	defer c.rw.Unlock()
1308	cpy := c.nextBlock().copy()
1309	defer func() { c.revertIfErr(err, cpy) }()
1310	if c.addr == nil {
1311		return nil, tracerr.Wrap(eth.ErrAccountNil)
1312	}
1313
1314	log.Error("TODO")
1315	return nil, tracerr.Wrap(errTODO)
1316}
1317
1318// AuctionGetBootCoordinator is the interface to call the smart contract function
1319func (c *Client) AuctionGetBootCoordinator() (*ethCommon.Address, error) {
1320	c.rw.RLock()
1321	defer c.rw.RUnlock()
1322
1323	currentBlock := c.currentBlock()
1324	a := currentBlock.Auction
1325
1326	return &a.Vars.BootCoordinator, nil
1327}
1328
1329// AuctionChangeDefaultSlotSetBid is the interface to call the smart contract function
1330func (c *Client) AuctionChangeDefaultSlotSetBid(slotSet int64, newInitialMinBid *big.Int) (tx *types.Transaction, err error) {
1331	c.rw.Lock()
1332	defer c.rw.Unlock()
1333	cpy := c.nextBlock().copy()
1334	defer func() { c.revertIfErr(err, cpy) }()
1335	if c.addr == nil {
1336		return nil, tracerr.Wrap(eth.ErrAccountNil)
1337	}
1338
1339	log.Error("TODO")
1340	return nil, tracerr.Wrap(errTODO)
1341}
1342
1343// AuctionSetCoordinator is the interface to call the smart contract function
1344func (c *Client) AuctionSetCoordinator(forger ethCommon.Address, URL string) (tx *types.Transaction, err error) {
1345	c.rw.Lock()
1346	defer c.rw.Unlock()
1347	cpy := c.nextBlock().copy()
1348	defer func() { c.revertIfErr(err, cpy) }()
1349	if c.addr == nil {
1350		return nil, tracerr.Wrap(eth.ErrAccountNil)
1351	}
1352
1353	nextBlock := c.nextBlock()
1354	a := nextBlock.Auction
1355
1356	a.State.Coordinators[*c.addr] = &eth.Coordinator{
1357		Forger: forger,
1358		URL:    URL,
1359	}
1360
1361	a.Events.SetCoordinator = append(a.Events.SetCoordinator,
1362		eth.AuctionEventSetCoordinator{
1363			BidderAddress:  *c.addr,
1364			ForgerAddress:  forger,
1365			CoordinatorURL: URL,
1366		})
1367
1368	type data struct {
1369		BidderAddress ethCommon.Address
1370		ForgerAddress ethCommon.Address
1371		URL           string
1372	}
1373	return a.addTransaction(c.newTransaction("registercoordinator", data{*c.addr, forger, URL})), nil
1374}
1375
1376// AuctionIsRegisteredCoordinator is the interface to call the smart contract function
1377func (c *Client) AuctionIsRegisteredCoordinator(forgerAddress ethCommon.Address) (bool, error) {
1378	c.rw.RLock()
1379	defer c.rw.RUnlock()
1380
1381	log.Error("TODO")
1382	return false, tracerr.Wrap(errTODO)
1383}
1384
1385// AuctionUpdateCoordinatorInfo is the interface to call the smart contract function
1386func (c *Client) AuctionUpdateCoordinatorInfo(forgerAddress ethCommon.Address, newWithdrawAddress ethCommon.Address, newURL string) (tx *types.Transaction, err error) {
1387	c.rw.Lock()
1388	defer c.rw.Unlock()
1389	cpy := c.nextBlock().copy()
1390	defer func() { c.revertIfErr(err, cpy) }()
1391	if c.addr == nil {
1392		return nil, tracerr.Wrap(eth.ErrAccountNil)
1393	}
1394
1395	log.Error("TODO")
1396	return nil, tracerr.Wrap(errTODO)
1397}
1398
1399// AuctionGetSlotNumber is the interface to call the smart contract function
1400func (c *Client) AuctionGetSlotNumber(blockNum int64) (int64, error) {
1401	c.rw.RLock()
1402	defer c.rw.RUnlock()
1403
1404	currentBlock := c.currentBlock()
1405	a := currentBlock.Auction
1406	return a.getSlotNumber(blockNum), nil
1407}
1408
1409// AuctionGetCurrentSlotNumber is the interface to call the smart contract function
1410func (c *Client) AuctionGetCurrentSlotNumber() (int64, error) {
1411	c.rw.RLock()
1412	defer c.rw.RUnlock()
1413
1414	log.Error("TODO")
1415	return 0, tracerr.Wrap(errTODO)
1416}
1417
1418// AuctionGetMinBidBySlot is the interface to call the smart contract function
1419func (c *Client) AuctionGetMinBidBySlot(slot int64) (*big.Int, error) {
1420	c.rw.RLock()
1421	defer c.rw.RUnlock()
1422
1423	log.Error("TODO")
1424	return nil, tracerr.Wrap(errTODO)
1425}
1426
1427// AuctionGetDefaultSlotSetBid is the interface to call the smart contract function
1428func (c *Client) AuctionGetDefaultSlotSetBid(slotSet uint8) (*big.Int, error) {
1429	c.rw.RLock()
1430	defer c.rw.RUnlock()
1431
1432	log.Error("TODO")
1433	return nil, tracerr.Wrap(errTODO)
1434}
1435
1436// AuctionGetSlotSet is the interface to call the smart contract function
1437func (c *Client) AuctionGetSlotSet(slot int64) (*big.Int, error) {
1438	c.rw.RLock()
1439	defer c.rw.RUnlock()
1440
1441	log.Error("TODO")
1442	return nil, tracerr.Wrap(errTODO)
1443}
1444
1445// AuctionTokensReceived is the interface to call the smart contract function
1446// func (c *Client) AuctionTokensReceived(operator, from, to ethCommon.Address, amount *big.Int, userData, operatorData []byte) error {
1447// 	return errTODO
1448// }
1449
1450// AuctionBidSimple is a wrapper around AuctionBid that automatically sets `amount` and `deadline`.
1451func (c *Client) AuctionBidSimple(slot int64, bidAmount *big.Int) (tx *types.Transaction, err error) {
1452	return c.AuctionBid(bidAmount, slot, bidAmount, big.NewInt(99999)) //nolint:gomnd
1453}
1454
1455// AuctionBid is the interface to call the smart contract function.  This
1456// implementation behaves as if any address has infinite tokens.
1457func (c *Client) AuctionBid(amount *big.Int, slot int64, bidAmount *big.Int,
1458	deadline *big.Int) (tx *types.Transaction, err error) {
1459	c.rw.Lock()
1460	defer c.rw.Unlock()
1461	cpy := c.nextBlock().copy()
1462	defer func() { func() { c.revertIfErr(err, cpy) }() }()
1463	if c.addr == nil {
1464		return nil, tracerr.Wrap(eth.ErrAccountNil)
1465	}
1466
1467	nextBlock := c.nextBlock()
1468	a := nextBlock.Auction
1469
1470	if slot <= a.getCurrentSlotNumber()+int64(a.Vars.ClosedAuctionSlots) {
1471		return nil, tracerr.Wrap(errBidClosed)
1472	}
1473
1474	if slot > a.getCurrentSlotNumber()+int64(a.Vars.ClosedAuctionSlots)+int64(a.Vars.OpenAuctionSlots) {
1475		return nil, tracerr.Wrap(errBidNotOpen)
1476	}
1477
1478	minBid, err := a.getMinBidBySlot(slot)
1479	if err != nil {
1480		return nil, tracerr.Wrap(err)
1481	}
1482	if bidAmount.Cmp(minBid) == -1 {
1483		return nil, tracerr.Wrap(errBidBelowMin)
1484	}
1485
1486	if _, ok := a.State.Coordinators[*c.addr]; !ok {
1487		return nil, tracerr.Wrap(errCoordNotReg)
1488	}
1489
1490	slotState, ok := a.State.Slots[slot]
1491	if !ok {
1492		slotState = eth.NewSlotState()
1493		a.State.Slots[slot] = slotState
1494	}
1495	slotState.Bidder = *c.addr
1496	slotState.BidAmount = bidAmount
1497
1498	a.Events.NewBid = append(a.Events.NewBid,
1499		eth.AuctionEventNewBid{Slot: slot, BidAmount: bidAmount, Bidder: *c.addr})
1500
1501	type data struct {
1502		Slot      int64
1503		BidAmount *big.Int
1504		Bidder    ethCommon.Address
1505	}
1506	return a.addTransaction(c.newTransaction("bid", data{slot, bidAmount, *c.addr})), nil
1507}
1508
1509// AuctionMultiBid is the interface to call the smart contract function.  This
1510// implementation behaves as if any address has infinite tokens.
1511func (c *Client) AuctionMultiBid(amount *big.Int, startingSlot int64, endingSlot int64, slotSet [6]bool,
1512	maxBid, closedMinBid, deadline *big.Int) (tx *types.Transaction, err error) {
1513	c.rw.Lock()
1514	defer c.rw.Unlock()
1515	cpy := c.nextBlock().copy()
1516	defer func() { c.revertIfErr(err, cpy) }()
1517	if c.addr == nil {
1518		return nil, tracerr.Wrap(eth.ErrAccountNil)
1519	}
1520
1521	log.Error("TODO")
1522	return nil, tracerr.Wrap(errTODO)
1523}
1524
1525// AuctionCanForge is the interface to call the smart contract function
1526func (c *Client) AuctionCanForge(forger ethCommon.Address, blockNum int64) (bool, error) {
1527	c.rw.RLock()
1528	defer c.rw.RUnlock()
1529
1530	currentBlock := c.currentBlock()
1531	a := currentBlock.Auction
1532	return a.canForge(forger, blockNum)
1533}
1534
1535// AuctionForge is the interface to call the smart contract function
1536func (c *Client) AuctionForge(forger ethCommon.Address) (tx *types.Transaction, err error) {
1537	c.rw.Lock()
1538	defer c.rw.Unlock()
1539	cpy := c.nextBlock().copy()
1540	defer func() { c.revertIfErr(err, cpy) }()
1541	if c.addr == nil {
1542		return nil, tracerr.Wrap(eth.ErrAccountNil)
1543	}
1544
1545	log.Error("TODO")
1546	return nil, tracerr.Wrap(errTODO)
1547}
1548
1549// AuctionClaimHEZ is the interface to call the smart contract function
1550func (c *Client) AuctionClaimHEZ() (tx *types.Transaction, err error) {
1551	c.rw.Lock()
1552	defer c.rw.Unlock()
1553	cpy := c.nextBlock().copy()
1554	defer func() { c.revertIfErr(err, cpy) }()
1555	if c.addr == nil {
1556		return nil, tracerr.Wrap(eth.ErrAccountNil)
1557	}
1558
1559	log.Error("TODO")
1560	return nil, tracerr.Wrap(errTODO)
1561}
1562
1563// AuctionGetClaimableHEZ is the interface to call the smart contract function
1564func (c *Client) AuctionGetClaimableHEZ(bidder ethCommon.Address) (*big.Int, error) {
1565	c.rw.RLock()
1566	defer c.rw.RUnlock()
1567
1568	log.Error("TODO")
1569	return nil, tracerr.Wrap(errTODO)
1570}
1571
1572// AuctionConstants returns the Constants of the Auction Smart Contract
1573func (c *Client) AuctionConstants() (*common.AuctionConstants, error) {
1574	c.rw.RLock()
1575	defer c.rw.RUnlock()
1576
1577	return c.auctionConstants, nil
1578}
1579
1580// AuctionEventsByBlock returns the events in a block that happened in the Auction Smart Contract
1581func (c *Client) AuctionEventsByBlock(blockNum int64,
1582	blockHash *ethCommon.Hash) (*eth.AuctionEvents, error) {
1583	c.rw.RLock()
1584	defer c.rw.RUnlock()
1585
1586	block, ok := c.blocks[blockNum]
1587	if !ok {
1588		return nil, tracerr.Wrap(fmt.Errorf("Block %v doesn't exist", blockNum))
1589	}
1590	if blockHash != nil && *blockHash != block.Eth.Hash {
1591		return nil, tracerr.Wrap(fmt.Errorf("Hash mismatch, requested %v got %v",
1592			blockHash, block.Eth.Hash))
1593	}
1594	return &block.Auction.Events, nil
1595}
1596
1597// AuctionEventInit returns the initialize event with its corresponding block number
1598func (c *Client) AuctionEventInit() (*eth.AuctionEventInitialize, int64, error) {
1599	vars := c.blocks[0].Auction.Vars
1600	return &eth.AuctionEventInitialize{
1601		DonationAddress:        vars.DonationAddress,
1602		BootCoordinatorAddress: vars.BootCoordinator,
1603		BootCoordinatorURL:     vars.BootCoordinatorURL,
1604		Outbidding:             vars.Outbidding,
1605		SlotDeadline:           vars.SlotDeadline,
1606		ClosedAuctionSlots:     vars.ClosedAuctionSlots,
1607		OpenAuctionSlots:       vars.OpenAuctionSlots,
1608		AllocationRatio:        vars.AllocationRatio,
1609	}, 1, nil
1610}
1611
1612//
1613// WDelayer
1614//
1615
1616// WDelayerGetHermezGovernanceAddress is the interface to call the smart contract function
1617func (c *Client) WDelayerGetHermezGovernanceAddress() (*ethCommon.Address, error) {
1618	c.rw.RLock()
1619	defer c.rw.RUnlock()
1620
1621	log.Error("TODO")
1622	return nil, tracerr.Wrap(errTODO)
1623}
1624
1625// WDelayerTransferGovernance is the interface to call the smart contract function
1626func (c *Client) WDelayerTransferGovernance(newAddress ethCommon.Address) (tx *types.Transaction, err error) {
1627	c.rw.Lock()
1628	defer c.rw.Unlock()
1629	cpy := c.nextBlock().copy()
1630	defer func() { c.revertIfErr(err, cpy) }()
1631	if c.addr == nil {
1632		return nil, tracerr.Wrap(eth.ErrAccountNil)
1633	}
1634
1635	log.Error("TODO")
1636	return nil, tracerr.Wrap(errTODO)
1637}
1638
1639// WDelayerClaimGovernance is the interface to call the smart contract function
1640func (c *Client) WDelayerClaimGovernance() (tx *types.Transaction, err error) {
1641	c.rw.Lock()
1642	defer c.rw.Unlock()
1643	cpy := c.nextBlock().copy()
1644	defer func() { c.revertIfErr(err, cpy) }()
1645	if c.addr == nil {
1646		return nil, tracerr.Wrap(eth.ErrAccountNil)
1647	}
1648
1649	log.Error("TODO")
1650	return nil, tracerr.Wrap(errTODO)
1651}
1652
1653// WDelayerGetEmergencyCouncil is the interface to call the smart contract function
1654func (c *Client) WDelayerGetEmergencyCouncil() (*ethCommon.Address, error) {
1655	c.rw.RLock()
1656	defer c.rw.RUnlock()
1657
1658	log.Error("TODO")
1659	return nil, tracerr.Wrap(errTODO)
1660}
1661
1662// WDelayerTransferEmergencyCouncil is the interface to call the smart contract function
1663func (c *Client) WDelayerTransferEmergencyCouncil(newAddress ethCommon.Address) (tx *types.Transaction, err error) {
1664	c.rw.Lock()
1665	defer c.rw.Unlock()
1666	cpy := c.nextBlock().copy()
1667	defer func() { c.revertIfErr(err, cpy) }()
1668	if c.addr == nil {
1669		return nil, tracerr.Wrap(eth.ErrAccountNil)
1670	}
1671
1672	log.Error("TODO")
1673	return nil, tracerr.Wrap(errTODO)
1674}
1675
1676// WDelayerClaimEmergencyCouncil is the interface to call the smart contract function
1677func (c *Client) WDelayerClaimEmergencyCouncil() (tx *types.Transaction, err error) {
1678	c.rw.Lock()
1679	defer c.rw.Unlock()
1680	cpy := c.nextBlock().copy()
1681	defer func() { c.revertIfErr(err, cpy) }()
1682	if c.addr == nil {
1683		return nil, tracerr.Wrap(eth.ErrAccountNil)
1684	}
1685
1686	log.Error("TODO")
1687	return nil, tracerr.Wrap(errTODO)
1688}
1689
1690// WDelayerIsEmergencyMode is the interface to call the smart contract function
1691func (c *Client) WDelayerIsEmergencyMode() (bool, error) {
1692	c.rw.RLock()
1693	defer c.rw.RUnlock()
1694
1695	log.Error("TODO")
1696	return false, tracerr.Wrap(errTODO)
1697}
1698
1699// WDelayerGetWithdrawalDelay is the interface to call the smart contract function
1700func (c *Client) WDelayerGetWithdrawalDelay() (int64, error) {
1701	c.rw.RLock()
1702	defer c.rw.RUnlock()
1703
1704	log.Error("TODO")
1705	return 0, tracerr.Wrap(errTODO)
1706}
1707
1708// WDelayerGetEmergencyModeStartingTime is the interface to call the smart contract function
1709func (c *Client) WDelayerGetEmergencyModeStartingTime() (int64, error) {
1710	c.rw.RLock()
1711	defer c.rw.RUnlock()
1712
1713	log.Error("TODO")
1714	return 0, tracerr.Wrap(errTODO)
1715}
1716
1717// WDelayerEnableEmergencyMode is the interface to call the smart contract function
1718func (c *Client) WDelayerEnableEmergencyMode() (tx *types.Transaction, err error) {
1719	c.rw.Lock()
1720	defer c.rw.Unlock()
1721	cpy := c.nextBlock().copy()
1722	defer func() { c.revertIfErr(err, cpy) }()
1723	if c.addr == nil {
1724		return nil, tracerr.Wrap(eth.ErrAccountNil)
1725	}
1726
1727	log.Error("TODO")
1728	return nil, tracerr.Wrap(errTODO)
1729}
1730
1731// WDelayerChangeWithdrawalDelay is the interface to call the smart contract function
1732func (c *Client) WDelayerChangeWithdrawalDelay(newWithdrawalDelay uint64) (tx *types.Transaction, err error) {
1733	c.rw.Lock()
1734	defer c.rw.Unlock()
1735	cpy := c.nextBlock().copy()
1736	defer func() { c.revertIfErr(err, cpy) }()
1737	if c.addr == nil {
1738		return nil, tracerr.Wrap(eth.ErrAccountNil)
1739	}
1740
1741	nextBlock := c.nextBlock()
1742	w := nextBlock.WDelayer
1743	w.Vars.WithdrawalDelay = newWithdrawalDelay
1744	w.Events.NewWithdrawalDelay = append(w.Events.NewWithdrawalDelay,
1745		eth.WDelayerEventNewWithdrawalDelay{WithdrawalDelay: newWithdrawalDelay})
1746
1747	return w.addTransaction(c.newTransaction("changeWithdrawalDelay", newWithdrawalDelay)), nil
1748}
1749
1750// WDelayerDepositInfo is the interface to call the smart contract function
1751func (c *Client) WDelayerDepositInfo(owner, token ethCommon.Address) (eth.DepositState, error) {
1752	c.rw.RLock()
1753	defer c.rw.RUnlock()
1754
1755	log.Error("TODO")
1756	return eth.DepositState{}, tracerr.Wrap(errTODO)
1757}
1758
1759// WDelayerDeposit is the interface to call the smart contract function
1760func (c *Client) WDelayerDeposit(onwer, token ethCommon.Address, amount *big.Int) (tx *types.Transaction, err error) {
1761	c.rw.Lock()
1762	defer c.rw.Unlock()
1763	cpy := c.nextBlock().copy()
1764	defer func() { c.revertIfErr(err, cpy) }()
1765	if c.addr == nil {
1766		return nil, tracerr.Wrap(eth.ErrAccountNil)
1767	}
1768
1769	log.Error("TODO")
1770	return nil, tracerr.Wrap(errTODO)
1771}
1772
1773// WDelayerWithdrawal is the interface to call the smart contract function
1774func (c *Client) WDelayerWithdrawal(owner, token ethCommon.Address) (tx *types.Transaction, err error) {
1775	c.rw.Lock()
1776	defer c.rw.Unlock()
1777	cpy := c.nextBlock().copy()
1778	defer func() { c.revertIfErr(err, cpy) }()
1779	if c.addr == nil {
1780		return nil, tracerr.Wrap(eth.ErrAccountNil)
1781	}
1782
1783	log.Error("TODO")
1784	return nil, tracerr.Wrap(errTODO)
1785}
1786
1787// WDelayerEscapeHatchWithdrawal is the interface to call the smart contract function
1788func (c *Client) WDelayerEscapeHatchWithdrawal(to, token ethCommon.Address, amount *big.Int) (tx *types.Transaction, err error) {
1789	c.rw.Lock()
1790	defer c.rw.Unlock()
1791	cpy := c.nextBlock().copy()
1792	defer func() { c.revertIfErr(err, cpy) }()
1793	if c.addr == nil {
1794		return nil, tracerr.Wrap(eth.ErrAccountNil)
1795	}
1796
1797	log.Error("TODO")
1798	return nil, tracerr.Wrap(errTODO)
1799}
1800
1801// WDelayerEventsByBlock returns the events in a block that happened in the WDelayer Contract
1802func (c *Client) WDelayerEventsByBlock(blockNum int64,
1803	blockHash *ethCommon.Hash) (*eth.WDelayerEvents, error) {
1804	c.rw.RLock()
1805	defer c.rw.RUnlock()
1806
1807	block, ok := c.blocks[blockNum]
1808	if !ok {
1809		return nil, tracerr.Wrap(fmt.Errorf("Block %v doesn't exist", blockNum))
1810	}
1811	if blockHash != nil && *blockHash != block.Eth.Hash {
1812		return nil, tracerr.Wrap(fmt.Errorf("Hash mismatch, requested %v got %v",
1813			blockHash, block.Eth.Hash))
1814	}
1815	return &block.WDelayer.Events, nil
1816}
1817
1818// WDelayerConstants returns the Constants of the WDelayer Contract
1819func (c *Client) WDelayerConstants() (*common.WDelayerConstants, error) {
1820	c.rw.RLock()
1821	defer c.rw.RUnlock()
1822
1823	return c.wDelayerConstants, nil
1824}
1825
1826// WDelayerEventInit returns the initialize event with its corresponding block number
1827func (c *Client) WDelayerEventInit() (*eth.WDelayerEventInitialize, int64, error) {
1828	vars := c.blocks[0].WDelayer.Vars
1829	return &eth.WDelayerEventInitialize{
1830		InitialWithdrawalDelay:         vars.WithdrawalDelay,
1831		InitialHermezGovernanceAddress: vars.HermezGovernanceAddress,
1832		InitialEmergencyCouncil:        vars.EmergencyCouncilAddress,
1833	}, 1, nil
1834}
1835
1836// CtlAddBlocks adds block data to the smarts contracts.  The added blocks will
1837// appear as mined.  Not thread safe.
1838func (c *Client) CtlAddBlocks(blocks []common.BlockData) (err error) {
1839	// NOTE: We don't lock because internally we call public functions that
1840	// lock already.
1841	for _, block := range blocks {
1842		nextBlock := c.nextBlock()
1843		rollup := nextBlock.Rollup
1844		auction := nextBlock.Auction
1845		for _, token := range block.Rollup.AddedTokens {
1846			if _, err := c.RollupAddTokenSimple(token.EthAddr, rollup.Vars.FeeAddToken); err != nil {
1847				return tracerr.Wrap(err)
1848			}
1849		}
1850		for _, tx := range block.Rollup.L1UserTxs {
1851			c.CtlSetAddr(tx.FromEthAddr)
1852			if _, err := c.RollupL1UserTxERC20ETH(tx.FromBJJ, int64(tx.FromIdx), tx.DepositAmount, tx.Amount,
1853				uint32(tx.TokenID), int64(tx.ToIdx)); err != nil {
1854				return tracerr.Wrap(err)
1855			}
1856		}
1857		c.CtlSetAddr(auction.Vars.BootCoordinator)
1858		for _, batch := range block.Rollup.Batches {
1859			if _, err := c.RollupForgeBatch(&eth.RollupForgeBatchArgs{
1860				NewLastIdx:            batch.Batch.LastIdx,
1861				NewStRoot:             batch.Batch.StateRoot,
1862				NewExitRoot:           batch.Batch.ExitRoot,
1863				L1CoordinatorTxs:      batch.L1CoordinatorTxs,
1864				L1CoordinatorTxsAuths: [][]byte{}, // Intentionally empty
1865				L2TxsData:             batch.L2Txs,
1866				FeeIdxCoordinator:     batch.Batch.FeeIdxsCoordinator,
1867				// Circuit selector
1868				VerifierIdx: 0, // Intentionally empty
1869				L1Batch:     batch.L1Batch,
1870				ProofA:      [2]*big.Int{},    // Intentionally empty
1871				ProofB:      [2][2]*big.Int{}, // Intentionally empty
1872				ProofC:      [2]*big.Int{},    // Intentionally empty
1873			}, nil); err != nil {
1874				return tracerr.Wrap(err)
1875			}
1876		}
1877		// Mine block and sync
1878		c.CtlMineBlock()
1879	}
1880	return nil
1881}