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.

1687 lines
50 KiB

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