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.

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