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.

195 lines
6.0 KiB

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 api
  2. import (
  3. "database/sql"
  4. "net/http"
  5. "time"
  6. ethCommon "github.com/ethereum/go-ethereum/common"
  7. "github.com/gin-gonic/gin"
  8. "github.com/hermeznetwork/hermez-node/common"
  9. "github.com/hermeznetwork/hermez-node/db/historydb"
  10. "github.com/hermeznetwork/tracerr"
  11. )
  12. // Network define status of the network
  13. type Network struct {
  14. LastEthBlock int64 `json:"lastEthereumBlock"`
  15. LastSyncBlock int64 `json:"lastSynchedBlock"`
  16. LastBatch *historydb.BatchAPI `json:"lastBatch"`
  17. CurrentSlot int64 `json:"currentSlot"`
  18. NextForgers []NextForger `json:"nextForgers"`
  19. }
  20. // NextForger is a representation of the information of a coordinator and the period will forge
  21. type NextForger struct {
  22. Coordinator historydb.CoordinatorAPI `json:"coordinator"`
  23. Period Period `json:"period"`
  24. }
  25. // Period is a representation of a period
  26. type Period struct {
  27. SlotNum int64 `json:"slotNum"`
  28. FromBlock int64 `json:"fromBlock"`
  29. ToBlock int64 `json:"toBlock"`
  30. FromTimestamp time.Time `json:"fromTimestamp"`
  31. ToTimestamp time.Time `json:"toTimestamp"`
  32. }
  33. var bootCoordinator historydb.CoordinatorAPI = historydb.CoordinatorAPI{
  34. ItemID: 0,
  35. Bidder: ethCommon.HexToAddress("0x111111111111111111111111111111111111111"),
  36. Forger: ethCommon.HexToAddress("0x111111111111111111111111111111111111111"),
  37. URL: "https://bootCoordinator",
  38. }
  39. func (a *API) getState(c *gin.Context) {
  40. // TODO: There are no events for the buckets information, so now this information will be 0
  41. a.status.RLock()
  42. status := a.status //nolint
  43. a.status.RUnlock()
  44. c.JSON(http.StatusOK, status) //nolint
  45. }
  46. // SC Vars
  47. // SetRollupVariables set Status.Rollup variables
  48. func (a *API) SetRollupVariables(rollupVariables common.RollupVariables) {
  49. a.status.Lock()
  50. a.status.Rollup = rollupVariables
  51. a.status.Unlock()
  52. }
  53. // SetWDelayerVariables set Status.WithdrawalDelayer variables
  54. func (a *API) SetWDelayerVariables(wDelayerVariables common.WDelayerVariables) {
  55. a.status.Lock()
  56. a.status.WithdrawalDelayer = wDelayerVariables
  57. a.status.Unlock()
  58. }
  59. // SetAuctionVariables set Status.Auction variables
  60. func (a *API) SetAuctionVariables(auctionVariables common.AuctionVariables) {
  61. a.status.Lock()
  62. a.status.Auction = auctionVariables
  63. a.status.Unlock()
  64. }
  65. // Network
  66. // UpdateNetworkInfoBlock update Status.Network block related information
  67. func (a *API) UpdateNetworkInfoBlock(
  68. lastEthBlock, lastSyncBlock common.Block,
  69. ) {
  70. a.status.Network.LastSyncBlock = lastSyncBlock.Num
  71. a.status.Network.LastEthBlock = lastEthBlock.Num
  72. }
  73. // UpdateNetworkInfo update Status.Network information
  74. func (a *API) UpdateNetworkInfo(
  75. lastEthBlock, lastSyncBlock common.Block,
  76. lastBatchNum common.BatchNum, currentSlot int64,
  77. ) error {
  78. lastBatch, err := a.h.GetBatchAPI(lastBatchNum)
  79. if tracerr.Unwrap(err) == sql.ErrNoRows {
  80. lastBatch = nil
  81. } else if err != nil {
  82. return tracerr.Wrap(err)
  83. }
  84. lastClosedSlot := currentSlot + int64(a.status.Auction.ClosedAuctionSlots)
  85. nextForgers, err := a.getNextForgers(lastSyncBlock, currentSlot, lastClosedSlot)
  86. if tracerr.Unwrap(err) == sql.ErrNoRows {
  87. nextForgers = nil
  88. } else if err != nil {
  89. return tracerr.Wrap(err)
  90. }
  91. a.status.Lock()
  92. a.status.Network.LastSyncBlock = lastSyncBlock.Num
  93. a.status.Network.LastEthBlock = lastEthBlock.Num
  94. a.status.Network.LastBatch = lastBatch
  95. a.status.Network.CurrentSlot = currentSlot
  96. a.status.Network.NextForgers = nextForgers
  97. a.status.Unlock()
  98. return nil
  99. }
  100. // getNextForgers returns next forgers
  101. func (a *API) getNextForgers(lastBlock common.Block, currentSlot, lastClosedSlot int64) ([]NextForger, error) {
  102. secondsPerBlock := int64(15) //nolint:gomnd
  103. // currentSlot and lastClosedSlot included
  104. limit := uint(lastClosedSlot - currentSlot + 1)
  105. bids, _, err := a.h.GetBestBidsAPI(&currentSlot, &lastClosedSlot, nil, &limit, "ASC")
  106. if err != nil {
  107. return nil, tracerr.Wrap(err)
  108. }
  109. nextForgers := []NextForger{}
  110. // Create nextForger for each slot
  111. for i := currentSlot; i <= lastClosedSlot; i++ {
  112. fromBlock := i*int64(a.cg.AuctionConstants.BlocksPerSlot) + a.cg.AuctionConstants.GenesisBlockNum
  113. toBlock := (i+1)*int64(a.cg.AuctionConstants.BlocksPerSlot) + a.cg.AuctionConstants.GenesisBlockNum - 1
  114. nextForger := NextForger{
  115. Period: Period{
  116. SlotNum: i,
  117. FromBlock: fromBlock,
  118. ToBlock: toBlock,
  119. FromTimestamp: lastBlock.Timestamp.Add(time.Second * time.Duration(secondsPerBlock*(fromBlock-lastBlock.Num))),
  120. ToTimestamp: lastBlock.Timestamp.Add(time.Second * time.Duration(secondsPerBlock*(toBlock-lastBlock.Num))),
  121. },
  122. }
  123. foundBid := false
  124. // If there is a bid for a slot, get forger (coordinator)
  125. for j := range bids {
  126. if bids[j].SlotNum == i {
  127. foundBid = true
  128. coordinator, err := a.h.GetCoordinatorAPI(bids[j].Bidder)
  129. if err != nil {
  130. return nil, tracerr.Wrap(err)
  131. }
  132. nextForger.Coordinator = *coordinator
  133. break
  134. }
  135. }
  136. // If there is no bid, the coordinator that will forge is boot coordinator
  137. if !foundBid {
  138. nextForger.Coordinator = bootCoordinator
  139. }
  140. nextForgers = append(nextForgers, nextForger)
  141. }
  142. return nextForgers, nil
  143. }
  144. // Metrics
  145. // UpdateMetrics update Status.Metrics information
  146. func (a *API) UpdateMetrics() error {
  147. a.status.RLock()
  148. if a.status.Network.LastBatch == nil {
  149. a.status.RUnlock()
  150. return nil
  151. }
  152. batchNum := a.status.Network.LastBatch.BatchNum
  153. a.status.RUnlock()
  154. metrics, err := a.h.GetMetrics(batchNum)
  155. if err != nil {
  156. return tracerr.Wrap(err)
  157. }
  158. a.status.Lock()
  159. a.status.Metrics = *metrics
  160. a.status.Unlock()
  161. return nil
  162. }
  163. // Recommended fee
  164. // UpdateRecommendedFee update Status.RecommendedFee information
  165. func (a *API) UpdateRecommendedFee() error {
  166. feeExistingAccount, err := a.h.GetAvgTxFee()
  167. if err != nil {
  168. return tracerr.Wrap(err)
  169. }
  170. a.status.Lock()
  171. a.status.RecommendedFee.ExistingAccount = feeExistingAccount
  172. a.status.RecommendedFee.CreatesAccount = createAccountExtraFeePercentage * feeExistingAccount
  173. a.status.RecommendedFee.CreatesAccountAndRegister = createAccountInternalExtraFeePercentage * feeExistingAccount
  174. a.status.Unlock()
  175. return nil
  176. }