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.

1364 lines
39 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. L1Tx: *l1Tx,
  535. ToForgeL1TxsNum: r.State.LastToForgeL1TxsNum,
  536. Position: len(queue.L1TxQueue) - 1,
  537. })
  538. }
  539. type transactionData struct {
  540. Name string
  541. Value interface{}
  542. }
  543. func newTransaction(name string, value interface{}) *types.Transaction {
  544. data, err := json.Marshal(transactionData{name, value})
  545. if err != nil {
  546. panic(err)
  547. }
  548. return types.NewTransaction(0, ethCommon.Address{}, nil, 0, nil,
  549. data)
  550. }
  551. // RollupForgeBatch is the interface to call the smart contract function
  552. func (c *Client) RollupForgeBatch(args *eth.RollupForgeBatchArgs) (tx *types.Transaction, err error) {
  553. c.rw.Lock()
  554. defer c.rw.Unlock()
  555. cpy := c.nextBlock().copy()
  556. defer func() { c.revertIfErr(err, cpy) }()
  557. if c.addr == nil {
  558. return nil, eth.ErrAccountNil
  559. }
  560. a := c.nextBlock().Auction
  561. ok, err := a.canForge(*c.addr, a.Eth.BlockNum)
  562. if err != nil {
  563. return nil, err
  564. }
  565. if !ok {
  566. return nil, fmt.Errorf("incorrect slot")
  567. }
  568. // TODO: Verify proof
  569. // Auction
  570. err = a.forge(*c.addr)
  571. if err != nil {
  572. return nil, err
  573. }
  574. // TODO: If successful, store the tx in a successful array.
  575. // TODO: If failed, store the tx in a failed array.
  576. // TODO: Add method to move the tx to another block, reapply it there, and possibly go from successful to failed.
  577. return c.addBatch(args)
  578. }
  579. // CtlAddBatch adds forged batch to the Rollup, without checking any ZKProof
  580. func (c *Client) CtlAddBatch(args *eth.RollupForgeBatchArgs) {
  581. c.rw.Lock()
  582. defer c.rw.Unlock()
  583. if _, err := c.addBatch(args); err != nil {
  584. panic(err)
  585. }
  586. }
  587. func (c *Client) addBatch(args *eth.RollupForgeBatchArgs) (*types.Transaction, error) {
  588. nextBlock := c.nextBlock()
  589. r := nextBlock.Rollup
  590. r.State.StateRoot = args.NewStRoot
  591. if args.NewLastIdx < r.State.CurrentIdx {
  592. return nil, fmt.Errorf("args.NewLastIdx < r.State.CurrentIdx")
  593. }
  594. r.State.CurrentIdx = args.NewLastIdx
  595. r.State.ExitRoots = append(r.State.ExitRoots, args.NewExitRoot)
  596. if args.L1Batch {
  597. r.State.CurrentToForgeL1TxsNum++
  598. if r.State.CurrentToForgeL1TxsNum == r.State.LastToForgeL1TxsNum {
  599. r.State.LastToForgeL1TxsNum++
  600. r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum] = eth.NewQueueStruct()
  601. }
  602. }
  603. ethTx := r.addTransaction(newTransaction("forgebatch", args))
  604. c.forgeBatchArgsPending[ethTx.Hash()] = args
  605. r.Events.ForgeBatch = append(r.Events.ForgeBatch, eth.RollupEventForgeBatch{
  606. BatchNum: int64(len(r.State.ExitRoots)),
  607. EthTxHash: ethTx.Hash(),
  608. })
  609. return ethTx, nil
  610. }
  611. // RollupAddToken is the interface to call the smart contract function
  612. func (c *Client) RollupAddToken(tokenAddress ethCommon.Address) (tx *types.Transaction, err error) {
  613. c.rw.Lock()
  614. defer c.rw.Unlock()
  615. cpy := c.nextBlock().copy()
  616. defer func() { c.revertIfErr(err, cpy) }()
  617. if c.addr == nil {
  618. return nil, eth.ErrAccountNil
  619. }
  620. nextBlock := c.nextBlock()
  621. r := nextBlock.Rollup
  622. if _, ok := r.State.TokenMap[tokenAddress]; ok {
  623. return nil, fmt.Errorf("Token %v already registered", tokenAddress)
  624. }
  625. r.State.TokenMap[tokenAddress] = true
  626. r.State.TokenList = append(r.State.TokenList, tokenAddress)
  627. r.Events.AddToken = append(r.Events.AddToken, eth.RollupEventAddToken{Address: tokenAddress,
  628. TokenID: uint32(len(r.State.TokenList) - 1)})
  629. return r.addTransaction(newTransaction("addtoken", tokenAddress)), nil
  630. }
  631. // RollupWithdrawSNARK is the interface to call the smart contract function
  632. // func (c *Client) RollupWithdrawSNARK() (*types.Transaction, error) { // TODO (Not defined in Hermez.sol)
  633. // return nil, errTODO
  634. // }
  635. // RollupWithdraw is the interface to call the smart contract function
  636. 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) {
  637. c.rw.Lock()
  638. defer c.rw.Unlock()
  639. cpy := c.nextBlock().copy()
  640. defer func() { c.revertIfErr(err, cpy) }()
  641. if c.addr == nil {
  642. return nil, eth.ErrAccountNil
  643. }
  644. log.Error("TODO")
  645. return nil, errTODO
  646. }
  647. // RollupForceExit is the interface to call the smart contract function
  648. func (c *Client) RollupForceExit(fromIdx int64, amountF common.Float16, tokenID int64) (tx *types.Transaction, err error) {
  649. c.rw.Lock()
  650. defer c.rw.Unlock()
  651. cpy := c.nextBlock().copy()
  652. defer func() { c.revertIfErr(err, cpy) }()
  653. if c.addr == nil {
  654. return nil, eth.ErrAccountNil
  655. }
  656. log.Error("TODO")
  657. return nil, errTODO
  658. }
  659. // RollupForceTransfer is the interface to call the smart contract function
  660. func (c *Client) RollupForceTransfer(fromIdx int64, amountF common.Float16, tokenID, toIdx int64) (tx *types.Transaction, err error) {
  661. c.rw.Lock()
  662. defer c.rw.Unlock()
  663. cpy := c.nextBlock().copy()
  664. defer func() { c.revertIfErr(err, cpy) }()
  665. if c.addr == nil {
  666. return nil, eth.ErrAccountNil
  667. }
  668. log.Error("TODO")
  669. return nil, errTODO
  670. }
  671. // RollupCreateAccountDepositTransfer is the interface to call the smart contract function
  672. func (c *Client) RollupCreateAccountDepositTransfer(babyPubKey babyjub.PublicKey, loadAmountF, amountF common.Float16, tokenID int64, toIdx int64) (tx *types.Transaction, err error) {
  673. c.rw.Lock()
  674. defer c.rw.Unlock()
  675. cpy := c.nextBlock().copy()
  676. defer func() { c.revertIfErr(err, cpy) }()
  677. if c.addr == nil {
  678. return nil, eth.ErrAccountNil
  679. }
  680. log.Error("TODO")
  681. return nil, errTODO
  682. }
  683. // RollupGetCurrentTokens is the interface to call the smart contract function
  684. func (c *Client) RollupGetCurrentTokens() (*big.Int, error) {
  685. c.rw.RLock()
  686. defer c.rw.RUnlock()
  687. log.Error("TODO")
  688. return nil, errTODO
  689. }
  690. // RollupDepositTransfer is the interface to call the smart contract function
  691. func (c *Client) RollupDepositTransfer(fromIdx int64, loadAmountF, amountF common.Float16, tokenID int64, toIdx int64) (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. if c.addr == nil {
  697. return nil, eth.ErrAccountNil
  698. }
  699. log.Error("TODO")
  700. return nil, errTODO
  701. }
  702. // RollupDeposit is the interface to call the smart contract function
  703. func (c *Client) RollupDeposit(fromIdx int64, loadAmountF common.Float16, tokenID int64) (tx *types.Transaction, err error) {
  704. c.rw.Lock()
  705. defer c.rw.Unlock()
  706. cpy := c.nextBlock().copy()
  707. defer func() { c.revertIfErr(err, cpy) }()
  708. if c.addr == nil {
  709. return nil, eth.ErrAccountNil
  710. }
  711. log.Error("TODO")
  712. return nil, errTODO
  713. }
  714. // RollupCreateAccountDepositFromRelayer is the interface to call the smart contract function
  715. func (c *Client) RollupCreateAccountDepositFromRelayer(accountCreationAuthSig []byte, babyPubKey babyjub.PublicKey, loadAmountF common.Float16) (tx *types.Transaction, err error) {
  716. c.rw.Lock()
  717. defer c.rw.Unlock()
  718. cpy := c.nextBlock().copy()
  719. defer func() { c.revertIfErr(err, cpy) }()
  720. if c.addr == nil {
  721. return nil, eth.ErrAccountNil
  722. }
  723. log.Error("TODO")
  724. return nil, errTODO
  725. }
  726. // RollupCreateAccountDeposit is the interface to call the smart contract function
  727. func (c *Client) RollupCreateAccountDeposit(babyPubKey babyjub.PublicKey, loadAmountF common.Float16, tokenID int64) (tx *types.Transaction, err error) {
  728. c.rw.Lock()
  729. defer c.rw.Unlock()
  730. cpy := c.nextBlock().copy()
  731. defer func() { c.revertIfErr(err, cpy) }()
  732. if c.addr == nil {
  733. return nil, eth.ErrAccountNil
  734. }
  735. log.Error("TODO")
  736. return nil, errTODO
  737. }
  738. // RollupGetTokenAddress is the interface to call the smart contract function
  739. // func (c *Client) RollupGetTokenAddress(tokenID int64) (*ethCommon.Address, error) {
  740. // c.rw.RLock()
  741. // defer c.rw.RUnlock()
  742. //
  743. // log.Error("TODO")
  744. // return nil, errTODO
  745. // }
  746. // RollupGetL1TxFromQueue is the interface to call the smart contract function
  747. // func (c *Client) RollupGetL1TxFromQueue(queue int64, position int64) ([]byte, error) {
  748. // c.rw.RLock()
  749. // defer c.rw.RUnlock()
  750. //
  751. // log.Error("TODO")
  752. // return nil, errTODO
  753. // }
  754. // RollupGetQueue is the interface to call the smart contract function
  755. // func (c *Client) RollupGetQueue(queue int64) ([]byte, error) {
  756. // c.rw.RLock()
  757. // defer c.rw.RUnlock()
  758. //
  759. // log.Error("TODO")
  760. // return nil, errTODO
  761. // }
  762. // RollupUpdateForgeL1L2BatchTimeout is the interface to call the smart contract function
  763. func (c *Client) RollupUpdateForgeL1L2BatchTimeout(newForgeL1Timeout int64) (tx *types.Transaction, err error) {
  764. c.rw.Lock()
  765. defer c.rw.Unlock()
  766. cpy := c.nextBlock().copy()
  767. defer func() { c.revertIfErr(err, cpy) }()
  768. if c.addr == nil {
  769. return nil, eth.ErrAccountNil
  770. }
  771. log.Error("TODO")
  772. return nil, errTODO
  773. }
  774. // RollupUpdateFeeAddToken is the interface to call the smart contract function
  775. func (c *Client) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (tx *types.Transaction, err error) {
  776. c.rw.Lock()
  777. defer c.rw.Unlock()
  778. cpy := c.nextBlock().copy()
  779. defer func() { c.revertIfErr(err, cpy) }()
  780. if c.addr == nil {
  781. return nil, eth.ErrAccountNil
  782. }
  783. log.Error("TODO")
  784. return nil, errTODO
  785. }
  786. // RollupUpdateTokensHEZ is the interface to call the smart contract function
  787. // func (c *Client) RollupUpdateTokensHEZ(newTokenHEZ ethCommon.Address) (tx *types.Transaction, err error) {
  788. // c.rw.Lock()
  789. // defer c.rw.Unlock()
  790. // cpy := c.nextBlock().copy()
  791. // defer func() { c.revertIfErr(err, cpy) }()
  792. //
  793. // log.Error("TODO")
  794. // return nil, errTODO
  795. // }
  796. // RollupUpdateGovernance is the interface to call the smart contract function
  797. // func (c *Client) RollupUpdateGovernance() (*types.Transaction, error) { // TODO (Not defined in Hermez.sol)
  798. // return nil, errTODO
  799. // }
  800. // RollupConstants returns the Constants of the Rollup Smart Contract
  801. func (c *Client) RollupConstants() (*eth.RollupPublicConstants, error) {
  802. c.rw.RLock()
  803. defer c.rw.RUnlock()
  804. log.Error("TODO")
  805. return nil, errTODO
  806. }
  807. // RollupEventsByBlock returns the events in a block that happened in the Rollup Smart Contract
  808. func (c *Client) RollupEventsByBlock(blockNum int64) (*eth.RollupEvents, *ethCommon.Hash, error) {
  809. c.rw.RLock()
  810. defer c.rw.RUnlock()
  811. block, ok := c.blocks[blockNum]
  812. if !ok {
  813. return nil, nil, fmt.Errorf("Block %v doesn't exist", blockNum)
  814. }
  815. return &block.Rollup.Events, &block.Eth.Hash, nil
  816. }
  817. // RollupForgeBatchArgs returns the arguments used in a ForgeBatch call in the Rollup Smart Contract in the given transaction
  818. func (c *Client) RollupForgeBatchArgs(ethTxHash ethCommon.Hash) (*eth.RollupForgeBatchArgs, error) {
  819. c.rw.RLock()
  820. defer c.rw.RUnlock()
  821. forgeBatchArgs, ok := c.forgeBatchArgs[ethTxHash]
  822. if !ok {
  823. return nil, fmt.Errorf("transaction not found")
  824. }
  825. return forgeBatchArgs, nil
  826. }
  827. //
  828. // Auction
  829. //
  830. // AuctionSetSlotDeadline is the interface to call the smart contract function
  831. func (c *Client) AuctionSetSlotDeadline(newDeadline uint8) (tx *types.Transaction, err error) {
  832. c.rw.Lock()
  833. defer c.rw.Unlock()
  834. cpy := c.nextBlock().copy()
  835. defer func() { c.revertIfErr(err, cpy) }()
  836. if c.addr == nil {
  837. return nil, eth.ErrAccountNil
  838. }
  839. log.Error("TODO")
  840. return nil, errTODO
  841. }
  842. // AuctionGetSlotDeadline is the interface to call the smart contract function
  843. func (c *Client) AuctionGetSlotDeadline() (uint8, error) {
  844. c.rw.RLock()
  845. defer c.rw.RUnlock()
  846. log.Error("TODO")
  847. return 0, errTODO
  848. }
  849. // AuctionSetOpenAuctionSlots is the interface to call the smart contract function
  850. func (c *Client) AuctionSetOpenAuctionSlots(newOpenAuctionSlots uint16) (tx *types.Transaction, err error) {
  851. c.rw.Lock()
  852. defer c.rw.Unlock()
  853. cpy := c.nextBlock().copy()
  854. defer func() { c.revertIfErr(err, cpy) }()
  855. if c.addr == nil {
  856. return nil, eth.ErrAccountNil
  857. }
  858. log.Error("TODO")
  859. return nil, errTODO
  860. }
  861. // AuctionGetOpenAuctionSlots is the interface to call the smart contract function
  862. func (c *Client) AuctionGetOpenAuctionSlots() (uint16, error) {
  863. c.rw.RLock()
  864. defer c.rw.RUnlock()
  865. log.Error("TODO")
  866. return 0, errTODO
  867. }
  868. // AuctionSetClosedAuctionSlots is the interface to call the smart contract function
  869. func (c *Client) AuctionSetClosedAuctionSlots(newClosedAuctionSlots uint16) (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. // AuctionGetClosedAuctionSlots is the interface to call the smart contract function
  881. func (c *Client) AuctionGetClosedAuctionSlots() (uint16, error) {
  882. c.rw.RLock()
  883. defer c.rw.RUnlock()
  884. log.Error("TODO")
  885. return 0, errTODO
  886. }
  887. // AuctionSetOutbidding is the interface to call the smart contract function
  888. func (c *Client) AuctionSetOutbidding(newOutbidding uint16) (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. if c.addr == nil {
  894. return nil, eth.ErrAccountNil
  895. }
  896. log.Error("TODO")
  897. return nil, errTODO
  898. }
  899. // AuctionGetOutbidding is the interface to call the smart contract function
  900. func (c *Client) AuctionGetOutbidding() (uint16, error) {
  901. c.rw.RLock()
  902. defer c.rw.RUnlock()
  903. log.Error("TODO")
  904. return 0, errTODO
  905. }
  906. // AuctionSetAllocationRatio is the interface to call the smart contract function
  907. func (c *Client) AuctionSetAllocationRatio(newAllocationRatio [3]uint16) (tx *types.Transaction, err error) {
  908. c.rw.Lock()
  909. defer c.rw.Unlock()
  910. cpy := c.nextBlock().copy()
  911. defer func() { c.revertIfErr(err, cpy) }()
  912. if c.addr == nil {
  913. return nil, eth.ErrAccountNil
  914. }
  915. log.Error("TODO")
  916. return nil, errTODO
  917. }
  918. // AuctionGetAllocationRatio is the interface to call the smart contract function
  919. func (c *Client) AuctionGetAllocationRatio() ([3]uint16, error) {
  920. c.rw.RLock()
  921. defer c.rw.RUnlock()
  922. log.Error("TODO")
  923. return [3]uint16{}, errTODO
  924. }
  925. // AuctionSetDonationAddress is the interface to call the smart contract function
  926. func (c *Client) AuctionSetDonationAddress(newDonationAddress ethCommon.Address) (tx *types.Transaction, err error) {
  927. c.rw.Lock()
  928. defer c.rw.Unlock()
  929. cpy := c.nextBlock().copy()
  930. defer func() { c.revertIfErr(err, cpy) }()
  931. if c.addr == nil {
  932. return nil, eth.ErrAccountNil
  933. }
  934. log.Error("TODO")
  935. return nil, errTODO
  936. }
  937. // AuctionGetDonationAddress is the interface to call the smart contract function
  938. func (c *Client) AuctionGetDonationAddress() (*ethCommon.Address, error) {
  939. c.rw.RLock()
  940. defer c.rw.RUnlock()
  941. log.Error("TODO")
  942. return nil, errTODO
  943. }
  944. // AuctionSetBootCoordinator is the interface to call the smart contract function
  945. func (c *Client) AuctionSetBootCoordinator(newBootCoordinator ethCommon.Address) (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. // AuctionGetBootCoordinator is the interface to call the smart contract function
  957. func (c *Client) AuctionGetBootCoordinator() (*ethCommon.Address, error) {
  958. c.rw.RLock()
  959. defer c.rw.RUnlock()
  960. currentBlock := c.currentBlock()
  961. a := currentBlock.Auction
  962. return &a.Vars.BootCoordinator, nil
  963. }
  964. // AuctionChangeDefaultSlotSetBid is the interface to call the smart contract function
  965. func (c *Client) AuctionChangeDefaultSlotSetBid(slotSet int64, newInitialMinBid *big.Int) (tx *types.Transaction, err error) {
  966. c.rw.Lock()
  967. defer c.rw.Unlock()
  968. cpy := c.nextBlock().copy()
  969. defer func() { c.revertIfErr(err, cpy) }()
  970. if c.addr == nil {
  971. return nil, eth.ErrAccountNil
  972. }
  973. log.Error("TODO")
  974. return nil, errTODO
  975. }
  976. // AuctionSetCoordinator is the interface to call the smart contract function
  977. func (c *Client) AuctionSetCoordinator(forger ethCommon.Address, URL string) (tx *types.Transaction, err error) {
  978. c.rw.Lock()
  979. defer c.rw.Unlock()
  980. cpy := c.nextBlock().copy()
  981. defer func() { c.revertIfErr(err, cpy) }()
  982. if c.addr == nil {
  983. return nil, eth.ErrAccountNil
  984. }
  985. nextBlock := c.nextBlock()
  986. a := nextBlock.Auction
  987. a.State.Coordinators[*c.addr] = &eth.Coordinator{
  988. Forger: forger,
  989. URL: URL,
  990. }
  991. a.Events.SetCoordinator = append(a.Events.SetCoordinator,
  992. eth.AuctionEventSetCoordinator{
  993. BidderAddress: *c.addr,
  994. ForgerAddress: forger,
  995. CoordinatorURL: URL,
  996. })
  997. type data struct {
  998. BidderAddress ethCommon.Address
  999. ForgerAddress ethCommon.Address
  1000. URL string
  1001. }
  1002. return a.addTransaction(newTransaction("registercoordinator", data{*c.addr, forger, URL})), nil
  1003. }
  1004. // AuctionIsRegisteredCoordinator is the interface to call the smart contract function
  1005. func (c *Client) AuctionIsRegisteredCoordinator(forgerAddress ethCommon.Address) (bool, error) {
  1006. c.rw.RLock()
  1007. defer c.rw.RUnlock()
  1008. log.Error("TODO")
  1009. return false, errTODO
  1010. }
  1011. // AuctionUpdateCoordinatorInfo is the interface to call the smart contract function
  1012. func (c *Client) AuctionUpdateCoordinatorInfo(forgerAddress ethCommon.Address, newWithdrawAddress ethCommon.Address, newURL string) (tx *types.Transaction, err error) {
  1013. c.rw.Lock()
  1014. defer c.rw.Unlock()
  1015. cpy := c.nextBlock().copy()
  1016. defer func() { c.revertIfErr(err, cpy) }()
  1017. if c.addr == nil {
  1018. return nil, eth.ErrAccountNil
  1019. }
  1020. log.Error("TODO")
  1021. return nil, errTODO
  1022. }
  1023. // AuctionGetSlotNumber is the interface to call the smart contract function
  1024. func (c *Client) AuctionGetSlotNumber(blockNum int64) (int64, error) {
  1025. c.rw.RLock()
  1026. defer c.rw.RUnlock()
  1027. currentBlock := c.currentBlock()
  1028. a := currentBlock.Auction
  1029. return a.getSlotNumber(blockNum), nil
  1030. }
  1031. // AuctionGetCurrentSlotNumber is the interface to call the smart contract function
  1032. func (c *Client) AuctionGetCurrentSlotNumber() (int64, error) {
  1033. c.rw.RLock()
  1034. defer c.rw.RUnlock()
  1035. log.Error("TODO")
  1036. return 0, errTODO
  1037. }
  1038. // AuctionGetMinBidBySlot is the interface to call the smart contract function
  1039. func (c *Client) AuctionGetMinBidBySlot(slot int64) (*big.Int, error) {
  1040. c.rw.RLock()
  1041. defer c.rw.RUnlock()
  1042. log.Error("TODO")
  1043. return nil, errTODO
  1044. }
  1045. // AuctionGetDefaultSlotSetBid is the interface to call the smart contract function
  1046. func (c *Client) AuctionGetDefaultSlotSetBid(slotSet uint8) (*big.Int, error) {
  1047. c.rw.RLock()
  1048. defer c.rw.RUnlock()
  1049. log.Error("TODO")
  1050. return nil, errTODO
  1051. }
  1052. // AuctionGetSlotSet is the interface to call the smart contract function
  1053. func (c *Client) AuctionGetSlotSet(slot int64) (*big.Int, error) {
  1054. c.rw.RLock()
  1055. defer c.rw.RUnlock()
  1056. log.Error("TODO")
  1057. return nil, errTODO
  1058. }
  1059. // AuctionTokensReceived is the interface to call the smart contract function
  1060. // func (c *Client) AuctionTokensReceived(operator, from, to ethCommon.Address, amount *big.Int, userData, operatorData []byte) error {
  1061. // return errTODO
  1062. // }
  1063. // AuctionBid is the interface to call the smart contract function
  1064. func (c *Client) AuctionBid(slot int64, bidAmount *big.Int) (tx *types.Transaction, err error) {
  1065. c.rw.Lock()
  1066. defer c.rw.Unlock()
  1067. cpy := c.nextBlock().copy()
  1068. defer func() { func() { c.revertIfErr(err, cpy) }() }()
  1069. if c.addr == nil {
  1070. return nil, eth.ErrAccountNil
  1071. }
  1072. nextBlock := c.nextBlock()
  1073. a := nextBlock.Auction
  1074. if slot < a.getCurrentSlotNumber()+int64(a.Vars.ClosedAuctionSlots) {
  1075. return nil, errBidClosed
  1076. }
  1077. if slot >= a.getCurrentSlotNumber()+int64(a.Vars.ClosedAuctionSlots)+int64(a.Vars.OpenAuctionSlots) {
  1078. return nil, errBidNotOpen
  1079. }
  1080. minBid, err := a.getMinBidBySlot(slot)
  1081. if err != nil {
  1082. return nil, err
  1083. }
  1084. if bidAmount.Cmp(minBid) == -1 {
  1085. return nil, errBidBelowMin
  1086. }
  1087. if _, ok := a.State.Coordinators[*c.addr]; !ok {
  1088. return nil, errCoordNotReg
  1089. }
  1090. slotState, ok := a.State.Slots[slot]
  1091. if !ok {
  1092. slotState = eth.NewSlotState()
  1093. a.State.Slots[slot] = slotState
  1094. }
  1095. slotState.Bidder = *c.addr
  1096. slotState.BidAmount = bidAmount
  1097. a.Events.NewBid = append(a.Events.NewBid,
  1098. eth.AuctionEventNewBid{Slot: slot, BidAmount: bidAmount, Bidder: *c.addr})
  1099. type data struct {
  1100. Slot int64
  1101. BidAmount *big.Int
  1102. Bidder ethCommon.Address
  1103. }
  1104. return a.addTransaction(newTransaction("bid", data{slot, bidAmount, *c.addr})), nil
  1105. }
  1106. // AuctionMultiBid is the interface to call the smart contract function
  1107. func (c *Client) AuctionMultiBid(startingSlot int64, endingSlot int64, slotSet [6]bool, maxBid, closedMinBid, budget *big.Int) (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. // AuctionCanForge is the interface to call the smart contract function
  1119. func (c *Client) AuctionCanForge(forger ethCommon.Address, blockNum int64) (bool, error) {
  1120. c.rw.RLock()
  1121. defer c.rw.RUnlock()
  1122. currentBlock := c.currentBlock()
  1123. a := currentBlock.Auction
  1124. return a.canForge(forger, blockNum)
  1125. }
  1126. // AuctionForge is the interface to call the smart contract function
  1127. func (c *Client) AuctionForge(forger ethCommon.Address) (tx *types.Transaction, err error) {
  1128. c.rw.Lock()
  1129. defer c.rw.Unlock()
  1130. cpy := c.nextBlock().copy()
  1131. defer func() { c.revertIfErr(err, cpy) }()
  1132. if c.addr == nil {
  1133. return nil, eth.ErrAccountNil
  1134. }
  1135. log.Error("TODO")
  1136. return nil, errTODO
  1137. }
  1138. // AuctionClaimHEZ is the interface to call the smart contract function
  1139. func (c *Client) AuctionClaimHEZ() (tx *types.Transaction, err error) {
  1140. c.rw.Lock()
  1141. defer c.rw.Unlock()
  1142. cpy := c.nextBlock().copy()
  1143. defer func() { c.revertIfErr(err, cpy) }()
  1144. if c.addr == nil {
  1145. return nil, eth.ErrAccountNil
  1146. }
  1147. log.Error("TODO")
  1148. return nil, errTODO
  1149. }
  1150. // AuctionGetClaimableHEZ is the interface to call the smart contract function
  1151. func (c *Client) AuctionGetClaimableHEZ(bidder ethCommon.Address) (*big.Int, error) {
  1152. c.rw.RLock()
  1153. defer c.rw.RUnlock()
  1154. log.Error("TODO")
  1155. return nil, errTODO
  1156. }
  1157. // AuctionConstants returns the Constants of the Auction Smart Contract
  1158. func (c *Client) AuctionConstants() (*eth.AuctionConstants, error) {
  1159. c.rw.RLock()
  1160. defer c.rw.RUnlock()
  1161. return c.auctionConstants, nil
  1162. }
  1163. // AuctionEventsByBlock returns the events in a block that happened in the Auction Smart Contract
  1164. func (c *Client) AuctionEventsByBlock(blockNum int64) (*eth.AuctionEvents, *ethCommon.Hash, error) {
  1165. c.rw.RLock()
  1166. defer c.rw.RUnlock()
  1167. block, ok := c.blocks[blockNum]
  1168. if !ok {
  1169. return nil, nil, fmt.Errorf("Block %v doesn't exist", blockNum)
  1170. }
  1171. return &block.Auction.Events, &block.Eth.Hash, nil
  1172. }