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.

170 lines
5.0 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
  1. package historydb
  2. import (
  3. "time"
  4. ethCommon "github.com/ethereum/go-ethereum/common"
  5. "github.com/hermeznetwork/hermez-node/apitypes"
  6. "github.com/hermeznetwork/hermez-node/common"
  7. "github.com/hermeznetwork/tracerr"
  8. "github.com/russross/meddler"
  9. )
  10. // Period represents a time period in ethereum
  11. type Period struct {
  12. SlotNum int64 `json:"slotNum"`
  13. FromBlock int64 `json:"fromBlock"`
  14. ToBlock int64 `json:"toBlock"`
  15. FromTimestamp time.Time `json:"fromTimestamp"`
  16. ToTimestamp time.Time `json:"toTimestamp"`
  17. }
  18. // NextForgerAPI represents the next forger exposed via the API
  19. type NextForgerAPI struct {
  20. Coordinator CoordinatorAPI `json:"coordinator"`
  21. Period Period `json:"period"`
  22. }
  23. // NetworkAPI is the network state exposed via the API
  24. type NetworkAPI struct {
  25. LastEthBlock int64 `json:"lastEthereumBlock"`
  26. LastSyncBlock int64 `json:"lastSynchedBlock"`
  27. LastBatch *BatchAPI `json:"lastBatch"`
  28. CurrentSlot int64 `json:"currentSlot"`
  29. NextForgers []NextForgerAPI `json:"nextForgers"`
  30. }
  31. // NodePublicConfig is the configuration of the node that is exposed via API
  32. type NodePublicConfig struct {
  33. // ForgeDelay in seconds
  34. ForgeDelay float64 `json:"forgeDelay"`
  35. }
  36. // StateAPI is an object representing the node and network state exposed via the API
  37. type StateAPI struct {
  38. // NodePublicConfig is the configuration of the node that is exposed via API
  39. NodePublicConfig NodePublicConfig `json:"nodeConfig"`
  40. Network NetworkAPI `json:"network"`
  41. Metrics MetricsAPI `json:"metrics"`
  42. Rollup RollupVariablesAPI `json:"rollup"`
  43. Auction AuctionVariablesAPI `json:"auction"`
  44. WithdrawalDelayer common.WDelayerVariables `json:"withdrawalDelayer"`
  45. RecommendedFee common.RecommendedFee `json:"recommendedFee"`
  46. }
  47. // Constants contains network constants
  48. type Constants struct {
  49. common.SCConsts
  50. ChainID uint16
  51. HermezAddress ethCommon.Address
  52. }
  53. // NodeConfig contains the node config exposed in the API
  54. type NodeConfig struct {
  55. MaxPoolTxs uint32
  56. MinFeeUSD float64
  57. ForgeDelay float64
  58. }
  59. // NodeInfo contains information about he node used when serving the API
  60. type NodeInfo struct {
  61. ItemID int `meddler:"item_id,pk"`
  62. StateAPI *StateAPI `meddler:"state,json"`
  63. NodeConfig *NodeConfig `meddler:"config,json"`
  64. Constants *Constants `meddler:"constants,json"`
  65. }
  66. // GetNodeInfo returns the NodeInfo
  67. func (hdb *HistoryDB) GetNodeInfo() (*NodeInfo, error) {
  68. ni := &NodeInfo{}
  69. err := meddler.QueryRow(
  70. hdb.dbRead, ni, `SELECT * FROM node_info WHERE item_id = 1;`,
  71. )
  72. return ni, tracerr.Wrap(err)
  73. }
  74. // GetConstants returns the Constats
  75. func (hdb *HistoryDB) GetConstants() (*Constants, error) {
  76. var nodeInfo NodeInfo
  77. err := meddler.QueryRow(
  78. hdb.dbRead, &nodeInfo,
  79. "SELECT constants FROM node_info WHERE item_id = 1;",
  80. )
  81. return nodeInfo.Constants, tracerr.Wrap(err)
  82. }
  83. // SetConstants sets the Constants
  84. func (hdb *HistoryDB) SetConstants(constants *Constants) error {
  85. _constants := struct {
  86. Constants *Constants `meddler:"constants,json"`
  87. }{constants}
  88. values, err := meddler.Default.Values(&_constants, false)
  89. if err != nil {
  90. return tracerr.Wrap(err)
  91. }
  92. _, err = hdb.dbWrite.Exec(
  93. "UPDATE node_info SET constants = $1 WHERE item_id = 1;",
  94. values[0],
  95. )
  96. return tracerr.Wrap(err)
  97. }
  98. // GetStateInternalAPI returns the StateAPI
  99. func (hdb *HistoryDB) GetStateInternalAPI() (*StateAPI, error) {
  100. return hdb.getStateAPI(hdb.dbRead)
  101. }
  102. func (hdb *HistoryDB) getStateAPI(d meddler.DB) (*StateAPI, error) {
  103. var nodeInfo NodeInfo
  104. err := meddler.QueryRow(
  105. d, &nodeInfo,
  106. "SELECT state FROM node_info WHERE item_id = 1;",
  107. )
  108. return nodeInfo.StateAPI, tracerr.Wrap(err)
  109. }
  110. // SetStateInternalAPI sets the StateAPI
  111. func (hdb *HistoryDB) SetStateInternalAPI(stateAPI *StateAPI) error {
  112. if stateAPI.Network.LastBatch != nil {
  113. stateAPI.Network.LastBatch.CollectedFeesAPI =
  114. apitypes.NewCollectedFeesAPI(stateAPI.Network.LastBatch.CollectedFeesDB)
  115. }
  116. _stateAPI := struct {
  117. StateAPI *StateAPI `meddler:"state,json"`
  118. }{stateAPI}
  119. values, err := meddler.Default.Values(&_stateAPI, false)
  120. if err != nil {
  121. return tracerr.Wrap(err)
  122. }
  123. _, err = hdb.dbWrite.Exec(
  124. "UPDATE node_info SET state = $1 WHERE item_id = 1;",
  125. values[0],
  126. )
  127. return tracerr.Wrap(err)
  128. }
  129. // GetNodeConfig returns the NodeConfig
  130. func (hdb *HistoryDB) GetNodeConfig() (*NodeConfig, error) {
  131. var nodeInfo NodeInfo
  132. err := meddler.QueryRow(
  133. hdb.dbRead, &nodeInfo,
  134. "SELECT config FROM node_info WHERE item_id = 1;",
  135. )
  136. return nodeInfo.NodeConfig, tracerr.Wrap(err)
  137. }
  138. // SetNodeConfig sets the NodeConfig
  139. func (hdb *HistoryDB) SetNodeConfig(nodeConfig *NodeConfig) error {
  140. _nodeConfig := struct {
  141. NodeConfig *NodeConfig `meddler:"config,json"`
  142. }{nodeConfig}
  143. values, err := meddler.Default.Values(&_nodeConfig, false)
  144. if err != nil {
  145. return tracerr.Wrap(err)
  146. }
  147. _, err = hdb.dbWrite.Exec(
  148. "UPDATE node_info SET config = $1 WHERE item_id = 1;",
  149. values[0],
  150. )
  151. return tracerr.Wrap(err)
  152. }