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