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.

193 lines
6.6 KiB

4 years ago
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
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 missing parts, improve til, and more - Node - Updated configuration to initialize the interface to all the smart contracts - Common - Moved BlockData and BatchData types to common so that they can be shared among: historydb, til and synchronizer - Remove hash.go (it was never used) - Remove slot.go (it was never used) - Remove smartcontractparams.go (it was never used, and appropriate structs are defined in `eth/`) - Comment state / status method until requirements of this method are properly defined, and move it to Synchronizer - Synchronizer - Simplify `Sync` routine to only sync one block per call, and return useful information. - Use BlockData and BatchData from common - Check that events belong to the expected block hash - In L1Batch, query L1UserTxs from HistoryDB - Fill ERC20 token information - Test AddTokens with test.Client - HistryDB - Use BlockData and BatchData from common - Add `GetAllTokens` method - Uncomment and update GetL1UserTxs (with corresponding tests) - Til - Rename all instances of RegisterToken to AddToken (to follow the smart contract implementation naming) - Use BlockData and BatchData from common - Move testL1CoordinatorTxs and testL2Txs to a separate struct from BatchData in Context - Start Context with BatchNum = 1 (which the protocol defines to be the first batchNum) - In every Batch, set StateRoot and ExitRoot to a non-nil big.Int (zero). - In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not used, set it to 0; so that no *big.Int is nil. - In L1UserTx, don't set BatchNum, because when L1UserTxs are created and obtained by the synchronizer, the BatchNum is not known yet (it's a synchronizer job to set it) - In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago
Update missing parts, improve til, and more - Node - Updated configuration to initialize the interface to all the smart contracts - Common - Moved BlockData and BatchData types to common so that they can be shared among: historydb, til and synchronizer - Remove hash.go (it was never used) - Remove slot.go (it was never used) - Remove smartcontractparams.go (it was never used, and appropriate structs are defined in `eth/`) - Comment state / status method until requirements of this method are properly defined, and move it to Synchronizer - Synchronizer - Simplify `Sync` routine to only sync one block per call, and return useful information. - Use BlockData and BatchData from common - Check that events belong to the expected block hash - In L1Batch, query L1UserTxs from HistoryDB - Fill ERC20 token information - Test AddTokens with test.Client - HistryDB - Use BlockData and BatchData from common - Add `GetAllTokens` method - Uncomment and update GetL1UserTxs (with corresponding tests) - Til - Rename all instances of RegisterToken to AddToken (to follow the smart contract implementation naming) - Use BlockData and BatchData from common - Move testL1CoordinatorTxs and testL2Txs to a separate struct from BatchData in Context - Start Context with BatchNum = 1 (which the protocol defines to be the first batchNum) - In every Batch, set StateRoot and ExitRoot to a non-nil big.Int (zero). - In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not used, set it to 0; so that no *big.Int is nil. - In L1UserTx, don't set BatchNum, because when L1UserTxs are created and obtained by the synchronizer, the BatchNum is not known yet (it's a synchronizer job to set it) - In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
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 missing parts, improve til, and more - Node - Updated configuration to initialize the interface to all the smart contracts - Common - Moved BlockData and BatchData types to common so that they can be shared among: historydb, til and synchronizer - Remove hash.go (it was never used) - Remove slot.go (it was never used) - Remove smartcontractparams.go (it was never used, and appropriate structs are defined in `eth/`) - Comment state / status method until requirements of this method are properly defined, and move it to Synchronizer - Synchronizer - Simplify `Sync` routine to only sync one block per call, and return useful information. - Use BlockData and BatchData from common - Check that events belong to the expected block hash - In L1Batch, query L1UserTxs from HistoryDB - Fill ERC20 token information - Test AddTokens with test.Client - HistryDB - Use BlockData and BatchData from common - Add `GetAllTokens` method - Uncomment and update GetL1UserTxs (with corresponding tests) - Til - Rename all instances of RegisterToken to AddToken (to follow the smart contract implementation naming) - Use BlockData and BatchData from common - Move testL1CoordinatorTxs and testL2Txs to a separate struct from BatchData in Context - Start Context with BatchNum = 1 (which the protocol defines to be the first batchNum) - In every Batch, set StateRoot and ExitRoot to a non-nil big.Int (zero). - In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not used, set it to 0; so that no *big.Int is nil. - In L1UserTx, don't set BatchNum, because when L1UserTxs are created and obtained by the synchronizer, the BatchNum is not known yet (it's a synchronizer job to set it) - In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago
  1. package config
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "time"
  6. "github.com/BurntSushi/toml"
  7. ethCommon "github.com/ethereum/go-ethereum/common"
  8. "github.com/hermeznetwork/hermez-node/common"
  9. "github.com/hermeznetwork/tracerr"
  10. "gopkg.in/go-playground/validator.v9"
  11. )
  12. // Duration is a wrapper type that parses time duration from text.
  13. type Duration struct {
  14. time.Duration `validate:"required"`
  15. }
  16. // UnmarshalText unmarshalls time duration from text.
  17. func (d *Duration) UnmarshalText(data []byte) error {
  18. duration, err := time.ParseDuration(string(data))
  19. if err != nil {
  20. return tracerr.Wrap(err)
  21. }
  22. d.Duration = duration
  23. return nil
  24. }
  25. // ServerProof is the server proof configuration data.
  26. type ServerProof struct {
  27. URL string `validate:"required"`
  28. }
  29. // Coordinator is the coordinator specific configuration.
  30. type Coordinator struct {
  31. // ForgerAddress is the address under which this coordinator is forging
  32. ForgerAddress ethCommon.Address `validate:"required"`
  33. // ConfirmBlocks is the number of confirmation blocks to wait for sent
  34. // ethereum transactions before forgetting about them
  35. ConfirmBlocks int64 `validate:"required"`
  36. // L1BatchTimeoutPerc is the portion of the range before the L1Batch
  37. // timeout that will trigger a schedule to forge an L1Batch
  38. L1BatchTimeoutPerc float64 `validate:"required"`
  39. // ProofServerPollInterval is the waiting interval between polling the
  40. // ProofServer while waiting for a particular status
  41. ProofServerPollInterval Duration `validate:"required"`
  42. // SyncRetryInterval is the waiting interval between calls to the main
  43. // handler of a synced block after an error
  44. SyncRetryInterval Duration `validate:"required"`
  45. L2DB struct {
  46. SafetyPeriod common.BatchNum `validate:"required"`
  47. MaxTxs uint32 `validate:"required"`
  48. TTL Duration `validate:"required"`
  49. // PurgeBatchDelay is the delay between batches to purge outdated transactions
  50. PurgeBatchDelay int64 `validate:"required"`
  51. // InvalidateBatchDelay is the delay between batches to mark invalid transactions
  52. InvalidateBatchDelay int64 `validate:"required"`
  53. // PurgeBlockDelay is the delay between blocks to purge outdated transactions
  54. PurgeBlockDelay int64 `validate:"required"`
  55. // InvalidateBlockDelay is the delay between blocks to mark invalid transactions
  56. InvalidateBlockDelay int64 `validate:"required"`
  57. } `validate:"required"`
  58. TxSelector struct {
  59. Path string `validate:"required"`
  60. } `validate:"required"`
  61. BatchBuilder struct {
  62. Path string `validate:"required"`
  63. } `validate:"required"`
  64. ServerProofs []ServerProof `validate:"required"`
  65. Circuit struct {
  66. // VerifierIdx uint8 `validate:"required"`
  67. MaxTx int64 `validate:"required"`
  68. NLevels int64 `validate:"required"`
  69. } `validate:"required"`
  70. EthClient struct {
  71. CallGasLimit uint64 `validate:"required"`
  72. DeployGasLimit uint64 `validate:"required"`
  73. GasPriceDiv uint64 `validate:"required"`
  74. ReceiptTimeout Duration `validate:"required"`
  75. ReceiptLoopInterval Duration `validate:"required"`
  76. // CheckLoopInterval is the waiting interval between receipt
  77. // checks of ethereum transactions in the TxManager
  78. CheckLoopInterval Duration `validate:"required"`
  79. // Attempts is the number of attempts to do an eth client RPC
  80. // call before giving up
  81. Attempts int `validate:"required"`
  82. // AttemptsDelay is delay between attempts do do an eth client
  83. // RPC call
  84. AttemptsDelay Duration `validate:"required"`
  85. Keystore struct {
  86. Path string `validate:"required"`
  87. Password string `validate:"required"`
  88. } `validate:"required"`
  89. } `validate:"required"`
  90. API struct {
  91. Coordinator bool
  92. } `validate:"required"`
  93. Debug struct {
  94. // BatchPath if set, specifies the path where batchInfo is stored
  95. // in JSON in every step/update of the pipeline
  96. BatchPath string
  97. // LightScrypt if set, uses light parameters for the ethereum
  98. // keystore encryption algorithm.
  99. LightScrypt bool
  100. }
  101. }
  102. // Node is the hermez node configuration.
  103. type Node struct {
  104. PriceUpdater struct {
  105. Interval Duration `valudate:"required"`
  106. URL string `valudate:"required"`
  107. Type string `valudate:"required"`
  108. } `validate:"required"`
  109. StateDB struct {
  110. Path string `validate:"required"`
  111. Keep int `validate:"required"`
  112. } `validate:"required"`
  113. PostgreSQL struct {
  114. Port int `validate:"required"`
  115. Host string `validate:"required"`
  116. User string `validate:"required"`
  117. Password string `validate:"required"`
  118. Name string `validate:"required"`
  119. } `validate:"required"`
  120. Web3 struct {
  121. URL string `validate:"required"`
  122. } `validate:"required"`
  123. Synchronizer struct {
  124. SyncLoopInterval Duration `validate:"required"`
  125. StatsRefreshPeriod Duration `validate:"required"`
  126. } `validate:"required"`
  127. SmartContracts struct {
  128. Rollup ethCommon.Address `validate:"required"`
  129. Auction ethCommon.Address `validate:"required"`
  130. WDelayer ethCommon.Address `validate:"required"`
  131. TokenHEZ ethCommon.Address `validate:"required"`
  132. TokenHEZName string `validate:"required"`
  133. } `validate:"required"`
  134. API struct {
  135. Address string
  136. Explorer bool
  137. UpdateMetricsInterval Duration
  138. UpdateRecommendedFeeInterval Duration
  139. } `validate:"required"`
  140. Debug struct {
  141. APIAddress string
  142. }
  143. Coordinator Coordinator `validate:"-"`
  144. }
  145. // Load loads a generic config.
  146. func Load(path string, cfg interface{}) error {
  147. bs, err := ioutil.ReadFile(path) //nolint:gosec
  148. if err != nil {
  149. return tracerr.Wrap(err)
  150. }
  151. cfgToml := string(bs)
  152. if _, err := toml.Decode(cfgToml, cfg); err != nil {
  153. return tracerr.Wrap(err)
  154. }
  155. return nil
  156. }
  157. // LoadCoordinator loads the Coordinator configuration from path.
  158. func LoadCoordinator(path string) (*Node, error) {
  159. var cfg Node
  160. if err := Load(path, &cfg); err != nil {
  161. return nil, tracerr.Wrap(fmt.Errorf("error loading node configuration file: %w", err))
  162. }
  163. validate := validator.New()
  164. if err := validate.Struct(cfg); err != nil {
  165. return nil, tracerr.Wrap(fmt.Errorf("error validating configuration file: %w", err))
  166. }
  167. if err := validate.Struct(cfg.Coordinator); err != nil {
  168. return nil, tracerr.Wrap(fmt.Errorf("error validating configuration file: %w", err))
  169. }
  170. return &cfg, nil
  171. }
  172. // LoadNode loads the Node configuration from path.
  173. func LoadNode(path string) (*Node, error) {
  174. var cfg Node
  175. if err := Load(path, &cfg); err != nil {
  176. return nil, tracerr.Wrap(fmt.Errorf("error loading node configuration file: %w", err))
  177. }
  178. validate := validator.New()
  179. if err := validate.Struct(cfg); err != nil {
  180. return nil, tracerr.Wrap(fmt.Errorf("error validating configuration file: %w", err))
  181. }
  182. return &cfg, nil
  183. }