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.

953 lines
28 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) getEpoch(slot int64) int64 {
  60. return slot % int64(len(a.Vars.MinBidEpoch))
  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. epoch := a.getEpoch(slot)
  67. var prevBid *big.Int
  68. slotState, ok := a.State.Slots[slot]
  69. // If the bidAmount for a slot is 0 it means that it has not yet been bid, so the midBid will be the minimum
  70. // bid for the slot time plus the outbidding set, otherwise it will be the bidAmount plus the outbidding
  71. if !ok || slotState.BidAmount.Cmp(big.NewInt(0)) == 0 {
  72. prevBid = a.Vars.MinBidEpoch[epoch]
  73. } else {
  74. prevBid = slotState.BidAmount
  75. }
  76. outBid := new(big.Int).Set(prevBid)
  77. outBid.Mul(outBid, big.NewInt(int64(a.Vars.Outbidding)))
  78. outBid.Div(outBid, big.NewInt(100)) //nolint:gomnd
  79. outBid.Add(prevBid, outBid)
  80. return outBid, nil
  81. }
  82. // EthereumBlock stores all the generic data related to the an ethereum block
  83. type EthereumBlock struct {
  84. BlockNum int64
  85. Time int64
  86. Hash ethCommon.Hash
  87. ParentHash ethCommon.Hash
  88. // state ethState
  89. }
  90. // Block represents a ethereum block
  91. type Block struct {
  92. Rollup *RollupBlock
  93. Auction *AuctionBlock
  94. Eth *EthereumBlock
  95. }
  96. // Next prepares the successive block.
  97. func (b *Block) Next() *Block {
  98. blockNextRaw, err := copystructure.Copy(b)
  99. if err != nil {
  100. panic(err)
  101. }
  102. blockNext := blockNextRaw.(*Block)
  103. blockNext.Rollup.Events = eth.NewRollupEvents()
  104. blockNext.Auction.Events = eth.NewAuctionEvents()
  105. blockNext.Eth = &EthereumBlock{
  106. BlockNum: b.Eth.BlockNum + 1,
  107. ParentHash: b.Eth.Hash,
  108. }
  109. blockNext.Rollup.Constants = b.Rollup.Constants
  110. blockNext.Auction.Constants = b.Auction.Constants
  111. blockNext.Rollup.Eth = blockNext.Eth
  112. blockNext.Auction.Eth = blockNext.Eth
  113. return blockNext
  114. }
  115. // ClientSetup is used to initialize the constants of the Smart Contracts and
  116. // other details of the test Client
  117. type ClientSetup struct {
  118. RollupConstants *eth.RollupConstants
  119. RollupVariables *eth.RollupVariables
  120. AuctionConstants *eth.AuctionConstants
  121. AuctionVariables *eth.AuctionVariables
  122. VerifyProof bool
  123. }
  124. // NewClientSetupExample returns a ClientSetup example with hardcoded realistic values.
  125. // TODO: Fill all values that are currently default.
  126. //nolint:gomnd
  127. func NewClientSetupExample() *ClientSetup {
  128. rollupConstants := &eth.RollupConstants{}
  129. rollupVariables := &eth.RollupVariables{
  130. MaxTxVerifiers: make([]int, 0),
  131. TokenHEZ: ethCommon.Address{},
  132. GovernanceAddress: ethCommon.Address{},
  133. SafetyBot: ethCommon.Address{},
  134. ConsensusContract: ethCommon.Address{},
  135. WithdrawalContract: ethCommon.Address{},
  136. FeeAddToken: big.NewInt(1),
  137. ForgeL1Timeout: 16,
  138. FeeL1UserTx: big.NewInt(2),
  139. }
  140. auctionConstants := &eth.AuctionConstants{
  141. BlocksPerSlot: 40,
  142. }
  143. auctionVariables := &eth.AuctionVariables{
  144. DonationAddress: ethCommon.Address{},
  145. BootCoordinator: ethCommon.Address{},
  146. MinBidEpoch: [6]*big.Int{
  147. big.NewInt(10), big.NewInt(11), big.NewInt(12),
  148. big.NewInt(13), big.NewInt(14), big.NewInt(15)},
  149. ClosedAuctionSlots: 2,
  150. OpenAuctionSlots: 100,
  151. AllocationRatio: [3]uint8{},
  152. Outbidding: 10,
  153. SlotDeadline: 20,
  154. }
  155. return &ClientSetup{
  156. RollupConstants: rollupConstants,
  157. RollupVariables: rollupVariables,
  158. AuctionConstants: auctionConstants,
  159. AuctionVariables: auctionVariables,
  160. }
  161. }
  162. // Timer is an interface to simulate a source of time, useful to advance time
  163. // virtually.
  164. type Timer interface {
  165. Time() int64
  166. }
  167. // type forgeBatchArgs struct {
  168. // ethTx *types.Transaction
  169. // blockNum int64
  170. // blockHash ethCommon.Hash
  171. // }
  172. // Client implements the eth.ClientInterface interface, allowing to manipulate the
  173. // values for testing, working with deterministic results.
  174. type Client struct {
  175. rw *sync.RWMutex
  176. log bool
  177. addr ethCommon.Address
  178. rollupConstants *eth.RollupConstants
  179. auctionConstants *eth.AuctionConstants
  180. blocks map[int64]*Block
  181. // state state
  182. blockNum int64 // last mined block num
  183. maxBlockNum int64 // highest block num calculated
  184. timer Timer
  185. hasher hasher
  186. forgeBatchArgsPending map[ethCommon.Hash]*eth.RollupForgeBatchArgs
  187. forgeBatchArgs map[ethCommon.Hash]*eth.RollupForgeBatchArgs
  188. }
  189. // NewClient returns a new test Client that implements the eth.IClient
  190. // interface, at the given initialBlockNumber.
  191. func NewClient(l bool, timer Timer, addr ethCommon.Address, setup *ClientSetup) *Client {
  192. blocks := make(map[int64]*Block)
  193. blockNum := int64(0)
  194. hasher := hasher{}
  195. // Add ethereum genesis block
  196. mapL1TxQueue := make(map[int64]*eth.QueueStruct)
  197. mapL1TxQueue[0] = eth.NewQueueStruct()
  198. mapL1TxQueue[1] = eth.NewQueueStruct()
  199. blockCurrent := Block{
  200. Rollup: &RollupBlock{
  201. State: eth.RollupState{
  202. StateRoot: big.NewInt(0),
  203. ExitRoots: make([]*big.Int, 0),
  204. ExitNullifierMap: make(map[[256 / 8]byte]bool),
  205. TokenList: make([]ethCommon.Address, 0),
  206. TokenMap: make(map[ethCommon.Address]bool),
  207. MapL1TxQueue: mapL1TxQueue,
  208. LastL1L2Batch: 0,
  209. CurrentToForgeL1TxsNum: 0,
  210. LastToForgeL1TxsNum: 1,
  211. CurrentIdx: 0,
  212. },
  213. Vars: *setup.RollupVariables,
  214. Events: eth.NewRollupEvents(),
  215. Constants: setup.RollupConstants,
  216. },
  217. Auction: &AuctionBlock{
  218. State: eth.AuctionState{
  219. Slots: make(map[int64]*eth.SlotState),
  220. PendingBalances: make(map[ethCommon.Address]*big.Int),
  221. Coordinators: make(map[ethCommon.Address]*eth.Coordinator),
  222. },
  223. Vars: *setup.AuctionVariables,
  224. Events: eth.NewAuctionEvents(),
  225. Constants: setup.AuctionConstants,
  226. },
  227. Eth: &EthereumBlock{
  228. BlockNum: blockNum,
  229. Time: timer.Time(),
  230. Hash: hasher.Next(),
  231. ParentHash: ethCommon.Hash{},
  232. },
  233. }
  234. blockCurrent.Rollup.Eth = blockCurrent.Eth
  235. blockCurrent.Auction.Eth = blockCurrent.Eth
  236. blocks[blockNum] = &blockCurrent
  237. blockNext := blockCurrent.Next()
  238. blocks[blockNum+1] = blockNext
  239. return &Client{
  240. rw: &sync.RWMutex{},
  241. log: l,
  242. addr: addr,
  243. rollupConstants: setup.RollupConstants,
  244. auctionConstants: setup.AuctionConstants,
  245. blocks: blocks,
  246. timer: timer,
  247. hasher: hasher,
  248. forgeBatchArgsPending: make(map[ethCommon.Hash]*eth.RollupForgeBatchArgs),
  249. forgeBatchArgs: make(map[ethCommon.Hash]*eth.RollupForgeBatchArgs),
  250. }
  251. }
  252. //
  253. // Mock Control
  254. //
  255. // Debugf calls log.Debugf if c.log is true
  256. func (c *Client) Debugf(template string, args ...interface{}) {
  257. if c.log {
  258. log.Debugf(template, args...)
  259. }
  260. }
  261. // Debugw calls log.Debugw if c.log is true
  262. func (c *Client) Debugw(template string, kv ...interface{}) {
  263. if c.log {
  264. log.Debugw(template, kv...)
  265. }
  266. }
  267. type hasher struct {
  268. counter uint64
  269. }
  270. // Next returns the next hash
  271. func (h *hasher) Next() ethCommon.Hash {
  272. var hash ethCommon.Hash
  273. binary.LittleEndian.PutUint64(hash[:], h.counter)
  274. h.counter++
  275. return hash
  276. }
  277. func (c *Client) nextBlock() *Block {
  278. return c.blocks[c.blockNum+1]
  279. }
  280. func (c *Client) currentBlock() *Block {
  281. return c.blocks[c.blockNum]
  282. }
  283. // CtlMineBlock moves one block forward
  284. func (c *Client) CtlMineBlock() {
  285. c.rw.Lock()
  286. defer c.rw.Unlock()
  287. blockCurrent := c.nextBlock()
  288. c.blockNum++
  289. c.maxBlockNum = c.blockNum
  290. blockCurrent.Eth.Time = c.timer.Time()
  291. blockCurrent.Eth.Hash = c.hasher.Next()
  292. for ethTxHash, forgeBatchArgs := range c.forgeBatchArgsPending {
  293. c.forgeBatchArgs[ethTxHash] = forgeBatchArgs
  294. }
  295. c.forgeBatchArgsPending = make(map[ethCommon.Hash]*eth.RollupForgeBatchArgs)
  296. blockNext := blockCurrent.Next()
  297. c.blocks[c.blockNum+1] = blockNext
  298. c.Debugw("TestClient mined block", "blockNum", c.blockNum)
  299. }
  300. // CtlRollback discards the last mined block. Use this to replace a mined
  301. // block to simulate reorgs.
  302. func (c *Client) CtlRollback() {
  303. c.rw.Lock()
  304. defer c.rw.Unlock()
  305. if c.blockNum == 0 {
  306. panic("Can't rollback at blockNum = 0")
  307. }
  308. delete(c.blocks, c.blockNum+1) // delete next block
  309. delete(c.blocks, c.blockNum) // delete current block
  310. c.blockNum--
  311. blockCurrent := c.blocks[c.blockNum]
  312. blockNext := blockCurrent.Next()
  313. c.blocks[c.blockNum+1] = blockNext
  314. }
  315. //
  316. // Ethereum
  317. //
  318. // EthCurrentBlock returns the current blockNum
  319. func (c *Client) EthCurrentBlock() (int64, error) {
  320. c.rw.RLock()
  321. defer c.rw.RUnlock()
  322. if c.blockNum < c.maxBlockNum {
  323. panic("blockNum has decreased. " +
  324. "After a rollback you must mine to reach the same or higher blockNum")
  325. }
  326. return c.blockNum, nil
  327. }
  328. // func newHeader(number *big.Int) *types.Header {
  329. // return &types.Header{
  330. // Number: number,
  331. // Time: uint64(number.Int64()),
  332. // }
  333. // }
  334. // EthHeaderByNumber returns the *types.Header for the given block number in a
  335. // deterministic way.
  336. // func (c *Client) EthHeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
  337. // return newHeader(number), nil
  338. // }
  339. // EthBlockByNumber returns the *common.Block for the given block number in a
  340. // deterministic way.
  341. func (c *Client) EthBlockByNumber(ctx context.Context, blockNum int64) (*common.Block, error) {
  342. c.rw.RLock()
  343. defer c.rw.RUnlock()
  344. block, ok := c.blocks[blockNum]
  345. if !ok {
  346. return nil, fmt.Errorf("block not found")
  347. }
  348. return &common.Block{
  349. EthBlockNum: blockNum,
  350. Timestamp: time.Unix(block.Eth.Time, 0),
  351. Hash: block.Eth.Hash,
  352. ParentHash: block.Eth.ParentHash,
  353. }, nil
  354. }
  355. var errTODO = fmt.Errorf("TODO: Not implemented yet")
  356. //
  357. // Rollup
  358. //
  359. // CtlAddL1TxUser adds an L1TxUser to the L1UserTxs queue of the Rollup
  360. func (c *Client) CtlAddL1TxUser(l1Tx *common.L1Tx) {
  361. c.rw.Lock()
  362. defer c.rw.Unlock()
  363. nextBlock := c.nextBlock()
  364. r := nextBlock.Rollup
  365. queue := r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum]
  366. if len(queue.L1TxQueue) >= c.rollupConstants.MaxL1UserTx {
  367. r.State.LastToForgeL1TxsNum++
  368. r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum] = eth.NewQueueStruct()
  369. queue = r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum]
  370. }
  371. if int64(l1Tx.FromIdx) > r.State.CurrentIdx {
  372. panic("l1Tx.FromIdx > r.State.CurrentIdx")
  373. }
  374. if int(l1Tx.TokenID)+1 > len(r.State.TokenList) {
  375. panic("l1Tx.TokenID + 1 > len(r.State.TokenList)")
  376. }
  377. queue.L1TxQueue = append(queue.L1TxQueue, *l1Tx)
  378. r.Events.L1UserTx = append(r.Events.L1UserTx, eth.RollupEventL1UserTx{L1Tx: *l1Tx})
  379. }
  380. type transactionData struct {
  381. Name string
  382. Value interface{}
  383. }
  384. func (c *Client) newTransaction(name string, value interface{}) *types.Transaction {
  385. data, err := json.Marshal(transactionData{name, value})
  386. if err != nil {
  387. panic(err)
  388. }
  389. return types.NewTransaction(0, ethCommon.Address{}, nil, 0, nil,
  390. data)
  391. }
  392. // RollupForgeBatch is the interface to call the smart contract function
  393. func (c *Client) RollupForgeBatch(*eth.RollupForgeBatchArgs) (*types.Transaction, error) {
  394. c.rw.Lock()
  395. defer c.rw.Unlock()
  396. return nil, errTODO
  397. }
  398. // CtlAddBatch adds forged batch to the Rollup, without checking any ZKProof
  399. func (c *Client) CtlAddBatch(args *eth.RollupForgeBatchArgs) {
  400. c.rw.Lock()
  401. defer c.rw.Unlock()
  402. nextBlock := c.nextBlock()
  403. r := nextBlock.Rollup
  404. r.State.StateRoot = args.NewStRoot
  405. if args.NewLastIdx < r.State.CurrentIdx {
  406. panic("args.NewLastIdx < r.State.CurrentIdx")
  407. }
  408. r.State.CurrentIdx = args.NewLastIdx
  409. r.State.ExitRoots = append(r.State.ExitRoots, args.NewExitRoot)
  410. if args.L1Batch {
  411. r.State.CurrentToForgeL1TxsNum++
  412. if r.State.CurrentToForgeL1TxsNum == r.State.LastToForgeL1TxsNum {
  413. r.State.LastToForgeL1TxsNum++
  414. r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum] = eth.NewQueueStruct()
  415. }
  416. }
  417. ethTx := c.newTransaction("forgebatch", args)
  418. c.forgeBatchArgsPending[ethTx.Hash()] = args
  419. r.Events.ForgeBatch = append(r.Events.ForgeBatch, eth.RollupEventForgeBatch{
  420. BatchNum: int64(len(r.State.ExitRoots)),
  421. EthTxHash: ethTx.Hash(),
  422. })
  423. }
  424. // RollupAddToken is the interface to call the smart contract function
  425. func (c *Client) RollupAddToken(tokenAddress ethCommon.Address) (*types.Transaction, error) {
  426. c.rw.Lock()
  427. defer c.rw.Unlock()
  428. nextBlock := c.nextBlock()
  429. r := nextBlock.Rollup
  430. if _, ok := r.State.TokenMap[tokenAddress]; ok {
  431. return nil, fmt.Errorf("Token %v already registered", tokenAddress)
  432. }
  433. r.State.TokenMap[tokenAddress] = true
  434. r.State.TokenList = append(r.State.TokenList, tokenAddress)
  435. r.Events.AddToken = append(r.Events.AddToken, eth.RollupEventAddToken{Address: tokenAddress,
  436. TokenID: uint32(len(r.State.TokenList) - 1)})
  437. return c.newTransaction("addtoken", tokenAddress), nil
  438. }
  439. // RollupWithdrawSNARK is the interface to call the smart contract function
  440. // func (c *Client) RollupWithdrawSNARK() (*types.Transaction, error) { // TODO (Not defined in Hermez.sol)
  441. // return nil, errTODO
  442. // }
  443. // RollupWithdrawMerkleProof is the interface to call the smart contract function
  444. func (c *Client) RollupWithdrawMerkleProof(tokenID int64, balance *big.Int, babyPubKey *babyjub.PublicKey, numExitRoot int64, siblings []*big.Int, idx int64, instantWithdraw bool) (*types.Transaction, error) {
  445. c.rw.Lock()
  446. defer c.rw.Unlock()
  447. return nil, errTODO
  448. }
  449. // RollupForceExit is the interface to call the smart contract function
  450. func (c *Client) RollupForceExit(fromIdx int64, amountF utils.Float16, tokenID int64) (*types.Transaction, error) {
  451. c.rw.Lock()
  452. defer c.rw.Unlock()
  453. return nil, errTODO
  454. }
  455. // RollupForceTransfer is the interface to call the smart contract function
  456. func (c *Client) RollupForceTransfer(fromIdx int64, amountF utils.Float16, tokenID, toIdx int64) (*types.Transaction, error) {
  457. c.rw.Lock()
  458. defer c.rw.Unlock()
  459. return nil, errTODO
  460. }
  461. // RollupCreateAccountDepositTransfer is the interface to call the smart contract function
  462. func (c *Client) RollupCreateAccountDepositTransfer(babyPubKey babyjub.PublicKey, loadAmountF, amountF utils.Float16, tokenID int64, toIdx int64) (*types.Transaction, error) {
  463. c.rw.Lock()
  464. defer c.rw.Unlock()
  465. return nil, errTODO
  466. }
  467. // RollupDepositTransfer is the interface to call the smart contract function
  468. func (c *Client) RollupDepositTransfer(fromIdx int64, loadAmountF, amountF utils.Float16, tokenID int64, toIdx int64) (*types.Transaction, error) {
  469. c.rw.Lock()
  470. defer c.rw.Unlock()
  471. return nil, errTODO
  472. }
  473. // RollupDeposit is the interface to call the smart contract function
  474. func (c *Client) RollupDeposit(fromIdx int64, loadAmountF utils.Float16, tokenID int64) (*types.Transaction, error) {
  475. c.rw.Lock()
  476. defer c.rw.Unlock()
  477. return nil, errTODO
  478. }
  479. // RollupCreateAccountDepositFromRelayer is the interface to call the smart contract function
  480. func (c *Client) RollupCreateAccountDepositFromRelayer(accountCreationAuthSig []byte, babyPubKey babyjub.PublicKey, loadAmountF utils.Float16) (*types.Transaction, error) {
  481. c.rw.Lock()
  482. defer c.rw.Unlock()
  483. return nil, errTODO
  484. }
  485. // RollupCreateAccountDeposit is the interface to call the smart contract function
  486. func (c *Client) RollupCreateAccountDeposit(babyPubKey babyjub.PublicKey, loadAmountF utils.Float16, tokenID int64) (*types.Transaction, error) {
  487. c.rw.Lock()
  488. defer c.rw.Unlock()
  489. return nil, errTODO
  490. }
  491. // RollupGetTokenAddress is the interface to call the smart contract function
  492. func (c *Client) RollupGetTokenAddress(tokenID int64) (*ethCommon.Address, error) {
  493. c.rw.RLock()
  494. defer c.rw.RUnlock()
  495. return nil, errTODO
  496. }
  497. // RollupGetL1TxFromQueue is the interface to call the smart contract function
  498. func (c *Client) RollupGetL1TxFromQueue(queue int64, position int64) ([]byte, error) {
  499. c.rw.RLock()
  500. defer c.rw.RUnlock()
  501. return nil, errTODO
  502. }
  503. // RollupGetQueue is the interface to call the smart contract function
  504. func (c *Client) RollupGetQueue(queue int64) ([]byte, error) {
  505. c.rw.RLock()
  506. defer c.rw.RUnlock()
  507. return nil, errTODO
  508. }
  509. // RollupUpdateForgeL1Timeout is the interface to call the smart contract function
  510. func (c *Client) RollupUpdateForgeL1Timeout(newForgeL1Timeout int64) (*types.Transaction, error) {
  511. c.rw.Lock()
  512. defer c.rw.Unlock()
  513. return nil, errTODO
  514. }
  515. // RollupUpdateFeeL1UserTx is the interface to call the smart contract function
  516. func (c *Client) RollupUpdateFeeL1UserTx(newFeeL1UserTx *big.Int) (*types.Transaction, error) {
  517. c.rw.Lock()
  518. defer c.rw.Unlock()
  519. return nil, errTODO
  520. }
  521. // RollupUpdateFeeAddToken is the interface to call the smart contract function
  522. func (c *Client) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (*types.Transaction, error) {
  523. c.rw.Lock()
  524. defer c.rw.Unlock()
  525. return nil, errTODO
  526. }
  527. // RollupUpdateTokensHEZ is the interface to call the smart contract function
  528. func (c *Client) RollupUpdateTokensHEZ(newTokenHEZ ethCommon.Address) (*types.Transaction, error) {
  529. c.rw.Lock()
  530. defer c.rw.Unlock()
  531. return nil, errTODO
  532. }
  533. // RollupUpdateGovernance is the interface to call the smart contract function
  534. // func (c *Client) RollupUpdateGovernance() (*types.Transaction, error) { // TODO (Not defined in Hermez.sol)
  535. // return nil, errTODO
  536. // }
  537. // RollupConstants returns the Constants of the Rollup Smart Contract
  538. func (c *Client) RollupConstants() (*eth.RollupConstants, error) {
  539. c.rw.RLock()
  540. defer c.rw.RUnlock()
  541. return nil, errTODO
  542. }
  543. // RollupEventsByBlock returns the events in a block that happened in the Rollup Smart Contract
  544. func (c *Client) RollupEventsByBlock(blockNum int64) (*eth.RollupEvents, *ethCommon.Hash, error) {
  545. c.rw.RLock()
  546. defer c.rw.RUnlock()
  547. block, ok := c.blocks[blockNum]
  548. if !ok {
  549. return nil, nil, fmt.Errorf("Block %v doesn't exist", blockNum)
  550. }
  551. return &block.Rollup.Events, &block.Eth.Hash, nil
  552. }
  553. // RollupForgeBatchArgs returns the arguments used in a ForgeBatch call in the Rollup Smart Contract in the given transaction
  554. func (c *Client) RollupForgeBatchArgs(ethTxHash ethCommon.Hash) (*eth.RollupForgeBatchArgs, error) {
  555. c.rw.RLock()
  556. defer c.rw.RUnlock()
  557. forgeBatchArgs, ok := c.forgeBatchArgs[ethTxHash]
  558. if !ok {
  559. return nil, fmt.Errorf("transaction not found")
  560. }
  561. return forgeBatchArgs, nil
  562. }
  563. //
  564. // Auction
  565. //
  566. // AuctionSetSlotDeadline is the interface to call the smart contract function
  567. func (c *Client) AuctionSetSlotDeadline(newDeadline uint8) (*types.Transaction, error) {
  568. c.rw.Lock()
  569. defer c.rw.Unlock()
  570. return nil, errTODO
  571. }
  572. // AuctionGetSlotDeadline is the interface to call the smart contract function
  573. func (c *Client) AuctionGetSlotDeadline() (uint8, error) {
  574. c.rw.RLock()
  575. defer c.rw.RUnlock()
  576. return 0, errTODO
  577. }
  578. // AuctionSetOpenAuctionSlots is the interface to call the smart contract function
  579. func (c *Client) AuctionSetOpenAuctionSlots(newOpenAuctionSlots uint16) (*types.Transaction, error) {
  580. c.rw.Lock()
  581. defer c.rw.Unlock()
  582. return nil, errTODO
  583. }
  584. // AuctionGetOpenAuctionSlots is the interface to call the smart contract function
  585. func (c *Client) AuctionGetOpenAuctionSlots() (uint16, error) {
  586. c.rw.RLock()
  587. defer c.rw.RUnlock()
  588. return 0, errTODO
  589. }
  590. // AuctionSetClosedAuctionSlots is the interface to call the smart contract function
  591. func (c *Client) AuctionSetClosedAuctionSlots(newClosedAuctionSlots uint16) (*types.Transaction, error) {
  592. c.rw.Lock()
  593. defer c.rw.Unlock()
  594. return nil, errTODO
  595. }
  596. // AuctionGetClosedAuctionSlots is the interface to call the smart contract function
  597. func (c *Client) AuctionGetClosedAuctionSlots() (uint16, error) {
  598. c.rw.RLock()
  599. defer c.rw.RUnlock()
  600. return 0, errTODO
  601. }
  602. // AuctionSetOutbidding is the interface to call the smart contract function
  603. func (c *Client) AuctionSetOutbidding(newOutbidding uint8) (*types.Transaction, error) {
  604. c.rw.Lock()
  605. defer c.rw.Unlock()
  606. return nil, errTODO
  607. }
  608. // AuctionGetOutbidding is the interface to call the smart contract function
  609. func (c *Client) AuctionGetOutbidding() (uint8, error) {
  610. c.rw.RLock()
  611. defer c.rw.RUnlock()
  612. return 0, errTODO
  613. }
  614. // AuctionSetAllocationRatio is the interface to call the smart contract function
  615. func (c *Client) AuctionSetAllocationRatio(newAllocationRatio [3]uint8) (*types.Transaction, error) {
  616. c.rw.Lock()
  617. defer c.rw.Unlock()
  618. return nil, errTODO
  619. }
  620. // AuctionGetAllocationRatio is the interface to call the smart contract function
  621. func (c *Client) AuctionGetAllocationRatio() ([3]uint8, error) {
  622. c.rw.RLock()
  623. defer c.rw.RUnlock()
  624. return [3]uint8{}, errTODO
  625. }
  626. // AuctionSetDonationAddress is the interface to call the smart contract function
  627. func (c *Client) AuctionSetDonationAddress(newDonationAddress ethCommon.Address) (*types.Transaction, error) {
  628. c.rw.Lock()
  629. defer c.rw.Unlock()
  630. return nil, errTODO
  631. }
  632. // AuctionGetDonationAddress is the interface to call the smart contract function
  633. func (c *Client) AuctionGetDonationAddress() (*ethCommon.Address, error) {
  634. c.rw.RLock()
  635. defer c.rw.RUnlock()
  636. return nil, errTODO
  637. }
  638. // AuctionSetBootCoordinator is the interface to call the smart contract function
  639. func (c *Client) AuctionSetBootCoordinator(newBootCoordinator ethCommon.Address) (*types.Transaction, error) {
  640. c.rw.Lock()
  641. defer c.rw.Unlock()
  642. return nil, errTODO
  643. }
  644. // AuctionGetBootCoordinator is the interface to call the smart contract function
  645. func (c *Client) AuctionGetBootCoordinator() (*ethCommon.Address, error) {
  646. c.rw.RLock()
  647. defer c.rw.RUnlock()
  648. currentBlock := c.currentBlock()
  649. a := currentBlock.Auction
  650. return &a.Vars.BootCoordinator, nil
  651. }
  652. // AuctionChangeEpochMinBid is the interface to call the smart contract function
  653. func (c *Client) AuctionChangeEpochMinBid(slotEpoch int64, newInitialMinBid *big.Int) (*types.Transaction, error) {
  654. c.rw.Lock()
  655. defer c.rw.Unlock()
  656. return nil, errTODO
  657. }
  658. // AuctionRegisterCoordinator is the interface to call the smart contract function
  659. func (c *Client) AuctionRegisterCoordinator(forgerAddress ethCommon.Address, URL string) (*types.Transaction, error) {
  660. c.rw.Lock()
  661. defer c.rw.Unlock()
  662. nextBlock := c.nextBlock()
  663. a := nextBlock.Auction
  664. if _, ok := a.State.Coordinators[forgerAddress]; ok {
  665. return nil, fmt.Errorf("Already registered")
  666. }
  667. a.State.Coordinators[forgerAddress] = &eth.Coordinator{
  668. WithdrawalAddress: c.addr,
  669. URL: URL,
  670. }
  671. a.Events.NewCoordinator = append(a.Events.NewCoordinator,
  672. eth.AuctionEventNewCoordinator{
  673. ForgerAddress: forgerAddress,
  674. WithdrawalAddress: c.addr,
  675. URL: URL,
  676. })
  677. type data struct {
  678. ForgerAddress ethCommon.Address
  679. URL string
  680. }
  681. return c.newTransaction("registercoordinator", data{forgerAddress, URL}), nil
  682. }
  683. // AuctionIsRegisteredCoordinator is the interface to call the smart contract function
  684. func (c *Client) AuctionIsRegisteredCoordinator(forgerAddress ethCommon.Address) (bool, error) {
  685. c.rw.RLock()
  686. defer c.rw.RUnlock()
  687. return false, errTODO
  688. }
  689. // AuctionUpdateCoordinatorInfo is the interface to call the smart contract function
  690. func (c *Client) AuctionUpdateCoordinatorInfo(forgerAddress ethCommon.Address, newWithdrawAddress ethCommon.Address, newURL string) (*types.Transaction, error) {
  691. c.rw.Lock()
  692. defer c.rw.Unlock()
  693. return nil, errTODO
  694. }
  695. // AuctionGetCurrentSlotNumber is the interface to call the smart contract function
  696. func (c *Client) AuctionGetCurrentSlotNumber() (int64, error) {
  697. c.rw.RLock()
  698. defer c.rw.RUnlock()
  699. return 0, errTODO
  700. }
  701. // AuctionGetMinBidBySlot is the interface to call the smart contract function
  702. func (c *Client) AuctionGetMinBidBySlot(slot int64) (*big.Int, error) {
  703. c.rw.RLock()
  704. defer c.rw.RUnlock()
  705. return nil, errTODO
  706. }
  707. // AuctionGetMinBidEpoch is the interface to call the smart contract function
  708. func (c *Client) AuctionGetMinBidEpoch(epoch uint8) (*big.Int, error) {
  709. c.rw.RLock()
  710. defer c.rw.RUnlock()
  711. return nil, errTODO
  712. }
  713. // AuctionTokensReceived is the interface to call the smart contract function
  714. // func (c *Client) AuctionTokensReceived(operator, from, to ethCommon.Address, amount *big.Int, userData, operatorData []byte) error {
  715. // return errTODO
  716. // }
  717. // AuctionBid is the interface to call the smart contract function
  718. func (c *Client) AuctionBid(slot int64, bidAmount *big.Int, forger ethCommon.Address) (*types.Transaction, error) {
  719. c.rw.Lock()
  720. defer c.rw.Unlock()
  721. nextBlock := c.nextBlock()
  722. a := nextBlock.Auction
  723. if slot < a.getCurrentSlotNumber()+int64(a.Vars.ClosedAuctionSlots) {
  724. return nil, errBidClosed
  725. }
  726. if slot >= a.getCurrentSlotNumber()+int64(a.Vars.ClosedAuctionSlots)+int64(a.Vars.OpenAuctionSlots) {
  727. return nil, errBidNotOpen
  728. }
  729. minBid, err := a.getMinBidBySlot(slot)
  730. if err != nil {
  731. return nil, err
  732. }
  733. if bidAmount.Cmp(minBid) == -1 {
  734. return nil, errBidBelowMin
  735. }
  736. if _, ok := a.State.Coordinators[forger]; !ok {
  737. return nil, errCoordNotReg
  738. }
  739. slotState, ok := a.State.Slots[slot]
  740. if !ok {
  741. slotState = &eth.SlotState{}
  742. a.State.Slots[slot] = slotState
  743. }
  744. slotState.Forger = forger
  745. slotState.BidAmount = bidAmount
  746. a.Events.NewBid = append(a.Events.NewBid,
  747. eth.AuctionEventNewBid{Slot: slot, BidAmount: bidAmount, CoordinatorForger: forger})
  748. type data struct {
  749. Slot int64
  750. BidAmount *big.Int
  751. Forger ethCommon.Address
  752. }
  753. return c.newTransaction("bid", data{slot, bidAmount, forger}), nil
  754. }
  755. // AuctionMultiBid is the interface to call the smart contract function
  756. func (c *Client) AuctionMultiBid(startingSlot int64, endingSlot int64, slotEpoch [6]bool, maxBid, closedMinBid, budget *big.Int, forger ethCommon.Address) (*types.Transaction, error) {
  757. c.rw.Lock()
  758. defer c.rw.Unlock()
  759. return nil, errTODO
  760. }
  761. // AuctionCanForge is the interface to call the smart contract function
  762. func (c *Client) AuctionCanForge(forger ethCommon.Address) (bool, error) {
  763. c.rw.RLock()
  764. defer c.rw.RUnlock()
  765. return false, errTODO
  766. }
  767. // AuctionForge is the interface to call the smart contract function
  768. // func (c *Client) AuctionForge(forger ethCommon.Address) (bool, error) {
  769. // return false, errTODO
  770. // }
  771. // AuctionClaimHEZ is the interface to call the smart contract function
  772. func (c *Client) AuctionClaimHEZ() (*types.Transaction, error) {
  773. c.rw.Lock()
  774. defer c.rw.Unlock()
  775. return nil, errTODO
  776. }
  777. // AuctionConstants returns the Constants of the Auction Smart Contract
  778. func (c *Client) AuctionConstants() (*eth.AuctionConstants, error) {
  779. c.rw.RLock()
  780. defer c.rw.RUnlock()
  781. return c.auctionConstants, nil
  782. }
  783. // AuctionEventsByBlock returns the events in a block that happened in the Auction Smart Contract
  784. func (c *Client) AuctionEventsByBlock(blockNum int64) (*eth.AuctionEvents, *ethCommon.Hash, error) {
  785. c.rw.RLock()
  786. defer c.rw.RUnlock()
  787. block, ok := c.blocks[blockNum]
  788. if !ok {
  789. return nil, nil, fmt.Errorf("Block %v doesn't exist", blockNum)
  790. }
  791. return &block.Auction.Events, &block.Eth.Hash, nil
  792. }