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.

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