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