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.

1174 lines
35 KiB

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