Skip to content

Commit

Permalink
Merge branch 'master' into metrics-grpahql-coplexity
Browse files Browse the repository at this point in the history
  • Loading branch information
xgreenx authored Oct 14, 2024
2 parents 8ed4ed8 + 7528047 commit 7d6349d
Show file tree
Hide file tree
Showing 26 changed files with 473 additions and 130 deletions.
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,18 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]
### Added
- [2350](https://github.com/FuelLabs/fuel-core/pull/2350): Added a new CLI flag `graphql-number-of-threads` to limit the number of threads used by the GraphQL service. The default value is `2`, `0` enables the old behavior.

### Changed
### Fixed
- [2345](https://github.com/FuelLabs/fuel-core/pull/2345): In PoA increase priority of block creation timer trigger compare to txpool event management

### Changed
- [2334](https://github.com/FuelLabs/fuel-core/pull/2334): Prepare the GraphQL service for the switching to `async` methods.
- [2350](https://github.com/FuelLabs/fuel-core/pull/2350): Limited the number of threads used by the GraphQL service.

### Added
- [2335](https://github.com/FuelLabs/fuel-core/pull/2335): Added CLI arguments for configuring GraphQL query costs.

### Added
- [2347](https://github.com/FuelLabs/fuel-core/pull/2347): Add GraphQL complexity histogram
Expand Down
25 changes: 25 additions & 0 deletions bin/fuel-core/src/cli/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use fuel_core::{
},
fuel_core_graphql_api::{
worker_service::DaCompressionConfig,
Costs,
ServiceConfig as GraphQLConfig,
},
producer::Config as ProducerConfig,
Expand Down Expand Up @@ -488,6 +489,7 @@ impl Command {
let config = Config {
graphql_config: GraphQLConfig {
addr,
number_of_threads: graphql.graphql_number_of_threads,
max_queries_depth: graphql.graphql_max_depth,
max_queries_complexity: graphql.graphql_max_complexity,
max_queries_recursive_depth: graphql.graphql_max_recursive_depth,
Expand All @@ -498,6 +500,29 @@ impl Command {
request_body_bytes_limit: graphql.graphql_request_body_bytes_limit,
api_request_timeout: graphql.api_request_timeout.into(),
query_log_threshold_time: graphql.query_log_threshold_time.into(),
costs: Costs {
balance_query: graphql.costs.balance_query,
coins_to_spend: graphql.costs.coins_to_spend,
get_peers: graphql.costs.get_peers,
estimate_predicates: graphql.costs.estimate_predicates,
dry_run: graphql.costs.dry_run,
submit: graphql.costs.submit,
submit_and_await: graphql.costs.submit_and_await,
status_change: graphql.costs.status_change,
storage_read: graphql.costs.storage_read,
tx_get: graphql.costs.tx_get,
tx_status_read: graphql.costs.tx_status_read,
tx_raw_payload: graphql.costs.tx_raw_payload,
block_header: graphql.costs.block_header,
block_transactions: graphql.costs.block_transactions,
block_transactions_ids: graphql.costs.block_transactions_ids,
storage_iterator: graphql.costs.storage_iterator,
bytecode_read: graphql.costs.bytecode_read,
state_transition_bytecode_read: graphql
.costs
.state_transition_bytecode_read,
da_compressed_block_read: graphql.costs.da_compressed_block_read,
},
},
combined_db_config,
snapshot_reader,
Expand Down
164 changes: 164 additions & 0 deletions bin/fuel-core/src/cli/run/graphql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
use std::net;

use fuel_core::fuel_core_graphql_api::DEFAULT_QUERY_COSTS;

#[derive(Debug, Clone, clap::Args)]
pub struct GraphQLArgs {
/// The IP address to bind the GraphQL service to.
Expand All @@ -12,6 +14,10 @@ pub struct GraphQLArgs {
#[clap(long = "port", default_value = "4000", env)]
pub port: u16,

/// The number of threads to use for the GraphQL service.
#[clap(long = "graphql-number-of-threads", default_value = "2", env)]
pub graphql_number_of_threads: usize,

/// The max depth of GraphQL queries.
#[clap(long = "graphql-max-depth", default_value = "16", env)]
pub graphql_max_depth: usize,
Expand Down Expand Up @@ -55,4 +61,162 @@ pub struct GraphQLArgs {
/// Timeout before drop the request.
#[clap(long = "api-request-timeout", default_value = "30s", env)]
pub api_request_timeout: humantime::Duration,

#[clap(flatten)]
pub costs: QueryCosts,
}

/// Costs for individual graphql queries.
#[derive(Debug, Clone, clap::Args)]
pub struct QueryCosts {
/// Query costs for getting balances.
#[clap(
long = "query-cost-balance-query",
default_value = DEFAULT_QUERY_COSTS.balance_query.to_string(),
env
)]
pub balance_query: usize,

/// Query costs for getting coins to spend.
#[clap(
long = "query-cost-coins-to-spend",
default_value = DEFAULT_QUERY_COSTS.coins_to_spend.to_string(),
env)]
pub coins_to_spend: usize,

/// Query costs for getting peers.
#[clap(
long = "query-cost-get-peers",
default_value = DEFAULT_QUERY_COSTS.get_peers.to_string(),
env
)]
pub get_peers: usize,

/// Query costs for estimating predicates.
#[clap(
long = "query-cost-estimate-predicates",
default_value = DEFAULT_QUERY_COSTS.estimate_predicates.to_string(),
env
)]
pub estimate_predicates: usize,

/// Query costs for dry running a set of transactions.
#[clap(
long = "query-cost-dry-run",
default_value = DEFAULT_QUERY_COSTS.dry_run.to_string(),
env
)]
pub dry_run: usize,

/// Query costs for submitting a transaction.
#[clap(
long = "query-cost-submit",
default_value = DEFAULT_QUERY_COSTS.submit.to_string(),
env
)]
pub submit: usize,

