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.

1253 lines
36 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. Tokens map[ethCommon.Address]eth.ERC20Consts
  161. // state ethState
  162. }
  163. // Block represents a ethereum block
  164. type Block struct {
  165. Rollup *RollupBlock
  166. Auction *AuctionBlock
  167. Eth *EthereumBlock
  168. }
  169. func (b *Block) copy() *Block {
  170. bCopyRaw, err := copystructure.Copy(b)
  171. if err != nil {
  172. panic(err)
  173. }
  174. bCopy := bCopyRaw.(*Block)
  175. return bCopy
  176. }
  177. // Next prepares the successive block.
  178. func (b *Block) Next() *Block {
  179. blockNext := b.copy()
  180. blockNext.Rollup.Events = eth.NewRollupEvents()
  181. blockNext.Auction.Events = eth.NewAuctionEvents()
  182. blockNext.Eth.BlockNum = b.Eth.BlockNum + 1
  183. blockNext.Eth.ParentHash = b.Eth.Hash
  184. blockNext.Rollup.Constants = b.Rollup.Constants
  185. blockNext.Auction.Constants = b.Auction.Constants
  186. blockNext.Rollup.Eth = blockNext.Eth
  187. blockNext.Auction.Eth = blockNext.Eth
  188. return blockNext
  189. }
  190. // ClientSetup is used to initialize the constants of the Smart Contracts and
  191. // other details of the test Client
  192. type ClientSetup struct {
  193. RollupConstants *eth.RollupPublicConstants
  194. RollupVariables *eth.RollupVariables
  195. AuctionConstants *eth.AuctionConstants
  196. AuctionVariables *eth.AuctionVariables
  197. VerifyProof bool
  198. }
  199. // NewClientSetupExample returns a ClientSetup example with hardcoded realistic values.
  200. //nolint:gomnd
  201. func NewClientSetupExample() *ClientSetup {
  202. // rfield, ok := new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
  203. // if !ok {
  204. // panic("bad rfield")
  205. // }
  206. initialMinimalBidding, ok := new(big.Int).SetString("10000000000000000000", 10) // 10 * (1e18)
  207. if !ok {
  208. panic("bad initialMinimalBidding")
  209. }
  210. tokenHEZ := ethCommon.HexToAddress("0x51D243D62852Bba334DD5cc33f242BAc8c698074")
  211. governanceAddress := ethCommon.HexToAddress("0x688EfD95BA4391f93717CF02A9aED9DBD2855cDd")
  212. rollupConstants := &eth.RollupPublicConstants{
  213. Verifiers: []eth.RollupVerifierStruct{
  214. {
  215. MaxTx: 2048,
  216. NLevels: 32,
  217. },
  218. },
  219. TokenHEZ: tokenHEZ,
  220. HermezGovernanceDAOAddress: governanceAddress,
  221. SafetyAddress: ethCommon.HexToAddress("0x84d8B79E84fe87B14ad61A554e740f6736bF4c20"),
  222. HermezAuctionContract: ethCommon.HexToAddress("0x8E442975805fb1908f43050c9C1A522cB0e28D7b"),
  223. WithdrawDelayerContract: ethCommon.HexToAddress("0x5CB7979cBdbf65719BEE92e4D15b7b7Ed3D79114"),
  224. }
  225. rollupVariables := &eth.RollupVariables{
  226. FeeAddToken: big.NewInt(11),
  227. ForgeL1L2BatchTimeout: 9,
  228. WithdrawalDelay: 80,
  229. }
  230. auctionConstants := &eth.AuctionConstants{
  231. BlocksPerSlot: 40,
  232. InitialMinimalBidding: initialMinimalBidding,
  233. GenesisBlockNum: 0,
  234. GovernanceAddress: governanceAddress,
  235. TokenHEZ: tokenHEZ,
  236. HermezRollup: ethCommon.HexToAddress("0x474B6e29852257491cf283EfB1A9C61eBFe48369"),
  237. }
  238. auctionVariables := &eth.AuctionVariables{
  239. DonationAddress: ethCommon.HexToAddress("0x61Ed87CF0A1496b49A420DA6D84B58196b98f2e7"),
  240. BootCoordinator: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"),
  241. DefaultSlotSetBid: [6]*big.Int{
  242. big.NewInt(1000), big.NewInt(1100), big.NewInt(1200),
  243. big.NewInt(1300), big.NewInt(1400), big.NewInt(1500)},
  244. ClosedAuctionSlots: 2,
  245. OpenAuctionSlots: 4320,
  246. AllocationRatio: [3]uint16{4000, 4000, 2000},
  247. Outbidding: 1000,
  248. SlotDeadline: 20,
  249. }
  250. return &ClientSetup{
  251. RollupConstants: rollupConstants,
  252. RollupVariables: rollupVariables,
  253. AuctionConstants: auctionConstants,
  254. AuctionVariables: auctionVariables,
  255. }
  256. }
  257. // Timer is an interface to simulate a source of time, useful to advance time
  258. // virtually.
  259. type Timer interface {
  260. Time() int64
  261. }
  262. // type forgeBatchArgs struct {
  263. // ethTx *types.Transaction
  264. // blockNum int64
  265. // blockHash ethCommon.Hash
  266. // }
  267. // Client implements the eth.ClientInterface interface, allowing to manipulate the
  268. // values for testing, working with deterministic results.
  269. type Client struct {
  270. rw *sync.RWMutex
  271. log bool
  272. addr *ethCommon.Address
  273. rollupConstants *eth.RollupPublicConstants
  274. auctionConstants *eth.AuctionConstants
  275. blocks map[int64]*Block
  276. // state state
  277. blockNum int64 // last mined block num
  278. maxBlockNum int64 // highest block num calculated
  279. timer Timer
  280. hasher hasher
  281. forgeBatchArgsPending map[ethCommon.Hash]*eth.RollupForgeBatchArgs
  282. forgeBatchArgs map[ethCommon.Hash]*eth.RollupForgeBatchArgs
  283. }
  284. // NewClient returns a new test Client that implements the eth.IClient
  285. // interface, at the given initialBlockNumber.
  286. func NewClient(l bool, timer Timer, addr *ethCommon.Address, setup *ClientSetup) *Client {
  287. blocks := make(map[int64]*Block)
  288. blockNum := int64(0)
  289. hasher := hasher{}
  290. // Add ethereum genesis block
  291. mapL1TxQueue := make(map[int64]*eth.QueueStruct)
  292. mapL1TxQueue[0] = eth.NewQueueStruct()
  293. mapL1TxQueue[1] = eth.NewQueueStruct()
  294. blockCurrent := Block{
  295. Rollup: &RollupBlock{
  296. State: eth.RollupState{
  297. StateRoot: big.NewInt(0),
  298. ExitRoots: make([]*big.Int, 0),
  299. ExitNullifierMap: make(map[[256 / 8]byte]bool),
  300. // TokenID = 0 is ETH. Set first entry in TokenList with 0x0 address for ETH.
  301. TokenList: []ethCommon.Address{{}},
  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. Tokens: make(map[ethCommon.Address]eth.ERC20Consts),
  331. },
  332. }
  333. blockCurrent.Rollup.Eth = blockCurrent.Eth
  334. blockCurrent.Auction.Eth = blockCurrent.Eth
  335. blocks[blockNum] = &blockCurrent
  336. blockNext := blockCurrent.Next()
  337. blocks[blockNum+1] = blockNext
  338. return &Client{
  339. rw: &sync.RWMutex{},
  340. log: l,
  341. addr: addr,
  342. rollupConstants: setup.RollupConstants,
  343. auctionConstants: setup.AuctionConstants,
  344. blocks: blocks,
  345. timer: timer,
  346. hasher: hasher,
  347. forgeBatchArgsPending: make(map[ethCommon.Hash]*eth.RollupForgeBatchArgs),
  348. forgeBatchArgs: make(map[ethCommon.Hash]*eth.RollupForgeBatchArgs),
  349. }
  350. }
  351. //
  352. // Mock Control
  353. //
  354. func (c *Client) setNextBlock(block *Block) {
  355. c.blocks[c.blockNum+1] = block
  356. }
  357. func (c *Client) revertIfErr(err error, block *Block) {
  358. if err != nil {
  359. log.Infow("TestClient revert", "block", block.Eth.BlockNum, "err", err)
  360. c.setNextBlock(block)
  361. }
  362. }
  363. // Debugf calls log.Debugf if c.log is true
  364. func (c *Client) Debugf(template string, args ...interface{}) {
  365. if c.log {
  366. log.Debugf(template, args...)
  367. }
  368. }
  369. // Debugw calls log.Debugw if c.log is true
  370. func (c *Client) Debugw(template string, kv ...interface{}) {
  371. if c.log {
  372. log.Debugw(template, kv...)
  373. }
  374. }
  375. type hasher struct {
  376. counter uint64
  377. }
  378. // Next returns the next hash
  379. func (h *hasher) Next() ethCommon.Hash {
  380. var hash ethCommon.Hash
  381. binary.LittleEndian.PutUint64(hash[:], h.counter)
  382. h.counter++
  383. return hash
  384. }
  385. func (c *Client) nextBlock() *Block {
  386. return c.blocks[c.blockNum+1]
  387. }
  388. func (c *Client) currentBlock() *Block {
  389. return c.blocks[c.blockNum]
  390. }
  391. // CtlSetAddr sets the address of the client
  392. func (c *Client) CtlSetAddr(addr ethCommon.Address) {
  393. c.addr = &addr
  394. }
  395. // CtlMineBlock moves one block forward
  396. func (c *Client) CtlMineBlock() {
  397. c.rw.Lock()
  398. defer c.rw.Unlock()
  399. blockCurrent := c.nextBlock()
  400. c.blockNum++
  401. c.maxBlockNum = c.blockNum
  402. blockCurrent.Eth.Time = c.timer.Time()
  403. blockCurrent.Eth.Hash = c.hasher.Next()
  404. for ethTxHash, forgeBatchArgs := range c.forgeBatchArgsPending {
  405. c.forgeBatchArgs[ethTxHash] = forgeBatchArgs
  406. }
  407. c.forgeBatchArgsPending = make(map[ethCommon.Hash]*eth.RollupForgeBatchArgs)
  408. blockNext := blockCurrent.Next()
  409. c.blocks[c.blockNum+1] = blockNext
  410. c.Debugw("TestClient mined block", "blockNum", c.blockNum)
  411. }
  412. // CtlRollback discards the last mined block. Use this to replace a mined
  413. // block to simulate reorgs.
  414. func (c *Client) CtlRollback() {
  415. c.rw.Lock()
  416. defer c.rw.Unlock()
  417. if c.blockNum == 0 {
  418. panic("Can't rollback at blockNum = 0")
  419. }
  420. delete(c.blocks, c.blockNum+1) // delete next block
  421. delete(c.blocks, c.blockNum) // delete current block
  422. c.blockNum--
  423. blockCurrent := c.blocks[c.blockNum]
  424. blockNext := blockCurrent.Next()
  425. c.blocks[c.blockNum+1] = blockNext
  426. }
  427. //
  428. // Ethereum
  429. //
  430. // EthCurrentBlock returns the current blockNum
  431. func (c *Client) EthCurrentBlock() (int64, error) {
  432. c.rw.RLock()
  433. defer c.rw.RUnlock()
  434. if c.blockNum < c.maxBlockNum {
  435. panic("blockNum has decreased. " +
  436. "After a rollback you must mine to reach the same or higher blockNum")
  437. }
  438. return c.blockNum, nil
  439. }
  440. // EthTransactionReceipt returns the transaction receipt of the given txHash
  441. func (c *Client) EthTransactionReceipt(ctx context.Context, txHash ethCommon.Hash) (*types.Receipt, error) {
  442. c.rw.RLock()
  443. defer c.rw.RUnlock()
  444. for i := int64(0); i < c.blockNum; i++ {
  445. b := c.blocks[i]
  446. _, ok := b.Rollup.Txs[txHash]
  447. if !ok {
  448. _, ok = b.Auction.Txs[txHash]
  449. }
  450. if ok {
  451. return &types.Receipt{
  452. TxHash: txHash,
  453. Status: types.ReceiptStatusSuccessful,
  454. BlockHash: b.Eth.Hash,
  455. BlockNumber: big.NewInt(b.Eth.BlockNum),
  456. }, nil
  457. }
  458. }
  459. return nil, nil
  460. }
  461. // CtlAddERC20 adds an ERC20 token to the blockchain.
  462. func (c *Client) CtlAddERC20(tokenAddr ethCommon.Address, constants eth.ERC20Consts) {
  463. nextBlock := c.nextBlock()
  464. e := nextBlock.Eth
  465. e.Tokens[tokenAddr] = constants
  466. }
  467. // EthERC20Consts returns the constants defined for a particular ERC20 Token instance.
  468. func (c *Client) EthERC20Consts(tokenAddr ethCommon.Address) (*eth.ERC20Consts, error) {
  469. currentBlock := c.currentBlock()
  470. e := currentBlock.Eth
  471. if constants, ok := e.Tokens[tokenAddr]; ok {
  472. return &constants, nil
  473. }
  474. return nil, fmt.Errorf("tokenAddr not found")
  475. }
  476. // func newHeader(number *big.Int) *types.Header {
  477. // return &types.Header{
  478. // Number: number,
  479. // Time: uint64(number.Int64()),
  480. // }
  481. // }
  482. // EthHeaderByNumber returns the *types.Header for the given block number in a
  483. // deterministic way.
  484. // func (c *Client) EthHeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
  485. // return newHeader(number), nil
  486. // }
  487. // EthBlockByNumber returns the *common.Block for the given block number in a
  488. // deterministic way.
  489. func (c *Client) EthBlockByNumber(ctx context.Context, blockNum int64) (*common.Block, error) {
  490. c.rw.RLock()
  491. defer c.rw.RUnlock()
  492. block, ok := c.blocks[blockNum]
  493. if !ok {
  494. return nil, fmt.Errorf("block not found")
  495. }
  496. return &common.Block{
  497. EthBlockNum: blockNum,
  498. Timestamp: time.Unix(block.Eth.Time, 0),
  499. Hash: block.Eth.Hash,
  500. ParentHash: block.Eth.ParentHash,
  501. }, nil
  502. }
  503. // EthAddress returns the ethereum address of the account loaded into the Client
  504. func (c *Client) EthAddress() (*ethCommon.Address, error) {
  505. if c.addr == nil {
  506. return nil, eth.ErrAccountNil
  507. }
  508. return c.addr, nil
  509. }
  510. var errTODO = fmt.Errorf("TODO: Not implemented yet")
  511. //
  512. // Rollup
  513. //
  514. // CtlAddL1TxUser adds an L1TxUser to the L1UserTxs queue of the Rollup
  515. func (c *Client) CtlAddL1TxUser(l1Tx *common.L1Tx) {
  516. c.rw.Lock()
  517. defer c.rw.Unlock()
  518. nextBlock := c.nextBlock()
  519. r := nextBlock.Rollup
  520. queue := r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum]
  521. if len(queue.L1TxQueue) >= eth.RollupConstMaxL1UserTx {
  522. r.State.LastToForgeL1TxsNum++
  523. r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum] = eth.NewQueueStruct()
  524. queue = r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum]
  525. }
  526. if int64(l1Tx.FromIdx) > r.State.CurrentIdx {
  527. panic("l1Tx.FromIdx > r.State.CurrentIdx")
  528. }
  529. if int(l1Tx.TokenID)+1 > len(r.State.TokenList) {
  530. panic("l1Tx.TokenID + 1 > len(r.State.TokenList)")
  531. }
  532. queue.L1TxQueue = append(queue.L1TxQueue, *l1Tx)
  533. r.Events.L1UserTx = append(r.Events.L1UserTx, eth.RollupEventL1UserTx{
  534. L1UserTx: *l1Tx,
  535. ToForgeL1TxsNum: r.State.LastToForgeL1TxsNum,
  536. Position: len(queue.L1TxQueue) - 1,
  537. })
  538. }
  539. // RollupL1UserTxERC20ETH is the interface to call the smart contract function
  540. func (c *Client) RollupL1UserTxERC20ETH(fromBJJ *babyjub.PublicKey, fromIdx int64, loadAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64) (*types.Transaction, error) {
  541. log.Error("TODO")
  542. return nil, errTODO
  543. }
  544. // RollupL1UserTxERC777 is the interface to call the smart contract function
  545. func (c *Client) RollupL1UserTxERC777(fromBJJ *babyjub.PublicKey, fromIdx int64, loadAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64) (*types.Transaction, error) {
  546. log.Error("TODO")
  547. return nil, errTODO
  548. }
  549. // RollupRegisterTokensCount is the interface to call the smart contract function
  550. func (c *Client) RollupRegisterTokensCount() (*big.Int, error) {
  551. log.Error("TODO")
  552. return nil, errTODO
  553. }
  554. // RollupWithdrawCircuit is the interface to call the smart contract function
  555. func (c *Client) RollupWithdrawCircuit(proofA, proofC [2]*big.Int, proofB [2][2]*big.Int, tokenID uint32, numExitRoot, idx int64, amount *big.Int, instantWithdraw bool) (*types.Transaction, error) {
  556. log.Error("TODO")
  557. return nil, errTODO
  558. }
  559. // RollupWithdrawMerkleProof is the interface to call the smart contract function
  560. func (c *Client) RollupWithdrawMerkleProof(babyPubKey *babyjub.PublicKey, tokenID uint32, numExitRoot, idx int64, amount *big.Int, siblings []*big.Int, instantWithdraw bool) (*types.Transaction, error) {
  561. log.Error("TODO")
  562. return nil, errTODO
  563. }
  564. type transactionData struct {
  565. Name string
  566. Value interface{}
  567. }
  568. func newTransaction(name string, value interface{}) *types.Transaction {
  569. data, err := json.Marshal(transactionData{name, value})
  570. if err != nil {
  571. panic(err)
  572. }
  573. return types.NewTransaction(0, ethCommon.Address{}, nil, 0, nil,
  574. data)
  575. }
  576. // RollupForgeBatch is the interface to call the smart contract function
  577. func (c *Client) RollupForgeBatch(args *eth.RollupForgeBatchArgs) (tx *types.Transaction, err error) {
  578. c.rw.Lock()
  579. defer c.rw.Unlock()
  580. cpy := c.nextBlock().copy()
  581. defer func() { c.revertIfErr(err, cpy) }()
  582. if c.addr == nil {
  583. return nil, eth.ErrAccountNil
  584. }
  585. a := c.nextBlock().Auction
  586. ok, err := a.canForge(*c.addr, a.Eth.BlockNum)
  587. if err != nil {
  588. return nil, err
  589. }
  590. if !ok {
  591. return nil, fmt.Errorf("incorrect slot")
  592. }
  593. // TODO: Verify proof
  594. // Auction
  595. err = a.forge(*c.addr)
  596. if err != nil {
  597. return nil, err
  598. }
  599. // TODO: If successful, store the tx in a successful array.
  600. // TODO: If failed, store the tx in a failed array.
  601. // TODO: Add method to move the tx to another block, reapply it there, and possibly go from successful to failed.
  602. return c.addBatch(args)
  603. }
  604. // CtlAddBatch adds forged batch to the Rollup, without checking any ZKProof
  605. func (c *Client) CtlAddBatch(args *eth.RollupForgeBatchArgs) {
  606. c.rw.Lock()
  607. defer c.rw.Unlock()
  608. if _, err := c.addBatch(args); err != nil {
  609. panic(err)
  610. }
  611. }
  612. func (c *Client) addBatch(args *eth.RollupForgeBatchArgs) (*types.Transaction, error) {
  613. nextBlock := c.nextBlock()
  614. r := nextBlock.Rollup
  615. r.State.StateRoot = args.NewStRoot
  616. if args.NewLastIdx < r.State.CurrentIdx {
  617. return nil, fmt.Errorf("args.NewLastIdx < r.State.CurrentIdx")
  618. }
  619. r.State.CurrentIdx = args.NewLastIdx
  620. r.State.ExitRoots = append(r.State.ExitRoots, args.NewExitRoot)
  621. if args.L1Batch {
  622. r.State.CurrentToForgeL1TxsNum++
  623. if r.State.CurrentToForgeL1TxsNum == r.State.LastToForgeL1TxsNum {
  624. r.State.LastToForgeL1TxsNum++
  625. r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum] = eth.NewQueueStruct()
  626. }
  627. }
  628. ethTx := r.addTransaction(newTransaction("forgebatch", args))
  629. c.forgeBatchArgsPending[ethTx.Hash()] = args
  630. r.Events.ForgeBatch = append(r.Events.ForgeBatch, eth.RollupEventForgeBatch{
  631. BatchNum: int64(len(r.State.ExitRoots)),
  632. EthTxHash: ethTx.Hash(),
  633. })
  634. return ethTx, nil
  635. }
  636. // RollupAddToken is the interface to call the smart contract function
  637. func (c *Client) RollupAddToken(tokenAddress ethCommon.Address, feeAddToken *big.Int) (tx *types.Transaction, err error) {
  638. c.rw.Lock()
  639. defer c.rw.Unlock()
  640. cpy := c.nextBlock().copy()
  641. defer func() { c.revertIfErr(err, cpy) }()
  642. if c.addr == nil {
  643. return nil, eth.ErrAccountNil
  644. }
  645. nextBlock := c.nextBlock()
  646. r := nextBlock.Rollup
  647. if _, ok := r.State.TokenMap[tokenAddress]; ok {
  648. return nil, fmt.Errorf("Token %v already registered", tokenAddress)
  649. }
  650. if feeAddToken.Cmp(r.Vars.FeeAddToken) != 0 {
  651. return nil, fmt.Errorf("Expected fee: %v but got: %v", r.Vars.FeeAddToken, feeAddToken)
  652. }
  653. r.State.TokenMap[tokenAddress] = true
  654. r.State.TokenList = append(r.State.TokenList, tokenAddress)
  655. r.Events.AddToken = append(r.Events.AddToken, eth.RollupEventAddToken{TokenAddress: tokenAddress,
  656. TokenID: uint32(len(r.State.TokenList) - 1)})
  657. return r.addTransaction(newTransaction("addtoken", tokenAddress)), nil
  658. }
  659. // RollupGetCurrentTokens is the interface to call the smart contract function
  660. func (c *Client) RollupGetCurrentTokens() (*big.Int, error) {
  661. c.rw.RLock()
  662. defer c.rw.RUnlock()
  663. log.Error("TODO")
  664. return nil, errTODO
  665. }
  666. // RollupUpdateForgeL1L2BatchTimeout is the interface to call the smart contract function
  667. func (c *Client) RollupUpdateForgeL1L2BatchTimeout(newForgeL1Timeout int64) (tx *types.Transaction, err error) {
  668. c.rw.Lock()
  669. defer c.rw.Unlock()
  670. cpy := c.nextBlock().copy()
  671. defer func() { c.revertIfErr(err, cpy) }()
  672. if c.addr == nil {
  673. return nil, eth.ErrAccountNil
  674. }
  675. log.Error("TODO")
  676. return nil, errTODO
  677. }
  678. // RollupUpdateFeeAddToken is the interface to call the smart contract function
  679. func (c *Client) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (tx *types.Transaction, err error) {
  680. c.rw.Lock()
  681. defer c.rw.Unlock()
  682. cpy := c.nextBlock().copy()
  683. defer func() { c.revertIfErr(err, cpy) }()
  684. if c.addr == nil {
  685. return nil, eth.ErrAccountNil
  686. }
  687. log.Error("TODO")
  688. return nil, errTODO
  689. }
  690. // RollupUpdateTokensHEZ is the interface to call the smart contract function
  691. // func (c *Client) RollupUpdateTokensHEZ(newTokenHEZ ethCommon.Address) (tx *types.Transaction, err error) {
  692. // c.rw.Lock()
  693. // defer c.rw.Unlock()
  694. // cpy := c.nextBlock().copy()
  695. // defer func() { c.revertIfErr(err, cpy) }()
  696. //
  697. // log.Error("TODO")
  698. // return nil, errTODO
  699. // }
  700. // RollupUpdateGovernance is the interface to call the smart contract function
  701. // func (c *Client) RollupUpdateGovernance() (*types.Transaction, error) { // TODO (Not defined in Hermez.sol)
  702. // return nil, errTODO
  703. // }
  704. // RollupConstants returns the Constants of the Rollup Smart Contract
  705. func (c *Client) RollupConstants() (*eth.RollupPublicConstants, error) {
  706. c.rw.RLock()
  707. defer c.rw.RUnlock()
  708. log.Error("TODO")
  709. return nil, errTODO
  710. }
  711. // RollupEventsByBlock returns the events in a block that happened in the Rollup Smart Contract
  712. func (c *Client) RollupEventsByBlock(blockNum int64) (*eth.RollupEvents, *ethCommon.Hash, error) {
  713. c.rw.RLock()
  714. defer c.rw.RUnlock()
  715. block, ok := c.blocks[blockNum]
  716. if !ok {
  717. return nil, nil, fmt.Errorf("Block %v doesn't exist", blockNum)
  718. }
  719. return &block.Rollup.Events, &block.Eth.Hash, nil
  720. }
  721. // RollupForgeBatchArgs returns the arguments used in a ForgeBatch call in the Rollup Smart Contract in the given transaction
  722. func (c *Client) RollupForgeBatchArgs(ethTxHash ethCommon.Hash) (*eth.RollupForgeBatchArgs, error) {
  723. c.rw.RLock()
  724. defer c.rw.RUnlock()
  725. forgeBatchArgs, ok := c.forgeBatchArgs[ethTxHash]
  726. if !ok {
  727. return nil, fmt.Errorf("transaction not found")
  728. }
  729. return forgeBatchArgs, nil
  730. }
  731. //
  732. // Auction
  733. //
  734. // AuctionSetSlotDeadline is the interface to call the smart contract function
  735. func (c *Client) AuctionSetSlotDeadline(newDeadline uint8) (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. log.Error("TODO")
  744. return nil, errTODO
  745. }
  746. // AuctionGetSlotDeadline is the interface to call the smart contract function
  747. func (c *Client) AuctionGetSlotDeadline() (uint8, error) {
  748. c.rw.RLock()
  749. defer c.rw.RUnlock()
  750. log.Error("TODO")
  751. return 0, errTODO
  752. }
  753. // AuctionSetOpenAuctionSlots is the interface to call the smart contract function
  754. func (c *Client) AuctionSetOpenAuctionSlots(newOpenAuctionSlots uint16) (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. log.Error("TODO")
  763. return nil, errTODO
  764. }
  765. // AuctionGetOpenAuctionSlots is the interface to call the smart contract function
  766. func (c *Client) AuctionGetOpenAuctionSlots() (uint16, error) {
  767. c.rw.RLock()
  768. defer c.rw.RUnlock()
  769. log.Error("TODO")
  770. return 0, errTODO
  771. }
  772. // AuctionSetClosedAuctionSlots is the interface to call the smart contract function
  773. func (c *Client) AuctionSetClosedAuctionSlots(newClosedAuctionSlots uint16) (tx *types.Transaction, err error) {
  774. c.rw.Lock()
  775. defer c.rw.Unlock()
  776. cpy := c.nextBlock().copy()
  777. defer func() { c.revertIfErr(err, cpy) }()
  778. if c.addr == nil {
  779. return nil, eth.ErrAccountNil
  780. }
  781. log.Error("TODO")
  782. return nil, errTODO
  783. }
  784. // AuctionGetClosedAuctionSlots is the interface to call the smart contract function
  785. func (c *Client) AuctionGetClosedAuctionSlots() (uint16, error) {
  786. c.rw.RLock()
  787. defer c.rw.RUnlock()
  788. log.Error("TODO")
  789. return 0, errTODO
  790. }
  791. // AuctionSetOutbidding is the interface to call the smart contract function
  792. func (c *Client) AuctionSetOutbidding(newOutbidding uint16) (tx *types.Transaction, err error) {
  793. c.rw.Lock()
  794. defer c.rw.Unlock()
  795. cpy := c.nextBlock().copy()
  796. defer func() { c.revertIfErr(err, cpy) }()
  797. if c.addr == nil {
  798. return nil, eth.ErrAccountNil
  799. }
  800. log.Error("TODO")
  801. return nil, errTODO
  802. }
  803. // AuctionGetOutbidding is the interface to call the smart contract function
  804. func (c *Client) AuctionGetOutbidding() (uint16, error) {
  805. c.rw.RLock()
  806. defer c.rw.RUnlock()
  807. log.Error("TODO")
  808. return 0, errTODO
  809. }
  810. // AuctionSetAllocationRatio is the interface to call the smart contract function
  811. func (c *Client) AuctionSetAllocationRatio(newAllocationRatio [3]uint16) (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. // AuctionGetAllocationRatio is the interface to call the smart contract function
  823. func (c *Client) AuctionGetAllocationRatio() ([3]uint16, error) {
  824. c.rw.RLock()
  825. defer c.rw.RUnlock()
  826. log.Error("TODO")
  827. return [3]uint16{}, errTODO
  828. }
  829. // AuctionSetDonationAddress is the interface to call the smart contract function
  830. func (c *Client) AuctionSetDonationAddress(newDonationAddress ethCommon.Address) (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. // AuctionGetDonationAddress is the interface to call the smart contract function
  842. func (c *Client) AuctionGetDonationAddress() (*ethCommon.Address, error) {
  843. c.rw.RLock()
  844. defer c.rw.RUnlock()
  845. log.Error("TODO")
  846. return nil, errTODO
  847. }
  848. // AuctionSetBootCoordinator is the interface to call the smart contract function
  849. func (c *Client) AuctionSetBootCoordinator(newBootCoordinator ethCommon.Address) (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. // AuctionGetBootCoordinator is the interface to call the smart contract function
  861. func (c *Client) AuctionGetBootCoordinator() (*ethCommon.Address, error) {
  862. c.rw.RLock()
  863. defer c.rw.RUnlock()
  864. currentBlock := c.currentBlock()
  865. a := currentBlock.Auction
  866. return &a.Vars.BootCoordinator, nil
  867. }
  868. // AuctionChangeDefaultSlotSetBid is the interface to call the smart contract function
  869. func (c *Client) AuctionChangeDefaultSlotSetBid(slotSet int64, newInitialMinBid *big.Int) (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. log.Error("TODO")
  878. return nil, errTODO
  879. }
  880. // AuctionSetCoordinator is the interface to call the smart contract function
  881. func (c *Client) AuctionSetCoordinator(forger ethCommon.Address, URL string) (tx *types.Transaction, err error) {
  882. c.rw.Lock()
  883. defer c.rw.Unlock()
  884. cpy := c.nextBlock().copy()
  885. defer func() { c.revertIfErr(err, cpy) }()
  886. if c.addr == nil {
  887. return nil, eth.ErrAccountNil
  888. }
  889. nextBlock := c.nextBlock()
  890. a := nextBlock.Auction
  891. a.State.Coordinators[*c.addr] = &eth.Coordinator{
  892. Forger: forger,
  893. URL: URL,
  894. }
  895. a.Events.SetCoordinator = append(a.Events.SetCoordinator,
  896. eth.AuctionEventSetCoordinator{
  897. BidderAddress: *c.addr,
  898. ForgerAddress: forger,
  899. CoordinatorURL: URL,
  900. })
  901. type data struct {
  902. BidderAddress ethCommon.Address
  903. ForgerAddress ethCommon.Address
  904. URL string
  905. }
  906. return a.addTransaction(newTransaction("registercoordinator", data{*c.addr, forger, URL})), nil
  907. }
  908. // AuctionIsRegisteredCoordinator is the interface to call the smart contract function
  909. func (c *Client) AuctionIsRegisteredCoordinator(forgerAddress ethCommon.Address) (bool, error) {
  910. c.rw.RLock()
  911. defer c.rw.RUnlock()
  912. log.Error("TODO")
  913. return false, errTODO
  914. }
  915. // AuctionUpdateCoordinatorInfo is the interface to call the smart contract function
  916. func (c *Client) AuctionUpdateCoordinatorInfo(forgerAddress ethCommon.Address, newWithdrawAddress ethCommon.Address, newURL string) (tx *types.Transaction, err error) {
  917. c.rw.Lock()
  918. defer c.rw.Unlock()
  919. cpy := c.nextBlock().copy()
  920. defer func() { c.revertIfErr(err, cpy) }()
  921. if c.addr == nil {
  922. return nil, eth.ErrAccountNil
  923. }
  924. log.Error("TODO")
  925. return nil, errTODO
  926. }
  927. // AuctionGetSlotNumber is the interface to call the smart contract function
  928. func (c *Client) AuctionGetSlotNumber(blockNum int64) (int64, error) {
  929. c.rw.RLock()
  930. defer c.rw.RUnlock()
  931. currentBlock := c.currentBlock()
  932. a := currentBlock.Auction
  933. return a.getSlotNumber(blockNum), nil
  934. }
  935. // AuctionGetCurrentSlotNumber is the interface to call the smart contract function
  936. func (c *Client) AuctionGetCurrentSlotNumber() (int64, error) {
  937. c.rw.RLock()
  938. defer c.rw.RUnlock()
  939. log.Error("TODO")
  940. return 0, errTODO
  941. }
  942. // AuctionGetMinBidBySlot is the interface to call the smart contract function
  943. func (c *Client) AuctionGetMinBidBySlot(slot int64) (*big.Int, error) {
  944. c.rw.RLock()
  945. defer c.rw.RUnlock()
  946. log.Error("TODO")
  947. return nil, errTODO
  948. }
  949. // AuctionGetDefaultSlotSetBid is the interface to call the smart contract function
  950. func (c *Client) AuctionGetDefaultSlotSetBid(slotSet uint8) (*big.Int, error) {
  951. c.rw.RLock()
  952. defer c.rw.RUnlock()
  953. log.Error("TODO")
  954. return nil, errTODO
  955. }
  956. // AuctionGetSlotSet is the interface to call the smart contract function
  957. func (c *Client) AuctionGetSlotSet(slot int64) (*big.Int, error) {
  958. c.rw.RLock()
  959. defer c.rw.RUnlock()
  960. log.Error("TODO")
  961. return nil, errTODO
  962. }
  963. // AuctionTokensReceived is the interface to call the smart contract function
  964. // func (c *Client) AuctionTokensReceived(operator, from, to ethCommon.Address, amount *big.Int, userData, operatorData []byte) error {
  965. // return errTODO
  966. // }
  967. // AuctionBid is the interface to call the smart contract function
  968. func (c *Client) AuctionBid(slot int64, bidAmount *big.Int) (tx *types.Transaction, err error) {
  969. c.rw.Lock()
  970. defer c.rw.Unlock()
  971. cpy := c.nextBlock().copy()
  972. defer func() { func() { c.revertIfErr(err, cpy) }() }()
  973. if c.addr == nil {
  974. return nil, eth.ErrAccountNil
  975. }
  976. nextBlock := c.nextBlock()
  977. a := nextBlock.Auction
  978. if slot < a.getCurrentSlotNumber()+int64(a.Vars.ClosedAuctionSlots) {
  979. return nil, errBidClosed
  980. }
  981. if slot >= a.getCurrentSlotNumber()+int64(a.Vars.ClosedAuctionSlots)+int64(a.Vars.OpenAuctionSlots) {
  982. return nil, errBidNotOpen
  983. }
  984. minBid, err := a.getMinBidBySlot(slot)
  985. if err != nil {
  986. return nil, err
  987. }
  988. if bidAmount.Cmp(minBid) == -1 {
  989. return nil, errBidBelowMin
  990. }
  991. if _, ok := a.State.Coordinators[*c.addr]; !ok {
  992. return nil, errCoordNotReg
  993. }
  994. slotState, ok := a.State.Slots[slot]
  995. if !ok {
  996. slotState = eth.NewSlotState()
  997. a.State.Slots[slot] = slotState
  998. }
  999. slotState.Bidder = *c.addr
  1000. slotState.BidAmount = bidAmount
  1001. a.Events.NewBid = append(a.Events.NewBid,
  1002. eth.AuctionEventNewBid{Slot: slot, BidAmount: bidAmount, Bidder: *c.addr})
  1003. type data struct {
  1004. Slot int64
  1005. BidAmount *big.Int
  1006. Bidder ethCommon.Address
  1007. }
  1008. return a.addTransaction(newTransaction("bid", data{slot, bidAmount, *c.addr})), nil
  1009. }
  1010. // AuctionMultiBid is the interface to call the smart contract function
  1011. func (c *Client) AuctionMultiBid(startingSlot int64, endingSlot int64, slotSet [6]bool, maxBid, closedMinBid, budget *big.Int) (tx *types.Transaction, err error) {
  1012. c.rw.Lock()
  1013. defer c.rw.Unlock()
  1014. cpy := c.nextBlock().copy()
  1015. defer func() { c.revertIfErr(err, cpy) }()
  1016. if c.addr == nil {
  1017. return nil, eth.ErrAccountNil
  1018. }
  1019. log.Error("TODO")
  1020. return nil, errTODO
  1021. }
  1022. // AuctionCanForge is the interface to call the smart contract function
  1023. func (c *Client) AuctionCanForge(forger ethCommon.Address, blockNum int64) (bool, error) {
  1024. c.rw.RLock()
  1025. defer c.rw.RUnlock()
  1026. currentBlock := c.currentBlock()
  1027. a := currentBlock.Auction
  1028. return a.canForge(forger, blockNum)
  1029. }
  1030. // AuctionForge is the interface to call the smart contract function
  1031. func (c *Client) AuctionForge(forger ethCommon.Address) (tx *types.Transaction, err error) {
  1032. c.rw.Lock()
  1033. defer c.rw.Unlock()
  1034. cpy := c.nextBlock().copy()
  1035. defer func() { c.revertIfErr(err, cpy) }()
  1036. if c.addr == nil {
  1037. return nil, eth.ErrAccountNil
  1038. }
  1039. log.Error("TODO")
  1040. return nil, errTODO
  1041. }
  1042. // AuctionClaimHEZ is the interface to call the smart contract function
  1043. func (c *Client) AuctionClaimHEZ() (tx *types.Transaction, err error) {
  1044. c.rw.Lock()
  1045. defer c.rw.Unlock()
  1046. cpy := c.nextBlock().copy()
  1047. defer func() { c.revertIfErr(err, cpy) }()
  1048. if c.addr == nil {
  1049. return nil, eth.ErrAccountNil
  1050. }
  1051. log.Error("TODO")
  1052. return nil, errTODO
  1053. }
  1054. // AuctionGetClaimableHEZ is the interface to call the smart contract function
  1055. func (c *Client) AuctionGetClaimableHEZ(bidder ethCommon.Address) (*big.Int, error) {
  1056. c.rw.RLock()
  1057. defer c.rw.RUnlock()
  1058. log.Error("TODO")
  1059. return nil, errTODO
  1060. }
  1061. // AuctionConstants returns the Constants of the Auction Smart Contract
  1062. func (c *Client) AuctionConstants() (*eth.AuctionConstants, error) {
  1063. c.rw.RLock()
  1064. defer c.rw.RUnlock()
  1065. return c.auctionConstants, nil
  1066. }
  1067. // AuctionEventsByBlock returns the events in a block that happened in the Auction Smart Contract
  1068. func (c *Client) AuctionEventsByBlock(blockNum int64) (*eth.AuctionEvents, *ethCommon.Hash, error) {
  1069. c.rw.RLock()
  1070. defer c.rw.RUnlock()
  1071. block, ok := c.blocks[blockNum]
  1072. if !ok {
  1073. return nil, nil, fmt.Errorf("Block %v doesn't exist", blockNum)
  1074. }
  1075. return &block.Auction.Events, &block.Eth.Hash, nil
  1076. }