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.PublicKeyComp, 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.PublicKeyComp,
 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.PublicKeyComp, 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	babyPubKeyDecomp, err := babyPubKey.Decompress()
 847	if err != nil {
 848		return nil, tracerr.Wrap(err)
 849	}
 850
 851	type data struct {
 852		BabyPubKey      *babyjub.PublicKey
 853		TokenID         uint32
 854		NumExitRoot     int64
 855		Idx             int64
 856		Amount          *big.Int
 857		Siblings        []*big.Int
 858		InstantWithdraw bool
 859	}
 860	tx = r.addTransaction(c.newTransaction("withdrawMerkleProof", data{
 861		BabyPubKey:      babyPubKeyDecomp,
 862		TokenID:         tokenID,
 863		NumExitRoot:     numExitRoot,
 864		Idx:             idx,
 865		Amount:          amount,
 866		Siblings:        siblings,
 867		InstantWithdraw: instantWithdraw,
 868	}))
 869	r.Events.Withdraw = append(r.Events.Withdraw, eth.RollupEventWithdraw{
 870		Idx:             uint64(idx),
 871		NumExitRoot:     uint64(numExitRoot),
 872		InstantWithdraw: instantWithdraw,
 873		TxHash:          tx.Hash(),
 874	})
 875
 876	if !instantWithdraw {
 877		w := nextBlock.WDelayer
 878		w.deposit(tx.Hash(), *c.addr, r.State.TokenList[int(tokenID)], amount)
 879	}
 880	return tx, nil
 881}
 882
 883type transactionData struct {
 884	Name  string
 885	Value interface{}
 886}
 887
 888func (c *Client) newTransaction(name string, value interface{}) *types.Transaction {
 889	eth := c.nextBlock().Eth
 890	nonce := eth.Nonce
 891	eth.Nonce++
 892	data, err := json.Marshal(transactionData{name, value})
 893	if err != nil {
 894		panic(err)
 895	}
 896	return types.NewTransaction(nonce, ethCommon.Address{}, nil, 0, nil,
 897		data)
 898}
 899
 900// RollupForgeBatch is the interface to call the smart contract function
 901func (c *Client) RollupForgeBatch(args *eth.RollupForgeBatchArgs) (tx *types.Transaction, err error) {
 902	c.rw.Lock()
 903	defer c.rw.Unlock()
 904	cpy := c.nextBlock().copy()
 905	defer func() { c.revertIfErr(err, cpy) }()
 906	if c.addr == nil {
 907		return nil, tracerr.Wrap(eth.ErrAccountNil)
 908	}
 909
 910	a := c.nextBlock().Auction
 911	ok, err := a.canForge(*c.addr, a.Eth.BlockNum)
 912	if err != nil {
 913		return nil, tracerr.Wrap(err)
 914	}
 915	if !ok {
 916		return nil, tracerr.Wrap(fmt.Errorf(common.AuctionErrMsgCannotForge))
 917	}
 918
 919	// TODO: Verify proof
 920
 921	// Auction
 922	err = a.forge(*c.addr)
 923	if err != nil {
 924		return nil, tracerr.Wrap(err)
 925	}
 926
 927	// TODO: If successful, store the tx in a successful array.
 928	// TODO: If failed, store the tx in a failed array.
 929	// TODO: Add method to move the tx to another block, reapply it there, and possibly go from successful to failed.
 930
 931	return c.addBatch(args)
 932}
 933
 934// CtlAddBatch adds forged batch to the Rollup, without checking any ZKProof
 935func (c *Client) CtlAddBatch(args *eth.RollupForgeBatchArgs) {
 936	c.rw.Lock()
 937	defer c.rw.Unlock()
 938
 939	if _, err := c.addBatch(args); err != nil {
 940		panic(err)
 941	}
 942}
 943
 944func (c *Client) addBatch(args *eth.RollupForgeBatchArgs) (*types.Transaction, error) {
 945	nextBlock := c.nextBlock()
 946	r := nextBlock.Rollup
 947	r.State.StateRoot = args.NewStRoot
 948	if args.NewLastIdx < r.State.CurrentIdx {
 949		return nil, tracerr.Wrap(fmt.Errorf("args.NewLastIdx < r.State.CurrentIdx"))
 950	}
 951	r.State.CurrentIdx = args.NewLastIdx
 952	r.State.ExitNullifierMap[int64(len(r.State.ExitRoots))] = make(map[int64]bool)
 953	r.State.ExitRoots = append(r.State.ExitRoots, args.NewExitRoot)
 954	if args.L1Batch {
 955		r.State.CurrentToForgeL1TxsNum++
 956		if r.State.CurrentToForgeL1TxsNum == r.State.LastToForgeL1TxsNum {
 957			r.State.LastToForgeL1TxsNum++
 958			r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum] = eth.NewQueueStruct()
 959		}
 960	}
 961	ethTx := r.addTransaction(c.newTransaction("forgebatch", args))
 962	c.forgeBatchArgsPending[ethTx.Hash()] = &batch{*args, *c.addr}
 963	r.Events.ForgeBatch = append(r.Events.ForgeBatch, eth.RollupEventForgeBatch{
 964		BatchNum:     int64(len(r.State.ExitRoots)) - 1,
 965		EthTxHash:    ethTx.Hash(),
 966		L1UserTxsLen: uint16(len(args.L1UserTxs)),
 967	})
 968
 969	return ethTx, nil
 970}
 971
 972// RollupAddTokenSimple is a wrapper around RollupAddToken that automatically
 973// sets `deadlie`.
 974func (c *Client) RollupAddTokenSimple(tokenAddress ethCommon.Address, feeAddToken *big.Int) (tx *types.Transaction, err error) {
 975	return c.RollupAddToken(tokenAddress, feeAddToken, big.NewInt(9999)) //nolint:gomnd
 976}
 977
 978// RollupAddToken is the interface to call the smart contract function
 979func (c *Client) RollupAddToken(tokenAddress ethCommon.Address, feeAddToken *big.Int,
 980	deadline *big.Int) (tx *types.Transaction, err error) {
 981	c.rw.Lock()
 982	defer c.rw.Unlock()
 983	cpy := c.nextBlock().copy()
 984	defer func() { c.revertIfErr(err, cpy) }()
 985	if c.addr == nil {
 986		return nil, tracerr.Wrap(eth.ErrAccountNil)
 987	}
 988
 989	nextBlock := c.nextBlock()
 990	r := nextBlock.Rollup
 991	if _, ok := r.State.TokenMap[tokenAddress]; ok {
 992		return nil, tracerr.Wrap(fmt.Errorf("Token %v already registered", tokenAddress))
 993	}
 994	if feeAddToken.Cmp(r.Vars.FeeAddToken) != 0 {
 995		return nil, tracerr.Wrap(fmt.Errorf("Expected fee: %v but got: %v", r.Vars.FeeAddToken, feeAddToken))
 996	}
 997
 998	r.State.TokenMap[tokenAddress] = true
 999	r.State.TokenList = append(r.State.TokenList, tokenAddress)
1000	r.Events.AddToken = append(r.Events.AddToken, eth.RollupEventAddToken{TokenAddress: tokenAddress,
1001		TokenID: uint32(len(r.State.TokenList) - 1)})
1002	return r.addTransaction(c.newTransaction("addtoken", tokenAddress)), nil
1003}
1004
1005// RollupGetCurrentTokens is the interface to call the smart contract function
1006func (c *Client) RollupGetCurrentTokens() (*big.Int, error) {
1007	c.rw.RLock()
1008	defer c.rw.RUnlock()
1009
1010	log.Error("TODO")
1011	return nil, tracerr.Wrap(errTODO)
1012}
1013
1014// RollupUpdateForgeL1L2BatchTimeout is the interface to call the smart contract function
1015func (c *Client) RollupUpdateForgeL1L2BatchTimeout(newForgeL1Timeout int64) (tx *types.Transaction, err error) {
1016	c.rw.Lock()
1017	defer c.rw.Unlock()
1018	cpy := c.nextBlock().copy()
1019	defer func() { c.revertIfErr(err, cpy) }()
1020	if c.addr == nil {
1021		return nil, tracerr.Wrap(eth.ErrAccountNil)
1022	}
1023
1024	nextBlock := c.nextBlock()
1025	r := nextBlock.Rollup
1026	r.Vars.ForgeL1L2BatchTimeout = newForgeL1Timeout
1027	r.Events.UpdateForgeL1L2BatchTimeout = append(r.Events.UpdateForgeL1L2BatchTimeout,
1028		eth.RollupEventUpdateForgeL1L2BatchTimeout{NewForgeL1L2BatchTimeout: newForgeL1Timeout})
1029
1030	return r.addTransaction(c.newTransaction("updateForgeL1L2BatchTimeout", newForgeL1Timeout)), nil
1031}
1032
1033// RollupUpdateFeeAddToken is the interface to call the smart contract function
1034func (c *Client) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (tx *types.Transaction, err error) {
1035	c.rw.Lock()
1036	defer c.rw.Unlock()
1037	cpy := c.nextBlock().copy()
1038	defer func() { c.revertIfErr(err, cpy) }()
1039	if c.addr == nil {
1040		return nil, tracerr.Wrap(eth.ErrAccountNil)
1041	}
1042
1043	log.Error("TODO")
1044	return nil, tracerr.Wrap(errTODO)
1045}
1046
1047// RollupUpdateTokensHEZ is the interface to call the smart contract function
1048// func (c *Client) RollupUpdateTokensHEZ(newTokenHEZ ethCommon.Address) (tx *types.Transaction, err error) {
1049// 	c.rw.Lock()
1050// 	defer c.rw.Unlock()
1051// 	cpy := c.nextBlock().copy()
1052// 	defer func() { c.revertIfErr(err, cpy) }()
1053//
1054// 	log.Error("TODO")
1055// 	return nil, errTODO
1056// }
1057
1058// RollupUpdateGovernance is the interface to call the smart contract function
1059// func (c *Client) RollupUpdateGovernance() (*types.Transaction, error) { // TODO (Not defined in Hermez.sol)
1060// 	return nil, errTODO
1061// }
1062
1063// RollupConstants returns the Constants of the Rollup Smart Contract
1064func (c *Client) RollupConstants() (*common.RollupConstants, error) {
1065	c.rw.RLock()
1066	defer c.rw.RUnlock()
1067
1068	return c.rollupConstants, nil
1069}
1070
1071// RollupEventsByBlock returns the events in a block that happened in the Rollup Smart Contract
1072func (c *Client) RollupEventsByBlock(blockNum int64) (*eth.RollupEvents, *ethCommon.Hash, error) {
1073	c.rw.RLock()
1074	defer c.rw.RUnlock()
1075
1076	block, ok := c.blocks[blockNum]
1077	if !ok {
1078		return nil, nil, tracerr.Wrap(fmt.Errorf("Block %v doesn't exist", blockNum))
1079	}
1080	return &block.Rollup.Events, &block.Eth.Hash, nil
1081}
1082
1083// RollupEventInit returns the initialize event with its corresponding block number
1084func (c *Client) RollupEventInit() (*eth.RollupEventInitialize, int64, error) {
1085	vars := c.blocks[0].Rollup.Vars
1086	return &eth.RollupEventInitialize{
1087		ForgeL1L2BatchTimeout: uint8(vars.ForgeL1L2BatchTimeout),
1088		FeeAddToken:           vars.FeeAddToken,
1089		WithdrawalDelay:       vars.WithdrawalDelay,
1090	}, 1, nil
1091}
1092
1093// RollupForgeBatchArgs returns the arguments used in a ForgeBatch call in the Rollup Smart Contract in the given transaction
1094func (c *Client) RollupForgeBatchArgs(ethTxHash ethCommon.Hash, l1UserTxsLen uint16) (*eth.RollupForgeBatchArgs, *ethCommon.Address, error) {
1095	c.rw.RLock()
1096	defer c.rw.RUnlock()
1097
1098	batch, ok := c.forgeBatchArgs[ethTxHash]
1099	if !ok {
1100		return nil, nil, tracerr.Wrap(fmt.Errorf("transaction not found"))
1101	}
1102	return &batch.ForgeBatchArgs, &batch.Sender, nil
1103}
1104
1105//
1106// Auction
1107//
1108
1109// AuctionSetSlotDeadline is the interface to call the smart contract function
1110func (c *Client) AuctionSetSlotDeadline(newDeadline uint8) (tx *types.Transaction, err error) {
1111	c.rw.Lock()
1112	defer c.rw.Unlock()
1113	cpy := c.nextBlock().copy()
1114	defer func() { c.revertIfErr(err, cpy) }()
1115	if c.addr == nil {
1116		return nil, tracerr.Wrap(eth.ErrAccountNil)
1117	}
1118
1119	log.Error("TODO")
1120	return nil, tracerr.Wrap(errTODO)
1121}
1122
1123// AuctionGetSlotDeadline is the interface to call the smart contract function
1124func (c *Client) AuctionGetSlotDeadline() (uint8, error) {
1125	c.rw.RLock()
1126	defer c.rw.RUnlock()
1127
1128	log.Error("TODO")
1129	return 0, tracerr.Wrap(errTODO)
1130}
1131
1132// AuctionSetOpenAuctionSlots is the interface to call the smart contract function
1133func (c *Client) AuctionSetOpenAuctionSlots(newOpenAuctionSlots uint16) (tx *types.Transaction, err error) {
1134	c.rw.Lock()
1135	defer c.rw.Unlock()
1136	cpy := c.nextBlock().copy()
1137	defer func() { c.revertIfErr(err, cpy) }()
1138	if c.addr == nil {
1139		return nil, tracerr.Wrap(eth.ErrAccountNil)
1140	}
1141
1142	nextBlock := c.nextBlock()
1143	a := nextBlock.Auction
1144	a.Vars.OpenAuctionSlots = newOpenAuctionSlots
1145	a.Events.NewOpenAuctionSlots = append(a.Events.NewOpenAuctionSlots,
1146		eth.AuctionEventNewOpenAuctionSlots{NewOpenAuctionSlots: newOpenAuctionSlots})
1147
1148	return a.addTransaction(c.newTransaction("setOpenAuctionSlots", newOpenAuctionSlots)), nil
1149}
1150
1151// AuctionGetOpenAuctionSlots is the interface to call the smart contract function
1152func (c *Client) AuctionGetOpenAuctionSlots() (uint16, error) {
1153	c.rw.RLock()
1154	defer c.rw.RUnlock()
1155
1156	log.Error("TODO")
1157	return 0, tracerr.Wrap(errTODO)
1158}
1159
1160// AuctionSetClosedAuctionSlots is the interface to call the smart contract function
1161func (c *Client) AuctionSetClosedAuctionSlots(newClosedAuctionSlots uint16) (tx *types.Transaction, err error) {
1162	c.rw.Lock()
1163	defer c.rw.Unlock()
1164	cpy := c.nextBlock().copy()
1165	defer func() { c.revertIfErr(err, cpy) }()
1166	if c.addr == nil {
1167		return nil, tracerr.Wrap(eth.ErrAccountNil)
1168	}
1169
1170	log.Error("TODO")
1171	return nil, tracerr.Wrap(errTODO)
1172}
1173
1174// AuctionGetClosedAuctionSlots is the interface to call the smart contract function
1175func (c *Client) AuctionGetClosedAuctionSlots() (uint16, error) {
1176	c.rw.RLock()
1177	defer c.rw.RUnlock()
1178
1179	log.Error("TODO")
1180	return 0, tracerr.Wrap(errTODO)
1181}
1182
1183// AuctionSetOutbidding is the interface to call the smart contract function
1184func (c *Client) AuctionSetOutbidding(newOutbidding uint16) (tx *types.Transaction, err error) {
1185	c.rw.Lock()
1186	defer c.rw.Unlock()
1187	cpy := c.nextBlock().copy()
1188	defer func() { c.revertIfErr(err, cpy) }()
1189	if c.addr == nil {
1190		return nil, tracerr.Wrap(eth.ErrAccountNil)
1191	}
1192
1193	log.Error("TODO")
1194	return nil, tracerr.Wrap(errTODO)
1195}
1196
1197// AuctionGetOutbidding is the interface to call the smart contract function
1198func (c *Client) AuctionGetOutbidding() (uint16, error) {
1199	c.rw.RLock()
1200	defer c.rw.RUnlock()
1201
1202	log.Error("TODO")
1203	return 0, tracerr.Wrap(errTODO)
1204}
1205
1206// AuctionSetAllocationRatio is the interface to call the smart contract function
1207func (c *Client) AuctionSetAllocationRatio(newAllocationRatio [3]uint16) (tx *types.Transaction, err error) {
1208	c.rw.Lock()
1209	defer c.rw.Unlock()
1210	cpy := c.nextBlock().copy()
1211	defer func() { c.revertIfErr(err, cpy) }()
1212	if c.addr == nil {
1213		return nil, tracerr.Wrap(eth.ErrAccountNil)
1214	}
1215
1216	log.Error("TODO")
1217	return nil, tracerr.Wrap(errTODO)
1218}
1219
1220// AuctionGetAllocationRatio is the interface to call the smart contract function
1221func (c *Client) AuctionGetAllocationRatio() ([3]uint16, error) {
1222	c.rw.RLock()
1223	defer c.rw.RUnlock()
1224
1225	log.Error("TODO")
1226	return [3]uint16{}, tracerr.Wrap(errTODO)
1227}
1228
1229// AuctionSetDonationAddress is the interface to call the smart contract function
1230func (c *Client) AuctionSetDonationAddress(newDonationAddress ethCommon.Address) (tx *types.Transaction, err error) {
1231	c.rw.Lock()
1232	defer c.rw.Unlock()
1233	cpy := c.nextBlock().copy()
1234	defer func() { c.revertIfErr(err, cpy) }()
1235	if c.addr == nil {
1236		return nil, tracerr.Wrap(eth.ErrAccountNil)
1237	}
1238
1239	log.Error("TODO")
1240	return nil, tracerr.Wrap(errTODO)
1241}
1242
1243// AuctionGetDonationAddress is the interface to call the smart contract function
1244func (c *Client) AuctionGetDonationAddress() (*ethCommon.Address, error) {
1245	c.rw.RLock()
1246	defer c.rw.RUnlock()
1247
1248	log.Error("TODO")
1249	return nil, tracerr.Wrap(errTODO)
1250}
1251
1252// AuctionSetBootCoordinator is the interface to call the smart contract function
1253func (c *Client) AuctionSetBootCoordinator(newBootCoordinator ethCommon.Address, newBootCoordinatorURL string) (tx *types.Transaction, err error) {
1254	c.rw.Lock()
1255	defer c.rw.Unlock()
1256	cpy := c.nextBlock().copy()
1257	defer func() { c.revertIfErr(err, cpy) }()
1258	if c.addr == nil {
1259		return nil, tracerr.Wrap(eth.ErrAccountNil)
1260	}
1261
1262	log.Error("TODO")
1263	return nil, tracerr.Wrap(errTODO)
1264}
1265
1266// AuctionGetBootCoordinator is the interface to call the smart contract function
1267func (c *Client) AuctionGetBootCoordinator() (*ethCommon.Address, error) {
1268	c.rw.RLock()
1269	defer c.rw.RUnlock()
1270
1271	currentBlock := c.currentBlock()
1272	a := currentBlock.Auction
1273
1274	return &a.Vars.BootCoordinator, nil
1275}
1276
1277// AuctionChangeDefaultSlotSetBid is the interface to call the smart contract function
1278func (c *Client) AuctionChangeDefaultSlotSetBid(slotSet int64, newInitialMinBid *big.Int) (tx *types.Transaction, err error) {
1279	c.rw.Lock()
1280	defer c.rw.Unlock()
1281	cpy := c.nextBlock().copy()
1282	defer func() { c.revertIfErr(err, cpy) }()
1283	if c.addr == nil {
1284		return nil, tracerr.Wrap(eth.ErrAccountNil)
1285	}
1286
1287	log.Error("TODO")
1288	return nil, tracerr.Wrap(errTODO)
1289}
1290
1291// AuctionSetCoordinator is the interface to call the smart contract function
1292func (c *Client) AuctionSetCoordinator(forger ethCommon.Address, URL string) (tx *types.Transaction, err error) {
1293	c.rw.Lock()
1294	defer c.rw.Unlock()
1295	cpy := c.nextBlock().copy()
1296	defer func() { c.revertIfErr(err, cpy) }()
1297	if c.addr == nil {
1298		return nil, tracerr.Wrap(eth.ErrAccountNil)
1299	}
1300
1301	nextBlock := c.nextBlock()
1302	a := nextBlock.Auction
1303
1304	a.State.Coordinators[*c.addr] = &eth.Coordinator{
1305		Forger: forger,
1306		URL:    URL,
1307	}
1308
1309	a.Events.SetCoordinator = append(a.Events.SetCoordinator,
1310		eth.AuctionEventSetCoordinator{
1311			BidderAddress:  *c.addr,
1312			ForgerAddress:  forger,
1313			CoordinatorURL: URL,
1314		})
1315
1316	type data struct {
1317		BidderAddress ethCommon.Address
1318		ForgerAddress ethCommon.Address
1319		URL           string
1320	}
1321	return a.addTransaction(c.newTransaction("registercoordinator", data{*c.addr, forger, URL})), nil
1322}
1323
1324// AuctionIsRegisteredCoordinator is the interface to call the smart contract function
1325func (c *Client) AuctionIsRegisteredCoordinator(forgerAddress ethCommon.Address) (bool, error) {
1326	c.rw.RLock()
1327	defer c.rw.RUnlock()
1328
1329	log.Error("TODO")
1330	return false, tracerr.Wrap(errTODO)
1331}
1332
1333// AuctionUpdateCoordinatorInfo is the interface to call the smart contract function
1334func (c *Client) AuctionUpdateCoordinatorInfo(forgerAddress ethCommon.Address, newWithdrawAddress ethCommon.Address, newURL string) (tx *types.Transaction, err error) {
1335	c.rw.Lock()
1336	defer c.rw.Unlock()
1337	cpy := c.nextBlock().copy()
1338	defer func() { c.revertIfErr(err, cpy) }()
1339	if c.addr == nil {
1340		return nil, tracerr.Wrap(eth.ErrAccountNil)
1341	}
1342
1343	log.Error("TODO")
1344	return nil, tracerr.Wrap(errTODO)
1345}
1346
1347// AuctionGetSlotNumber is the interface to call the smart contract function
1348func (c *Client) AuctionGetSlotNumber(blockNum int64) (int64, error) {
1349	c.rw.RLock()
1350	defer c.rw.RUnlock()
1351
1352	currentBlock := c.currentBlock()
1353	a := currentBlock.Auction
1354	return a.getSlotNumber(blockNum), nil
1355}
1356
1357// AuctionGetCurrentSlotNumber is the interface to call the smart contract function
1358func (c *Client) AuctionGetCurrentSlotNumber() (int64, error) {
1359	c.rw.RLock()
1360	defer c.rw.RUnlock()
1361
1362	log.Error("TODO")
1363	return 0, tracerr.Wrap(errTODO)
1364}
1365
1366// AuctionGetMinBidBySlot is the interface to call the smart contract function
1367func (c *Client) AuctionGetMinBidBySlot(slot int64) (*big.Int, error) {
1368	c.rw.RLock()
1369	defer c.rw.RUnlock()
1370
1371	log.Error("TODO")
1372	return nil, tracerr.Wrap(errTODO)
1373}
1374
1375// AuctionGetDefaultSlotSetBid is the interface to call the smart contract function
1376func (c *Client) AuctionGetDefaultSlotSetBid(slotSet uint8) (*big.Int, error) {
1377	c.rw.RLock()
1378	defer c.rw.RUnlock()
1379
1380	log.Error("TODO")
1381	return nil, tracerr.Wrap(errTODO)
1382}
1383
1384// AuctionGetSlotSet is the interface to call the smart contract function
1385func (c *Client) AuctionGetSlotSet(slot int64) (*big.Int, error) {
1386	c.rw.RLock()
1387	defer c.rw.RUnlock()
1388
1389	log.Error("TODO")
1390	return nil, tracerr.Wrap(errTODO)
1391}
1392
1393// AuctionTokensReceived is the interface to call the smart contract function
1394// func (c *Client) AuctionTokensReceived(operator, from, to ethCommon.Address, amount *big.Int, userData, operatorData []byte) error {
1395// 	return errTODO
1396// }
1397
1398// AuctionBidSimple is a wrapper around AuctionBid that automatically sets `amount` and `deadline`.
1399func (c *Client) AuctionBidSimple(slot int64, bidAmount *big.Int) (tx *types.Transaction, err error) {
1400	return c.AuctionBid(bidAmount, slot, bidAmount, big.NewInt(99999)) //nolint:gomnd
1401}
1402
1403// AuctionBid is the interface to call the smart contract function.  This
1404// implementation behaves as if any address has infinite tokens.
1405func (c *Client) AuctionBid(amount *big.Int, slot int64, bidAmount *big.Int,
1406	deadline *big.Int) (tx *types.Transaction, err error) {
1407	c.rw.Lock()
1408	defer c.rw.Unlock()
1409	cpy := c.nextBlock().copy()
1410	defer func() { func() { c.revertIfErr(err, cpy) }() }()
1411	if c.addr == nil {
1412		return nil, tracerr.Wrap(eth.ErrAccountNil)
1413	}
1414
1415	nextBlock := c.nextBlock()
1416	a := nextBlock.Auction
1417
1418	if slot < a.getCurrentSlotNumber()+int64(a.Vars.ClosedAuctionSlots) {
1419		return nil, tracerr.Wrap(errBidClosed)
1420	}
1421
1422	if slot >= a.getCurrentSlotNumber()+int64(a.Vars.ClosedAuctionSlots)+int64(a.Vars.OpenAuctionSlots) {
1423		return nil, tracerr.Wrap(errBidNotOpen)
1424	}
1425
1426	minBid, err := a.getMinBidBySlot(slot)
1427	if err != nil {
1428		return nil, tracerr.Wrap(err)
1429	}
1430	if bidAmount.Cmp(minBid) == -1 {
1431		return nil, tracerr.Wrap(errBidBelowMin)
1432	}
1433
1434	if _, ok := a.State.Coordinators[*c.addr]; !ok {
1435		return nil, tracerr.Wrap(errCoordNotReg)
1436	}
1437
1438	slotState, ok := a.State.Slots[slot]
1439	if !ok {
1440		slotState = eth.NewSlotState()
1441		a.State.Slots[slot] = slotState
1442	}
1443	slotState.Bidder = *c.addr
1444	slotState.BidAmount = bidAmount
1445
1446	a.Events.NewBid = append(a.Events.NewBid,
1447		eth.AuctionEventNewBid{Slot: slot, BidAmount: bidAmount, Bidder: *c.addr})
1448
1449	type data struct {
1450		Slot      int64
1451		BidAmount *big.Int
1452		Bidder    ethCommon.Address
1453	}
1454	return a.addTransaction(c.newTransaction("bid", data{slot, bidAmount, *c.addr})), nil
1455}
1456
1457// AuctionMultiBid is the interface to call the smart contract function.  This
1458// implementation behaves as if any address has infinite tokens.
1459func (c *Client) AuctionMultiBid(amount *big.Int, startingSlot int64, endingSlot int64, slotSet [6]bool,
1460	maxBid, closedMinBid, deadline *big.Int) (tx *types.Transaction, err error) {
1461	c.rw.Lock()
1462	defer c.rw.Unlock()
1463	cpy := c.nextBlock().copy()
1464	defer func() { c.revertIfErr(err, cpy) }()
1465	if c.addr == nil {
1466		return nil, tracerr.Wrap(eth.ErrAccountNil)
1467	}
1468
1469	log.Error("TODO")
1470	return nil, tracerr.Wrap(errTODO)
1471}
1472
1473// AuctionCanForge is the interface to call the smart contract function
1474func (c *Client) AuctionCanForge(forger ethCommon.Address, blockNum int64) (bool, error) {
1475	c.rw.RLock()
1476	defer c.rw.RUnlock()
1477
1478	currentBlock := c.currentBlock()
1479	a := currentBlock.Auction
1480	return a.canForge(forger, blockNum)
1481}
1482
1483// AuctionForge is the interface to call the smart contract function
1484func (c *Client) AuctionForge(forger ethCommon.Address) (tx *types.Transaction, err error) {
1485	c.rw.Lock()
1486	defer c.rw.Unlock()
1487	cpy := c.nextBlock().copy()
1488	defer func() { c.revertIfErr(err, cpy) }()
1489	if c.addr == nil {
1490		return nil, tracerr.Wrap(eth.ErrAccountNil)
1491	}
1492
1493	log.Error("TODO")
1494	return nil, tracerr.Wrap(errTODO)
1495}
1496
1497// AuctionClaimHEZ is the interface to call the smart contract function
1498func (c *Client) AuctionClaimHEZ() (tx *types.Transaction, err error) {
1499	c.rw.Lock()
1500	defer c.rw.Unlock()
1501	cpy := c.nextBlock().copy()
1502	defer func() { c.revertIfErr(err, cpy) }()
1503	if c.addr == nil {
1504		return nil, tracerr.Wrap(eth.ErrAccountNil)
1505	}
1506
1507	log.Error("TODO")
1508	return nil, tracerr.Wrap(errTODO)
1509}
1510
1511// AuctionGetClaimableHEZ is the interface to call the smart contract function
1512func (c *Client) AuctionGetClaimableHEZ(bidder ethCommon.Address) (*big.Int, error) {
1513	c.rw.RLock()
1514	defer c.rw.RUnlock()
1515
1516	log.Error("TODO")
1517	return nil, tracerr.Wrap(errTODO)
1518}
1519
1520// AuctionConstants returns the Constants of the Auction Smart Contract
1521func (c *Client) AuctionConstants() (*common.AuctionConstants, error) {
1522	c.rw.RLock()
1523	defer c.rw.RUnlock()
1524
1525	return c.auctionConstants, nil
1526}
1527
1528// AuctionEventsByBlock returns the events in a block that happened in the Auction Smart Contract
1529func (c *Client) AuctionEventsByBlock(blockNum int64) (*eth.AuctionEvents, *ethCommon.Hash, error) {
1530	c.rw.RLock()
1531	defer c.rw.RUnlock()
1532
1533	block, ok := c.blocks[blockNum]
1534	if !ok {
1535		return nil, nil, tracerr.Wrap(fmt.Errorf("Block %v doesn't exist", blockNum))
1536	}
1537	return &block.Auction.Events, &block.Eth.Hash, nil
1538}
1539
1540// AuctionEventInit returns the initialize event with its corresponding block number
1541func (c *Client) AuctionEventInit() (*eth.AuctionEventInitialize, int64, error) {
1542	vars := c.blocks[0].Auction.Vars
1543	return &eth.AuctionEventInitialize{
1544		DonationAddress:        vars.DonationAddress,
1545		BootCoordinatorAddress: vars.BootCoordinator,
1546		BootCoordinatorURL:     vars.BootCoordinatorURL,
1547		Outbidding:             vars.Outbidding,
1548		SlotDeadline:           vars.SlotDeadline,
1549		ClosedAuctionSlots:     vars.ClosedAuctionSlots,
1550		OpenAuctionSlots:       vars.OpenAuctionSlots,
1551		AllocationRatio:        vars.AllocationRatio,
1552	}, 1, nil
1553}
1554
1555//
1556// WDelayer
1557//
1558
1559// WDelayerGetHermezGovernanceAddress is the interface to call the smart contract function
1560func (c *Client) WDelayerGetHermezGovernanceAddress() (*ethCommon.Address, error) {
1561	c.rw.RLock()
1562	defer c.rw.RUnlock()
1563
1564	log.Error("TODO")
1565	return nil, tracerr.Wrap(errTODO)
1566}
1567
1568// WDelayerTransferGovernance is the interface to call the smart contract function
1569func (c *Client) WDelayerTransferGovernance(newAddress ethCommon.Address) (tx *types.Transaction, err error) {
1570	c.rw.Lock()
1571	defer c.rw.Unlock()
1572	cpy := c.nextBlock().copy()
1573	defer func() { c.revertIfErr(err, cpy) }()
1574	if c.addr == nil {
1575		return nil, tracerr.Wrap(eth.ErrAccountNil)
1576	}
1577
1578	log.Error("TODO")
1579	return nil, tracerr.Wrap(errTODO)
1580}
1581
1582// WDelayerClaimGovernance is the interface to call the smart contract function
1583func (c *Client) WDelayerClaimGovernance() (tx *types.Transaction, err error) {
1584	c.rw.Lock()
1585	defer c.rw.Unlock()
1586	cpy := c.nextBlock().copy()
1587	defer func() { c.revertIfErr(err, cpy) }()
1588	if c.addr == nil {
1589		return nil, tracerr.Wrap(eth.ErrAccountNil)
1590	}
1591
1592	log.Error("TODO")
1593	return nil, tracerr.Wrap(errTODO)
1594}
1595
1596// WDelayerGetEmergencyCouncil is the interface to call the smart contract function
1597func (c *Client) WDelayerGetEmergencyCouncil() (*ethCommon.Address, error) {
1598	c.rw.RLock()
1599	defer c.rw.RUnlock()
1600
1601	log.Error("TODO")
1602	return nil, tracerr.Wrap(errTODO)
1603}
1604
1605// WDelayerTransferEmergencyCouncil is the interface to call the smart contract function
1606func (c *Client) WDelayerTransferEmergencyCouncil(newAddress ethCommon.Address) (tx *types.Transaction, err error) {
1607	c.rw.Lock()
1608	defer c.rw.Unlock()
1609	cpy := c.nextBlock().copy()
1610	defer func() { c.revertIfErr(err, cpy) }()
1611	if c.addr == nil {
1612		return nil, tracerr.Wrap(eth.ErrAccountNil)
1613	}
1614
1615	log.Error("TODO")
1616	return nil, tracerr.Wrap(errTODO)
1617}
1618
1619// WDelayerClaimEmergencyCouncil is the interface to call the smart contract function
1620func (c *Client) WDelayerClaimEmergencyCouncil() (tx *types.Transaction, err error) {
1621	c.rw.Lock()
1622	defer c.rw.Unlock()
1623	cpy := c.nextBlock().copy()
1624	defer func() { c.revertIfErr(err, cpy) }()
1625	if c.addr == nil {
1626		return nil, tracerr.Wrap(eth.ErrAccountNil)
1627	}
1628
1629	log.Error("TODO")
1630	return nil, tracerr.Wrap(errTODO)
1631}
1632
1633// WDelayerIsEmergencyMode is the interface to call the smart contract function
1634func (c *Client) WDelayerIsEmergencyMode() (bool, error) {
1635	c.rw.RLock()
1636	defer c.rw.RUnlock()
1637
1638	log.Error("TODO")
1639	return false, tracerr.Wrap(errTODO)
1640}
1641
1642// WDelayerGetWithdrawalDelay is the interface to call the smart contract function
1643func (c *Client) WDelayerGetWithdrawalDelay() (int64, error) {
1644	c.rw.RLock()
1645	defer c.rw.RUnlock()
1646
1647	log.Error("TODO")
1648	return 0, tracerr.Wrap(errTODO)
1649}
1650
1651// WDelayerGetEmergencyModeStartingTime is the interface to call the smart contract function
1652func (c *Client) WDelayerGetEmergencyModeStartingTime() (int64, error) {
1653	c.rw.RLock()
1654	defer c.rw.RUnlock()
1655
1656	log.Error("TODO")
1657	return 0, tracerr.Wrap(errTODO)
1658}
1659
1660// WDelayerEnableEmergencyMode is the interface to call the smart contract function
1661func (c *Client) WDelayerEnableEmergencyMode() (tx *types.Transaction, err error) {
1662	c.rw.Lock()
1663	defer c.rw.Unlock()
1664	cpy := c.nextBlock().copy()
1665	defer func() { c.revertIfErr(err, cpy) }()
1666	if c.addr == nil {
1667		return nil, tracerr.Wrap(eth.ErrAccountNil)
1668	}
1669
1670	log.Error("TODO")
1671	return nil, tracerr.Wrap(errTODO)
1672}
1673
1674// WDelayerChangeWithdrawalDelay is the interface to call the smart contract function
1675func (c *Client) WDelayerChangeWithdrawalDelay(newWithdrawalDelay uint64) (tx *types.Transaction, err error) {
1676	c.rw.Lock()
1677	defer c.rw.Unlock()
1678	cpy := c.nextBlock().copy()
1679	defer func() { c.revertIfErr(err, cpy) }()
1680	if c.addr == nil {
1681		return nil, tracerr.Wrap(eth.ErrAccountNil)
1682	}
1683
1684	nextBlock := c.nextBlock()
1685	w := nextBlock.WDelayer
1686	w.Vars.WithdrawalDelay = newWithdrawalDelay
1687	w.Events.NewWithdrawalDelay = append(w.Events.NewWithdrawalDelay,
1688		eth.WDelayerEventNewWithdrawalDelay{WithdrawalDelay: newWithdrawalDelay})
1689
1690	return w.addTransaction(c.newTransaction("changeWithdrawalDelay", newWithdrawalDelay)), nil
1691}
1692
1693// WDelayerDepositInfo is the interface to call the smart contract function
1694func (c *Client) WDelayerDepositInfo(owner, token ethCommon.Address) (eth.DepositState, error) {
1695	c.rw.RLock()
1696	defer c.rw.RUnlock()
1697
1698	log.Error("TODO")
1699	return eth.DepositState{}, tracerr.Wrap(errTODO)
1700}
1701
1702// WDelayerDeposit is the interface to call the smart contract function
1703func (c *Client) WDelayerDeposit(onwer, token ethCommon.Address, amount *big.Int) (tx *types.Transaction, err error) {
1704	c.rw.Lock()
1705	defer c.rw.Unlock()
1706	cpy := c.nextBlock().copy()
1707	defer func() { c.revertIfErr(err, cpy) }()
1708	if c.addr == nil {
1709		return nil, tracerr.Wrap(eth.ErrAccountNil)
1710	}
1711
1712	log.Error("TODO")
1713	return nil, tracerr.Wrap(errTODO)
1714}
1715
1716// WDelayerWithdrawal is the interface to call the smart contract function
1717func (c *Client) WDelayerWithdrawal(owner, token ethCommon.Address) (tx *types.Transaction, err error) {
1718	c.rw.Lock()
1719	defer c.rw.Unlock()
1720	cpy := c.nextBlock().copy()
1721	defer func() { c.revertIfErr(err, cpy) }()
1722	if c.addr == nil {
1723		return nil, tracerr.Wrap(eth.ErrAccountNil)
1724	}
1725
1726	log.Error("TODO")
1727	return nil, tracerr.Wrap(errTODO)
1728}
1729
1730// WDelayerEscapeHatchWithdrawal is the interface to call the smart contract function
1731func (c *Client) WDelayerEscapeHatchWithdrawal(to, token ethCommon.Address, amount *big.Int) (tx *types.Transaction, err error) {
1732	c.rw.Lock()
1733	defer c.rw.Unlock()
1734	cpy := c.nextBlock().copy()
1735	defer func() { c.revertIfErr(err, cpy) }()
1736	if c.addr == nil {
1737		return nil, tracerr.Wrap(eth.ErrAccountNil)
1738	}
1739
1740	log.Error("TODO")
1741	return nil, tracerr.Wrap(errTODO)
1742}
1743
1744// WDelayerEventsByBlock returns the events in a block that happened in the WDelayer Contract
1745func (c *Client) WDelayerEventsByBlock(blockNum int64) (*eth.WDelayerEvents, *ethCommon.Hash, error) {
1746	c.rw.RLock()
1747	defer c.rw.RUnlock()
1748
1749	block, ok := c.blocks[blockNum]
1750	if !ok {
1751		return nil, nil, tracerr.Wrap(fmt.Errorf("Block %v doesn't exist", blockNum))
1752	}
1753	return &block.WDelayer.Events, &block.Eth.Hash, nil
1754}
1755
1756// WDelayerConstants returns the Constants of the WDelayer Contract
1757func (c *Client) WDelayerConstants() (*common.WDelayerConstants, error) {
1758	c.rw.RLock()
1759	defer c.rw.RUnlock()
1760
1761	return c.wDelayerConstants, nil
1762}
1763
1764// WDelayerEventInit returns the initialize event with its corresponding block number
1765func (c *Client) WDelayerEventInit() (*eth.WDelayerEventInitialize, int64, error) {
1766	vars := c.blocks[0].WDelayer.Vars
1767	return &eth.WDelayerEventInitialize{
1768		InitialWithdrawalDelay:         vars.WithdrawalDelay,
1769		InitialHermezGovernanceAddress: vars.HermezGovernanceAddress,
1770		InitialEmergencyCouncil:        vars.EmergencyCouncilAddress,
1771	}, 1, nil
1772}
1773
1774// CtlAddBlocks adds block data to the smarts contracts.  The added blocks will
1775// appear as mined.  Not thread safe.
1776func (c *Client) CtlAddBlocks(blocks []common.BlockData) (err error) {
1777	// NOTE: We don't lock because internally we call public functions that
1778	// lock already.
1779	for _, block := range blocks {
1780		nextBlock := c.nextBlock()
1781		rollup := nextBlock.Rollup
1782		auction := nextBlock.Auction
1783		for _, token := range block.Rollup.AddedTokens {
1784			if _, err := c.RollupAddTokenSimple(token.EthAddr, rollup.Vars.FeeAddToken); err != nil {
1785				return tracerr.Wrap(err)
1786			}
1787		}
1788		for _, tx := range block.Rollup.L1UserTxs {
1789			c.CtlSetAddr(tx.FromEthAddr)
1790			if _, err := c.RollupL1UserTxERC20ETH(tx.FromBJJ, int64(tx.FromIdx), tx.DepositAmount, tx.Amount,
1791				uint32(tx.TokenID), int64(tx.ToIdx)); err != nil {
1792				return tracerr.Wrap(err)
1793			}
1794		}
1795		c.CtlSetAddr(auction.Vars.BootCoordinator)
1796		for _, batch := range block.Rollup.Batches {
1797			if _, err := c.RollupForgeBatch(&eth.RollupForgeBatchArgs{
1798				NewLastIdx:            batch.Batch.LastIdx,
1799				NewStRoot:             batch.Batch.StateRoot,
1800				NewExitRoot:           batch.Batch.ExitRoot,
1801				L1CoordinatorTxs:      batch.L1CoordinatorTxs,
1802				L1CoordinatorTxsAuths: [][]byte{}, // Intentionally empty
1803				L2TxsData:             batch.L2Txs,
1804				FeeIdxCoordinator:     batch.Batch.FeeIdxsCoordinator,
1805				// Circuit selector
1806				VerifierIdx: 0, // Intentionally empty
1807				L1Batch:     batch.L1Batch,
1808				ProofA:      [2]*big.Int{},    // Intentionally empty
1809				ProofB:      [2][2]*big.Int{}, // Intentionally empty
1810				ProofC:      [2]*big.Int{},    // Intentionally empty
1811			}); err != nil {
1812				return tracerr.Wrap(err)
1813			}
1814		}
1815		// Mine block and sync
1816		c.CtlMineBlock()
1817	}
1818	return nil
1819}