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.

1211 lines
36 KiB

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