Skip to content

Commit

Permalink
Merge pull request #2603 from eqlabs/sistemd/configurable-fee-estimat…
Browse files Browse the repository at this point in the history
…ion-epsilon

feat(execution): add fee estimation EPSILON as a CLI param
  • Loading branch information
sistemd authored Feb 18, 2025
2 parents 8b82f1c + 2ca4ff0 commit 8f07667
Show file tree
Hide file tree
Showing 21 changed files with 207 additions and 6 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ metrics-exporter-prometheus = "0.11.0"
mime = "0.3"
mockall = "0.11.4"
num-bigint = "0.4.4"
num-traits = "0.2.19"
paste = "1.0.14"
pretty_assertions_sorted = "1.2.3"
primitive-types = "0.12.1"
Expand Down
1 change: 1 addition & 0 deletions crates/executor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ starknet-types-core = { workspace = true }
starknet_api = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
util = { path = "../util" }
3 changes: 3 additions & 0 deletions crates/executor/src/estimate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use blockifier::transaction::transaction_execution::Transaction;
use pathfinder_common::TransactionHash;
use starknet_api::block::FeeType;
use starknet_api::transaction::fields::GasVectorComputationMode;
use util::percentage::Percentage;

use super::error::TransactionExecutionError;
use super::execution_state::ExecutionState;
Expand All @@ -18,6 +19,7 @@ use crate::IntoFelt;
pub fn estimate(
execution_state: ExecutionState<'_>,
transactions: Vec<Transaction>,
epsilon: Percentage,
) -> Result<Vec<FeeEstimate>, TransactionExecutionError> {
let block_number = execution_state.header.number;

Expand Down Expand Up @@ -48,6 +50,7 @@ pub fn estimate(
&mut state,
&block_context,
ExecutionBehaviorOnRevert::Fail,
epsilon,
)?
} else {
execute_transaction(
Expand Down
3 changes: 3 additions & 0 deletions crates/executor/src/simulate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use pathfinder_common::{
TransactionHash,
};
use starknet_api::transaction::fields::GasVectorComputationMode;
use util::percentage::Percentage;

use super::error::TransactionExecutionError;
use super::execution_state::ExecutionState;
Expand Down Expand Up @@ -86,6 +87,7 @@ impl Default for TraceCache {
pub fn simulate(
execution_state: ExecutionState<'_>,
transactions: Vec<Transaction>,
epsilon: Percentage,
) -> Result<Vec<TransactionSimulation>, TransactionExecutionError> {
let block_number = execution_state.header.number;

Expand Down Expand Up @@ -117,6 +119,7 @@ pub fn simulate(
&mut tx_state,
&block_context,
ExecutionBehaviorOnRevert::Continue,
epsilon,
)?
} else {
execute_transaction(&tx, tx_index, &mut tx_state, &block_context, &ExecutionBehaviorOnRevert::Continue)?
Expand Down
6 changes: 4 additions & 2 deletions crates/executor/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use blockifier::transaction::transactions::ExecutableTransaction;
use starknet_api::core::ClassHash;
use starknet_api::execution_resources::GasAmount;
use starknet_api::transaction::fields::GasVectorComputationMode;
use util::percentage::Percentage;

use crate::TransactionExecutionError;

Expand Down Expand Up @@ -119,6 +120,7 @@ pub(crate) fn find_l2_gas_limit_and_execute_transaction<S>(
state: &mut S,
block_context: &blockifier::context::BlockContext,
revert_behavior: ExecutionBehaviorOnRevert,
epsilon: Percentage,
) -> Result<TransactionExecutionInfo, TransactionExecutionError>
where
S: UpdatableState,
Expand All @@ -142,8 +144,8 @@ where

let GasAmount(l2_gas_consumed) = tx_info.receipt.gas.l2_gas;

// Add a 10% buffer to the actual L2 gas fee.
let l2_gas_adjusted = GasAmount(l2_gas_consumed.saturating_add(l2_gas_consumed / 10));
// Add a buffer (in terms of %) to the actual L2 gas fee.
let l2_gas_adjusted = GasAmount(l2_gas_consumed.saturating_add(epsilon.of(l2_gas_consumed)));
set_l2_gas_limit(tx, l2_gas_adjusted);

let (l2_gas_limit, mut tx_info, tx_state) =
Expand Down
3 changes: 2 additions & 1 deletion crates/pathfinder/examples/re_execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use pathfinder_executor::ExecutionState;
use pathfinder_rpc::context::{ETH_FEE_TOKEN_ADDRESS, STRK_FEE_TOKEN_ADDRESS};
use pathfinder_storage::{BlockId, Storage};
use rayon::prelude::*;
use util::percentage::Percentage;

// The Cairo VM allocates felts on the stack, so during execution it's making
// a huge number of allocations. We get roughly two times better execution
Expand Down Expand Up @@ -157,7 +158,7 @@ fn execute(storage: &mut Storage, chain_id: ChainId, work: Work) {
}
};

match pathfinder_executor::simulate(execution_state, transactions) {
match pathfinder_executor::simulate(execution_state, transactions, Percentage::new(10)) {
Ok(simulations) => {
for (simulation, (receipt, transaction)) in simulations
.iter()
Expand Down
30 changes: 30 additions & 0 deletions crates/pathfinder/src/bin/pathfinder/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use pathfinder_common::AllowedOrigins;
use pathfinder_executor::VersionedConstants;
use pathfinder_storage::JournalMode;
use reqwest::Url;
use util::percentage::Percentage;

#[derive(Parser)]
#[command(name = "Pathfinder")]
Expand Down Expand Up @@ -324,6 +325,18 @@ This should only be enabled for debugging purposes as it adds substantial proces
default_value = "10"
)]
shutdown_grace_period: std::num::NonZeroU64,

#[arg(
long = "rpc.fee-estimation-epsilon",
value_name = "Percentage",
long_help = "Acceptable overhead to add on top of consumed L2 gas (g) during fee estimation (`estimateFee` and `simulate` RPC methods). \
Setting a lower value gives a more precise fee estimation (in terms of L2 gas) but runs a higher risk of having to resort to a binary \
search if the initial L2 gas limit (`g + (g * EPSILON/100)`) is insufficient.",
env = "PATHFINDER_RPC_FEE_ESTIMATION_EPSILON",
default_value = "10",
value_parser = parse_fee_estimation_epsilon
)]
fee_estimation_epsilon: Percentage,
}

#[derive(clap::ValueEnum, Debug, Clone, Copy, PartialEq)]
Expand Down Expand Up @@ -372,6 +385,21 @@ fn parse_state_tries(s: &str) -> Result<StateTries, String> {
}
}

