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