You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1339 lines
38 KiB

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