Skip to content

Commit

Permalink
Add current pool gas to the node info endpoint (#2550)
Browse files Browse the repository at this point in the history
/
Add the information of the statistics of the pool on `node_info`
endpoint. Useful for trying to predicting tx block inclusion in some
cases
- [x] Breaking changes are clearly marked as such in the PR description
and changelog
- [x] New behavior is reflected in tests
- [x] [The specification](https://github.com/FuelLabs/fuel-specs/)
matches the implemented behavior (link update PR if changes are needed)
- [x] I have reviewed the code myself
- [x] I have created follow-up issues caused by this PR and linked them
here

[Add or remove entries as needed]

- [ ] [Rust SDK](https://github.com/FuelLabs/fuels-rs/)
- [ ] [Sway compiler](https://github.com/FuelLabs/sway/)
- [ ] [Platform
documentation](https://github.com/FuelLabs/devrel-requests/issues/new?assignees=&labels=new+request&projects=&template=NEW-REQUEST.yml&title=%5BRequest%5D%3A+)
(for out-of-organization contributors, the person merging the PR will do
this)
- [ ] Someone else?

---------

Co-authored-by: Green Baneling <[email protected]>
  • Loading branch information
AurelienFT and xgreenx committed Jan 15, 2025
1 parent ab12fb6 commit 8f21da6
Show file tree
Hide file tree
Showing 15 changed files with 252 additions and 10 deletions.
20 changes: 20 additions & 0 deletions crates/client/assets/schema.sdl
Original file line number Diff line number Diff line change
Expand Up @@ -751,8 +751,11 @@ type NodeInfo {
utxoValidation: Boolean!
vmBacktrace: Boolean!
maxTx: U64!
maxGas: U64!
maxSize: U64!
maxDepth: U64!
nodeVersion: String!
txPoolStats: TxPoolStats!
peers: [PeerInfo!]!
}

Expand Down Expand Up @@ -1259,6 +1262,23 @@ enum TxParametersVersion {

scalar TxPointer

type TxPoolStats {
"""
The number of transactions in the pool
"""
txCount: U64!
"""
The total size of the transactions in the pool
"""
totalSize: U64!
"""
The total gas of the transactions in the pool
"""
totalGas: U64!
}

scalar U128

scalar U16

scalar U32
Expand Down
11 changes: 11 additions & 0 deletions crates/client/src/client/schema/node_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ pub struct NodeInfo {
pub utxo_validation: bool,
pub vm_backtrace: bool,
pub max_tx: U64,
pub max_gas: U64,
pub max_size: U64,
pub max_depth: U64,
pub node_version: String,
pub tx_pool_stats: TxPoolStats,
}

#[derive(cynic::QueryFragment, Clone, Debug)]
Expand Down Expand Up @@ -77,6 +80,14 @@ impl From<PeerInfo> for fuel_core_types::services::p2p::PeerInfo {
}
}

#[derive(cynic::QueryFragment, Clone, Debug, PartialEq, Eq)]
#[cynic(schema_path = "./assets/schema.sdl")]
pub struct TxPoolStats {
pub tx_count: U64,
pub total_gas: U64,
pub total_size: U64,
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
---
source: crates/client/src/client/schema/node_info.rs
expression: operation.query
snapshot_kind: text
---
query {
nodeInfo {
utxoValidation
vmBacktrace
maxTx
maxGas
maxSize
maxDepth
nodeVersion
txPoolStats {
txCount
totalGas
totalSize
}
}
}

Expand Down
11 changes: 10 additions & 1 deletion crates/client/src/client/types/node_info.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
use crate::client::schema;
use crate::client::schema::{
self,
node_info::TxPoolStats,
};

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct NodeInfo {
pub utxo_validation: bool,
pub vm_backtrace: bool,
pub max_tx: u64,
pub max_gas: u64,
pub max_size: u64,
pub max_depth: u64,
pub node_version: String,
pub tx_pool_stats: TxPoolStats,
}

// GraphQL Translation
Expand All @@ -17,8 +23,11 @@ impl From<schema::node_info::NodeInfo> for NodeInfo {
utxo_validation: value.utxo_validation,
vm_backtrace: value.vm_backtrace,
max_tx: value.max_tx.into(),
max_gas: value.max_gas.into(),
max_size: value.max_size.into(),
max_depth: value.max_depth.into(),
node_version: value.node_version,
tx_pool_stats: value.tx_pool_stats,
}
}
}
2 changes: 2 additions & 0 deletions crates/fuel-core/src/graphql_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ pub struct Config {
pub debug: bool,
pub vm_backtrace: bool,
pub max_tx: usize,
pub max_gas: u64,
pub max_size: usize,
pub max_txpool_dependency_chain_length: usize,
pub chain_name: String,
}
Expand Down
7 changes: 6 additions & 1 deletion crates/fuel-core/src/graphql_api/ports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ use fuel_core_storage::{
StorageInspect,
StorageRead,
};
use fuel_core_txpool::TxStatusMessage;
use fuel_core_txpool::{
TxPoolStats,
TxStatusMessage,
};
use fuel_core_types::{
blockchain::{
block::CompressedBlock,
Expand Down Expand Up @@ -206,6 +209,8 @@ pub trait TxPoolPort: Send + Sync {
&self,
tx_id: TxId,
) -> anyhow::Result<BoxStream<TxStatusMessage>>;

fn latest_pool_stats(&self) -> TxPoolStats;
}

#[async_trait]
Expand Down
50 changes: 47 additions & 3 deletions crates/fuel-core/src/schema/node_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ use super::scalars::{
U32,
U64,
};
use crate::fuel_core_graphql_api::{
query_costs,
Config as GraphQLConfig,
use crate::{
fuel_core_graphql_api::{
query_costs,
Config as GraphQLConfig,
},
graphql_api::api_service::TxPool,
};
use async_graphql::{
Context,
Expand All @@ -16,6 +19,8 @@ pub struct NodeInfo {
utxo_validation: bool,
vm_backtrace: bool,
max_tx: U64,
max_gas: U64,
max_size: U64,
max_depth: U64,
node_version: String,
}
Expand All @@ -34,6 +39,14 @@ impl NodeInfo {
self.max_tx
}

async fn max_gas(&self) -> U64 {
self.max_gas
}

async fn max_size(&self) -> U64 {
self.max_size
}

async fn max_depth(&self) -> U64 {
self.max_depth
}
Expand All @@ -42,6 +55,15 @@ impl NodeInfo {
self.node_version.to_owned()
}

#[graphql(complexity = "query_costs().storage_read + child_complexity")]
async fn tx_pool_stats(
&self,
ctx: &Context<'_>,
) -> async_graphql::Result<TxPoolStats> {
let tx_pool = ctx.data_unchecked::<TxPool>();
Ok(TxPoolStats(tx_pool.latest_pool_stats()))
}

#[graphql(complexity = "query_costs().get_peers + child_complexity")]
async fn peers(&self, _ctx: &Context<'_>) -> async_graphql::Result<Vec<PeerInfo>> {
#[cfg(feature = "p2p")]
Expand Down Expand Up @@ -76,6 +98,8 @@ impl NodeQuery {
utxo_validation: config.utxo_validation,
vm_backtrace: config.vm_backtrace,
max_tx: (config.max_tx as u64).into(),
max_gas: config.max_gas.into(),
max_size: (config.max_size as u64).into(),
max_depth: (config.max_txpool_dependency_chain_length as u64).into(),
node_version: VERSION.to_owned(),
})
Expand Down Expand Up @@ -124,3 +148,23 @@ impl PeerInfo {
self.0.app_score
}
}

struct TxPoolStats(fuel_core_txpool::TxPoolStats);

#[Object]
impl TxPoolStats {
/// The number of transactions in the pool
async fn tx_count(&self) -> U64 {
self.0.tx_count.into()
}

/// The total size of the transactions in the pool
async fn total_size(&self) -> U64 {
self.0.total_size.into()
}

/// The total gas of the transactions in the pool
async fn total_gas(&self) -> U64 {
self.0.total_gas.into()
}
}
9 changes: 8 additions & 1 deletion crates/fuel-core/src/service/adapters/graphql_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ use crate::{
use async_trait::async_trait;
use fuel_core_services::stream::BoxStream;
use fuel_core_storage::Result as StorageResult;
use fuel_core_txpool::TxStatusMessage;
use fuel_core_txpool::{
TxPoolStats,
TxStatusMessage,
};
use fuel_core_types::{
blockchain::header::ConsensusParametersVersion,
entities::relayer::message::MerkleProof,
Expand Down Expand Up @@ -96,6 +99,10 @@ impl TxPoolPort for TxPoolAdapter {
) -> anyhow::Result<BoxStream<TxStatusMessage>> {
self.service.tx_update_subscribe(id)
}

fn latest_pool_stats(&self) -> TxPoolStats {
self.service.latest_stats()
}
}

impl DatabaseMessageProof for OnChainIterableKeyValueView {
Expand Down
2 changes: 2 additions & 0 deletions crates/fuel-core/src/service/sub_services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,8 @@ pub fn init_sub_services(
debug: config.debug,
vm_backtrace: config.vm.backtrace,
max_tx: config.txpool.pool_limits.max_txs,
max_gas: config.txpool.pool_limits.max_gas,
max_size: config.txpool.pool_limits.max_bytes_size,
max_txpool_dependency_chain_length: config.txpool.max_txs_chain_count,
chain_name,
};
Expand Down
1 change: 1 addition & 0 deletions crates/services/txpool_v2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ mod tests;
fuel_core_trace::enable_tracing!();

use fuel_core_types::fuel_asm::Word;
pub use pool::TxPoolStats;
pub use selection_algorithms::Constraints;
pub use service::{
new_service,
Expand Down
38 changes: 36 additions & 2 deletions crates/services/txpool_v2/src/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ use crate::{
},
};

#[cfg(test)]
use std::collections::HashSet;

#[derive(Debug, Clone, Copy, Default)]
pub struct TxPoolStats {
pub tx_count: u64,
pub total_size: u64,
pub total_gas: u64,
}

/// The pool is the main component of the txpool service. It is responsible for storing transactions
/// and allowing the selection of transactions for inclusion in a block.
pub struct Pool<S, SI, CM, SA> {
Expand All @@ -59,6 +69,8 @@ pub struct Pool<S, SI, CM, SA> {
pub(crate) current_gas: u64,
/// Current pool size in bytes.
pub(crate) current_bytes_size: usize,
/// The current pool gas.
pub(crate) pool_stats_sender: tokio::sync::watch::Sender<TxPoolStats>,
}

impl<S, SI, CM, SA> Pool<S, SI, CM, SA> {
Expand All @@ -68,6 +80,7 @@ impl<S, SI, CM, SA> Pool<S, SI, CM, SA> {
collision_manager: CM,
selection_algorithm: SA,
config: Config,
pool_stats_sender: tokio::sync::watch::Sender<TxPoolStats>,
) -> Self {
Pool {
storage,
Expand All @@ -77,6 +90,7 @@ impl<S, SI, CM, SA> Pool<S, SI, CM, SA> {
tx_id_to_storage_id: HashMap::new(),
current_gas: 0,
current_bytes_size: 0,
pool_stats_sender,
}
}

Expand Down Expand Up @@ -157,10 +171,18 @@ where
.into_iter()
.map(|data| data.transaction)
.collect::<Vec<_>>();

self.update_stats();
Ok(removed_transactions)
}

fn update_stats(&self) {
let _ = self.pool_stats_sender.send(TxPoolStats {
tx_count: self.tx_count() as u64,
total_size: self.current_bytes_size as u64,
total_gas: self.current_gas,
});
}

/// Check if a transaction can be inserted into the pool.
pub fn can_insert_transaction(
&self,
Expand Down Expand Up @@ -244,7 +266,11 @@ where

storage_entry.transaction
})
.collect::<Vec<_>>()
.collect::<Vec<_>>();

self.update_stats();

txs
}

pub fn find_one(&self, tx_id: &TxId) -> Option<&StorageData> {
Expand Down Expand Up @@ -292,6 +318,8 @@ where
self.update_components_and_caches_on_removal(iter::once(&transaction));
}
}

self.update_stats();
}

/// Check if the pool has enough space to store a transaction.
Expand Down Expand Up @@ -443,6 +471,9 @@ where
.extend(removed.into_iter().map(|data| data.transaction));
}
}

self.update_stats();

removed_transactions
}

Expand All @@ -456,6 +487,9 @@ where
self.update_components_and_caches_on_removal(removed.iter());
txs_removed.extend(removed.into_iter().map(|data| data.transaction));
}

self.update_stats();

txs_removed
}

Expand Down
Loading

0 comments on commit 8f21da6

Please sign in to comment.