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.

171 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
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. PendingL1Txs int `json:"pendingL1Transactions"`
  31. }
  32. // NodePublicConfig is the configuration of the node that is exposed via API
  33. type NodePublicConfig struct {
  34. // ForgeDelay in seconds
  35. ForgeDelay float64 `json:"forgeDelay"`
  36. }
  37. // StateAPI is an object representing the node and network state exposed via the API
  38. type StateAPI struct {
  39. // NodePublicConfig is the configuration of the node that is exposed via API
  40. NodePublicConfig NodePublicConfig `json:"nodeConfig"`
  41. Network NetworkAPI `json:"network"`
  42. Metrics MetricsAPI `json:"metrics"`
  43. Rollup RollupVariablesAPI `json:"rollup"`
  44. Auction AuctionVariablesAPI `json:"auction"`
  45. WithdrawalDelayer common.WDelayerVariables `json:"withdrawalDelayer"`
  46. RecommendedFee common.RecommendedFee `json:"recommendedFee"`
  47. }
  48. // Constants contains network constants
  49. type Constants struct {
  50. common.SCConsts
  51. ChainID uint16
  52. HermezAddress ethCommon.Address
  53. }
  54. // NodeConfig contains the node config exposed in the API
  55. type NodeConfig struct {
  56. MaxPoolTxs uint32
  57. MinFeeUSD float64
  58. ForgeDelay float64
  59. }
  60. // NodeInfo contains information about he node used when serving the API
  61. type NodeInfo struct {
  62. ItemID int `meddler:"item_id,pk"`
  63. StateAPI *StateAPI `meddler:"state,json"`
  64. NodeConfig *NodeConfig `meddler:"config,json"`
  65. Constants *Constants `meddler:"constants,json"`
  66. }
  67. // GetNodeInfo returns the NodeInfo
  68. func (hdb *HistoryDB) GetNodeInfo() (*NodeInfo, error) {
  69. ni := &NodeInfo{}
  70. err := meddler.QueryRow(
  71. hdb.dbRead, ni, `SELECT * FROM node_info WHERE item_id = 1;`,
  72. )
  73. return ni, tracerr.Wrap(err)
  74. }
  75. // GetConstants returns the Constats
  76. func (hdb *HistoryDB) GetConstants() (*Constants, error) {
  77. var nodeInfo NodeInfo
  78. err := meddler.QueryRow(
  79. hdb.dbRead, &nodeInfo,
  80. "SELECT constants FROM node_info WHERE item_id = 1;",
  81. )
  82. return nodeInfo.Constants, tracerr.Wrap(err)
  83. }
  84. // SetConstants sets the Constants
  85. func (hdb *HistoryDB) SetConstants(constants *Constants) error {
  86. _constants := struct {
  87. Constants *Constants `meddler:"constants,json"`
  88. }{constants}
  89. values, err := meddler.Default.Values(&_constants, false)
  90. if err != nil {
  91. return tracerr.Wrap(err)
  92. }
  93. _, err = hdb.dbWrite.Exec(
  94. "UPDATE node_info SET constants = $1 WHERE item_id = 1;",
  95. values[0],
  96. )
  97. return tracerr.Wrap(err)
  98. }
  99. // GetStateInternalAPI returns the StateAPI
  100. func (hdb *HistoryDB) GetStateInternalAPI() (*StateAPI, error) {
  101. return hdb.getStateAPI(hdb.dbRead)
  102. }
  103. func (hdb *HistoryDB) getStateAPI(d meddler.DB) (*StateAPI, error) {
  104. var nodeInfo NodeInfo
  105. err := meddler.QueryRow(
  106. d, &nodeInfo,
  107. "SELECT state FROM node_info WHERE item_id = 1;",
  108. )
  109. return nodeInfo.StateAPI, tracerr.Wrap(err)
  110. }
  111. // SetStateInternalAPI sets the StateAPI
  112. func (hdb *HistoryDB) SetStateInternalAPI(stateAPI *StateAPI) error {
  113. if stateAPI.Network.LastBatch != nil {
  114. stateAPI.Network.LastBatch.CollectedFeesAPI =
  115. apitypes.NewCollectedFeesAPI(stateAPI.Network.LastBatch.CollectedFeesDB)
  116. }
  117. _stateAPI := struct {
  118. StateAPI *StateAPI `meddler:"state,json"`
  119. }{stateAPI}
  120. values, err := meddler.Default.Values(&_stateAPI, false)
  121. if err != nil {
  122. return tracerr.Wrap(err)
  123. }
  124. _, err = hdb.dbWrite.Exec(
  125. "UPDATE node_info SET state = $1 WHERE item_id = 1;",
  126. values[0],
  127. )
  128. return tracerr.Wrap(err)
  129. }
  130. // GetNodeConfig returns the NodeConfig
  131. func (hdb *HistoryDB) GetNodeConfig() (*NodeConfig, error) {
  132. var nodeInfo NodeInfo
  133. err := meddler.QueryRow(
  134. hdb.dbRead, &nodeInfo,
  135. "SELECT config FROM node_info WHERE item_id = 1;",
  136. )
  137. return nodeInfo.NodeConfig, tracerr.Wrap(err)
  138. }
  139. // SetNodeConfig sets the NodeConfig
  140. func (hdb *HistoryDB) SetNodeConfig(nodeConfig *NodeConfig) error {
  141. _nodeConfig := struct {
  142. NodeConfig *NodeConfig `meddler:"config,json"`
  143. }{nodeConfig}
  144. values, err := meddler.Default.Values(&_nodeConfig, false)
  145. if err != nil {
  146. return tracerr.Wrap(err)
  147. }
  148. _, err = hdb.dbWrite.Exec(
  149. "UPDATE node_info SET config = $1 WHERE item_id = 1;",
  150. values[0],
  151. )
  152. return tracerr.Wrap(err)
  153. }