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.

1178 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. }
  211. rollupVariables := &eth.RollupVariables{
  212. MaxTxVerifiers: []int{512, 1024, 2048},
  213. TokenHEZ: tokenHEZ,
  214. GovernanceAddress: governanceAddress,
  215. SafetyBot: ethCommon.HexToAddress("0x84d8B79E84fe87B14ad61A554e740f6736bF4c20"),
  216. ConsensusContract: ethCommon.HexToAddress("0x8E442975805fb1908f43050c9C1A522cB0e28D7b"),
  217. WithdrawalContract: ethCommon.HexToAddress("0x5CB7979cBdbf65719BEE92e4D15b7b7Ed3D79114"),
  218. FeeAddToken: big.NewInt(11),
  219. ForgeL1Timeout: 9,
  220. FeeL1UserTx: big.NewInt(22),
  221. }
  222. auctionConstants := &eth.AuctionConstants{
  223. DelayGenesis: 0,
  224. BlocksPerSlot: 40,
  225. InitialMinimalBidding: initialMinimalBidding,
  226. GenesisBlockNum: 0,
  227. GovernanceAddress: governanceAddress,
  228. TokenHEZ: tokenHEZ,
  229. HermezRollup: ethCommon.HexToAddress("0x474B6e29852257491cf283EfB1A9C61eBFe48369"),
  230. }
  231. auctionVariables := &eth.AuctionVariables{
  232. DonationAddress: ethCommon.HexToAddress("0x61Ed87CF0A1496b49A420DA6D84B58196b98f2e7"),
  233. BootCoordinator: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"),
  234. DefaultSlotSetBid: [6]*big.Int{
  235. big.NewInt(1000), big.NewInt(1100), big.NewInt(1200),
  236. big.NewInt(1300), big.NewInt(1400), big.NewInt(1500)},
  237. ClosedAuctionSlots: 2,
  238. OpenAuctionSlots: 4320,
  239. AllocationRatio: [3]uint16{4000, 4000, 2000},
  240. Outbidding: 1000,
  241. SlotDeadline: 20,
  242. }
  243. return &ClientSetup{
  244. RollupConstants: rollupConstants,
  245. RollupVariables: rollupVariables,
  246. AuctionConstants: auctionConstants,
  247. AuctionVariables: auctionVariables,
  248. }
  249. }
  250. // Timer is an interface to simulate a source of time, useful to advance time
  251. // virtually.
  252. type Timer interface {
  253. Time() int64
  254. }
  255. // type forgeBatchArgs struct {
  256. // ethTx *types.Transaction
  257. // blockNum int64
  258. // blockHash ethCommon.Hash
  259. // }
  260. // Client implements the eth.ClientInterface interface, allowing to manipulate the
  261. // values for testing, working with deterministic results.
  262. type Client struct {
  263. rw *sync.RWMutex
  264. log bool
  265. addr ethCommon.Address
  266. rollupConstants *eth.RollupConstants
  267. auctionConstants *eth.AuctionConstants
  268. blocks map[int64]*Block
  269. // state state
  270. blockNum int64 // last mined block num
  271. maxBlockNum int64 // highest block num calculated
  272. timer Timer
  273. hasher hasher
  274. forgeBatchArgsPending map[ethCommon.Hash]*eth.RollupForgeBatchArgs
  275. forgeBatchArgs map[ethCommon.Hash]*eth.RollupForgeBatchArgs
  276. }
  277. // NewClient returns a new test Client that implements the eth.IClient
  278. // interface, at the given initialBlockNumber.
  279. func NewClient(l bool, timer Timer, addr ethCommon.Address, setup *ClientSetup) *Client {
  280. blocks := make(map[int64]*Block)
  281. blockNum := int64(0)
  282. hasher := hasher{}
  283. // Add ethereum genesis block
  284. mapL1TxQueue := make(map[int64]*eth.QueueStruct)
  285. mapL1TxQueue[0] = eth.NewQueueStruct()
  286. mapL1TxQueue[1] = eth.NewQueueStruct()
  287. blockCurrent := Block{
  288. Rollup: &RollupBlock{
  289. State: eth.RollupState{
  290. StateRoot: big.NewInt(0),
  291. ExitRoots: make([]*big.Int, 0),
  292. ExitNullifierMap: make(map[[256 / 8]byte]bool),
  293. TokenList: make([]ethCommon.Address, 0),
  294. TokenMap: make(map[ethCommon.Address]bool),
  295. MapL1TxQueue: mapL1TxQueue,
  296. LastL1L2Batch: 0,
  297. CurrentToForgeL1TxsNum: 0,
  298. LastToForgeL1TxsNum: 1,
  299. CurrentIdx: 0,
  300. },
  301. Vars: *setup.RollupVariables,
  302. Events: eth.NewRollupEvents(),
  303. Constants: setup.RollupConstants,
  304. },
  305. Auction: &AuctionBlock{
  306. State: eth.AuctionState{
  307. Slots: make(map[int64]*eth.SlotState),
  308. PendingBalances: make(map[ethCommon.Address]*big.Int),
  309. Coordinators: make(map[ethCommon.Address]*eth.Coordinator),
  310. },
  311. Vars: *setup.AuctionVariables,
  312. Events: eth.NewAuctionEvents(),
  313. Constants: setup.AuctionConstants,
  314. },
  315. Eth: &EthereumBlock{
  316. BlockNum: blockNum,
  317. Time: timer.Time(),
  318. Hash: hasher.Next(),
  319. ParentHash: ethCommon.Hash{},
  320. },
  321. }
  322. blockCurrent.Rollup.Eth = blockCurrent.Eth
  323. blockCurrent.Auction.Eth = blockCurrent.Eth
  324. blocks[blockNum] = &blockCurrent
  325. blockNext := blockCurrent.Next()
  326. blocks[blockNum+1] = blockNext
  327. return &Client{
  328. rw: &sync.RWMutex{},
  329. log: l,
  330. addr: addr,
  331. rollupConstants: setup.RollupConstants,
  332. auctionConstants: setup.AuctionConstants,
  333. blocks: blocks,
  334. timer: timer,
  335. hasher: hasher,
  336. forgeBatchArgsPending: make(map[ethCommon.Hash]*eth.RollupForgeBatchArgs),
  337. forgeBatchArgs: make(map[ethCommon.Hash]*eth.RollupForgeBatchArgs),
  338. }
  339. }
  340. //
  341. // Mock Control
  342. //
  343. func (c *Client) setNextBlock(block *Block) {
  344. c.blocks[c.blockNum+1] = block
  345. }
  346. func (c *Client) revertIfErr(err error, block *Block) {
  347. if err != nil {
  348. log.Infow("TestClient revert", "block", block.Eth.BlockNum, "err", err)
  349. c.setNextBlock(block)
  350. }
  351. }
  352. // Debugf calls log.Debugf if c.log is true
  353. func (c *Client) Debugf(template string, args ...interface{}) {
  354. if c.log {
  355. log.Debugf(template, args...)
  356. }
  357. }
  358. // Debugw calls log.Debugw if c.log is true
  359. func (c *Client) Debugw(template string, kv ...interface{}) {
  360. if c.log {
  361. log.Debugw(template, kv...)
  362. }
  363. }
  364. type hasher struct {
  365. counter uint64
  366. }
  367. // Next returns the next hash
  368. func (h *hasher) Next() ethCommon.Hash {
  369. var hash ethCommon.Hash
  370. binary.LittleEndian.PutUint64(hash[:], h.counter)
  371. h.counter++
  372. return hash
  373. }
  374. func (c *Client) nextBlock() *Block {
  375. return c.blocks[c.blockNum+1]
  376. }
  377. func (c *Client) currentBlock() *Block {
  378. return c.blocks[c.blockNum]
  379. }
  380. // CtlMineBlock moves one block forward
  381. func (c *Client) CtlMineBlock() {
  382. c.rw.Lock()
  383. defer c.rw.Unlock()
  384. blockCurrent := c.nextBlock()
  385. c.blockNum++
  386. c.maxBlockNum = c.blockNum
  387. blockCurrent.Eth.Time = c.timer.Time()
  388. blockCurrent.Eth.Hash = c.hasher.Next()
  389. for ethTxHash, forgeBatchArgs := range c.forgeBatchArgsPending {
  390. c.forgeBatchArgs[ethTxHash] = forgeBatchArgs
  391. }
  392. c.forgeBatchArgsPending = make(map[ethCommon.Hash]*eth.RollupForgeBatchArgs)
  393. blockNext := blockCurrent.Next()
  394. c.blocks[c.blockNum+1] = blockNext
  395. c.Debugw("TestClient mined block", "blockNum", c.blockNum)
  396. }
  397. // CtlRollback discards the last mined block. Use this to replace a mined
  398. // block to simulate reorgs.
  399. func (c *Client) CtlRollback() {
  400. c.rw.Lock()
  401. defer c.rw.Unlock()
  402. if c.blockNum == 0 {
  403. panic("Can't rollback at blockNum = 0")
  404. }
  405. delete(c.blocks, c.blockNum+1) // delete next block
  406. delete(c.blocks, c.blockNum) // delete current block
  407. c.blockNum--
  408. blockCurrent := c.blocks[c.blockNum]
  409. blockNext := blockCurrent.Next()
  410. c.blocks[c.blockNum+1] = blockNext
  411. }
  412. //
  413. // Ethereum
  414. //
  415. // EthCurrentBlock returns the current blockNum
  416. func (c *Client) EthCurrentBlock() (int64, error) {
  417. c.rw.RLock()
  418. defer c.rw.RUnlock()
  419. if c.blockNum < c.maxBlockNum {
  420. panic("blockNum has decreased. " +
  421. "After a rollback you must mine to reach the same or higher blockNum")
  422. }
  423. return c.blockNum, nil
  424. }
  425. // func newHeader(number *big.Int) *types.Header {
  426. // return &types.Header{
  427. // Number: number,
  428. // Time: uint64(number.Int64()),
  429. // }
  430. // }
  431. // EthHeaderByNumber returns the *types.Header for the given block number in a
  432. // deterministic way.
  433. // func (c *Client) EthHeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
  434. // return newHeader(number), nil
  435. // }
  436. // EthBlockByNumber returns the *common.Block for the given block number in a
  437. // deterministic way.
  438. func (c *Client) EthBlockByNumber(ctx context.Context, blockNum int64) (*common.Block, error) {
  439. c.rw.RLock()
  440. defer c.rw.RUnlock()
  441. block, ok := c.blocks[blockNum]
  442. if !ok {
  443. return nil, fmt.Errorf("block not found")
  444. }
  445. return &common.Block{
  446. EthBlockNum: blockNum,
  447. Timestamp: time.Unix(block.Eth.Time, 0),
  448. Hash: block.Eth.Hash,
  449. ParentHash: block.Eth.ParentHash,
  450. }, nil
  451. }
  452. var errTODO = fmt.Errorf("TODO: Not implemented yet")
  453. //
  454. // Rollup
  455. //
  456. // CtlAddL1TxUser adds an L1TxUser to the L1UserTxs queue of the Rollup
  457. func (c *Client) CtlAddL1TxUser(l1Tx *common.L1Tx) {
  458. c.rw.Lock()
  459. defer c.rw.Unlock()
  460. nextBlock := c.nextBlock()
  461. r := nextBlock.Rollup
  462. queue := r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum]
  463. if len(queue.L1TxQueue) >= c.rollupConstants.MaxL1UserTx {
  464. r.State.LastToForgeL1TxsNum++
  465. r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum] = eth.NewQueueStruct()
  466. queue = r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum]
  467. }
  468. if int64(l1Tx.FromIdx) > r.State.CurrentIdx {
  469. panic("l1Tx.FromIdx > r.State.CurrentIdx")
  470. }
  471. if int(l1Tx.TokenID)+1 > len(r.State.TokenList) {
  472. panic("l1Tx.TokenID + 1 > len(r.State.TokenList)")
  473. }
  474. queue.L1TxQueue = append(queue.L1TxQueue, *l1Tx)
  475. r.Events.L1UserTx = append(r.Events.L1UserTx, eth.RollupEventL1UserTx{L1Tx: *l1Tx})
  476. }
  477. type transactionData struct {
  478. Name string
  479. Value interface{}
  480. }
  481. func (c *Client) newTransaction(name string, value interface{}) *types.Transaction {
  482. data, err := json.Marshal(transactionData{name, value})
  483. if err != nil {
  484. panic(err)
  485. }
  486. return types.NewTransaction(0, ethCommon.Address{}, nil, 0, nil,
  487. data)
  488. }
  489. // RollupForgeBatch is the interface to call the smart contract function
  490. func (c *Client) RollupForgeBatch(args *eth.RollupForgeBatchArgs) (tx *types.Transaction, err error) {
  491. c.rw.Lock()
  492. defer c.rw.Unlock()
  493. cpy := c.nextBlock().copy()
  494. defer func() { c.revertIfErr(err, cpy) }()
  495. a := c.nextBlock().Auction
  496. ok, err := a.canForge(c.addr, a.Eth.BlockNum)
  497. if err != nil {
  498. return nil, err
  499. }
  500. if !ok {
  501. return nil, fmt.Errorf("incorrect slot")
  502. }
  503. // TODO: Verify proof
  504. // Auction
  505. err = a.forge(c.addr)
  506. if err != nil {
  507. return nil, err
  508. }
  509. return c.addBatch(args)
  510. }
  511. // CtlAddBatch adds forged batch to the Rollup, without checking any ZKProof
  512. func (c *Client) CtlAddBatch(args *eth.RollupForgeBatchArgs) {
  513. c.rw.Lock()
  514. defer c.rw.Unlock()
  515. if _, err := c.addBatch(args); err != nil {
  516. panic(err)
  517. }
  518. }
  519. func (c *Client) addBatch(args *eth.RollupForgeBatchArgs) (*types.Transaction, error) {
  520. nextBlock := c.nextBlock()
  521. r := nextBlock.Rollup
  522. r.State.StateRoot = args.NewStRoot
  523. if args.NewLastIdx < r.State.CurrentIdx {
  524. return nil, fmt.Errorf("args.NewLastIdx < r.State.CurrentIdx")
  525. }
  526. r.State.CurrentIdx = args.NewLastIdx
  527. r.State.ExitRoots = append(r.State.ExitRoots, args.NewExitRoot)
  528. if args.L1Batch {
  529. r.State.CurrentToForgeL1TxsNum++
  530. if r.State.CurrentToForgeL1TxsNum == r.State.LastToForgeL1TxsNum {
  531. r.State.LastToForgeL1TxsNum++
  532. r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum] = eth.NewQueueStruct()
  533. }
  534. }
  535. ethTx := c.newTransaction("forgebatch", args)
  536. c.forgeBatchArgsPending[ethTx.Hash()] = args
  537. r.Events.ForgeBatch = append(r.Events.ForgeBatch, eth.RollupEventForgeBatch{
  538. BatchNum: int64(len(r.State.ExitRoots)),
  539. EthTxHash: ethTx.Hash(),
  540. })
  541. return ethTx, nil
  542. }
  543. // RollupAddToken is the interface to call the smart contract function
  544. func (c *Client) RollupAddToken(tokenAddress ethCommon.Address) (tx *types.Transaction, err error) {
  545. c.rw.Lock()
  546. defer c.rw.Unlock()
  547. cpy := c.nextBlock().copy()
  548. defer func() { c.revertIfErr(err, cpy) }()
  549. nextBlock := c.nextBlock()
  550. r := nextBlock.Rollup
  551. if _, ok := r.State.TokenMap[tokenAddress]; ok {
  552. return nil, fmt.Errorf("Token %v already registered", tokenAddress)
  553. }
  554. r.State.TokenMap[tokenAddress] = true
  555. r.State.TokenList = append(r.State.TokenList, tokenAddress)
  556. r.Events.AddToken = append(r.Events.AddToken, eth.RollupEventAddToken{Address: tokenAddress,
  557. TokenID: uint32(len(r.State.TokenList) - 1)})
  558. return c.newTransaction("addtoken", tokenAddress), nil
  559. }
  560. // RollupWithdrawSNARK is the interface to call the smart contract function
  561. // func (c *Client) RollupWithdrawSNARK() (*types.Transaction, error) { // TODO (Not defined in Hermez.sol)
  562. // return nil, errTODO
  563. // }
  564. // RollupWithdrawMerkleProof is the interface to call the smart contract function
  565. func (c *Client) RollupWithdrawMerkleProof(tokenID int64, balance *big.Int, babyPubKey *babyjub.PublicKey, numExitRoot int64, siblings []*big.Int, idx int64, instantWithdraw bool) (tx *types.Transaction, err error) {
  566. c.rw.Lock()
  567. defer c.rw.Unlock()
  568. cpy := c.nextBlock().copy()
  569. defer func() { c.revertIfErr(err, cpy) }()
  570. log.Error("TODO")
  571. return nil, errTODO
  572. }
  573. // RollupForceExit is the interface to call the smart contract function
  574. func (c *Client) RollupForceExit(fromIdx int64, amountF utils.Float16, tokenID int64) (tx *types.Transaction, err error) {
  575. c.rw.Lock()
  576. defer c.rw.Unlock()
  577. cpy := c.nextBlock().copy()
  578. defer func() { c.revertIfErr(err, cpy) }()
  579. log.Error("TODO")
  580. return nil, errTODO
  581. }
  582. // RollupForceTransfer is the interface to call the smart contract function
  583. func (c *Client) RollupForceTransfer(fromIdx int64, amountF utils.Float16, tokenID, toIdx int64) (tx *types.Transaction, err error) {
  584. c.rw.Lock()
  585. defer c.rw.Unlock()
  586. cpy := c.nextBlock().copy()
  587. defer func() { c.revertIfErr(err, cpy) }()
  588. log.Error("TODO")
  589. return nil, errTODO
  590. }
  591. // RollupCreateAccountDepositTransfer is the interface to call the smart contract function
  592. func (c *Client) RollupCreateAccountDepositTransfer(babyPubKey babyjub.PublicKey, loadAmountF, amountF utils.Float16, tokenID int64, toIdx int64) (tx *types.Transaction, err error) {
  593. c.rw.Lock()
  594. defer c.rw.Unlock()
  595. cpy := c.nextBlock().copy()
  596. defer func() { c.revertIfErr(err, cpy) }()
  597. log.Error("TODO")
  598. return nil, errTODO
  599. }
  600. // RollupDepositTransfer is the interface to call the smart contract function
  601. func (c *Client) RollupDepositTransfer(fromIdx int64, loadAmountF, amountF utils.Float16, tokenID int64, toIdx int64) (tx *types.Transaction, err error) {
  602. c.rw.Lock()
  603. defer c.rw.Unlock()
  604. cpy := c.nextBlock().copy()
  605. defer func() { c.revertIfErr(err, cpy) }()
  606. log.Error("TODO")
  607. return nil, errTODO
  608. }
  609. // RollupDeposit is the interface to call the smart contract function
  610. func (c *Client) RollupDeposit(fromIdx int64, loadAmountF utils.Float16, tokenID int64) (tx *types.Transaction, err error) {
  611. c.rw.Lock()
  612. defer c.rw.Unlock()
  613. cpy := c.nextBlock().copy()
  614. defer func() { c.revertIfErr(err, cpy) }()
  615. log.Error("TODO")
  616. return nil, errTODO
  617. }
  618. // RollupCreateAccountDepositFromRelayer is the interface to call the smart contract function
  619. func (c *Client) RollupCreateAccountDepositFromRelayer(accountCreationAuthSig []byte, babyPubKey babyjub.PublicKey, loadAmountF utils.Float16) (tx *types.Transaction, err error) {
  620. c.rw.Lock()
  621. defer c.rw.Unlock()
  622. cpy := c.nextBlock().copy()
  623. defer func() { c.revertIfErr(err, cpy) }()
  624. log.Error("TODO")
  625. return nil, errTODO
  626. }
  627. // RollupCreateAccountDeposit is the interface to call the smart contract function
  628. func (c *Client) RollupCreateAccountDeposit(babyPubKey babyjub.PublicKey, loadAmountF utils.Float16, tokenID int64) (tx *types.Transaction, err error) {
  629. c.rw.Lock()
  630. defer c.rw.Unlock()
  631. cpy := c.nextBlock().copy()
  632. defer func() { c.revertIfErr(err, cpy) }()
  633. log.Error("TODO")
  634. return nil, errTODO
  635. }
  636. // RollupGetTokenAddress is the interface to call the smart contract function
  637. func (c *Client) RollupGetTokenAddress(tokenID int64) (*ethCommon.Address, error) {
  638. c.rw.RLock()
  639. defer c.rw.RUnlock()
  640. log.Error("TODO")
  641. return nil, errTODO
  642. }
  643. // RollupGetL1TxFromQueue is the interface to call the smart contract function
  644. func (c *Client) RollupGetL1TxFromQueue(queue int64, position int64) ([]byte, error) {
  645. c.rw.RLock()
  646. defer c.rw.RUnlock()
  647. log.Error("TODO")
  648. return nil, errTODO
  649. }
  650. // RollupGetQueue is the interface to call the smart contract function
  651. func (c *Client) RollupGetQueue(queue int64) ([]byte, error) {
  652. c.rw.RLock()
  653. defer c.rw.RUnlock()
  654. log.Error("TODO")
  655. return nil, errTODO
  656. }
  657. // RollupUpdateForgeL1Timeout is the interface to call the smart contract function
  658. func (c *Client) RollupUpdateForgeL1Timeout(newForgeL1Timeout int64) (tx *types.Transaction, err error) {
  659. c.rw.Lock()
  660. defer c.rw.Unlock()
  661. cpy := c.nextBlock().copy()
  662. defer func() { c.revertIfErr(err, cpy) }()
  663. log.Error("TODO")
  664. return nil, errTODO
  665. }
  666. // RollupUpdateFeeL1UserTx is the interface to call the smart contract function
  667. func (c *Client) RollupUpdateFeeL1UserTx(newFeeL1UserTx *big.Int) (tx *types.Transaction, err error) {
  668. c.rw.Lock()
  669. defer c.rw.Unlock()
  670. cpy := c.nextBlock().copy()
  671. defer func() { c.revertIfErr(err, cpy) }()
  672. log.Error("TODO")
  673. return nil, errTODO
  674. }
  675. // RollupUpdateFeeAddToken is the interface to call the smart contract function
  676. func (c *Client) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (tx *types.Transaction, err error) {
  677. c.rw.Lock()
  678. defer c.rw.Unlock()
  679. cpy := c.nextBlock().copy()
  680. defer func() { c.revertIfErr(err, cpy) }()
  681. log.Error("TODO")
  682. return nil, errTODO
  683. }
  684. // RollupUpdateTokensHEZ is the interface to call the smart contract function
  685. func (c *Client) RollupUpdateTokensHEZ(newTokenHEZ ethCommon.Address) (tx *types.Transaction, err error) {
  686. c.rw.Lock()
  687. defer c.rw.Unlock()
  688. cpy := c.nextBlock().copy()
  689. defer func() { c.revertIfErr(err, cpy) }()
  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 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 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) (bool, error) {
  968. c.rw.RLock()
  969. defer c.rw.RUnlock()
  970. currentBlock := c.currentBlock()
  971. a := currentBlock.Auction
  972. return a.canForge(forger, a.Eth.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() (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. }