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.

1224 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, fromIdx, toIdx *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 fromIdx != nil && toIdx != nil {
  498. if nextIsAnd {
  499. queryStr += "AND "
  500. } else {
  501. queryStr += "WHERE "
  502. }
  503. queryStr += "(tx.effective_from_idx = ? "
  504. queryStr += "OR tx.to_idx = ?) "
  505. args = append(args, fromIdx, toIdx)
  506. nextIsAnd = true
  507. } else if fromIdx != nil {
  508. if nextIsAnd {
  509. queryStr += "AND "
  510. } else {
  511. queryStr += "WHERE "
  512. }
  513. queryStr += "tx.effective_from_idx = ? "
  514. nextIsAnd = true
  515. } else if toIdx != nil {
  516. if nextIsAnd {
  517. queryStr += "AND "
  518. } else {
  519. queryStr += "WHERE "
  520. }
  521. queryStr += "tx.to_idx = ? "
  522. args = append(args, toIdx)
  523. nextIsAnd = true
  524. }
  525. // batchNum filter
  526. if batchNum != nil {
  527. if nextIsAnd {
  528. queryStr += "AND "
  529. } else {
  530. queryStr += "WHERE "
  531. }
  532. queryStr += "tx.batch_num = ? "
  533. args = append(args, batchNum)
  534. nextIsAnd = true
  535. }
  536. // txType filter
  537. if txType != nil {
  538. if nextIsAnd {
  539. queryStr += "AND "
  540. } else {
  541. queryStr += "WHERE "
  542. }
  543. queryStr += "tx.type = ? "
  544. args = append(args, txType)
  545. nextIsAnd = true
  546. }
  547. if fromItem != nil {
  548. if nextIsAnd {
  549. queryStr += "AND "
  550. } else {
  551. queryStr += "WHERE "
  552. }
  553. if order == OrderAsc {
  554. queryStr += "tx.item_id >= ? "
  555. } else {
  556. queryStr += "tx.item_id <= ? "
  557. }
  558. args = append(args, fromItem)
  559. nextIsAnd = true
  560. }
  561. if nextIsAnd {
  562. queryStr += "AND "
  563. } else {
  564. queryStr += "WHERE "
  565. }
  566. queryStr += "tx.batch_num IS NOT NULL "
  567. // pagination
  568. queryStr += "ORDER BY tx.item_id "
  569. if order == OrderAsc {
  570. queryStr += " ASC "
  571. } else {
  572. queryStr += " DESC "
  573. }
  574. queryStr += fmt.Sprintf("LIMIT %d;", *limit)
  575. query = hdb.dbRead.Rebind(queryStr)
  576. // log.Debug(query)
  577. txsPtrs := []*TxAPI{}
  578. if err := meddler.QueryAll(hdb.dbRead, &txsPtrs, query, args...); err != nil {
  579. return nil, 0, tracerr.Wrap(err)
  580. }
  581. txs := db.SlicePtrsToSlice(txsPtrs).([]TxAPI)
  582. if len(txs) == 0 {
  583. return txs, 0, nil
  584. }
  585. return txs, txs[0].TotalItems - uint64(len(txs)), nil
  586. }
  587. // GetExitAPI returns a exit from the DB
  588. func (hdb *HistoryDB) GetExitAPI(batchNum *uint, idx *common.Idx) (*ExitAPI, error) {
  589. cancel, err := hdb.apiConnCon.Acquire()
  590. defer cancel()
  591. if err != nil {
  592. return nil, tracerr.Wrap(err)
  593. }
  594. defer hdb.apiConnCon.Release()
  595. exit := &ExitAPI{}
  596. err = meddler.QueryRow(
  597. hdb.dbRead, exit, `SELECT exit_tree.item_id, exit_tree.batch_num,
  598. hez_idx(exit_tree.account_idx, token.symbol) AS account_idx,
  599. account.bjj, account.eth_addr,
  600. exit_tree.merkle_proof, exit_tree.balance, exit_tree.instant_withdrawn,
  601. exit_tree.delayed_withdraw_request, exit_tree.delayed_withdrawn,
  602. token.token_id, token.item_id AS token_item_id,
  603. token.eth_block_num AS token_block, token.eth_addr AS token_eth_addr, token.name, token.symbol,
  604. token.decimals, token.usd, token.usd_update
  605. FROM exit_tree INNER JOIN account ON exit_tree.account_idx = account.idx
  606. INNER JOIN token ON account.token_id = token.token_id
  607. WHERE exit_tree.batch_num = $1 AND exit_tree.account_idx = $2;`, batchNum, idx,
  608. )
  609. return exit, tracerr.Wrap(err)
  610. }
  611. // GetExitsAPI returns a list of exits from the DB and pagination info
  612. func (hdb *HistoryDB) GetExitsAPI(
  613. ethAddr *ethCommon.Address, bjj *babyjub.PublicKeyComp, tokenID *common.TokenID,
  614. idx *common.Idx, batchNum *uint, onlyPendingWithdraws *bool,
  615. fromItem, limit *uint, order string,
  616. ) ([]ExitAPI, uint64, error) {
  617. if ethAddr != nil && bjj != nil {
  618. return nil, 0, tracerr.Wrap(errors.New("ethAddr and bjj are incompatible"))
  619. }
  620. cancel, err := hdb.apiConnCon.Acquire()
  621. defer cancel()
  622. if err != nil {
  623. return nil, 0, tracerr.Wrap(err)
  624. }
  625. defer hdb.apiConnCon.Release()
  626. var query string
  627. var args []interface{}
  628. queryStr := `SELECT exit_tree.item_id, exit_tree.batch_num,
  629. hez_idx(exit_tree.account_idx, token.symbol) AS account_idx,
  630. account.bjj, account.eth_addr,
  631. exit_tree.merkle_proof, exit_tree.balance, exit_tree.instant_withdrawn,
  632. exit_tree.delayed_withdraw_request, exit_tree.delayed_withdrawn,
  633. token.token_id, token.item_id AS token_item_id,
  634. token.eth_block_num AS token_block, token.eth_addr AS token_eth_addr, token.name, token.symbol,
  635. token.decimals, token.usd, token.usd_update, COUNT(*) OVER() AS total_items
  636. FROM exit_tree INNER JOIN account ON exit_tree.account_idx = account.idx
  637. INNER JOIN token ON account.token_id = token.token_id `
  638. // Apply filters
  639. nextIsAnd := false
  640. // ethAddr filter
  641. if ethAddr != nil {
  642. queryStr += "WHERE account.eth_addr = ? "
  643. nextIsAnd = true
  644. args = append(args, ethAddr)
  645. } else if bjj != nil { // bjj filter
  646. queryStr += "WHERE account.bjj = ? "
  647. nextIsAnd = true
  648. args = append(args, bjj)
  649. }
  650. // tokenID filter
  651. if tokenID != nil {
  652. if nextIsAnd {
  653. queryStr += "AND "
  654. } else {
  655. queryStr += "WHERE "
  656. }
  657. queryStr += "account.token_id = ? "
  658. args = append(args, tokenID)
  659. nextIsAnd = true
  660. }
  661. // idx filter
  662. if idx != nil {
  663. if nextIsAnd {
  664. queryStr += "AND "
  665. } else {
  666. queryStr += "WHERE "
  667. }
  668. queryStr += "exit_tree.account_idx = ? "
  669. args = append(args, idx)
  670. nextIsAnd = true
  671. }
  672. // batchNum filter
  673. if batchNum != nil {
  674. if nextIsAnd {
  675. queryStr += "AND "
  676. } else {
  677. queryStr += "WHERE "
  678. }
  679. queryStr += "exit_tree.batch_num = ? "
  680. args = append(args, batchNum)
  681. nextIsAnd = true
  682. }
  683. // onlyPendingWithdraws
  684. if onlyPendingWithdraws != nil {
  685. if *onlyPendingWithdraws {
  686. if nextIsAnd {
  687. queryStr += "AND "
  688. } else {
  689. queryStr += "WHERE "
  690. }
  691. queryStr += "(exit_tree.instant_withdrawn IS NULL AND exit_tree.delayed_withdrawn IS NULL) "
  692. nextIsAnd = true
  693. }
  694. }
  695. if fromItem != nil {
  696. if nextIsAnd {
  697. queryStr += "AND "
  698. } else {
  699. queryStr += "WHERE "
  700. }
  701. if order == OrderAsc {
  702. queryStr += "exit_tree.item_id >= ? "
  703. } else {
  704. queryStr += "exit_tree.item_id <= ? "
  705. }
  706. args = append(args, fromItem)
  707. // nextIsAnd = true
  708. }
  709. // pagination
  710. queryStr += "ORDER BY exit_tree.item_id "
  711. if order == OrderAsc {
  712. queryStr += " ASC "
  713. } else {
  714. queryStr += " DESC "
  715. }
  716. queryStr += fmt.Sprintf("LIMIT %d;", *limit)
  717. query = hdb.dbRead.Rebind(queryStr)
  718. // log.Debug(query)
  719. exits := []*ExitAPI{}
  720. if err := meddler.QueryAll(hdb.dbRead, &exits, query, args...); err != nil {
  721. return nil, 0, tracerr.Wrap(err)
  722. }
  723. if len(exits) == 0 {
  724. return []ExitAPI{}, 0, nil
  725. }
  726. return db.SlicePtrsToSlice(exits).([]ExitAPI), exits[0].TotalItems - uint64(len(exits)), nil
  727. }
  728. // GetCoordinatorsAPI returns a list of coordinators from the DB and pagination info
  729. func (hdb *HistoryDB) GetCoordinatorsAPI(
  730. bidderAddr, forgerAddr *ethCommon.Address,
  731. fromItem, limit *uint, order string,
  732. ) ([]CoordinatorAPI, uint64, error) {
  733. cancel, err := hdb.apiConnCon.Acquire()
  734. defer cancel()
  735. if err != nil {
  736. return nil, 0, tracerr.Wrap(err)
  737. }
  738. defer hdb.apiConnCon.Release()
  739. var query string
  740. var args []interface{}
  741. queryStr := `SELECT coordinator.*, COUNT(*) OVER() AS total_items
  742. FROM coordinator INNER JOIN (
  743. SELECT MAX(item_id) AS item_id FROM coordinator
  744. GROUP BY bidder_addr
  745. ) c ON coordinator.item_id = c.item_id `
  746. // Apply filters
  747. nextIsAnd := false
  748. if bidderAddr != nil {
  749. queryStr += "WHERE bidder_addr = ? "
  750. nextIsAnd = true
  751. args = append(args, bidderAddr)
  752. }
  753. if forgerAddr != nil {
  754. if nextIsAnd {
  755. queryStr += "AND "
  756. } else {
  757. queryStr += "WHERE "
  758. }
  759. queryStr += "forger_addr = ? "
  760. nextIsAnd = true
  761. args = append(args, forgerAddr)
  762. }
  763. if fromItem != nil {
  764. if nextIsAnd {
  765. queryStr += "AND "
  766. } else {
  767. queryStr += "WHERE "
  768. }
  769. if order == OrderAsc {
  770. queryStr += "coordinator.item_id >= ? "
  771. } else {
  772. queryStr += "coordinator.item_id <= ? "
  773. }
  774. args = append(args, fromItem)
  775. }
  776. // pagination
  777. queryStr += "ORDER BY coordinator.item_id "
  778. if order == OrderAsc {
  779. queryStr += " ASC "
  780. } else {
  781. queryStr += " DESC "
  782. }
  783. queryStr += fmt.Sprintf("LIMIT %d;", *limit)
  784. query = hdb.dbRead.Rebind(queryStr)
  785. coordinators := []*CoordinatorAPI{}
  786. if err := meddler.QueryAll(hdb.dbRead, &coordinators, query, args...); err != nil {
  787. return nil, 0, tracerr.Wrap(err)
  788. }
  789. if len(coordinators) == 0 {
  790. return []CoordinatorAPI{}, 0, nil
  791. }
  792. return db.SlicePtrsToSlice(coordinators).([]CoordinatorAPI),
  793. coordinators[0].TotalItems - uint64(len(coordinators)), nil
  794. }
  795. // GetAuctionVarsAPI returns auction variables
  796. func (hdb *HistoryDB) GetAuctionVarsAPI() (*common.AuctionVariables, error) {
  797. cancel, err := hdb.apiConnCon.Acquire()
  798. defer cancel()
  799. if err != nil {
  800. return nil, tracerr.Wrap(err)
  801. }
  802. defer hdb.apiConnCon.Release()
  803. auctionVars := &common.AuctionVariables{}
  804. err = meddler.QueryRow(
  805. hdb.dbRead, auctionVars, `SELECT * FROM auction_vars;`,
  806. )
  807. return auctionVars, tracerr.Wrap(err)
  808. }
  809. // GetAccountAPI returns an account by its index
  810. func (hdb *HistoryDB) GetAccountAPI(idx common.Idx) (*AccountAPI, error) {
  811. cancel, err := hdb.apiConnCon.Acquire()
  812. defer cancel()
  813. if err != nil {
  814. return nil, tracerr.Wrap(err)
  815. }
  816. defer hdb.apiConnCon.Release()
  817. account := &AccountAPI{}
  818. err = meddler.QueryRow(hdb.dbRead, account, `SELECT account.item_id, hez_idx(account.idx,
  819. token.symbol) as idx, account.batch_num, account.bjj, account.eth_addr,
  820. token.token_id, token.item_id AS token_item_id, token.eth_block_num AS token_block,
  821. token.eth_addr as token_eth_addr, token.name, token.symbol, token.decimals, token.usd,
  822. token.usd_update, account_update.nonce, account_update.balance
  823. FROM account inner JOIN (
  824. SELECT idx, nonce, balance
  825. FROM account_update
  826. WHERE idx = $1
  827. ORDER BY item_id DESC LIMIT 1
  828. ) AS account_update ON account_update.idx = account.idx
  829. INNER JOIN token ON account.token_id = token.token_id
  830. WHERE account.idx = $1;`, idx)
  831. if err != nil {
  832. return nil, tracerr.Wrap(err)
  833. }
  834. return account, nil
  835. }
  836. // GetAccountsAPI returns a list of accounts from the DB and pagination info
  837. func (hdb *HistoryDB) GetAccountsAPI(
  838. tokenIDs []common.TokenID, ethAddr *ethCommon.Address,
  839. bjj *babyjub.PublicKeyComp, fromItem, limit *uint, order string,
  840. ) ([]AccountAPI, uint64, error) {
  841. if ethAddr != nil && bjj != nil {
  842. return nil, 0, tracerr.Wrap(errors.New("ethAddr and bjj are incompatible"))
  843. }
  844. cancel, err := hdb.apiConnCon.Acquire()
  845. defer cancel()
  846. if err != nil {
  847. return nil, 0, tracerr.Wrap(err)
  848. }
  849. defer hdb.apiConnCon.Release()
  850. var query string
  851. var args []interface{}
  852. queryStr := `SELECT account.item_id, hez_idx(account.idx, token.symbol) as idx, account.batch_num,
  853. account.bjj, account.eth_addr, token.token_id, token.item_id AS token_item_id, token.eth_block_num AS token_block,
  854. token.eth_addr as token_eth_addr, token.name, token.symbol, token.decimals, token.usd, token.usd_update,
  855. account_update.nonce, account_update.balance, COUNT(*) OVER() AS total_items
  856. FROM account inner JOIN (
  857. SELECT DISTINCT idx,
  858. first_value(nonce) over(partition by idx ORDER BY item_id DESC) as nonce,
  859. first_value(balance) over(partition by idx ORDER BY item_id DESC) as balance
  860. FROM account_update
  861. ) AS account_update ON account_update.idx = account.idx INNER JOIN token ON account.token_id = token.token_id `
  862. // Apply filters
  863. nextIsAnd := false
  864. // ethAddr filter
  865. if ethAddr != nil {
  866. queryStr += "WHERE account.eth_addr = ? "
  867. nextIsAnd = true
  868. args = append(args, ethAddr)
  869. } else if bjj != nil { // bjj filter
  870. queryStr += "WHERE account.bjj = ? "
  871. nextIsAnd = true
  872. args = append(args, bjj)
  873. }
  874. // tokenID filter
  875. if len(tokenIDs) > 0 {
  876. if nextIsAnd {
  877. queryStr += "AND "
  878. } else {
  879. queryStr += "WHERE "
  880. }
  881. queryStr += "account.token_id IN (?) "
  882. args = append(args, tokenIDs)
  883. nextIsAnd = true
  884. }
  885. if fromItem != nil {
  886. if nextIsAnd {
  887. queryStr += "AND "
  888. } else {
  889. queryStr += "WHERE "
  890. }
  891. if order == OrderAsc {
  892. queryStr += "account.item_id >= ? "
  893. } else {
  894. queryStr += "account.item_id <= ? "
  895. }
  896. args = append(args, fromItem)
  897. }
  898. // pagination
  899. queryStr += "ORDER BY account.item_id "
  900. if order == OrderAsc {
  901. queryStr += " ASC "
  902. } else {
  903. queryStr += " DESC "
  904. }
  905. queryStr += fmt.Sprintf("LIMIT %d;", *limit)
  906. query, argsQ, err := sqlx.In(queryStr, args...)
  907. if err != nil {
  908. return nil, 0, tracerr.Wrap(err)
  909. }
  910. query = hdb.dbRead.Rebind(query)
  911. accounts := []*AccountAPI{}
  912. if err := meddler.QueryAll(hdb.dbRead, &accounts, query, argsQ...); err != nil {
  913. return nil, 0, tracerr.Wrap(err)
  914. }
  915. if len(accounts) == 0 {
  916. return []AccountAPI{}, 0, nil
  917. }
  918. return db.SlicePtrsToSlice(accounts).([]AccountAPI),
  919. accounts[0].TotalItems - uint64(len(accounts)), nil
  920. }
  921. // GetCommonAccountAPI returns the account associated to an account idx
  922. func (hdb *HistoryDB) GetCommonAccountAPI(idx common.Idx) (*common.Account, error) {
  923. cancel, err := hdb.apiConnCon.Acquire()
  924. defer cancel()
  925. if err != nil {
  926. return nil, tracerr.Wrap(err)
  927. }
  928. defer hdb.apiConnCon.Release()
  929. account := &common.Account{}
  930. err = meddler.QueryRow(
  931. hdb.dbRead, account, `SELECT idx, token_id, batch_num, bjj, eth_addr
  932. FROM account WHERE idx = $1;`, idx,
  933. )
  934. return account, tracerr.Wrap(err)
  935. }
  936. // GetCoordinatorAPI returns a coordinator by its bidderAddr
  937. func (hdb *HistoryDB) GetCoordinatorAPI(bidderAddr ethCommon.Address) (*CoordinatorAPI, error) {
  938. cancel, err := hdb.apiConnCon.Acquire()
  939. defer cancel()
  940. if err != nil {
  941. return nil, tracerr.Wrap(err)
  942. }
  943. defer hdb.apiConnCon.Release()
  944. return hdb.getCoordinatorAPI(hdb.dbRead, bidderAddr)
  945. }
  946. func (hdb *HistoryDB) getCoordinatorAPI(d meddler.DB, bidderAddr ethCommon.Address) (*CoordinatorAPI, error) {
  947. coordinator := &CoordinatorAPI{}
  948. err := meddler.QueryRow(
  949. d, coordinator,
  950. "SELECT * FROM coordinator WHERE bidder_addr = $1 ORDER BY item_id DESC LIMIT 1;",
  951. bidderAddr,
  952. )
  953. return coordinator, tracerr.Wrap(err)
  954. }
  955. // GetNodeInfoAPI retusnt he NodeInfo
  956. func (hdb *HistoryDB) GetNodeInfoAPI() (*NodeInfo, error) {
  957. cancel, err := hdb.apiConnCon.Acquire()
  958. defer cancel()
  959. if err != nil {
  960. return nil, tracerr.Wrap(err)
  961. }
  962. defer hdb.apiConnCon.Release()
  963. return hdb.GetNodeInfo()
  964. }
  965. // GetBucketUpdatesInternalAPI returns the latest bucket updates
  966. func (hdb *HistoryDB) GetBucketUpdatesInternalAPI() ([]BucketUpdateAPI, error) {
  967. var bucketUpdates []*BucketUpdateAPI
  968. err := meddler.QueryAll(
  969. hdb.dbRead, &bucketUpdates,
  970. `SELECT num_bucket, withdrawals FROM bucket_update
  971. WHERE item_id in(SELECT max(item_id) FROM bucket_update
  972. group by num_bucket)
  973. ORDER BY num_bucket ASC;`,
  974. )
  975. return db.SlicePtrsToSlice(bucketUpdates).([]BucketUpdateAPI), tracerr.Wrap(err)
  976. }
  977. // GetNextForgersInternalAPI returns next forgers
  978. func (hdb *HistoryDB) GetNextForgersInternalAPI(auctionVars *common.AuctionVariables,
  979. auctionConsts *common.AuctionConstants,
  980. lastBlock common.Block, currentSlot, lastClosedSlot int64) ([]NextForgerAPI, error) {
  981. secondsPerBlock := int64(15) //nolint:gomnd
  982. // currentSlot and lastClosedSlot included
  983. limit := uint(lastClosedSlot - currentSlot + 1)
  984. bids, _, err := hdb.getBestBidsAPI(hdb.dbRead, &currentSlot, &lastClosedSlot, nil, &limit, "ASC")
  985. if err != nil && tracerr.Unwrap(err) != sql.ErrNoRows {
  986. return nil, tracerr.Wrap(err)
  987. }
  988. nextForgers := []NextForgerAPI{}
  989. // Get min bid info
  990. var minBidInfo []MinBidInfo
  991. if currentSlot >= auctionVars.DefaultSlotSetBidSlotNum {
  992. // All min bids can be calculated with the last update of AuctionVariables
  993. minBidInfo = []MinBidInfo{{
  994. DefaultSlotSetBid: auctionVars.DefaultSlotSetBid,
  995. DefaultSlotSetBidSlotNum: auctionVars.DefaultSlotSetBidSlotNum,
  996. }}
  997. } else {
  998. // Get all the relevant updates from the DB
  999. minBidInfo, err = hdb.getMinBidInfo(hdb.dbRead, currentSlot, lastClosedSlot)
  1000. if err != nil {
  1001. return nil, tracerr.Wrap(err)
  1002. }
  1003. }
  1004. // Create nextForger for each slot
  1005. for i := currentSlot; i <= lastClosedSlot; i++ {
  1006. fromBlock := i*int64(auctionConsts.BlocksPerSlot) +
  1007. auctionConsts.GenesisBlockNum
  1008. toBlock := (i+1)*int64(auctionConsts.BlocksPerSlot) +
  1009. auctionConsts.GenesisBlockNum - 1
  1010. nextForger := NextForgerAPI{
  1011. Period: Period{
  1012. SlotNum: i,
  1013. FromBlock: fromBlock,
  1014. ToBlock: toBlock,
  1015. FromTimestamp: lastBlock.Timestamp.Add(time.Second *
  1016. time.Duration(secondsPerBlock*(fromBlock-lastBlock.Num))),
  1017. ToTimestamp: lastBlock.Timestamp.Add(time.Second *
  1018. time.Duration(secondsPerBlock*(toBlock-lastBlock.Num))),
  1019. },
  1020. }
  1021. foundForger := false
  1022. // If there is a bid for a slot, get forger (coordinator)
  1023. for j := range bids {
  1024. slotNum := bids[j].SlotNum
  1025. if slotNum == i {
  1026. // There's a bid for the slot
  1027. // Check if the bid is greater than the minimum required
  1028. for i := 0; i < len(minBidInfo); i++ {
  1029. // Find the most recent update
  1030. if slotNum >= minBidInfo[i].DefaultSlotSetBidSlotNum {
  1031. // Get min bid
  1032. minBidSelector := slotNum % int64(len(auctionVars.DefaultSlotSetBid))
  1033. minBid := minBidInfo[i].DefaultSlotSetBid[minBidSelector]
  1034. // Check if the bid has beaten the minimum
  1035. bid, ok := new(big.Int).SetString(string(bids[j].BidValue), 10)
  1036. if !ok {
  1037. return nil, tracerr.New("Wrong bid value, error parsing it as big.Int")
  1038. }
  1039. if minBid.Cmp(bid) == 1 {
  1040. // Min bid is greater than bid, the slot will be forged by boot coordinator
  1041. break
  1042. }
  1043. foundForger = true
  1044. break
  1045. }
  1046. }
  1047. if !foundForger { // There is no bid or it's smaller than the minimum
  1048. break
  1049. }
  1050. coordinator, err := hdb.getCoordinatorAPI(hdb.dbRead, bids[j].Bidder)
  1051. if err != nil {
  1052. return nil, tracerr.Wrap(err)
  1053. }
  1054. nextForger.Coordinator = *coordinator
  1055. break
  1056. }
  1057. }
  1058. // If there is no bid, the coordinator that will forge is boot coordinator
  1059. if !foundForger {
  1060. nextForger.Coordinator = CoordinatorAPI{
  1061. Forger: auctionVars.BootCoordinator,
  1062. URL: auctionVars.BootCoordinatorURL,
  1063. }
  1064. }
  1065. nextForgers = append(nextForgers, nextForger)
  1066. }
  1067. return nextForgers, nil
  1068. }
  1069. // GetMetricsInternalAPI returns the MetricsAPI
  1070. func (hdb *HistoryDB) GetMetricsInternalAPI(lastBatchNum common.BatchNum) (metrics *MetricsAPI, poolLoad int64, err error) {
  1071. metrics = &MetricsAPI{}
  1072. type period struct {
  1073. FromBatchNum common.BatchNum `meddler:"from_batch_num"`
  1074. FromTimestamp time.Time `meddler:"from_timestamp"`
  1075. ToBatchNum common.BatchNum `meddler:"-"`
  1076. ToTimestamp time.Time `meddler:"to_timestamp"`
  1077. }
  1078. p := &period{
  1079. ToBatchNum: lastBatchNum,
  1080. }
  1081. if err := meddler.QueryRow(
  1082. hdb.dbRead, p, `SELECT
  1083. COALESCE (MIN(batch.batch_num), 0) as from_batch_num,
  1084. COALESCE (MIN(block.timestamp), NOW()) AS from_timestamp,
  1085. COALESCE (MAX(block.timestamp), NOW()) AS to_timestamp
  1086. FROM batch INNER JOIN block ON batch.eth_block_num = block.eth_block_num
  1087. WHERE block.timestamp >= NOW() - INTERVAL '24 HOURS';`,
  1088. ); err != nil {
  1089. return nil, 0, tracerr.Wrap(err)
  1090. }
  1091. // Get the amount of txs of that period
  1092. row := hdb.dbRead.QueryRow(
  1093. `SELECT COUNT(*) as total_txs FROM tx WHERE tx.batch_num between $1 AND $2;`,
  1094. p.FromBatchNum, p.ToBatchNum,
  1095. )
  1096. var nTxs int
  1097. if err := row.Scan(&nTxs); err != nil {
  1098. return nil, 0, tracerr.Wrap(err)
  1099. }
  1100. // Set txs/s
  1101. seconds := p.ToTimestamp.Sub(p.FromTimestamp).Seconds()
  1102. if seconds == 0 { // Avoid dividing by 0
  1103. seconds++
  1104. }
  1105. metrics.TransactionsPerSecond = float64(nTxs) / seconds
  1106. // Set txs/batch
  1107. nBatches := p.ToBatchNum - p.FromBatchNum + 1
  1108. if nBatches == 0 { // Avoid dividing by 0
  1109. nBatches++
  1110. }
  1111. if (p.ToBatchNum - p.FromBatchNum) > 0 {
  1112. metrics.TransactionsPerBatch = float64(nTxs) /
  1113. float64(nBatches)
  1114. } else {
  1115. metrics.TransactionsPerBatch = 0
  1116. }
  1117. // Get total fee of that period
  1118. row = hdb.dbRead.QueryRow(
  1119. `SELECT COALESCE (SUM(total_fees_usd), 0) FROM batch WHERE batch_num between $1 AND $2;`,
  1120. p.FromBatchNum, p.ToBatchNum,
  1121. )
  1122. var totalFee float64
  1123. if err := row.Scan(&totalFee); err != nil {
  1124. return nil, 0, tracerr.Wrap(err)
  1125. }
  1126. // Set batch frequency
  1127. metrics.BatchFrequency = seconds / float64(nBatches)
  1128. // Set avg transaction fee (only L2 txs have fee)
  1129. row = hdb.dbRead.QueryRow(
  1130. `SELECT COUNT(*) as total_txs FROM tx WHERE tx.batch_num between $1 AND $2 AND NOT is_l1;`,
  1131. p.FromBatchNum, p.ToBatchNum,
  1132. )
  1133. var nL2Txs int
  1134. if err := row.Scan(&nL2Txs); err != nil {
  1135. return nil, 0, tracerr.Wrap(err)
  1136. }
  1137. if nL2Txs > 0 {
  1138. metrics.AvgTransactionFee = totalFee / float64(nL2Txs)
  1139. } else {
  1140. metrics.AvgTransactionFee = 0
  1141. }
  1142. // Get and set amount of registered accounts
  1143. type registeredAccounts struct {
  1144. TokenAccounts int64 `meddler:"token_accounts"`
  1145. Wallets int64 `meddler:"wallets"`
  1146. }
  1147. ra := &registeredAccounts{}
  1148. if err := meddler.QueryRow(
  1149. hdb.dbRead, ra,
  1150. `SELECT COUNT(*) AS token_accounts, COUNT(DISTINCT(bjj)) AS wallets FROM account;`,
  1151. ); err != nil {
  1152. return nil, 0, tracerr.Wrap(err)
  1153. }
  1154. metrics.TokenAccounts = ra.TokenAccounts
  1155. metrics.Wallets = ra.Wallets
  1156. // Get and set estimated time to forge L1 tx
  1157. row = hdb.dbRead.QueryRow(
  1158. `SELECT COALESCE (AVG(EXTRACT(EPOCH FROM (forged.timestamp - added.timestamp))), 0) FROM tx
  1159. INNER JOIN block AS added ON tx.eth_block_num = added.eth_block_num
  1160. INNER JOIN batch AS forged_batch ON tx.batch_num = forged_batch.batch_num
  1161. INNER JOIN block AS forged ON forged_batch.eth_block_num = forged.eth_block_num
  1162. WHERE tx.batch_num between $1 and $2 AND tx.is_l1 AND tx.user_origin;`,
  1163. p.FromBatchNum, p.ToBatchNum,
  1164. )
  1165. var timeToForgeL1 float64
  1166. if err := row.Scan(&timeToForgeL1); err != nil {
  1167. return nil, 0, tracerr.Wrap(err)
  1168. }
  1169. metrics.EstimatedTimeToForgeL1 = timeToForgeL1
  1170. // Get amount of txs in the pool
  1171. row = hdb.dbRead.QueryRow(
  1172. `SELECT COUNT(*) FROM tx_pool WHERE state = $1 AND NOT external_delete;`,
  1173. common.PoolL2TxStatePending,
  1174. )
  1175. if err := row.Scan(&poolLoad); err != nil {
  1176. return nil, 0, tracerr.Wrap(err)
  1177. }
  1178. return metrics, poolLoad, nil
  1179. }
  1180. // GetStateAPI returns the StateAPI
  1181. func (hdb *HistoryDB) GetStateAPI() (*StateAPI, error) {
  1182. cancel, err := hdb.apiConnCon.Acquire()
  1183. defer cancel()
  1184. if err != nil {
  1185. return nil, tracerr.Wrap(err)
  1186. }
  1187. defer hdb.apiConnCon.Release()
  1188. return hdb.getStateAPI(hdb.dbRead)
  1189. }