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.

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