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	ethCommon "github.com/ethereum/go-ethereum/common"
  14	"github.com/ethereum/go-ethereum/core/types"
  15	"github.com/hermeznetwork/hermez-node/common"
  16	"github.com/hermeznetwork/hermez-node/eth"
  17	"github.com/hermeznetwork/hermez-node/log"
  18	"github.com/hermeznetwork/hermez-node/utils"
  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// RollupBlock stores all the data related to the Rollup SC from an ethereum block
  33type RollupBlock struct {
  34	State     eth.RollupState
  35	Vars      eth.RollupVariables
  36	Events    eth.RollupEvents
  37	Constants *eth.RollupConstants
  38	Eth       *EthereumBlock
  39}
  40
  41var (
  42	errBidClosed   = fmt.Errorf("Bid has already been closed")
  43	errBidNotOpen  = fmt.Errorf("Bid has not been opened yet")
  44	errBidBelowMin = fmt.Errorf("Bid below minimum")
  45	errCoordNotReg = fmt.Errorf("Coordinator not registered")
  46)
  47
  48// AuctionBlock stores all the data related to the Auction SC from an ethereum block
  49type AuctionBlock struct {
  50	State     eth.AuctionState
  51	Vars      eth.AuctionVariables
  52	Events    eth.AuctionEvents
  53	Constants *eth.AuctionConstants
  54	Eth       *EthereumBlock
  55}
  56
  57func (a *AuctionBlock) getSlotNumber(blockNumber int64) int64 {
  58	if a.Eth.BlockNum >= a.Constants.GenesisBlockNum {
  59		return (blockNumber - a.Constants.GenesisBlockNum) / int64(a.Constants.BlocksPerSlot)
  60	}
  61	return 0
  62}
  63
  64func (a *AuctionBlock) getCurrentSlotNumber() int64 {
  65	return a.getSlotNumber(a.Eth.BlockNum)
  66}
  67
  68func (a *AuctionBlock) getSlotSet(slot int64) int64 {
  69	return slot % int64(len(a.Vars.DefaultSlotSetBid))
  70}
  71
  72func (a *AuctionBlock) getMinBidBySlot(slot int64) (*big.Int, error) {
  73	if slot < a.getCurrentSlotNumber()+int64(a.Vars.ClosedAuctionSlots) {
  74		return nil, errBidClosed
  75	}
  76
  77	slotSet := a.getSlotSet(slot)
  78	// fmt.Println("slot:", slot, "slotSet:", slotSet)
  79	var prevBid *big.Int
  80	slotState, ok := a.State.Slots[slot]
  81	if !ok {
  82		slotState = eth.NewSlotState()
  83		a.State.Slots[slot] = slotState
  84	}
  85	// If the bidAmount for a slot is 0 it means that it has not yet been bid, so the midBid will be the minimum
  86	// bid for the slot time plus the outbidding set, otherwise it will be the bidAmount plus the outbidding
  87	if slotState.BidAmount.Cmp(big.NewInt(0)) == 0 {
  88		prevBid = a.Vars.DefaultSlotSetBid[slotSet]
  89	} else {
  90		prevBid = slotState.BidAmount
  91	}
  92	outBid := new(big.Int).Set(prevBid)
  93	// fmt.Println("outBid:", outBid)
  94	outBid.Mul(outBid, big.NewInt(int64(a.Vars.Outbidding)))
  95	outBid.Div(outBid, big.NewInt(10000)) //nolint:gomnd
  96	outBid.Add(prevBid, outBid)
  97	// fmt.Println("minBid:", outBid)
  98	return outBid, nil
  99}
 100
 101func (a *AuctionBlock) forge(forger ethCommon.Address) error {
 102	if ok, err := a.canForge(forger, a.Eth.BlockNum); err != nil {
 103		return err
 104	} else if !ok {
 105		return fmt.Errorf("Can't forge")
 106	}
 107
 108	slotToForge := a.getSlotNumber(a.Eth.BlockNum)
 109	slotState, ok := a.State.Slots[slotToForge]
 110	if !ok {
 111		slotState = eth.NewSlotState()
 112		a.State.Slots[slotToForge] = slotState
 113	}
 114	slotState.Fulfilled = true
 115
 116	a.Events.NewForge = append(a.Events.NewForge, eth.AuctionEventNewForge{
 117		Forger:      forger,
 118		CurrentSlot: slotToForge,
 119	})
 120	return nil
 121}
 122
 123func (a *AuctionBlock) canForge(forger ethCommon.Address, blockNum int64) (bool, error) {
 124	if blockNum < a.Constants.GenesisBlockNum {
 125		return false, fmt.Errorf("Auction has not started yet")
 126	}
 127
 128	slotToForge := a.getSlotNumber(blockNum)
 129	// Get the relativeBlock to check if the slotDeadline has been exceeded
 130	relativeBlock := blockNum - (a.Constants.GenesisBlockNum + (slotToForge * int64(a.Constants.BlocksPerSlot)))
 131
 132	// If the closedMinBid is 0 it means that we have to take as minBid the one that is set for this slot set,
 133	// otherwise the one that has been saved will be used
 134	var minBid *big.Int
 135	slotState, ok := a.State.Slots[slotToForge]
 136	if !ok {
 137		slotState = eth.NewSlotState()
 138		a.State.Slots[slotToForge] = slotState
 139	}
 140	if slotState.ClosedMinBid.Cmp(big.NewInt(0)) == 0 {
 141		minBid = a.Vars.DefaultSlotSetBid[a.getSlotSet(slotToForge)]
 142	} else {
 143		minBid = slotState.ClosedMinBid
 144	}
 145
 146	if !slotState.Fulfilled && (relativeBlock >= int64(a.Vars.SlotDeadline)) {
 147		// if the relative block has exceeded the slotDeadline and no batch has been forged, anyone can forge
 148		return true, nil
 149	} else if slotState.Forger == forger && slotState.BidAmount.Cmp(minBid) >= 0 {
 150		// if forger bidAmount has exceeded the minBid it can forge
 151		return true, nil
 152	} else if a.Vars.BootCoordinator == forger && slotState.BidAmount.Cmp(minBid) == -1 {
 153		// if it's the boot coordinator and it has not been bid or the bid is below the minimum it can forge
 154		return true, nil
 155	} else {
 156		return false, nil
 157	}
 158}
 159
 160// EthereumBlock stores all the generic data related to the an ethereum block
 161type EthereumBlock struct {
 162	BlockNum   int64
 163	Time       int64
 164	Hash       ethCommon.Hash
 165	ParentHash ethCommon.Hash
 166	// state      ethState
 167}
 168
 169// Block represents a ethereum block
 170type Block struct {
 171	Rollup  *RollupBlock
 172	Auction *AuctionBlock
 173	Eth     *EthereumBlock
 174}
 175
 176func (b *Block) copy() *Block {
 177	bCopyRaw, err := copystructure.Copy(b)
 178	if err != nil {
 179		panic(err)
 180	}
 181	bCopy := bCopyRaw.(*Block)
 182	return bCopy
 183}
 184
 185// Next prepares the successive block.
 186func (b *Block) Next() *Block {
 187	blockNext := b.copy()
 188	blockNext.Rollup.Events = eth.NewRollupEvents()
 189	blockNext.Auction.Events = eth.NewAuctionEvents()
 190	blockNext.Eth = &EthereumBlock{
 191		BlockNum:   b.Eth.BlockNum + 1,
 192		ParentHash: b.Eth.Hash,
 193	}
 194	blockNext.Rollup.Constants = b.Rollup.Constants
 195	blockNext.Auction.Constants = b.Auction.Constants
 196	blockNext.Rollup.Eth = blockNext.Eth
 197	blockNext.Auction.Eth = blockNext.Eth
 198	return blockNext
 199}
 200
 201// ClientSetup is used to initialize the constants of the Smart Contracts and
 202// other details of the test Client
 203type ClientSetup struct {
 204	RollupConstants  *eth.RollupConstants
 205	RollupVariables  *eth.RollupVariables
 206	AuctionConstants *eth.AuctionConstants
 207	AuctionVariables *eth.AuctionVariables
 208	VerifyProof      bool
 209}
 210
 211// NewClientSetupExample returns a ClientSetup example with hardcoded realistic values.
 212//nolint:gomnd
 213func NewClientSetupExample() *ClientSetup {
 214	rfield, ok := new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
 215	if !ok {
 216		panic("bad rfield")
 217	}
 218	initialMinimalBidding, ok := new(big.Int).SetString("10000000000000000000", 10) // 10 * (1e18)
 219	if !ok {
 220		panic("bad initialMinimalBidding")
 221	}
 222	tokenHEZ := ethCommon.HexToAddress("0x51D243D62852Bba334DD5cc33f242BAc8c698074")
 223	governanceAddress := ethCommon.HexToAddress("0x688EfD95BA4391f93717CF02A9aED9DBD2855cDd")
 224	rollupConstants := &eth.RollupConstants{
 225		MaxAmountDeposit:   new(big.Int).Lsh(big.NewInt(1), 128),
 226		MaxAmountL2:        new(big.Int).Lsh(big.NewInt(1), 192),
 227		MaxTokens:          0xffffffff,
 228		MaxL1Tx:            256,
 229		MaxL1UserTx:        128,
 230		Rfield:             rfield,
 231		L1CoordinatorBytes: 101,
 232		L1UserBytes:        68,
 233		L2Bytes:            11,
 234	}
 235	rollupVariables := &eth.RollupVariables{
 236		MaxTxVerifiers:     []int{512, 1024, 2048},
 237		TokenHEZ:           tokenHEZ,
 238		GovernanceAddress:  governanceAddress,
 239		SafetyBot:          ethCommon.HexToAddress("0x84d8B79E84fe87B14ad61A554e740f6736bF4c20"),
 240		ConsensusContract:  ethCommon.HexToAddress("0x8E442975805fb1908f43050c9C1A522cB0e28D7b"),
 241		WithdrawalContract: ethCommon.HexToAddress("0x5CB7979cBdbf65719BEE92e4D15b7b7Ed3D79114"),
 242		FeeAddToken:        big.NewInt(11),
 243		ForgeL1Timeout:     9,
 244		FeeL1UserTx:        big.NewInt(22),
 245	}
 246	auctionConstants := &eth.AuctionConstants{
 247		DelayGenesis:          0,
 248		BlocksPerSlot:         40,
 249		InitialMinimalBidding: initialMinimalBidding,
 250		GenesisBlockNum:       0,
 251		GovernanceAddress:     governanceAddress,
 252		TokenHEZ:              tokenHEZ,
 253		HermezRollup:          ethCommon.HexToAddress("0x474B6e29852257491cf283EfB1A9C61eBFe48369"),
 254	}
 255	auctionVariables := &eth.AuctionVariables{
 256		DonationAddress: ethCommon.HexToAddress("0x61Ed87CF0A1496b49A420DA6D84B58196b98f2e7"),
 257		BootCoordinator: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"),
 258		DefaultSlotSetBid: [6]*big.Int{
 259			big.NewInt(1000), big.NewInt(1100), big.NewInt(1200),
 260			big.NewInt(1300), big.NewInt(1400), big.NewInt(1500)},
 261		ClosedAuctionSlots: 2,
 262		OpenAuctionSlots:   4320,
 263		AllocationRatio:    [3]uint16{4000, 4000, 2000},
 264		Outbidding:         1000,
 265		SlotDeadline:       20,
 266	}
 267	return &ClientSetup{
 268		RollupConstants:  rollupConstants,
 269		RollupVariables:  rollupVariables,
 270		AuctionConstants: auctionConstants,
 271		AuctionVariables: auctionVariables,
 272	}
 273}
 274
 275// Timer is an interface to simulate a source of time, useful to advance time
 276// virtually.
 277type Timer interface {
 278	Time() int64
 279}
 280
 281// type forgeBatchArgs struct {
 282// 	ethTx     *types.Transaction
 283// 	blockNum  int64
 284// 	blockHash ethCommon.Hash
 285// }
 286
 287// Client implements the eth.ClientInterface interface, allowing to manipulate the
 288// values for testing, working with deterministic results.
 289type Client struct {
 290	rw               *sync.RWMutex
 291	log              bool
 292	addr             ethCommon.Address
 293	rollupConstants  *eth.RollupConstants
 294	auctionConstants *eth.AuctionConstants
 295	blocks           map[int64]*Block
 296	// state            state
 297	blockNum    int64 // last mined block num
 298	maxBlockNum int64 // highest block num calculated
 299	timer       Timer
 300	hasher      hasher
 301
 302	forgeBatchArgsPending map[ethCommon.Hash]*eth.RollupForgeBatchArgs
 303	forgeBatchArgs        map[ethCommon.Hash]*eth.RollupForgeBatchArgs
 304}
 305
 306// NewClient returns a new test Client that implements the eth.IClient
 307// interface, at the given initialBlockNumber.
 308func NewClient(l bool, timer Timer, addr ethCommon.Address, setup *ClientSetup) *Client {
 309	blocks := make(map[int64]*Block)
 310	blockNum := int64(0)
 311
 312	hasher := hasher{}
 313	// Add ethereum genesis block
 314	mapL1TxQueue := make(map[int64]*eth.QueueStruct)
 315	mapL1TxQueue[0] = eth.NewQueueStruct()
 316	mapL1TxQueue[1] = eth.NewQueueStruct()
 317	blockCurrent := Block{
 318		Rollup: &RollupBlock{
 319			State: eth.RollupState{
 320				StateRoot:              big.NewInt(0),
 321				ExitRoots:              make([]*big.Int, 0),
 322				ExitNullifierMap:       make(map[[256 / 8]byte]bool),
 323				TokenList:              make([]ethCommon.Address, 0),
 324				TokenMap:               make(map[ethCommon.Address]bool),
 325				MapL1TxQueue:           mapL1TxQueue,
 326				LastL1L2Batch:          0,
 327				CurrentToForgeL1TxsNum: 0,
 328				LastToForgeL1TxsNum:    1,
 329				CurrentIdx:             0,
 330			},
 331			Vars:      *setup.RollupVariables,
 332			Events:    eth.NewRollupEvents(),
 333			Constants: setup.RollupConstants,
 334		},
 335		Auction: &AuctionBlock{
 336			State: eth.AuctionState{
 337				Slots:           make(map[int64]*eth.SlotState),
 338				PendingBalances: make(map[ethCommon.Address]*big.Int),
 339				Coordinators:    make(map[ethCommon.Address]*eth.Coordinator),
 340			},
 341			Vars:      *setup.AuctionVariables,
 342			Events:    eth.NewAuctionEvents(),
 343			Constants: setup.AuctionConstants,
 344		},
 345		Eth: &EthereumBlock{
 346			BlockNum:   blockNum,
 347			Time:       timer.Time(),
 348			Hash:       hasher.Next(),
 349			ParentHash: ethCommon.Hash{},
 350		},
 351	}
 352	blockCurrent.Rollup.Eth = blockCurrent.Eth
 353	blockCurrent.Auction.Eth = blockCurrent.Eth
 354	blocks[blockNum] = &blockCurrent
 355	blockNext := blockCurrent.Next()
 356	blocks[blockNum+1] = blockNext
 357
 358	return &Client{
 359		rw:                    &sync.RWMutex{},
 360		log:                   l,
 361		addr:                  addr,
 362		rollupConstants:       setup.RollupConstants,
 363		auctionConstants:      setup.AuctionConstants,
 364		blocks:                blocks,
 365		timer:                 timer,
 366		hasher:                hasher,
 367		forgeBatchArgsPending: make(map[ethCommon.Hash]*eth.RollupForgeBatchArgs),
 368		forgeBatchArgs:        make(map[ethCommon.Hash]*eth.RollupForgeBatchArgs),
 369	}
 370}
 371
 372//
 373// Mock Control
 374//
 375
 376func (c *Client) setNextBlock(block *Block) {
 377	c.blocks[c.blockNum+1] = block
 378}
 379
 380func (c *Client) revertIfErr(err error, block *Block) {
 381	if err != nil {
 382		log.Infow("TestClient revert", "block", block.Eth.BlockNum, "err", err)
 383		c.setNextBlock(block)
 384	}
 385}
 386
 387// Debugf calls log.Debugf if c.log is true
 388func (c *Client) Debugf(template string, args ...interface{}) {
 389	if c.log {
 390		log.Debugf(template, args...)
 391	}
 392}
 393
 394// Debugw calls log.Debugw if c.log is true
 395func (c *Client) Debugw(template string, kv ...interface{}) {
 396	if c.log {
 397		log.Debugw(template, kv...)
 398	}
 399}
 400
 401type hasher struct {
 402	counter uint64
 403}
 404
 405// Next returns the next hash
 406func (h *hasher) Next() ethCommon.Hash {
 407	var hash ethCommon.Hash
 408	binary.LittleEndian.PutUint64(hash[:], h.counter)
 409	h.counter++
 410	return hash
 411}
 412
 413func (c *Client) nextBlock() *Block {
 414	return c.blocks[c.blockNum+1]
 415}
 416
 417func (c *Client) currentBlock() *Block {
 418	return c.blocks[c.blockNum]
 419}
 420
 421// CtlMineBlock moves one block forward
 422func (c *Client) CtlMineBlock() {
 423	c.rw.Lock()
 424	defer c.rw.Unlock()
 425
 426	blockCurrent := c.nextBlock()
 427	c.blockNum++
 428	c.maxBlockNum = c.blockNum
 429	blockCurrent.Eth.Time = c.timer.Time()
 430	blockCurrent.Eth.Hash = c.hasher.Next()
 431	for ethTxHash, forgeBatchArgs := range c.forgeBatchArgsPending {
 432		c.forgeBatchArgs[ethTxHash] = forgeBatchArgs
 433	}
 434	c.forgeBatchArgsPending = make(map[ethCommon.Hash]*eth.RollupForgeBatchArgs)
 435
 436	blockNext := blockCurrent.Next()
 437	c.blocks[c.blockNum+1] = blockNext
 438	c.Debugw("TestClient mined block", "blockNum", c.blockNum)
 439}
 440
 441// CtlRollback discards the last mined block.  Use this to replace a mined
 442// block to simulate reorgs.
 443func (c *Client) CtlRollback() {
 444	c.rw.Lock()
 445	defer c.rw.Unlock()
 446
 447	if c.blockNum == 0 {
 448		panic("Can't rollback at blockNum = 0")
 449	}
 450	delete(c.blocks, c.blockNum+1) // delete next block
 451	delete(c.blocks, c.blockNum)   // delete current block
 452	c.blockNum--
 453	blockCurrent := c.blocks[c.blockNum]
 454	blockNext := blockCurrent.Next()
 455	c.blocks[c.blockNum+1] = blockNext
 456}
 457
 458//
 459// Ethereum
 460//
 461
 462// EthCurrentBlock returns the current blockNum
 463func (c *Client) EthCurrentBlock() (int64, error) {
 464	c.rw.RLock()
 465	defer c.rw.RUnlock()
 466
 467	if c.blockNum < c.maxBlockNum {
 468		panic("blockNum has decreased.  " +
 469			"After a rollback you must mine to reach the same or higher blockNum")
 470	}
 471	return c.blockNum, nil
 472}
 473
 474// func newHeader(number *big.Int) *types.Header {
 475// 	return &types.Header{
 476// 		Number: number,
 477// 		Time:   uint64(number.Int64()),
 478// 	}
 479// }
 480
 481// EthHeaderByNumber returns the *types.Header for the given block number in a
 482// deterministic way.
 483// func (c *Client) EthHeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
 484// 	return newHeader(number), nil
 485// }
 486
 487// EthBlockByNumber returns the *common.Block for the given block number in a
 488// deterministic way.
 489func (c *Client) EthBlockByNumber(ctx context.Context, blockNum int64) (*common.Block, error) {
 490	c.rw.RLock()
 491	defer c.rw.RUnlock()
 492
 493	block, ok := c.blocks[blockNum]
 494	if !ok {
 495		return nil, fmt.Errorf("block not found")
 496	}
 497	return &common.Block{
 498		EthBlockNum: blockNum,
 499		Timestamp:   time.Unix(block.Eth.Time, 0),
 500		Hash:        block.Eth.Hash,
 501		ParentHash:  block.Eth.ParentHash,
 502	}, nil
 503}
 504
 505var errTODO = fmt.Errorf("TODO: Not implemented yet")
 506
 507//
 508// Rollup
 509//
 510
 511// CtlAddL1TxUser adds an L1TxUser to the L1UserTxs queue of the Rollup
 512func (c *Client) CtlAddL1TxUser(l1Tx *common.L1Tx) {
 513	c.rw.Lock()
 514	defer c.rw.Unlock()
 515
 516	nextBlock := c.nextBlock()
 517	r := nextBlock.Rollup
 518	queue := r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum]
 519	if len(queue.L1TxQueue) >= c.rollupConstants.MaxL1UserTx {
 520		r.State.LastToForgeL1TxsNum++
 521		r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum] = eth.NewQueueStruct()
 522		queue = r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum]
 523	}
 524	if int64(l1Tx.FromIdx) > r.State.CurrentIdx {
 525		panic("l1Tx.FromIdx > r.State.CurrentIdx")
 526	}
 527	if int(l1Tx.TokenID)+1 > len(r.State.TokenList) {
 528		panic("l1Tx.TokenID + 1 > len(r.State.TokenList)")
 529	}
 530	queue.L1TxQueue = append(queue.L1TxQueue, *l1Tx)
 531	r.Events.L1UserTx = append(r.Events.L1UserTx, eth.RollupEventL1UserTx{L1Tx: *l1Tx})
 532}
 533
 534type transactionData struct {
 535	Name  string
 536	Value interface{}
 537}
 538
 539func (c *Client) newTransaction(name string, value interface{}) *types.Transaction {
 540	data, err := json.Marshal(transactionData{name, value})
 541	if err != nil {
 542		panic(err)
 543	}
 544	return types.NewTransaction(0, ethCommon.Address{}, nil, 0, nil,
 545		data)
 546}
 547
 548// RollupForgeBatch is the interface to call the smart contract function
 549func (c *Client) RollupForgeBatch(args *eth.RollupForgeBatchArgs) (tx *types.Transaction, err error) {
 550	c.rw.Lock()
 551	defer c.rw.Unlock()
 552	cpy := c.nextBlock().copy()
 553	defer func() { c.revertIfErr(err, cpy) }()
 554
 555	a := c.nextBlock().Auction
 556	ok, err := a.canForge(c.addr, a.Eth.BlockNum)
 557	if err != nil {
 558		return nil, err
 559	}
 560	if !ok {
 561		return nil, fmt.Errorf("incorrect slot")
 562	}
 563
 564	// TODO: Verify proof
 565
 566	// Auction
 567	err = a.forge(c.addr)
 568	if err != nil {
 569		return nil, err
 570	}
 571
 572	return c.addBatch(args)
 573}
 574
 575// CtlAddBatch adds forged batch to the Rollup, without checking any ZKProof
 576func (c *Client) CtlAddBatch(args *eth.RollupForgeBatchArgs) {
 577	c.rw.Lock()
 578	defer c.rw.Unlock()
 579
 580	if _, err := c.addBatch(args); err != nil {
 581		panic(err)
 582	}
 583}
 584
 585func (c *Client) addBatch(args *eth.RollupForgeBatchArgs) (*types.Transaction, error) {
 586	nextBlock := c.nextBlock()
 587	r := nextBlock.Rollup
 588	r.State.StateRoot = args.NewStRoot
 589	if args.NewLastIdx < r.State.CurrentIdx {
 590		return nil, fmt.Errorf("args.NewLastIdx < r.State.CurrentIdx")
 591	}
 592	r.State.CurrentIdx = args.NewLastIdx
 593	r.State.ExitRoots = append(r.State.ExitRoots, args.NewExitRoot)
 594	if args.L1Batch {
 595		r.State.CurrentToForgeL1TxsNum++
 596		if r.State.CurrentToForgeL1TxsNum == r.State.LastToForgeL1TxsNum {
 597			r.State.LastToForgeL1TxsNum++
 598			r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum] = eth.NewQueueStruct()
 599		}
 600	}
 601	ethTx := c.newTransaction("forgebatch", args)
 602	c.forgeBatchArgsPending[ethTx.Hash()] = args
 603	r.Events.ForgeBatch = append(r.Events.ForgeBatch, eth.RollupEventForgeBatch{
 604		BatchNum:  int64(len(r.State.ExitRoots)),
 605		EthTxHash: ethTx.Hash(),
 606	})
 607
 608	return ethTx, nil
 609}
 610
 611// RollupAddToken is the interface to call the smart contract function
 612func (c *Client) RollupAddToken(tokenAddress ethCommon.Address) (tx *types.Transaction, err error) {
 613	c.rw.Lock()
 614	defer c.rw.Unlock()
 615	cpy := c.nextBlock().copy()
 616	defer func() { c.revertIfErr(err, cpy) }()
 617
 618	nextBlock := c.nextBlock()
 619	r := nextBlock.Rollup
 620	if _, ok := r.State.TokenMap[tokenAddress]; ok {
 621		return nil, fmt.Errorf("Token %v already registered", tokenAddress)
 622	}
 623
 624	r.State.TokenMap[tokenAddress] = true
 625	r.State.TokenList = append(r.State.TokenList, tokenAddress)
 626	r.Events.AddToken = append(r.Events.AddToken, eth.RollupEventAddToken{Address: tokenAddress,
 627		TokenID: uint32(len(r.State.TokenList) - 1)})
 628	return c.newTransaction("addtoken", tokenAddress), nil
 629}
 630
 631// RollupWithdrawSNARK is the interface to call the smart contract function
 632// func (c *Client) RollupWithdrawSNARK() (*types.Transaction, error) { // TODO (Not defined in Hermez.sol)
 633// 	return nil, errTODO
 634// }
 635
 636// RollupWithdrawMerkleProof is the interface to call the smart contract function
 637func (c *Client) RollupWithdrawMerkleProof(tokenID int64, balance *big.Int, babyPubKey *babyjub.PublicKey, numExitRoot int64, siblings []*big.Int, idx int64, instantWithdraw bool) (tx *types.Transaction, err error) {
 638	c.rw.Lock()
 639	defer c.rw.Unlock()
 640	cpy := c.nextBlock().copy()
 641	defer func() { c.revertIfErr(err, cpy) }()
 642
 643	log.Error("TODO")
 644	return nil, errTODO
 645}
 646
 647// RollupForceExit is the interface to call the smart contract function
 648func (c *Client) RollupForceExit(fromIdx int64, amountF utils.Float16, tokenID int64) (tx *types.Transaction, err error) {
 649	c.rw.Lock()
 650	defer c.rw.Unlock()
 651	cpy := c.nextBlock().copy()
 652	defer func() { c.revertIfErr(err, cpy) }()
 653
 654	log.Error("TODO")
 655	return nil, errTODO
 656}
 657
 658// RollupForceTransfer is the interface to call the smart contract function
 659func (c *Client) RollupForceTransfer(fromIdx int64, amountF utils.Float16, tokenID, toIdx int64) (tx *types.Transaction, err error) {
 660	c.rw.Lock()
 661	defer c.rw.Unlock()
 662	cpy := c.nextBlock().copy()
 663	defer func() { c.revertIfErr(err, cpy) }()
 664
 665	log.Error("TODO")
 666	return nil, errTODO
 667}
 668
 669// RollupCreateAccountDepositTransfer is the interface to call the smart contract function
 670func (c *Client) RollupCreateAccountDepositTransfer(babyPubKey babyjub.PublicKey, loadAmountF, amountF utils.Float16, tokenID int64, toIdx int64) (tx *types.Transaction, err error) {
 671	c.rw.Lock()
 672	defer c.rw.Unlock()
 673	cpy := c.nextBlock().copy()
 674	defer func() { c.revertIfErr(err, cpy) }()
 675
 676	log.Error("TODO")
 677	return nil, errTODO
 678}
 679
 680// RollupDepositTransfer is the interface to call the smart contract function
 681func (c *Client) RollupDepositTransfer(fromIdx int64, loadAmountF, amountF utils.Float16, tokenID int64, toIdx int64) (tx *types.Transaction, err error) {
 682	c.rw.Lock()
 683	defer c.rw.Unlock()
 684	cpy := c.nextBlock().copy()
 685	defer func() { c.revertIfErr(err, cpy) }()
 686
 687	log.Error("TODO")
 688	return nil, errTODO
 689}
 690
 691// RollupDeposit is the interface to call the smart contract function
 692func (c *Client) RollupDeposit(fromIdx int64, loadAmountF utils.Float16, tokenID int64) (tx *types.Transaction, err error) {
 693	c.rw.Lock()
 694	defer c.rw.Unlock()
 695	cpy := c.nextBlock().copy()
 696	defer func() { c.revertIfErr(err, cpy) }()
 697
 698	log.Error("TODO")
 699	return nil, errTODO
 700}
 701
 702// RollupCreateAccountDepositFromRelayer is the interface to call the smart contract function
 703func (c *Client) RollupCreateAccountDepositFromRelayer(accountCreationAuthSig []byte, babyPubKey babyjub.PublicKey, loadAmountF utils.Float16) (tx *types.Transaction, err error) {
 704	c.rw.Lock()
 705	defer c.rw.Unlock()
 706	cpy := c.nextBlock().copy()
 707	defer func() { c.revertIfErr(err, cpy) }()
 708
 709	log.Error("TODO")
 710	return nil, errTODO
 711}
 712
 713// RollupCreateAccountDeposit is the interface to call the smart contract function
 714func (c *Client) RollupCreateAccountDeposit(babyPubKey babyjub.PublicKey, loadAmountF utils.Float16, tokenID int64) (tx *types.Transaction, err error) {
 715	c.rw.Lock()
 716	defer c.rw.Unlock()
 717	cpy := c.nextBlock().copy()
 718	defer func() { c.revertIfErr(err, cpy) }()
 719
 720	log.Error("TODO")
 721	return nil, errTODO
 722}
 723
 724// RollupGetTokenAddress is the interface to call the smart contract function
 725func (c *Client) RollupGetTokenAddress(tokenID int64) (*ethCommon.Address, error) {
 726	c.rw.RLock()
 727	defer c.rw.RUnlock()
 728
 729	log.Error("TODO")
 730	return nil, errTODO
 731}
 732
 733// RollupGetL1TxFromQueue is the interface to call the smart contract function
 734func (c *Client) RollupGetL1TxFromQueue(queue int64, position int64) ([]byte, error) {
 735	c.rw.RLock()
 736	defer c.rw.RUnlock()
 737
 738	log.Error("TODO")
 739	return nil, errTODO
 740}
 741
 742// RollupGetQueue is the interface to call the smart contract function
 743func (c *Client) RollupGetQueue(queue int64) ([]byte, error) {
 744	c.rw.RLock()
 745	defer c.rw.RUnlock()
 746
 747	log.Error("TODO")
 748	return nil, errTODO
 749}
 750
 751// RollupUpdateForgeL1Timeout is the interface to call the smart contract function
 752func (c *Client) RollupUpdateForgeL1Timeout(newForgeL1Timeout int64) (tx *types.Transaction, err error) {
 753	c.rw.Lock()
 754	defer c.rw.Unlock()
 755	cpy := c.nextBlock().copy()
 756	defer func() { c.revertIfErr(err, cpy) }()
 757
 758	log.Error("TODO")
 759	return nil, errTODO
 760}
 761
 762// RollupUpdateFeeL1UserTx is the interface to call the smart contract function
 763func (c *Client) RollupUpdateFeeL1UserTx(newFeeL1UserTx *big.Int) (tx *types.Transaction, err error) {
 764	c.rw.Lock()
 765	defer c.rw.Unlock()
 766	cpy := c.nextBlock().copy()
 767	defer func() { c.revertIfErr(err, cpy) }()
 768
 769	log.Error("TODO")
 770	return nil, errTODO
 771}
 772
 773// RollupUpdateFeeAddToken is the interface to call the smart contract function
 774func (c *Client) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (tx *types.Transaction, err error) {
 775	c.rw.Lock()
 776	defer c.rw.Unlock()
 777	cpy := c.nextBlock().copy()
 778	defer func() { c.revertIfErr(err, cpy) }()
 779
 780	log.Error("TODO")
 781	return nil, errTODO
 782}
 783
 784// RollupUpdateTokensHEZ is the interface to call the smart contract function
 785func (c *Client) RollupUpdateTokensHEZ(newTokenHEZ ethCommon.Address) (tx *types.Transaction, err error) {
 786	c.rw.Lock()
 787	defer c.rw.Unlock()
 788	cpy := c.nextBlock().copy()
 789	defer func() { c.revertIfErr(err, cpy) }()
 790
 791	log.Error("TODO")
 792	return nil, errTODO
 793}
 794
 795// RollupUpdateGovernance is the interface to call the smart contract function
 796// func (c *Client) RollupUpdateGovernance() (*types.Transaction, error) { // TODO (Not defined in Hermez.sol)
 797// 	return nil, errTODO
 798// }
 799
 800// RollupConstants returns the Constants of the Rollup Smart Contract
 801func (c *Client) RollupConstants() (*eth.RollupConstants, error) {
 802	c.rw.RLock()
 803	defer c.rw.RUnlock()
 804
 805	log.Error("TODO")
 806	return nil, errTODO
 807}
 808
 809// RollupEventsByBlock returns the events in a block that happened in the Rollup Smart Contract
 810func (c *Client) RollupEventsByBlock(blockNum int64) (*eth.RollupEvents, *ethCommon.Hash, error) {
 811	c.rw.RLock()
 812	defer c.rw.RUnlock()
 813
 814	block, ok := c.blocks[blockNum]
 815	if !ok {
 816		return nil, nil, fmt.Errorf("Block %v doesn't exist", blockNum)
 817	}
 818	return &block.Rollup.Events, &block.Eth.Hash, nil
 819}
 820
 821// RollupForgeBatchArgs returns the arguments used in a ForgeBatch call in the Rollup Smart Contract in the given transaction
 822func (c *Client) RollupForgeBatchArgs(ethTxHash ethCommon.Hash) (*eth.RollupForgeBatchArgs, error) {
 823	c.rw.RLock()
 824	defer c.rw.RUnlock()
 825
 826	forgeBatchArgs, ok := c.forgeBatchArgs[ethTxHash]
 827	if !ok {
 828		return nil, fmt.Errorf("transaction not found")
 829	}
 830	return forgeBatchArgs, nil
 831}
 832
 833//
 834// Auction
 835//
 836
 837// AuctionSetSlotDeadline is the interface to call the smart contract function
 838func (c *Client) AuctionSetSlotDeadline(newDeadline uint8) (tx *types.Transaction, err error) {
 839	c.rw.Lock()
 840	defer c.rw.Unlock()
 841	cpy := c.nextBlock().copy()
 842	defer func() { c.revertIfErr(err, cpy) }()
 843
 844	log.Error("TODO")
 845	return nil, errTODO
 846}
 847
 848// AuctionGetSlotDeadline is the interface to call the smart contract function
 849func (c *Client) AuctionGetSlotDeadline() (uint8, error) {
 850	c.rw.RLock()
 851	defer c.rw.RUnlock()
 852
 853	log.Error("TODO")
 854	return 0, errTODO
 855}
 856
 857// AuctionSetOpenAuctionSlots is the interface to call the smart contract function
 858func (c *Client) AuctionSetOpenAuctionSlots(newOpenAuctionSlots uint16) (tx *types.Transaction, err error) {
 859	c.rw.Lock()
 860	defer c.rw.Unlock()
 861	cpy := c.nextBlock().copy()
 862	defer func() { c.revertIfErr(err, cpy) }()
 863
 864	log.Error("TODO")
 865	return nil, errTODO
 866}
 867
 868// AuctionGetOpenAuctionSlots is the interface to call the smart contract function
 869func (c *Client) AuctionGetOpenAuctionSlots() (uint16, error) {
 870	c.rw.RLock()
 871	defer c.rw.RUnlock()
 872
 873	log.Error("TODO")
 874	return 0, errTODO
 875}
 876
 877// AuctionSetClosedAuctionSlots is the interface to call the smart contract function
 878func (c *Client) AuctionSetClosedAuctionSlots(newClosedAuctionSlots uint16) (tx *types.Transaction, err error) {
 879	c.rw.Lock()
 880	defer c.rw.Unlock()
 881	cpy := c.nextBlock().copy()
 882	defer func() { c.revertIfErr(err, cpy) }()
 883
 884	log.Error("TODO")
 885	return nil, errTODO
 886}
 887
 888// AuctionGetClosedAuctionSlots is the interface to call the smart contract function
 889func (c *Client) AuctionGetClosedAuctionSlots() (uint16, error) {
 890	c.rw.RLock()
 891	defer c.rw.RUnlock()
 892
 893	log.Error("TODO")
 894	return 0, errTODO
 895}
 896
 897// AuctionSetOutbidding is the interface to call the smart contract function
 898func (c *Client) AuctionSetOutbidding(newOutbidding uint16) (tx *types.Transaction, err error) {
 899	c.rw.Lock()
 900	defer c.rw.Unlock()
 901	cpy := c.nextBlock().copy()
 902	defer func() { c.revertIfErr(err, cpy) }()
 903
 904	log.Error("TODO")
 905	return nil, errTODO
 906}
 907
 908// AuctionGetOutbidding is the interface to call the smart contract function
 909func (c *Client) AuctionGetOutbidding() (uint16, error) {
 910	c.rw.RLock()
 911	defer c.rw.RUnlock()
 912
 913	log.Error("TODO")
 914	return 0, errTODO
 915}
 916
 917// AuctionSetAllocationRatio is the interface to call the smart contract function
 918func (c *Client) AuctionSetAllocationRatio(newAllocationRatio [3]uint16) (tx *types.Transaction, err error) {
 919	c.rw.Lock()
 920	defer c.rw.Unlock()
 921	cpy := c.nextBlock().copy()
 922	defer func() { c.revertIfErr(err, cpy) }()
 923
 924	log.Error("TODO")
 925	return nil, errTODO
 926}
 927
 928// AuctionGetAllocationRatio is the interface to call the smart contract function
 929func (c *Client) AuctionGetAllocationRatio() ([3]uint16, error) {
 930	c.rw.RLock()
 931	defer c.rw.RUnlock()
 932
 933	log.Error("TODO")
 934	return [3]uint16{}, errTODO
 935}
 936
 937// AuctionSetDonationAddress is the interface to call the smart contract function
 938func (c *Client) AuctionSetDonationAddress(newDonationAddress ethCommon.Address) (tx *types.Transaction, err error) {
 939	c.rw.Lock()
 940	defer c.rw.Unlock()
 941	cpy := c.nextBlock().copy()
 942	defer func() { c.revertIfErr(err, cpy) }()
 943
 944	log.Error("TODO")
 945	return nil, errTODO
 946}
 947
 948// AuctionGetDonationAddress is the interface to call the smart contract function
 949func (c *Client) AuctionGetDonationAddress() (*ethCommon.Address, error) {
 950	c.rw.RLock()
 951	defer c.rw.RUnlock()
 952
 953	log.Error("TODO")
 954	return nil, errTODO
 955}
 956
 957// AuctionSetBootCoordinator is the interface to call the smart contract function
 958func (c *Client) AuctionSetBootCoordinator(newBootCoordinator ethCommon.Address) (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
 964	log.Error("TODO")
 965	return nil, errTODO
 966}
 967
 968// AuctionGetBootCoordinator is the interface to call the smart contract function
 969func (c *Client) AuctionGetBootCoordinator() (*ethCommon.Address, error) {
 970	c.rw.RLock()
 971	defer c.rw.RUnlock()
 972
 973	currentBlock := c.currentBlock()
 974	a := currentBlock.Auction
 975
 976	return &a.Vars.BootCoordinator, nil
 977}
 978
 979// AuctionChangeDefaultSlotSetBid is the interface to call the smart contract function
 980func (c *Client) AuctionChangeDefaultSlotSetBid(slotSet int64, newInitialMinBid *big.Int) (tx *types.Transaction, err error) {
 981	c.rw.Lock()
 982	defer c.rw.Unlock()
 983	cpy := c.nextBlock().copy()
 984	defer func() { c.revertIfErr(err, cpy) }()
 985
 986	log.Error("TODO")
 987	return nil, errTODO
 988}
 989
 990// AuctionRegisterCoordinator is the interface to call the smart contract function
 991func (c *Client) AuctionRegisterCoordinator(forgerAddress ethCommon.Address, URL string) (tx *types.Transaction, err error) {
 992	c.rw.Lock()
 993	defer c.rw.Unlock()
 994	cpy := c.nextBlock().copy()
 995	defer func() { c.revertIfErr(err, cpy) }()
 996
 997	nextBlock := c.nextBlock()
 998	a := nextBlock.Auction
 999
1000	if _, ok := a.State.Coordinators[forgerAddress]; ok {
1001		return nil, fmt.Errorf("Already registered")
1002	}
1003	a.State.Coordinators[forgerAddress] = &eth.Coordinator{
1004		WithdrawalAddress: c.addr,
1005		URL:               URL,
1006	}
1007
1008	a.Events.NewCoordinator = append(a.Events.NewCoordinator,
1009		eth.AuctionEventNewCoordinator{
1010			ForgerAddress:     forgerAddress,
1011			WithdrawalAddress: c.addr,
1012			URL:               URL,
1013		})
1014
1015	type data struct {
1016		ForgerAddress ethCommon.Address
1017		URL           string
1018	}
1019	return c.newTransaction("registercoordinator", data{forgerAddress, URL}), nil
1020}
1021
1022// AuctionIsRegisteredCoordinator is the interface to call the smart contract function
1023func (c *Client) AuctionIsRegisteredCoordinator(forgerAddress ethCommon.Address) (bool, error) {
1024	c.rw.RLock()
1025	defer c.rw.RUnlock()
1026
1027	log.Error("TODO")
1028	return false, errTODO
1029}
1030
1031// AuctionUpdateCoordinatorInfo is the interface to call the smart contract function
1032func (c *Client) AuctionUpdateCoordinatorInfo(forgerAddress ethCommon.Address, newWithdrawAddress ethCommon.Address, newURL string) (tx *types.Transaction, err error) {
1033	c.rw.Lock()
1034	defer c.rw.Unlock()
1035	cpy := c.nextBlock().copy()
1036	defer func() { c.revertIfErr(err, cpy) }()
1037
1038	log.Error("TODO")
1039	return nil, errTODO
1040}
1041
1042// AuctionGetCurrentSlotNumber is the interface to call the smart contract function
1043func (c *Client) AuctionGetCurrentSlotNumber() (int64, error) {
1044	c.rw.RLock()
1045	defer c.rw.RUnlock()
1046
1047	log.Error("TODO")
1048	return 0, errTODO
1049}
1050
1051// AuctionGetMinBidBySlot is the interface to call the smart contract function
1052func (c *Client) AuctionGetMinBidBySlot(slot int64) (*big.Int, error) {
1053	c.rw.RLock()
1054	defer c.rw.RUnlock()
1055
1056	log.Error("TODO")
1057	return nil, errTODO
1058}
1059
1060// AuctionGetDefaultSlotSetBid is the interface to call the smart contract function
1061func (c *Client) AuctionGetDefaultSlotSetBid(slotSet uint8) (*big.Int, error) {
1062	c.rw.RLock()
1063	defer c.rw.RUnlock()
1064
1065	log.Error("TODO")
1066	return nil, errTODO
1067}
1068
1069// AuctionTokensReceived is the interface to call the smart contract function
1070// func (c *Client) AuctionTokensReceived(operator, from, to ethCommon.Address, amount *big.Int, userData, operatorData []byte) error {
1071// 	return errTODO
1072// }
1073
1074// AuctionBid is the interface to call the smart contract function
1075func (c *Client) AuctionBid(slot int64, bidAmount *big.Int, forger ethCommon.Address) (tx *types.Transaction, err error) {
1076	c.rw.Lock()
1077	defer c.rw.Unlock()
1078	cpy := c.nextBlock().copy()
1079	defer func() { func() { c.revertIfErr(err, cpy) }() }()
1080
1081	nextBlock := c.nextBlock()
1082	a := nextBlock.Auction
1083
1084	if slot < a.getCurrentSlotNumber()+int64(a.Vars.ClosedAuctionSlots) {
1085		return nil, errBidClosed
1086	}
1087
1088	if slot >= a.getCurrentSlotNumber()+int64(a.Vars.ClosedAuctionSlots)+int64(a.Vars.OpenAuctionSlots) {
1089		return nil, errBidNotOpen
1090	}
1091
1092	minBid, err := a.getMinBidBySlot(slot)
1093	if err != nil {
1094		return nil, err
1095	}
1096	if bidAmount.Cmp(minBid) == -1 {
1097		return nil, errBidBelowMin
1098	}
1099
1100	if _, ok := a.State.Coordinators[forger]; !ok {
1101		return nil, errCoordNotReg
1102	}
1103
1104	slotState, ok := a.State.Slots[slot]
1105	if !ok {
1106		slotState = eth.NewSlotState()
1107		a.State.Slots[slot] = slotState
1108	}
1109	slotState.Forger = forger
1110	slotState.BidAmount = bidAmount
1111
1112	a.Events.NewBid = append(a.Events.NewBid,
1113		eth.AuctionEventNewBid{Slot: slot, BidAmount: bidAmount, CoordinatorForger: forger})
1114
1115	type data struct {
1116		Slot      int64
1117		BidAmount *big.Int
1118		Forger    ethCommon.Address
1119	}
1120	return c.newTransaction("bid", data{slot, bidAmount, forger}), nil
1121}
1122
1123// AuctionMultiBid is the interface to call the smart contract function
1124func (c *Client) AuctionMultiBid(startingSlot int64, endingSlot int64, slotSet [6]bool, maxBid, closedMinBid, budget *big.Int, forger ethCommon.Address) (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
1130	log.Error("TODO")
1131	return nil, errTODO
1132}
1133
1134// AuctionCanForge is the interface to call the smart contract function
1135func (c *Client) AuctionCanForge(forger ethCommon.Address) (bool, error) {
1136	c.rw.RLock()
1137	defer c.rw.RUnlock()
1138
1139	currentBlock := c.currentBlock()
1140	a := currentBlock.Auction
1141	return a.canForge(forger, a.Eth.BlockNum)
1142}
1143
1144// AuctionForge is the interface to call the smart contract function
1145// func (c *Client) AuctionForge(forger ethCommon.Address) (bool, error) {
1146// 	return false, errTODO
1147// }
1148
1149// AuctionClaimHEZ is the interface to call the smart contract function
1150func (c *Client) AuctionClaimHEZ() (tx *types.Transaction, err error) {
1151	c.rw.Lock()
1152	defer c.rw.Unlock()
1153	cpy := c.nextBlock().copy()
1154	defer func() { c.revertIfErr(err, cpy) }()
1155
1156	log.Error("TODO")
1157	return nil, errTODO
1158}
1159
1160// AuctionConstants returns the Constants of the Auction Smart Contract
1161func (c *Client) AuctionConstants() (*eth.AuctionConstants, error) {
1162	c.rw.RLock()
1163	defer c.rw.RUnlock()
1164
1165	return c.auctionConstants, nil
1166}
1167
1168// AuctionEventsByBlock returns the events in a block that happened in the Auction Smart Contract
1169func (c *Client) AuctionEventsByBlock(blockNum int64) (*eth.AuctionEvents, *ethCommon.Hash, error) {
1170	c.rw.RLock()
1171	defer c.rw.RUnlock()
1172
1173	block, ok := c.blocks[blockNum]
1174	if !ok {
1175		return nil, nil, fmt.Errorf("Block %v doesn't exist", blockNum)
1176	}
1177	return &block.Auction.Events, &block.Eth.Hash, nil
1178}