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