From a10fc80509ac522a0ca11a7a24019c573cd03c52 Mon Sep 17 00:00:00 2001 From: Arni Hod Date: Thu, 19 Dec 2024 13:46:53 +0200 Subject: [PATCH] feat(starknet_gateway): create transaction generator towards benchmarking --- Cargo.lock | 2 + crates/starknet_gateway/Cargo.toml | 2 +- .../starknet_gateway/bench/gateway_bench.rs | 11 ++- crates/starknet_gateway/src/lib.rs | 4 +- crates/starknet_gateway/src/test_utils.rs | 2 + .../src/test_utils/bench_test_setup.rs | 75 +++++++++++++++++++ 6 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 crates/starknet_gateway/src/test_utils/bench_test_setup.rs diff --git a/Cargo.lock b/Cargo.lock index 232eb908db2..5a86f71d740 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2875,6 +2875,7 @@ dependencies = [ "ciborium", "clap", "criterion-plot", + "futures", "is-terminal", "itertools 0.10.5", "num-traits 0.2.19", @@ -2887,6 +2888,7 @@ dependencies = [ "serde_derive", "serde_json", "tinytemplate", + "tokio", "walkdir", ] diff --git a/crates/starknet_gateway/Cargo.toml b/crates/starknet_gateway/Cargo.toml index 8d5999f6810..016f692971e 100644 --- a/crates/starknet_gateway/Cargo.toml +++ b/crates/starknet_gateway/Cargo.toml @@ -39,7 +39,7 @@ validator.workspace = true [dev-dependencies] assert_matches.workspace = true cairo-lang-sierra-to-casm.workspace = true -criterion = { workspace = true, features = ["html_reports"] } +criterion = { workspace = true, features = ["html_reports", "async_tokio"] } mockall.workspace = true mockito.workspace = true num-bigint.workspace = true diff --git a/crates/starknet_gateway/bench/gateway_bench.rs b/crates/starknet_gateway/bench/gateway_bench.rs index a28f74db34a..d0878749375 100644 --- a/crates/starknet_gateway/bench/gateway_bench.rs +++ b/crates/starknet_gateway/bench/gateway_bench.rs @@ -9,7 +9,8 @@ //! //! Run the benchmarks using `cargo bench --bench gateway_bench`. -use criterion::{criterion_group, criterion_main, Criterion}; +use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; +use starknet_gateway::test_utils::bench_test_setup::{BenchTestSetup, BenchTestSetupConfig}; pub fn declare_benchmark(c: &mut Criterion) { c.bench_function("declares", |benchmark| benchmark.iter(|| {})); @@ -20,7 +21,13 @@ pub fn deploy_account_benchmark(c: &mut Criterion) { } pub fn invoke_benchmark(c: &mut Criterion) { - c.bench_function("invokes", |benchmark| benchmark.iter(|| {})); + let n_txs = 100; + let tx_generator_config = BenchTestSetupConfig { n_txs, ..Default::default() }; + + let test_setup = BenchTestSetup::new(tx_generator_config); + c.bench_with_input(BenchmarkId::new("invoke", n_txs), &test_setup, |b, s| { + b.to_async(tokio::runtime::Runtime::new().unwrap()).iter(|| s.send_txs_to_gateway()); + }); } pub fn gateway_benchmark(c: &mut Criterion) { diff --git a/crates/starknet_gateway/src/lib.rs b/crates/starknet_gateway/src/lib.rs index 057e1cef10c..98b7510d470 100644 --- a/crates/starknet_gateway/src/lib.rs +++ b/crates/starknet_gateway/src/lib.rs @@ -14,6 +14,6 @@ mod state_reader_test_utils; mod stateful_transaction_validator; mod stateless_transaction_validator; mod sync_state_reader; -#[cfg(test)] -mod test_utils; +#[cfg(any(feature = "testing", test))] +pub mod test_utils; mod utils; diff --git a/crates/starknet_gateway/src/test_utils.rs b/crates/starknet_gateway/src/test_utils.rs index f92bb5bce8e..55121fb6443 100644 --- a/crates/starknet_gateway/src/test_utils.rs +++ b/crates/starknet_gateway/src/test_utils.rs @@ -21,6 +21,8 @@ use starknet_types_core::felt::Felt; use crate::compiler_version::VersionId; +pub mod bench_test_setup; + pub const NON_EMPTY_RESOURCE_BOUNDS: ResourceBounds = ResourceBounds { max_amount: GasAmount(1), max_price_per_unit: GasPrice(1) }; diff --git a/crates/starknet_gateway/src/test_utils/bench_test_setup.rs b/crates/starknet_gateway/src/test_utils/bench_test_setup.rs new file mode 100644 index 00000000000..e5b94a423d8 --- /dev/null +++ b/crates/starknet_gateway/src/test_utils/bench_test_setup.rs @@ -0,0 +1,75 @@ +use std::sync::Arc; + +use blockifier::test_utils::contracts::FeatureContract; +use blockifier::test_utils::CairoVersion; +use mempool_test_utils::starknet_api_test_utils::MultiAccountTransactionGenerator; +use starknet_api::rpc_transaction::RpcTransaction; +use starknet_mempool_types::communication::MockMempoolClient; +use starknet_sierra_compile::config::SierraToCasmCompilationConfig; + +use crate::compilation::GatewayCompiler; +use crate::config::{GatewayConfig, RpcStateReaderConfig}; +use crate::gateway::Gateway; +use crate::rpc_state_reader::RpcStateReaderFactory; + +const N_TXS: usize = 1000; + +pub struct BenchTestSetupConfig { + pub n_txs: usize, + pub gateway_config: GatewayConfig, + pub rpc_state_reader_config: RpcStateReaderConfig, + pub compiler_config: SierraToCasmCompilationConfig, +} + +impl Default for BenchTestSetupConfig { + fn default() -> Self { + Self { + n_txs: N_TXS, + gateway_config: GatewayConfig::default(), + rpc_state_reader_config: RpcStateReaderConfig::default(), + compiler_config: SierraToCasmCompilationConfig::default(), + } + } +} + +pub struct BenchTestSetup { + gateway: Gateway, + txs: Vec, +} + +impl BenchTestSetup { + pub fn new(config: BenchTestSetupConfig) -> Self { + // TODO(Arni): Register accounts see [`register_account_for_flow_test`]. + let mut tx_generator = MultiAccountTransactionGenerator::new(); + let default_account = FeatureContract::AccountWithoutValidations(CairoVersion::Cairo0); + + tx_generator.register_account(default_account); + + let mut txs: Vec = Vec::with_capacity(config.n_txs); + for _ in 0..config.n_txs { + txs.push(tx_generator.account_with_id(0). + // TODO(Arni): Do something smarter than generate raw invoke. + generate_raw_invoke(Default::default())); + } + + let state_reader_factory = + Arc::new(RpcStateReaderFactory { config: config.rpc_state_reader_config.clone() }); + let gateway_compiler = + GatewayCompiler::new_command_line_compiler(config.compiler_config.clone()); + let mempool_client = Arc::new(MockMempoolClient::new()); + let gateway = Gateway::new( + config.gateway_config.clone(), + state_reader_factory, + gateway_compiler, + mempool_client, + ); + + Self { gateway, txs } + } + + pub async fn send_txs_to_gateway(&self) { + for tx in &self.txs { + let _tx_hash = self.gateway.add_tx(tx.clone(), None).await; + } + } +}