/// Query costs for submitting and awaiting a transaction.
#[clap(
long = "query-cost-submit-and-await",
default_value = DEFAULT_QUERY_COSTS.submit_and_await.to_string(),
env
)]
pub submit_and_await: usize,

/// Query costs for the status change query.
#[clap(
long = "query-cost-status-change",
default_value = DEFAULT_QUERY_COSTS.status_change.to_string(),
env
)]
pub status_change: usize,

/// Query costs for reading from storage.
#[clap(
long = "query-cost-storage-read",
default_value = DEFAULT_QUERY_COSTS.storage_read.to_string(),
env
)]
pub storage_read: usize,

/// Query costs for getting a transaction.
#[clap(
long = "query-cost-tx-get",
default_value = DEFAULT_QUERY_COSTS.tx_get.to_string(),
env
)]
pub tx_get: usize,

/// Query costs for reading tx status.
#[clap(
long = "query-cost-tx-status-read",
default_value = DEFAULT_QUERY_COSTS.tx_status_read.to_string(),
env
)]
pub tx_status_read: usize,

/// Query costs for getting the raw tx payload.
#[clap(
long = "query-cost-tx-raw-payload",
default_value = DEFAULT_QUERY_COSTS.tx_raw_payload.to_string(),
env
)]
pub tx_raw_payload: usize,

/// Query costs for block header.
#[clap(
long = "query-cost-block-header",
default_value = DEFAULT_QUERY_COSTS.block_header.to_string(),
env
)]
pub block_header: usize,

/// Query costs for block transactions.
#[clap(
long = "query-cost-block-transactions",
default_value = DEFAULT_QUERY_COSTS.block_transactions.to_string(),
env
)]
pub block_transactions: usize,

/// Query costs for block transactions ids.
#[clap(
long = "query-cost-block-transactions-ids",
default_value = DEFAULT_QUERY_COSTS.block_transactions_ids.to_string(),
env
)]
pub block_transactions_ids: usize,

/// Query costs for iterating over storage entries.
#[clap(
long = "query-cost-storage-iterator",
default_value = DEFAULT_QUERY_COSTS.storage_iterator.to_string(),
env
)]
pub storage_iterator: usize,

