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.

162 lines
4.3 KiB

Allow serving API only via new cli command - Add new command to the cli/node: `serveapi` that alows serving the API just by connecting to the PostgreSQL database. The mode flag should me passed in order to select whether we are connecting to a synchronizer database or a coordinator database. If `coord` is chosen as mode, the coordinator endpoints can be activated in order to allow inserting l2txs and authorizations into the L2DB. Summary of the implementation details - New SQL table with 3 columns (plus `item_id` pk). The table only contains a single row with `item_id` = 1. Columns: - state: historydb.StateAPI in JSON. This is the struct that is served via the `/state` API endpoint. The node will periodically update this struct and store it int he DB. The api server will query it from the DB to serve it. - config: historydb.NodeConfig in JSON. This struct contains node configuration parameters that the API needs to be aware of. It's updated once every time the node starts. - constants: historydb.Constants in JSON. This struct contains all the hermez network constants gathered via the ethereum client by the node. It's written once every time the node starts. - The HistoryDB contains methods to get and update each one of these columns individually. - The HistoryDB contains all methods that query the DB and prepare objects that will appear in the StateAPI endpoint. - The configuration used in for the `serveapi` cli/node command is defined in `config.APIServer`, and is a subset of `node.Config` in order to allow reusing the same configuration file of the node if desired. - A new object is introduced in the api: `StateAPIUpdater`, which contains all the necessary information to update the StateAPI in the DB periodically by the node. - Moved the types `SCConsts`, `SCVariables` and `SCVariablesPtr` from `syncrhonizer` to `common` for convenience.
3 years ago
Allow serving API only via new cli command - Add new command to the cli/node: `serveapi` that alows serving the API just by connecting to the PostgreSQL database. The mode flag should me passed in order to select whether we are connecting to a synchronizer database or a coordinator database. If `coord` is chosen as mode, the coordinator endpoints can be activated in order to allow inserting l2txs and authorizations into the L2DB. Summary of the implementation details - New SQL table with 3 columns (plus `item_id` pk). The table only contains a single row with `item_id` = 1. Columns: - state: historydb.StateAPI in JSON. This is the struct that is served via the `/state` API endpoint. The node will periodically update this struct and store it int he DB. The api server will query it from the DB to serve it. - config: historydb.NodeConfig in JSON. This struct contains node configuration parameters that the API needs to be aware of. It's updated once every time the node starts. - constants: historydb.Constants in JSON. This struct contains all the hermez network constants gathered via the ethereum client by the node. It's written once every time the node starts. - The HistoryDB contains methods to get and update each one of these columns individually. - The HistoryDB contains all methods that query the DB and prepare objects that will appear in the StateAPI endpoint. - The configuration used in for the `serveapi` cli/node command is defined in `config.APIServer`, and is a subset of `node.Config` in order to allow reusing the same configuration file of the node if desired. - A new object is introduced in the api: `StateAPIUpdater`, which contains all the necessary information to update the StateAPI in the DB periodically by the node. - Moved the types `SCConsts`, `SCVariables` and `SCVariablesPtr` from `syncrhonizer` to `common` for convenience.
3 years ago
Allow serving API only via new cli command - Add new command to the cli/node: `serveapi` that alows serving the API just by connecting to the PostgreSQL database. The mode flag should me passed in order to select whether we are connecting to a synchronizer database or a coordinator database. If `coord` is chosen as mode, the coordinator endpoints can be activated in order to allow inserting l2txs and authorizations into the L2DB. Summary of the implementation details - New SQL table with 3 columns (plus `item_id` pk). The table only contains a single row with `item_id` = 1. Columns: - state: historydb.StateAPI in JSON. This is the struct that is served via the `/state` API endpoint. The node will periodically update this struct and store it int he DB. The api server will query it from the DB to serve it. - config: historydb.NodeConfig in JSON. This struct contains node configuration parameters that the API needs to be aware of. It's updated once every time the node starts. - constants: historydb.Constants in JSON. This struct contains all the hermez network constants gathered via the ethereum client by the node. It's written once every time the node starts. - The HistoryDB contains methods to get and update each one of these columns individually. - The HistoryDB contains all methods that query the DB and prepare objects that will appear in the StateAPI endpoint. - The configuration used in for the `serveapi` cli/node command is defined in `config.APIServer`, and is a subset of `node.Config` in order to allow reusing the same configuration file of the node if desired. - A new object is introduced in the api: `StateAPIUpdater`, which contains all the necessary information to update the StateAPI in the DB periodically by the node. - Moved the types `SCConsts`, `SCVariables` and `SCVariablesPtr` from `syncrhonizer` to `common` for convenience.
3 years ago
Allow serving API only via new cli command - Add new command to the cli/node: `serveapi` that alows serving the API just by connecting to the PostgreSQL database. The mode flag should me passed in order to select whether we are connecting to a synchronizer database or a coordinator database. If `coord` is chosen as mode, the coordinator endpoints can be activated in order to allow inserting l2txs and authorizations into the L2DB. Summary of the implementation details - New SQL table with 3 columns (plus `item_id` pk). The table only contains a single row with `item_id` = 1. Columns: - state: historydb.StateAPI in JSON. This is the struct that is served via the `/state` API endpoint. The node will periodically update this struct and store it int he DB. The api server will query it from the DB to serve it. - config: historydb.NodeConfig in JSON. This struct contains node configuration parameters that the API needs to be aware of. It's updated once every time the node starts. - constants: historydb.Constants in JSON. This struct contains all the hermez network constants gathered via the ethereum client by the node. It's written once every time the node starts. - The HistoryDB contains methods to get and update each one of these columns individually. - The HistoryDB contains all methods that query the DB and prepare objects that will appear in the StateAPI endpoint. - The configuration used in for the `serveapi` cli/node command is defined in `config.APIServer`, and is a subset of `node.Config` in order to allow reusing the same configuration file of the node if desired. - A new object is introduced in the api: `StateAPIUpdater`, which contains all the necessary information to update the StateAPI in the DB periodically by the node. - Moved the types `SCConsts`, `SCVariables` and `SCVariablesPtr` from `syncrhonizer` to `common` for convenience.
3 years ago
Allow serving API only via new cli command - Add new command to the cli/node: `serveapi` that alows serving the API just by connecting to the PostgreSQL database. The mode flag should me passed in order to select whether we are connecting to a synchronizer database or a coordinator database. If `coord` is chosen as mode, the coordinator endpoints can be activated in order to allow inserting l2txs and authorizations into the L2DB. Summary of the implementation details - New SQL table with 3 columns (plus `item_id` pk). The table only contains a single row with `item_id` = 1. Columns: - state: historydb.StateAPI in JSON. This is the struct that is served via the `/state` API endpoint. The node will periodically update this struct and store it int he DB. The api server will query it from the DB to serve it. - config: historydb.NodeConfig in JSON. This struct contains node configuration parameters that the API needs to be aware of. It's updated once every time the node starts. - constants: historydb.Constants in JSON. This struct contains all the hermez network constants gathered via the ethereum client by the node. It's written once every time the node starts. - The HistoryDB contains methods to get and update each one of these columns individually. - The HistoryDB contains all methods that query the DB and prepare objects that will appear in the StateAPI endpoint. - The configuration used in for the `serveapi` cli/node command is defined in `config.APIServer`, and is a subset of `node.Config` in order to allow reusing the same configuration file of the node if desired. - A new object is introduced in the api: `StateAPIUpdater`, which contains all the necessary information to update the StateAPI in the DB periodically by the node. - Moved the types `SCConsts`, `SCVariables` and `SCVariablesPtr` from `syncrhonizer` to `common` for convenience.
3 years ago
Allow serving API only via new cli command - Add new command to the cli/node: `serveapi` that alows serving the API just by connecting to the PostgreSQL database. The mode flag should me passed in order to select whether we are connecting to a synchronizer database or a coordinator database. If `coord` is chosen as mode, the coordinator endpoints can be activated in order to allow inserting l2txs and authorizations into the L2DB. Summary of the implementation details - New SQL table with 3 columns (plus `item_id` pk). The table only contains a single row with `item_id` = 1. Columns: - state: historydb.StateAPI in JSON. This is the struct that is served via the `/state` API endpoint. The node will periodically update this struct and store it int he DB. The api server will query it from the DB to serve it. - config: historydb.NodeConfig in JSON. This struct contains node configuration parameters that the API needs to be aware of. It's updated once every time the node starts. - constants: historydb.Constants in JSON. This struct contains all the hermez network constants gathered via the ethereum client by the node. It's written once every time the node starts. - The HistoryDB contains methods to get and update each one of these columns individually. - The HistoryDB contains all methods that query the DB and prepare objects that will appear in the StateAPI endpoint. - The configuration used in for the `serveapi` cli/node command is defined in `config.APIServer`, and is a subset of `node.Config` in order to allow reusing the same configuration file of the node if desired. - A new object is introduced in the api: `StateAPIUpdater`, which contains all the necessary information to update the StateAPI in the DB periodically by the node. - Moved the types `SCConsts`, `SCVariables` and `SCVariablesPtr` from `syncrhonizer` to `common` for convenience.
3 years ago
Allow serving API only via new cli command - Add new command to the cli/node: `serveapi` that alows serving the API just by connecting to the PostgreSQL database. The mode flag should me passed in order to select whether we are connecting to a synchronizer database or a coordinator database. If `coord` is chosen as mode, the coordinator endpoints can be activated in order to allow inserting l2txs and authorizations into the L2DB. Summary of the implementation details - New SQL table with 3 columns (plus `item_id` pk). The table only contains a single row with `item_id` = 1. Columns: - state: historydb.StateAPI in JSON. This is the struct that is served via the `/state` API endpoint. The node will periodically update this struct and store it int he DB. The api server will query it from the DB to serve it. - config: historydb.NodeConfig in JSON. This struct contains node configuration parameters that the API needs to be aware of. It's updated once every time the node starts. - constants: historydb.Constants in JSON. This struct contains all the hermez network constants gathered via the ethereum client by the node. It's written once every time the node starts. - The HistoryDB contains methods to get and update each one of these columns individually. - The HistoryDB contains all methods that query the DB and prepare objects that will appear in the StateAPI endpoint. - The configuration used in for the `serveapi` cli/node command is defined in `config.APIServer`, and is a subset of `node.Config` in order to allow reusing the same configuration file of the node if desired. - A new object is introduced in the api: `StateAPIUpdater`, which contains all the necessary information to update the StateAPI in the DB periodically by the node. - Moved the types `SCConsts`, `SCVariables` and `SCVariablesPtr` from `syncrhonizer` to `common` for convenience.
3 years ago
  1. package stateapiupdater
  2. import (
  3. "database/sql"
  4. "sync"
  5. "github.com/hermeznetwork/hermez-node/common"
  6. "github.com/hermeznetwork/hermez-node/db/historydb"
  7. "github.com/hermeznetwork/tracerr"
  8. )
  9. // Updater is an utility object to facilitate updating the StateAPI
  10. type Updater struct {
  11. hdb *historydb.HistoryDB
  12. state historydb.StateAPI
  13. config historydb.NodeConfig
  14. vars common.SCVariablesPtr
  15. consts historydb.Constants
  16. rw sync.RWMutex
  17. }
  18. // NewUpdater creates a new Updater
  19. func NewUpdater(hdb *historydb.HistoryDB, config *historydb.NodeConfig, vars *common.SCVariables,
  20. consts *historydb.Constants) *Updater {
  21. u := Updater{
  22. hdb: hdb,
  23. config: *config,
  24. consts: *consts,
  25. state: historydb.StateAPI{
  26. NodePublicInfo: historydb.NodePublicInfo{
  27. ForgeDelay: config.ForgeDelay,
  28. },
  29. },
  30. }
  31. u.SetSCVars(vars.AsPtr())
  32. return &u
  33. }
  34. // Store the State in the HistoryDB
  35. func (u *Updater) Store() error {
  36. u.rw.RLock()
  37. defer u.rw.RUnlock()
  38. return tracerr.Wrap(u.hdb.SetStateInternalAPI(&u.state))
  39. }
  40. // SetSCVars sets the smart contract vars (ony updates those that are not nil)
  41. func (u *Updater) SetSCVars(vars *common.SCVariablesPtr) {
  42. u.rw.Lock()
  43. defer u.rw.Unlock()
  44. if vars.Rollup != nil {
  45. u.vars.Rollup = vars.Rollup
  46. rollupVars := historydb.NewRollupVariablesAPI(u.vars.Rollup)
  47. u.state.Rollup = *rollupVars
  48. }
  49. if vars.Auction != nil {
  50. u.vars.Auction = vars.Auction
  51. auctionVars := historydb.NewAuctionVariablesAPI(u.vars.Auction)
  52. u.state.Auction = *auctionVars
  53. }
  54. if vars.WDelayer != nil {
  55. u.vars.WDelayer = vars.WDelayer
  56. u.state.WithdrawalDelayer = *u.vars.WDelayer
  57. }
  58. }
  59. // UpdateRecommendedFee update Status.RecommendedFee information
  60. func (u *Updater) UpdateRecommendedFee() error {
  61. recommendedFee, err := u.hdb.GetRecommendedFee(u.config.MinFeeUSD, u.config.MaxFeeUSD)
  62. if err != nil {
  63. return tracerr.Wrap(err)
  64. }
  65. u.rw.Lock()
  66. u.state.RecommendedFee = *recommendedFee
  67. u.rw.Unlock()
  68. return nil
  69. }
  70. // UpdateMetrics update Status.Metrics information
  71. func (u *Updater) UpdateMetrics() error {
  72. u.rw.RLock()
  73. lastBatch := u.state.Network.LastBatch
  74. u.rw.RUnlock()
  75. if lastBatch == nil {
  76. return nil
  77. }
  78. lastBatchNum := lastBatch.BatchNum
  79. metrics, poolLoad, err := u.hdb.GetMetricsInternalAPI(lastBatchNum)
  80. if err != nil {
  81. return tracerr.Wrap(err)
  82. }
  83. u.rw.Lock()
  84. u.state.Metrics = *metrics
  85. u.state.NodePublicInfo.PoolLoad = poolLoad
  86. u.rw.Unlock()
  87. return nil
  88. }
  89. // UpdateNetworkInfoBlock update Status.Network block related information
  90. func (u *Updater) UpdateNetworkInfoBlock(lastEthBlock, lastSyncBlock common.Block) {
  91. u.rw.Lock()
  92. u.state.Network.LastSyncBlock = lastSyncBlock.Num
  93. u.state.Network.LastEthBlock = lastEthBlock.Num
  94. u.rw.Unlock()
  95. }
  96. // UpdateNetworkInfo update Status.Network information
  97. func (u *Updater) UpdateNetworkInfo(
  98. lastEthBlock, lastSyncBlock common.Block,
  99. lastBatchNum common.BatchNum, currentSlot int64,
  100. ) error {
  101. // Get last batch in API format
  102. lastBatch, err := u.hdb.GetBatchInternalAPI(lastBatchNum)
  103. if tracerr.Unwrap(err) == sql.ErrNoRows {
  104. lastBatch = nil
  105. } else if err != nil {
  106. return tracerr.Wrap(err)
  107. }
  108. u.rw.RLock()
  109. auctionVars := u.vars.Auction
  110. u.rw.RUnlock()
  111. // Get next forgers
  112. lastClosedSlot := currentSlot + int64(auctionVars.ClosedAuctionSlots)
  113. nextForgers, err := u.hdb.GetNextForgersInternalAPI(auctionVars, &u.consts.Auction,
  114. lastSyncBlock, currentSlot, lastClosedSlot)
  115. if tracerr.Unwrap(err) == sql.ErrNoRows {
  116. nextForgers = nil
  117. } else if err != nil {
  118. return tracerr.Wrap(err)
  119. }
  120. bucketUpdates, err := u.hdb.GetBucketUpdatesInternalAPI()
  121. if err == sql.ErrNoRows {
  122. bucketUpdates = nil
  123. } else if err != nil {
  124. return tracerr.Wrap(err)
  125. }
  126. u.rw.Lock()
  127. // Update NodeInfo struct
  128. for i, bucketParams := range u.state.Rollup.Buckets {
  129. for _, bucketUpdate := range bucketUpdates {
  130. if bucketUpdate.NumBucket == i {
  131. bucketParams.Withdrawals = bucketUpdate.Withdrawals
  132. u.state.Rollup.Buckets[i] = bucketParams
  133. break
  134. }
  135. }
  136. }
  137. // Update pending L1s
  138. pendingL1s, err := u.hdb.GetUnforgedL1UserTxsCount()
  139. if err != nil {
  140. return tracerr.Wrap(err)
  141. }
  142. u.state.Network.LastSyncBlock = lastSyncBlock.Num
  143. u.state.Network.LastEthBlock = lastEthBlock.Num
  144. u.state.Network.LastBatch = lastBatch
  145. u.state.Network.CurrentSlot = currentSlot
  146. u.state.Network.NextForgers = nextForgers
  147. u.state.Network.PendingL1Txs = pendingL1s
  148. u.rw.Unlock()
  149. return nil
  150. }