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