fn parse_fee_estimation_epsilon(s: &str) -> Result<Percentage, String> {
let value: u8 = s
.parse()
.map_err(|_| "Expected a number (u8)".to_string())
.and_then(|value| {
if value > 100 {
Err("Expected a number between 0 and 100".to_string())
} else {
Ok(value)
}
})?;

Ok(Percentage::new(value))
}

#[derive(clap::Args)]
struct NetworkCli {
#[arg(
Expand Down Expand Up @@ -735,6 +763,7 @@ pub struct Config {
pub feeder_gateway_fetch_concurrency: NonZeroUsize,
pub fetch_casm_from_fgw: bool,
pub shutdown_grace_period: Duration,
pub fee_estimation_epsilon: Percentage,
}

pub struct Ethereum {
Expand Down Expand Up @@ -1030,6 +1059,7 @@ impl Config {
.map(parse_versioned_constants_or_exit),
fetch_casm_from_fgw: cli.fetch_casm_from_fgw,
shutdown_grace_period: Duration::from_secs(cli.shutdown_grace_period.get()),
fee_estimation_epsilon: cli.fee_estimation_epsilon,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/pathfinder/src/bin/pathfinder/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ Hint: This is usually caused by exceeding the file descriptor limit of your syst
get_events_max_blocks_to_scan: config.get_events_max_blocks_to_scan,
get_events_max_uncached_event_filters_to_load: config
.get_events_max_uncached_event_filters_to_load,
fee_estimation_epsilon: config.fee_estimation_epsilon,
custom_versioned_constants: config.custom_versioned_constants.take(),
};

Expand Down
3 changes: 3 additions & 0 deletions crates/rpc/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use pathfinder_ethereum::EthereumClient;
use pathfinder_executor::{TraceCache, VersionedConstants};
use pathfinder_storage::Storage;
use primitive_types::{H160, H256};
use util::percentage::Percentage;

pub use crate::jsonrpc::websocket::WebsocketContext;
use crate::jsonrpc::Notifications;
Expand Down Expand Up @@ -68,6 +69,7 @@ pub struct RpcConfig {
pub batch_concurrency_limit: NonZeroUsize,
pub get_events_max_blocks_to_scan: NonZeroUsize,
pub get_events_max_uncached_event_filters_to_load: NonZeroUsize,
pub fee_estimation_epsilon: Percentage,
pub custom_versioned_constants: Option<VersionedConstants>,
}

Expand Down Expand Up @@ -169,6 +171,7 @@ impl RpcContext {
batch_concurrency_limit: NonZeroUsize::new(8).unwrap(),
get_events_max_blocks_to_scan: NonZeroUsize::new(1000).unwrap(),
get_events_max_uncached_event_filters_to_load: NonZeroUsize::new(1000).unwrap(),
fee_estimation_epsilon: Percentage::new(10),
custom_versioned_constants: None,
};

Expand Down
1 change: 1 addition & 0 deletions crates/rpc/src/jsonrpc/router/subscription.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,7 @@ mod tests {
batch_concurrency_limit: 1.try_into().unwrap(),
get_events_max_blocks_to_scan: 1.try_into().unwrap(),
get_events_max_uncached_event_filters_to_load: 1.try_into().unwrap(),
fee_estimation_epsilon: Default::default(),
custom_versioned_constants: None,
},
};
Expand Down
6 changes: 5 additions & 1 deletion crates/rpc/src/method/estimate_fee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,11 @@ pub async fn estimate_fee(context: RpcContext, input: Input) -> Result<Output, E
})
.collect::<Result<Vec<_>, _>>()?;

