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