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 l1Tx.FromIdx != nil && 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) (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
 708	r.State.TokenMap[tokenAddress] = true
 709	r.State.TokenList = append(r.State.TokenList, tokenAddress)
 710	r.Events.AddToken = append(r.Events.AddToken, eth.RollupEventAddToken{Address: tokenAddress,
 711		TokenID: uint32(len(r.State.TokenList) - 1)})
 712	return r.addTransaction(newTransaction("addtoken", tokenAddress)), nil
 713}
 714
 715// RollupWithdrawSNARK is the interface to call the smart contract function
 716// func (c *Client) RollupWithdrawSNARK() (*types.Transaction, error) { // TODO (Not defined in Hermez.sol)
 717// 	return nil, errTODO
 718// }
 719
 720// RollupWithdraw is the interface to call the smart contract function
 721func (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) {
 722	c.rw.Lock()
 723	defer c.rw.Unlock()
 724	cpy := c.nextBlock().copy()
 725	defer func() { c.revertIfErr(err, cpy) }()
 726	if c.addr == nil {
 727		return nil, eth.ErrAccountNil
 728	}
 729
 730	log.Error("TODO")
 731	return nil, errTODO
 732}
 733
 734// RollupForceExit is the interface to call the smart contract function
 735func (c *Client) RollupForceExit(fromIdx int64, amountF common.Float16, tokenID int64) (tx *types.Transaction, err error) {
 736	c.rw.Lock()
 737	defer c.rw.Unlock()
 738	cpy := c.nextBlock().copy()
 739	defer func() { c.revertIfErr(err, cpy) }()
 740	if c.addr == nil {
 741		return nil, eth.ErrAccountNil
 742	}
 743
 744	log.Error("TODO")
 745	return nil, errTODO
 746}
 747
 748// RollupForceTransfer is the interface to call the smart contract function
 749func (c *Client) RollupForceTransfer(fromIdx int64, amountF common.Float16, tokenID, toIdx int64) (tx *types.Transaction, err error) {
 750	c.rw.Lock()
 751	defer c.rw.Unlock()
 752	cpy := c.nextBlock().copy()
 753	defer func() { c.revertIfErr(err, cpy) }()
 754	if c.addr == nil {
 755		return nil, eth.ErrAccountNil
 756	}
 757
 758	log.Error("TODO")
 759	return nil, errTODO
 760}
 761
 762// RollupCreateAccountDepositTransfer is the interface to call the smart contract function
 763func (c *Client) RollupCreateAccountDepositTransfer(babyPubKey babyjub.PublicKey, loadAmountF, amountF common.Float16, tokenID int64, toIdx int64) (tx *types.Transaction, err error) {
 764	c.rw.Lock()
 765	defer c.rw.Unlock()
 766	cpy := c.nextBlock().copy()
 767	defer func() { c.revertIfErr(err, cpy) }()
 768	if c.addr == nil {
 769		return nil, eth.ErrAccountNil
 770	}
 771
 772	log.Error("TODO")
 773	return nil, errTODO
 774}
 775
 776// RollupGetCurrentTokens is the interface to call the smart contract function
 777func (c *Client) RollupGetCurrentTokens() (*big.Int, error) {
 778	c.rw.RLock()
 779	defer c.rw.RUnlock()
 780
 781	log.Error("TODO")
 782	return nil, errTODO
 783}
 784
 785// RollupDepositTransfer is the interface to call the smart contract function
 786func (c *Client) RollupDepositTransfer(fromIdx int64, loadAmountF, amountF common.Float16, tokenID int64, toIdx int64) (tx *types.Transaction, err error) {
 787	c.rw.Lock()
 788	defer c.rw.Unlock()
 789	cpy := c.nextBlock().copy()
 790	defer func() { c.revertIfErr(err, cpy) }()
 791	if c.addr == nil {
 792		return nil, eth.ErrAccountNil
 793	}
 794
 795	log.Error("TODO")
 796	return nil, errTODO
 797}
 798
 799// RollupDeposit is the interface to call the smart contract function
 800func (c *Client) RollupDeposit(fromIdx int64, loadAmountF common.Float16, tokenID int64) (tx *types.Transaction, err error) {
 801	c.rw.Lock()
 802	defer c.rw.Unlock()
 803	cpy := c.nextBlock().copy()
 804	defer func() { c.revertIfErr(err, cpy) }()
 805	if c.addr == nil {
 806		return nil, eth.ErrAccountNil
 807	}
 808
 809	log.Error("TODO")
 810	return nil, errTODO
 811}
 812
 813// RollupCreateAccountDepositFromRelayer is the interface to call the smart contract function
 814func (c *Client) RollupCreateAccountDepositFromRelayer(accountCreationAuthSig []byte, babyPubKey babyjub.PublicKey, loadAmountF common.Float16) (tx *types.Transaction, err error) {
 815	c.rw.Lock()
 816	defer c.rw.Unlock()
 817	cpy := c.nextBlock().copy()
 818	defer func() { c.revertIfErr(err, cpy) }()
 819	if c.addr == nil {
 820		return nil, eth.ErrAccountNil
 821	}
 822
 823	log.Error("TODO")
 824	return nil, errTODO
 825}
 826
 827// RollupCreateAccountDeposit is the interface to call the smart contract function
 828func (c *Client) RollupCreateAccountDeposit(babyPubKey babyjub.PublicKey, loadAmountF common.Float16, tokenID int64) (tx *types.Transaction, err error) {
 829	c.rw.Lock()
 830	defer c.rw.Unlock()
 831	cpy := c.nextBlock().copy()
 832	defer func() { c.revertIfErr(err, cpy) }()
 833	if c.addr == nil {
 834		return nil, eth.ErrAccountNil
 835	}
 836
 837	log.Error("TODO")
 838	return nil, errTODO
 839}
 840
 841// RollupGetTokenAddress is the interface to call the smart contract function
 842// func (c *Client) RollupGetTokenAddress(tokenID int64) (*ethCommon.Address, error) {
 843// 	c.rw.RLock()
 844// 	defer c.rw.RUnlock()
 845//
 846// 	log.Error("TODO")
 847// 	return nil, errTODO
 848// }
 849
 850// RollupGetL1TxFromQueue is the interface to call the smart contract function
 851// func (c *Client) RollupGetL1TxFromQueue(queue int64, position int64) ([]byte, error) {
 852// 	c.rw.RLock()
 853// 	defer c.rw.RUnlock()
 854//
 855// 	log.Error("TODO")
 856// 	return nil, errTODO
 857// }
 858
 859// RollupGetQueue is the interface to call the smart contract function
 860// func (c *Client) RollupGetQueue(queue int64) ([]byte, error) {
 861// 	c.rw.RLock()
 862// 	defer c.rw.RUnlock()
 863//
 864// 	log.Error("TODO")
 865// 	return nil, errTODO
 866// }
 867
 868// RollupUpdateForgeL1L2BatchTimeout is the interface to call the smart contract function
 869func (c *Client) RollupUpdateForgeL1L2BatchTimeout(newForgeL1Timeout int64) (tx *types.Transaction, err error) {
 870	c.rw.Lock()
 871	defer c.rw.Unlock()
 872	cpy := c.nextBlock().copy()
 873	defer func() { c.revertIfErr(err, cpy) }()
 874	if c.addr == nil {
 875		return nil, eth.ErrAccountNil
 876	}
 877
 878	log.Error("TODO")
 879	return nil, errTODO
 880}
 881
 882// RollupUpdateFeeAddToken is the interface to call the smart contract function
 883func (c *Client) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (tx *types.Transaction, err error) {
 884	c.rw.Lock()
 885	defer c.rw.Unlock()
 886	cpy := c.nextBlock().copy()
 887	defer func() { c.revertIfErr(err, cpy) }()
 888	if c.addr == nil {
 889		return nil, eth.ErrAccountNil
 890	}
 891
 892	log.Error("TODO")
 893	return nil, errTODO
 894}
 895
 896// RollupUpdateTokensHEZ is the interface to call the smart contract function
 897// func (c *Client) RollupUpdateTokensHEZ(newTokenHEZ ethCommon.Address) (tx *types.Transaction, err error) {
 898// 	c.rw.Lock()
 899// 	defer c.rw.Unlock()
 900// 	cpy := c.nextBlock().copy()
 901// 	defer func() { c.revertIfErr(err, cpy) }()
 902//
 903// 	log.Error("TODO")
 904// 	return nil, errTODO
 905// }
 906
 907// RollupUpdateGovernance is the interface to call the smart contract function
 908// func (c *Client) RollupUpdateGovernance() (*types.Transaction, error) { // TODO (Not defined in Hermez.sol)
 909// 	return nil, errTODO
 910// }
 911
 912// RollupConstants returns the Constants of the Rollup Smart Contract
 913func (c *Client) RollupConstants() (*eth.RollupPublicConstants, error) {
 914	c.rw.RLock()
 915	defer c.rw.RUnlock()
 916
 917	log.Error("TODO")
 918	return nil, errTODO
 919}
 920
 921// RollupEventsByBlock returns the events in a block that happened in the Rollup Smart Contract
 922func (c *Client) RollupEventsByBlock(blockNum int64) (*eth.RollupEvents, *ethCommon.Hash, error) {
 923	c.rw.RLock()
 924	defer c.rw.RUnlock()
 925
 926	block, ok := c.blocks[blockNum]
 927	if !ok {
 928		return nil, nil, fmt.Errorf("Block %v doesn't exist", blockNum)
 929	}
 930	return &block.Rollup.Events, &block.Eth.Hash, nil
 931}
 932
 933// RollupForgeBatchArgs returns the arguments used in a ForgeBatch call in the Rollup Smart Contract in the given transaction
 934func (c *Client) RollupForgeBatchArgs(ethTxHash ethCommon.Hash) (*eth.RollupForgeBatchArgs, error) {
 935	c.rw.RLock()
 936	defer c.rw.RUnlock()
 937
 938	forgeBatchArgs, ok := c.forgeBatchArgs[ethTxHash]
 939	if !ok {
 940		return nil, fmt.Errorf("transaction not found")
 941	}
 942	return forgeBatchArgs, nil
 943}
 944
 945//
 946// Auction
 947//
 948
 949// AuctionSetSlotDeadline is the interface to call the smart contract function
 950func (c *Client) AuctionSetSlotDeadline(newDeadline uint8) (tx *types.Transaction, err error) {
 951	c.rw.Lock()
 952	defer c.rw.Unlock()
 953	cpy := c.nextBlock().copy()
 954	defer func() { c.revertIfErr(err, cpy) }()
 955	if c.addr == nil {
 956		return nil, eth.ErrAccountNil
 957	}
 958
 959	log.Error("TODO")
 960	return nil, errTODO
 961}
 962
 963// AuctionGetSlotDeadline is the interface to call the smart contract function
 964func (c *Client) AuctionGetSlotDeadline() (uint8, error) {
 965	c.rw.RLock()
 966	defer c.rw.RUnlock()
 967
 968	log.Error("TODO")
 969	return 0, errTODO
 970}
 971
 972// AuctionSetOpenAuctionSlots is the interface to call the smart contract function
 973func (c *Client) AuctionSetOpenAuctionSlots(newOpenAuctionSlots uint16) (tx *types.Transaction, err error) {
 974	c.rw.Lock()
 975	defer c.rw.Unlock()
 976	cpy := c.nextBlock().copy()
 977	defer func() { c.revertIfErr(err, cpy) }()
 978	if c.addr == nil {
 979		return nil, eth.ErrAccountNil
 980	}
 981
 982	log.Error("TODO")
 983	return nil, errTODO
 984}
 985
 986// AuctionGetOpenAuctionSlots is the interface to call the smart contract function
 987func (c *Client) AuctionGetOpenAuctionSlots() (uint16, error) {
 988	c.rw.RLock()
 989	defer c.rw.RUnlock()
 990
 991	log.Error("TODO")
 992	return 0, errTODO
 993}
 994
 995// AuctionSetClosedAuctionSlots is the interface to call the smart contract function
 996func (c *Client) AuctionSetClosedAuctionSlots(newClosedAuctionSlots uint16) (tx *types.Transaction, err error) {
 997	c.rw.Lock()
 998	defer c.rw.Unlock()
 999	cpy := c.nextBlock().copy()
1000	defer func() { c.revertIfErr(err, cpy) }()
1001	if c.addr == nil {
1002		return nil, eth.ErrAccountNil
1003	}
1004
1005	log.Error("TODO")
1006	return nil, errTODO
1007}
1008
1009// AuctionGetClosedAuctionSlots is the interface to call the smart contract function
1010func (c *Client) AuctionGetClosedAuctionSlots() (uint16, error) {
1011	c.rw.RLock()
1012	defer c.rw.RUnlock()
1013
1014	log.Error("TODO")
1015	return 0, errTODO
1016}
1017
1018// AuctionSetOutbidding is the interface to call the smart contract function
1019func (c *Client) AuctionSetOutbidding(newOutbidding uint16) (tx *types.Transaction, err error) {
1020	c.rw.Lock()
1021	defer c.rw.Unlock()
1022	cpy := c.nextBlock().copy()
1023	defer func() { c.revertIfErr(err, cpy) }()
1024	if c.addr == nil {
1025		return nil, eth.ErrAccountNil
1026	}
1027
1028	log.Error("TODO")
1029	return nil, errTODO
1030}
1031
1032// AuctionGetOutbidding is the interface to call the smart contract function
1033func (c *Client) AuctionGetOutbidding() (uint16, error) {
1034	c.rw.RLock()
1035	defer c.rw.RUnlock()
1036
1037	log.Error("TODO")
1038	return 0, errTODO
1039}
1040
1041// AuctionSetAllocationRatio is the interface to call the smart contract function
1042func (c *Client) AuctionSetAllocationRatio(newAllocationRatio [3]uint16) (tx *types.Transaction, err error) {
1043	c.rw.Lock()
1044	defer c.rw.Unlock()
1045	cpy := c.nextBlock().copy()
1046	defer func() { c.revertIfErr(err, cpy) }()
1047	if c.addr == nil {
1048		return nil, eth.ErrAccountNil
1049	}
1050
1051	log.Error("TODO")
1052	return nil, errTODO
1053}
1054
1055// AuctionGetAllocationRatio is the interface to call the smart contract function
1056func (c *Client) AuctionGetAllocationRatio() ([3]uint16, error) {
1057	c.rw.RLock()
1058	defer c.rw.RUnlock()
1059
1060	log.Error("TODO")
1061	return [3]uint16{}, errTODO
1062}
1063
1064// AuctionSetDonationAddress is the interface to call the smart contract function
1065func (c *Client) AuctionSetDonationAddress(newDonationAddress ethCommon.Address) (tx *types.Transaction, err error) {
1066	c.rw.Lock()
1067	defer c.rw.Unlock()
1068	cpy := c.nextBlock().copy()
1069	defer func() { c.revertIfErr(err, cpy) }()
1070	if c.addr == nil {
1071		return nil, eth.ErrAccountNil
1072	}
1073
1074	log.Error("TODO")
1075	return nil, errTODO
1076}
1077
1078// AuctionGetDonationAddress is the interface to call the smart contract function
1079func (c *Client) AuctionGetDonationAddress() (*ethCommon.Address, error) {
1080	c.rw.RLock()
1081	defer c.rw.RUnlock()
1082
1083	log.Error("TODO")
1084	return nil, errTODO
1085}
1086
1087// AuctionSetBootCoordinator is the interface to call the smart contract function
1088func (c *Client) AuctionSetBootCoordinator(newBootCoordinator ethCommon.Address) (tx *types.Transaction, err error) {
1089	c.rw.Lock()
1090	defer c.rw.Unlock()
1091	cpy := c.nextBlock().copy()
1092	defer func() { c.revertIfErr(err, cpy) }()
1093	if c.addr == nil {
1094		return nil, eth.ErrAccountNil
1095	}
1096
1097	log.Error("TODO")
1098	return nil, errTODO
1099}
1100
1101// AuctionGetBootCoordinator is the interface to call the smart contract function
1102func (c *Client) AuctionGetBootCoordinator() (*ethCommon.Address, error) {
1103	c.rw.RLock()
1104	defer c.rw.RUnlock()
1105
1106	currentBlock := c.currentBlock()
1107	a := currentBlock.Auction
1108
1109	return &a.Vars.BootCoordinator, nil
1110}
1111
1112// AuctionChangeDefaultSlotSetBid is the interface to call the smart contract function
1113func (c *Client) AuctionChangeDefaultSlotSetBid(slotSet int64, newInitialMinBid *big.Int) (tx *types.Transaction, err error) {
1114	c.rw.Lock()
1115	defer c.rw.Unlock()
1116	cpy := c.nextBlock().copy()
1117	defer func() { c.revertIfErr(err, cpy) }()
1118	if c.addr == nil {
1119		return nil, eth.ErrAccountNil
1120	}
1121
1122	log.Error("TODO")
1123	return nil, errTODO
1124}
1125
1126// AuctionSetCoordinator is the interface to call the smart contract function
1127func (c *Client) AuctionSetCoordinator(forger ethCommon.Address, URL string) (tx *types.Transaction, err error) {
1128	c.rw.Lock()
1129	defer c.rw.Unlock()
1130	cpy := c.nextBlock().copy()
1131	defer func() { c.revertIfErr(err, cpy) }()
1132	if c.addr == nil {
1133		return nil, eth.ErrAccountNil
1134	}
1135
1136	nextBlock := c.nextBlock()
1137	a := nextBlock.Auction
1138
1139	a.State.Coordinators[*c.addr] = &eth.Coordinator{
1140		Forger: forger,
1141		URL:    URL,
1142	}
1143
1144	a.Events.SetCoordinator = append(a.Events.SetCoordinator,
1145		eth.AuctionEventSetCoordinator{
1146			BidderAddress:  *c.addr,
1147			ForgerAddress:  forger,
1148			CoordinatorURL: URL,
1149		})
1150
1151	type data struct {
1152		BidderAddress ethCommon.Address
1153		ForgerAddress ethCommon.Address
1154		URL           string
1155	}
1156	return a.addTransaction(newTransaction("registercoordinator", data{*c.addr, forger, URL})), nil
1157}
1158
1159// AuctionIsRegisteredCoordinator is the interface to call the smart contract function
1160func (c *Client) AuctionIsRegisteredCoordinator(forgerAddress ethCommon.Address) (bool, error) {
1161	c.rw.RLock()
1162	defer c.rw.RUnlock()
1163
1164	log.Error("TODO")
1165	return false, errTODO
1166}
1167
1168// AuctionUpdateCoordinatorInfo is the interface to call the smart contract function
1169func (c *Client) AuctionUpdateCoordinatorInfo(forgerAddress ethCommon.Address, newWithdrawAddress ethCommon.Address, newURL string) (tx *types.Transaction, err error) {
1170	c.rw.Lock()
1171	defer c.rw.Unlock()
1172	cpy := c.nextBlock().copy()
1173	defer func() { c.revertIfErr(err, cpy) }()
1174	if c.addr == nil {
1175		return nil, eth.ErrAccountNil
1176	}
1177
1178	log.Error("TODO")
1179	return nil, errTODO
1180}
1181
1182// AuctionGetSlotNumber is the interface to call the smart contract function
1183func (c *Client) AuctionGetSlotNumber(blockNum int64) (int64, error) {
1184	c.rw.RLock()
1185	defer c.rw.RUnlock()
1186
1187	currentBlock := c.currentBlock()
1188	a := currentBlock.Auction
1189	return a.getSlotNumber(blockNum), nil
1190}
1191
1192// AuctionGetCurrentSlotNumber is the interface to call the smart contract function
1193func (c *Client) AuctionGetCurrentSlotNumber() (int64, error) {
1194	c.rw.RLock()
1195	defer c.rw.RUnlock()
1196
1197	log.Error("TODO")
1198	return 0, errTODO
1199}
1200
1201// AuctionGetMinBidBySlot is the interface to call the smart contract function
1202func (c *Client) AuctionGetMinBidBySlot(slot int64) (*big.Int, error) {
1203	c.rw.RLock()
1204	defer c.rw.RUnlock()
1205
1206	log.Error("TODO")
1207	return nil, errTODO
1208}
1209
1210// AuctionGetDefaultSlotSetBid is the interface to call the smart contract function
1211func (c *Client) AuctionGetDefaultSlotSetBid(slotSet uint8) (*big.Int, error) {
1212	c.rw.RLock()
1213	defer c.rw.RUnlock()
1214
1215	log.Error("TODO")
1216	return nil, errTODO
1217}
1218
1219// AuctionGetSlotSet is the interface to call the smart contract function
1220func (c *Client) AuctionGetSlotSet(slot int64) (*big.Int, error) {
1221	c.rw.RLock()
1222	defer c.rw.RUnlock()
1223
1224	log.Error("TODO")
1225	return nil, errTODO
1226}
1227
1228// AuctionTokensReceived is the interface to call the smart contract function
1229// func (c *Client) AuctionTokensReceived(operator, from, to ethCommon.Address, amount *big.Int, userData, operatorData []byte) error {
1230// 	return errTODO
1231// }
1232
1233// AuctionBid is the interface to call the smart contract function
1234func (c *Client) AuctionBid(slot int64, bidAmount *big.Int) (tx *types.Transaction, err error) {
1235	c.rw.Lock()
1236	defer c.rw.Unlock()
1237	cpy := c.nextBlock().copy()
1238	defer func() { func() { c.revertIfErr(err, cpy) }() }()
1239	if c.addr == nil {
1240		return nil, eth.ErrAccountNil
1241	}
1242
1243	nextBlock := c.nextBlock()
1244	a := nextBlock.Auction
1245
1246	if slot < a.getCurrentSlotNumber()+int64(a.Vars.ClosedAuctionSlots) {
1247		return nil, errBidClosed
1248	}
1249
1250	if slot >= a.getCurrentSlotNumber()+int64(a.Vars.ClosedAuctionSlots)+int64(a.Vars.OpenAuctionSlots) {
1251		return nil, errBidNotOpen
1252	}
1253
1254	minBid, err := a.getMinBidBySlot(slot)
1255	if err != nil {
1256		return nil, err
1257	}
1258	if bidAmount.Cmp(minBid) == -1 {
1259		return nil, errBidBelowMin
1260	}
1261
1262	if _, ok := a.State.Coordinators[*c.addr]; !ok {
1263		return nil, errCoordNotReg
1264	}
1265
1266	slotState, ok := a.State.Slots[slot]
1267	if !ok {
1268		slotState = eth.NewSlotState()
1269		a.State.Slots[slot] = slotState
1270	}
1271	slotState.Bidder = *c.addr
1272	slotState.BidAmount = bidAmount
1273
1274	a.Events.NewBid = append(a.Events.NewBid,
1275		eth.AuctionEventNewBid{Slot: slot, BidAmount: bidAmount, Bidder: *c.addr})
1276
1277	type data struct {
1278		Slot      int64
1279		BidAmount *big.Int
1280		Bidder    ethCommon.Address
1281	}
1282	return a.addTransaction(newTransaction("bid", data{slot, bidAmount, *c.addr})), nil
1283}
1284
1285// AuctionMultiBid is the interface to call the smart contract function
1286func (c *Client) AuctionMultiBid(startingSlot int64, endingSlot int64, slotSet [6]bool, maxBid, closedMinBid, budget *big.Int) (tx *types.Transaction, err error) {
1287	c.rw.Lock()
1288	defer c.rw.Unlock()
1289	cpy := c.nextBlock().copy()
1290	defer func() { c.revertIfErr(err, cpy) }()
1291	if c.addr == nil {
1292		return nil, eth.ErrAccountNil
1293	}
1294
1295	log.Error("TODO")
1296	return nil, errTODO
1297}
1298
1299// AuctionCanForge is the interface to call the smart contract function
1300func (c *Client) AuctionCanForge(forger ethCommon.Address, blockNum int64) (bool, error) {
1301	c.rw.RLock()
1302	defer c.rw.RUnlock()
1303
1304	currentBlock := c.currentBlock()
1305	a := currentBlock.Auction
1306	return a.canForge(forger, blockNum)
1307}
1308
1309// AuctionForge is the interface to call the smart contract function
1310func (c *Client) AuctionForge(forger ethCommon.Address) (tx *types.Transaction, err error) {
1311	c.rw.Lock()
1312	defer c.rw.Unlock()
1313	cpy := c.nextBlock().copy()
1314	defer func() { c.revertIfErr(err, cpy) }()
1315	if c.addr == nil {
1316		return nil, eth.ErrAccountNil
1317	}
1318
1319	log.Error("TODO")
1320	return nil, errTODO
1321}
1322
1323// AuctionClaimHEZ is the interface to call the smart contract function
1324func (c *Client) AuctionClaimHEZ() (tx *types.Transaction, err error) {
1325	c.rw.Lock()
1326	defer c.rw.Unlock()
1327	cpy := c.nextBlock().copy()
1328	defer func() { c.revertIfErr(err, cpy) }()
1329	if c.addr == nil {
1330		return nil, eth.ErrAccountNil
1331	}
1332
1333	log.Error("TODO")
1334	return nil, errTODO
1335}
1336
1337// AuctionGetClaimableHEZ is the interface to call the smart contract function
1338func (c *Client) AuctionGetClaimableHEZ(bidder ethCommon.Address) (*big.Int, error) {
1339	c.rw.RLock()
1340	defer c.rw.RUnlock()
1341
1342	log.Error("TODO")
1343	return nil, errTODO
1344}
1345
1346// AuctionConstants returns the Constants of the Auction Smart Contract
1347func (c *Client) AuctionConstants() (*eth.AuctionConstants, error) {
1348	c.rw.RLock()
1349	defer c.rw.RUnlock()
1350
1351	return c.auctionConstants, nil
1352}
1353
1354// AuctionEventsByBlock returns the events in a block that happened in the Auction Smart Contract
1355func (c *Client) AuctionEventsByBlock(blockNum int64) (*eth.AuctionEvents, *ethCommon.Hash, error) {
1356	c.rw.RLock()
1357	defer c.rw.RUnlock()
1358
1359	block, ok := c.blocks[blockNum]
1360	if !ok {
1361		return nil, nil, fmt.Errorf("Block %v doesn't exist", blockNum)
1362	}
1363	return &block.Auction.Events, &block.Eth.Hash, nil
1364}