let result = pathfinder_executor::estimate(state, transactions)?;
let result = pathfinder_executor::estimate(
state,
transactions,
context.config.fee_estimation_epsilon,
)?;

Ok::<_, EstimateFeeError>(result)
})
Expand Down
6 changes: 5 additions & 1 deletion crates/rpc/src/method/estimate_message_fee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,11 @@ pub async fn estimate_message_fee(

let transaction = create_executor_transaction(input, context.chain_id)?;

let result = pathfinder_executor::estimate(state, vec![transaction])?;
let result = pathfinder_executor::estimate(
state,
vec![transaction],
context.config.fee_estimation_epsilon,
)?;

Ok::<_, EstimateMessageFeeError>(result)
})
Expand Down
6 changes: 5 additions & 1 deletion crates/rpc/src/method/simulate_transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,11 @@ pub async fn simulate_transactions(
})
.collect::<Result<Vec<_>, _>>()?;

let txs = pathfinder_executor::simulate(state, transactions)?;
let txs = pathfinder_executor::simulate(
state,
transactions,
context.config.fee_estimation_epsilon,
)?;
Ok(Output(txs))
})
.await
Expand Down
1 change: 1 addition & 0 deletions crates/rpc/src/method/subscribe_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,7 @@ mod tests {
batch_concurrency_limit: 64.try_into().unwrap(),
get_events_max_blocks_to_scan: 1024.try_into().unwrap(),
get_events_max_uncached_event_filters_to_load: 1.try_into().unwrap(),
fee_estimation_epsilon: Default::default(),
custom_versioned_constants: None,
},
};
Expand Down
1 change: 1 addition & 0 deletions crates/rpc/src/method/subscribe_new_heads.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,7 @@ mod tests {
batch_concurrency_limit: 1.try_into().unwrap(),
get_events_max_blocks_to_scan: 1.try_into().unwrap(),
get_events_max_uncached_event_filters_to_load: 1.try_into().unwrap(),
fee_estimation_epsilon: Default::default(),
custom_versioned_constants: None,
},
};
Expand Down
1 change: 1 addition & 0 deletions crates/rpc/src/method/subscribe_pending_transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,7 @@ mod tests {
batch_concurrency_limit: 1.try_into().unwrap(),
get_events_max_blocks_to_scan: 1.try_into().unwrap(),
get_events_max_uncached_event_filters_to_load: 1.try_into().unwrap(),
fee_estimation_epsilon: Default::default(),
custom_versioned_constants: None,
},
};
Expand Down
1 change: 1 addition & 0 deletions crates/rpc/src/method/subscribe_transaction_status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1156,6 +1156,7 @@ mod tests {
batch_concurrency_limit: 1.try_into().unwrap(),
get_events_max_blocks_to_scan: 1.try_into().unwrap(),
get_events_max_uncached_event_filters_to_load: 1.try_into().unwrap(),
fee_estimation_epsilon: Default::default(),
custom_versioned_constants: None,
},
};
Expand Down
1 change: 1 addition & 0 deletions crates/util/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ rust-version = { workspace = true }

[dependencies]
anyhow = { workspace = true }
num-traits = { workspace = true }
tokio = { workspace = true }
tokio-stream = { workspace = true }
tokio-util = { workspace = true }
Expand Down
1 change: 1 addition & 0 deletions crates/util/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
pub mod error;
pub mod make_stream;
pub mod percentage;
pub mod task;
Loading

0 comments on commit 8f07667

Please sign in to comment.