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.

1206 lines
36 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
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
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
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
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
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. "database/sql"
  4. "errors"
  5. "fmt"
  6. "math/big"
  7. "time"
  8. ethCommon "github.com/ethereum/go-ethereum/common"
  9. "github.com/hermeznetwork/hermez-node/api/apitypes"
  10. "github.com/hermeznetwork/hermez-node/common"
  11. "github.com/hermeznetwork/hermez-node/db"
  12. "github.com/hermeznetwork/tracerr"
  13. "github.com/iden3/go-iden3-crypto/babyjub"
  14. "github.com/jmoiron/sqlx"
  15. "github.com/russross/meddler"
  16. )
  17. // GetLastBlockAPI retrieve the block with the highest block number from the DB
  18. func (hdb *HistoryDB) GetLastBlockAPI() (*common.Block, error) {
  19. cancel, err := hdb.apiConnCon.Acquire()
  20. defer cancel()
  21. if err != nil {
  22. return nil, tracerr.Wrap(err)
  23. }
  24. defer hdb.apiConnCon.Release()
  25. return hdb.GetLastBlock()
  26. }
  27. // GetBatchAPI return the batch with the given batchNum
  28. func (hdb *HistoryDB) GetBatchAPI(batchNum common.BatchNum) (*BatchAPI, error) {
  29. cancel, err := hdb.apiConnCon.Acquire()
  30. defer cancel()
  31. if err != nil {
  32. return nil, tracerr.Wrap(err)
  33. }
  34. defer hdb.apiConnCon.Release()
  35. return hdb.getBatchAPI(hdb.dbRead, batchNum)
  36. }
  37. // GetBatchInternalAPI return the batch with the given batchNum
  38. func (hdb *HistoryDB) GetBatchInternalAPI(batchNum common.BatchNum) (*BatchAPI, error) {
  39. return hdb.getBatchAPI(hdb.dbRead, batchNum)
  40. }
  41. func (hdb *HistoryDB) getBatchAPI(d meddler.DB, batchNum common.BatchNum) (*BatchAPI, error) {
  42. batch := &BatchAPI{}
  43. if err := meddler.QueryRow(
  44. d, batch,
  45. `SELECT batch.item_id, batch.batch_num, batch.eth_block_num,
  46. batch.forger_addr, batch.fees_collected, batch.total_fees_usd, batch.state_root,
  47. batch.num_accounts, batch.exit_root, batch.forge_l1_txs_num, batch.slot_num,
  48. block.timestamp, block.hash,
  49. COALESCE ((SELECT COUNT(*) FROM tx WHERE batch_num = batch.batch_num), 0) AS forged_txs
  50. FROM batch INNER JOIN block ON batch.eth_block_num = block.eth_block_num
  51. WHERE batch_num = $1;`, batchNum,
  52. ); err != nil {
  53. return nil, tracerr.Wrap(err)
  54. }
  55. batch.CollectedFeesAPI = apitypes.NewCollectedFeesAPI(batch.CollectedFeesDB)
  56. return batch, nil
  57. }
  58. // GetBatchesAPI return the batches applying the given filters
  59. func (hdb *HistoryDB) GetBatchesAPI(
  60. minBatchNum, maxBatchNum, slotNum *uint,
  61. forgerAddr *ethCommon.Address,
  62. fromItem, limit *uint, order string,
  63. ) ([]BatchAPI, uint64, error) {
  64. cancel, err := hdb.apiConnCon.Acquire()
  65. defer cancel()
  66. if err != nil {
  67. return nil, 0, tracerr.Wrap(err)
  68. }
  69. defer hdb.apiConnCon.Release()
  70. var query string
  71. var args []interface{}
  72. queryStr := `SELECT batch.item_id, batch.batch_num, batch.eth_block_num,
  73. batch.forger_addr, batch.fees_collected, batch.total_fees_usd, batch.state_root,
  74. batch.num_accounts, batch.exit_root, batch.forge_l1_txs_num, batch.slot_num,
  75. block.timestamp, block.hash,
  76. COALESCE ((SELECT COUNT(*) FROM tx WHERE batch_num = batch.batch_num), 0) AS forged_txs,
  77. count(*) OVER() AS total_items
  78. FROM batch INNER JOIN block ON batch.eth_block_num = block.eth_block_num `
  79. // Apply filters
  80. nextIsAnd := false
  81. // minBatchNum filter
  82. if minBatchNum != nil {
  83. if nextIsAnd {
  84. queryStr += "AND "
  85. } else {
  86. queryStr += "WHERE "
  87. }
  88. queryStr += "batch.batch_num > ? "
  89. args = append(args, minBatchNum)
  90. nextIsAnd = true
  91. }
  92. // maxBatchNum filter
  93. if maxBatchNum != nil {
  94. if nextIsAnd {
  95. queryStr += "AND "
  96. } else {
  97. queryStr += "WHERE "
  98. }
  99. queryStr += "batch.batch_num < ? "
  100. args = append(args, maxBatchNum)
  101. nextIsAnd = true
  102. }
  103. // slotNum filter
  104. if slotNum != nil {
  105. if nextIsAnd {
  106. queryStr += "AND "
  107. } else {
  108. queryStr += "WHERE "
  109. }
  110. queryStr += "batch.slot_num = ? "
  111. args = append(args, slotNum)
  112. nextIsAnd = true
  113. }
  114. // forgerAddr filter
  115. if forgerAddr != nil {
  116. if nextIsAnd {
  117. queryStr += "AND "
  118. } else {
  119. queryStr += "WHERE "
  120. }
  121. queryStr += "batch.forger_addr = ? "
  122. args = append(args, forgerAddr)
  123. nextIsAnd = true
  124. }
  125. // pagination
  126. if fromItem != nil {
  127. if nextIsAnd {
  128. queryStr += "AND "
  129. } else {
  130. queryStr += "WHERE "
  131. }
  132. if order == OrderAsc {
  133. queryStr += "batch.item_id >= ? "
  134. } else {
  135. queryStr += "batch.item_id <= ? "
  136. }
  137. args = append(args, fromItem)
  138. }
  139. queryStr += "ORDER BY batch.item_id "
  140. if order == OrderAsc {
  141. queryStr += " ASC "
  142. } else {
  143. queryStr += " DESC "
  144. }
  145. queryStr += fmt.Sprintf("LIMIT %d;", *limit)
  146. query = hdb.dbRead.Rebind(queryStr)
  147. // log.Debug(query)
  148. batchPtrs := []*BatchAPI{}
  149. if err := meddler.QueryAll(hdb.dbRead, &batchPtrs, query, args...); err != nil {
  150. return nil, 0, tracerr.Wrap(err)
  151. }
  152. batches := db.SlicePtrsToSlice(batchPtrs).([]BatchAPI)
  153. if len(batches) == 0 {
  154. return batches, 0, nil
  155. }
  156. for i := range batches {
  157. batches[i].CollectedFeesAPI = apitypes.NewCollectedFeesAPI(batches[i].CollectedFeesDB)
  158. }
  159. return batches, batches[0].TotalItems - uint64(len(batches)), nil
  160. }
  161. // GetBestBidAPI returns the best bid in specific slot by slotNum
  162. func (hdb *HistoryDB) GetBestBidAPI(slotNum *int64) (BidAPI, error) {
  163. bid := &BidAPI{}
  164. cancel, err := hdb.apiConnCon.Acquire()
  165. defer cancel()
  166. if err != nil {
  167. return *bid, tracerr.Wrap(err)
  168. }
  169. defer hdb.apiConnCon.Release()
  170. err = meddler.QueryRow(
  171. hdb.dbRead, bid, `SELECT bid.*, block.timestamp, coordinator.forger_addr, coordinator.url
  172. FROM bid INNER JOIN block ON bid.eth_block_num = block.eth_block_num
  173. INNER JOIN (
  174. SELECT bidder_addr, MAX(item_id) AS item_id FROM coordinator
  175. GROUP BY bidder_addr
  176. ) c ON bid.bidder_addr = c.bidder_addr
  177. INNER JOIN coordinator ON c.item_id = coordinator.item_id
  178. WHERE slot_num = $1 ORDER BY item_id DESC LIMIT 1;`, slotNum,
  179. )
  180. return *bid, tracerr.Wrap(err)
  181. }
  182. // GetBestBidsAPI returns the best bid in specific slot by slotNum
  183. func (hdb *HistoryDB) GetBestBidsAPI(
  184. minSlotNum, maxSlotNum *int64,
  185. bidderAddr *ethCommon.Address,
  186. limit *uint, order string,
  187. ) ([]BidAPI, uint64, error) {
  188. cancel, err := hdb.apiConnCon.Acquire()
  189. defer cancel()
  190. if err != nil {
  191. return nil, 0, tracerr.Wrap(err)
  192. }
  193. defer hdb.apiConnCon.Release()
  194. return hdb.getBestBidsAPI(hdb.dbRead, minSlotNum, maxSlotNum, bidderAddr, limit, order)
  195. }
  196. func (hdb *HistoryDB) getBestBidsAPI(
  197. d meddler.DB,
  198. minSlotNum, maxSlotNum *int64,
  199. bidderAddr *ethCommon.Address,
  200. limit *uint, order string,
  201. ) ([]BidAPI, uint64, error) {
  202. var query string
  203. var args []interface{}
  204. // JOIN the best bid of each slot with the latest update of each coordinator
  205. queryStr := `SELECT b.*, block.timestamp, coordinator.forger_addr, coordinator.url,
  206. COUNT(*) OVER() AS total_items FROM (
  207. SELECT slot_num, MAX(item_id) as maxitem
  208. FROM bid GROUP BY slot_num
  209. )
  210. AS x INNER JOIN bid AS b ON b.item_id = x.maxitem
  211. INNER JOIN block ON b.eth_block_num = block.eth_block_num
  212. INNER JOIN (
  213. SELECT bidder_addr, MAX(item_id) AS item_id FROM coordinator
  214. GROUP BY bidder_addr
  215. ) c ON b.bidder_addr = c.bidder_addr
  216. INNER JOIN coordinator ON c.item_id = coordinator.item_id
  217. WHERE (b.slot_num >= ? AND b.slot_num <= ?)`
  218. args = append(args, minSlotNum)
  219. args = append(args, maxSlotNum)
  220. // Apply filters
  221. if bidderAddr != nil {
  222. queryStr += " AND b.bidder_addr = ? "
  223. args = append(args, bidderAddr)
  224. }
  225. queryStr += " ORDER BY b.slot_num "
  226. if order == OrderAsc {
  227. queryStr += "ASC "
  228. } else {
  229. queryStr += "DESC "
  230. }
  231. if limit != nil {
  232. queryStr += fmt.Sprintf("LIMIT %d;", *limit)
  233. }
  234. query = hdb.dbRead.Rebind(queryStr)
  235. bidPtrs := []*BidAPI{}
  236. if err := meddler.QueryAll(d, &bidPtrs, query, args...); err != nil {
  237. return nil, 0, tracerr.Wrap(err)
  238. }
  239. // log.Debug(query)
  240. bids := db.SlicePtrsToSlice(bidPtrs).([]BidAPI)
  241. if len(bids) == 0 {
  242. return bids, 0, nil
  243. }
  244. return bids, bids[0].TotalItems - uint64(len(bids)), nil
  245. }
  246. // GetBidsAPI return the bids applying the given filters
  247. func (hdb *HistoryDB) GetBidsAPI(
  248. slotNum *int64, bidderAddr *ethCommon.Address,
  249. fromItem, limit *uint, order string,
  250. ) ([]BidAPI, uint64, error) {
  251. cancel, err := hdb.apiConnCon.Acquire()
  252. defer cancel()
  253. if err != nil {
  254. return nil, 0, tracerr.Wrap(err)
  255. }
  256. defer hdb.apiConnCon.Release()
  257. var query string
  258. var args []interface{}
  259. // JOIN each bid with the latest update of each coordinator
  260. queryStr := `SELECT bid.*, block.timestamp, coord.forger_addr, coord.url,
  261. COUNT(*) OVER() AS total_items
  262. FROM bid INNER JOIN block ON bid.eth_block_num = block.eth_block_num
  263. INNER JOIN (
  264. SELECT bidder_addr, MAX(item_id) AS item_id FROM coordinator
  265. GROUP BY bidder_addr
  266. ) c ON bid.bidder_addr = c.bidder_addr
  267. INNER JOIN coordinator coord ON c.item_id = coord.item_id `
  268. // Apply filters
  269. nextIsAnd := false
  270. // slotNum filter
  271. if slotNum != nil {
  272. if nextIsAnd {
  273. queryStr += "AND "
  274. } else {
  275. queryStr += "WHERE "
  276. }
  277. queryStr += "bid.slot_num = ? "
  278. args = append(args, slotNum)
  279. nextIsAnd = true
  280. }
  281. // bidder filter
  282. if bidderAddr != nil {
  283. if nextIsAnd {
  284. queryStr += "AND "
  285. } else {
  286. queryStr += "WHERE "
  287. }
  288. queryStr += "bid.bidder_addr = ? "
  289. args = append(args, bidderAddr)
  290. nextIsAnd = true
  291. }
  292. if fromItem != nil {
  293. if nextIsAnd {
  294. queryStr += "AND "
  295. } else {
  296. queryStr += "WHERE "
  297. }
  298. if order == OrderAsc {
  299. queryStr += "bid.item_id >= ? "
  300. } else {
  301. queryStr += "bid.item_id <= ? "
  302. }
  303. args = append(args, fromItem)
  304. }
  305. // pagination
  306. queryStr += "ORDER BY bid.item_id "
  307. if order == OrderAsc {
  308. queryStr += "ASC "
  309. } else {
  310. queryStr += "DESC "
  311. }
  312. queryStr += fmt.Sprintf("LIMIT %d;", *limit)
  313. query, argsQ, err := sqlx.In(queryStr, args...)
  314. if err != nil {
  315. return nil, 0, tracerr.Wrap(err)
  316. }
  317. query = hdb.dbRead.Rebind(query)
  318. bids := []*BidAPI{}
  319. if err := meddler.QueryAll(hdb.dbRead, &bids, query, argsQ...); err != nil {
  320. return nil, 0, tracerr.Wrap(err)
  321. }
  322. if len(bids) == 0 {
  323. return []BidAPI{}, 0, nil
  324. }
  325. return db.SlicePtrsToSlice(bids).([]BidAPI), bids[0].TotalItems - uint64(len(bids)), nil
  326. }
  327. // GetTokenAPI returns a token from the DB given a TokenID
  328. func (hdb *HistoryDB) GetTokenAPI(tokenID common.TokenID) (*TokenWithUSD, error) {
  329. cancel, err := hdb.apiConnCon.Acquire()
  330. defer cancel()
  331. if err != nil {
  332. return nil, tracerr.Wrap(err)
  333. }
  334. defer hdb.apiConnCon.Release()
  335. return hdb.GetToken(tokenID)
  336. }
  337. // GetTokensAPI returns a list of tokens from the DB
  338. func (hdb *HistoryDB) GetTokensAPI(
  339. ids []common.TokenID, symbols []string, name string, fromItem,
  340. limit *uint, order string,
  341. ) ([]TokenWithUSD, uint64, error) {
  342. cancel, err := hdb.apiConnCon.Acquire()
  343. defer cancel()
  344. if err != nil {
  345. return nil, 0, tracerr.Wrap(err)
  346. }
  347. defer hdb.apiConnCon.Release()
  348. var query string
  349. var args []interface{}
  350. queryStr := `SELECT * , COUNT(*) OVER() AS total_items FROM token `
  351. // Apply filters
  352. nextIsAnd := false
  353. if len(ids) > 0 {
  354. queryStr += "WHERE token_id IN (?) "
  355. nextIsAnd = true
  356. args = append(args, ids)
  357. }
  358. if len(symbols) > 0 {
  359. if nextIsAnd {
  360. queryStr += "AND "
  361. } else {
  362. queryStr += "WHERE "
  363. }
  364. queryStr += "symbol IN (?) "
  365. args = append(args, symbols)
  366. nextIsAnd = true
  367. }
  368. if name != "" {
  369. if nextIsAnd {
  370. queryStr += "AND "
  371. } else {
  372. queryStr += "WHERE "
  373. }
  374. queryStr += "name ~ ? "
  375. args = append(args, name)
  376. nextIsAnd = true
  377. }
  378. if fromItem != nil {
  379. if nextIsAnd {
  380. queryStr += "AND "
  381. } else {
  382. queryStr += "WHERE "
  383. }
  384. if order == OrderAsc {
  385. queryStr += "item_id >= ? "
  386. } else {
  387. queryStr += "item_id <= ? "
  388. }
  389. args = append(args, fromItem)
  390. }
  391. // pagination
  392. queryStr += "ORDER BY item_id "
  393. if order == OrderAsc {
  394. queryStr += "ASC "
  395. } else {
  396. queryStr += "DESC "
  397. }
  398. queryStr += fmt.Sprintf("LIMIT %d;", *limit)
  399. query, argsQ, err := sqlx.In(queryStr, args...)
  400. if err != nil {
  401. return nil, 0, tracerr.Wrap(err)
  402. }
  403. query = hdb.dbRead.Rebind(query)
  404. tokens := []*TokenWithUSD{}
  405. if err := meddler.QueryAll(hdb.dbRead, &tokens, query, argsQ...); err != nil {
  406. return nil, 0, tracerr.Wrap(err)
  407. }
  408. if len(tokens) == 0 {
  409. return []TokenWithUSD{}, 0, nil
  410. }
  411. return db.SlicePtrsToSlice(tokens).([]TokenWithUSD), uint64(len(tokens)) - tokens[0].TotalItems, nil
  412. }
  413. // GetTxAPI returns a tx from the DB given a TxID
  414. func (hdb *HistoryDB) GetTxAPI(txID common.TxID) (*TxAPI, error) {
  415. // Warning: amount_success and deposit_amount_success have true as default for
  416. // performance reasons. The expected default value is false (when txs are unforged)
  417. // this case is handled at the function func (tx TxAPI) MarshalJSON() ([]byte, error)
  418. cancel, err := hdb.apiConnCon.Acquire()
  419. defer cancel()
  420. if err != nil {
  421. return nil, tracerr.Wrap(err)
  422. }
  423. defer hdb.apiConnCon.Release()
  424. tx := &TxAPI{}
  425. err = meddler.QueryRow(
  426. hdb.dbRead, tx, `SELECT tx.item_id, tx.is_l1, tx.id, tx.type, tx.position,
  427. hez_idx(tx.effective_from_idx, token.symbol) AS from_idx, tx.from_eth_addr, tx.from_bjj,
  428. hez_idx(tx.to_idx, token.symbol) AS to_idx, tx.to_eth_addr, tx.to_bjj,
  429. tx.amount, tx.amount_success, tx.token_id, tx.amount_usd,
  430. tx.batch_num, tx.eth_block_num, tx.to_forge_l1_txs_num, tx.user_origin,
  431. tx.deposit_amount, tx.deposit_amount_usd, tx.deposit_amount_success, tx.fee, tx.fee_usd, tx.nonce,
  432. token.token_id, token.item_id AS token_item_id, token.eth_block_num AS token_block,
  433. token.eth_addr, token.name, token.symbol, token.decimals, token.usd,
  434. token.usd_update, block.timestamp
  435. FROM tx INNER JOIN token ON tx.token_id = token.token_id
  436. INNER JOIN block ON tx.eth_block_num = block.eth_block_num
  437. WHERE tx.id = $1;`, txID,
  438. )
  439. return tx, tracerr.Wrap(err)
  440. }
  441. // GetTxsAPI returns a list of txs from the DB using the HistoryTx struct
  442. // and pagination info
  443. func (hdb *HistoryDB) GetTxsAPI(
  444. ethAddr *ethCommon.Address, bjj *babyjub.PublicKeyComp,
  445. tokenID *common.TokenID, idx *common.Idx, batchNum *uint, txType *common.TxType,
  446. fromItem, limit *uint, order string,
  447. ) ([]TxAPI, uint64, error) {
  448. // Warning: amount_success and deposit_amount_success have true as default for
  449. // performance reasons. The expected default value is false (when txs are unforged)
  450. // this case is handled at the function func (tx TxAPI) MarshalJSON() ([]byte, error)
  451. cancel, err := hdb.apiConnCon.Acquire()
  452. defer cancel()
  453. if err != nil {
  454. return nil, 0, tracerr.Wrap(err)
  455. }
  456. defer hdb.apiConnCon.Release()
  457. if ethAddr != nil && bjj != nil {
  458. return nil, 0, tracerr.Wrap(errors.New("ethAddr and bjj are incompatible"))
  459. }
  460. var query string
  461. var args []interface{}
  462. queryStr := `SELECT tx.item_id, tx.is_l1, tx.id, tx.type, tx.position,
  463. hez_idx(tx.effective_from_idx, token.symbol) AS from_idx, tx.from_eth_addr, tx.from_bjj,
  464. hez_idx(tx.to_idx, token.symbol) AS to_idx, tx.to_eth_addr, tx.to_bjj,
  465. tx.amount, tx.amount_success, tx.token_id, tx.amount_usd,
  466. tx.batch_num, tx.eth_block_num, tx.to_forge_l1_txs_num, tx.user_origin,
  467. tx.deposit_amount, tx.deposit_amount_usd, tx.deposit_amount_success, tx.fee, tx.fee_usd, tx.nonce,
  468. token.token_id, token.item_id AS token_item_id, token.eth_block_num AS token_block,
  469. token.eth_addr, token.name, token.symbol, token.decimals, token.usd,
  470. token.usd_update, block.timestamp, count(*) OVER() AS total_items
  471. FROM tx INNER JOIN token ON tx.token_id = token.token_id
  472. INNER JOIN block ON tx.eth_block_num = block.eth_block_num `
  473. // Apply filters
  474. nextIsAnd := false
  475. // ethAddr filter
  476. if ethAddr != nil {
  477. queryStr += "WHERE (tx.from_eth_addr = ? OR tx.to_eth_addr = ?) "
  478. nextIsAnd = true
  479. args = append(args, ethAddr, ethAddr)
  480. } else if bjj != nil { // bjj filter
  481. queryStr += "WHERE (tx.from_bjj = ? OR tx.to_bjj = ?) "
  482. nextIsAnd = true
  483. args = append(args, bjj, bjj)
  484. }
  485. // tokenID filter
  486. if tokenID != nil {
  487. if nextIsAnd {
  488. queryStr += "AND "
  489. } else {
  490. queryStr += "WHERE "
  491. }
  492. queryStr += "tx.token_id = ? "
  493. args = append(args, tokenID)
  494. nextIsAnd = true
  495. }
  496. // idx filter
  497. if idx != nil {
  498. if nextIsAnd {
  499. queryStr += "AND "
  500. } else {
  501. queryStr += "WHERE "
  502. }
  503. queryStr += "(tx.effective_from_idx = ? OR tx.to_idx = ?) "
  504. args = append(args, idx, idx)
  505. nextIsAnd = true
  506. }
  507. // batchNum filter
  508. if batchNum != nil {
  509. if nextIsAnd {
  510. queryStr += "AND "
  511. } else {
  512. queryStr += "WHERE "
  513. }
  514. queryStr += "tx.batch_num = ? "
  515. args = append(args, batchNum)
  516. nextIsAnd = true
  517. }
  518. // txType filter
  519. if txType != nil {
  520. if nextIsAnd {
  521. queryStr += "AND "
  522. } else {
  523. queryStr += "WHERE "
  524. }
  525. queryStr += "tx.type = ? "
  526. args = append(args, txType)
  527. nextIsAnd = true
  528. }
  529. if fromItem != nil {
  530. if nextIsAnd {
  531. queryStr += "AND "
  532. } else {
  533. queryStr += "WHERE "
  534. }
  535. if order == OrderAsc {
  536. queryStr += "tx.item_id >= ? "
  537. } else {
  538. queryStr += "tx.item_id <= ? "
  539. }
  540. args = append(args, fromItem)
  541. nextIsAnd = true
  542. }
  543. if nextIsAnd {
  544. queryStr += "AND "
  545. } else {
  546. queryStr += "WHERE "
  547. }
  548. queryStr += "tx.batch_num IS NOT NULL "
  549. // pagination
  550. queryStr += "ORDER BY tx.item_id "
  551. if order == OrderAsc {
  552. queryStr += " ASC "
  553. } else {
  554. queryStr += " DESC "
  555. }
  556. queryStr += fmt.Sprintf("LIMIT %d;", *limit)
  557. query = hdb.dbRead.Rebind(queryStr)
  558. // log.Debug(query)
  559. txsPtrs := []*TxAPI{}
  560. if err := meddler.QueryAll(hdb.dbRead, &txsPtrs, query, args...); err != nil {
  561. return nil, 0, tracerr.Wrap(err)
  562. }
  563. txs := db.SlicePtrsToSlice(txsPtrs).([]TxAPI)
  564. if len(txs) == 0 {
  565. return txs, 0, nil
  566. }
  567. return txs, txs[0].TotalItems - uint64(len(txs)), nil
  568. }
  569. // GetExitAPI returns a exit from the DB
  570. func (hdb *HistoryDB) GetExitAPI(batchNum *uint, idx *common.Idx) (*ExitAPI, error) {
  571. cancel, err := hdb.apiConnCon.Acquire()
  572. defer cancel()
  573. if err != nil {
  574. return nil, tracerr.Wrap(err)
  575. }
  576. defer hdb.apiConnCon.Release()
  577. exit := &ExitAPI{}
  578. err = meddler.QueryRow(
  579. hdb.dbRead, exit, `SELECT exit_tree.item_id, exit_tree.batch_num,
  580. hez_idx(exit_tree.account_idx, token.symbol) AS account_idx,
  581. account.bjj, account.eth_addr,
  582. exit_tree.merkle_proof, exit_tree.balance, exit_tree.instant_withdrawn,
  583. exit_tree.delayed_withdraw_request, exit_tree.delayed_withdrawn,
  584. token.token_id, token.item_id AS token_item_id,
  585. token.eth_block_num AS token_block, token.eth_addr AS token_eth_addr, token.name, token.symbol,
  586. token.decimals, token.usd, token.usd_update
  587. FROM exit_tree INNER JOIN account ON exit_tree.account_idx = account.idx
  588. INNER JOIN token ON account.token_id = token.token_id
  589. WHERE exit_tree.batch_num = $1 AND exit_tree.account_idx = $2;`, batchNum, idx,
  590. )
  591. return exit, tracerr.Wrap(err)
  592. }
  593. // GetExitsAPI returns a list of exits from the DB and pagination info
  594. func (hdb *HistoryDB) GetExitsAPI(
  595. ethAddr *ethCommon.Address, bjj *babyjub.PublicKeyComp, tokenID *common.TokenID,
  596. idx *common.Idx, batchNum *uint, onlyPendingWithdraws *bool,
  597. fromItem, limit *uint, order string,
  598. ) ([]ExitAPI, uint64, error) {
  599. if ethAddr != nil && bjj != nil {
  600. return nil, 0, tracerr.Wrap(errors.New("ethAddr and bjj are incompatible"))
  601. }
  602. cancel, err := hdb.apiConnCon.Acquire()
  603. defer cancel()
  604. if err != nil {
  605. return nil, 0, tracerr.Wrap(err)
  606. }
  607. defer hdb.apiConnCon.Release()
  608. var query string
  609. var args []interface{}
  610. queryStr := `SELECT exit_tree.item_id, exit_tree.batch_num,
  611. hez_idx(exit_tree.account_idx, token.symbol) AS account_idx,
  612. account.bjj, account.eth_addr,
  613. exit_tree.merkle_proof, exit_tree.balance, exit_tree.instant_withdrawn,
  614. exit_tree.delayed_withdraw_request, exit_tree.delayed_withdrawn,
  615. token.token_id, token.item_id AS token_item_id,
  616. token.eth_block_num AS token_block, token.eth_addr AS token_eth_addr, token.name, token.symbol,
  617. token.decimals, token.usd, token.usd_update, COUNT(*) OVER() AS total_items
  618. FROM exit_tree INNER JOIN account ON exit_tree.account_idx = account.idx
  619. INNER JOIN token ON account.token_id = token.token_id `
  620. // Apply filters
  621. nextIsAnd := false
  622. // ethAddr filter
  623. if ethAddr != nil {
  624. queryStr += "WHERE account.eth_addr = ? "
  625. nextIsAnd = true
  626. args = append(args, ethAddr)
  627. } else if bjj != nil { // bjj filter
  628. queryStr += "WHERE account.bjj = ? "
  629. nextIsAnd = true
  630. args = append(args, bjj)
  631. }
  632. // tokenID filter
  633. if tokenID != nil {
  634. if nextIsAnd {
  635. queryStr += "AND "
  636. } else {
  637. queryStr += "WHERE "
  638. }
  639. queryStr += "account.token_id = ? "
  640. args = append(args, tokenID)
  641. nextIsAnd = true
  642. }
  643. // idx filter
  644. if idx != nil {
  645. if nextIsAnd {
  646. queryStr += "AND "
  647. } else {
  648. queryStr += "WHERE "
  649. }
  650. queryStr += "exit_tree.account_idx = ? "
  651. args = append(args, idx)
  652. nextIsAnd = true
  653. }
  654. // batchNum filter
  655. if batchNum != nil {
  656. if nextIsAnd {
  657. queryStr += "AND "
  658. } else {
  659. queryStr += "WHERE "
  660. }
  661. queryStr += "exit_tree.batch_num = ? "
  662. args = append(args, batchNum)
  663. nextIsAnd = true
  664. }
  665. // onlyPendingWithdraws
  666. if onlyPendingWithdraws != nil {
  667. if *onlyPendingWithdraws {
  668. if nextIsAnd {
  669. queryStr += "AND "
  670. } else {
  671. queryStr += "WHERE "
  672. }
  673. queryStr += "(exit_tree.instant_withdrawn IS NULL AND exit_tree.delayed_withdrawn IS NULL) "
  674. nextIsAnd = true
  675. }
  676. }
  677. if fromItem != nil {
  678. if nextIsAnd {
  679. queryStr += "AND "
  680. } else {
  681. queryStr += "WHERE "
  682. }
  683. if order == OrderAsc {
  684. queryStr += "exit_tree.item_id >= ? "
  685. } else {
  686. queryStr += "exit_tree.item_id <= ? "
  687. }
  688. args = append(args, fromItem)
  689. // nextIsAnd = true
  690. }
  691. // pagination
  692. queryStr += "ORDER BY exit_tree.item_id "
  693. if order == OrderAsc {
  694. queryStr += " ASC "
  695. } else {
  696. queryStr += " DESC "
  697. }
  698. queryStr += fmt.Sprintf("LIMIT %d;", *limit)
  699. query = hdb.dbRead.Rebind(queryStr)
  700. // log.Debug(query)
  701. exits := []*ExitAPI{}
  702. if err := meddler.QueryAll(hdb.dbRead, &exits, query, args...); err != nil {
  703. return nil, 0, tracerr.Wrap(err)
  704. }
  705. if len(exits) == 0 {
  706. return []ExitAPI{}, 0, nil
  707. }
  708. return db.SlicePtrsToSlice(exits).([]ExitAPI), exits[0].TotalItems - uint64(len(exits)), nil
  709. }
  710. // GetCoordinatorsAPI returns a list of coordinators from the DB and pagination info
  711. func (hdb *HistoryDB) GetCoordinatorsAPI(
  712. bidderAddr, forgerAddr *ethCommon.Address,
  713. fromItem, limit *uint, order string,
  714. ) ([]CoordinatorAPI, uint64, error) {
  715. cancel, err := hdb.apiConnCon.Acquire()
  716. defer cancel()
  717. if err != nil {
  718. return nil, 0, tracerr.Wrap(err)
  719. }
  720. defer hdb.apiConnCon.Release()
  721. var query string
  722. var args []interface{}
  723. queryStr := `SELECT coordinator.*, COUNT(*) OVER() AS total_items
  724. FROM coordinator INNER JOIN (
  725. SELECT MAX(item_id) AS item_id FROM coordinator
  726. GROUP BY bidder_addr
  727. ) c ON coordinator.item_id = c.item_id `
  728. // Apply filters
  729. nextIsAnd := false
  730. if bidderAddr != nil {
  731. queryStr += "WHERE bidder_addr = ? "
  732. nextIsAnd = true
  733. args = append(args, bidderAddr)
  734. }
  735. if forgerAddr != nil {
  736. if nextIsAnd {
  737. queryStr += "AND "
  738. } else {
  739. queryStr += "WHERE "
  740. }
  741. queryStr += "forger_addr = ? "
  742. nextIsAnd = true
  743. args = append(args, forgerAddr)
  744. }
  745. if fromItem != nil {
  746. if nextIsAnd {
  747. queryStr += "AND "
  748. } else {
  749. queryStr += "WHERE "
  750. }
  751. if order == OrderAsc {
  752. queryStr += "coordinator.item_id >= ? "
  753. } else {
  754. queryStr += "coordinator.item_id <= ? "
  755. }
  756. args = append(args, fromItem)
  757. }
  758. // pagination
  759. queryStr += "ORDER BY coordinator.item_id "
  760. if order == OrderAsc {
  761. queryStr += " ASC "
  762. } else {
  763. queryStr += " DESC "
  764. }
  765. queryStr += fmt.Sprintf("LIMIT %d;", *limit)
  766. query = hdb.dbRead.Rebind(queryStr)
  767. coordinators := []*CoordinatorAPI{}
  768. if err := meddler.QueryAll(hdb.dbRead, &coordinators, query, args...); err != nil {
  769. return nil, 0, tracerr.Wrap(err)
  770. }
  771. if len(coordinators) == 0 {
  772. return []CoordinatorAPI{}, 0, nil
  773. }
  774. return db.SlicePtrsToSlice(coordinators).([]CoordinatorAPI),
  775. coordinators[0].TotalItems - uint64(len(coordinators)), nil
  776. }
  777. // GetAuctionVarsAPI returns auction variables
  778. func (hdb *HistoryDB) GetAuctionVarsAPI() (*common.AuctionVariables, error) {
  779. cancel, err := hdb.apiConnCon.Acquire()
  780. defer cancel()
  781. if err != nil {
  782. return nil, tracerr.Wrap(err)
  783. }
  784. defer hdb.apiConnCon.Release()
  785. auctionVars := &common.AuctionVariables{}
  786. err = meddler.QueryRow(
  787. hdb.dbRead, auctionVars, `SELECT * FROM auction_vars;`,
  788. )
  789. return auctionVars, tracerr.Wrap(err)
  790. }
  791. // GetAccountAPI returns an account by its index
  792. func (hdb *HistoryDB) GetAccountAPI(idx common.Idx) (*AccountAPI, error) {
  793. cancel, err := hdb.apiConnCon.Acquire()
  794. defer cancel()
  795. if err != nil {
  796. return nil, tracerr.Wrap(err)
  797. }
  798. defer hdb.apiConnCon.Release()
  799. account := &AccountAPI{}
  800. err = meddler.QueryRow(hdb.dbRead, account, `SELECT account.item_id, hez_idx(account.idx,
  801. token.symbol) as idx, account.batch_num, account.bjj, account.eth_addr,
  802. token.token_id, token.item_id AS token_item_id, token.eth_block_num AS token_block,
  803. token.eth_addr as token_eth_addr, token.name, token.symbol, token.decimals, token.usd,
  804. token.usd_update, account_update.nonce, account_update.balance
  805. FROM account inner JOIN (
  806. SELECT idx, nonce, balance
  807. FROM account_update
  808. WHERE idx = $1
  809. ORDER BY item_id DESC LIMIT 1
  810. ) AS account_update ON account_update.idx = account.idx
  811. INNER JOIN token ON account.token_id = token.token_id
  812. WHERE account.idx = $1;`, idx)
  813. if err != nil {
  814. return nil, tracerr.Wrap(err)
  815. }
  816. return account, nil
  817. }
  818. // GetAccountsAPI returns a list of accounts from the DB and pagination info
  819. func (hdb *HistoryDB) GetAccountsAPI(
  820. tokenIDs []common.TokenID, ethAddr *ethCommon.Address,
  821. bjj *babyjub.PublicKeyComp, fromItem, limit *uint, order string,
  822. ) ([]AccountAPI, uint64, error) {
  823. if ethAddr != nil && bjj != nil {
  824. return nil, 0, tracerr.Wrap(errors.New("ethAddr and bjj are incompatible"))
  825. }
  826. cancel, err := hdb.apiConnCon.Acquire()
  827. defer cancel()
  828. if err != nil {
  829. return nil, 0, tracerr.Wrap(err)
  830. }
  831. defer hdb.apiConnCon.Release()
  832. var query string
  833. var args []interface{}
  834. queryStr := `SELECT account.item_id, hez_idx(account.idx, token.symbol) as idx, account.batch_num,
  835. account.bjj, account.eth_addr, token.token_id, token.item_id AS token_item_id, token.eth_block_num AS token_block,
  836. token.eth_addr as token_eth_addr, token.name, token.symbol, token.decimals, token.usd, token.usd_update,
  837. account_update.nonce, account_update.balance, COUNT(*) OVER() AS total_items
  838. FROM account inner JOIN (
  839. SELECT DISTINCT idx,
  840. first_value(nonce) over(partition by idx ORDER BY item_id DESC) as nonce,
  841. first_value(balance) over(partition by idx ORDER BY item_id DESC) as balance
  842. FROM account_update
  843. ) AS account_update ON account_update.idx = account.idx INNER JOIN token ON account.token_id = token.token_id `
  844. // Apply filters
  845. nextIsAnd := false
  846. // ethAddr filter
  847. if ethAddr != nil {
  848. queryStr += "WHERE account.eth_addr = ? "
  849. nextIsAnd = true
  850. args = append(args, ethAddr)
  851. } else if bjj != nil { // bjj filter
  852. queryStr += "WHERE account.bjj = ? "
  853. nextIsAnd = true
  854. args = append(args, bjj)
  855. }
  856. // tokenID filter
  857. if len(tokenIDs) > 0 {
  858. if nextIsAnd {
  859. queryStr += "AND "
  860. } else {
  861. queryStr += "WHERE "
  862. }
  863. queryStr += "account.token_id IN (?) "
  864. args = append(args, tokenIDs)
  865. nextIsAnd = true
  866. }
  867. if fromItem != nil {
  868. if nextIsAnd {
  869. queryStr += "AND "
  870. } else {
  871. queryStr += "WHERE "
  872. }
  873. if order == OrderAsc {
  874. queryStr += "account.item_id >= ? "
  875. } else {
  876. queryStr += "account.item_id <= ? "
  877. }
  878. args = append(args, fromItem)
  879. }
  880. // pagination
  881. queryStr += "ORDER BY account.item_id "
  882. if order == OrderAsc {
  883. queryStr += " ASC "
  884. } else {
  885. queryStr += " DESC "
  886. }
  887. queryStr += fmt.Sprintf("LIMIT %d;", *limit)
  888. query, argsQ, err := sqlx.In(queryStr, args...)
  889. if err != nil {
  890. return nil, 0, tracerr.Wrap(err)
  891. }
  892. query = hdb.dbRead.Rebind(query)
  893. accounts := []*AccountAPI{}
  894. if err := meddler.QueryAll(hdb.dbRead, &accounts, query, argsQ...); err != nil {
  895. return nil, 0, tracerr.Wrap(err)
  896. }
  897. if len(accounts) == 0 {
  898. return []AccountAPI{}, 0, nil
  899. }
  900. return db.SlicePtrsToSlice(accounts).([]AccountAPI),
  901. accounts[0].TotalItems - uint64(len(accounts)), nil
  902. }
  903. // GetCommonAccountAPI returns the account associated to an account idx
  904. func (hdb *HistoryDB) GetCommonAccountAPI(idx common.Idx) (*common.Account, error) {
  905. cancel, err := hdb.apiConnCon.Acquire()
  906. defer cancel()
  907. if err != nil {
  908. return nil, tracerr.Wrap(err)
  909. }
  910. defer hdb.apiConnCon.Release()
  911. account := &common.Account{}
  912. err = meddler.QueryRow(
  913. hdb.dbRead, account, `SELECT idx, token_id, batch_num, bjj, eth_addr
  914. FROM account WHERE idx = $1;`, idx,
  915. )
  916. return account, tracerr.Wrap(err)
  917. }
  918. // GetCoordinatorAPI returns a coordinator by its bidderAddr
  919. func (hdb *HistoryDB) GetCoordinatorAPI(bidderAddr ethCommon.Address) (*CoordinatorAPI, error) {
  920. cancel, err := hdb.apiConnCon.Acquire()
  921. defer cancel()
  922. if err != nil {
  923. return nil, tracerr.Wrap(err)
  924. }
  925. defer hdb.apiConnCon.Release()
  926. return hdb.getCoordinatorAPI(hdb.dbRead, bidderAddr)
  927. }
  928. func (hdb *HistoryDB) getCoordinatorAPI(d meddler.DB, bidderAddr ethCommon.Address) (*CoordinatorAPI, error) {
  929. coordinator := &CoordinatorAPI{}
  930. err := meddler.QueryRow(
  931. d, coordinator,
  932. "SELECT * FROM coordinator WHERE bidder_addr = $1 ORDER BY item_id DESC LIMIT 1;",
  933. bidderAddr,
  934. )
  935. return coordinator, tracerr.Wrap(err)
  936. }
  937. // GetNodeInfoAPI retusnt he NodeInfo
  938. func (hdb *HistoryDB) GetNodeInfoAPI() (*NodeInfo, error) {
  939. cancel, err := hdb.apiConnCon.Acquire()
  940. defer cancel()
  941. if err != nil {
  942. return nil, tracerr.Wrap(err)
  943. }
  944. defer hdb.apiConnCon.Release()
  945. return hdb.GetNodeInfo()
  946. }
  947. // GetBucketUpdatesInternalAPI returns the latest bucket updates
  948. func (hdb *HistoryDB) GetBucketUpdatesInternalAPI() ([]BucketUpdateAPI, error) {
  949. var bucketUpdates []*BucketUpdateAPI
  950. err := meddler.QueryAll(
  951. hdb.dbRead, &bucketUpdates,
  952. `SELECT num_bucket, withdrawals FROM bucket_update
  953. WHERE item_id in(SELECT max(item_id) FROM bucket_update
  954. group by num_bucket)
  955. ORDER BY num_bucket ASC;`,
  956. )
  957. return db.SlicePtrsToSlice(bucketUpdates).([]BucketUpdateAPI), tracerr.Wrap(err)
  958. }
  959. // GetNextForgersInternalAPI returns next forgers
  960. func (hdb *HistoryDB) GetNextForgersInternalAPI(auctionVars *common.AuctionVariables,
  961. auctionConsts *common.AuctionConstants,
  962. lastBlock common.Block, currentSlot, lastClosedSlot int64) ([]NextForgerAPI, error) {
  963. secondsPerBlock := int64(15) //nolint:gomnd
  964. // currentSlot and lastClosedSlot included
  965. limit := uint(lastClosedSlot - currentSlot + 1)
  966. bids, _, err := hdb.getBestBidsAPI(hdb.dbRead, &currentSlot, &lastClosedSlot, nil, &limit, "ASC")
  967. if err != nil && tracerr.Unwrap(err) != sql.ErrNoRows {
  968. return nil, tracerr.Wrap(err)
  969. }
  970. nextForgers := []NextForgerAPI{}
  971. // Get min bid info
  972. var minBidInfo []MinBidInfo
  973. if currentSlot >= auctionVars.DefaultSlotSetBidSlotNum {
  974. // All min bids can be calculated with the last update of AuctionVariables
  975. minBidInfo = []MinBidInfo{{
  976. DefaultSlotSetBid: auctionVars.DefaultSlotSetBid,
  977. DefaultSlotSetBidSlotNum: auctionVars.DefaultSlotSetBidSlotNum,
  978. }}
  979. } else {
  980. // Get all the relevant updates from the DB
  981. minBidInfo, err = hdb.getMinBidInfo(hdb.dbRead, currentSlot, lastClosedSlot)
  982. if err != nil {
  983. return nil, tracerr.Wrap(err)
  984. }
  985. }
  986. // Create nextForger for each slot
  987. for i := currentSlot; i <= lastClosedSlot; i++ {
  988. fromBlock := i*int64(auctionConsts.BlocksPerSlot) +
  989. auctionConsts.GenesisBlockNum
  990. toBlock := (i+1)*int64(auctionConsts.BlocksPerSlot) +
  991. auctionConsts.GenesisBlockNum - 1
  992. nextForger := NextForgerAPI{
  993. Period: Period{
  994. SlotNum: i,
  995. FromBlock: fromBlock,
  996. ToBlock: toBlock,
  997. FromTimestamp: lastBlock.Timestamp.Add(time.Second *
  998. time.Duration(secondsPerBlock*(fromBlock-lastBlock.Num))),
  999. ToTimestamp: lastBlock.Timestamp.Add(time.Second *
  1000. time.Duration(secondsPerBlock*(toBlock-lastBlock.Num))),
  1001. },
  1002. }
  1003. foundForger := false
  1004. // If there is a bid for a slot, get forger (coordinator)
  1005. for j := range bids {
  1006. slotNum := bids[j].SlotNum
  1007. if slotNum == i {
  1008. // There's a bid for the slot
  1009. // Check if the bid is greater than the minimum required
  1010. for i := 0; i < len(minBidInfo); i++ {
  1011. // Find the most recent update
  1012. if slotNum >= minBidInfo[i].DefaultSlotSetBidSlotNum {
  1013. // Get min bid
  1014. minBidSelector := slotNum % int64(len(auctionVars.DefaultSlotSetBid))
  1015. minBid := minBidInfo[i].DefaultSlotSetBid[minBidSelector]
  1016. // Check if the bid has beaten the minimum
  1017. bid, ok := new(big.Int).SetString(string(bids[j].BidValue), 10)
  1018. if !ok {
  1019. return nil, tracerr.New("Wrong bid value, error parsing it as big.Int")
  1020. }
  1021. if minBid.Cmp(bid) == 1 {
  1022. // Min bid is greater than bid, the slot will be forged by boot coordinator
  1023. break
  1024. }
  1025. foundForger = true
  1026. break
  1027. }
  1028. }
  1029. if !foundForger { // There is no bid or it's smaller than the minimum
  1030. break
  1031. }
  1032. coordinator, err := hdb.getCoordinatorAPI(hdb.dbRead, bids[j].Bidder)
  1033. if err != nil {
  1034. return nil, tracerr.Wrap(err)
  1035. }
  1036. nextForger.Coordinator = *coordinator
  1037. break
  1038. }
  1039. }
  1040. // If there is no bid, the coordinator that will forge is boot coordinator
  1041. if !foundForger {
  1042. nextForger.Coordinator = CoordinatorAPI{
  1043. Forger: auctionVars.BootCoordinator,
  1044. URL: auctionVars.BootCoordinatorURL,
  1045. }
  1046. }
  1047. nextForgers = append(nextForgers, nextForger)
  1048. }
  1049. return nextForgers, nil
  1050. }
  1051. // GetMetricsInternalAPI returns the MetricsAPI
  1052. func (hdb *HistoryDB) GetMetricsInternalAPI(lastBatchNum common.BatchNum) (metrics *MetricsAPI, poolLoad int64, err error) {
  1053. metrics = &MetricsAPI{}
  1054. type period struct {
  1055. FromBatchNum common.BatchNum `meddler:"from_batch_num"`
  1056. FromTimestamp time.Time `meddler:"from_timestamp"`
  1057. ToBatchNum common.BatchNum `meddler:"-"`
  1058. ToTimestamp time.Time `meddler:"to_timestamp"`
  1059. }
  1060. p := &period{
  1061. ToBatchNum: lastBatchNum,
  1062. }
  1063. if err := meddler.QueryRow(
  1064. hdb.dbRead, p, `SELECT
  1065. COALESCE (MIN(batch.batch_num), 0) as from_batch_num,
  1066. COALESCE (MIN(block.timestamp), NOW()) AS from_timestamp,
  1067. COALESCE (MAX(block.timestamp), NOW()) AS to_timestamp
  1068. FROM batch INNER JOIN block ON batch.eth_block_num = block.eth_block_num
  1069. WHERE block.timestamp >= NOW() - INTERVAL '24 HOURS';`,
  1070. ); err != nil {
  1071. return nil, 0, tracerr.Wrap(err)
  1072. }
  1073. // Get the amount of txs of that period
  1074. row := hdb.dbRead.QueryRow(
  1075. `SELECT COUNT(*) as total_txs FROM tx WHERE tx.batch_num between $1 AND $2;`,
  1076. p.FromBatchNum, p.ToBatchNum,
  1077. )
  1078. var nTxs int
  1079. if err := row.Scan(&nTxs); err != nil {
  1080. return nil, 0, tracerr.Wrap(err)
  1081. }
  1082. // Set txs/s
  1083. seconds := p.ToTimestamp.Sub(p.FromTimestamp).Seconds()
  1084. if seconds == 0 { // Avoid dividing by 0
  1085. seconds++
  1086. }
  1087. metrics.TransactionsPerSecond = float64(nTxs) / seconds
  1088. // Set txs/batch
  1089. nBatches := p.ToBatchNum - p.FromBatchNum + 1
  1090. if nBatches == 0 { // Avoid dividing by 0
  1091. nBatches++
  1092. }
  1093. if (p.ToBatchNum - p.FromBatchNum) > 0 {
  1094. metrics.TransactionsPerBatch = float64(nTxs) /
  1095. float64(nBatches)
  1096. } else {
  1097. metrics.TransactionsPerBatch = 0
  1098. }
  1099. // Get total fee of that period
  1100. row = hdb.dbRead.QueryRow(
  1101. `SELECT COALESCE (SUM(total_fees_usd), 0) FROM batch WHERE batch_num between $1 AND $2;`,
  1102. p.FromBatchNum, p.ToBatchNum,
  1103. )
  1104. var totalFee float64
  1105. if err := row.Scan(&totalFee); err != nil {
  1106. return nil, 0, tracerr.Wrap(err)
  1107. }
  1108. // Set batch frequency
  1109. metrics.BatchFrequency = seconds / float64(nBatches)
  1110. // Set avg transaction fee (only L2 txs have fee)
  1111. row = hdb.dbRead.QueryRow(
  1112. `SELECT COUNT(*) as total_txs FROM tx WHERE tx.batch_num between $1 AND $2 AND NOT is_l1;`,
  1113. p.FromBatchNum, p.ToBatchNum,
  1114. )
  1115. var nL2Txs int
  1116. if err := row.Scan(&nL2Txs); err != nil {
  1117. return nil, 0, tracerr.Wrap(err)
  1118. }
  1119. if nL2Txs > 0 {
  1120. metrics.AvgTransactionFee = totalFee / float64(nL2Txs)
  1121. } else {
  1122. metrics.AvgTransactionFee = 0
  1123. }
  1124. // Get and set amount of registered accounts
  1125. type registeredAccounts struct {
  1126. TokenAccounts int64 `meddler:"token_accounts"`
  1127. Wallets int64 `meddler:"wallets"`
  1128. }
  1129. ra := &registeredAccounts{}
  1130. if err := meddler.QueryRow(
  1131. hdb.dbRead, ra,
  1132. `SELECT COUNT(*) AS token_accounts, COUNT(DISTINCT(bjj)) AS wallets FROM account;`,
  1133. ); err != nil {
  1134. return nil, 0, tracerr.Wrap(err)
  1135. }
  1136. metrics.TokenAccounts = ra.TokenAccounts
  1137. metrics.Wallets = ra.Wallets
  1138. // Get and set estimated time to forge L1 tx
  1139. row = hdb.dbRead.QueryRow(
  1140. `SELECT COALESCE (AVG(EXTRACT(EPOCH FROM (forged.timestamp - added.timestamp))), 0) FROM tx
  1141. INNER JOIN block AS added ON tx.eth_block_num = added.eth_block_num
  1142. INNER JOIN batch AS forged_batch ON tx.batch_num = forged_batch.batch_num
  1143. INNER JOIN block AS forged ON forged_batch.eth_block_num = forged.eth_block_num
  1144. WHERE tx.batch_num between $1 and $2 AND tx.is_l1 AND tx.user_origin;`,
  1145. p.FromBatchNum, p.ToBatchNum,
  1146. )
  1147. var timeToForgeL1 float64
  1148. if err := row.Scan(&timeToForgeL1); err != nil {
  1149. return nil, 0, tracerr.Wrap(err)
  1150. }
  1151. metrics.EstimatedTimeToForgeL1 = timeToForgeL1
  1152. // Get amount of txs in the pool
  1153. row = hdb.dbRead.QueryRow(
  1154. `SELECT COUNT(*) FROM tx_pool WHERE state = $1 AND NOT external_delete;`,
  1155. common.PoolL2TxStatePending,
  1156. )
  1157. if err := row.Scan(&poolLoad); err != nil {
  1158. return nil, 0, tracerr.Wrap(err)
  1159. }
  1160. return metrics, poolLoad, nil
  1161. }
  1162. // GetStateAPI returns the StateAPI
  1163. func (hdb *HistoryDB) GetStateAPI() (*StateAPI, error) {
  1164. cancel, err := hdb.apiConnCon.Acquire()
  1165. defer cancel()
  1166. if err != nil {
  1167. return nil, tracerr.Wrap(err)
  1168. }
  1169. defer hdb.apiConnCon.Release()
  1170. return hdb.getStateAPI(hdb.dbRead)
  1171. }