From bed07cc6d92617b4be29a0234943c67dbb6e89e6 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Thu, 22 Feb 2024 11:57:48 +0200 Subject: [PATCH 01/45] Add reporting to goose shoot and improve error handling --- README.md | 32 +++++- config/default.yaml | 2 +- config/katana.yaml | 2 +- config/sharingan.yaml | 2 +- config/v2.1.0.yaml | 2 +- src/actions/goose.rs | 183 ++++++++++++++++++++++++------- src/actions/mod.rs | 74 ++++++++++++- src/config.rs | 2 +- src/metrics.rs | 248 ++++++++++++++++++++++++++---------------- src/utils.rs | 104 ++++++------------ 10 files changed, 438 insertions(+), 213 deletions(-) diff --git a/README.md b/README.md index e427ea0..98a4c3e 100644 --- a/README.md +++ b/README.md @@ -85,11 +85,12 @@ The configuration is defined by the following spec - `num_erc20_transfers`: Number of ERC20 `transfer` transactions - `num_erc721_mints`: Number of ERC721 `mint` transactions + - `concurrency`: How many transactions to do simultaneously - `report` - `num_blocks`: Number of last blocks to take into account in the report - - `reports_dir`: Path to the directory where to save the reports + - `location`: Path to the file where to save the reports - `deployer` @@ -103,6 +104,35 @@ The configuration is defined by the following spec gatling shoot -c config/default.yaml ``` +### Output + +The main output of gomu gomu is the report location specified in specified in the configuration file. + +At the end of all benchmarks gomu gomu will collect the results into a single json file with the following structure: + +- `users`: The amount of goose users used to do the benchmarks, changed by `concurrency` + +- `all_bench_report`: A report over all benchmarks done + +- `benches`: A array of reports for all benchmarks + + - `name`: The name of the benchmark + - `amount`: How many times this benchmark was ran + - `metrics`: An array of benchmark metrics over the whole benchmark + + - `name`: The name of the metric + - `unit`: The unit of the metric, empty when there is no unit + - `value`: The metrics value, a number + + - For floats, `Infinite` and `NaN` are not JSON numbers and thus will be turned into `null` + + - `last_x_blocks_metrics`: An array of benchmark metrics over the last metrics, changed by `num_blocks` + +- `extra`: Extra information for this run + + +Gomu gomu will also display into the console information about each step in the benchmark. + ## Resources - Gomu Gomu is originally inspired from [Flood](https://github.com/paradigmxyz/flood) diff --git a/config/default.yaml b/config/default.yaml index 7f086b2..1c2a49b 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -22,7 +22,7 @@ run: report: num_blocks: 4 - reports_dir: "reports" + location: "report" deployer: salt: "1" diff --git a/config/katana.yaml b/config/katana.yaml index 94ccfd0..58c6cd9 100644 --- a/config/katana.yaml +++ b/config/katana.yaml @@ -22,7 +22,7 @@ run: report: num_blocks: 4 - reports_dir: "reports" + location: "report" deployer: salt: "1" diff --git a/config/sharingan.yaml b/config/sharingan.yaml index e34714b..dbe12d7 100644 --- a/config/sharingan.yaml +++ b/config/sharingan.yaml @@ -22,7 +22,7 @@ run: report: num_blocks: 4 - reports_dir: "reports" + location: "report" # need to add an adress and signing key on sharingan network deployer: diff --git a/config/v2.1.0.yaml b/config/v2.1.0.yaml index aa94d99..2a830da 100644 --- a/config/v2.1.0.yaml +++ b/config/v2.1.0.yaml @@ -28,7 +28,7 @@ run: report: num_blocks: 3 - reports_dir: "reports" + location: "report" deployer: salt: "1" diff --git a/src/actions/goose.rs b/src/actions/goose.rs index 8a575ea..701f303 100644 --- a/src/actions/goose.rs +++ b/src/actions/goose.rs @@ -1,8 +1,12 @@ -use std::{mem, sync::Arc}; +use std::{ + mem, + sync::Arc, + time::{Duration, SystemTime}, +}; use color_eyre::eyre::ensure; use crossbeam_queue::ArrayQueue; -use goose::{config::GooseConfiguration, prelude::*}; +use goose::{config::GooseConfiguration, metrics::GooseRequestMetric, prelude::*}; use serde::{de::DeserializeOwned, Serialize}; use starknet::{ accounts::{ @@ -10,11 +14,13 @@ use starknet::{ }, core::types::{ ExecutionResult, FieldElement, InvokeTransactionResult, MaybePendingTransactionReceipt, + StarknetError, }, macros::{felt, selector}, providers::{ jsonrpc::{ - HttpTransport, HttpTransportError, JsonRpcClientError, JsonRpcMethod, JsonRpcResponse, + HttpTransport, HttpTransportError, JsonRpcClientError, JsonRpcError, JsonRpcMethod, + JsonRpcResponse, }, JsonRpcClient, ProviderError, }, @@ -24,12 +30,11 @@ use starknet::{ use crate::{ actions::shoot::{GatlingShooterSetup, CHECK_INTERVAL, MAX_FEE}, generators::get_rng, - utils::wait_for_tx, }; use super::shoot::StarknetAccount; -pub async fn erc20(shooter: &GatlingShooterSetup) -> color_eyre::Result<()> { +pub async fn erc20(shooter: &GatlingShooterSetup) -> color_eyre::Result { let environment = shooter.environment()?; let erc20_address = environment.erc20_address; let config = shooter.config(); @@ -66,9 +71,9 @@ pub async fn erc20(shooter: &GatlingShooterSetup) -> color_eyre::Result<()> { let transfer: TransactionFunction = Arc::new(move |user| Box::pin(transfer(user, erc20_address))); - let transfer_wait: TransactionFunction = goose_user_wait_last_tx(shooter.rpc_client().clone()); + let transfer_wait: TransactionFunction = goose_user_wait_last_tx(); - GooseAttack::initialize_with_config(goose_config.clone())? + let metrics = GooseAttack::initialize_with_config(goose_config.clone())? .register_scenario( scenario!("Transfer") .register_transaction( @@ -89,7 +94,7 @@ pub async fn erc20(shooter: &GatlingShooterSetup) -> color_eyre::Result<()> { ) .register_transaction( transaction!(verify_transactions) - .set_name("Transfer Verification") + .set_name("Verification") .set_sequence(3) .set_on_stop(), ), @@ -97,10 +102,10 @@ pub async fn erc20(shooter: &GatlingShooterSetup) -> color_eyre::Result<()> { .execute() .await?; - Ok(()) + Ok(metrics) } -pub async fn erc721(shooter: &GatlingShooterSetup) -> color_eyre::Result<()> { +pub async fn erc721(shooter: &GatlingShooterSetup) -> color_eyre::Result { let config = shooter.config(); let environment = shooter.environment()?; @@ -154,9 +159,9 @@ pub async fn erc721(shooter: &GatlingShooterSetup) -> color_eyre::Result<()> { Box::pin(async move { mint(user, erc721_address, nonce, &from_account).await }) }); - let mint_wait: TransactionFunction = goose_user_wait_last_tx(shooter.rpc_client().clone()); + let mint_wait: TransactionFunction = goose_user_wait_last_tx(); - GooseAttack::initialize_with_config(goose_mint_config.clone())? + let metrics = GooseAttack::initialize_with_config(goose_mint_config.clone())? .register_scenario( scenario!("Minting") .register_transaction( @@ -173,7 +178,7 @@ pub async fn erc721(shooter: &GatlingShooterSetup) -> color_eyre::Result<()> { ) .register_transaction( transaction!(verify_transactions) - .set_name("Mint Verification") + .set_name("Verification") .set_sequence(3) .set_on_stop(), ), @@ -181,7 +186,7 @@ pub async fn erc721(shooter: &GatlingShooterSetup) -> color_eyre::Result<()> { .execute() .await?; - Ok(()) + Ok(metrics) } #[derive(Debug, Clone)] @@ -230,21 +235,20 @@ async fn setup( })) } -fn goose_user_wait_last_tx(provider: Arc>) -> TransactionFunction { +fn goose_user_wait_last_tx() -> TransactionFunction { Arc::new(move |user| { - let thing = user + let tx = user .get_session_data::() .expect("Should be in a goose user with GooseUserState session data") .prev_tx .last() - .expect("At least one transaction should have been done"); - - let provider = provider.clone(); + .copied(); Box::pin(async move { - wait_for_tx(&provider, *thing, CHECK_INTERVAL) - .await - .expect("Transaction should have been successful"); + // If all transactions failed, we can skip this step + if let Some(tx) = tx { + wait_for_tx(user, tx).await?; + } Ok(()) }) @@ -280,7 +284,8 @@ async fn transfer(user: &mut GooseUser, erc20_address: FieldElement) -> Transact &account.clone(), JsonRpcMethod::AddInvokeTransaction, ) - .await?; + .await? + .0; let GooseUserState { nonce, prev_tx, .. } = user.get_session_data_mut::().expect( @@ -322,7 +327,8 @@ async fn mint( from_account, JsonRpcMethod::AddInvokeTransaction, ) - .await?; + .await? + .0; user.get_session_data_mut::() .expect( @@ -343,18 +349,24 @@ async fn verify_transactions(user: &mut GooseUser) -> TransactionResult { ); for tx in transactions { - let receipt: MaybePendingTransactionReceipt = + let (receipt, mut metrics) = send_request(user, JsonRpcMethod::GetTransactionReceipt, tx).await?; match receipt { MaybePendingTransactionReceipt::Receipt(receipt) => match receipt.execution_result() { ExecutionResult::Succeeded => {} ExecutionResult::Reverted { reason } => { - panic!("Transaction {tx:#064x} has been rejected/reverted: {reason}"); + let tag = format!("Transaction {tx:#064x} has been rejected/reverted"); + + user.set_failure(&tag, &mut metrics, None, Some(reason))?; } }, - MaybePendingTransactionReceipt::PendingReceipt(_) => { - panic!("Transaction {tx:#064x} is pending when no transactions should be") + MaybePendingTransactionReceipt::PendingReceipt(pending) => { + let tag = + format!("Transaction {tx:#064x} is pending when no transactions should be"); + let body = format!("{pending:?}"); + + user.set_failure(&tag, &mut metrics, None, Some(&body))?; } } } @@ -362,13 +374,87 @@ async fn verify_transactions(user: &mut GooseUser) -> TransactionResult { Ok(()) } +const WAIT_FOR_TX_TIMEOUT: Duration = Duration::from_secs(60); + +pub async fn wait_for_tx( + user: &mut GooseUser, + tx_hash: FieldElement, +) -> Result<(), Box> { + let start = SystemTime::now(); + + loop { + let (receipt, mut metrics) = + raw_send_request(user, JsonRpcMethod::GetTransactionReceipt, tx_hash).await?; + + if start.elapsed().unwrap() >= WAIT_FOR_TX_TIMEOUT { + let tag = format!("Timeout while waiting for transaction {tx_hash:#064x}"); + user.set_failure(&tag, &mut metrics, None, None)?; + } + + match receipt { + JsonRpcResponse::Success { + result: MaybePendingTransactionReceipt::Receipt(receipt), + .. + } => { + // Logic copied from starkli and the following comment too + // tWith JSON-RPC, once we get a receipt, the transaction must have been confirmed. + // Rejected transactions simply aren't available. This needs to be changed once we + // implement the sequencer fallback. + + match receipt.execution_result() { + ExecutionResult::Succeeded => { + return Ok(()); + } + ExecutionResult::Reverted { reason } => { + let tag = format!( + "Transaction {tx_hash:#064x} has been rejected/reverted: {reason}" + ); + + user.set_failure(&tag, &mut metrics, None, None)?; + } + } + } + JsonRpcResponse::Success { + result: MaybePendingTransactionReceipt::PendingReceipt(pending), + .. + } => { + if let ExecutionResult::Reverted { reason } = pending.execution_result() { + let tag = + format!("Transaction {tx_hash:#064x} has been rejected/reverted: {reason}"); + + user.set_failure(&tag, &mut metrics, None, None)?; + } + log::debug!("Waiting for transaction {tx_hash:#064x} to be accepted"); + tokio::time::sleep(CHECK_INTERVAL).await; + } + JsonRpcResponse::Error { + error: JsonRpcError { code, .. }, + .. + } if code == StarknetError::TransactionHashNotFound as i64 => { + log::debug!("Waiting for transaction {tx_hash:#064x} to show up"); + tokio::time::sleep(CHECK_INTERVAL).await; + } + JsonRpcResponse::Error { + error: JsonRpcError { code, message }, + .. + } => { + let tag = format!( + "Error Code {code} while waiting for transaction {tx_hash:#064x}: {message}" + ); + + user.set_failure(&tag, &mut metrics, None, None)?; + } + } + } +} + pub async fn send_execution( user: &mut GooseUser, calls: Vec, nonce: FieldElement, from_account: &SingleOwnerAccount>, LocalWallet>, method: JsonRpcMethod, -) -> Result> { +) -> Result<(T, GooseRequestMetric), Box> { let calldata = from_account.encode_calls(&calls); #[allow(dead_code)] // Removes warning for unused fields, we need them to properly transmute @@ -407,7 +493,30 @@ pub async fn send_request( user: &mut GooseUser, method: JsonRpcMethod, param: impl Serialize, -) -> Result> { +) -> Result<(T, GooseRequestMetric), Box> { + let (body, mut metrics) = raw_send_request(user, method, param).await?; + + match body { + JsonRpcResponse::Success { result, .. } => Ok((result, metrics)), + JsonRpcResponse::Error { error, .. } => { + // While this is not the actual body we cannot serialize `JsonRpcResponse` + // due to it not implementing `Serialize`, and if we were to get the text before + // serializing we couldn't map the serde_json error to `TransactionError`. + // It also provides the exact same info and this is just debug information + let error = error.to_string(); + + Err(user + .set_failure("RPC Response was Error", &mut metrics, None, Some(&error)) + .unwrap_err()) // SAFETY: This always returns a error + } + } +} + +pub async fn raw_send_request( + user: &mut GooseUser, + method: JsonRpcMethod, + param: impl Serialize, +) -> Result<(JsonRpcResponse, GooseRequestMetric), Box> { // Copied from https://docs.rs/starknet-providers/0.9.0/src/starknet_providers/jsonrpc/transports/http.rs.html#21-27 #[derive(Debug, Serialize)] struct JsonRpcRequest { @@ -424,20 +533,14 @@ pub async fn send_request( params: [param], }; - let body = user - .post_json("/", &request) - .await? + let goose_response = user.post_json("/", &request).await?; + + let body = goose_response .response .map_err(TransactionError::Reqwest)? .json::>() .await .map_err(TransactionError::Reqwest)?; - match body { - JsonRpcResponse::Success { result, .. } => Ok(result), - // Returning this error would probably be a good idea, - // but the goose error type doesn't allow it and we are - // required to return it as a constraint of TransactionFunction - JsonRpcResponse::Error { error, .. } => panic!("{error}"), - } + Ok((body, goose_response.request)) } diff --git a/src/actions/mod.rs b/src/actions/mod.rs index afcb4ef..5728a00 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -1,4 +1,9 @@ -use crate::config::GatlingConfig; +use starknet::providers::Provider; + +use crate::{ + config::GatlingConfig, + metrics::{BenchmarkReport, WholeReport}, +}; use self::shoot::GatlingShooterSetup; @@ -9,20 +14,81 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { let run_erc20 = config.run.num_erc20_transfers != 0; let run_erc721 = config.run.num_erc721_mints != 0; - let mut shooter = GatlingShooterSetup::from_config(config).await?; + let mut shooter = GatlingShooterSetup::from_config(config.clone()).await?; shooter.setup().await?; + let mut whole_report = WholeReport { + users: shooter.config().run.concurrency, + all_bench_report: BenchmarkReport::new( + "", + (config.run.num_erc20_transfers + config.run.num_erc721_mints) as usize, + ), + benches: Vec::new(), + extra: crate::utils::sysinfo_string(), + }; + + let start_block = shooter.rpc_client().block_number().await?; + if run_erc20 { - goose::erc20(&shooter).await?; + let start_block = shooter.rpc_client().block_number().await?; + let goose_metrics = goose::erc20(&shooter).await?; + let end_block = shooter.rpc_client().block_number().await?; + + let mut report = + BenchmarkReport::new("Erc20 Transfers", goose_metrics.scenarios[0].counter); + + report + .with_block_range(shooter.rpc_client(), start_block + 1, end_block) + .await?; + + if config.report.num_blocks != 0 { + report + .with_last_x_blocks(shooter.rpc_client(), config.report.num_blocks) + .await?; + } + + report.with_goose_metrics(&goose_metrics)?; + + whole_report.benches.push(report); } else { log::info!("Skipping erc20 transfers") } if run_erc721 { - goose::erc721(&shooter).await?; + let start_block = shooter.rpc_client().block_number().await?; + let goose_metrics = goose::erc721(&shooter).await?; + let end_block = shooter.rpc_client().block_number().await?; + + let mut report = BenchmarkReport::new("Erc721 Mints", goose_metrics.scenarios[0].counter); + + report + .with_block_range(shooter.rpc_client(), start_block + 1, end_block) + .await?; + + if config.report.num_blocks != 0 { + report + .with_last_x_blocks(shooter.rpc_client(), config.report.num_blocks) + .await?; + } + + report.with_goose_metrics(&goose_metrics)?; + + whole_report.benches.push(report); } else { log::info!("Skipping erc721 mints") } + let end_block = shooter.rpc_client().block_number().await?; + + whole_report + .all_bench_report + .with_block_range(shooter.rpc_client(), start_block, end_block) + .await?; + + let report_path = shooter.config().report.location.with_extension("json"); + + let writer = std::fs::File::create(report_path)?; + serde_json::to_writer_pretty(writer, &whole_report)?; + Ok(()) } diff --git a/src/config.rs b/src/config.rs index 4192f5f..1ab23ab 100644 --- a/src/config.rs +++ b/src/config.rs @@ -111,7 +111,7 @@ pub struct RunConfig { #[derive(Debug, Deserialize, Clone)] pub struct ReportConfig { pub num_blocks: u64, - pub reports_dir: PathBuf, + pub location: PathBuf, } impl GatlingConfig { diff --git a/src/metrics.rs b/src/metrics.rs index 6801c98..1555545 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -1,13 +1,25 @@ -use crate::utils::{get_num_tx_per_block, SysInfo, SYSINFO}; +use crate::utils::get_num_tx_per_block; -use color_eyre::Result; +use color_eyre::{ + eyre::{bail, eyre}, + Result, +}; -use serde_json::{json, Value}; +use goose::metrics::GooseMetrics; +use serde_derive::Serialize; use starknet::providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}; -use std::{fmt, ops::Deref, sync::Arc}; +use std::fmt; pub const BLOCK_TIME: u64 = 6; +#[derive(Clone, Debug, Serialize)] +pub struct WholeReport { + pub users: u64, + pub all_bench_report: BenchmarkReport, + pub benches: Vec, + pub extra: String, +} + /// Metric struct that contains the name, unit and compute function for a metric /// A Metric is a measure of a specific performance aspect of a benchmark through /// the compute function which receives a vector of number of transactions per block @@ -18,7 +30,7 @@ pub const BLOCK_TIME: u64 = 6; /// { name: "Average TPS", unit: "transactions/second", compute: average_tps } /// "Average TPS: 1000 transactions/second" #[derive(PartialEq, Eq, Hash, Clone)] -pub struct Metric { +pub struct NodeMetrics { pub name: &'static str, pub unit: &'static str, pub compute: fn(&[u64]) -> f64, @@ -29,36 +41,43 @@ pub struct Metric { /// Example: /// MetricResult { name: "Average TPS", unit: "transactions/second", value: 1000 } /// "Average TPS: 1000 transactions/second" -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize)] pub struct MetricResult { pub name: &'static str, pub unit: &'static str, - pub value: f64, + pub value: serde_json::Value, } -/// The simulation report. -#[derive(Debug, Default, Clone)] -pub struct GatlingReport { - pub benchmark_reports: Vec, -} - -/// A benchmark report contains a name (used for displaying) and a vector of metric results +/// A benchmark report contains a name and a vector of metric results /// of all the metrics that were computed for the benchmark /// A benchmark report can be created from a block range or from the last x blocks /// It implements the Serialize trait so it can be serialized to json -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize)] pub struct BenchmarkReport { - pub name: String, + #[serde(skip_serializing_if = "str::is_empty")] + pub name: &'static str, + pub amount: usize, pub metrics: Vec, + #[serde(skip_serializing_if = "Option::is_none")] + pub last_x_blocks_metrics: Option>, } impl BenchmarkReport { - pub async fn from_block_range<'a>( - starknet_rpc: Arc>, - name: String, + pub fn new(name: &'static str, amount: usize) -> BenchmarkReport { + BenchmarkReport { + name, + amount, + metrics: Vec::new(), + last_x_blocks_metrics: None, + } + } + + pub async fn with_block_range( + &mut self, + starknet_rpc: &JsonRpcClient, mut start_block: u64, mut end_block: u64, - ) -> Result { + ) -> Result<()> { // Whenever possible, skip the first and last blocks from the metrics // to make sure all the blocks used for calculating metrics are full if end_block - start_block > 2 { @@ -67,60 +86,104 @@ impl BenchmarkReport { } let num_tx_per_block = get_num_tx_per_block(starknet_rpc, start_block, end_block).await?; - let metrics = compute_all_metrics(num_tx_per_block); + let metrics = compute_node_metrics(num_tx_per_block); - Ok(BenchmarkReport { name, metrics }) + self.metrics.extend_from_slice(&metrics); + + Ok(()) } - pub async fn from_last_x_blocks<'a>( - starknet_rpc: Arc>, - name: String, + pub async fn with_last_x_blocks( + &mut self, + starknet_rpc: &JsonRpcClient, num_blocks: u64, - ) -> Result { + ) -> Result<()> { // The last block won't be full of transactions, so we skip it let end_block = starknet_rpc.block_number().await? - 1; let start_block = end_block - num_blocks; let num_tx_per_block = get_num_tx_per_block(starknet_rpc, start_block, end_block).await?; - let metrics = compute_all_metrics(num_tx_per_block); + let metrics = compute_node_metrics(num_tx_per_block).to_vec(); - Ok(BenchmarkReport { name, metrics }) + self.last_x_blocks_metrics = Some(metrics); + + Ok(()) } - pub fn to_json(&self) -> Value { - let SysInfo { - os_name, - kernel_version, - arch, - cpu_count, - cpu_frequency, - cpu_brand, - memory, - } = SYSINFO.deref(); - - let gigabyte_memory = memory / (1024 * 1024 * 1024); - - let sysinfo_string = format!( - "CPU Count: {cpu_count}\n\ - CPU Model: {cpu_brand}\n\ - CPU Speed (MHz): {cpu_frequency}\n\ - Total Memory: {gigabyte_memory} GB\n\ - Platform: {os_name}\n\ - Release: {kernel_version}\n\ - Architecture: {arch}", - ); - - self.metrics - .iter() - .map(|metric| { - json!({ - "name": metric.name, - "unit": metric.unit, - "value": metric.value, - "extra": sysinfo_string - }) - }) - .collect::() + pub fn with_goose_metrics(&mut self, metrics: &GooseMetrics) -> Result<()> { + let scenario = metrics + .scenarios + .first() + .ok_or(eyre!("There is no scenario"))?; + + let transactions = metrics + .transactions + .first() + .ok_or(eyre!("Could no find scenario's transactions"))?; + + let [_setup, requests, _finalizing, verification] = transactions.as_slice() else { + bail!("Failed at getting all transaction aggragates") + }; + + let verification_requests = metrics + .requests + .get("POST Verification") + .ok_or(eyre!("Found no verification request metrics"))?; + + self.metrics.extend_from_slice(&[ + MetricResult { + name: "Total Submission Time", + unit: "milliseconds", + value: requests.total_time.into(), + }, + MetricResult { + name: "Total Verification Time", + unit: "milliseconds", + value: verification.total_time.into(), + }, + MetricResult { + name: "Failed Transactions Verifications", + unit: "", + value: verification_requests.fail_count.into(), + }, + MetricResult { + name: "Failed Transaction Submissions", + unit: "", + value: requests.fail_count.into(), + }, + MetricResult { + name: "Max Submission Time", + unit: "milliseconds", + value: requests.max_time.into(), + }, + MetricResult { + name: "Min Submission Time", + unit: "milliseconds", + value: requests.min_time.into(), + }, + MetricResult { + name: "Mean Submission Time", + unit: "milliseconds", + value: (requests.total_time as f64 / scenario.counter as f64).into(), + }, + MetricResult { + name: "Max Verification Time", + unit: "milliseconds", + value: verification_requests.raw_data.maximum_time.into(), + }, + MetricResult { + name: "Min Verification Time", + unit: "milliseconds", + value: verification_requests.raw_data.minimum_time.into(), + }, + MetricResult { + name: "Mean Verification Time", + unit: "milliseconds", + value: (verification_requests.raw_data.total_time as f64 / scenario.counter as f64).into(), + }, + ]); + + Ok(()) } } @@ -134,18 +197,48 @@ impl fmt::Display for MetricResult { impl fmt::Display for BenchmarkReport { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { name, metrics } = self; + let Self { + name, + amount, + metrics, + last_x_blocks_metrics: last_x_blocks, + } = self; - writeln!(f, "Benchmark Report: {name}")?; + writeln!(f, "Benchmark Report: {name} ({amount})")?; for metric in metrics { writeln!(f, "{metric}")?; } + if let Some(last_x_blocks) = last_x_blocks { + let len = last_x_blocks.len(); + + writeln!(f, "Last {len} block metrics:")?; + + for metric in last_x_blocks { + writeln!(f, "{metric}")?; + } + } + Ok(()) } } +pub fn compute_node_metrics(num_tx_per_block: Vec) -> [MetricResult; 2] { + [ + MetricResult { + name: "Average TPS", + unit: "transactions/second", + value: average_tps(&num_tx_per_block).into(), + }, + MetricResult { + name: "Average Extrinsics per block", + unit: "extrinsics/block", + value: average_tpb(&num_tx_per_block).into(), + }, + ] +} + fn average_tps(num_tx_per_block: &[u64]) -> f64 { average_tpb(num_tx_per_block) / BLOCK_TIME as f64 } @@ -153,30 +246,3 @@ fn average_tps(num_tx_per_block: &[u64]) -> f64 { fn average_tpb(num_tx_per_block: &[u64]) -> f64 { num_tx_per_block.iter().sum::() as f64 / num_tx_per_block.len() as f64 } - -pub fn compute_all_metrics(num_tx_per_block: Vec) -> Vec { - METRICS - .iter() - .map(|metric| { - let value = (metric.compute)(&num_tx_per_block); - MetricResult { - name: metric.name, - unit: metric.unit, - value, - } - }) - .collect() -} - -pub const METRICS: [Metric; 2] = [ - Metric { - name: "Average TPS", - unit: "transactions/second", - compute: average_tps, - }, - Metric { - name: "Average Extrinsics per block", - unit: "extrinsics/block", - compute: average_tpb, - }, -]; diff --git a/src/utils.rs b/src/utils.rs index d62470e..121511d 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,5 +1,4 @@ -use std::fmt; -use std::sync::Arc; +use std::ops::Deref; use std::time::SystemTime; use color_eyre::{eyre::eyre, Result}; @@ -18,8 +17,6 @@ use starknet::{ use std::time::Duration; use sysinfo::{CpuExt, System, SystemExt}; -use crate::metrics::{BenchmarkReport, GatlingReport}; - lazy_static! { pub static ref SYSINFO: SysInfo = SysInfo::new(); } @@ -83,38 +80,36 @@ impl SysInfo { } } +pub fn sysinfo_string() -> String { + let SysInfo { + os_name, + kernel_version, + arch, + cpu_count, + cpu_frequency, + cpu_brand, + memory, + } = SYSINFO.deref(); + + let gigabyte_memory = memory / (1024 * 1024 * 1024); + + format!( + "CPU Count: {cpu_count}\n\ + CPU Model: {cpu_brand}\n\ + CPU Speed (MHz): {cpu_frequency}\n\ + Total Memory: {gigabyte_memory} GB\n\ + Platform: {os_name}\n\ + Release: {kernel_version}\n\ + Architecture: {arch}", + ) +} + impl Default for SysInfo { fn default() -> Self { Self::new() } } -impl fmt::Display for SysInfo { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { - os_name, - kernel_version, - arch, - cpu_count, - cpu_frequency, - cpu_brand, - memory, - } = self; - - let cpu_ghz_freq = *cpu_frequency as f64 / 1000.0; - let gigabyte_memory = memory / (1024 * 1024 * 1024); - - writeln!( - f, - "System Information:\n\ - System : {os_name} Kernel Version {kernel_version}\n\ - Arch : {arch}\n\ - CPU : {cpu_brand} {cpu_ghz_freq:.2} GHz {cpu_count} cores\n\ - Memory : {gigabyte_memory} GB" - ) - } -} - const WAIT_FOR_TX_TIMEOUT: Duration = Duration::from_secs(60); pub async fn wait_for_tx( @@ -149,7 +144,12 @@ pub async fn wait_for_tx( } } } - Ok(PendingReceipt(_)) => { + Ok(PendingReceipt(pending)) => { + if let ExecutionResult::Reverted { reason } = pending.execution_result() { + return Err(eyre!(format!( + "Transaction {tx_hash:#064x} has been rejected/reverted: {reason}" + ))); + } debug!("Waiting for transaction {tx_hash:#064x} to be accepted"); tokio::time::sleep(check_interval).await; } @@ -175,7 +175,7 @@ pub async fn wait_for_tx( /// without hitting the StarkNet RPC multiple times // TODO: add a cache to avoid hitting the RPC for the same block pub async fn get_num_tx_per_block( - starknet_rpc: Arc>, + starknet_rpc: &JsonRpcClient, start_block: u64, end_block: u64, ) -> Result> { @@ -220,43 +220,3 @@ pub fn sanitize_filename(input: &str) -> String { truncated.to_string() } - -#[derive(Debug)] -pub enum BenchmarkType { - BlockRange(u64, u64), - LatestBlocks(u64), -} - -/// Builds a benchmark report for the given benchmark name and block range -pub async fn build_benchmark_report( - starknet_rpc: Arc>, - benchmark_name: String, - benchmark_type: BenchmarkType, - gatling_report: &mut GatlingReport, -) -> Result { - let benchmark_report = match benchmark_type { - BenchmarkType::BlockRange(start, end) => { - BenchmarkReport::from_block_range( - starknet_rpc.clone(), - benchmark_name.clone(), - start, - end, - ) - .await? - } - BenchmarkType::LatestBlocks(num_blocks) => { - BenchmarkReport::from_last_x_blocks( - starknet_rpc.clone(), - benchmark_name.clone(), - num_blocks, - ) - .await? - } - }; - - gatling_report - .benchmark_reports - .push(benchmark_report.clone()); - - Ok(benchmark_report) -} From 6c7edf897856cf9e54e4c0b52619e67d06e4b5a3 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Fri, 23 Feb 2024 13:41:15 +0200 Subject: [PATCH 02/45] Add `num_blocks` field to `last_x_blocks_metrics` --- README.md | 12 +++++++----- src/metrics.rs | 22 +++++++++++++++------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 98a4c3e..84cde52 100644 --- a/README.md +++ b/README.md @@ -115,21 +115,23 @@ At the end of all benchmarks gomu gomu will collect the results into a single js - `all_bench_report`: A report over all benchmarks done - `benches`: A array of reports for all benchmarks - + - `name`: The name of the benchmark - `amount`: How many times this benchmark was ran - - `metrics`: An array of benchmark metrics over the whole benchmark + - `metrics`: An array of metrics over the whole benchmark - `name`: The name of the metric - `unit`: The unit of the metric, empty when there is no unit - `value`: The metrics value, a number - + - For floats, `Infinite` and `NaN` are not JSON numbers and thus will be turned into `null` - - `last_x_blocks_metrics`: An array of benchmark metrics over the last metrics, changed by `num_blocks` + - `last_x_blocks_metrics`: Metrics over the last blocks of the benchmark -- `extra`: Extra information for this run + - `num_blocks`: The amount of last transactions that were measured + - `metrics`: An array of metrics +- `extra`: Extra information for this run Gomu gomu will also display into the console information about each step in the benchmark. diff --git a/src/metrics.rs b/src/metrics.rs index 1555545..99ca003 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -59,7 +59,13 @@ pub struct BenchmarkReport { pub amount: usize, pub metrics: Vec, #[serde(skip_serializing_if = "Option::is_none")] - pub last_x_blocks_metrics: Option>, + pub last_x_blocks_metrics: Option, +} + +#[derive(Debug, Clone, Serialize)] +pub struct LastXBlocksMetric { + pub num_blocks: u64, + pub metrics: Vec, } impl BenchmarkReport { @@ -105,7 +111,10 @@ impl BenchmarkReport { let num_tx_per_block = get_num_tx_per_block(starknet_rpc, start_block, end_block).await?; let metrics = compute_node_metrics(num_tx_per_block).to_vec(); - self.last_x_blocks_metrics = Some(metrics); + self.last_x_blocks_metrics = Some(LastXBlocksMetric { + num_blocks, + metrics, + }); Ok(()) } @@ -179,7 +188,8 @@ impl BenchmarkReport { MetricResult { name: "Mean Verification Time", unit: "milliseconds", - value: (verification_requests.raw_data.total_time as f64 / scenario.counter as f64).into(), + value: (verification_requests.raw_data.total_time as f64 / scenario.counter as f64) + .into(), }, ]); @@ -211,11 +221,9 @@ impl fmt::Display for BenchmarkReport { } if let Some(last_x_blocks) = last_x_blocks { - let len = last_x_blocks.len(); - - writeln!(f, "Last {len} block metrics:")?; + writeln!(f, "Last {} block metrics:", last_x_blocks.num_blocks)?; - for metric in last_x_blocks { + for metric in &last_x_blocks.metrics { writeln!(f, "{metric}")?; } } From 773cc4e34ca14163ce04ac1ee3ac1820f9c32bf5 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Tue, 27 Feb 2024 10:56:39 +0200 Subject: [PATCH 03/45] Add P50/P90 and UOPS Metrics --- src/actions/goose.rs | 8 ++- src/actions/shoot.rs | 8 +-- src/metrics.rs | 164 +++++++++++++++++++++++++++++++++---------- src/utils.rs | 70 +++++++++++++----- 4 files changed, 189 insertions(+), 61 deletions(-) diff --git a/src/actions/goose.rs b/src/actions/goose.rs index 701f303..11c1159 100644 --- a/src/actions/goose.rs +++ b/src/actions/goose.rs @@ -83,7 +83,7 @@ pub async fn erc20(shooter: &GatlingShooterSetup) -> color_eyre::Result color_eyre::Result Result<&GatlingEnvironment> { - self.environment.as_ref().ok_or(eyre!( - "Environment is not yet populated, you should run the setup function first" - )) + self.environment + .as_ref() + .ok_or_eyre("Environment is not yet populated, you should run the setup function first") } pub fn config(&self) -> &GatlingConfig { diff --git a/src/metrics.rs b/src/metrics.rs index 99ca003..dccfd16 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -1,14 +1,19 @@ -use crate::utils::get_num_tx_per_block; +use crate::utils::get_blocks_with_txs; use color_eyre::{ - eyre::{bail, eyre}, + eyre::{bail, OptionExt}, Result, }; -use goose::metrics::GooseMetrics; +use goose::metrics::{GooseMetrics, GooseRequestMetricTimingData}; use serde_derive::Serialize; -use starknet::providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}; -use std::fmt; +use starknet::{ + core::types::{ + BlockWithTxs, InvokeTransaction, InvokeTransactionV0, InvokeTransactionV1, Transaction, + }, + providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}, +}; +use std::{fmt, sync::Arc}; pub const BLOCK_TIME: u64 = 6; @@ -26,7 +31,7 @@ pub struct WholeReport { /// and returns the metric value as a f64 /// The name and unit are used for displaying the metric /// -/// ### Example +/// ### Example /// { name: "Average TPS", unit: "transactions/second", compute: average_tps } /// "Average TPS: 1000 transactions/second" #[derive(PartialEq, Eq, Hash, Clone)] @@ -80,7 +85,7 @@ impl BenchmarkReport { pub async fn with_block_range( &mut self, - starknet_rpc: &JsonRpcClient, + starknet_rpc: &Arc>, mut start_block: u64, mut end_block: u64, ) -> Result<()> { @@ -91,8 +96,8 @@ impl BenchmarkReport { end_block -= 1; } - let num_tx_per_block = get_num_tx_per_block(starknet_rpc, start_block, end_block).await?; - let metrics = compute_node_metrics(num_tx_per_block); + let blocks_with_txs = get_blocks_with_txs(starknet_rpc, start_block..=end_block).await?; + let metrics = compute_node_metrics(&blocks_with_txs)?; self.metrics.extend_from_slice(&metrics); @@ -101,15 +106,15 @@ impl BenchmarkReport { pub async fn with_last_x_blocks( &mut self, - starknet_rpc: &JsonRpcClient, + starknet_rpc: &Arc>, num_blocks: u64, ) -> Result<()> { // The last block won't be full of transactions, so we skip it let end_block = starknet_rpc.block_number().await? - 1; let start_block = end_block - num_blocks; - let num_tx_per_block = get_num_tx_per_block(starknet_rpc, start_block, end_block).await?; - let metrics = compute_node_metrics(num_tx_per_block).to_vec(); + let blocks_with_txs = get_blocks_with_txs(starknet_rpc, start_block..=end_block).await?; + let metrics = compute_node_metrics(&blocks_with_txs)?; self.last_x_blocks_metrics = Some(LastXBlocksMetric { num_blocks, @@ -120,30 +125,30 @@ impl BenchmarkReport { } pub fn with_goose_metrics(&mut self, metrics: &GooseMetrics) -> Result<()> { - let scenario = metrics - .scenarios - .first() - .ok_or(eyre!("There is no scenario"))?; - let transactions = metrics .transactions .first() - .ok_or(eyre!("Could no find scenario's transactions"))?; + .ok_or_eyre("Could no find scenario's transactions")?; - let [_setup, requests, _finalizing, verification] = transactions.as_slice() else { + let [_setup, submission, _finalizing, verification] = transactions.as_slice() else { bail!("Failed at getting all transaction aggragates") }; + let submission_requests = metrics + .requests + .get("POST Transaction Submission") + .ok_or_eyre("Found no submission request metrics")?; + let verification_requests = metrics .requests .get("POST Verification") - .ok_or(eyre!("Found no verification request metrics"))?; + .ok_or_eyre("Found no verification request metrics")?; self.metrics.extend_from_slice(&[ MetricResult { name: "Total Submission Time", unit: "milliseconds", - value: requests.total_time.into(), + value: submission_requests.raw_data.total_time.into(), }, MetricResult { name: "Total Verification Time", @@ -158,22 +163,24 @@ impl BenchmarkReport { MetricResult { name: "Failed Transaction Submissions", unit: "", - value: requests.fail_count.into(), + value: submission.fail_count.into(), }, MetricResult { name: "Max Submission Time", unit: "milliseconds", - value: requests.max_time.into(), + value: submission_requests.raw_data.maximum_time.into(), }, MetricResult { name: "Min Submission Time", unit: "milliseconds", - value: requests.min_time.into(), + value: submission_requests.raw_data.minimum_time.into(), }, MetricResult { name: "Mean Submission Time", unit: "milliseconds", - value: (requests.total_time as f64 / scenario.counter as f64).into(), + value: (submission_requests.raw_data.total_time as f64 + / submission_requests.success_count as f64) + .into(), }, MetricResult { name: "Max Verification Time", @@ -188,15 +195,65 @@ impl BenchmarkReport { MetricResult { name: "Mean Verification Time", unit: "milliseconds", - value: (verification_requests.raw_data.total_time as f64 / scenario.counter as f64) + value: (verification_requests.raw_data.total_time as f64 + / verification_requests.success_count as f64) .into(), }, ]); + if let Some((sub_p50, sub_90)) = calculate_p50_and_p90(&submission_requests.raw_data) { + self.metrics.extend_from_slice(&[ + MetricResult { + name: "P90 Submission Time", + unit: "milliseconds", + value: sub_90.into(), + }, + MetricResult { + name: "P50 Submission Time", + unit: "milliseconds", + value: sub_p50.into(), + }, + ]) + } + + if let Some((ver_p50, ver_p90)) = calculate_p50_and_p90(&verification_requests.raw_data) { + self.metrics.extend_from_slice(&[ + MetricResult { + name: "P90 Verification Time", + unit: "milliseconds", + value: ver_p90.into(), + }, + MetricResult { + name: "P50 Verification Time", + unit: "milliseconds", + value: ver_p50.into(), + }, + ]) + } + Ok(()) } } +fn calculate_p50_and_p90(timing_data: &GooseRequestMetricTimingData) -> Option<(usize, usize)> { + let p50_idx = (timing_data.counter * 50) / 100; + + let p90_idx = (timing_data.counter * 90) / 100; + + let mut ordered_times = timing_data + .times + .iter() + .flat_map(|(time, &amount)| std::iter::repeat(time).take(amount)); + + // These should only return None when there is only 1 or 0 times in the data + let &p50 = ordered_times.nth(p50_idx)?; + + // p50 already iterated some out, so we subtract it's idx from here + let &p90 = ordered_times.nth(p90_idx - p50_idx)?; + + Some((p50, p90)) +} + impl fmt::Display for MetricResult { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let Self { name, value, unit } = self; @@ -232,25 +289,60 @@ impl fmt::Display for BenchmarkReport { } } -pub fn compute_node_metrics(num_tx_per_block: Vec) -> [MetricResult; 2] { - [ +pub fn compute_node_metrics(blocks_with_txs: &[BlockWithTxs]) -> Result> { + let total_transactions: usize = blocks_with_txs.iter().map(|b| b.transactions.len()).sum(); + let avg_tpb = total_transactions as f64 / blocks_with_txs.len() as f64; + + let mut metrics = vec![ MetricResult { name: "Average TPS", unit: "transactions/second", - value: average_tps(&num_tx_per_block).into(), + value: (avg_tpb / BLOCK_TIME as f64).into(), }, MetricResult { name: "Average Extrinsics per block", unit: "extrinsics/block", - value: average_tpb(&num_tx_per_block).into(), + value: avg_tpb.into(), }, - ] -} + ]; + + let first_block = blocks_with_txs.first().ok_or_eyre("No first block")?; + let last_block = blocks_with_txs.last().ok_or_eyre("No last block")?; + + if first_block.timestamp != last_block.timestamp { + let time = last_block.timestamp - first_block.timestamp; + + let total_uops: u64 = blocks_with_txs + .iter() + .skip(1) // Skip first block as its creation time is the start time for this metric + .flat_map(|b| &b.transactions) + .map(tx_get_user_operations) + .collect::, _>>()? + .into_iter() + .sum(); + + metrics.push(MetricResult { + name: "Average UOPS", + unit: "operations/second", + value: (total_uops as f64 / time as f64).into(), + }) + } -fn average_tps(num_tx_per_block: &[u64]) -> f64 { - average_tpb(num_tx_per_block) / BLOCK_TIME as f64 + Ok(metrics) } -fn average_tpb(num_tx_per_block: &[u64]) -> f64 { - num_tx_per_block.iter().sum::() as f64 / num_tx_per_block.len() as f64 +fn tx_get_user_operations(tx: &Transaction) -> Result { + Ok(match tx { + Transaction::Invoke( + InvokeTransaction::V0(InvokeTransactionV0 { calldata, .. }) + | InvokeTransaction::V1(InvokeTransactionV1 { calldata, .. }), + ) => { + let &user_operations = calldata + .first() + .ok_or_eyre("Expected calldata to have at least one field element")?; + + user_operations.try_into()? + } + _ => bail!("Unexpected transaction type when getting"), + }) } diff --git a/src/utils.rs b/src/utils.rs index 121511d..21e3800 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,11 +1,15 @@ use std::ops::Deref; +use std::sync::Arc; use std::time::SystemTime; +use color_eyre::eyre::{bail, OptionExt}; use color_eyre::{eyre::eyre, Result}; use lazy_static::lazy_static; use log::debug; -use starknet::core::types::{BlockId, ExecutionResult, StarknetError}; +use starknet::core::types::{ + BlockId, BlockWithTxs, ExecutionResult, MaybePendingBlockWithTxs, StarknetError, +}; use starknet::core::{crypto::compute_hash_on_elements, types::FieldElement}; use starknet::providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}; use starknet::providers::{MaybeUnknownErrorCode, ProviderError}; @@ -13,6 +17,7 @@ use starknet::{ core::types::MaybePendingTransactionReceipt::{PendingReceipt, Receipt}, providers::StarknetErrorWithMessage, }; +use tokio::task::JoinSet; use std::time::Duration; use sysinfo::{CpuExt, System, SystemExt}; @@ -169,27 +174,54 @@ pub async fn wait_for_tx( } } -/// Get a Map of the number of transactions per block from `start_block` to -/// `end_block` (including both) -/// This is meant to be used to calculate multiple metrics such as TPS and TPB +/// Get a list of blocks with transaction information from +/// `start_block` to `end_block` (including both) +/// This is meant to be used to calculate multiple metrics such as TPS and UOPS /// without hitting the StarkNet RPC multiple times -// TODO: add a cache to avoid hitting the RPC for the same block -pub async fn get_num_tx_per_block( - starknet_rpc: &JsonRpcClient, - start_block: u64, - end_block: u64, -) -> Result> { - let mut num_tx_per_block = Vec::new(); - - for block_number in start_block..=end_block { - let n = starknet_rpc - .get_block_transaction_count(BlockId::Number(block_number)) - .await?; - - num_tx_per_block.push(n); +pub async fn get_blocks_with_txs( + starknet_rpc: &Arc>, + block_range: impl Iterator, +) -> Result> { + const MAX_CONCURRENT: usize = 50; + + // A collection of spawned tokio tasks + let mut join_set = JoinSet::new(); + + let mut results = Vec::with_capacity(block_range.size_hint().0); + + for block_number in block_range { + // Make sure we don't hit dev server with too many requests + while join_set.len() >= MAX_CONCURRENT { + let next = join_set + .join_next() + .await + .ok_or_eyre("JoinSet should have items")???; + + results.push(match_result(next)?); + } + + let starknet_rpc = starknet_rpc.clone(); + + join_set.spawn(async move { + starknet_rpc + .get_block_with_txs(BlockId::Number(block_number)) + .await + }); + } + + // Process the rest + while let Some(next) = join_set.join_next().await { + results.push(match_result(next??)?) + } + + fn match_result(maybe_block: MaybePendingBlockWithTxs) -> Result { + match maybe_block { + MaybePendingBlockWithTxs::Block(block) => Ok(block), + MaybePendingBlockWithTxs::PendingBlock(_) => bail!("Blocks should not be pending!"), + } } - Ok(num_tx_per_block) + Ok(results) } /// Sanitize a string to be used as a filename by removing/replacing illegal chars From 3af9043bfb4aab6dfcf741fcdc396f310f25554b Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Wed, 28 Feb 2024 08:35:53 +0200 Subject: [PATCH 04/45] Remove `colored` crate --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index ba3eecf..53d35c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,5 @@ serde_json = { version = "1.0.96", features = ["preserve_order"] } url = "2.4.0" rand = { version = "0.8.5", features = ["rand_chacha"] } lazy_static = "1.4.0" -colored = "2.0.4" sysinfo = "0.29.8" crossbeam-queue = "0.3.11" From 7568c6cbc2ddea255583199d52cc79e4d453cc15 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Wed, 28 Feb 2024 10:58:19 +0200 Subject: [PATCH 05/45] Rename metrics from Mean to Average --- src/metrics.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/metrics.rs b/src/metrics.rs index dccfd16..a4a5fdb 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -176,7 +176,7 @@ impl BenchmarkReport { value: submission_requests.raw_data.minimum_time.into(), }, MetricResult { - name: "Mean Submission Time", + name: "Average Submission Time", unit: "milliseconds", value: (submission_requests.raw_data.total_time as f64 / submission_requests.success_count as f64) @@ -193,7 +193,7 @@ impl BenchmarkReport { value: verification_requests.raw_data.minimum_time.into(), }, MetricResult { - name: "Mean Verification Time", + name: "Average Verification Time", unit: "milliseconds", value: (verification_requests.raw_data.total_time as f64 / verification_requests.success_count as f64) From 10eca1b03ae28f3fa62116570d4a8e2b8d178873 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Wed, 28 Feb 2024 14:37:18 +0200 Subject: [PATCH 06/45] Update deps --- Cargo.toml | 6 +++--- src/utils.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 53d35c1..bdd68f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,13 +17,13 @@ opt-level = 3 starknet = "0.6.0" goose = "0.17.2" -env_logger = "0.10.0" +env_logger = "0.11.2" log = "0.4.17" tokio = { version = "1", features = ["full"] } futures = "0.3" clap = { version = "4.2.7", features = ["derive"] } color-eyre = "0.6.2" -config = "0.13.3" +config = "0.14.0" dotenvy = "0.15.7" serde = "1.0.163" serde_derive = "1.0.163" @@ -31,5 +31,5 @@ serde_json = { version = "1.0.96", features = ["preserve_order"] } url = "2.4.0" rand = { version = "0.8.5", features = ["rand_chacha"] } lazy_static = "1.4.0" -sysinfo = "0.29.8" +sysinfo = "0.30.5" crossbeam-queue = "0.3.11" diff --git a/src/utils.rs b/src/utils.rs index 21e3800..7025539 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -20,7 +20,7 @@ use starknet::{ use tokio::task::JoinSet; use std::time::Duration; -use sysinfo::{CpuExt, System, SystemExt}; +use sysinfo::System; lazy_static! { pub static ref SYSINFO: SysInfo = SysInfo::new(); @@ -74,8 +74,8 @@ impl SysInfo { let cpu = sys.global_cpu_info(); Self { - os_name: sys.long_os_version().unwrap().trim().to_string(), - kernel_version: sys.kernel_version().unwrap(), + os_name: System::long_os_version().unwrap().trim().to_string(), + kernel_version: System::kernel_version().unwrap(), arch: std::env::consts::ARCH.to_string(), cpu_count: sys.cpus().len(), cpu_frequency: cpu.frequency(), From 231b957323c069263cb3b4685769574709c567c8 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Wed, 28 Feb 2024 14:41:19 +0200 Subject: [PATCH 07/45] Default UOP to 1 for other txs --- src/metrics.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/metrics.rs b/src/metrics.rs index a4a5fdb..15a30a3 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -336,13 +336,14 @@ fn tx_get_user_operations(tx: &Transaction) -> Result { Transaction::Invoke( InvokeTransaction::V0(InvokeTransactionV0 { calldata, .. }) | InvokeTransaction::V1(InvokeTransactionV1 { calldata, .. }), - ) => { + ) + | Transaction::L1Handler(L1HandlerTransaction { calldata, .. }) => { let &user_operations = calldata .first() .ok_or_eyre("Expected calldata to have at least one field element")?; user_operations.try_into()? } - _ => bail!("Unexpected transaction type when getting"), + _ => 1 // Other txs can be considered as 1 uop }) } From 034074aeb578714f7938e92acc9970b38ae5288a Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Wed, 28 Feb 2024 14:45:22 +0200 Subject: [PATCH 08/45] Add SPS --- Cargo.toml | 5 ++-- src/actions/goose.rs | 29 ++++++++++---------- src/actions/shoot.rs | 3 +- src/metrics.rs | 37 +++++++++++++++++++------ src/utils.rs | 65 ++++++++++++++++++++++++++++++++------------ 5 files changed, 94 insertions(+), 45 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bdd68f1..c45c062 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,8 +13,9 @@ description = "Gomu Gomu No Gatling is a blazing fast tool to benchmark Starknet opt-level = 3 [dependencies] -# Starknet dependencies -starknet = "0.6.0" +# Starknet dependencies, currently the same starknet revision as the one in +# madara https://github.com/keep-starknet-strange/madara/blob/main/Cargo.toml#L268 +starknet = { git = "https://github.com/xJonathanLEI/starknet-rs.git", rev = "64ebc36" } goose = "0.17.2" env_logger = "0.11.2" diff --git a/src/actions/goose.rs b/src/actions/goose.rs index 11c1159..caa69e1 100644 --- a/src/actions/goose.rs +++ b/src/actions/goose.rs @@ -13,15 +13,12 @@ use starknet::{ Account, Call, ConnectedAccount, ExecutionEncoder, RawExecution, SingleOwnerAccount, }, core::types::{ - ExecutionResult, FieldElement, InvokeTransactionResult, MaybePendingTransactionReceipt, - StarknetError, + BroadcastedInvokeTransaction, ExecutionResult, FieldElement, InvokeTransactionResult, + MaybePendingTransactionReceipt, }, macros::{felt, selector}, providers::{ - jsonrpc::{ - HttpTransport, HttpTransportError, JsonRpcClientError, JsonRpcError, JsonRpcMethod, - JsonRpcResponse, - }, + jsonrpc::{HttpTransport, JsonRpcError, JsonRpcMethod, JsonRpcResponse}, JsonRpcClient, ProviderError, }, signers::LocalWallet, @@ -200,13 +197,11 @@ struct GooseUserState { prev_tx: Vec, } -pub type RpcError = ProviderError>; - impl GooseUserState { pub async fn new( account: StarknetAccount, transactions_amount: usize, - ) -> Result { + ) -> Result { Ok(Self { nonce: account.get_nonce().await?, account, @@ -218,7 +213,7 @@ impl GooseUserState { async fn setup( accounts: Vec, transactions_amount: usize, -) -> Result { +) -> Result { let queue = ArrayQueue::new(accounts.len()); for account in accounts { queue @@ -395,6 +390,8 @@ pub async fn wait_for_tx( user.set_failure(&tag, &mut metrics, None, None)?; } + const TRANSACTION_HASH_NOT_FOUND: i64 = 29; + match receipt { JsonRpcResponse::Success { result: MaybePendingTransactionReceipt::Receipt(receipt), @@ -432,9 +429,13 @@ pub async fn wait_for_tx( tokio::time::sleep(CHECK_INTERVAL).await; } JsonRpcResponse::Error { - error: JsonRpcError { code, .. }, + error: + JsonRpcError { + code: TRANSACTION_HASH_NOT_FOUND, + .. + }, .. - } if code == StarknetError::TransactionHashNotFound as i64 => { + } => { log::debug!("Waiting for transaction {tx_hash:#064x} to show up"); tokio::time::sleep(CHECK_INTERVAL).await; } @@ -478,12 +479,12 @@ pub async fn send_execution( // see https://github.com/xJonathanLEI/starknet-rs/issues/538 let raw_exec = unsafe { mem::transmute::(raw_exec) }; - let param = starknet::core::types::BroadcastedInvokeTransaction { + let param = BroadcastedInvokeTransaction { sender_address: from_account.address(), calldata, max_fee: MAX_FEE, signature: from_account - .sign_execution(&raw_exec) + .sign_execution(&raw_exec, false) .await .expect("Raw Execution should be correctly constructed for signature"), nonce, diff --git a/src/actions/shoot.rs b/src/actions/shoot.rs index 6fc8204..dd7745f 100644 --- a/src/actions/shoot.rs +++ b/src/actions/shoot.rs @@ -18,9 +18,8 @@ use starknet::core::types::{ contract::legacy::LegacyContractClass, BlockId, BlockTag, FieldElement, StarknetError, }; use starknet::macros::{felt, selector}; -use starknet::providers::ProviderError; use starknet::providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}; -use starknet::providers::{MaybeUnknownErrorCode, StarknetErrorWithMessage}; +use starknet::providers::{MaybeUnknownErrorCode, ProviderError, StarknetErrorWithMessage}; use starknet::signers::{LocalWallet, SigningKey}; use std::str; use std::sync::Arc; diff --git a/src/metrics.rs b/src/metrics.rs index 15a30a3..a7c0045 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -9,7 +9,8 @@ use goose::metrics::{GooseMetrics, GooseRequestMetricTimingData}; use serde_derive::Serialize; use starknet::{ core::types::{ - BlockWithTxs, InvokeTransaction, InvokeTransactionV0, InvokeTransactionV1, Transaction, + BlockWithTxs, ExecutionResources, InvokeTransaction, InvokeTransactionV0, + InvokeTransactionV1, L1HandlerTransaction, Transaction, }, providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}, }; @@ -97,7 +98,7 @@ impl BenchmarkReport { } let blocks_with_txs = get_blocks_with_txs(starknet_rpc, start_block..=end_block).await?; - let metrics = compute_node_metrics(&blocks_with_txs)?; + let metrics = compute_node_metrics(blocks_with_txs)?; self.metrics.extend_from_slice(&metrics); @@ -114,7 +115,7 @@ impl BenchmarkReport { let start_block = end_block - num_blocks; let blocks_with_txs = get_blocks_with_txs(starknet_rpc, start_block..=end_block).await?; - let metrics = compute_node_metrics(&blocks_with_txs)?; + let metrics = compute_node_metrics(blocks_with_txs)?; self.last_x_blocks_metrics = Some(LastXBlocksMetric { num_blocks, @@ -289,8 +290,13 @@ impl fmt::Display for BenchmarkReport { } } -pub fn compute_node_metrics(blocks_with_txs: &[BlockWithTxs]) -> Result> { - let total_transactions: usize = blocks_with_txs.iter().map(|b| b.transactions.len()).sum(); +pub fn compute_node_metrics( + blocks_with_txs: Vec<(BlockWithTxs, Vec)>, +) -> Result> { + let total_transactions: usize = blocks_with_txs + .iter() + .map(|(b, _)| b.transactions.len()) + .sum(); let avg_tpb = total_transactions as f64 / blocks_with_txs.len() as f64; let mut metrics = vec![ @@ -306,8 +312,8 @@ pub fn compute_node_metrics(blocks_with_txs: &[BlockWithTxs]) -> Result Result, _>>()? .into_iter() .sum(); + let total_steps: u64 = blocks_with_txs + .iter() + .skip(1) + .flat_map(|(_, r)| r) + .map(|resource| resource.steps) + .sum(); + metrics.push(MetricResult { name: "Average UOPS", unit: "operations/second", value: (total_uops as f64 / time as f64).into(), - }) + }); + + metrics.push(MetricResult { + name: "Average Steps Per Second", + unit: "operations/second", + value: (total_steps as f64 / time as f64).into(), + }); } Ok(metrics) diff --git a/src/utils.rs b/src/utils.rs index 7025539..04d521c 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -7,16 +7,14 @@ use color_eyre::{eyre::eyre, Result}; use lazy_static::lazy_static; use log::debug; +use starknet::core::types::MaybePendingTransactionReceipt::{PendingReceipt, Receipt}; use starknet::core::types::{ - BlockId, BlockWithTxs, ExecutionResult, MaybePendingBlockWithTxs, StarknetError, + BlockId, BlockWithTxs, ExecutionResources, ExecutionResult, MaybePendingBlockWithTxs, + StarknetError, TransactionReceipt, }; use starknet::core::{crypto::compute_hash_on_elements, types::FieldElement}; use starknet::providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}; -use starknet::providers::{MaybeUnknownErrorCode, ProviderError}; -use starknet::{ - core::types::MaybePendingTransactionReceipt::{PendingReceipt, Receipt}, - providers::StarknetErrorWithMessage, -}; +use starknet::providers::{MaybeUnknownErrorCode, ProviderError, StarknetErrorWithMessage}; use tokio::task::JoinSet; use std::time::Duration; @@ -181,7 +179,7 @@ pub async fn wait_for_tx( pub async fn get_blocks_with_txs( starknet_rpc: &Arc>, block_range: impl Iterator, -) -> Result> { +) -> Result)>> { const MAX_CONCURRENT: usize = 50; // A collection of spawned tokio tasks @@ -197,28 +195,59 @@ pub async fn get_blocks_with_txs( .await .ok_or_eyre("JoinSet should have items")???; - results.push(match_result(next)?); + results.push(next); } let starknet_rpc = starknet_rpc.clone(); - join_set.spawn(async move { - starknet_rpc - .get_block_with_txs(BlockId::Number(block_number)) - .await - }); + join_set.spawn(get_block_info(starknet_rpc, block_number)); } // Process the rest while let Some(next) = join_set.join_next().await { - results.push(match_result(next??)?) + results.push(next??) } - fn match_result(maybe_block: MaybePendingBlockWithTxs) -> Result { - match maybe_block { - MaybePendingBlockWithTxs::Block(block) => Ok(block), - MaybePendingBlockWithTxs::PendingBlock(_) => bail!("Blocks should not be pending!"), + async fn get_block_info( + starknet_rpc: Arc>, + block_number: u64, + ) -> Result<(BlockWithTxs, Vec)> { + let block_with_txs = match starknet_rpc + .get_block_with_txs(BlockId::Number(block_number)) + .await? + { + MaybePendingBlockWithTxs::Block(b) => b, + MaybePendingBlockWithTxs::PendingBlock(pending) => { + bail!("Block should not be pending. Pending: {pending:?}") + } + }; + + let mut resources = Vec::with_capacity(block_with_txs.transactions.len()); + + for tx in block_with_txs.transactions.iter() { + let maybe_receipt = starknet_rpc + .get_transaction_receipt(tx.transaction_hash()) + .await?; + + use TransactionReceipt as TR; + + let resource = match maybe_receipt { + Receipt(receipt) => match receipt { + TR::Invoke(receipt) => receipt.execution_resources, + TR::L1Handler(receipt) => receipt.execution_resources, + TR::Declare(receipt) => receipt.execution_resources, + TR::Deploy(receipt) => receipt.execution_resources, + TR::DeployAccount(receipt) => receipt.execution_resources, + }, + PendingReceipt(pending) => { + bail!("Transaction should not be pending. Pending: {pending:?}"); + } + }; + + resources.push(resource); } + + Ok((block_with_txs, resources)) } Ok(results) From c0b1f1516c430ee118a520ff42d54cb7384e48b8 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Wed, 28 Feb 2024 14:53:14 +0200 Subject: [PATCH 09/45] Use return instead of ? to clarify intent for set_failure --- src/actions/goose.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/actions/goose.rs b/src/actions/goose.rs index 701f303..245675f 100644 --- a/src/actions/goose.rs +++ b/src/actions/goose.rs @@ -358,7 +358,7 @@ async fn verify_transactions(user: &mut GooseUser) -> TransactionResult { ExecutionResult::Reverted { reason } => { let tag = format!("Transaction {tx:#064x} has been rejected/reverted"); - user.set_failure(&tag, &mut metrics, None, Some(reason))?; + return user.set_failure(&tag, &mut metrics, None, Some(reason)); } }, MaybePendingTransactionReceipt::PendingReceipt(pending) => { @@ -366,7 +366,7 @@ async fn verify_transactions(user: &mut GooseUser) -> TransactionResult { format!("Transaction {tx:#064x} is pending when no transactions should be"); let body = format!("{pending:?}"); - user.set_failure(&tag, &mut metrics, None, Some(&body))?; + return user.set_failure(&tag, &mut metrics, None, Some(&body)); } } } @@ -388,7 +388,7 @@ pub async fn wait_for_tx( if start.elapsed().unwrap() >= WAIT_FOR_TX_TIMEOUT { let tag = format!("Timeout while waiting for transaction {tx_hash:#064x}"); - user.set_failure(&tag, &mut metrics, None, None)?; + return user.set_failure(&tag, &mut metrics, None, None); } match receipt { @@ -410,7 +410,7 @@ pub async fn wait_for_tx( "Transaction {tx_hash:#064x} has been rejected/reverted: {reason}" ); - user.set_failure(&tag, &mut metrics, None, None)?; + return user.set_failure(&tag, &mut metrics, None, None); } } } @@ -422,7 +422,7 @@ pub async fn wait_for_tx( let tag = format!("Transaction {tx_hash:#064x} has been rejected/reverted: {reason}"); - user.set_failure(&tag, &mut metrics, None, None)?; + return user.set_failure(&tag, &mut metrics, None, None); } log::debug!("Waiting for transaction {tx_hash:#064x} to be accepted"); tokio::time::sleep(CHECK_INTERVAL).await; @@ -442,7 +442,7 @@ pub async fn wait_for_tx( "Error Code {code} while waiting for transaction {tx_hash:#064x}: {message}" ); - user.set_failure(&tag, &mut metrics, None, None)?; + return user.set_failure(&tag, &mut metrics, None, None); } } } From 8ad31dc005e62a13ab8064bfa312fb49486ab88d Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Wed, 28 Feb 2024 15:05:26 +0200 Subject: [PATCH 10/45] Abstract out making individual reports --- src/actions/mod.rs | 76 ++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 36 deletions(-) diff --git a/src/actions/mod.rs b/src/actions/mod.rs index 5728a00..d8798c6 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -1,4 +1,6 @@ -use starknet::providers::Provider; +use ::goose::metrics::GooseMetrics; +use futures::Future; +use starknet::providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}; use crate::{ config::GatlingConfig, @@ -30,24 +32,13 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { let start_block = shooter.rpc_client().block_number().await?; if run_erc20 { - let start_block = shooter.rpc_client().block_number().await?; - let goose_metrics = goose::erc20(&shooter).await?; - let end_block = shooter.rpc_client().block_number().await?; - - let mut report = - BenchmarkReport::new("Erc20 Transfers", goose_metrics.scenarios[0].counter); - - report - .with_block_range(shooter.rpc_client(), start_block + 1, end_block) - .await?; - - if config.report.num_blocks != 0 { - report - .with_last_x_blocks(shooter.rpc_client(), config.report.num_blocks) - .await?; - } - - report.with_goose_metrics(&goose_metrics)?; + let report = make_report_over_bench( + goose::erc20(&shooter), + "Erc20 Transfers", + shooter.rpc_client(), + config.report.num_blocks, + ) + .await?; whole_report.benches.push(report); } else { @@ -55,23 +46,13 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { } if run_erc721 { - let start_block = shooter.rpc_client().block_number().await?; - let goose_metrics = goose::erc721(&shooter).await?; - let end_block = shooter.rpc_client().block_number().await?; - - let mut report = BenchmarkReport::new("Erc721 Mints", goose_metrics.scenarios[0].counter); - - report - .with_block_range(shooter.rpc_client(), start_block + 1, end_block) - .await?; - - if config.report.num_blocks != 0 { - report - .with_last_x_blocks(shooter.rpc_client(), config.report.num_blocks) - .await?; - } - - report.with_goose_metrics(&goose_metrics)?; + let report = make_report_over_bench( + goose::erc721(&shooter), + "Erc721 Mints", + shooter.rpc_client(), + config.report.num_blocks, + ) + .await?; whole_report.benches.push(report); } else { @@ -92,3 +73,26 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { Ok(()) } + +async fn make_report_over_bench( + bench: impl Future>, + name: &'static str, + rpc_client: &JsonRpcClient, + num_blocks: u64, +) -> color_eyre::Result { + let start_block = rpc_client.block_number().await?; + let goose_metrics = bench.await?; + let end_block = rpc_client.block_number().await?; + + let mut report = BenchmarkReport::new(name, goose_metrics.scenarios[0].counter); + report + .with_block_range(rpc_client, start_block + 1, end_block) + .await?; + + if num_blocks != 0 { + report.with_last_x_blocks(rpc_client, num_blocks).await?; + } + + report.with_goose_metrics(&goose_metrics)?; + Ok(report) +} From a79fc9e4823513af8eb3f0480612cea0ee5141c1 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Wed, 28 Feb 2024 15:15:45 +0200 Subject: [PATCH 11/45] Update README and rename Mean to Average --- README.md | 6 ++++-- src/metrics.rs | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 84cde52..3a95fac 100644 --- a/README.md +++ b/README.md @@ -112,19 +112,21 @@ At the end of all benchmarks gomu gomu will collect the results into a single js - `users`: The amount of goose users used to do the benchmarks, changed by `concurrency` -- `all_bench_report`: A report over all benchmarks done +- `all_bench_report`: A report over all benchmarks done, has a portion of metrics that `benches` has - `benches`: A array of reports for all benchmarks - `name`: The name of the benchmark - `amount`: How many times this benchmark was ran - - `metrics`: An array of metrics over the whole benchmark + - `metrics`: Metrics over the whole benchmark - `name`: The name of the metric - `unit`: The unit of the metric, empty when there is no unit - `value`: The metrics value, a number - For floats, `Infinite` and `NaN` are not JSON numbers and thus will be turned into `null` + - Values gotten from submission time are calculated from the latency to add a new transaction to the node + - Values gotten from verification time are calculated from the latency to get the transaction receipt after the transactions have been processed - `last_x_blocks_metrics`: Metrics over the last blocks of the benchmark diff --git a/src/metrics.rs b/src/metrics.rs index 99ca003..ece6523 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -171,7 +171,7 @@ impl BenchmarkReport { value: requests.min_time.into(), }, MetricResult { - name: "Mean Submission Time", + name: "Average Submission Time", unit: "milliseconds", value: (requests.total_time as f64 / scenario.counter as f64).into(), }, @@ -186,7 +186,7 @@ impl BenchmarkReport { value: verification_requests.raw_data.minimum_time.into(), }, MetricResult { - name: "Mean Verification Time", + name: "Average Verification Time", unit: "milliseconds", value: (verification_requests.raw_data.total_time as f64 / scenario.counter as f64) .into(), From cd115f7cd02e1c7b3d67a595395f9b44c950157f Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Fri, 1 Mar 2024 13:53:44 +0200 Subject: [PATCH 12/45] Fix block data not being ordered --- src/metrics.rs | 10 +++------- src/utils.rs | 13 ++++++++----- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/metrics.rs b/src/metrics.rs index a7c0045..c07121d 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -316,11 +316,8 @@ pub fn compute_node_metrics( let (last_block, _) = blocks_with_txs.last().ok_or_eyre("No last block")?; if first_block.timestamp != last_block.timestamp { - let time = last_block.timestamp - first_block.timestamp; - let total_uops: u64 = blocks_with_txs .iter() - .skip(1) // Skip first block as its creation time is the start time for this metric .flat_map(|(b, _)| &b.transactions) .map(tx_get_user_operations) .collect::, _>>()? @@ -329,7 +326,6 @@ pub fn compute_node_metrics( let total_steps: u64 = blocks_with_txs .iter() - .skip(1) .flat_map(|(_, r)| r) .map(|resource| resource.steps) .sum(); @@ -337,13 +333,13 @@ pub fn compute_node_metrics( metrics.push(MetricResult { name: "Average UOPS", unit: "operations/second", - value: (total_uops as f64 / time as f64).into(), + value: (total_uops as f64 / blocks_with_txs.len() as f64 / BLOCK_TIME as f64).into(), }); metrics.push(MetricResult { name: "Average Steps Per Second", unit: "operations/second", - value: (total_steps as f64 / time as f64).into(), + value: (total_steps as f64 / blocks_with_txs.len() as f64 / BLOCK_TIME as f64).into(), }); } @@ -363,6 +359,6 @@ fn tx_get_user_operations(tx: &Transaction) -> Result { user_operations.try_into()? } - _ => 1 // Other txs can be considered as 1 uop + _ => 1, // Other txs can be considered as 1 uop }) } diff --git a/src/utils.rs b/src/utils.rs index 04d521c..c9fab44 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -203,11 +203,6 @@ pub async fn get_blocks_with_txs( join_set.spawn(get_block_info(starknet_rpc, block_number)); } - // Process the rest - while let Some(next) = join_set.join_next().await { - results.push(next??) - } - async fn get_block_info( starknet_rpc: Arc>, block_number: u64, @@ -250,6 +245,14 @@ pub async fn get_blocks_with_txs( Ok((block_with_txs, resources)) } + // Process the rest + while let Some(next) = join_set.join_next().await { + results.push(next??) + } + + // Make sure blocks are in order + results.sort_unstable_by_key(|(block, _)| block.block_number); + Ok(results) } From 481d0b19372e219b8695da517df4607fd62f8902 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Thu, 7 Mar 2024 16:31:58 +0200 Subject: [PATCH 13/45] Refactors for goose reporting --- src/actions/goose.rs | 26 +++++++++++--------------- src/actions/mod.rs | 31 +++++++++++++++---------------- src/metrics.rs | 28 +++++++++++++--------------- 3 files changed, 39 insertions(+), 46 deletions(-) diff --git a/src/actions/goose.rs b/src/actions/goose.rs index 245675f..155b6e8 100644 --- a/src/actions/goose.rs +++ b/src/actions/goose.rs @@ -383,14 +383,16 @@ pub async fn wait_for_tx( let start = SystemTime::now(); loop { - let (receipt, mut metrics) = + let (receipt, mut metric) = raw_send_request(user, JsonRpcMethod::GetTransactionReceipt, tx_hash).await?; if start.elapsed().unwrap() >= WAIT_FOR_TX_TIMEOUT { let tag = format!("Timeout while waiting for transaction {tx_hash:#064x}"); - return user.set_failure(&tag, &mut metrics, None, None); + return user.set_failure(&tag, &mut metric, None, None); } + let reverted_tag = || format!("Transaction {tx_hash:#064x} has been rejected/reverted"); + match receipt { JsonRpcResponse::Success { result: MaybePendingTransactionReceipt::Receipt(receipt), @@ -406,11 +408,7 @@ pub async fn wait_for_tx( return Ok(()); } ExecutionResult::Reverted { reason } => { - let tag = format!( - "Transaction {tx_hash:#064x} has been rejected/reverted: {reason}" - ); - - return user.set_failure(&tag, &mut metrics, None, None); + return user.set_failure(&reverted_tag(), &mut metric, None, Some(reason)); } } } @@ -419,10 +417,7 @@ pub async fn wait_for_tx( .. } => { if let ExecutionResult::Reverted { reason } = pending.execution_result() { - let tag = - format!("Transaction {tx_hash:#064x} has been rejected/reverted: {reason}"); - - return user.set_failure(&tag, &mut metrics, None, None); + return user.set_failure(&reverted_tag(), &mut metric, None, Some(reason)); } log::debug!("Waiting for transaction {tx_hash:#064x} to be accepted"); tokio::time::sleep(CHECK_INTERVAL).await; @@ -438,16 +433,15 @@ pub async fn wait_for_tx( error: JsonRpcError { code, message }, .. } => { - let tag = format!( - "Error Code {code} while waiting for transaction {tx_hash:#064x}: {message}" - ); + let tag = format!("Error Code {code} while waiting for tx {tx_hash:#064x}"); - return user.set_failure(&tag, &mut metrics, None, None); + return user.set_failure(&tag, &mut metric, None, Some(&message)); } } } } +/// Sends a execution request via goose, returning the successful json rpc response pub async fn send_execution( user: &mut GooseUser, calls: Vec, @@ -489,6 +483,7 @@ pub async fn send_execution( send_request(user, method, param).await } +/// Sends request via goose, returning the successful json rpc response pub async fn send_request( user: &mut GooseUser, method: JsonRpcMethod, @@ -512,6 +507,7 @@ pub async fn send_request( } } +/// Sends request via goose, returning the deserialized response pub async fn raw_send_request( user: &mut GooseUser, method: JsonRpcMethod, diff --git a/src/actions/mod.rs b/src/actions/mod.rs index d8798c6..033939d 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -4,7 +4,7 @@ use starknet::providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}; use crate::{ config::GatlingConfig, - metrics::{BenchmarkReport, WholeReport}, + metrics::{BenchmarkReport, GlobalReport}, }; use self::shoot::GatlingShooterSetup; @@ -15,16 +15,15 @@ mod shoot; pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { let run_erc20 = config.run.num_erc20_transfers != 0; let run_erc721 = config.run.num_erc721_mints != 0; + let total_txs = config.run.num_erc20_transfers + config.run.num_erc721_mints; + let num_blocks = config.report.num_blocks; - let mut shooter = GatlingShooterSetup::from_config(config.clone()).await?; + let mut shooter = GatlingShooterSetup::from_config(config).await?; shooter.setup().await?; - let mut whole_report = WholeReport { + let mut global_report = GlobalReport { users: shooter.config().run.concurrency, - all_bench_report: BenchmarkReport::new( - "", - (config.run.num_erc20_transfers + config.run.num_erc721_mints) as usize, - ), + all_bench_report: BenchmarkReport::new("".into(), total_txs as usize), benches: Vec::new(), extra: crate::utils::sysinfo_string(), }; @@ -34,13 +33,13 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { if run_erc20 { let report = make_report_over_bench( goose::erc20(&shooter), - "Erc20 Transfers", + "Erc20 Transfers".into(), shooter.rpc_client(), - config.report.num_blocks, + num_blocks, ) .await?; - whole_report.benches.push(report); + global_report.benches.push(report); } else { log::info!("Skipping erc20 transfers") } @@ -48,20 +47,20 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { if run_erc721 { let report = make_report_over_bench( goose::erc721(&shooter), - "Erc721 Mints", + "Erc721 Mints".into(), shooter.rpc_client(), - config.report.num_blocks, + num_blocks, ) .await?; - whole_report.benches.push(report); + global_report.benches.push(report); } else { log::info!("Skipping erc721 mints") } let end_block = shooter.rpc_client().block_number().await?; - whole_report + global_report .all_bench_report .with_block_range(shooter.rpc_client(), start_block, end_block) .await?; @@ -69,14 +68,14 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { let report_path = shooter.config().report.location.with_extension("json"); let writer = std::fs::File::create(report_path)?; - serde_json::to_writer_pretty(writer, &whole_report)?; + serde_json::to_writer_pretty(writer, &global_report)?; Ok(()) } async fn make_report_over_bench( bench: impl Future>, - name: &'static str, + name: String, rpc_client: &JsonRpcClient, num_blocks: u64, ) -> color_eyre::Result { diff --git a/src/metrics.rs b/src/metrics.rs index ece6523..0e8efa7 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -5,7 +5,7 @@ use color_eyre::{ Result, }; -use goose::metrics::GooseMetrics; +use goose::metrics::{GooseMetrics, TransactionMetricAggregate}; use serde_derive::Serialize; use starknet::providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}; use std::fmt; @@ -13,7 +13,7 @@ use std::fmt; pub const BLOCK_TIME: u64 = 6; #[derive(Clone, Debug, Serialize)] -pub struct WholeReport { +pub struct GlobalReport { pub users: u64, pub all_bench_report: BenchmarkReport, pub benches: Vec, @@ -48,14 +48,14 @@ pub struct MetricResult { pub value: serde_json::Value, } -/// A benchmark report contains a name and a vector of metric results -/// of all the metrics that were computed for the benchmark -/// A benchmark report can be created from a block range or from the last x blocks +/// A benchmark report contains the metrics for a single benchmark +/// it also includes the name, amount of times it was ran and +/// optionally metrics over the last x blocks /// It implements the Serialize trait so it can be serialized to json #[derive(Debug, Clone, Serialize)] pub struct BenchmarkReport { #[serde(skip_serializing_if = "str::is_empty")] - pub name: &'static str, + pub name: String, pub amount: usize, pub metrics: Vec, #[serde(skip_serializing_if = "Option::is_none")] @@ -69,7 +69,7 @@ pub struct LastXBlocksMetric { } impl BenchmarkReport { - pub fn new(name: &'static str, amount: usize) -> BenchmarkReport { + pub fn new(name: String, amount: usize) -> BenchmarkReport { BenchmarkReport { name, amount, @@ -120,11 +120,6 @@ impl BenchmarkReport { } pub fn with_goose_metrics(&mut self, metrics: &GooseMetrics) -> Result<()> { - let scenario = metrics - .scenarios - .first() - .ok_or(eyre!("There is no scenario"))?; - let transactions = metrics .transactions .first() @@ -173,7 +168,7 @@ impl BenchmarkReport { MetricResult { name: "Average Submission Time", unit: "milliseconds", - value: (requests.total_time as f64 / scenario.counter as f64).into(), + value: transaction_average(requests).into(), }, MetricResult { name: "Max Verification Time", @@ -188,8 +183,7 @@ impl BenchmarkReport { MetricResult { name: "Average Verification Time", unit: "milliseconds", - value: (verification_requests.raw_data.total_time as f64 / scenario.counter as f64) - .into(), + value: transaction_average(requests).into(), }, ]); @@ -197,6 +191,10 @@ impl BenchmarkReport { } } +fn transaction_average(requests: &TransactionMetricAggregate) -> f64 { + requests.total_time as f64 / requests.counter as f64 +} + impl fmt::Display for MetricResult { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let Self { name, value, unit } = self; From 8d1046f4e14779e3b34c01009bd93d6a518dfff2 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Thu, 7 Mar 2024 16:54:25 +0200 Subject: [PATCH 14/45] Fix goose wait_for_tx not found case --- src/actions/goose.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/actions/goose.rs b/src/actions/goose.rs index 155b6e8..69fb936 100644 --- a/src/actions/goose.rs +++ b/src/actions/goose.rs @@ -14,7 +14,6 @@ use starknet::{ }, core::types::{ ExecutionResult, FieldElement, InvokeTransactionResult, MaybePendingTransactionReceipt, - StarknetError, }, macros::{felt, selector}, providers::{ @@ -393,6 +392,8 @@ pub async fn wait_for_tx( let reverted_tag = || format!("Transaction {tx_hash:#064x} has been rejected/reverted"); + const TRANSACTION_HASH_NOT_FOUND: i64 = 29; + match receipt { JsonRpcResponse::Success { result: MaybePendingTransactionReceipt::Receipt(receipt), @@ -423,9 +424,13 @@ pub async fn wait_for_tx( tokio::time::sleep(CHECK_INTERVAL).await; } JsonRpcResponse::Error { - error: JsonRpcError { code, .. }, + error: + JsonRpcError { + code: TRANSACTION_HASH_NOT_FOUND, + .. + }, .. - } if code == StarknetError::TransactionHashNotFound as i64 => { + } => { log::debug!("Waiting for transaction {tx_hash:#064x} to show up"); tokio::time::sleep(CHECK_INTERVAL).await; } From d7c66001f0c9ccb189305959957a0efd1fbbe285 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Wed, 13 Mar 2024 10:41:22 +0200 Subject: [PATCH 15/45] Rename report location and remove SysInfo Default impl --- README.md | 4 ++-- config/default.yaml | 2 +- config/katana.yaml | 2 +- config/sharingan.yaml | 2 +- config/v2.1.0.yaml | 2 +- src/actions/mod.rs | 2 +- src/config.rs | 2 +- src/utils.rs | 7 +------ 8 files changed, 9 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 3a95fac..d9ef196 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ The configuration is defined by the following spec - `report` - `num_blocks`: Number of last blocks to take into account in the report - - `location`: Path to the file where to save the reports + - `output_location`: Path to the file where to save the reports - `deployer` @@ -106,7 +106,7 @@ gatling shoot -c config/default.yaml ### Output -The main output of gomu gomu is the report location specified in specified in the configuration file. +The main output of gomu gomu is the report output location specified in specified in the configuration file. At the end of all benchmarks gomu gomu will collect the results into a single json file with the following structure: diff --git a/config/default.yaml b/config/default.yaml index 1c2a49b..d8dcd0f 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -22,7 +22,7 @@ run: report: num_blocks: 4 - location: "report" + output_location: "report" deployer: salt: "1" diff --git a/config/katana.yaml b/config/katana.yaml index 58c6cd9..d13c008 100644 --- a/config/katana.yaml +++ b/config/katana.yaml @@ -22,7 +22,7 @@ run: report: num_blocks: 4 - location: "report" + output_location: "report" deployer: salt: "1" diff --git a/config/sharingan.yaml b/config/sharingan.yaml index dbe12d7..5a18d48 100644 --- a/config/sharingan.yaml +++ b/config/sharingan.yaml @@ -22,7 +22,7 @@ run: report: num_blocks: 4 - location: "report" + output_location: "report" # need to add an adress and signing key on sharingan network deployer: diff --git a/config/v2.1.0.yaml b/config/v2.1.0.yaml index 2a830da..68b92ce 100644 --- a/config/v2.1.0.yaml +++ b/config/v2.1.0.yaml @@ -28,7 +28,7 @@ run: report: num_blocks: 3 - location: "report" + output_location: "report" deployer: salt: "1" diff --git a/src/actions/mod.rs b/src/actions/mod.rs index 033939d..04f273b 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -65,7 +65,7 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { .with_block_range(shooter.rpc_client(), start_block, end_block) .await?; - let report_path = shooter.config().report.location.with_extension("json"); + let report_path = shooter.config().report.output_location.with_extension("json"); let writer = std::fs::File::create(report_path)?; serde_json::to_writer_pretty(writer, &global_report)?; diff --git a/src/config.rs b/src/config.rs index 1ab23ab..715694e 100644 --- a/src/config.rs +++ b/src/config.rs @@ -111,7 +111,7 @@ pub struct RunConfig { #[derive(Debug, Deserialize, Clone)] pub struct ReportConfig { pub num_blocks: u64, - pub location: PathBuf, + pub output_location: PathBuf, } impl GatlingConfig { diff --git a/src/utils.rs b/src/utils.rs index 121511d..5f818a1 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -64,6 +64,7 @@ pub struct SysInfo { } impl SysInfo { + #[allow(clippy::new_without_default)] pub fn new() -> Self { let sys = System::new_all(); let cpu = sys.global_cpu_info(); @@ -104,12 +105,6 @@ pub fn sysinfo_string() -> String { ) } -impl Default for SysInfo { - fn default() -> Self { - Self::new() - } -} - const WAIT_FOR_TX_TIMEOUT: Duration = Duration::from_secs(60); pub async fn wait_for_tx( From be3edb38f38aa498de558173c070c68849ec90e1 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Wed, 13 Mar 2024 10:44:11 +0200 Subject: [PATCH 16/45] Create GOOSE_TIME_UNIT constant --- src/metrics.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/metrics.rs b/src/metrics.rs index 0e8efa7..942bef2 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -134,15 +134,17 @@ impl BenchmarkReport { .get("POST Verification") .ok_or(eyre!("Found no verification request metrics"))?; + const GOOSE_TIME_UNIT: &str = "milliseconds"; + self.metrics.extend_from_slice(&[ MetricResult { name: "Total Submission Time", - unit: "milliseconds", + unit: GOOSE_TIME_UNIT, value: requests.total_time.into(), }, MetricResult { name: "Total Verification Time", - unit: "milliseconds", + unit: GOOSE_TIME_UNIT, value: verification.total_time.into(), }, MetricResult { @@ -157,32 +159,32 @@ impl BenchmarkReport { }, MetricResult { name: "Max Submission Time", - unit: "milliseconds", + unit: GOOSE_TIME_UNIT, value: requests.max_time.into(), }, MetricResult { name: "Min Submission Time", - unit: "milliseconds", + unit: GOOSE_TIME_UNIT, value: requests.min_time.into(), }, MetricResult { name: "Average Submission Time", - unit: "milliseconds", + unit: GOOSE_TIME_UNIT, value: transaction_average(requests).into(), }, MetricResult { name: "Max Verification Time", - unit: "milliseconds", + unit: GOOSE_TIME_UNIT, value: verification_requests.raw_data.maximum_time.into(), }, MetricResult { name: "Min Verification Time", - unit: "milliseconds", + unit: GOOSE_TIME_UNIT, value: verification_requests.raw_data.minimum_time.into(), }, MetricResult { name: "Average Verification Time", - unit: "milliseconds", + unit: GOOSE_TIME_UNIT, value: transaction_average(requests).into(), }, ]); From 956df85e443c8cc836cdac0ee761cdb371d641aa Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Wed, 13 Mar 2024 10:44:55 +0200 Subject: [PATCH 17/45] cargo fmt --- src/actions/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/actions/mod.rs b/src/actions/mod.rs index 04f273b..2c0bb8d 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -65,7 +65,11 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { .with_block_range(shooter.rpc_client(), start_block, end_block) .await?; - let report_path = shooter.config().report.output_location.with_extension("json"); + let report_path = shooter + .config() + .report + .output_location + .with_extension("json"); let writer = std::fs::File::create(report_path)?; serde_json::to_writer_pretty(writer, &global_report)?; From bb5603d3d770dd5ab31813491ba1a7361594d682 Mon Sep 17 00:00:00 2001 From: Angel Petrov <146711006+Angel-Petrov@users.noreply.github.com> Date: Wed, 13 Mar 2024 13:16:49 +0200 Subject: [PATCH 18/45] Add GOOSE_TIME_UNIT for P90/P50 --- src/metrics.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/metrics.rs b/src/metrics.rs index cc00763..d2096c7 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -204,12 +204,12 @@ impl BenchmarkReport { self.metrics.extend_from_slice(&[ MetricResult { name: "P90 Submission Time", - unit: "milliseconds", + unit: GOOSE_TIME_UNIT, value: sub_90.into(), }, MetricResult { name: "P50 Submission Time", - unit: "milliseconds", + unit: GOOSE_TIME_UNIT, value: sub_p50.into(), }, ]) @@ -219,12 +219,12 @@ impl BenchmarkReport { self.metrics.extend_from_slice(&[ MetricResult { name: "P90 Verification Time", - unit: "milliseconds", + unit: GOOSE_TIME_UNIT, value: ver_p90.into(), }, MetricResult { name: "P50 Verification Time", - unit: "milliseconds", + unit: GOOSE_TIME_UNIT, value: ver_p50.into(), }, ]) From f59f1ff3db84eb0d59193fe51890c4c3abb5230f Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Wed, 13 Mar 2024 13:23:55 +0200 Subject: [PATCH 19/45] Add Get Events and genric read metrics --- config/default.yaml | 1 + config/katana.yaml | 1 + config/sharingan.yaml | 1 + config/v2.1.0.yaml | 1 + src/actions/goose.rs | 82 +++++++++++++++++++++++++++++++++++-------- src/actions/mod.rs | 48 ++++++++++++++++++++----- src/config.rs | 1 + src/metrics.rs | 53 ++++++++++++++++++++++++++-- src/utils.rs | 2 +- 9 files changed, 162 insertions(+), 28 deletions(-) diff --git a/config/default.yaml b/config/default.yaml index d8dcd0f..6c7a90b 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -18,6 +18,7 @@ setup: run: num_erc20_transfers: 1000 num_erc721_mints: 1000 + num_get_events: 1000 concurrency: 5 report: diff --git a/config/katana.yaml b/config/katana.yaml index d13c008..00d145a 100644 --- a/config/katana.yaml +++ b/config/katana.yaml @@ -18,6 +18,7 @@ setup: run: num_erc20_transfers: 300 num_erc721_mints: 300 + num_get_events: 300 concurrency: 5 report: diff --git a/config/sharingan.yaml b/config/sharingan.yaml index 5a18d48..376980a 100644 --- a/config/sharingan.yaml +++ b/config/sharingan.yaml @@ -18,6 +18,7 @@ setup: run: num_erc20_transfers: 1200 num_erc721_mints: 1200 + num_get_events: 1200 concurrency: 5 report: diff --git a/config/v2.1.0.yaml b/config/v2.1.0.yaml index 68b92ce..d97b9f7 100644 --- a/config/v2.1.0.yaml +++ b/config/v2.1.0.yaml @@ -24,6 +24,7 @@ setup: run: num_erc20_transfers: 100 num_erc721_mints: 100 + num_get_events: 100 concurrency: 5 report: diff --git a/src/actions/goose.rs b/src/actions/goose.rs index 1bb27bb..452b0b7 100644 --- a/src/actions/goose.rs +++ b/src/actions/goose.rs @@ -68,7 +68,7 @@ pub async fn erc20(shooter: &GatlingShooterSetup) -> color_eyre::Result color_eyre::Result color_eyre::Result, } -impl GooseUserState { +impl GooseWriteUserState { pub async fn new( account: StarknetAccount, transactions_amount: usize, @@ -217,7 +217,7 @@ async fn setup( let queue = ArrayQueue::new(accounts.len()); for account in accounts { queue - .push(GooseUserState::new(account, transactions_amount).await?) + .push(GooseWriteUserState::new(account, transactions_amount).await?) .expect("Queue should have enough space for all accounts as it's length is from the accounts vec"); } let queue = Arc::new(queue); @@ -234,10 +234,10 @@ async fn setup( })) } -fn goose_user_wait_last_tx() -> TransactionFunction { +fn goose_write_user_wait_last_tx() -> TransactionFunction { Arc::new(move |user| { let tx = user - .get_session_data::() + .get_session_data::() .expect("Should be in a goose user with GooseUserState session data") .prev_tx .last() @@ -254,6 +254,58 @@ fn goose_user_wait_last_tx() -> TransactionFunction { }) } +pub async fn read_method( + shooter: &GatlingShooterSetup, + amount: u64, + method: JsonRpcMethod, + parameters: serde_json::Value, +) -> color_eyre::Result { + let config = shooter.config(); + + ensure!( + amount >= config.run.concurrency, + "Too few reads for the amount of concurrency" + ); + + // div_euclid will truncate integers when not evenly divisable + let user_iterations = amount.div_euclid(config.run.concurrency); + // this will always be a multiple of concurrency, unlike the provided amount + let total_transactions = user_iterations * config.run.concurrency; + + // If these are not equal that means user_iterations was truncated + if total_transactions != amount { + log::warn!("Number of erc721 mints is not evenly divisble by concurrency, doing {total_transactions} mints instead"); + } + + let goose_get_events_config = { + let mut default = GooseConfiguration::default(); + default.host = config.rpc.url.clone(); + default.iterations = user_iterations as usize; + default.users = Some(config.run.concurrency as usize); + default + }; + + let events: TransactionFunction = Arc::new(move |user| { + let paramaters = parameters.clone(); + + Box::pin(async move { + let _: (serde_json::Value, _) = send_request(user, method, paramaters).await?; + + Ok(()) + }) + }); + + let metrics = GooseAttack::initialize_with_config(goose_get_events_config)? + .register_scenario( + scenario!("Read Metric") + .register_transaction(Transaction::new(events).set_name("Request")), + ) + .execute() + .await?; + + Ok(metrics) +} + // Hex: 0xdead // from_hex_be isn't const whereas from_mont is const VOID_ADDRESS: FieldElement = FieldElement::from_mont([ @@ -264,8 +316,8 @@ const VOID_ADDRESS: FieldElement = FieldElement::from_mont([ ]); async fn transfer(user: &mut GooseUser, erc20_address: FieldElement) -> TransactionResult { - let GooseUserState { account, nonce, .. } = user - .get_session_data::() + let GooseWriteUserState { account, nonce, .. } = user + .get_session_data::() .expect("Should be in a goose user with GooseUserState session data"); let (amount_low, amount_high) = (felt!("1"), felt!("0")); @@ -286,8 +338,8 @@ async fn transfer(user: &mut GooseUser, erc20_address: FieldElement) -> Transact .await? .0; - let GooseUserState { nonce, prev_tx, .. } = - user.get_session_data_mut::().expect( + let GooseWriteUserState { nonce, prev_tx, .. } = + user.get_session_data_mut::().expect( "Should be successful as we already asserted that the session data is a GooseUserState", ); @@ -305,7 +357,7 @@ async fn mint( from_account: &SingleOwnerAccount>, LocalWallet>, ) -> TransactionResult { let recipient = user - .get_session_data::() + .get_session_data::() .expect("Should be in a goose user with GooseUserState session data") .account .clone() @@ -329,7 +381,7 @@ async fn mint( .await? .0; - user.get_session_data_mut::() + user.get_session_data_mut::() .expect( "Should be successful as we already asserted that the session data is a GooseUserState", ) @@ -342,7 +394,7 @@ async fn mint( async fn verify_transactions(user: &mut GooseUser) -> TransactionResult { let transactions = mem::take( &mut user - .get_session_data_mut::() + .get_session_data_mut::() .expect("Should be in a goose user with GooseUserState session data") .prev_tx, ); @@ -391,7 +443,7 @@ pub async fn wait_for_tx( } let reverted_tag = || format!("Transaction {tx_hash:#064x} has been rejected/reverted"); - + const TRANSACTION_HASH_NOT_FOUND: i64 = 29; match receipt { diff --git a/src/actions/mod.rs b/src/actions/mod.rs index 843521a..9423cf8 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -2,7 +2,14 @@ use std::sync::Arc; use ::goose::metrics::GooseMetrics; use futures::Future; -use starknet::providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}; +use serde_json::json; +use starknet::{ + core::types::BlockId, + providers::{ + jsonrpc::{HttpTransport, JsonRpcMethod}, + JsonRpcClient, Provider, + }, +}; use crate::{ config::GatlingConfig, @@ -15,8 +22,6 @@ mod goose; mod shoot; pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { - let run_erc20 = config.run.num_erc20_transfers != 0; - let run_erc721 = config.run.num_erc721_mints != 0; let total_txs = config.run.num_erc20_transfers + config.run.num_erc721_mints; let num_blocks = config.report.num_blocks; @@ -32,8 +37,8 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { let start_block = shooter.rpc_client().block_number().await?; - if run_erc20 { - let report = make_report_over_bench( + if shooter.config().run.num_erc20_transfers != 0 { + let report = make_report_over_write_bench( goose::erc20(&shooter), "Erc20 Transfers".into(), shooter.rpc_client(), @@ -46,8 +51,8 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { log::info!("Skipping erc20 transfers") } - if run_erc721 { - let report = make_report_over_bench( + if shooter.config().run.num_erc721_mints != 0 { + let report = make_report_over_write_bench( goose::erc721(&shooter), "Erc721 Mints".into(), shooter.rpc_client(), @@ -62,6 +67,31 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { let end_block = shooter.rpc_client().block_number().await?; + let num_get_events = shooter.config().run.num_get_events; + if num_get_events != 0 { + let request = json!( + { + "from_block": BlockId::Number(start_block), + "to_block": BlockId::Number(end_block), + "address": null, + "keys": [], + "continuation_token": null, + "chunk_size": global_report.all_bench_report.amount as u64 + } + ); + + let metrics = + goose::read_method(&shooter, num_get_events, JsonRpcMethod::GetEvents, request).await?; + + let mut report = BenchmarkReport::new("Get Events".into(), metrics.scenarios[0].counter); + + report.with_goose_read_metrics(&metrics)?; + + global_report.benches.push(report); + } else { + log::info!("Skipping get events") + } + global_report .all_bench_report .with_block_range(shooter.rpc_client(), start_block, end_block) @@ -79,7 +109,7 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { Ok(()) } -async fn make_report_over_bench( +async fn make_report_over_write_bench( bench: impl Future>, name: String, rpc_client: &Arc>, @@ -98,6 +128,6 @@ async fn make_report_over_bench( report.with_last_x_blocks(rpc_client, num_blocks).await?; } - report.with_goose_metrics(&goose_metrics)?; + report.with_goose_write_metrics(&goose_metrics)?; Ok(report) } diff --git a/src/config.rs b/src/config.rs index 715694e..a990741 100644 --- a/src/config.rs +++ b/src/config.rs @@ -105,6 +105,7 @@ pub struct DeployerConfig { pub struct RunConfig { pub num_erc20_transfers: u64, pub num_erc721_mints: u64, + pub num_get_events: u64, pub concurrency: u64, } diff --git a/src/metrics.rs b/src/metrics.rs index d2096c7..b450ee7 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -42,6 +42,8 @@ pub struct NodeMetrics { pub compute: fn(&[u64]) -> f64, } +const GOOSE_TIME_UNIT: &str = "milliseconds"; + /// A struct that contains the result of a metric computation alognside the name and unit /// This struct is used for displaying the metric result /// Example: @@ -125,7 +127,7 @@ impl BenchmarkReport { Ok(()) } - pub fn with_goose_metrics(&mut self, metrics: &GooseMetrics) -> Result<()> { + pub fn with_goose_write_metrics(&mut self, metrics: &GooseMetrics) -> Result<()> { let transactions = metrics .transactions .first() @@ -145,8 +147,6 @@ impl BenchmarkReport { .get("POST Verification") .ok_or_eyre("Found no verification request metrics")?; - const GOOSE_TIME_UNIT: &str = "milliseconds"; - self.metrics.extend_from_slice(&[ MetricResult { name: "Total Submission Time", @@ -232,6 +232,53 @@ impl BenchmarkReport { Ok(()) } + + pub fn with_goose_read_metrics(&mut self, metrics: &GooseMetrics) -> color_eyre::Result<()> { + let requests = metrics + .requests + .get("POST Request") + .ok_or_eyre("Found no read request metrics")?; + + self.metrics.extend_from_slice(&[ + MetricResult { + name: "Total Time", + unit: GOOSE_TIME_UNIT, + value: requests.raw_data.total_time.into(), + }, + MetricResult { + name: "Max Time", + unit: GOOSE_TIME_UNIT, + value: requests.raw_data.maximum_time.into(), + }, + MetricResult { + name: "Min Time", + unit: GOOSE_TIME_UNIT, + value: requests.raw_data.minimum_time.into(), + }, + MetricResult { + name: "Average Time", + unit: GOOSE_TIME_UNIT, + value: (requests.raw_data.total_time as f64 / requests.success_count as f64).into(), + }, + ]); + + if let Some((ver_p50, ver_p90)) = calculate_p50_and_p90(&requests.raw_data) { + self.metrics.extend_from_slice(&[ + MetricResult { + name: "P90 Verification Time", + unit: GOOSE_TIME_UNIT, + value: ver_p90.into(), + }, + MetricResult { + name: "P50 Verification Time", + unit: GOOSE_TIME_UNIT, + value: ver_p50.into(), + }, + ]) + } + + Ok(()) + } } fn transaction_average(timings: &GooseRequestMetricTimingData) -> f64 { diff --git a/src/utils.rs b/src/utils.rs index 2fba241..f3e2cd7 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -244,7 +244,7 @@ pub async fn get_blocks_with_txs( while let Some(next) = join_set.join_next().await { results.push(next??) } - + // Make sure blocks are in order results.sort_unstable_by_key(|(block, _)| block.block_number); From 48031a2df2488b28b67f2b9775056a18757f3d72 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Wed, 13 Mar 2024 15:00:30 +0200 Subject: [PATCH 20/45] Make block range rpc errors not throw on error --- src/actions/mod.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/actions/mod.rs b/src/actions/mod.rs index 9423cf8..813d895 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -92,10 +92,14 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { log::info!("Skipping get events") } - global_report + let rpc_result = global_report .all_bench_report .with_block_range(shooter.rpc_client(), start_block, end_block) - .await?; + .await; + + if let Err(error) = rpc_result { + log::error!("Failed to get block range: {error}") + } let report_path = shooter .config() @@ -120,11 +124,14 @@ async fn make_report_over_write_bench( let end_block = rpc_client.block_number().await?; let mut report = BenchmarkReport::new(name, goose_metrics.scenarios[0].counter); - report + + let rpc_result = report .with_block_range(rpc_client, start_block + 1, end_block) - .await?; + .await; - if num_blocks != 0 { + if let Err(error) = rpc_result { + log::error!("Failed to get block range: {error}") + } else if num_blocks != 0 { report.with_last_x_blocks(rpc_client, num_blocks).await?; } From 77ffb55b98029389c5ec44bbbbf42e915f217203 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Fri, 15 Mar 2024 12:01:25 +0200 Subject: [PATCH 21/45] Add failed requests to temp events chunk size --- src/actions/mod.rs | 2 +- src/metrics.rs | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/actions/mod.rs b/src/actions/mod.rs index 813d895..edc93a6 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -76,7 +76,7 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { "address": null, "keys": [], "continuation_token": null, - "chunk_size": global_report.all_bench_report.amount as u64 + "chunk_size": 10 } ); diff --git a/src/metrics.rs b/src/metrics.rs index b450ee7..639cd22 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -260,6 +260,11 @@ impl BenchmarkReport { unit: GOOSE_TIME_UNIT, value: (requests.raw_data.total_time as f64 / requests.success_count as f64).into(), }, + MetricResult { + name: "Failed Requests", + unit: "", + value: requests.fail_count.into(), + }, ]); if let Some((ver_p50, ver_p90)) = calculate_p50_and_p90(&requests.raw_data) { From 7faff254517694c232184d369a530c7f50958c32 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Fri, 15 Mar 2024 14:57:52 +0200 Subject: [PATCH 22/45] Lower number of get events to reasonable number --- config/default.yaml | 8 ++++++-- config/katana.yaml | 2 +- config/sharingan.yaml | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/config/default.yaml b/config/default.yaml index 6c7a90b..037b672 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -18,8 +18,12 @@ setup: run: num_erc20_transfers: 1000 num_erc721_mints: 1000 - num_get_events: 1000 - concurrency: 5 + num_get_events: 100 + concurrency: 10 + +# read_metrics: +# get_events: +# parameters_loc: "params.json" report: num_blocks: 4 diff --git a/config/katana.yaml b/config/katana.yaml index 00d145a..7fc938c 100644 --- a/config/katana.yaml +++ b/config/katana.yaml @@ -18,7 +18,7 @@ setup: run: num_erc20_transfers: 300 num_erc721_mints: 300 - num_get_events: 300 + num_get_events: 100 concurrency: 5 report: diff --git a/config/sharingan.yaml b/config/sharingan.yaml index 376980a..4c68486 100644 --- a/config/sharingan.yaml +++ b/config/sharingan.yaml @@ -18,7 +18,7 @@ setup: run: num_erc20_transfers: 1200 num_erc721_mints: 1200 - num_get_events: 1200 + num_get_events: 100 concurrency: 5 report: From ba2205a6a062192f4dbd62f54894595f7c90ece2 Mon Sep 17 00:00:00 2001 From: Angel Petrov <146711006+Angel-Petrov@users.noreply.github.com> Date: Fri, 15 Mar 2024 14:59:41 +0200 Subject: [PATCH 23/45] Fix default.yaml formatting --- config/default.yaml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/config/default.yaml b/config/default.yaml index 037b672..af35adc 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -19,11 +19,7 @@ run: num_erc20_transfers: 1000 num_erc721_mints: 1000 num_get_events: 100 - concurrency: 10 - -# read_metrics: -# get_events: -# parameters_loc: "params.json" + concurrency: 5 report: num_blocks: 4 From f26b04002d1bace2b1c2b81ef540451dd729bf03 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Tue, 19 Mar 2024 11:20:12 +0200 Subject: [PATCH 24/45] Add read benches to configuration file --- config/default.yaml | 8 +++-- config/katana.yaml | 8 +++-- config/read_params/get_events.json | 10 ++++++ config/sharingan.yaml | 7 ++-- config/v2.1.0.yaml | 7 ++-- src/actions/goose.rs | 17 ++++++++-- src/actions/mod.rs | 51 ++++++++++++++++-------------- src/config.rs | 46 ++++++++++++++++++++++----- 8 files changed, 111 insertions(+), 43 deletions(-) create mode 100644 config/read_params/get_events.json diff --git a/config/default.yaml b/config/default.yaml index af35adc..b4d4892 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -16,10 +16,14 @@ setup: chain_id: "SN_GOERLI" run: + concurrency: 5 num_erc20_transfers: 1000 num_erc721_mints: 1000 - num_get_events: 100 - concurrency: 5 + read_benches: + - name: "Get Events" + num_requests: 100 + method: "starknet_getEvents" + parameters_location: "config/read_params/get_events.json" report: num_blocks: 4 diff --git a/config/katana.yaml b/config/katana.yaml index 7fc938c..86729f8 100644 --- a/config/katana.yaml +++ b/config/katana.yaml @@ -16,10 +16,14 @@ setup: chain_id: "KATANA" run: + concurrency: 5 num_erc20_transfers: 300 num_erc721_mints: 300 - num_get_events: 100 - concurrency: 5 + read_benches: + - name: "Get Events" + num_requests: 100 + method: "starknet_getEvents" + parameters_location: "config/read_params/get_events.json" report: num_blocks: 4 diff --git a/config/read_params/get_events.json b/config/read_params/get_events.json new file mode 100644 index 0000000..fe94181 --- /dev/null +++ b/config/read_params/get_events.json @@ -0,0 +1,10 @@ +[ + { + "from_block": null, + "to_block": null, + "address": null, + "keys": [], + "continuation_token": null, + "chunk_size": 10 + } +] \ No newline at end of file diff --git a/config/sharingan.yaml b/config/sharingan.yaml index 4c68486..2b45866 100644 --- a/config/sharingan.yaml +++ b/config/sharingan.yaml @@ -16,10 +16,13 @@ setup: chain_id: "SN_GOERLI" run: + concurrency: 5 num_erc20_transfers: 1200 num_erc721_mints: 1200 - num_get_events: 100 - concurrency: 5 + - name: "Get Events" + num_requests: 100 + method: "starknet_getEvents" + parameters_location: "config/read_params/get_events.json" report: num_blocks: 4 diff --git a/config/v2.1.0.yaml b/config/v2.1.0.yaml index d97b9f7..a694ae1 100644 --- a/config/v2.1.0.yaml +++ b/config/v2.1.0.yaml @@ -22,10 +22,13 @@ setup: chain_id: "SN_GOERLI" run: + concurrency: 5 num_erc20_transfers: 100 num_erc721_mints: 100 - num_get_events: 100 - concurrency: 5 + - name: "Get Events" + num_requests: 100 + method: "starknet_getEvents" + parameters_location: "config/read_params/get_events.json" report: num_blocks: 3 diff --git a/src/actions/goose.rs b/src/actions/goose.rs index 452b0b7..c724140 100644 --- a/src/actions/goose.rs +++ b/src/actions/goose.rs @@ -7,6 +7,7 @@ use std::{ use color_eyre::eyre::ensure; use crossbeam_queue::ArrayQueue; use goose::{config::GooseConfiguration, metrics::GooseRequestMetric, prelude::*}; +use rand::prelude::SliceRandom; use serde::{de::DeserializeOwned, Serialize}; use starknet::{ accounts::{ @@ -26,6 +27,7 @@ use starknet::{ use crate::{ actions::shoot::{GatlingShooterSetup, CHECK_INTERVAL, MAX_FEE}, + config::ParametersFile, generators::get_rng, }; @@ -258,7 +260,7 @@ pub async fn read_method( shooter: &GatlingShooterSetup, amount: u64, method: JsonRpcMethod, - parameters: serde_json::Value, + parameters_list: ParametersFile, ) -> color_eyre::Result { let config = shooter.config(); @@ -286,10 +288,19 @@ pub async fn read_method( }; let events: TransactionFunction = Arc::new(move |user| { - let paramaters = parameters.clone(); + let mut rng = rand::thread_rng(); + + let mut params_list = parameters_list.clone(); + params_list.shuffle(&mut rng); // Make sure each goose user has their own order + let mut paramaters_cycle = params_list.into_iter().cycle(); Box::pin(async move { - let _: (serde_json::Value, _) = send_request(user, method, paramaters).await?; + let params = paramaters_cycle + .next() + .expect("Cyclic iterator should never end"); + + let _: (serde_json::Value, _) = + send_request(user, method, serde_json::Value::Object(params)).await?; Ok(()) }) diff --git a/src/actions/mod.rs b/src/actions/mod.rs index edc93a6..4291feb 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -2,14 +2,7 @@ use std::sync::Arc; use ::goose::metrics::GooseMetrics; use futures::Future; -use serde_json::json; -use starknet::{ - core::types::BlockId, - providers::{ - jsonrpc::{HttpTransport, JsonRpcMethod}, - JsonRpcClient, Provider, - }, -}; +use starknet::{core::types::BlockId, providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}}; use crate::{ config::GatlingConfig, @@ -67,29 +60,39 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { let end_block = shooter.rpc_client().block_number().await?; - let num_get_events = shooter.config().run.num_get_events; - if num_get_events != 0 { - let request = json!( - { - "from_block": BlockId::Number(start_block), - "to_block": BlockId::Number(end_block), - "address": null, - "keys": [], - "continuation_token": null, - "chunk_size": 10 + for read_bench in &shooter.config().run.read_benches { + let mut params = read_bench.parameters_location.clone(); + + // Look into templating json for these if it becomes more complex to handle + // liquid_json sees like a relatively popular option for this + for parameter in &mut params { + if let Some(from) = parameter.get_mut("from_block") { + if from.is_null() { + *from = serde_json::to_value(BlockId::Number(start_block))?; + } } - ); - let metrics = - goose::read_method(&shooter, num_get_events, JsonRpcMethod::GetEvents, request).await?; + if let Some(to) = parameter.get_mut("to_block") { + if to.is_null() { + *to = serde_json::to_value(BlockId::Number(end_block))?; + } + } + } - let mut report = BenchmarkReport::new("Get Events".into(), metrics.scenarios[0].counter); + let metrics = goose::read_method( + &shooter, + read_bench.num_requests, + read_bench.method, + read_bench.parameters_location.clone(), + ) + .await?; + + let mut report = + BenchmarkReport::new(read_bench.name.clone(), metrics.scenarios[0].counter); report.with_goose_read_metrics(&metrics)?; global_report.benches.push(report); - } else { - log::info!("Skipping get events") } let rpc_result = global_report diff --git a/src/config.rs b/src/config.rs index a990741..bab387e 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,15 +1,21 @@ //! General configuration +use std::fs::File; +use std::io::BufReader; use std::path::PathBuf; use color_eyre::eyre::Result; -use config::{builder::DefaultState, Config, ConfigBuilder, File}; +use config::{builder::DefaultState, Config, ConfigBuilder}; -use serde::de::Error as DeError; use serde::Deserialize; -use starknet::core::{ - types::{contract::CompiledClass, FieldElement}, - utils::{cairo_short_string_to_felt, CairoShortStringToFeltError}, +use serde::{de::Error as DeError, Deserializer}; +use serde_json::{Map, Value}; +use starknet::{ + core::{ + types::{contract::CompiledClass, FieldElement}, + utils::{cairo_short_string_to_felt, CairoShortStringToFeltError}, + }, + providers::jsonrpc::JsonRpcMethod, }; /// Configuration for the application. @@ -103,12 +109,23 @@ pub struct DeployerConfig { #[derive(Debug, Deserialize, Clone)] pub struct RunConfig { + pub concurrency: u64, pub num_erc20_transfers: u64, pub num_erc721_mints: u64, - pub num_get_events: u64, - pub concurrency: u64, + pub read_benches: Vec, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct ReadBenchConfig { + pub name: String, + pub num_requests: u64, + pub method: JsonRpcMethod, + #[serde(deserialize_with = "parameters_file_deserializer")] + pub parameters_location: ParametersFile, } +pub type ParametersFile = Vec>; + #[derive(Debug, Deserialize, Clone)] pub struct ReportConfig { pub num_blocks: u64, @@ -128,7 +145,7 @@ impl GatlingConfig { /// Create a new configuration from a file. pub fn from_file(path: &str) -> Result { base_config_builder() - .add_source(File::with_name(path)) + .add_source(config::File::with_name(path)) .build() .unwrap() .try_deserialize() @@ -157,3 +174,16 @@ where CairoShortStringToFeltError::StringTooLong => D::Error::custom("string too long"), }) } + +fn parameters_file_deserializer<'de, D>(de: D) -> Result +where + D: Deserializer<'de>, +{ + let path = PathBuf::deserialize(de)?; + + let file = File::open(path).expect("Could not open file"); + let reader = BufReader::new(file); + let params = + serde_json::from_reader(reader).expect("Could not deserialize read params correctly"); + Ok(params) +} From c11ec7e9827169e4631c24b442764334060644e5 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Tue, 19 Mar 2024 13:19:48 +0200 Subject: [PATCH 25/45] cargo fmt --- src/actions/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/actions/mod.rs b/src/actions/mod.rs index 4291feb..26cd82d 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -2,7 +2,10 @@ use std::sync::Arc; use ::goose::metrics::GooseMetrics; use futures::Future; -use starknet::{core::types::BlockId, providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}}; +use starknet::{ + core::types::BlockId, + providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}, +}; use crate::{ config::GatlingConfig, From 4dd841c69b82c404f345b78944db60a60b3ec625 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Tue, 19 Mar 2024 13:42:14 +0200 Subject: [PATCH 26/45] Update README with read metric configuration --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d9ef196..3d1e77c 100644 --- a/README.md +++ b/README.md @@ -83,9 +83,15 @@ The configuration is defined by the following spec - `run` + - `concurrency`: How many transactions to do simultaneously - `num_erc20_transfers`: Number of ERC20 `transfer` transactions - `num_erc721_mints`: Number of ERC721 `mint` transactions - - `concurrency`: How many transactions to do simultaneously + - `read_benches`: A list of read benchmarks to run + + - `name`: The name to write on the output report + - `num_requests`: How many times to call this request + - `method`: What method to call on the rpc node + - `parameters_location`: A file with a array of multiple parameters to use for requests - `report` From d32719281d654a191ad92ba8ca950e32b8fa5e5d Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Tue, 19 Mar 2024 13:45:48 +0200 Subject: [PATCH 27/45] Fix sharingham and v2.1.0 configs --- config/sharingan.yaml | 3 ++- config/v2.1.0.yaml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/config/sharingan.yaml b/config/sharingan.yaml index 2b45866..e89d8f5 100644 --- a/config/sharingan.yaml +++ b/config/sharingan.yaml @@ -19,7 +19,8 @@ run: concurrency: 5 num_erc20_transfers: 1200 num_erc721_mints: 1200 - - name: "Get Events" + read_benches: + - name: "Get Events" num_requests: 100 method: "starknet_getEvents" parameters_location: "config/read_params/get_events.json" diff --git a/config/v2.1.0.yaml b/config/v2.1.0.yaml index a694ae1..9013519 100644 --- a/config/v2.1.0.yaml +++ b/config/v2.1.0.yaml @@ -25,7 +25,8 @@ run: concurrency: 5 num_erc20_transfers: 100 num_erc721_mints: 100 - - name: "Get Events" + read_benches: + - name: "Get Events" num_requests: 100 method: "starknet_getEvents" parameters_location: "config/read_params/get_events.json" From dc679b820582ab1ab0504c0f245d13384bb45836 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Tue, 19 Mar 2024 13:52:09 +0200 Subject: [PATCH 28/45] Fix JSON formatting --- config/read_params/get_events.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/config/read_params/get_events.json b/config/read_params/get_events.json index fe94181..f6bc91a 100644 --- a/config/read_params/get_events.json +++ b/config/read_params/get_events.json @@ -1,10 +1,10 @@ [ - { - "from_block": null, - "to_block": null, - "address": null, - "keys": [], - "continuation_token": null, - "chunk_size": 10 - } -] \ No newline at end of file + { + "from_block": null, + "to_block": null, + "address": null, + "keys": [], + "continuation_token": null, + "chunk_size": 10 + } +] From 816b34cf3bf21abd5cf004d5a23c224b933596fc Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Tue, 19 Mar 2024 15:09:23 +0200 Subject: [PATCH 29/45] Clarify error message for concurency and run amount --- src/actions/goose.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/actions/goose.rs b/src/actions/goose.rs index 4ca84a5..d23f5f3 100644 --- a/src/actions/goose.rs +++ b/src/actions/goose.rs @@ -40,7 +40,7 @@ pub async fn erc20(shooter: &GatlingShooterSetup) -> color_eyre::Result= config.run.concurrency, - "Too few erc20 transfers for the amount of concurrency" + "Too few erc20 transfers for the amount of concurrent users" ); // div_euclid will truncate integers when not evenly divisable @@ -110,7 +110,7 @@ pub async fn erc721(shooter: &GatlingShooterSetup) -> color_eyre::Result= config.run.concurrency, - "Too few erc721 mints for the amount of concurrency" + "Too few erc721 mints for the amount of concurrent users" ); // div_euclid will truncate integers when not evenly divisable @@ -266,7 +266,7 @@ pub async fn read_method( ensure!( amount >= config.run.concurrency, - "Too few reads for the amount of concurrency" + "Too few reads for the amount of concurrent users" ); // div_euclid will truncate integers when not evenly divisable From 1efdb6ad69c6ee5cf2659540b9f30c8dfa719780 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Fri, 22 Mar 2024 11:42:44 +0200 Subject: [PATCH 30/45] Swap erc20 and erc721 nonce logic --- src/actions/goose.rs | 71 ++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/src/actions/goose.rs b/src/actions/goose.rs index d23f5f3..931208e 100644 --- a/src/actions/goose.rs +++ b/src/actions/goose.rs @@ -64,11 +64,26 @@ pub async fn erc20(shooter: &GatlingShooterSetup) -> color_eyre::Result color_eyre::Result color_eyre::Result TransactionResult { - let GooseWriteUserState { account, nonce, .. } = user +async fn transfer( + user: &mut GooseUser, + nonce: FieldElement, + erc20_address: FieldElement, +) -> TransactionResult { + let GooseWriteUserState { account, .. } = user .get_session_data::() .expect("Should be in a goose user with GooseUserState session data"); @@ -342,20 +349,18 @@ async fn transfer(user: &mut GooseUser, erc20_address: FieldElement) -> Transact let response: InvokeTransactionResult = send_execution( user, vec![call], - *nonce, + nonce, &account.clone(), JsonRpcMethod::AddInvokeTransaction, ) .await? .0; - let GooseWriteUserState { nonce, prev_tx, .. } = + let GooseWriteUserState { prev_tx, .. } = user.get_session_data_mut::().expect( "Should be successful as we already asserted that the session data is a GooseUserState", ); - *nonce += FieldElement::ONE; - prev_tx.push(response.transaction_hash); Ok(()) @@ -364,15 +369,13 @@ async fn transfer(user: &mut GooseUser, erc20_address: FieldElement) -> Transact async fn mint( user: &mut GooseUser, erc721_address: FieldElement, - nonce: FieldElement, from_account: &SingleOwnerAccount>, LocalWallet>, ) -> TransactionResult { - let recipient = user + let GooseWriteUserState { account, nonce, .. } = user .get_session_data::() - .expect("Should be in a goose user with GooseUserState session data") - .account - .clone() - .address(); + .expect("Should be in a goose user with GooseUserState session data"); + + let recipient = account.address(); let (token_id_low, token_id_high) = (get_rng(), felt!("0x0000")); @@ -385,19 +388,21 @@ async fn mint( let response: InvokeTransactionResult = send_execution( user, vec![call], - nonce, + *nonce, from_account, JsonRpcMethod::AddInvokeTransaction, ) .await? .0; - user.get_session_data_mut::() - .expect( + let GooseWriteUserState { nonce, prev_tx, .. } = + user.get_session_data_mut::().expect( "Should be successful as we already asserted that the session data is a GooseUserState", - ) - .prev_tx - .push(response.transaction_hash); + ); + + *nonce += FieldElement::ONE; + + prev_tx.push(response.transaction_hash); Ok(()) } From 33d2ed273810feb11ea8fd4c5a99a247cbef669d Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Wed, 27 Mar 2024 10:46:09 +0200 Subject: [PATCH 31/45] Refactor code for Shooter trait --- src/actions/goose.rs | 288 ++-------------------- src/actions/mod.rs | 89 ++++--- src/actions/{shoot.rs => setup.rs} | 230 +++-------------- src/actions/shooter.rs | 381 +++++++++++++++++++++++++++++ 4 files changed, 485 insertions(+), 503 deletions(-) rename src/actions/{shoot.rs => setup.rs} (60%) create mode 100644 src/actions/shooter.rs diff --git a/src/actions/goose.rs b/src/actions/goose.rs index 931208e..078be41 100644 --- a/src/actions/goose.rs +++ b/src/actions/goose.rs @@ -14,10 +14,8 @@ use starknet::{ Account, Call, ConnectedAccount, ExecutionEncoder, RawExecution, SingleOwnerAccount, }, core::types::{ - BroadcastedInvokeTransaction, ExecutionResult, FieldElement, InvokeTransactionResult, - MaybePendingTransactionReceipt, + BroadcastedInvokeTransaction, ExecutionResult, FieldElement, MaybePendingTransactionReceipt, }, - macros::{felt, selector}, providers::{ jsonrpc::{HttpTransport, JsonRpcError, JsonRpcMethod, JsonRpcResponse}, JsonRpcClient, ProviderError, @@ -26,180 +24,17 @@ use starknet::{ }; use crate::{ - actions::shoot::{GatlingShooterSetup, CHECK_INTERVAL, MAX_FEE}, + actions::setup::{GatlingSetup, CHECK_INTERVAL, MAX_FEE}, config::ParametersFile, - generators::get_rng, }; -use super::shoot::StarknetAccount; - -pub async fn erc20(shooter: &GatlingShooterSetup) -> color_eyre::Result { - let environment = shooter.environment()?; - let erc20_address = environment.erc20_address; - let config = shooter.config(); - - ensure!( - config.run.num_erc20_transfers >= config.run.concurrency, - "Too few erc20 transfers for the amount of concurrent users" - ); - - // div_euclid will truncate integers when not evenly divisable - let user_iterations = config - .run - .num_erc20_transfers - .div_euclid(config.run.concurrency); - // this will always be a multiple of concurrency, unlike num_erc20_transfers - let total_transactions = user_iterations * config.run.concurrency; - - // If these are not equal that means user_iterations was truncated - if total_transactions != config.run.num_erc20_transfers { - log::warn!("Number of erc20 transfers is not evenly divisble by concurrency, doing {total_transactions} transfers instead"); - } - - let goose_config = { - let mut default = GooseConfiguration::default(); - default.host = config.rpc.url.clone(); - default.iterations = user_iterations as usize; - default.users = Some(config.run.concurrency as usize); - default - }; - - let nonces = Arc::new(ArrayQueue::new(total_transactions as usize)); - let mut nonce = shooter.deployer_account().get_nonce().await?; - - for _ in 0..total_transactions { - nonces - .push(nonce) - .expect("ArrayQueue has capacity for all mints"); - nonce += FieldElement::ONE; - } - - let transfer_setup: TransactionFunction = - setup(environment.accounts.clone(), user_iterations as usize).await?; - - let transfer: TransactionFunction = Arc::new(move |user| { - let nonce = nonces - .pop() - .expect("Nonce ArrayQueue should have enough nonces for all mints"); - - Box::pin(transfer(user, nonce, erc20_address)) - }); - - let transfer_wait: TransactionFunction = goose_write_user_wait_last_tx(); - - let metrics = GooseAttack::initialize_with_config(goose_config.clone())? - .register_scenario( - scenario!("Transfer") - .register_transaction( - Transaction::new(transfer_setup) - .set_name("Transfer Setup") - .set_on_start(), - ) - .register_transaction( - Transaction::new(transfer) - .set_name("Transaction Submission") - .set_sequence(1), - ) - .register_transaction( - Transaction::new(transfer_wait) - .set_name("Transfer Finalizing") - .set_sequence(2) - .set_on_stop(), - ) - .register_transaction( - transaction!(verify_transactions) - .set_name("Verification") - .set_sequence(3) - .set_on_stop(), - ), - ) - .execute() - .await?; - - Ok(metrics) -} - -pub async fn erc721(shooter: &GatlingShooterSetup) -> color_eyre::Result { - let config = shooter.config(); - let environment = shooter.environment()?; - - ensure!( - config.run.num_erc721_mints >= config.run.concurrency, - "Too few erc721 mints for the amount of concurrent users" - ); - - // div_euclid will truncate integers when not evenly divisable - let user_iterations = config - .run - .num_erc721_mints - .div_euclid(config.run.concurrency); - // this will always be a multiple of concurrency, unlike num_erc721_mints - let total_transactions = user_iterations * config.run.concurrency; - - // If these are not equal that means user_iterations was truncated - if total_transactions != config.run.num_erc721_mints { - log::warn!("Number of erc721 mints is not evenly divisble by concurrency, doing {total_transactions} mints instead"); - } - - let goose_mint_config = { - let mut default = GooseConfiguration::default(); - default.host = config.rpc.url.clone(); - default.iterations = user_iterations as usize; - default.users = Some(config.run.concurrency as usize); - default - }; - - let erc721_address = environment.erc721_address; - - let from_account = shooter.deployer_account().clone(); - - let mint_setup: TransactionFunction = - setup(environment.accounts.clone(), user_iterations as usize).await?; - - let mint: TransactionFunction = Arc::new(move |user| { - let from_account = from_account.clone(); - Box::pin(async move { mint(user, erc721_address, &from_account).await }) - }); - - let mint_wait: TransactionFunction = goose_write_user_wait_last_tx(); - - let metrics = GooseAttack::initialize_with_config(goose_mint_config.clone())? - .register_scenario( - scenario!("Minting") - .register_transaction( - Transaction::new(mint_setup) - .set_name("Mint Setup") - .set_on_start(), - ) - .register_transaction( - Transaction::new(mint) - .set_name("Transaction Submission") - .set_sequence(1), - ) - .register_transaction( - Transaction::new(mint_wait) - .set_name("Mint Finalizing") - .set_sequence(2) - .set_on_stop(), - ) - .register_transaction( - transaction!(verify_transactions) - .set_name("Verification") - .set_sequence(3) - .set_on_stop(), - ), - ) - .execute() - .await?; - - Ok(metrics) -} +use super::setup::StarknetAccount; #[derive(Debug, Clone)] -struct GooseWriteUserState { - account: StarknetAccount, - nonce: FieldElement, - prev_tx: Vec, +pub struct GooseWriteUserState { + pub account: StarknetAccount, + pub nonce: FieldElement, + pub prev_tx: Vec, } impl GooseWriteUserState { @@ -215,7 +50,7 @@ impl GooseWriteUserState { } } -async fn setup( +pub async fn setup( accounts: Vec, transactions_amount: usize, ) -> Result { @@ -239,7 +74,7 @@ async fn setup( })) } -fn goose_write_user_wait_last_tx() -> TransactionFunction { +pub fn goose_write_user_wait_last_tx() -> TransactionFunction { Arc::new(move |user| { let tx = user .get_session_data::() @@ -260,7 +95,7 @@ fn goose_write_user_wait_last_tx() -> TransactionFunction { } pub async fn read_method( - shooter: &GatlingShooterSetup, + shooter: &GatlingSetup, amount: u64, method: JsonRpcMethod, parameters_list: ParametersFile, @@ -320,94 +155,7 @@ pub async fn read_method( Ok(metrics) } -// Hex: 0xdead -// from_hex_be isn't const whereas from_mont is -const VOID_ADDRESS: FieldElement = FieldElement::from_mont([ - 18446744073707727457, - 18446744073709551615, - 18446744073709551615, - 576460752272412784, -]); - -async fn transfer( - user: &mut GooseUser, - nonce: FieldElement, - erc20_address: FieldElement, -) -> TransactionResult { - let GooseWriteUserState { account, .. } = user - .get_session_data::() - .expect("Should be in a goose user with GooseUserState session data"); - - let (amount_low, amount_high) = (felt!("1"), felt!("0")); - - let call = Call { - to: erc20_address, - selector: selector!("transfer"), - calldata: vec![VOID_ADDRESS, amount_low, amount_high], - }; - - let response: InvokeTransactionResult = send_execution( - user, - vec![call], - nonce, - &account.clone(), - JsonRpcMethod::AddInvokeTransaction, - ) - .await? - .0; - - let GooseWriteUserState { prev_tx, .. } = - user.get_session_data_mut::().expect( - "Should be successful as we already asserted that the session data is a GooseUserState", - ); - - prev_tx.push(response.transaction_hash); - - Ok(()) -} - -async fn mint( - user: &mut GooseUser, - erc721_address: FieldElement, - from_account: &SingleOwnerAccount>, LocalWallet>, -) -> TransactionResult { - let GooseWriteUserState { account, nonce, .. } = user - .get_session_data::() - .expect("Should be in a goose user with GooseUserState session data"); - - let recipient = account.address(); - - let (token_id_low, token_id_high) = (get_rng(), felt!("0x0000")); - - let call = Call { - to: erc721_address, - selector: selector!("mint"), - calldata: vec![recipient, token_id_low, token_id_high], - }; - - let response: InvokeTransactionResult = send_execution( - user, - vec![call], - *nonce, - from_account, - JsonRpcMethod::AddInvokeTransaction, - ) - .await? - .0; - - let GooseWriteUserState { nonce, prev_tx, .. } = - user.get_session_data_mut::().expect( - "Should be successful as we already asserted that the session data is a GooseUserState", - ); - - *nonce += FieldElement::ONE; - - prev_tx.push(response.transaction_hash); - - Ok(()) -} - -async fn verify_transactions(user: &mut GooseUser) -> TransactionResult { +pub async fn verify_transactions(user: &mut GooseUser) -> TransactionResult { let transactions = mem::take( &mut user .get_session_data_mut::() @@ -471,7 +219,12 @@ pub async fn wait_for_tx( return Ok(()); } ExecutionResult::Reverted { reason } => { - return user.set_failure(&reverted_tag(), &mut metric, None, Some(reason)); + return user.set_failure( + &(reverted_tag() + reason), + &mut metric, + None, + Some(reason), + ); } }, JsonRpcResponse::Success { @@ -479,7 +232,12 @@ pub async fn wait_for_tx( .. } => { if let ExecutionResult::Reverted { reason } = pending.execution_result() { - return user.set_failure(&reverted_tag(), &mut metric, None, Some(reason)); + return user.set_failure( + &(reverted_tag() + reason), + &mut metric, + None, + Some(reason), + ); } log::debug!("Waiting for transaction {tx_hash:#064x} to be accepted"); tokio::time::sleep(CHECK_INTERVAL).await; diff --git a/src/actions/mod.rs b/src/actions/mod.rs index 26cd82d..23f6a43 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -1,69 +1,60 @@ use std::sync::Arc; -use ::goose::metrics::GooseMetrics; -use futures::Future; -use starknet::{ - core::types::BlockId, - providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}, -}; +use starknet::{core::types::BlockId, providers::Provider}; use crate::{ config::GatlingConfig, metrics::{BenchmarkReport, GlobalReport}, }; -use self::shoot::GatlingShooterSetup; +use self::{ + setup::GatlingSetup, + shooter::{MintShooter, Shooter, TransferShooter}, +}; mod goose; -mod shoot; +mod setup; +mod shooter; pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { let total_txs = config.run.num_erc20_transfers + config.run.num_erc721_mints; - let num_blocks = config.report.num_blocks; - let mut shooter = GatlingShooterSetup::from_config(config).await?; - shooter.setup().await?; + let mut shooter_setup = GatlingSetup::from_config(config).await?; + let transfer_shooter = TransferShooter::setup(&mut shooter_setup).await?; + shooter_setup + .setup_accounts(transfer_shooter.erc20_address) + .await?; let mut global_report = GlobalReport { - users: shooter.config().run.concurrency, + users: shooter_setup.config().run.concurrency, all_bench_report: BenchmarkReport::new("".into(), total_txs as usize), benches: Vec::new(), extra: crate::utils::sysinfo_string(), }; - let start_block = shooter.rpc_client().block_number().await?; + let start_block = shooter_setup.rpc_client().block_number().await?; - if shooter.config().run.num_erc20_transfers != 0 { - let report = make_report_over_write_bench( - goose::erc20(&shooter), - "Erc20 Transfers".into(), - shooter.rpc_client(), - num_blocks, - ) - .await?; + if shooter_setup.config().run.num_erc20_transfers != 0 { + let report = make_report_over_shooter(transfer_shooter, &shooter_setup).await?; global_report.benches.push(report); } else { log::info!("Skipping erc20 transfers") } - if shooter.config().run.num_erc721_mints != 0 { - let report = make_report_over_write_bench( - goose::erc721(&shooter), - "Erc721 Mints".into(), - shooter.rpc_client(), - num_blocks, - ) - .await?; + if shooter_setup.config().run.num_erc721_mints != 0 { + let shooter = MintShooter::setup(&mut shooter_setup).await?; + + let report = make_report_over_shooter(shooter, &shooter_setup).await?; global_report.benches.push(report); } else { log::info!("Skipping erc721 mints") } - let end_block = shooter.rpc_client().block_number().await?; + let end_block = shooter_setup.rpc_client().block_number().await?; - for read_bench in &shooter.config().run.read_benches { + for read_bench in &shooter_setup.config().run.read_benches { let mut params = read_bench.parameters_location.clone(); // Look into templating json for these if it becomes more complex to handle @@ -83,7 +74,7 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { } let metrics = goose::read_method( - &shooter, + &shooter_setup, read_bench.num_requests, read_bench.method, read_bench.parameters_location.clone(), @@ -100,14 +91,14 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { let rpc_result = global_report .all_bench_report - .with_block_range(shooter.rpc_client(), start_block, end_block) + .with_block_range(shooter_setup.rpc_client(), start_block, end_block) .await; if let Err(error) = rpc_result { log::error!("Failed to get block range: {error}") } - let report_path = shooter + let report_path = shooter_setup .config() .report .output_location @@ -119,26 +110,34 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { Ok(()) } -async fn make_report_over_write_bench( - bench: impl Future>, - name: String, - rpc_client: &Arc>, - num_blocks: u64, +async fn make_report_over_shooter( + shooter: S, + setup: &GatlingSetup, ) -> color_eyre::Result { - let start_block = rpc_client.block_number().await?; - let goose_metrics = bench.await?; - let end_block = rpc_client.block_number().await?; + let goose_config = S::get_goose_config(setup.config())?; + + let attack = Arc::new(shooter) + .create_goose_attack(goose_config, setup.accounts().to_vec()) + .await?; + + let start_block = setup.rpc_client().block_number().await?; + let goose_metrics = attack.execute().await?; + let end_block = setup.rpc_client().block_number().await?; - let mut report = BenchmarkReport::new(name, goose_metrics.scenarios[0].counter); + let mut report = BenchmarkReport::new(S::NAME.to_string(), goose_metrics.scenarios[0].counter); let rpc_result = report - .with_block_range(rpc_client, start_block + 1, end_block) + .with_block_range(setup.rpc_client(), start_block + 1, end_block) .await; + let num_blocks = setup.config().report.num_blocks; + if let Err(error) = rpc_result { log::error!("Failed to get block range: {error}") } else if num_blocks != 0 { - report.with_last_x_blocks(rpc_client, num_blocks).await?; + report + .with_last_x_blocks(setup.rpc_client(), num_blocks) + .await?; } report.with_goose_write_metrics(&goose_metrics)?; diff --git a/src/actions/shoot.rs b/src/actions/setup.rs similarity index 60% rename from src/actions/shoot.rs rename to src/actions/setup.rs index dd7745f..86ccc97 100644 --- a/src/actions/shoot.rs +++ b/src/actions/setup.rs @@ -1,19 +1,21 @@ use crate::config::{ContractSourceConfig, GatlingConfig}; -use crate::utils::{compute_contract_address, wait_for_tx}; -use color_eyre::eyre::{Context, OptionExt}; -use color_eyre::{eyre::eyre, Result}; +use crate::utils::wait_for_tx; +use color_eyre::{ + eyre::{ + Context, {bail, eyre}, + }, + Result, +}; use log::{debug, info, warn}; use starknet::core::types::contract::SierraClass; -use std::collections::HashMap; use std::path::Path; use starknet::accounts::{ Account, AccountFactory, Call, ConnectedAccount, ExecutionEncoding, OpenZeppelinAccountFactory, SingleOwnerAccount, }; -use starknet::contract::ContractFactory; use starknet::core::types::{ contract::legacy::LegacyContractClass, BlockId, BlockTag, FieldElement, StarknetError, }; @@ -21,7 +23,6 @@ use starknet::macros::{felt, selector}; use starknet::providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}; use starknet::providers::{MaybeUnknownErrorCode, ProviderError, StarknetErrorWithMessage}; use starknet::signers::{LocalWallet, SigningKey}; -use std::str; use std::sync::Arc; use std::time::Duration; @@ -33,23 +34,15 @@ pub static CHECK_INTERVAL: Duration = Duration::from_millis(500); pub type StarknetAccount = SingleOwnerAccount>, LocalWallet>; -pub struct GatlingShooterSetup { +pub struct GatlingSetup { config: GatlingConfig, starknet_rpc: Arc>, signer: LocalWallet, account: StarknetAccount, - nonces: HashMap, - environment: Option, // Will be populated in setup phase -} - -#[derive(Clone)] -pub struct GatlingEnvironment { - pub erc20_address: FieldElement, - pub erc721_address: FieldElement, - pub accounts: Vec, + accounts: Vec, } -impl GatlingShooterSetup { +impl GatlingSetup { pub async fn from_config(config: GatlingConfig) -> Result { let starknet_rpc: Arc> = Arc::new(starknet_rpc_provider(Url::parse(&config.clone().rpc.url)?)); @@ -68,28 +61,15 @@ impl GatlingShooterSetup { }, ); - // Fails if nonce is null (which is the case for 1st startup) - let cur_nonce = account.get_nonce().await?; - - let mut nonces: HashMap = HashMap::new(); - nonces.insert(config.deployer.address, cur_nonce); - Ok(Self { config, starknet_rpc, signer, account, - nonces, - environment: None, + accounts: vec![], }) } - pub fn environment(&self) -> Result<&GatlingEnvironment> { - self.environment - .as_ref() - .ok_or_eyre("Environment is not yet populated, you should run the setup function first") - } - pub fn config(&self) -> &GatlingConfig { &self.config } @@ -102,34 +82,21 @@ impl GatlingShooterSetup { &self.account } - /// Setup the simulation. - pub async fn setup(&mut self) -> Result<()> { - let chain_id = self.starknet_rpc.chain_id().await?.to_bytes_be(); - let block_number = self.starknet_rpc.block_number().await?; - info!( - "Shoot - {} @ block number - {}", - str::from_utf8(&chain_id)?.trim_start_matches('\0'), - block_number - ); - - let setup_config = self.config.clone().setup; + pub fn accounts(&self) -> &[StarknetAccount] { + &self.accounts + } - let erc20_class_hash = self.declare_contract(&setup_config.erc20_contract).await?; + /// Setup the simulation. + pub async fn setup_accounts(&mut self, erc20_address: FieldElement) -> Result<()> { + let account_contract = self.config.setup.account_contract.clone(); - let erc721_class_hash = self.declare_contract(&setup_config.erc721_contract).await?; + let account_class_hash = self.declare_contract(&account_contract).await?; - let account_class_hash = self - .declare_contract(&setup_config.account_contract) - .await?; - - let execution_encoding = match setup_config.account_contract { + let execution_encoding = match account_contract { ContractSourceConfig::V0(_) => ExecutionEncoding::Legacy, ContractSourceConfig::V1(_) => ExecutionEncoding::New, }; - let erc20_address = self.deploy_erc20(erc20_class_hash).await?; - let erc721_address = self.deploy_erc721(erc721_class_hash).await?; - let accounts = self .create_accounts( account_class_hash, @@ -139,13 +106,7 @@ impl GatlingShooterSetup { ) .await?; - let environment = GatlingEnvironment { - erc20_address, - erc721_address, - accounts, - }; - - self.environment = Some(environment); + self.accounts = accounts; Ok(()) } @@ -156,12 +117,9 @@ impl GatlingShooterSetup { account: StarknetAccount, recipient: FieldElement, amount: FieldElement, + nonce: FieldElement, ) -> Result { let from_address = account.address(); - let nonce = match self.nonces.get(&from_address) { - Some(nonce) => *nonce, - None => account.get_nonce().await?, - }; debug!( "Transferring {amount} of {contract_address:#064x} from address {from_address:#064x} to address {recipient:#064x} with nonce={}", @@ -183,122 +141,9 @@ impl GatlingShooterSetup { .send() .await?; - self.nonces.insert(from_address, nonce + FieldElement::ONE); - Ok(result.transaction_hash) } - async fn deploy_erc721(&mut self, class_hash: FieldElement) -> Result { - let contract_factory = ContractFactory::new(class_hash, self.account.clone()); - let from_address = self.account.address(); - let nonce = match self.nonces.get(&from_address) { - Some(nonce) => *nonce, - None => self.account.get_nonce().await?, - }; - - let name = selector!("TestNFT"); - let symbol = selector!("TNFT"); - let recipient = self.account.address(); - - let constructor_args = vec![name, symbol, recipient]; - let unique = false; - - let address = - compute_contract_address(self.config.deployer.salt, class_hash, &constructor_args); - - if let Ok(contract_class_hash) = self - .starknet_rpc - .get_class_hash_at(BlockId::Tag(BlockTag::Pending), address) - .await - { - if contract_class_hash == class_hash { - warn!("ERC721 contract already deployed at address {address:#064x}"); - return Ok(address); - } else { - return Err(eyre!("ERC721 contract {address:#064x} already deployed with a different class hash {contract_class_hash:#064x}, expected {class_hash:#064x}")); - } - } - - let deploy = contract_factory.deploy(constructor_args, self.config.deployer.salt, unique); - - info!("Deploying ERC721 with nonce={}, address={address}", nonce); - - let result = deploy.nonce(nonce).max_fee(MAX_FEE).send().await?; - wait_for_tx(&self.starknet_rpc, result.transaction_hash, CHECK_INTERVAL).await?; - - self.nonces.insert(from_address, nonce + FieldElement::ONE); - - debug!( - "Deploy ERC721 transaction accepted {:#064x}", - result.transaction_hash - ); - - info!("ERC721 contract deployed at address {:#064x}", address); - Ok(address) - } - - async fn deploy_erc20(&mut self, class_hash: FieldElement) -> Result { - let contract_factory = ContractFactory::new(class_hash, self.account.clone()); - let from_address = self.account.address(); - let nonce = match self.nonces.get(&from_address) { - Some(nonce) => *nonce, - None => self.account.get_nonce().await?, - }; - - let name = selector!("TestToken"); - let symbol = selector!("TT"); - let decimals = felt!("128"); - let (initial_supply_low, initial_supply_high) = - (felt!("0xFFFFFFFFF"), felt!("0xFFFFFFFFF")); - let recipient = self.account.address(); - - let constructor_args = vec![ - name, - symbol, - decimals, - initial_supply_low, - initial_supply_high, - recipient, - ]; - let unique = false; - - let address = - compute_contract_address(self.config.deployer.salt, class_hash, &constructor_args); - - if let Ok(contract_class_hash) = self - .starknet_rpc - .get_class_hash_at(BlockId::Tag(BlockTag::Pending), address) - .await - { - if contract_class_hash == class_hash { - warn!("ERC20 contract already deployed at address {address:#064x}"); - return Ok(address); - } else { - return Err(eyre!("ERC20 contract {address:#064x} already deployed with a different class hash {contract_class_hash:#064x}, expected {class_hash:#064x}")); - } - } - - let deploy = contract_factory.deploy(constructor_args, self.config.deployer.salt, unique); - - info!( - "Deploying ERC20 contract with nonce={}, address={:#064x}", - nonce, address - ); - - let result = deploy.nonce(nonce).max_fee(MAX_FEE).send().await?; - wait_for_tx(&self.starknet_rpc, result.transaction_hash, CHECK_INTERVAL).await?; - - self.nonces.insert(from_address, nonce + FieldElement::ONE); - - debug!( - "Deploy ERC20 transaction accepted {:#064x}", - result.transaction_hash - ); - - info!("ERC20 contract deployed at address {:#064x}", address); - Ok(address) - } - /// Create accounts. /// /// # Arguments @@ -322,6 +167,8 @@ impl GatlingShooterSetup { let mut deployed_accounts: Vec = Vec::with_capacity(num_accounts); + let mut nonce = self.account.get_nonce().await?; + for i in 0..num_accounts { self.account.set_block_id(BlockId::Tag(BlockTag::Pending)); @@ -361,14 +208,21 @@ impl GatlingShooterSetup { deployed_accounts.push(account); continue; } else { - return Err(eyre!("Account {i} already deployed at address {address:#064x} with a different class hash {account_class_hash:#064x}, expected {class_hash:#064x}")); + bail!("Account {i} already deployed at address {address:#064x} with a different class hash {account_class_hash:#064x}, expected {class_hash:#064x}"); } } info!("Funding account {i} at address {address:#064x}"); let tx_hash = self - .transfer(erc20_address, self.account.clone(), address, felt!("0xFFF")) + .transfer( + erc20_address, + self.account.clone(), + address, + felt!("0xFFF"), + nonce, + ) .await?; + nonce += FieldElement::ONE; wait_for_tx(&self.starknet_rpc, tx_hash, CHECK_INTERVAL).await?; let tx_hash = self .transfer( @@ -376,8 +230,10 @@ impl GatlingShooterSetup { self.account.clone(), address, felt!("0xFFFFFFFFFFFFFFFFFFFF"), + nonce, ) .await?; + nonce += FieldElement::ONE; wait_for_tx(&self.starknet_rpc, tx_hash, CHECK_INTERVAL).await?; let result = deploy.send().await?; @@ -435,11 +291,7 @@ impl GatlingShooterSetup { } self.account.set_block_id(BlockId::Tag(BlockTag::Pending)); - let from_address = self.account.address(); - let nonce = match self.nonces.get(&from_address) { - Some(nonce) => *nonce, - None => self.account.get_nonce().await?, - }; + let nonce = self.account.get_nonce().await?; let tx_resp = self .account @@ -452,8 +304,6 @@ impl GatlingShooterSetup { wait_for_tx(&self.starknet_rpc, tx_resp.transaction_hash, CHECK_INTERVAL).await?; - self.nonces.insert(from_address, nonce + FieldElement::ONE); - info!( "Contract declared successfully at {:#064x}", tx_resp.class_hash @@ -477,11 +327,7 @@ impl GatlingShooterSetup { contract_path.as_ref().display(), class_hash ); - let from_address = self.account.address(); - let nonce = match self.nonces.get(&from_address) { - Some(nonce) => *nonce, - None => self.account.get_nonce().await?, - }; + let nonce = self.account.get_nonce().await?; if self.check_already_declared(class_hash).await? { return Ok(class_hash); @@ -510,12 +356,10 @@ impl GatlingShooterSetup { tx_resp.class_hash ); - self.nonces.insert(from_address, nonce + FieldElement::ONE); - Ok(tx_resp.class_hash) } - async fn declare_contract( + pub async fn declare_contract( &mut self, contract_source: &crate::config::ContractSourceConfig, ) -> Result { diff --git a/src/actions/shooter.rs b/src/actions/shooter.rs new file mode 100644 index 0000000..627feb0 --- /dev/null +++ b/src/actions/shooter.rs @@ -0,0 +1,381 @@ +use std::{collections::HashMap, sync::Arc}; + +use color_eyre::eyre::{bail, ensure}; +use goose::{ + config::GooseConfiguration, + goose::{Scenario, Transaction, TransactionFunction}, + transaction, GooseAttack, +}; +use log::{debug, info, warn}; +use starknet::{ + accounts::{Account, Call, ConnectedAccount}, + contract::ContractFactory, + core::types::{BlockId, BlockTag, FieldElement, InvokeTransactionResult}, + macros::{felt, selector}, + providers::{ + jsonrpc::{HttpTransport, JsonRpcMethod}, + JsonRpcClient, Provider, + }, +}; +use tokio::task::JoinSet; + +use crate::{ + actions::{ + goose::{send_execution, GooseWriteUserState}, + setup::{CHECK_INTERVAL, MAX_FEE}, + }, + config::GatlingConfig, + generators::get_rng, + utils::{compute_contract_address, wait_for_tx}, +}; + +use super::{ + goose::{goose_write_user_wait_last_tx, setup, verify_transactions}, + setup::{GatlingSetup, StarknetAccount}, +}; + +pub trait Shooter { + const NAME: &'static str; + + async fn setup(setup: &mut GatlingSetup) -> color_eyre::Result + where + Self: Sized; + + fn get_goose_config(config: &GatlingConfig) -> color_eyre::Result; + + async fn create_goose_attack( + self: Arc, + config: GooseConfiguration, + accounts: Vec, + ) -> color_eyre::Result + where + Self: Send + Sync + 'static, + { + let setup: TransactionFunction = setup(accounts, config.iterations).await?; + + let submission: TransactionFunction = Self::execute(self.clone()); + + let finalizing: TransactionFunction = goose_write_user_wait_last_tx(); + + let attack = GooseAttack::initialize_with_config(config)?.register_scenario( + Scenario::new(Self::NAME) + .register_transaction(Transaction::new(setup).set_name("Setup").set_on_start()) + .register_transaction( + Transaction::new(submission) + .set_name("Transaction Submission") + .set_sequence(1), + ) + .register_transaction( + Transaction::new(finalizing) + .set_name("Finalizing") + .set_sequence(2) + .set_on_stop(), + ) + .register_transaction( + transaction!(verify_transactions) + .set_name("Verification") + .set_sequence(3) + .set_on_stop(), + ), + ); + + Ok(attack) + } + + fn execute(self: Arc) -> TransactionFunction + where + Self: Send + Sync + 'static, + { + Arc::new(move |user| { + let shooter = self.clone(); + + Box::pin(async move { + let GooseWriteUserState { account, nonce, .. } = user + .get_session_data::() + .expect("Should be in a goose user with GooseUserState session data"); + + let call = shooter.get_execution_data(account); + + let response: InvokeTransactionResult = send_execution( + user, + vec![call], + *nonce, + &account.clone(), + JsonRpcMethod::AddInvokeTransaction, + ) + .await? + .0; + + let GooseWriteUserState { nonce, prev_tx, .. } = + user.get_session_data_mut::().expect( + "Should be successful as we already asserted that the session data is a GooseUserState", + ); + + *nonce += FieldElement::ONE; + + prev_tx.push(response.transaction_hash); + + Ok(()) + }) + }) + } + + fn get_execution_data(&self, account: &StarknetAccount) -> Call; +} + +pub struct TransferShooter { + pub erc20_address: FieldElement, + pub account: StarknetAccount, +} + +pub struct MintShooter { + pub account_to_erc721_addresses: HashMap, + pub recipient: StarknetAccount, +} + +impl Shooter for TransferShooter { + const NAME: &'static str = "Erc20 Transfers"; + + async fn setup(setup: &mut GatlingSetup) -> color_eyre::Result + where + Self: Sized, + { + let class_hash = setup + .declare_contract(&setup.config().setup.erc20_contract.clone()) + .await?; + + let contract_factory = ContractFactory::new(class_hash, setup.deployer_account().clone()); + let nonce = setup.deployer_account().get_nonce().await?; + + let name = selector!("TestToken"); + let symbol = selector!("TT"); + let decimals = felt!("128"); + let (initial_supply_low, initial_supply_high) = + (felt!("0xFFFFFFFFF"), felt!("0xFFFFFFFFF")); + let recipient = setup.deployer_account().address(); + + let constructor_args = vec![ + name, + symbol, + decimals, + initial_supply_low, + initial_supply_high, + recipient, + ]; + let unique = false; + + let address = + compute_contract_address(setup.config().deployer.salt, class_hash, &constructor_args); + + if let Ok(contract_class_hash) = setup + .rpc_client() + .get_class_hash_at(BlockId::Tag(BlockTag::Pending), address) + .await + { + if contract_class_hash == class_hash { + warn!("ERC20 contract already deployed at address {address:#064x}"); + return Ok(TransferShooter { + erc20_address: address, + account: setup.deployer_account().clone(), + }); + } else { + bail!("ERC20 contract {address:#064x} already deployed with a different class hash {contract_class_hash:#064x}, expected {class_hash:#064x}"); + } + } + + let deploy = + contract_factory.deploy(constructor_args, setup.config().deployer.salt, unique); + + info!( + "Deploying ERC20 contract with nonce={}, address={:#064x}", + nonce, address + ); + + let result = deploy.nonce(nonce).max_fee(MAX_FEE).send().await?; + wait_for_tx(setup.rpc_client(), result.transaction_hash, CHECK_INTERVAL).await?; + + debug!( + "Deploy ERC20 transaction accepted {:#064x}", + result.transaction_hash + ); + + info!("ERC20 contract deployed at address {:#064x}", address); + + Ok(TransferShooter { + erc20_address: address, + account: setup.deployer_account().clone(), + }) + } + + fn get_goose_config(config: &GatlingConfig) -> color_eyre::Result { + ensure!( + config.run.num_erc20_transfers >= config.run.concurrency, + "Too few erc20 transfers for the amount of concurrent users" + ); + + // div_euclid will truncate integers when not evenly divisable + let user_iterations = config + .run + .num_erc20_transfers + .div_euclid(config.run.concurrency); + // this will always be a multiple of concurrency, unlike num_erc20_transfers + let total_transactions = user_iterations * config.run.concurrency; + + // If these are not equal that means user_iterations was truncated + if total_transactions != config.run.num_erc20_transfers { + log::warn!("Number of erc20 transfers is not evenly divisble by concurrency, doing {total_transactions} transfers instead"); + } + + { + let mut default = GooseConfiguration::default(); + default.host = config.rpc.url.clone(); + default.iterations = user_iterations as usize; + default.users = Some(config.run.concurrency as usize); + Ok(default) + } + } + + fn get_execution_data(&self, _account: &StarknetAccount) -> Call { + let (amount_low, amount_high) = (felt!("1"), felt!("0")); + + // Hex: 0xdead + // from_hex_be isn't const whereas from_mont is + const VOID_ADDRESS: FieldElement = FieldElement::from_mont([ + 18446744073707727457, + 18446744073709551615, + 18446744073709551615, + 576460752272412784, + ]); + + Call { + to: self.erc20_address, + selector: selector!("transfer"), + calldata: vec![VOID_ADDRESS, amount_low, amount_high], + } + } +} + +impl Shooter for MintShooter { + const NAME: &'static str = "Erc721 Mints"; + + async fn setup(setup: &mut GatlingSetup) -> color_eyre::Result { + let erc721_class_hash = setup + .declare_contract(&setup.config().setup.erc721_contract.clone()) + .await?; + + let deployer_salt = setup.config().deployer.salt; + let mut join_set = JoinSet::new(); + + for account in setup.accounts().iter().cloned() { + let address = account.address(); + let rpc_client = setup.rpc_client().clone(); + join_set.spawn(async move { + let contract = + Self::deploy_erc721(rpc_client, deployer_salt, erc721_class_hash, account) + .await; + + (address, contract) + }); + } + + let mut map = HashMap::with_capacity(setup.accounts().len()); + while let Some((account_address, contract_result)) = + join_set.join_next().await.transpose()? + { + map.insert(account_address, contract_result?); + } + + Ok(Self { + account_to_erc721_addresses: map, + recipient: setup.deployer_account().clone(), + }) + } + + fn get_goose_config(config: &GatlingConfig) -> color_eyre::Result { + ensure!( + config.run.num_erc721_mints >= config.run.concurrency, + "Too few erc721 mints for the amount of concurrent users" + ); + + // div_euclid will truncate integers when not evenly divisable + let user_iterations = config + .run + .num_erc721_mints + .div_euclid(config.run.concurrency); + // this will always be a multiple of concurrency, unlike num_erc721_mints + let total_transactions = user_iterations * config.run.concurrency; + + // If these are not equal that means user_iterations was truncated + if total_transactions != config.run.num_erc721_mints { + log::warn!("Number of erc721 mints is not evenly divisble by concurrency, doing {total_transactions} mints instead"); + } + + { + let mut default = GooseConfiguration::default(); + default.host = config.rpc.url.clone(); + default.iterations = user_iterations as usize; + default.users = Some(config.run.concurrency as usize); + Ok(default) + } + } + + fn get_execution_data(&self, account: &StarknetAccount) -> Call { + let recipient = account.address(); + + let (token_id_low, token_id_high) = (get_rng(), felt!("0x0000")); + + Call { + to: self.account_to_erc721_addresses[&account.address()], + selector: selector!("mint"), + calldata: vec![recipient, token_id_low, token_id_high], + } + } +} + +impl MintShooter { + async fn deploy_erc721( + starknet_rpc: Arc>, + deployer_salt: FieldElement, + class_hash: FieldElement, + recipient: StarknetAccount, + ) -> color_eyre::Result { + let contract_factory = ContractFactory::new(class_hash, &recipient); + + let name = selector!("TestNFT"); + let symbol = selector!("TNFT"); + + let constructor_args = vec![name, symbol, recipient.address()]; + let unique = false; + + let address = compute_contract_address(deployer_salt, class_hash, &constructor_args); + + if let Ok(contract_class_hash) = starknet_rpc + .get_class_hash_at(BlockId::Tag(BlockTag::Pending), address) + .await + { + if contract_class_hash == class_hash { + warn!("ERC721 contract already deployed at address {address:#064x}"); + return Ok(address); + } else { + bail!("ERC721 contract {address:#064x} already deployed with a different class hash {contract_class_hash:#064x}, expected {class_hash:#064x}"); + } + } + + let deploy = contract_factory.deploy(constructor_args, deployer_salt, unique); + + let nonce = recipient.get_nonce().await?; + + info!("Deploying ERC721 with nonce={}, address={address}", nonce); + + let result = deploy.nonce(nonce).max_fee(MAX_FEE).send().await?; + wait_for_tx(&starknet_rpc, result.transaction_hash, CHECK_INTERVAL).await?; + + debug!( + "Deploy ERC721 transaction accepted {:#064x}", + result.transaction_hash + ); + + info!("ERC721 contract deployed at address {:#064x}", address); + Ok(address) + } +} From 791e344fcf6b3386f837a2302ff1e60cd9146183 Mon Sep 17 00:00:00 2001 From: apoorvsadana <95699312+apoorvsadana@users.noreply.github.com> Date: Sat, 13 Apr 2024 15:47:47 +0530 Subject: [PATCH 32/45] add sps feature flag --- Cargo.toml | 4 ++++ config/default.yaml | 6 +++--- src/utils.rs | 25 ++++++++++++++++++++----- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c45c062..047d299 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,3 +34,7 @@ rand = { version = "0.8.5", features = ["rand_chacha"] } lazy_static = "1.4.0" sysinfo = "0.30.5" crossbeam-queue = "0.3.11" + +[features] +default = [] +with_sps = [] diff --git a/config/default.yaml b/config/default.yaml index b4d4892..fe8f685 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -13,12 +13,12 @@ setup: fee_token_address: "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7" num_accounts: 1 - chain_id: "SN_GOERLI" + chain_id: "MADARA" run: concurrency: 5 - num_erc20_transfers: 1000 - num_erc721_mints: 1000 + num_erc20_transfers: 10000 + num_erc721_mints: 0 read_benches: - name: "Get Events" num_requests: 100 diff --git a/src/utils.rs b/src/utils.rs index 3fc6351..69faa4c 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -145,16 +145,16 @@ pub async fn wait_for_tx( tokio::time::sleep(check_interval).await; } Err(ProviderError::StarknetError(StarknetErrorWithMessage { - code: MaybeUnknownErrorCode::Known(StarknetError::TransactionHashNotFound), - .. - })) => { + code: MaybeUnknownErrorCode::Known(StarknetError::TransactionHashNotFound), + .. + })) => { debug!("Waiting for transaction {tx_hash:#064x} to show up"); tokio::time::sleep(check_interval).await; } Err(err) => { return Err(eyre!(err).wrap_err(format!( "Error while waiting for transaction {tx_hash:#064x}" - ))) + ))); } } } @@ -166,7 +166,7 @@ pub async fn wait_for_tx( /// without hitting the StarkNet RPC multiple times pub async fn get_blocks_with_txs( starknet_rpc: &Arc>, - block_range: impl Iterator, + block_range: impl Iterator, ) -> Result)>> { const MAX_CONCURRENT: usize = 50; @@ -207,6 +207,7 @@ pub async fn get_blocks_with_txs( let mut resources = Vec::with_capacity(block_with_txs.transactions.len()); + #[cfg(with_sps)] for tx in block_with_txs.transactions.iter() { let maybe_receipt = starknet_rpc .get_transaction_receipt(tx.transaction_hash()) @@ -229,6 +230,20 @@ pub async fn get_blocks_with_txs( resources.push(resource); } + #[cfg(not(with_sps))] + for _ in block_with_txs.transactions.iter() { + resources.push(ExecutionResources { + steps: 0, + memory_holes: Some(0), + range_check_builtin_applications: 0, + pedersen_builtin_applications: 0, + poseidon_builtin_applications: 0, + ec_op_builtin_applications: 0, + ecdsa_builtin_applications: 0, + bitwise_builtin_applications: 0, + keccak_builtin_applications: 0, + }); + } Ok((block_with_txs, resources)) } From 9958b4ff910decdc0a20213c66eba85b59aae9c4 Mon Sep 17 00:00:00 2001 From: apoorvsadana <95699312+apoorvsadana@users.noreply.github.com> Date: Mon, 15 Apr 2024 15:16:31 +0530 Subject: [PATCH 33/45] review fixes --- config/default.yaml | 4 ++-- src/utils.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/config/default.yaml b/config/default.yaml index fe8f685..b70dcea 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -17,8 +17,8 @@ setup: run: concurrency: 5 - num_erc20_transfers: 10000 - num_erc721_mints: 0 + num_erc20_transfers: 1000 + num_erc721_mints: 1000 read_benches: - name: "Get Events" num_requests: 100 diff --git a/src/utils.rs b/src/utils.rs index 69faa4c..b2b3329 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -145,9 +145,9 @@ pub async fn wait_for_tx( tokio::time::sleep(check_interval).await; } Err(ProviderError::StarknetError(StarknetErrorWithMessage { - code: MaybeUnknownErrorCode::Known(StarknetError::TransactionHashNotFound), - .. - })) => { + code: MaybeUnknownErrorCode::Known(StarknetError::TransactionHashNotFound), + .. + })) => { debug!("Waiting for transaction {tx_hash:#064x} to show up"); tokio::time::sleep(check_interval).await; } @@ -166,7 +166,7 @@ pub async fn wait_for_tx( /// without hitting the StarkNet RPC multiple times pub async fn get_blocks_with_txs( starknet_rpc: &Arc>, - block_range: impl Iterator, + block_range: impl Iterator, ) -> Result)>> { const MAX_CONCURRENT: usize = 50; From 254df660a83847e3acbc78ea8b25338c2240d43f Mon Sep 17 00:00:00 2001 From: Angel Petrov <146711006+Angel-Petrov@users.noreply.github.com> Date: Mon, 15 Apr 2024 13:32:46 +0300 Subject: [PATCH 34/45] Fix conditional comp clippy error --- src/utils.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils.rs b/src/utils.rs index b2b3329..9aac981 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -10,7 +10,7 @@ use log::debug; use starknet::core::types::MaybePendingTransactionReceipt::{PendingReceipt, Receipt}; use starknet::core::types::{ BlockId, BlockWithTxs, ExecutionResources, ExecutionResult, MaybePendingBlockWithTxs, - StarknetError, TransactionReceipt, + StarknetError, }; use starknet::core::{crypto::compute_hash_on_elements, types::FieldElement}; use starknet::providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}; @@ -213,7 +213,7 @@ pub async fn get_blocks_with_txs( .get_transaction_receipt(tx.transaction_hash()) .await?; - use TransactionReceipt as TR; + use starknet::core::types::TransactionReceipt as TR; let resource = match maybe_receipt { Receipt(receipt) => match receipt { From 1e9f7c89b0f488adeabf84ff13a55f2226f9b6ad Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Tue, 16 Apr 2024 13:42:09 +0300 Subject: [PATCH 35/45] Update color-eyre and check Cargo.lock into git --- .gitignore | 4 - Cargo.lock | 3483 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 3483 insertions(+), 4 deletions(-) create mode 100644 Cargo.lock diff --git a/.gitignore b/.gitignore index 4195f06..0500924 100644 --- a/.gitignore +++ b/.gitignore @@ -3,10 +3,6 @@ debug/ target/ -# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries -# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html -Cargo.lock - # These are backup files generated by rustfmt **/*.rs.bk diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..c97db5b --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,3483 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest", + "itertools 0.10.5", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std", + "digest", + "num-bigint", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "async-compression" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07dbbf24db18d609b1462965249abdf49129ccad073ec257da372adc83259c60" +dependencies = [ + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "async-trait" +version = "0.1.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.59", +] + +[[package]] +name = "auto_impl" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.59", +] + +[[package]] +name = "autocfg" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" + +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "bigdecimal" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +dependencies = [ + "serde", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" + +[[package]] +name = "cc" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17f6e324229dc011159fcc089755d1e2e216a90d43a7dea6853ca740b84f35e7" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "serde", + "windows-targets 0.52.5", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clap" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim 0.11.1", +] + +[[package]] +name = "clap_derive" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.59", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + +[[package]] +name = "color-eyre" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "config" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7328b20597b53c2454f0b1919720c25c7339051c02b72b7e05409e00b14132be" +dependencies = [ + "async-trait", + "convert_case", + "json5", + "lazy_static", + "nom", + "pathdiff", + "ron", + "rust-ini", + "serde", + "serde_json", + "toml", + "yaml-rust", +] + +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "cookie" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + +[[package]] +name = "cookie_store" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "387461abbc748185c3a6e1673d826918b450b87ff22639429c694619a83b6cf6" +dependencies = [ + "cookie", + "idna 0.3.0", + "log", + "publicsuffix", + "serde", + "serde_derive", + "serde_json", + "time", + "url", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "ctrlc" +version = "3.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "672465ae37dc1bc6380a6547a8883d5dd397b0f1faaad4f265726cc7042a5345" +dependencies = [ + "nix", + "windows-sys 0.52.0", +] + +[[package]] +name = "darling" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 2.0.59", +] + +[[package]] +name = "darling_macro" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.59", +] + +[[package]] +name = "data-encoding" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dlv-list" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" +dependencies = [ + "const-random", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "either" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" + +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "env_filter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "eth-keystore" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" +dependencies = [ + "aes", + "ctr", + "digest", + "hex", + "hmac", + "pbkdf2", + "rand", + "scrypt", + "serde", + "serde_json", + "sha2", + "sha3", + "thiserror", + "uuid", +] + +[[package]] +name = "ethbloom" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" +dependencies = [ + "crunchy", + "fixed-hash", + "impl-rlp", + "impl-serde", + "tiny-keccak", +] + +[[package]] +name = "ethereum-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" +dependencies = [ + "ethbloom", + "fixed-hash", + "impl-rlp", + "impl-serde", + "primitive-types", + "uint", +] + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fastrand" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" + +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "spin", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.59", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "gatling" +version = "0.1.4" +dependencies = [ + "clap", + "color-eyre", + "config", + "crossbeam-queue", + "dotenvy", + "env_logger", + "futures", + "goose", + "lazy_static", + "log", + "rand", + "serde", + "serde_derive", + "serde_json", + "starknet", + "sysinfo", + "tokio", + "url", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "goose" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cfeedc01d217935e1371901ea642ea6693d68893c67336d146eba23be04bf11" +dependencies = [ + "async-trait", + "chrono", + "ctrlc", + "downcast-rs", + "flume", + "futures", + "gumdrop", + "http", + "itertools 0.11.0", + "lazy_static", + "log", + "num-format", + "rand", + "regex", + "reqwest", + "serde", + "serde_json", + "simplelog", + "strum", + "strum_macros", + "tokio", + "tokio-tungstenite", + "tungstenite", + "url", +] + +[[package]] +name = "gumdrop" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bc700f989d2f6f0248546222d9b4258f5b02a171a431f8285a81c08142629e3" +dependencies = [ + "gumdrop_derive", +] + +[[package]] +name = "gumdrop_derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "729f9bd3449d77e7831a18abfb7ba2f99ee813dfd15b8c2167c9a54ba20aa99d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.2.6", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nix" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "cfg_aliases", + "libc", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-format" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3" +dependencies = [ + "arrayvec", + "itoa", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.59", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "ordered-multimap" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ed8acf08e98e744e5384c8bc63ceb0364e68a6854187221c18df61c4797690e" +dependencies = [ + "dlv-list", + "hashbrown 0.13.2", +] + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] +name = "parity-scale-codec" +version = "3.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +dependencies = [ + "arrayvec", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f73541b156d32197eecda1a4014d7f868fd2bcb3c550d5386087cfba442bf69c" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c35eeed0a3fab112f75165fdc026b3913f4183133f19b49be773ac9ea966e8bd" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.59", +] + +[[package]] +name = "pest_meta" +version = "2.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2adbf29bb9776f28caece835398781ab24435585fe0d4dc1374a61db5accedca" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +dependencies = [ + "toml_edit 0.20.7", +] + +[[package]] +name = "proc-macro2" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56dea16b0a29e94408b9aa5e2940a4eedbd128a1ba20e8f7ae60fd3d465af0e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "psl-types" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" + +[[package]] +name = "publicsuffix" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457" +dependencies = [ + "idna 0.3.0", + "psl-types", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "async-compression", + "base64 0.21.7", + "bytes", + "cookie", + "cookie_store", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-rustls", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", + "winreg", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rustc-hex", +] + +[[package]] +name = "ron" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" +dependencies = [ + "base64 0.21.7", + "bitflags 2.5.0", + "serde", + "serde_derive", +] + +[[package]] +name = "rust-ini" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e2a3bcec1f113553ef1c88aae6c020a369d03d55b58de9869a0908930385091" +dependencies = [ + "cfg-if", + "ordered-multimap", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.21.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "salsa20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +dependencies = [ + "cipher", +] + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scrypt" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f9e24d2b632954ded8ab2ef9fea0a0c769ea56ea98bddbafbad22caeeadf45d" +dependencies = [ + "hmac", + "pbkdf2", + "salsa20", + "sha2", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "security-framework" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.59", +] + +[[package]] +name = "serde_json" +version = "1.0.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" +dependencies = [ + "indexmap 2.2.6", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_json_pythonic" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62212da9872ca2a0cad0093191ee33753eddff9266cbbc1b4a602d13a3a768db" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" +dependencies = [ + "base64 0.13.1", + "chrono", + "hex", + "indexmap 1.9.3", + "serde", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.59", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "simplelog" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16257adbfaef1ee58b1363bdc0664c9b8e1e30aed86049635fb5f147d065a9c0" +dependencies = [ + "log", + "termcolor", + "time", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "starknet" +version = "0.7.0" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +dependencies = [ + "starknet-accounts", + "starknet-contract", + "starknet-core", + "starknet-crypto", + "starknet-ff", + "starknet-macros", + "starknet-providers", + "starknet-signers", +] + +[[package]] +name = "starknet-accounts" +version = "0.6.1" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +dependencies = [ + "async-trait", + "auto_impl", + "starknet-core", + "starknet-providers", + "starknet-signers", + "thiserror", +] + +[[package]] +name = "starknet-contract" +version = "0.6.0" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +dependencies = [ + "serde", + "serde_json", + "serde_with", + "starknet-accounts", + "starknet-core", + "starknet-providers", + "thiserror", +] + +[[package]] +name = "starknet-core" +version = "0.7.2" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +dependencies = [ + "base64 0.21.7", + "flate2", + "hex", + "serde", + "serde_json", + "serde_json_pythonic", + "serde_with", + "sha3", + "starknet-crypto", + "starknet-ff", +] + +[[package]] +name = "starknet-crypto" +version = "0.6.1" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +dependencies = [ + "crypto-bigint", + "hex", + "hmac", + "num-bigint", + "num-integer", + "num-traits", + "rfc6979", + "sha2", + "starknet-crypto-codegen", + "starknet-curve", + "starknet-ff", + "zeroize", +] + +[[package]] +name = "starknet-crypto-codegen" +version = "0.3.2" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +dependencies = [ + "starknet-curve", + "starknet-ff", + "syn 2.0.59", +] + +[[package]] +name = "starknet-curve" +version = "0.4.0" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +dependencies = [ + "starknet-ff", +] + +[[package]] +name = "starknet-ff" +version = "0.3.5" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +dependencies = [ + "ark-ff", + "bigdecimal", + "crypto-bigint", + "getrandom", + "hex", + "num-bigint", + "serde", +] + +[[package]] +name = "starknet-macros" +version = "0.1.4" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +dependencies = [ + "starknet-core", + "syn 2.0.59", +] + +[[package]] +name = "starknet-providers" +version = "0.7.0" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +dependencies = [ + "async-trait", + "auto_impl", + "ethereum-types", + "flate2", + "log", + "reqwest", + "serde", + "serde_json", + "serde_with", + "starknet-core", + "thiserror", + "url", +] + +[[package]] +name = "starknet-signers" +version = "0.5.0" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +dependencies = [ + "async-trait", + "auto_impl", + "crypto-bigint", + "eth-keystore", + "rand", + "starknet-core", + "starknet-crypto", + "thiserror", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.59", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a6531ffc7b071655e4ce2e04bd464c4830bb585a61cabb96cf808f05172615a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "sysinfo" +version = "0.30.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d7c217777061d5a2d652aea771fb9ba98b6dade657204b08c4b9604d11555b" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "windows", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.59", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.59", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.22.9", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" +dependencies = [ + "indexmap 2.2.6", + "serde", + "serde_spanned", + "toml_datetime", + "winnow 0.6.6", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "sharded-slab", + "thread_local", + "tracing-core", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand", + "sha1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna 0.5.0", + "percent-encoding", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom", + "serde", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.59", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.59", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c976aaaa0e1f90dbb21e9587cdaf1d9679a1cde8875c0d6bd83ab96a208352" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.59", +] From 219e8478c434ca95fafa2f2854899e05f205c078 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Mon, 29 Apr 2024 08:22:36 +0300 Subject: [PATCH 36/45] Update starknet to match madara main --- Cargo.lock | 44 ++++++++++++++++++++++---------------------- Cargo.toml | 2 +- src/actions/goose.rs | 9 +++++---- src/actions/setup.rs | 7 ++----- src/utils.rs | 24 +++++++++++------------- 5 files changed, 41 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c97db5b..c56ea1c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2457,8 +2457,8 @@ dependencies = [ [[package]] name = "starknet" -version = "0.7.0" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +version = "0.10.0" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=2d59636911628260fa460179010bbd00e89de06e#2d59636911628260fa460179010bbd00e89de06e" dependencies = [ "starknet-accounts", "starknet-contract", @@ -2472,8 +2472,8 @@ dependencies = [ [[package]] name = "starknet-accounts" -version = "0.6.1" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +version = "0.9.0" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=2d59636911628260fa460179010bbd00e89de06e#2d59636911628260fa460179010bbd00e89de06e" dependencies = [ "async-trait", "auto_impl", @@ -2485,8 +2485,8 @@ dependencies = [ [[package]] name = "starknet-contract" -version = "0.6.0" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +version = "0.9.0" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=2d59636911628260fa460179010bbd00e89de06e#2d59636911628260fa460179010bbd00e89de06e" dependencies = [ "serde", "serde_json", @@ -2499,8 +2499,8 @@ dependencies = [ [[package]] name = "starknet-core" -version = "0.7.2" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +version = "0.10.0" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=2d59636911628260fa460179010bbd00e89de06e#2d59636911628260fa460179010bbd00e89de06e" dependencies = [ "base64 0.21.7", "flate2", @@ -2516,8 +2516,8 @@ dependencies = [ [[package]] name = "starknet-crypto" -version = "0.6.1" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +version = "0.6.2" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=2d59636911628260fa460179010bbd00e89de06e#2d59636911628260fa460179010bbd00e89de06e" dependencies = [ "crypto-bigint", "hex", @@ -2535,8 +2535,8 @@ dependencies = [ [[package]] name = "starknet-crypto-codegen" -version = "0.3.2" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +version = "0.3.3" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=2d59636911628260fa460179010bbd00e89de06e#2d59636911628260fa460179010bbd00e89de06e" dependencies = [ "starknet-curve", "starknet-ff", @@ -2545,16 +2545,16 @@ dependencies = [ [[package]] name = "starknet-curve" -version = "0.4.0" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +version = "0.4.2" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=2d59636911628260fa460179010bbd00e89de06e#2d59636911628260fa460179010bbd00e89de06e" dependencies = [ "starknet-ff", ] [[package]] name = "starknet-ff" -version = "0.3.5" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +version = "0.3.7" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=2d59636911628260fa460179010bbd00e89de06e#2d59636911628260fa460179010bbd00e89de06e" dependencies = [ "ark-ff", "bigdecimal", @@ -2567,8 +2567,8 @@ dependencies = [ [[package]] name = "starknet-macros" -version = "0.1.4" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +version = "0.1.7" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=2d59636911628260fa460179010bbd00e89de06e#2d59636911628260fa460179010bbd00e89de06e" dependencies = [ "starknet-core", "syn 2.0.59", @@ -2576,8 +2576,8 @@ dependencies = [ [[package]] name = "starknet-providers" -version = "0.7.0" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +version = "0.10.0" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=2d59636911628260fa460179010bbd00e89de06e#2d59636911628260fa460179010bbd00e89de06e" dependencies = [ "async-trait", "auto_impl", @@ -2595,8 +2595,8 @@ dependencies = [ [[package]] name = "starknet-signers" -version = "0.5.0" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +version = "0.8.0" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=2d59636911628260fa460179010bbd00e89de06e#2d59636911628260fa460179010bbd00e89de06e" dependencies = [ "async-trait", "auto_impl", diff --git a/Cargo.toml b/Cargo.toml index 047d299..9e67c3f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ opt-level = 3 [dependencies] # Starknet dependencies, currently the same starknet revision as the one in # madara https://github.com/keep-starknet-strange/madara/blob/main/Cargo.toml#L268 -starknet = { git = "https://github.com/xJonathanLEI/starknet-rs.git", rev = "64ebc36" } +starknet = { git = "https://github.com/xJonathanLEI/starknet-rs.git", rev = "2d59636911628260fa460179010bbd00e89de06e" } goose = "0.17.2" env_logger = "0.11.2" diff --git a/src/actions/goose.rs b/src/actions/goose.rs index 078be41..02649f0 100644 --- a/src/actions/goose.rs +++ b/src/actions/goose.rs @@ -14,7 +14,8 @@ use starknet::{ Account, Call, ConnectedAccount, ExecutionEncoder, RawExecution, SingleOwnerAccount, }, core::types::{ - BroadcastedInvokeTransaction, ExecutionResult, FieldElement, MaybePendingTransactionReceipt, + BroadcastedInvokeTransaction, BroadcastedInvokeTransactionV1, ExecutionResult, + FieldElement, MaybePendingTransactionReceipt, }, providers::{ jsonrpc::{HttpTransport, JsonRpcError, JsonRpcMethod, JsonRpcResponse}, @@ -254,7 +255,7 @@ pub async fn wait_for_tx( tokio::time::sleep(CHECK_INTERVAL).await; } JsonRpcResponse::Error { - error: JsonRpcError { code, message }, + error: JsonRpcError { code, message, .. }, .. } => { let tag = format!("Error Code {code} while waiting for tx {tx_hash:#064x}"); @@ -292,7 +293,7 @@ pub async fn send_execution( // see https://github.com/xJonathanLEI/starknet-rs/issues/538 let raw_exec = unsafe { mem::transmute::(raw_exec) }; - let param = BroadcastedInvokeTransaction { + let param = BroadcastedInvokeTransaction::V1(BroadcastedInvokeTransactionV1 { sender_address: from_account.address(), calldata, max_fee: MAX_FEE, @@ -302,7 +303,7 @@ pub async fn send_execution( .expect("Raw Execution should be correctly constructed for signature"), nonce, is_query: false, - }; + }); send_request(user, method, param).await } diff --git a/src/actions/setup.rs b/src/actions/setup.rs index 86ccc97..4fd2dce 100644 --- a/src/actions/setup.rs +++ b/src/actions/setup.rs @@ -20,8 +20,8 @@ use starknet::core::types::{ contract::legacy::LegacyContractClass, BlockId, BlockTag, FieldElement, StarknetError, }; use starknet::macros::{felt, selector}; +use starknet::providers::ProviderError; use starknet::providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}; -use starknet::providers::{MaybeUnknownErrorCode, ProviderError, StarknetErrorWithMessage}; use starknet::signers::{LocalWallet, SigningKey}; use std::sync::Arc; use std::time::Duration; @@ -266,10 +266,7 @@ impl GatlingSetup { warn!("Contract already declared at {class_hash:#064x}"); Ok(true) } - Err(ProviderError::StarknetError(StarknetErrorWithMessage { - code: MaybeUnknownErrorCode::Known(StarknetError::ClassHashNotFound), - .. - })) => Ok(false), + Err(ProviderError::StarknetError(StarknetError::ClassHashNotFound)) => Ok(false), Err(err) => Err(eyre!(err)), } } diff --git a/src/utils.rs b/src/utils.rs index 9aac981..0e941bb 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -13,8 +13,8 @@ use starknet::core::types::{ StarknetError, }; use starknet::core::{crypto::compute_hash_on_elements, types::FieldElement}; +use starknet::providers::ProviderError; use starknet::providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}; -use starknet::providers::{MaybeUnknownErrorCode, ProviderError, StarknetErrorWithMessage}; use tokio::task::JoinSet; use std::time::Duration; @@ -144,10 +144,7 @@ pub async fn wait_for_tx( debug!("Waiting for transaction {tx_hash:#064x} to be accepted"); tokio::time::sleep(check_interval).await; } - Err(ProviderError::StarknetError(StarknetErrorWithMessage { - code: MaybeUnknownErrorCode::Known(StarknetError::TransactionHashNotFound), - .. - })) => { + Err(ProviderError::StarknetError(StarknetError::TransactionHashNotFound)) => { debug!("Waiting for transaction {tx_hash:#064x} to show up"); tokio::time::sleep(check_interval).await; } @@ -234,14 +231,15 @@ pub async fn get_blocks_with_txs( for _ in block_with_txs.transactions.iter() { resources.push(ExecutionResources { steps: 0, - memory_holes: Some(0), - range_check_builtin_applications: 0, - pedersen_builtin_applications: 0, - poseidon_builtin_applications: 0, - ec_op_builtin_applications: 0, - ecdsa_builtin_applications: 0, - bitwise_builtin_applications: 0, - keccak_builtin_applications: 0, + memory_holes: None, + range_check_builtin_applications: None, + pedersen_builtin_applications: None, + poseidon_builtin_applications: None, + ec_op_builtin_applications: None, + ecdsa_builtin_applications: None, + bitwise_builtin_applications: None, + keccak_builtin_applications: None, + segment_arena_builtin: None, }); } From 8a13a6b2184e898daa0912e6314cc8c8d0b433ef Mon Sep 17 00:00:00 2001 From: apoorvsadana <95699312+apoorvsadana@users.noreply.github.com> Date: Tue, 7 May 2024 16:01:28 +0530 Subject: [PATCH 37/45] receipt=>status and small fixes --- config/default.yaml | 4 ++-- src/actions/goose.rs | 28 ++++++++++++++-------------- src/actions/setup.rs | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/config/default.yaml b/config/default.yaml index b70dcea..52943f7 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -17,8 +17,8 @@ setup: run: concurrency: 5 - num_erc20_transfers: 1000 - num_erc721_mints: 1000 + num_erc20_transfers: 5000 + num_erc721_mints: 5000 read_benches: - name: "Get Events" num_requests: 100 diff --git a/src/actions/goose.rs b/src/actions/goose.rs index 02649f0..96d0587 100644 --- a/src/actions/goose.rs +++ b/src/actions/goose.rs @@ -9,6 +9,7 @@ use crossbeam_queue::ArrayQueue; use goose::{config::GooseConfiguration, metrics::GooseRequestMetric, prelude::*}; use rand::prelude::SliceRandom; use serde::{de::DeserializeOwned, Serialize}; +use starknet::core::types::{SequencerTransactionStatus, TransactionStatus}; use starknet::{ accounts::{ Account, Call, ConnectedAccount, ExecutionEncoder, RawExecution, SingleOwnerAccount, @@ -165,24 +166,23 @@ pub async fn verify_transactions(user: &mut GooseUser) -> TransactionResult { ); for tx in transactions { - let (receipt, mut metrics) = - send_request(user, JsonRpcMethod::GetTransactionReceipt, tx).await?; + let (status, mut metrics) = + send_request::(user, JsonRpcMethod::GetTransactionStatus, tx) + .await?; - match receipt { - MaybePendingTransactionReceipt::Receipt(receipt) => match receipt.execution_result() { - ExecutionResult::Succeeded => {} - ExecutionResult::Reverted { reason } => { - let tag = format!("Transaction {tx:#064x} has been rejected/reverted"); + match status.finality_status() { + SequencerTransactionStatus::Rejected => { + let tag = format!("Transaction {tx:#064x} has been rejected/reverted"); - return user.set_failure(&tag, &mut metrics, None, Some(reason)); - } - }, - MaybePendingTransactionReceipt::PendingReceipt(pending) => { + return user.set_failure(&tag, &mut metrics, None, None); + } + SequencerTransactionStatus::Received => { let tag = format!("Transaction {tx:#064x} is pending when no transactions should be"); - let body = format!("{pending:?}"); - return user.set_failure(&tag, &mut metrics, None, Some(&body)); + return user.set_failure(&tag, &mut metrics, None, None); + } + SequencerTransactionStatus::AcceptedOnL1 | SequencerTransactionStatus::AcceptedOnL2 => { } } } @@ -190,7 +190,7 @@ pub async fn verify_transactions(user: &mut GooseUser) -> TransactionResult { Ok(()) } -const WAIT_FOR_TX_TIMEOUT: Duration = Duration::from_secs(60); +const WAIT_FOR_TX_TIMEOUT: Duration = Duration::from_secs(600); pub async fn wait_for_tx( user: &mut GooseUser, diff --git a/src/actions/setup.rs b/src/actions/setup.rs index 4fd2dce..5b9042a 100644 --- a/src/actions/setup.rs +++ b/src/actions/setup.rs @@ -218,7 +218,7 @@ impl GatlingSetup { erc20_address, self.account.clone(), address, - felt!("0xFFF"), + felt!("0xFFFFF"), nonce, ) .await?; From f63697079f2669e6c5a31c2c8eb486081719e964 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Thu, 16 May 2024 10:49:56 +0300 Subject: [PATCH 38/45] Splitting read command & refactoring --- README.md | 5 + config/read_params/get_events.json | 4 +- src/actions/goose.rs | 120 +++++---- src/actions/mod.rs | 126 +++++----- src/actions/shooter.rs | 381 ----------------------------- src/actions/shooters.rs | 149 +++++++++++ src/actions/shooters/mint.rs | 127 ++++++++++ src/actions/shooters/transfer.rs | 120 +++++++++ src/cli/mod.rs | 4 +- src/main.rs | 3 + src/metrics.rs | 153 +++--------- 11 files changed, 591 insertions(+), 601 deletions(-) delete mode 100644 src/actions/shooter.rs create mode 100644 src/actions/shooters.rs create mode 100644 src/actions/shooters/mint.rs create mode 100644 src/actions/shooters/transfer.rs diff --git a/README.md b/README.md index 3d1e77c..76a1e0c 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,11 @@ The configuration is defined by the following spec gatling shoot -c config/default.yaml ``` +For a read test: +```bash +gatling read -c config/default.yaml +``` + ### Output The main output of gomu gomu is the report output location specified in specified in the configuration file. diff --git a/config/read_params/get_events.json b/config/read_params/get_events.json index f6bc91a..a7671e9 100644 --- a/config/read_params/get_events.json +++ b/config/read_params/get_events.json @@ -1,7 +1,7 @@ [ { - "from_block": null, - "to_block": null, + "from_block": {"block_number": null}, + "to_block": {"block_number": null}, "address": null, "keys": [], "continuation_token": null, diff --git a/src/actions/goose.rs b/src/actions/goose.rs index 96d0587..7e70de8 100644 --- a/src/actions/goose.rs +++ b/src/actions/goose.rs @@ -1,6 +1,9 @@ use std::{ mem, - sync::Arc, + sync::{ + atomic::{AtomicU64, Ordering}, + Arc, OnceLock, + }, time::{Duration, SystemTime}, }; @@ -9,7 +12,7 @@ use crossbeam_queue::ArrayQueue; use goose::{config::GooseConfiguration, metrics::GooseRequestMetric, prelude::*}; use rand::prelude::SliceRandom; use serde::{de::DeserializeOwned, Serialize}; -use starknet::core::types::{SequencerTransactionStatus, TransactionStatus}; +use starknet::core::types::TransactionReceipt; use starknet::{ accounts::{ Account, Call, ConnectedAccount, ExecutionEncoder, RawExecution, SingleOwnerAccount, @@ -27,11 +30,40 @@ use starknet::{ use crate::{ actions::setup::{GatlingSetup, CHECK_INTERVAL, MAX_FEE}, - config::ParametersFile, + config::{GatlingConfig, ParametersFile}, }; use super::setup::StarknetAccount; +pub fn make_goose_config( + config: &GatlingConfig, + amount: u64, + name: &'static str, +) -> color_eyre::Result { + ensure!( + amount >= config.run.concurrency, + "Too few {name} for the amount of concurrent users" + ); + + // div_euclid will truncate integers when not evenly divisable + let user_iterations = amount.div_euclid(config.run.concurrency); + // this will always be a multiple of concurrency, unlike the provided amount + let total_transactions = user_iterations * config.run.concurrency; + + // If these are not equal that means user_iterations was truncated + if total_transactions != amount { + log::warn!("Number of {name} is not evenly divisble by concurrency, doing {total_transactions} calls instead"); + } + + Ok({ + let mut default = GooseConfiguration::default(); + default.host.clone_from(&config.rpc.url); + default.iterations = user_iterations as usize; + default.users = Some(config.run.concurrency as usize); + default + }) +} + #[derive(Debug, Clone)] pub struct GooseWriteUserState { pub account: StarknetAccount, @@ -88,7 +120,7 @@ pub fn goose_write_user_wait_last_tx() -> TransactionFunction { Box::pin(async move { // If all transactions failed, we can skip this step if let Some(tx) = tx { - wait_for_tx(user, tx).await?; + wait_for_tx_with_goose(user, tx).await?; } Ok(()) @@ -102,32 +134,9 @@ pub async fn read_method( method: JsonRpcMethod, parameters_list: ParametersFile, ) -> color_eyre::Result { - let config = shooter.config(); - - ensure!( - amount >= config.run.concurrency, - "Too few reads for the amount of concurrent users" - ); + let goose_read_config = make_goose_config(shooter.config(), amount, "read calls")?; - // div_euclid will truncate integers when not evenly divisable - let user_iterations = amount.div_euclid(config.run.concurrency); - // this will always be a multiple of concurrency, unlike the provided amount - let total_transactions = user_iterations * config.run.concurrency; - - // If these are not equal that means user_iterations was truncated - if total_transactions != amount { - log::warn!("Number of erc721 mints is not evenly divisble by concurrency, doing {total_transactions} mints instead"); - } - - let goose_get_events_config = { - let mut default = GooseConfiguration::default(); - default.host = config.rpc.url.clone(); - default.iterations = user_iterations as usize; - default.users = Some(config.run.concurrency as usize); - default - }; - - let events: TransactionFunction = Arc::new(move |user| { + let reads: TransactionFunction = Arc::new(move |user| { let mut rng = rand::thread_rng(); let mut params_list = parameters_list.clone(); @@ -146,10 +155,10 @@ pub async fn read_method( }) }); - let metrics = GooseAttack::initialize_with_config(goose_get_events_config)? + let metrics = GooseAttack::initialize_with_config(goose_read_config)? .register_scenario( scenario!("Read Metric") - .register_transaction(Transaction::new(events).set_name("Request")), + .register_transaction(Transaction::new(reads).set_name("Request")), ) .execute() .await?; @@ -157,7 +166,16 @@ pub async fn read_method( Ok(metrics) } -pub async fn verify_transactions(user: &mut GooseUser) -> TransactionResult { +#[derive(Default)] +pub struct TransactionBlocks { + pub first: OnceLock, + pub last: AtomicU64, +} + +pub async fn verify_transactions( + user: &mut GooseUser, + blocks: Arc, +) -> TransactionResult { let transactions = mem::take( &mut user .get_session_data_mut::() @@ -166,24 +184,37 @@ pub async fn verify_transactions(user: &mut GooseUser) -> TransactionResult { ); for tx in transactions { - let (status, mut metrics) = - send_request::(user, JsonRpcMethod::GetTransactionStatus, tx) - .await?; + let (receipt, mut metrics) = + send_request(user, JsonRpcMethod::GetTransactionReceipt, tx).await?; - match status.finality_status() { - SequencerTransactionStatus::Rejected => { - let tag = format!("Transaction {tx:#064x} has been rejected/reverted"); - - return user.set_failure(&tag, &mut metrics, None, None); + match receipt { + MaybePendingTransactionReceipt::Receipt(TransactionReceipt::Invoke(receipt)) => { + match receipt.execution_result { + ExecutionResult::Succeeded => { + let _ = blocks.first.set(receipt.block_number); + blocks.last.store(receipt.block_number, Ordering::Relaxed) + } + ExecutionResult::Reverted { .. } => { + let tag = format!("Transaction {tx:#064x} has been rejected/reverted"); + + return user.set_failure(&tag, &mut metrics, None, None); + } + } + } + MaybePendingTransactionReceipt::Receipt(_) => { + return user.set_failure( + "Receipt is not of type InvokeTransactionReceipt", + &mut metrics, + None, + None, + ); } - SequencerTransactionStatus::Received => { + MaybePendingTransactionReceipt::PendingReceipt(_) => { let tag = format!("Transaction {tx:#064x} is pending when no transactions should be"); return user.set_failure(&tag, &mut metrics, None, None); } - SequencerTransactionStatus::AcceptedOnL1 | SequencerTransactionStatus::AcceptedOnL2 => { - } } } @@ -192,7 +223,8 @@ pub async fn verify_transactions(user: &mut GooseUser) -> TransactionResult { const WAIT_FOR_TX_TIMEOUT: Duration = Duration::from_secs(600); -pub async fn wait_for_tx( +/// This function is different then `crate::utils::wait_for_tx` due to it using the goose requester +pub async fn wait_for_tx_with_goose( user: &mut GooseUser, tx_hash: FieldElement, ) -> Result<(), Box> { diff --git a/src/actions/mod.rs b/src/actions/mod.rs index 23f6a43..a6b0ee6 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -1,6 +1,6 @@ -use std::sync::Arc; +use std::{fs::File, sync::Arc}; -use starknet::{core::types::BlockId, providers::Provider}; +use log::info; use crate::{ config::GatlingConfig, @@ -9,12 +9,12 @@ use crate::{ use self::{ setup::GatlingSetup, - shooter::{MintShooter, Shooter, TransferShooter}, + shooters::{mint::MintShooter, transfer::TransferShooter, Shooter, ShooterAttack}, }; mod goose; mod setup; -mod shooter; +mod shooters; pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { let total_txs = config.run.num_erc20_transfers + config.run.num_erc721_mints; @@ -27,17 +27,18 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { let mut global_report = GlobalReport { users: shooter_setup.config().run.concurrency, - all_bench_report: BenchmarkReport::new("".into(), total_txs as usize), + all_bench_report: None, benches: Vec::new(), extra: crate::utils::sysinfo_string(), }; - let start_block = shooter_setup.rpc_client().block_number().await?; + let mut blocks = Option::<(u64, u64)>::None; if shooter_setup.config().run.num_erc20_transfers != 0 { let report = make_report_over_shooter(transfer_shooter, &shooter_setup).await?; - global_report.benches.push(report); + global_report.benches.push(report.0); + blocks.get_or_insert((report.1, report.2)).1 = report.2; } else { log::info!("Skipping erc20 transfers") } @@ -47,55 +48,27 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { let report = make_report_over_shooter(shooter, &shooter_setup).await?; - global_report.benches.push(report); + global_report.benches.push(report.0); + blocks.get_or_insert((report.1, report.2)).1 = report.2; + } else { log::info!("Skipping erc721 mints") } - let end_block = shooter_setup.rpc_client().block_number().await?; - - for read_bench in &shooter_setup.config().run.read_benches { - let mut params = read_bench.parameters_location.clone(); - - // Look into templating json for these if it becomes more complex to handle - // liquid_json sees like a relatively popular option for this - for parameter in &mut params { - if let Some(from) = parameter.get_mut("from_block") { - if from.is_null() { - *from = serde_json::to_value(BlockId::Number(start_block))?; - } - } - - if let Some(to) = parameter.get_mut("to_block") { - if to.is_null() { - *to = serde_json::to_value(BlockId::Number(end_block))?; - } - } - } - - let metrics = goose::read_method( - &shooter_setup, - read_bench.num_requests, - read_bench.method, - read_bench.parameters_location.clone(), - ) - .await?; - - let mut report = - BenchmarkReport::new(read_bench.name.clone(), metrics.scenarios[0].counter); - - report.with_goose_read_metrics(&metrics)?; + let mut all_bench_report = BenchmarkReport::new("".into(), total_txs as usize); - global_report.benches.push(report); - } + if let Some((start_block, end_block)) = blocks { + info!("Start and End Blocks: {start_block}, {end_block}"); - let rpc_result = global_report - .all_bench_report + let rpc_result = all_bench_report .with_block_range(shooter_setup.rpc_client(), start_block, end_block) .await; - if let Err(error) = rpc_result { - log::error!("Failed to get block range: {error}") + global_report.all_bench_report = Some(all_bench_report); + + if let Err(error) = rpc_result { + log::error!("Failed to get block range: {error}") + } } let report_path = shooter_setup @@ -104,8 +77,7 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { .output_location .with_extension("json"); - let writer = std::fs::File::create(report_path)?; - serde_json::to_writer_pretty(writer, &global_report)?; + serde_json::to_writer_pretty(File::create(report_path)?, &global_report)?; Ok(()) } @@ -113,21 +85,21 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { async fn make_report_over_shooter( shooter: S, setup: &GatlingSetup, -) -> color_eyre::Result { +) -> color_eyre::Result<(BenchmarkReport, u64, u64)> { let goose_config = S::get_goose_config(setup.config())?; - let attack = Arc::new(shooter) - .create_goose_attack(goose_config, setup.accounts().to_vec()) + let ShooterAttack { + goose_metrics, + first_block, + last_block, + } = Arc::new(shooter) + .goose_attack(goose_config, setup.accounts().to_vec()) .await?; - let start_block = setup.rpc_client().block_number().await?; - let goose_metrics = attack.execute().await?; - let end_block = setup.rpc_client().block_number().await?; - let mut report = BenchmarkReport::new(S::NAME.to_string(), goose_metrics.scenarios[0].counter); let rpc_result = report - .with_block_range(setup.rpc_client(), start_block + 1, end_block) + .with_block_range(setup.rpc_client(), first_block + 1, last_block) .await; let num_blocks = setup.config().report.num_blocks; @@ -141,5 +113,43 @@ async fn make_report_over_shooter( } report.with_goose_write_metrics(&goose_metrics)?; - Ok(report) + Ok((report, first_block, last_block)) +} + +pub async fn read(config: GatlingConfig) -> color_eyre::Result<()> { + let shooter_setup = GatlingSetup::from_config(config).await?; + + let mut global_report = GlobalReport { + users: shooter_setup.config().run.concurrency, + all_bench_report: None, + benches: Vec::new(), + extra: crate::utils::sysinfo_string(), + }; + + for read_bench in &shooter_setup.config().run.read_benches { + let metrics = goose::read_method( + &shooter_setup, + read_bench.num_requests, + read_bench.method, + read_bench.parameters_location.clone(), + ) + .await?; + + let mut report = + BenchmarkReport::new(read_bench.name.clone(), metrics.scenarios[0].counter); + + report.with_goose_read_metrics(&metrics)?; + + global_report.benches.push(report); + } + + let report_path = shooter_setup + .config() + .report + .output_location + .with_extension("json"); + + serde_json::to_writer_pretty(File::create(report_path)?, &global_report)?; + + Ok(()) } diff --git a/src/actions/shooter.rs b/src/actions/shooter.rs deleted file mode 100644 index 627feb0..0000000 --- a/src/actions/shooter.rs +++ /dev/null @@ -1,381 +0,0 @@ -use std::{collections::HashMap, sync::Arc}; - -use color_eyre::eyre::{bail, ensure}; -use goose::{ - config::GooseConfiguration, - goose::{Scenario, Transaction, TransactionFunction}, - transaction, GooseAttack, -}; -use log::{debug, info, warn}; -use starknet::{ - accounts::{Account, Call, ConnectedAccount}, - contract::ContractFactory, - core::types::{BlockId, BlockTag, FieldElement, InvokeTransactionResult}, - macros::{felt, selector}, - providers::{ - jsonrpc::{HttpTransport, JsonRpcMethod}, - JsonRpcClient, Provider, - }, -}; -use tokio::task::JoinSet; - -use crate::{ - actions::{ - goose::{send_execution, GooseWriteUserState}, - setup::{CHECK_INTERVAL, MAX_FEE}, - }, - config::GatlingConfig, - generators::get_rng, - utils::{compute_contract_address, wait_for_tx}, -}; - -use super::{ - goose::{goose_write_user_wait_last_tx, setup, verify_transactions}, - setup::{GatlingSetup, StarknetAccount}, -}; - -pub trait Shooter { - const NAME: &'static str; - - async fn setup(setup: &mut GatlingSetup) -> color_eyre::Result - where - Self: Sized; - - fn get_goose_config(config: &GatlingConfig) -> color_eyre::Result; - - async fn create_goose_attack( - self: Arc, - config: GooseConfiguration, - accounts: Vec, - ) -> color_eyre::Result - where - Self: Send + Sync + 'static, - { - let setup: TransactionFunction = setup(accounts, config.iterations).await?; - - let submission: TransactionFunction = Self::execute(self.clone()); - - let finalizing: TransactionFunction = goose_write_user_wait_last_tx(); - - let attack = GooseAttack::initialize_with_config(config)?.register_scenario( - Scenario::new(Self::NAME) - .register_transaction(Transaction::new(setup).set_name("Setup").set_on_start()) - .register_transaction( - Transaction::new(submission) - .set_name("Transaction Submission") - .set_sequence(1), - ) - .register_transaction( - Transaction::new(finalizing) - .set_name("Finalizing") - .set_sequence(2) - .set_on_stop(), - ) - .register_transaction( - transaction!(verify_transactions) - .set_name("Verification") - .set_sequence(3) - .set_on_stop(), - ), - ); - - Ok(attack) - } - - fn execute(self: Arc) -> TransactionFunction - where - Self: Send + Sync + 'static, - { - Arc::new(move |user| { - let shooter = self.clone(); - - Box::pin(async move { - let GooseWriteUserState { account, nonce, .. } = user - .get_session_data::() - .expect("Should be in a goose user with GooseUserState session data"); - - let call = shooter.get_execution_data(account); - - let response: InvokeTransactionResult = send_execution( - user, - vec![call], - *nonce, - &account.clone(), - JsonRpcMethod::AddInvokeTransaction, - ) - .await? - .0; - - let GooseWriteUserState { nonce, prev_tx, .. } = - user.get_session_data_mut::().expect( - "Should be successful as we already asserted that the session data is a GooseUserState", - ); - - *nonce += FieldElement::ONE; - - prev_tx.push(response.transaction_hash); - - Ok(()) - }) - }) - } - - fn get_execution_data(&self, account: &StarknetAccount) -> Call; -} - -pub struct TransferShooter { - pub erc20_address: FieldElement, - pub account: StarknetAccount, -} - -pub struct MintShooter { - pub account_to_erc721_addresses: HashMap, - pub recipient: StarknetAccount, -} - -impl Shooter for TransferShooter { - const NAME: &'static str = "Erc20 Transfers"; - - async fn setup(setup: &mut GatlingSetup) -> color_eyre::Result - where - Self: Sized, - { - let class_hash = setup - .declare_contract(&setup.config().setup.erc20_contract.clone()) - .await?; - - let contract_factory = ContractFactory::new(class_hash, setup.deployer_account().clone()); - let nonce = setup.deployer_account().get_nonce().await?; - - let name = selector!("TestToken"); - let symbol = selector!("TT"); - let decimals = felt!("128"); - let (initial_supply_low, initial_supply_high) = - (felt!("0xFFFFFFFFF"), felt!("0xFFFFFFFFF")); - let recipient = setup.deployer_account().address(); - - let constructor_args = vec![ - name, - symbol, - decimals, - initial_supply_low, - initial_supply_high, - recipient, - ]; - let unique = false; - - let address = - compute_contract_address(setup.config().deployer.salt, class_hash, &constructor_args); - - if let Ok(contract_class_hash) = setup - .rpc_client() - .get_class_hash_at(BlockId::Tag(BlockTag::Pending), address) - .await - { - if contract_class_hash == class_hash { - warn!("ERC20 contract already deployed at address {address:#064x}"); - return Ok(TransferShooter { - erc20_address: address, - account: setup.deployer_account().clone(), - }); - } else { - bail!("ERC20 contract {address:#064x} already deployed with a different class hash {contract_class_hash:#064x}, expected {class_hash:#064x}"); - } - } - - let deploy = - contract_factory.deploy(constructor_args, setup.config().deployer.salt, unique); - - info!( - "Deploying ERC20 contract with nonce={}, address={:#064x}", - nonce, address - ); - - let result = deploy.nonce(nonce).max_fee(MAX_FEE).send().await?; - wait_for_tx(setup.rpc_client(), result.transaction_hash, CHECK_INTERVAL).await?; - - debug!( - "Deploy ERC20 transaction accepted {:#064x}", - result.transaction_hash - ); - - info!("ERC20 contract deployed at address {:#064x}", address); - - Ok(TransferShooter { - erc20_address: address, - account: setup.deployer_account().clone(), - }) - } - - fn get_goose_config(config: &GatlingConfig) -> color_eyre::Result { - ensure!( - config.run.num_erc20_transfers >= config.run.concurrency, - "Too few erc20 transfers for the amount of concurrent users" - ); - - // div_euclid will truncate integers when not evenly divisable - let user_iterations = config - .run - .num_erc20_transfers - .div_euclid(config.run.concurrency); - // this will always be a multiple of concurrency, unlike num_erc20_transfers - let total_transactions = user_iterations * config.run.concurrency; - - // If these are not equal that means user_iterations was truncated - if total_transactions != config.run.num_erc20_transfers { - log::warn!("Number of erc20 transfers is not evenly divisble by concurrency, doing {total_transactions} transfers instead"); - } - - { - let mut default = GooseConfiguration::default(); - default.host = config.rpc.url.clone(); - default.iterations = user_iterations as usize; - default.users = Some(config.run.concurrency as usize); - Ok(default) - } - } - - fn get_execution_data(&self, _account: &StarknetAccount) -> Call { - let (amount_low, amount_high) = (felt!("1"), felt!("0")); - - // Hex: 0xdead - // from_hex_be isn't const whereas from_mont is - const VOID_ADDRESS: FieldElement = FieldElement::from_mont([ - 18446744073707727457, - 18446744073709551615, - 18446744073709551615, - 576460752272412784, - ]); - - Call { - to: self.erc20_address, - selector: selector!("transfer"), - calldata: vec![VOID_ADDRESS, amount_low, amount_high], - } - } -} - -impl Shooter for MintShooter { - const NAME: &'static str = "Erc721 Mints"; - - async fn setup(setup: &mut GatlingSetup) -> color_eyre::Result { - let erc721_class_hash = setup - .declare_contract(&setup.config().setup.erc721_contract.clone()) - .await?; - - let deployer_salt = setup.config().deployer.salt; - let mut join_set = JoinSet::new(); - - for account in setup.accounts().iter().cloned() { - let address = account.address(); - let rpc_client = setup.rpc_client().clone(); - join_set.spawn(async move { - let contract = - Self::deploy_erc721(rpc_client, deployer_salt, erc721_class_hash, account) - .await; - - (address, contract) - }); - } - - let mut map = HashMap::with_capacity(setup.accounts().len()); - while let Some((account_address, contract_result)) = - join_set.join_next().await.transpose()? - { - map.insert(account_address, contract_result?); - } - - Ok(Self { - account_to_erc721_addresses: map, - recipient: setup.deployer_account().clone(), - }) - } - - fn get_goose_config(config: &GatlingConfig) -> color_eyre::Result { - ensure!( - config.run.num_erc721_mints >= config.run.concurrency, - "Too few erc721 mints for the amount of concurrent users" - ); - - // div_euclid will truncate integers when not evenly divisable - let user_iterations = config - .run - .num_erc721_mints - .div_euclid(config.run.concurrency); - // this will always be a multiple of concurrency, unlike num_erc721_mints - let total_transactions = user_iterations * config.run.concurrency; - - // If these are not equal that means user_iterations was truncated - if total_transactions != config.run.num_erc721_mints { - log::warn!("Number of erc721 mints is not evenly divisble by concurrency, doing {total_transactions} mints instead"); - } - - { - let mut default = GooseConfiguration::default(); - default.host = config.rpc.url.clone(); - default.iterations = user_iterations as usize; - default.users = Some(config.run.concurrency as usize); - Ok(default) - } - } - - fn get_execution_data(&self, account: &StarknetAccount) -> Call { - let recipient = account.address(); - - let (token_id_low, token_id_high) = (get_rng(), felt!("0x0000")); - - Call { - to: self.account_to_erc721_addresses[&account.address()], - selector: selector!("mint"), - calldata: vec![recipient, token_id_low, token_id_high], - } - } -} - -impl MintShooter { - async fn deploy_erc721( - starknet_rpc: Arc>, - deployer_salt: FieldElement, - class_hash: FieldElement, - recipient: StarknetAccount, - ) -> color_eyre::Result { - let contract_factory = ContractFactory::new(class_hash, &recipient); - - let name = selector!("TestNFT"); - let symbol = selector!("TNFT"); - - let constructor_args = vec![name, symbol, recipient.address()]; - let unique = false; - - let address = compute_contract_address(deployer_salt, class_hash, &constructor_args); - - if let Ok(contract_class_hash) = starknet_rpc - .get_class_hash_at(BlockId::Tag(BlockTag::Pending), address) - .await - { - if contract_class_hash == class_hash { - warn!("ERC721 contract already deployed at address {address:#064x}"); - return Ok(address); - } else { - bail!("ERC721 contract {address:#064x} already deployed with a different class hash {contract_class_hash:#064x}, expected {class_hash:#064x}"); - } - } - - let deploy = contract_factory.deploy(constructor_args, deployer_salt, unique); - - let nonce = recipient.get_nonce().await?; - - info!("Deploying ERC721 with nonce={}, address={address}", nonce); - - let result = deploy.nonce(nonce).max_fee(MAX_FEE).send().await?; - wait_for_tx(&starknet_rpc, result.transaction_hash, CHECK_INTERVAL).await?; - - debug!( - "Deploy ERC721 transaction accepted {:#064x}", - result.transaction_hash - ); - - info!("ERC721 contract deployed at address {:#064x}", address); - Ok(address) - } -} diff --git a/src/actions/shooters.rs b/src/actions/shooters.rs new file mode 100644 index 0000000..c729613 --- /dev/null +++ b/src/actions/shooters.rs @@ -0,0 +1,149 @@ +use std::{boxed::Box, sync::Arc}; + +use color_eyre::eyre::OptionExt; +use goose::{ + config::GooseConfiguration, + goose::{Scenario, Transaction, TransactionFunction}, + metrics::GooseMetrics, + GooseAttack, +}; +use starknet::{ + accounts::Call, + core::types::{FieldElement, InvokeTransactionResult}, + providers::jsonrpc::JsonRpcMethod, +}; + +use crate::{ + actions::goose::{send_execution, GooseWriteUserState}, + config::GatlingConfig, +}; + +use super::{ + goose::{ + goose_write_user_wait_last_tx, make_goose_config, setup, verify_transactions, + TransactionBlocks, + }, + setup::{GatlingSetup, StarknetAccount}, +}; + +pub mod mint; +pub mod transfer; + +pub struct ShooterAttack { + pub goose_metrics: GooseMetrics, + pub first_block: u64, + pub last_block: u64, +} + +pub trait Shooter { + const NAME: &'static str; + + async fn setup(setup: &mut GatlingSetup) -> color_eyre::Result + where + Self: Sized; + + fn get_amount(config: &GatlingConfig) -> u64; + + fn get_goose_config(config: &GatlingConfig) -> color_eyre::Result { + make_goose_config(config, Self::get_amount(config), Self::NAME) + } + + async fn goose_attack( + self: Arc, + config: GooseConfiguration, + accounts: Vec, + ) -> color_eyre::Result + where + Self: Send + Sync + 'static, + { + let setup: TransactionFunction = setup(accounts, config.iterations).await?; + + let submission: TransactionFunction = Self::execute(self.clone()); + + let finalizing: TransactionFunction = goose_write_user_wait_last_tx(); + + let blocks: Arc = Arc::default(); + let blocks_cloned = blocks.clone(); + + let verify_transactions = Transaction::new(Arc::new(move |user| { + Box::pin(verify_transactions(user, blocks_cloned.clone())) + })); + + let goose_attack = GooseAttack::initialize_with_config(config)?.register_scenario( + Scenario::new(Self::NAME) + .register_transaction(Transaction::new(setup).set_name("Setup").set_on_start()) + .register_transaction( + Transaction::new(submission) + .set_name("Transaction Submission") + .set_sequence(1), + ) + .register_transaction( + Transaction::new(finalizing) + .set_name("Finalizing") + .set_sequence(2) + .set_on_stop(), + ) + .register_transaction( + verify_transactions + .set_name("Verification") + .set_sequence(3) + .set_on_stop(), + ), + ); + + let metrics = goose_attack.execute().await?; + + let blocks = Arc::into_inner(blocks).ok_or_eyre( + "Transaction blocks arc has multiple references after goose verification", + )?; + + Ok(ShooterAttack { + goose_metrics: metrics, + first_block: blocks + .first + .into_inner() + .ok_or_eyre("No transactions were verified")?, + last_block: blocks.last.into_inner(), + }) + } + + fn execute(self: Arc) -> TransactionFunction + where + Self: Send + Sync + 'static, + { + Arc::new(move |user| { + let shooter = self.clone(); + + Box::pin(async move { + let GooseWriteUserState { account, nonce, .. } = user + .get_session_data::() + .expect("Should be in a goose user with GooseUserState session data"); + + let call = shooter.get_execution_data(account); + + let response: InvokeTransactionResult = send_execution( + user, + vec![call], + *nonce, + &account.clone(), + JsonRpcMethod::AddInvokeTransaction, + ) + .await? + .0; + + let GooseWriteUserState { nonce, prev_tx, .. } = + user.get_session_data_mut::().expect( + "Should be successful as we already asserted that the session data is a GooseUserState", + ); + + *nonce += FieldElement::ONE; + + prev_tx.push(response.transaction_hash); + + Ok(()) + }) + }) + } + + fn get_execution_data(&self, account: &StarknetAccount) -> Call; +} diff --git a/src/actions/shooters/mint.rs b/src/actions/shooters/mint.rs new file mode 100644 index 0000000..dd81735 --- /dev/null +++ b/src/actions/shooters/mint.rs @@ -0,0 +1,127 @@ +use std::{collections::HashMap, sync::Arc}; + +use color_eyre::eyre::bail; +use log::{debug, info, warn}; +use starknet::{ + accounts::{Account, Call, ConnectedAccount}, + contract::ContractFactory, + core::types::{BlockId, BlockTag, FieldElement}, + macros::{felt, selector}, + providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}, +}; +use tokio::task::JoinSet; + +use crate::{ + actions::setup::{GatlingSetup, StarknetAccount, CHECK_INTERVAL, MAX_FEE}, + config::GatlingConfig, + generators::get_rng, + utils::{compute_contract_address, wait_for_tx}, +}; + +use super::Shooter; + +pub struct MintShooter { + pub account_to_erc721_addresses: HashMap, + pub recipient: StarknetAccount, +} + +impl Shooter for MintShooter { + const NAME: &'static str = "Erc721 Mints"; + + async fn setup(setup: &mut GatlingSetup) -> color_eyre::Result { + let erc721_class_hash = setup + .declare_contract(&setup.config().setup.erc721_contract.clone()) + .await?; + + let deployer_salt = setup.config().deployer.salt; + let mut join_set = JoinSet::new(); + + for account in setup.accounts().iter().cloned() { + let address = account.address(); + let rpc_client = setup.rpc_client().clone(); + join_set.spawn(async move { + let contract = + Self::deploy_erc721(rpc_client, deployer_salt, erc721_class_hash, account) + .await; + + (address, contract) + }); + } + + let mut map = HashMap::with_capacity(setup.accounts().len()); + while let Some((account_address, contract_result)) = + join_set.join_next().await.transpose()? + { + map.insert(account_address, contract_result?); + } + + Ok(Self { + account_to_erc721_addresses: map, + recipient: setup.deployer_account().clone(), + }) + } + + fn get_amount(config: &GatlingConfig) -> u64 { + config.run.num_erc721_mints + } + + fn get_execution_data(&self, account: &StarknetAccount) -> Call { + let recipient = account.address(); + + let (token_id_low, token_id_high) = (get_rng(), felt!("0x0000")); + + Call { + to: self.account_to_erc721_addresses[&account.address()], + selector: selector!("mint"), + calldata: vec![recipient, token_id_low, token_id_high], + } + } +} + +impl MintShooter { + async fn deploy_erc721( + starknet_rpc: Arc>, + deployer_salt: FieldElement, + class_hash: FieldElement, + recipient: StarknetAccount, + ) -> color_eyre::Result { + let contract_factory = ContractFactory::new(class_hash, &recipient); + + let name = selector!("TestNFT"); + let symbol = selector!("TNFT"); + + let constructor_args = vec![name, symbol, recipient.address()]; + let unique = false; + + let address = compute_contract_address(deployer_salt, class_hash, &constructor_args); + + if let Ok(contract_class_hash) = starknet_rpc + .get_class_hash_at(BlockId::Tag(BlockTag::Pending), address) + .await + { + if contract_class_hash == class_hash { + warn!("ERC721 contract already deployed at address {address:#064x}"); + return Ok(address); + } else { + bail!("ERC721 contract {address:#064x} already deployed with a different class hash {contract_class_hash:#064x}, expected {class_hash:#064x}"); + } + } + + let deploy = contract_factory.deploy(constructor_args, deployer_salt, unique); + + let nonce = recipient.get_nonce().await?; + + info!("Deploying ERC721 with nonce={}, address={address}", nonce); + + let result = deploy.nonce(nonce).max_fee(MAX_FEE).send().await?; + wait_for_tx(&starknet_rpc, result.transaction_hash, CHECK_INTERVAL).await?; + + debug!( + "Deploy ERC721 transaction accepted {:#064x}", + result.transaction_hash + ); + + info!("ERC721 contract deployed at address {:#064x}", address); + Ok(address) + } +} diff --git a/src/actions/shooters/transfer.rs b/src/actions/shooters/transfer.rs new file mode 100644 index 0000000..148b4fa --- /dev/null +++ b/src/actions/shooters/transfer.rs @@ -0,0 +1,120 @@ +use color_eyre::eyre::bail; +use log::{debug, info, warn}; +use starknet::{ + accounts::{Account, Call, ConnectedAccount}, + contract::ContractFactory, + core::types::{BlockId, BlockTag, FieldElement}, + macros::{felt, selector}, + providers::Provider, +}; + +use crate::{ + actions::setup::{GatlingSetup, StarknetAccount, CHECK_INTERVAL, MAX_FEE}, + config::GatlingConfig, + utils::{compute_contract_address, wait_for_tx}, +}; + +use super::Shooter; + +pub struct TransferShooter { + pub erc20_address: FieldElement, + pub account: StarknetAccount, +} + +impl Shooter for TransferShooter { + const NAME: &'static str = "Erc20 Transfers"; + + async fn setup(setup: &mut GatlingSetup) -> color_eyre::Result + where + Self: Sized, + { + let class_hash = setup + .declare_contract(&setup.config().setup.erc20_contract.clone()) + .await?; + + let contract_factory = ContractFactory::new(class_hash, setup.deployer_account().clone()); + let nonce = setup.deployer_account().get_nonce().await?; + + let name = selector!("TestToken"); + let symbol = selector!("TT"); + let decimals = felt!("128"); + let (initial_supply_low, initial_supply_high) = + (felt!("0xFFFFFFFFF"), felt!("0xFFFFFFFFF")); + let recipient = setup.deployer_account().address(); + + let constructor_args = vec![ + name, + symbol, + decimals, + initial_supply_low, + initial_supply_high, + recipient, + ]; + let unique = false; + + let address = + compute_contract_address(setup.config().deployer.salt, class_hash, &constructor_args); + + if let Ok(contract_class_hash) = setup + .rpc_client() + .get_class_hash_at(BlockId::Tag(BlockTag::Pending), address) + .await + { + if contract_class_hash == class_hash { + warn!("ERC20 contract already deployed at address {address:#064x}"); + return Ok(TransferShooter { + erc20_address: address, + account: setup.deployer_account().clone(), + }); + } else { + bail!("ERC20 contract {address:#064x} already deployed with a different class hash {contract_class_hash:#064x}, expected {class_hash:#064x}"); + } + } + + let deploy = + contract_factory.deploy(constructor_args, setup.config().deployer.salt, unique); + + info!( + "Deploying ERC20 contract with nonce={}, address={:#064x}", + nonce, address + ); + + let result = deploy.nonce(nonce).max_fee(MAX_FEE).send().await?; + wait_for_tx(setup.rpc_client(), result.transaction_hash, CHECK_INTERVAL).await?; + + debug!( + "Deploy ERC20 transaction accepted {:#064x}", + result.transaction_hash + ); + + info!("ERC20 contract deployed at address {:#064x}", address); + + Ok(TransferShooter { + erc20_address: address, + account: setup.deployer_account().clone(), + }) + } + + fn get_amount(config: &GatlingConfig) -> u64 { + config.run.num_erc20_transfers + } + + fn get_execution_data(&self, _account: &StarknetAccount) -> Call { + let (amount_low, amount_high) = (felt!("1"), felt!("0")); + + // Hex: 0xdead + // from_hex_be isn't const whereas from_mont is + const VOID_ADDRESS: FieldElement = FieldElement::from_mont([ + 18446744073707727457, + 18446744073709551615, + 18446744073709551615, + 576460752272412784, + ]); + + Call { + to: self.erc20_address, + selector: selector!("transfer"), + calldata: vec![VOID_ADDRESS, amount_low, amount_high], + } + } +} diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 04d2f5e..020b3c3 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -25,8 +25,10 @@ pub struct Cli { /// Subcommands #[derive(Subcommand, Debug)] pub enum Command { - /// Trigger a load test. + /// Trigger a write load test. Shoot {}, + // Trigger a read load test + Read {}, } #[derive(Debug, Args)] diff --git a/src/main.rs b/src/main.rs index c3d3643..87d8fbc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,6 +36,9 @@ async fn main() -> Result<()> { Command::Shoot { .. } => { actions::shoot(cfg).await?; } + Command::Read { .. } => { + actions::read(cfg).await?; + } } Ok(()) diff --git a/src/metrics.rs b/src/metrics.rs index b51a767..de80207 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -1,11 +1,8 @@ use crate::utils::get_blocks_with_txs; -use color_eyre::{ - eyre::{bail, OptionExt}, - Result, -}; +use color_eyre::{eyre::OptionExt, Result}; -use goose::metrics::{GooseMetrics, GooseRequestMetricTimingData}; +use goose::metrics::{GooseMetrics, GooseRequestMetricAggregate, GooseRequestMetricTimingData}; use serde_derive::Serialize; use starknet::{ core::types::{ @@ -14,14 +11,15 @@ use starknet::{ }, providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}, }; -use std::{fmt, sync::Arc}; +use std::{borrow::Cow, fmt, sync::Arc}; pub const BLOCK_TIME: u64 = 6; #[derive(Clone, Debug, Serialize)] pub struct GlobalReport { pub users: u64, - pub all_bench_report: BenchmarkReport, + #[serde(skip_serializing_if = "Option::is_none")] + pub all_bench_report: Option, pub benches: Vec, pub extra: String, } @@ -51,7 +49,7 @@ const GOOSE_TIME_UNIT: &str = "milliseconds"; /// "Average TPS: 1000 transactions/second" #[derive(Debug, Clone, Serialize)] pub struct MetricResult { - pub name: &'static str, + pub name: Cow<'static, str>, pub unit: &'static str, pub value: serde_json::Value, } @@ -128,15 +126,6 @@ impl BenchmarkReport { } pub fn with_goose_write_metrics(&mut self, metrics: &GooseMetrics) -> Result<()> { - let transactions = metrics - .transactions - .first() - .ok_or_eyre("Could no find scenario's transactions")?; - - let [_setup, submission, _finalizing, verification] = transactions.as_slice() else { - bail!("Failed at getting all transaction aggragates") - }; - let submission_requests = metrics .requests .get("POST Transaction Submission") @@ -147,90 +136,8 @@ impl BenchmarkReport { .get("POST Verification") .ok_or_eyre("Found no verification request metrics")?; - const GOOSE_TIME_UNIT: &str = "milliseconds"; - - self.metrics.extend_from_slice(&[ - MetricResult { - name: "Total Submission Time", - unit: GOOSE_TIME_UNIT, - value: submission_requests.raw_data.total_time.into(), - }, - MetricResult { - name: "Total Verification Time", - unit: GOOSE_TIME_UNIT, - value: verification.total_time.into(), - }, - MetricResult { - name: "Failed Transactions Verifications", - unit: "", - value: verification_requests.fail_count.into(), - }, - MetricResult { - name: "Failed Transaction Submissions", - unit: "", - value: submission.fail_count.into(), - }, - MetricResult { - name: "Max Submission Time", - unit: GOOSE_TIME_UNIT, - value: submission_requests.raw_data.maximum_time.into(), - }, - MetricResult { - name: "Min Submission Time", - unit: GOOSE_TIME_UNIT, - value: submission_requests.raw_data.minimum_time.into(), - }, - MetricResult { - name: "Average Submission Time", - unit: GOOSE_TIME_UNIT, - value: transaction_average(&submission_requests.raw_data).into(), - }, - MetricResult { - name: "Max Verification Time", - unit: GOOSE_TIME_UNIT, - value: verification_requests.raw_data.maximum_time.into(), - }, - MetricResult { - name: "Min Verification Time", - unit: GOOSE_TIME_UNIT, - value: verification_requests.raw_data.minimum_time.into(), - }, - MetricResult { - name: "Average Verification Time", - unit: GOOSE_TIME_UNIT, - value: transaction_average(&verification_requests.raw_data).into(), - }, - ]); - - if let Some((sub_p50, sub_90)) = calculate_p50_and_p90(&submission_requests.raw_data) { - self.metrics.extend_from_slice(&[ - MetricResult { - name: "P90 Submission Time", - unit: GOOSE_TIME_UNIT, - value: sub_90.into(), - }, - MetricResult { - name: "P50 Submission Time", - unit: GOOSE_TIME_UNIT, - value: sub_p50.into(), - }, - ]) - } - - if let Some((ver_p50, ver_p90)) = calculate_p50_and_p90(&verification_requests.raw_data) { - self.metrics.extend_from_slice(&[ - MetricResult { - name: "P90 Verification Time", - unit: GOOSE_TIME_UNIT, - value: ver_p90.into(), - }, - MetricResult { - name: "P50 Verification Time", - unit: GOOSE_TIME_UNIT, - value: ver_p50.into(), - }, - ]) - } + self.with_request_metric_aggregate(submission_requests, Some("Submission")); + self.with_request_metric_aggregate(verification_requests, Some("Verifcation")); Ok(()) } @@ -241,29 +148,47 @@ impl BenchmarkReport { .get("POST Request") .ok_or_eyre("Found no read request metrics")?; + self.with_request_metric_aggregate(requests, None); + + Ok(()) + } + + fn with_request_metric_aggregate( + &mut self, + requests: &GooseRequestMetricAggregate, + metric: Option<&str>, + ) { + fn fmt_with_name(template: &'static str, metric: Option<&str>) -> Cow<'static, str> { + if let Some(metric) = metric { + format!("{metric} {template}").into() + } else { + template.into() + } + } + self.metrics.extend_from_slice(&[ MetricResult { - name: "Total Time", + name: fmt_with_name("Total Time", metric), unit: GOOSE_TIME_UNIT, value: requests.raw_data.total_time.into(), }, MetricResult { - name: "Max Time", + name: fmt_with_name("Max Time", metric), unit: GOOSE_TIME_UNIT, value: requests.raw_data.maximum_time.into(), }, MetricResult { - name: "Min Time", + name: fmt_with_name("Min Time", metric), unit: GOOSE_TIME_UNIT, value: requests.raw_data.minimum_time.into(), }, MetricResult { - name: "Average Time", + name: fmt_with_name("Average Time", metric), unit: GOOSE_TIME_UNIT, - value: (requests.raw_data.total_time as f64 / requests.success_count as f64).into(), + value: transaction_average(&requests.raw_data).into(), }, MetricResult { - name: "Failed Requests", + name: fmt_with_name("Failed Requests", metric), unit: "", value: requests.fail_count.into(), }, @@ -272,19 +197,17 @@ impl BenchmarkReport { if let Some((ver_p50, ver_p90)) = calculate_p50_and_p90(&requests.raw_data) { self.metrics.extend_from_slice(&[ MetricResult { - name: "P90 Verification Time", + name: fmt_with_name("P90 Time", metric), unit: GOOSE_TIME_UNIT, value: ver_p90.into(), }, MetricResult { - name: "P50 Verification Time", + name: fmt_with_name("P50 Time", metric), unit: GOOSE_TIME_UNIT, value: ver_p50.into(), }, ]) } - - Ok(()) } } @@ -357,12 +280,12 @@ pub fn compute_node_metrics( let mut metrics = vec![ MetricResult { - name: "Average TPS", + name: "Average TPS".into(), unit: "transactions/second", value: (avg_tpb / BLOCK_TIME as f64).into(), }, MetricResult { - name: "Average Extrinsics per block", + name: "Average Extrinsics per block".into(), unit: "extrinsics/block", value: avg_tpb.into(), }, @@ -387,13 +310,13 @@ pub fn compute_node_metrics( .sum(); metrics.push(MetricResult { - name: "Average UOPS", + name: "Average UOPS".into(), unit: "operations/second", value: (total_uops as f64 / blocks_with_txs.len() as f64 / BLOCK_TIME as f64).into(), }); metrics.push(MetricResult { - name: "Average Steps Per Second", + name: "Average Steps Per Second".into(), unit: "operations/second", value: (total_steps as f64 / blocks_with_txs.len() as f64 / BLOCK_TIME as f64).into(), }); From 461d5a2efe017e57b9cad09bc5005b82cf1bbe7c Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Thu, 16 May 2024 12:44:44 +0300 Subject: [PATCH 39/45] Formatting fix --- README.md | 3 ++- config/read_params/get_events.json | 4 ++-- src/actions/mod.rs | 5 ++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 76a1e0c..0995331 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,8 @@ The configuration is defined by the following spec gatling shoot -c config/default.yaml ``` -For a read test: +For read tests: + ```bash gatling read -c config/default.yaml ``` diff --git a/config/read_params/get_events.json b/config/read_params/get_events.json index a7671e9..59beec5 100644 --- a/config/read_params/get_events.json +++ b/config/read_params/get_events.json @@ -1,7 +1,7 @@ [ { - "from_block": {"block_number": null}, - "to_block": {"block_number": null}, + "from_block": { "block_number": null }, + "to_block": { "block_number": null }, "address": null, "keys": [], "continuation_token": null, diff --git a/src/actions/mod.rs b/src/actions/mod.rs index a6b0ee6..f3ad44a 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -50,7 +50,6 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { global_report.benches.push(report.0); blocks.get_or_insert((report.1, report.2)).1 = report.2; - } else { log::info!("Skipping erc721 mints") } @@ -61,8 +60,8 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { info!("Start and End Blocks: {start_block}, {end_block}"); let rpc_result = all_bench_report - .with_block_range(shooter_setup.rpc_client(), start_block, end_block) - .await; + .with_block_range(shooter_setup.rpc_client(), start_block, end_block) + .await; global_report.all_bench_report = Some(all_bench_report); From fff7e6cdef9f3453cc2fb6e2d52cf3699135fe8e Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Thu, 16 May 2024 14:28:26 +0300 Subject: [PATCH 40/45] Switch to Atomic::fetch_max/min --- src/actions/goose.rs | 12 ++++++++---- src/actions/shooters.rs | 5 +---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/actions/goose.rs b/src/actions/goose.rs index 7e70de8..2a07c2f 100644 --- a/src/actions/goose.rs +++ b/src/actions/goose.rs @@ -2,7 +2,7 @@ use std::{ mem, sync::{ atomic::{AtomicU64, Ordering}, - Arc, OnceLock, + Arc, }, time::{Duration, SystemTime}, }; @@ -168,7 +168,7 @@ pub async fn read_method( #[derive(Default)] pub struct TransactionBlocks { - pub first: OnceLock, + pub first: AtomicU64, pub last: AtomicU64, } @@ -191,8 +191,12 @@ pub async fn verify_transactions( MaybePendingTransactionReceipt::Receipt(TransactionReceipt::Invoke(receipt)) => { match receipt.execution_result { ExecutionResult::Succeeded => { - let _ = blocks.first.set(receipt.block_number); - blocks.last.store(receipt.block_number, Ordering::Relaxed) + blocks + .first + .fetch_min(receipt.block_number, Ordering::Relaxed); + blocks + .last + .fetch_max(receipt.block_number, Ordering::Relaxed); } ExecutionResult::Reverted { .. } => { let tag = format!("Transaction {tx:#064x} has been rejected/reverted"); diff --git a/src/actions/shooters.rs b/src/actions/shooters.rs index c729613..84ff91d 100644 --- a/src/actions/shooters.rs +++ b/src/actions/shooters.rs @@ -99,10 +99,7 @@ pub trait Shooter { Ok(ShooterAttack { goose_metrics: metrics, - first_block: blocks - .first - .into_inner() - .ok_or_eyre("No transactions were verified")?, + first_block: blocks.first.into_inner(), last_block: blocks.last.into_inner(), }) } From b356969c58ccda4345f51100906c8bd032d336e8 Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Thu, 16 May 2024 15:00:22 +0300 Subject: [PATCH 41/45] Remove erc20 setup from shooter setup --- src/actions/mod.rs | 6 +-- src/actions/setup.rs | 76 +++++++++++++++----------------- src/actions/shooters/transfer.rs | 29 +++++++++++- 3 files changed, 65 insertions(+), 46 deletions(-) diff --git a/src/actions/mod.rs b/src/actions/mod.rs index f3ad44a..7c0a608 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -20,10 +20,7 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { let total_txs = config.run.num_erc20_transfers + config.run.num_erc721_mints; let mut shooter_setup = GatlingSetup::from_config(config).await?; - let transfer_shooter = TransferShooter::setup(&mut shooter_setup).await?; - shooter_setup - .setup_accounts(transfer_shooter.erc20_address) - .await?; + shooter_setup.setup_accounts().await?; let mut global_report = GlobalReport { users: shooter_setup.config().run.concurrency, @@ -35,6 +32,7 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { let mut blocks = Option::<(u64, u64)>::None; if shooter_setup.config().run.num_erc20_transfers != 0 { + let transfer_shooter = TransferShooter::setup(&mut shooter_setup).await?; let report = make_report_over_shooter(transfer_shooter, &shooter_setup).await?; global_report.benches.push(report.0); diff --git a/src/actions/setup.rs b/src/actions/setup.rs index 5b9042a..9fa1724 100644 --- a/src/actions/setup.rs +++ b/src/actions/setup.rs @@ -87,7 +87,7 @@ impl GatlingSetup { } /// Setup the simulation. - pub async fn setup_accounts(&mut self, erc20_address: FieldElement) -> Result<()> { + pub async fn setup_accounts(&mut self) -> Result<()> { let account_contract = self.config.setup.account_contract.clone(); let account_class_hash = self.declare_contract(&account_contract).await?; @@ -102,7 +102,6 @@ impl GatlingSetup { account_class_hash, self.config.run.concurrency as usize, execution_encoding, - erc20_address, ) .await?; @@ -111,37 +110,15 @@ impl GatlingSetup { Ok(()) } - async fn transfer( - &mut self, + pub async fn transfer( + &self, contract_address: FieldElement, account: StarknetAccount, recipient: FieldElement, amount: FieldElement, nonce: FieldElement, ) -> Result { - let from_address = account.address(); - - debug!( - "Transferring {amount} of {contract_address:#064x} from address {from_address:#064x} to address {recipient:#064x} with nonce={}", - nonce, - ); - - let (amount_low, amount_high) = (amount, felt!("0")); - - let call = Call { - to: contract_address, - selector: selector!("transfer"), - calldata: vec![recipient, amount_low, amount_high], - }; - - let result = account - .execute(vec![call]) - .max_fee(MAX_FEE) - .nonce(nonce) - .send() - .await?; - - Ok(result.transaction_hash) + transfer(account, nonce, amount, contract_address, recipient).await } /// Create accounts. @@ -161,7 +138,6 @@ impl GatlingSetup { class_hash: FieldElement, num_accounts: usize, execution_encoding: ExecutionEncoding, - erc20_address: FieldElement, ) -> Result> { info!("Creating {} accounts", num_accounts); @@ -212,18 +188,6 @@ impl GatlingSetup { } } - info!("Funding account {i} at address {address:#064x}"); - let tx_hash = self - .transfer( - erc20_address, - self.account.clone(), - address, - felt!("0xFFFFF"), - nonce, - ) - .await?; - nonce += FieldElement::ONE; - wait_for_tx(&self.starknet_rpc, tx_hash, CHECK_INTERVAL).await?; let tx_hash = self .transfer( fee_token_address, @@ -370,6 +334,38 @@ impl GatlingSetup { } } +pub async fn transfer( + account: StarknetAccount, + nonce: FieldElement, + amount: FieldElement, + contract_address: FieldElement, + recipient: FieldElement, +) -> color_eyre::Result { + let from_address = account.address(); + + debug!( + "Transferring {amount} of {contract_address:#064x} from address {from_address:#064x} to address {recipient:#064x} with nonce={}", + nonce, + ); + + let (amount_low, amount_high) = (amount, felt!("0")); + + let call = Call { + to: contract_address, + selector: selector!("transfer"), + calldata: vec![recipient, amount_low, amount_high], + }; + + let result = account + .execute(vec![call]) + .max_fee(MAX_FEE) + .nonce(nonce) + .send() + .await?; + + Ok(result.transaction_hash) +} + /// Create a StarkNet RPC provider from a URL. /// # Arguments /// * `rpc` - The URL of the StarkNet RPC provider. diff --git a/src/actions/shooters/transfer.rs b/src/actions/shooters/transfer.rs index 148b4fa..1a1c607 100644 --- a/src/actions/shooters/transfer.rs +++ b/src/actions/shooters/transfer.rs @@ -7,9 +7,10 @@ use starknet::{ macros::{felt, selector}, providers::Provider, }; +use tokio::task::JoinSet; use crate::{ - actions::setup::{GatlingSetup, StarknetAccount, CHECK_INTERVAL, MAX_FEE}, + actions::setup::{self, GatlingSetup, StarknetAccount, CHECK_INTERVAL, MAX_FEE}, config::GatlingConfig, utils::{compute_contract_address, wait_for_tx}, }; @@ -33,7 +34,7 @@ impl Shooter for TransferShooter { .await?; let contract_factory = ContractFactory::new(class_hash, setup.deployer_account().clone()); - let nonce = setup.deployer_account().get_nonce().await?; + let mut nonce = setup.deployer_account().get_nonce().await?; let name = selector!("TestToken"); let symbol = selector!("TT"); @@ -80,6 +81,7 @@ impl Shooter for TransferShooter { ); let result = deploy.nonce(nonce).max_fee(MAX_FEE).send().await?; + nonce += FieldElement::ONE; wait_for_tx(setup.rpc_client(), result.transaction_hash, CHECK_INTERVAL).await?; debug!( @@ -89,6 +91,29 @@ impl Shooter for TransferShooter { info!("ERC20 contract deployed at address {:#064x}", address); + let mut joinset = JoinSet::new(); + + for account in setup.accounts() { + info!("Funding account at address {address:#064x}"); + + let tx_hash = setup::transfer( + setup.deployer_account().clone(), + nonce, + felt!("0xFFFFF"), + address, + account.address(), + ) + .await?; + + nonce += FieldElement::ONE; + let rpc_client = setup.rpc_client().clone(); + joinset.spawn(async move { wait_for_tx(&rpc_client, tx_hash, CHECK_INTERVAL).await }); + } + + while let Some(result) = joinset.join_next().await { + result??; + } + Ok(TransferShooter { erc20_address: address, account: setup.deployer_account().clone(), From 7c5e1c753a17cab1e2e1461a18a2384bbe42b07e Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Thu, 16 May 2024 15:35:22 +0300 Subject: [PATCH 42/45] Make adding shooters easier --- README.md | 7 +++-- config/default.yaml | 7 +++-- config/katana.yaml | 7 +++-- config/sharingan.yaml | 7 +++-- config/v2.1.0.yaml | 7 +++-- src/actions/mod.rs | 49 +++++++++++++++++--------------- src/actions/shooters.rs | 9 +++--- src/actions/shooters/mint.rs | 5 ---- src/actions/shooters/transfer.rs | 5 ---- src/config.rs | 9 ++++-- 10 files changed, 63 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 0995331..21e239e 100644 --- a/README.md +++ b/README.md @@ -84,8 +84,11 @@ The configuration is defined by the following spec - `run` - `concurrency`: How many transactions to do simultaneously - - `num_erc20_transfers`: Number of ERC20 `transfer` transactions - - `num_erc721_mints`: Number of ERC721 `mint` transactions + - `shooter`: A list of write shooter benchmarks to run + + - `name`: The name of the shooter, must be either `transfer` or `mint` + - `shoot`: How many transactions to do + - `read_benches`: A list of read benchmarks to run - `name`: The name to write on the output report diff --git a/config/default.yaml b/config/default.yaml index 52943f7..72680e8 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -17,8 +17,11 @@ setup: run: concurrency: 5 - num_erc20_transfers: 5000 - num_erc721_mints: 5000 + shooters: + - name: "transfer" + shoot: 5000 + - name: "mint" + shoot: 5000 read_benches: - name: "Get Events" num_requests: 100 diff --git a/config/katana.yaml b/config/katana.yaml index 86729f8..4322d62 100644 --- a/config/katana.yaml +++ b/config/katana.yaml @@ -17,8 +17,11 @@ setup: run: concurrency: 5 - num_erc20_transfers: 300 - num_erc721_mints: 300 + shooters: + - name: "transfer" + shoot: 300 + - name: "mint" + shoot: 300 read_benches: - name: "Get Events" num_requests: 100 diff --git a/config/sharingan.yaml b/config/sharingan.yaml index e89d8f5..79ec236 100644 --- a/config/sharingan.yaml +++ b/config/sharingan.yaml @@ -17,8 +17,11 @@ setup: run: concurrency: 5 - num_erc20_transfers: 1200 - num_erc721_mints: 1200 + shooters: + - name: "transfer" + shoot: 1200 + - name: "mint" + shoot: 1200 read_benches: - name: "Get Events" num_requests: 100 diff --git a/config/v2.1.0.yaml b/config/v2.1.0.yaml index 9013519..cec932f 100644 --- a/config/v2.1.0.yaml +++ b/config/v2.1.0.yaml @@ -23,8 +23,11 @@ setup: run: concurrency: 5 - num_erc20_transfers: 100 - num_erc721_mints: 100 + shooters: + - name: "transfer" + shoot: 100 + - name: "mint" + shoot: 100 read_benches: - name: "Get Events" num_requests: 100 diff --git a/src/actions/mod.rs b/src/actions/mod.rs index 7c0a608..1585b04 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -1,5 +1,6 @@ -use std::{fs::File, sync::Arc}; +use std::{fs::File, mem, sync::Arc}; +use color_eyre::eyre::bail; use log::info; use crate::{ @@ -16,8 +17,9 @@ mod goose; mod setup; mod shooters; -pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { - let total_txs = config.run.num_erc20_transfers + config.run.num_erc721_mints; +pub async fn shoot(mut config: GatlingConfig) -> color_eyre::Result<()> { + let shooters = mem::take(&mut config.run.shooters); + let total_txs: u64 = shooters.iter().map(|s| s.shoot).sum(); let mut shooter_setup = GatlingSetup::from_config(config).await?; shooter_setup.setup_accounts().await?; @@ -31,25 +33,25 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { let mut blocks = Option::<(u64, u64)>::None; - if shooter_setup.config().run.num_erc20_transfers != 0 { - let transfer_shooter = TransferShooter::setup(&mut shooter_setup).await?; - let report = make_report_over_shooter(transfer_shooter, &shooter_setup).await?; - - global_report.benches.push(report.0); - blocks.get_or_insert((report.1, report.2)).1 = report.2; - } else { - log::info!("Skipping erc20 transfers") - } - - if shooter_setup.config().run.num_erc721_mints != 0 { - let shooter = MintShooter::setup(&mut shooter_setup).await?; + for shooter in shooters { + if shooter.shoot == 0 { + log::info!("Skipping {} transfers", shooter.name); + continue; + } - let report = make_report_over_shooter(shooter, &shooter_setup).await?; + let (report, first_block, last_block) = match shooter.name.as_str() { + "transfer" => { + make_report_over_shooter::(&mut shooter_setup, shooter.shoot) + .await? + } + "mint" => { + make_report_over_shooter::(&mut shooter_setup, shooter.shoot).await? + } + name => bail!("Shooter `{name}` not found!"), + }; - global_report.benches.push(report.0); - blocks.get_or_insert((report.1, report.2)).1 = report.2; - } else { - log::info!("Skipping erc721 mints") + global_report.benches.push(report); + blocks.get_or_insert((first_block, last_block)).1 = last_block; } let mut all_bench_report = BenchmarkReport::new("".into(), total_txs as usize); @@ -80,10 +82,11 @@ pub async fn shoot(config: GatlingConfig) -> color_eyre::Result<()> { } async fn make_report_over_shooter( - shooter: S, - setup: &GatlingSetup, + setup: &mut GatlingSetup, + amount: u64, ) -> color_eyre::Result<(BenchmarkReport, u64, u64)> { - let goose_config = S::get_goose_config(setup.config())?; + let shooter = S::setup(setup).await?; + let goose_config = S::get_goose_config(setup.config(), amount)?; let ShooterAttack { goose_metrics, diff --git a/src/actions/shooters.rs b/src/actions/shooters.rs index 84ff91d..9b35c98 100644 --- a/src/actions/shooters.rs +++ b/src/actions/shooters.rs @@ -42,10 +42,11 @@ pub trait Shooter { where Self: Sized; - fn get_amount(config: &GatlingConfig) -> u64; - - fn get_goose_config(config: &GatlingConfig) -> color_eyre::Result { - make_goose_config(config, Self::get_amount(config), Self::NAME) + fn get_goose_config( + config: &GatlingConfig, + amount: u64, + ) -> color_eyre::Result { + make_goose_config(config, amount, Self::NAME) } async fn goose_attack( diff --git a/src/actions/shooters/mint.rs b/src/actions/shooters/mint.rs index dd81735..1c099c6 100644 --- a/src/actions/shooters/mint.rs +++ b/src/actions/shooters/mint.rs @@ -13,7 +13,6 @@ use tokio::task::JoinSet; use crate::{ actions::setup::{GatlingSetup, StarknetAccount, CHECK_INTERVAL, MAX_FEE}, - config::GatlingConfig, generators::get_rng, utils::{compute_contract_address, wait_for_tx}, }; @@ -61,10 +60,6 @@ impl Shooter for MintShooter { }) } - fn get_amount(config: &GatlingConfig) -> u64 { - config.run.num_erc721_mints - } - fn get_execution_data(&self, account: &StarknetAccount) -> Call { let recipient = account.address(); diff --git a/src/actions/shooters/transfer.rs b/src/actions/shooters/transfer.rs index 1a1c607..baccab2 100644 --- a/src/actions/shooters/transfer.rs +++ b/src/actions/shooters/transfer.rs @@ -11,7 +11,6 @@ use tokio::task::JoinSet; use crate::{ actions::setup::{self, GatlingSetup, StarknetAccount, CHECK_INTERVAL, MAX_FEE}, - config::GatlingConfig, utils::{compute_contract_address, wait_for_tx}, }; @@ -120,10 +119,6 @@ impl Shooter for TransferShooter { }) } - fn get_amount(config: &GatlingConfig) -> u64 { - config.run.num_erc20_transfers - } - fn get_execution_data(&self, _account: &StarknetAccount) -> Call { let (amount_low, amount_high) = (felt!("1"), felt!("0")); diff --git a/src/config.rs b/src/config.rs index bab387e..cbb0e4b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -110,11 +110,16 @@ pub struct DeployerConfig { #[derive(Debug, Deserialize, Clone)] pub struct RunConfig { pub concurrency: u64, - pub num_erc20_transfers: u64, - pub num_erc721_mints: u64, + pub shooters: Vec, pub read_benches: Vec, } +#[derive(Debug, Deserialize, Clone)] +pub struct Shooters { + pub name: String, + pub shoot: u64, +} + #[derive(Debug, Deserialize, Clone)] pub struct ReadBenchConfig { pub name: String, From fba9d054a988d0db16957f95f54e24d0897df0ca Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Mon, 20 May 2024 10:53:08 +0300 Subject: [PATCH 43/45] Update dependencies --- Cargo.lock | 324 ++++++++++++++++++++++++------------------------- Cargo.toml | 17 ++- src/metrics.rs | 2 +- 3 files changed, 170 insertions(+), 173 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c56ea1c..21e6633 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -54,47 +54,48 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -172,9 +173,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-compression" -version = "0.4.8" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07dbbf24db18d609b1462965249abdf49129ccad073ec257da372adc83259c60" +checksum = "9c90a406b4495d129f00461241616194cb8a032c8d1c53c657f0961d5f8e0498" dependencies = [ "flate2", "futures-core", @@ -191,7 +192,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.65", ] [[package]] @@ -202,14 +203,14 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.65", ] [[package]] name = "autocfg" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" @@ -312,9 +313,9 @@ checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cc" -version = "1.0.94" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f6e324229dc011159fcc089755d1e2e216a90d43a7dea6853ca740b84f35e7" +checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" [[package]] name = "cfg-if" @@ -370,7 +371,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim 0.11.1", + "strsim", ] [[package]] @@ -382,7 +383,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.65", ] [[package]] @@ -420,9 +421,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "config" @@ -565,9 +566,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crunchy" @@ -617,9 +618,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" +checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" dependencies = [ "darling_core", "darling_macro", @@ -627,34 +628,34 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" +checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim 0.10.0", - "syn 2.0.59", + "strsim", + "syn 2.0.65", ] [[package]] name = "darling_macro" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" +checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core", "quote", - "syn 2.0.59", + "syn 2.0.65", ] [[package]] name = "data-encoding" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "deranged" @@ -711,9 +712,9 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "either" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" [[package]] name = "encoding_rs" @@ -755,9 +756,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -824,9 +825,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fixed-hash" @@ -842,9 +843,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "miniz_oxide", @@ -954,7 +955,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.65", ] [[package]] @@ -1003,7 +1004,6 @@ dependencies = [ "log", "rand", "serde", - "serde_derive", "serde_json", "starknet", "sysinfo", @@ -1023,9 +1023,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", @@ -1125,9 +1125,9 @@ checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "heck" @@ -1364,7 +1364,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -1382,6 +1382,12 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "itertools" version = "0.10.5" @@ -1443,9 +1449,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "linked-hash-map" @@ -1455,15 +1461,15 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -1495,9 +1501,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" dependencies = [ "adler", ] @@ -1573,11 +1579,10 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -1609,9 +1614,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -1673,7 +1678,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.65", ] [[package]] @@ -1712,9 +1717,9 @@ checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" [[package]] name = "parity-scale-codec" -version = "3.6.9" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ "arrayvec", "bitvec", @@ -1726,9 +1731,9 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.9" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -1738,9 +1743,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" dependencies = [ "lock_api", "parking_lot_core", @@ -1748,22 +1753,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.5", ] [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pathdiff" @@ -1788,9 +1793,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95" +checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" dependencies = [ "memchr", "thiserror", @@ -1799,9 +1804,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73541b156d32197eecda1a4014d7f868fd2bcb3c550d5386087cfba442bf69c" +checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" dependencies = [ "pest", "pest_generator", @@ -1809,22 +1814,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c35eeed0a3fab112f75165fdc026b3913f4183133f19b49be773ac9ea966e8bd" +checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.65", ] [[package]] name = "pest_meta" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2adbf29bb9776f28caece835398781ab24435585fe0d4dc1374a61db5accedca" +checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" dependencies = [ "once_cell", "pest", @@ -1876,18 +1881,18 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "2.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ - "toml_edit 0.20.7", + "toml_edit 0.21.1", ] [[package]] name = "proc-macro2" -version = "1.0.80" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56dea16b0a29e94408b9aa5e2940a4eedbd128a1ba20e8f7ae60fd3d465af0e" +checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" dependencies = [ "unicode-ident", ] @@ -1975,11 +1980,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", ] [[package]] @@ -2118,9 +2123,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hex" @@ -2139,9 +2144,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.32" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags 2.5.0", "errno", @@ -2152,9 +2157,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", "ring", @@ -2183,15 +2188,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "salsa20" @@ -2241,11 +2246,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", "core-foundation", "core-foundation-sys", "libc", @@ -2254,9 +2259,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" dependencies = [ "core-foundation-sys", "libc", @@ -2264,35 +2269,35 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.65", ] [[package]] name = "serde_json" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "indexmap 2.2.6", "itoa", @@ -2313,9 +2318,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" dependencies = [ "serde", ] @@ -2357,7 +2362,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.65", ] [[package]] @@ -2403,9 +2408,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -2438,9 +2443,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", "windows-sys 0.52.0", @@ -2540,7 +2545,7 @@ source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=2d596369116282 dependencies = [ "starknet-curve", "starknet-ff", - "syn 2.0.59", + "syn 2.0.65", ] [[package]] @@ -2571,7 +2576,7 @@ version = "0.1.7" source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=2d59636911628260fa460179010bbd00e89de06e#2d59636911628260fa460179010bbd00e89de06e" dependencies = [ "starknet-core", - "syn 2.0.59", + "syn 2.0.65", ] [[package]] @@ -2614,12 +2619,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "strsim" version = "0.11.1" @@ -2642,7 +2641,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.59", + "syn 2.0.65", ] [[package]] @@ -2664,9 +2663,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.59" +version = "2.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a6531ffc7b071655e4ce2e04bd464c4830bb585a61cabb96cf808f05172615a" +checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106" dependencies = [ "proc-macro2", "quote", @@ -2681,9 +2680,9 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "sysinfo" -version = "0.30.10" +version = "0.30.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d7c217777061d5a2d652aea771fb9ba98b6dade657204b08c4b9604d11555b" +checksum = "732ffa00f53e6b2af46208fba5718d9662a421049204e156328b66791ffa15ae" dependencies = [ "cfg-if", "core-foundation-sys", @@ -2744,22 +2743,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.65", ] [[package]] @@ -2856,7 +2855,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.65", ] [[package]] @@ -2893,44 +2892,43 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] name = "toml" -version = "0.8.12" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.9", + "toml_edit 0.22.13", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.20.7" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ "indexmap 2.2.6", "toml_datetime", @@ -2939,15 +2937,15 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.9" +version = "0.22.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" +checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c" dependencies = [ "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.6", + "winnow 0.6.8", ] [[package]] @@ -3166,7 +3164,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.65", "wasm-bindgen-shared", ] @@ -3200,7 +3198,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.65", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3245,11 +3243,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -3427,9 +3425,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c976aaaa0e1f90dbb21e9587cdaf1d9679a1cde8875c0d6bd83ab96a208352" +checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d" dependencies = [ "memchr", ] @@ -3479,5 +3477,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.65", ] diff --git a/Cargo.toml b/Cargo.toml index 9e67c3f..9710116 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,21 +18,20 @@ opt-level = 3 starknet = { git = "https://github.com/xJonathanLEI/starknet-rs.git", rev = "2d59636911628260fa460179010bbd00e89de06e" } goose = "0.17.2" -env_logger = "0.11.2" -log = "0.4.17" +env_logger = "0.11.3" +log = "0.4.21" tokio = { version = "1", features = ["full"] } futures = "0.3" -clap = { version = "4.2.7", features = ["derive"] } -color-eyre = "0.6.2" +clap = { version = "4.5.4", features = ["derive"] } +color-eyre = "0.6.3" config = "0.14.0" dotenvy = "0.15.7" -serde = "1.0.163" -serde_derive = "1.0.163" -serde_json = { version = "1.0.96", features = ["preserve_order"] } -url = "2.4.0" +serde = { version = "1.0.202", features = ["derive"] } +serde_json = { version = "1.0.117", features = ["preserve_order"] } +url = "2.5.0" rand = { version = "0.8.5", features = ["rand_chacha"] } lazy_static = "1.4.0" -sysinfo = "0.30.5" +sysinfo = "0.30.12" crossbeam-queue = "0.3.11" [features] diff --git a/src/metrics.rs b/src/metrics.rs index de80207..5352742 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -3,7 +3,7 @@ use crate::utils::get_blocks_with_txs; use color_eyre::{eyre::OptionExt, Result}; use goose::metrics::{GooseMetrics, GooseRequestMetricAggregate, GooseRequestMetricTimingData}; -use serde_derive::Serialize; +use serde::Serialize; use starknet::{ core::types::{ BlockWithTxs, ExecutionResources, InvokeTransaction, InvokeTransactionV0, From b1f9b478f50e2a1af00d340fea447d698feb1d1e Mon Sep 17 00:00:00 2001 From: Angel Petrov Date: Mon, 20 May 2024 10:54:08 +0300 Subject: [PATCH 44/45] Partially joinset account setup to speed up initialization --- src/actions/setup.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/actions/setup.rs b/src/actions/setup.rs index 9fa1724..e6a581d 100644 --- a/src/actions/setup.rs +++ b/src/actions/setup.rs @@ -9,6 +9,7 @@ use color_eyre::{ use log::{debug, info, warn}; use starknet::core::types::contract::SierraClass; +use tokio::task::JoinSet; use std::path::Path; @@ -145,6 +146,8 @@ impl GatlingSetup { let mut nonce = self.account.get_nonce().await?; + let mut deployment_joinset = JoinSet::new(); + for i in 0..num_accounts { self.account.set_block_id(BlockId::Tag(BlockTag::Pending)); @@ -212,11 +215,19 @@ impl GatlingSetup { deployed_accounts.push(account); - wait_for_tx(&self.starknet_rpc, result.transaction_hash, CHECK_INTERVAL).await?; + let starknet_rpc = self.starknet_rpc.clone(); + + deployment_joinset.spawn(async move { + wait_for_tx(&starknet_rpc, result.transaction_hash, CHECK_INTERVAL).await + }); info!("Account {i} deployed at address {address:#064x}"); } + while let Some(result) = deployment_joinset.join_next().await { + result??; + } + Ok(deployed_accounts) } From 6fc6339e57e978255893cb1cd313f20785a4e79f Mon Sep 17 00:00:00 2001 From: Apoorv Sadana <95699312+apoorvsadana@users.noreply.github.com> Date: Wed, 12 Jun 2024 22:10:19 +0530 Subject: [PATCH 45/45] Receipt to status (#6) * moved from tx receipt to status * remove report --- src/actions/goose.rs | 72 ++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/src/actions/goose.rs b/src/actions/goose.rs index 2a07c2f..ec59d11 100644 --- a/src/actions/goose.rs +++ b/src/actions/goose.rs @@ -12,7 +12,7 @@ use crossbeam_queue::ArrayQueue; use goose::{config::GooseConfiguration, metrics::GooseRequestMetric, prelude::*}; use rand::prelude::SliceRandom; use serde::{de::DeserializeOwned, Serialize}; -use starknet::core::types::TransactionReceipt; +use starknet::core::types::{SequencerTransactionStatus, TransactionReceipt, TransactionStatus}; use starknet::{ accounts::{ Account, Call, ConnectedAccount, ExecutionEncoder, RawExecution, SingleOwnerAccount, @@ -166,7 +166,7 @@ pub async fn read_method( Ok(metrics) } -#[derive(Default)] +#[derive(Default, Debug)] pub struct TransactionBlocks { pub first: AtomicU64, pub last: AtomicU64, @@ -183,42 +183,54 @@ pub async fn verify_transactions( .prev_tx, ); - for tx in transactions { - let (receipt, mut metrics) = - send_request(user, JsonRpcMethod::GetTransactionReceipt, tx).await?; + for (index, tx) in transactions.iter().enumerate() { + let (status, mut metrics) = + send_request::(user, JsonRpcMethod::GetTransactionStatus, tx) + .await?; - match receipt { - MaybePendingTransactionReceipt::Receipt(TransactionReceipt::Invoke(receipt)) => { - match receipt.execution_result { - ExecutionResult::Succeeded => { - blocks - .first - .fetch_min(receipt.block_number, Ordering::Relaxed); - blocks - .last - .fetch_max(receipt.block_number, Ordering::Relaxed); - } - ExecutionResult::Reverted { .. } => { - let tag = format!("Transaction {tx:#064x} has been rejected/reverted"); + match status.finality_status() { + SequencerTransactionStatus::Rejected => { + let tag = format!("Transaction {tx:#064x} has been rejected/reverted"); - return user.set_failure(&tag, &mut metrics, None, None); - } - } - } - MaybePendingTransactionReceipt::Receipt(_) => { - return user.set_failure( - "Receipt is not of type InvokeTransactionReceipt", - &mut metrics, - None, - None, - ); + return user.set_failure(&tag, &mut metrics, None, None); } - MaybePendingTransactionReceipt::PendingReceipt(_) => { + SequencerTransactionStatus::Received => { let tag = format!("Transaction {tx:#064x} is pending when no transactions should be"); return user.set_failure(&tag, &mut metrics, None, None); } + SequencerTransactionStatus::AcceptedOnL1 | SequencerTransactionStatus::AcceptedOnL2 => { + if index == 0 || index == transactions.len() - 1 { + let (receipt, mut metrics) = send_request::( + user, + JsonRpcMethod::GetTransactionReceipt, + tx, + ) + .await?; + let block_number = match receipt { + MaybePendingTransactionReceipt::Receipt(TransactionReceipt::Invoke( + receipt, + )) => receipt.block_number, + _ => { + return user.set_failure( + "Receipt is not of type InvokeTransactionReceipt or is Pending", + &mut metrics, + None, + None, + ); + } + }; + + if index == 0 { + blocks.first.store(block_number, Ordering::Relaxed); + } + + if index == transactions.len() - 1 { + blocks.last.store(block_number, Ordering::Relaxed); + } + } + } } }