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