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