/// Query costs for reading bytecode.
#[clap(
long = "query-cost-bytecode-read",
default_value = DEFAULT_QUERY_COSTS.bytecode_read.to_string(),
env
)]
pub bytecode_read: usize,

/// Query costs for reading state transition bytecode.
#[clap(
long = "query-cost-state-transition-bytecode-read",
default_value = DEFAULT_QUERY_COSTS.state_transition_bytecode_read.to_string(),
env
)]
pub state_transition_bytecode_read: usize,

/// Query costs for reading a DA compressed block.
#[clap(
long = "query-cost-da-compressed-block-read",
default_value = DEFAULT_QUERY_COSTS.da_compressed_block_read.to_string(),
env
)]
pub da_compressed_block_read: usize,
}
56 changes: 42 additions & 14 deletions crates/fuel-core/src/graphql_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use fuel_core_storage::{
};
use std::{
net::SocketAddr,
sync::OnceLock,
time::Duration,
};

Expand All @@ -17,9 +18,21 @@ pub(crate) mod validation_extension;
pub(crate) mod view_extension;
pub mod worker_service;

#[derive(Clone, Debug)]
pub struct Config {
pub config: ServiceConfig,
pub utxo_validation: bool,
pub debug: bool,
pub vm_backtrace: bool,
pub max_tx: usize,
pub max_txpool_dependency_chain_length: usize,
pub chain_name: String,
}

#[derive(Clone, Debug)]
pub struct ServiceConfig {
pub addr: SocketAddr,
pub number_of_threads: usize,
pub max_queries_depth: usize,
pub max_queries_complexity: usize,
pub max_queries_recursive_depth: usize,
Expand All @@ -30,8 +43,11 @@ pub struct ServiceConfig {
/// Time to wait after submitting a query before debug info will be logged about query.
pub query_log_threshold_time: Duration,
pub api_request_timeout: Duration,
/// Configurable cost parameters to limit graphql queries complexity
pub costs: Costs,
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Costs {
pub balance_query: usize,
pub coins_to_spend: usize,
Expand All @@ -54,16 +70,19 @@ pub struct Costs {
pub da_compressed_block_read: usize,
}

pub const QUERY_COSTS: Costs = Costs {
// balance_query: 4000,
#[cfg(feature = "test-helpers")]
impl Default for Costs {
fn default() -> Self {
DEFAULT_QUERY_COSTS
}
}

pub const DEFAULT_QUERY_COSTS: Costs = Costs {
balance_query: 40001,
coins_to_spend: 40001,
// get_peers: 2000,
get_peers: 40001,
// estimate_predicates: 3000,
estimate_predicates: 40001,
dry_run: 12000,
// submit: 5000,
submit: 40001,
submit_and_await: 40001,
status_change: 40001,
Expand All @@ -80,15 +99,24 @@ pub const QUERY_COSTS: Costs = Costs {
da_compressed_block_read: 4000,
};

#[derive(Clone, Debug)]
pub struct Config {
pub config: ServiceConfig,
pub utxo_validation: bool,
pub debug: bool,
pub vm_backtrace: bool,
pub max_tx: usize,
pub max_txpool_dependency_chain_length: usize,
pub chain_name: String,
pub fn query_costs() -> &'static Costs {
QUERY_COSTS.get().unwrap_or(&DEFAULT_QUERY_COSTS)
}

pub static QUERY_COSTS: OnceLock<Costs> = OnceLock::new();

fn initialize_query_costs(costs: Costs) -> anyhow::Result<()> {
#[cfg(feature = "test-helpers")]
if costs != DEFAULT_QUERY_COSTS {
// We don't support setting these values in test contexts, because
// it can lead to unexpected behavior if multiple tests try to
// initialize different values.
anyhow::bail!("cannot initialize queries with non-default costs in tests")
}

QUERY_COSTS.get_or_init(|| costs);

Ok(())
}

pub trait IntoApiResult<T> {
Expand Down
Loading

0 comments on commit 7d6349d

Please sign in to comment.