From 50f8444bf87a64591788501e89068698447b8d48 Mon Sep 17 00:00:00 2001 From: dylan Date: Tue, 7 Apr 2026 22:06:45 -0600 Subject: [PATCH 01/10] tests: adds builder simulation test harness (#219) * tests: adds builder simulation test harness - adds a builder test harness for simulating blocks that doesn't require network access and doesn't use alloy for test setup - adds test scenario helpers for future setup and use * fmt * chore: update claude workflows to run fmt and clippy * fmt and clippy * fix: add state source type support * refactor: pull integration tests back into tests/ and gate test_utils behind`#[cfg(test)]` * docs: update docs to match testing changes * fmt + clippy recrusion limits fix * cleanup: gate individual test files behind test-utils * cleanup: remove redundant rust version info * fix: make ci only run unit tests --- .claude/CLAUDE.md | 31 +++- .github/workflows/rust-ci.yml | 1 + .gitignore | 1 + Cargo.toml | 3 + Makefile | 6 +- README.md | 17 ++ src/lib.rs | 2 +- src/test_utils/block.rs | 181 +++++++++++++++++++++ src/test_utils/db.rs | 168 ++++++++++++++++++++ src/test_utils/env.rs | 186 ++++++++++++++++++++++ src/{test_utils.rs => test_utils/mod.rs} | 24 ++- src/test_utils/scenarios.rs | 187 ++++++++++++++++++++++ src/test_utils/tx.rs | 193 +++++++++++++++++++++++ tests/block_builder_test.rs | 5 +- tests/bundle_poller_test.rs | 3 +- tests/cache.rs | 2 +- tests/env.rs | 2 +- tests/tx_poller_test.rs | 3 +- 18 files changed, 1002 insertions(+), 13 deletions(-) create mode 100644 src/test_utils/block.rs create mode 100644 src/test_utils/db.rs create mode 100644 src/test_utils/env.rs rename src/{test_utils.rs => test_utils/mod.rs} (85%) create mode 100644 src/test_utils/scenarios.rs create mode 100644 src/test_utils/tx.rs diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index d2aacee2..c1497f36 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -10,13 +10,21 @@ Single-crate Rust application (not a workspace) that builds Signet rollup blocks make # Debug build make release # Optimized release build make run # Run zenith-builder-example binary -make test # Run all tests +make test # Run unit tests +make test-all # Run unit + integration tests (requires network) make fmt # Format code make clippy # Lint with warnings denied ``` Always lint before committing. The Makefile provides shortcuts (`make fmt`, `make clippy`, `make test`) +### Running Individual Tests + +```bash +cargo test test_name # Run specific unit test by name +cargo test --features test-utils --test test_file_name # Run a specific integration test +``` + ## Architecture Five actor tasks communicate via tokio channels: @@ -41,7 +49,7 @@ src/ service.rs - Axum /healthcheck endpoint macros.rs - span_scoped!, span_debug/info/warn/error!, res/opt_unwrap_or_continue! utils.rs - Signature extraction, gas population helpers - test_utils.rs - setup_test_config, new_signed_tx, test_block_env helpers + test_utils/ - Test harness (cfg-gated via test-utils feature) tasks/ mod.rs - Module re-exports env.rs - EnvTask, SimEnv, Environment types @@ -125,6 +133,25 @@ src/ - Fresh branches off `main` for PRs. Descriptive branch names. - AI-authored GitHub comments must include `**[Claude Code]**` header. +## Testing + +### Integration Tests + +Integration tests live in `tests/` and are gated behind the `test-utils` Cargo feature via `required-features` in `Cargo.toml`. They are not compiled by `cargo test` alone — use `make test-all` or `cargo test --features test-utils` to build and run them. They require network access (real RPC endpoints or Anvil). + +### Simulation Harness (Offline Tests) + +`src/test_utils/` provides a testing harness for offline simulation testing, gated with `#[cfg(any(test, feature = "test-utils"))]`: + +- `TestDbBuilder` - Create in-memory EVM state +- `TestSimEnvBuilder` - Create `RollupEnv`/`HostEnv` without RPC +- `TestBlockBuildBuilder` - Build blocks with `BlockBuild` +- `basic_scenario()`, `gas_limit_scenario()` - Pre-configured test scenarios + +## Workflow + +After completing a set of changes, always run `make fmt` and `make clippy` and fix any issues before committing. + ## Local Development For local SDK development, uncomment the `[patch.crates-io]` section in Cargo.toml to point to local signet-sdk paths. diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index 2665cf6d..1da3ef16 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -10,3 +10,4 @@ jobs: uses: init4tech/actions/.github/workflows/rust-base.yml@main with: install-foundry: true + test-all-features: false diff --git a/.gitignore b/.gitignore index 2aab8832..c716535f 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ target/ # VSCode debug launcher .vscode/launch.json +# Claude configs .claude/*.local.* .claude/settings.json CLAUDE.local.md diff --git a/Cargo.toml b/Cargo.toml index e9bcdb35..3794c386 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,9 @@ license = "Apache-2.0 OR MIT" homepage = "https://github.com/init4tech/builder" repository = "https://github.com/init4tech/builder" +[features] +test-utils = [] + [lib] name = "builder" diff --git a/Makefile b/Makefile index db935850..0ce5a089 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ PROFILE ?= dev # override with `make PROFILE=release build` CLIPPY_FLAGS ?= $(TARGETS) $(FEATURES) --workspace --profile dev -- -D warnings FMT_FLAGS ?= --all -.PHONY: build release run test clean fmt clippy default +.PHONY: build release run test test-all clean fmt clippy default default: build @@ -34,6 +34,10 @@ run: test: $(CARGO) test +# NB: requires auth and server configuration +test-all: + $(CARGO) test --features test-utils + clean: $(CARGO) clean diff --git a/README.md b/README.md index 169fca72..83052075 100644 --- a/README.md +++ b/README.md @@ -166,6 +166,23 @@ The previous header's basefee is tracked through the build loop and used for gas ## ✅ Testing +### Unit Tests + +```bash +make test +``` + +### Integration Tests + +Integration tests require network access (RPC endpoints or Anvil) and are gated behind the `test-utils` Cargo feature. They are not compiled by default. + +```bash +make test-all # Run all tests (unit + integration) +cargo test --features test-utils --test block_builder_test # Run a specific integration test +``` + +### Deployment Verification + 1. Build the Docker image: ```bash diff --git a/src/lib.rs b/src/lib.rs index dfb7245d..c5f48db0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,7 +31,7 @@ pub mod tasks; /// Utilities. pub mod utils; -/// Test utilitites +#[cfg(any(test, feature = "test-utils"))] pub mod test_utils; // Anonymous imports suppress warnings about unused crate dependencies. diff --git a/src/test_utils/block.rs b/src/test_utils/block.rs new file mode 100644 index 00000000..2ce13f09 --- /dev/null +++ b/src/test_utils/block.rs @@ -0,0 +1,181 @@ +//! Test utilities for block building and simulation. +//! This module provides builders for creating `BlockBuild` instances +//! for testing block simulation. + +use super::{ + db::{TestDb, TestStateSource}, + env::{TestHostEnv, TestRollupEnv, TestSimEnvBuilder}, +}; +use signet_sim::{BlockBuild, BuiltBlock, SimCache}; +use std::time::Duration; +use tokio::time::Instant; +use trevm::revm::inspector::NoOpInspector; + +/// Test block builder type using in-memory databases. +pub type TestBlockBuild = + BlockBuild; + +/// Builder for creating test `BlockBuild` instances. +/// Configures all the parameters needed for block simulation +/// and provides sensible defaults for testing scenarios. +#[derive(Debug)] +pub struct TestBlockBuildBuilder { + /// The test environment configuration for the block build. + env: TestBlockBuildEnv, + /// The simulation cache to use for the block build. + sim_cache: SimCache, + /// The duration from now until the block build should finish. + deadline_duration: Duration, + /// The concurrency limit for parallel simulation. + concurrency_limit: usize, + /// The maximum gas limit for the rollup block. + max_gas: u64, + /// The maximum gas limit for host transactions. + max_host_gas: u64, +} + +/// Internal enum to manage the environment configuration for the block build. +#[derive(Debug)] +#[allow(clippy::large_enum_variant)] +enum TestBlockBuildEnv { + /// A builder that will create the environments when `into_block_build()` is called. + Builder(TestSimEnvBuilder), + /// A pair of already built environments to use directly. + Built { rollup: TestRollupEnv, host: TestHostEnv }, +} + +impl Default for TestBlockBuildBuilder { + fn default() -> Self { + Self::new() + } +} + +impl TestBlockBuildBuilder { + /// Create a new test block build builder with test-focused defaults. + /// Default values: + /// - Deadline: 2 seconds + /// - Concurrency limit: 4 + /// - Max gas: 3,000,000,000 (3 billion) + /// - Max host gas: 24,000,000 + pub fn new() -> Self { + Self { + // Default to building fresh test environments unless the caller injects a pair. + env: TestBlockBuildEnv::Builder(TestSimEnvBuilder::new()), + sim_cache: SimCache::new(), + deadline_duration: Duration::from_secs(2), + concurrency_limit: 4, + max_gas: 3_000_000_000, + max_host_gas: 24_000_000, + } + } + + /// Set the simulation environment builder. + /// The environments will be built from this builder when `into_block_build()` is called. + pub fn with_sim_env_builder(mut self, builder: TestSimEnvBuilder) -> Self { + self.env = TestBlockBuildEnv::Builder(builder); + self + } + + /// Set both environments directly so the block build uses a consistent pair. + pub fn with_envs(mut self, rollup: TestRollupEnv, host: TestHostEnv) -> Self { + self.env = TestBlockBuildEnv::Built { rollup, host }; + self + } + + /// Set the simulation cache. + pub fn with_cache(mut self, cache: SimCache) -> Self { + self.sim_cache = cache; + self + } + + /// Set the deadline duration from now. + pub const fn with_deadline(mut self, duration: Duration) -> Self { + self.deadline_duration = duration; + self + } + + /// Set the concurrency limit for parallel simulation. + pub const fn with_concurrency(mut self, limit: usize) -> Self { + self.concurrency_limit = limit; + self + } + + /// Set the maximum gas limit for the rollup block. + pub const fn with_max_gas(mut self, gas: u64) -> Self { + self.max_gas = gas; + self + } + + /// Set the maximum gas limit for host transactions. + pub const fn with_max_host_gas(mut self, gas: u64) -> Self { + self.max_host_gas = gas; + self + } + + /// Build the test `BlockBuild` instance. + /// This creates a `BlockBuild` ready for simulation. + /// Call `.build().await` on the result to execute the simulation and get a `BuiltBlock`. + pub async fn into_block_build(self) -> BuiltBlock { + // Keep the async state sources aligned with whichever environment pair we use. + let (rollup_env, host_env, ru_source, host_source) = match self.env { + TestBlockBuildEnv::Builder(sim_env_builder) => sim_env_builder.build_with_sources(), + TestBlockBuildEnv::Built { rollup, host } => { + let ru_source = TestStateSource::from_inner_db(rollup.db().clone()); + let host_source = TestStateSource::from_inner_db(host.db().clone()); + (rollup, host, ru_source, host_source) + } + }; + + // Convert the relative deadline into the absolute instant expected by `BlockBuild`. + let finish_by = Instant::now() + self.deadline_duration; + + BlockBuild::new( + rollup_env, + host_env, + finish_by, + self.concurrency_limit, + self.sim_cache, + self.max_gas, + self.max_host_gas, + ru_source, + host_source, + ) + .build() + .await + } +} + +/// Convenience function to quickly build a block with a cache and optional configuration. +/// This is useful for simple test cases where you just want to simulate +/// some transactions quickly. +pub async fn quick_build_block(cache: SimCache, deadline: Duration) -> BuiltBlock { + TestBlockBuildBuilder::new().with_cache(cache).with_deadline(deadline).into_block_build().await +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_block_build_builder_defaults() { + let builder = TestBlockBuildBuilder::new(); + assert_eq!(builder.deadline_duration, Duration::from_secs(2)); + assert_eq!(builder.concurrency_limit, 4); + assert_eq!(builder.max_gas, 3_000_000_000); + assert_eq!(builder.max_host_gas, 24_000_000); + } + + #[test] + fn test_block_build_builder_custom_values() { + let builder = TestBlockBuildBuilder::new() + .with_deadline(Duration::from_secs(5)) + .with_concurrency(8) + .with_max_gas(1_000_000_000) + .with_max_host_gas(10_000_000); + + assert_eq!(builder.deadline_duration, Duration::from_secs(5)); + assert_eq!(builder.concurrency_limit, 8); + assert_eq!(builder.max_gas, 1_000_000_000); + assert_eq!(builder.max_host_gas, 10_000_000); + } +} diff --git a/src/test_utils/db.rs b/src/test_utils/db.rs new file mode 100644 index 00000000..4c3b87ad --- /dev/null +++ b/src/test_utils/db.rs @@ -0,0 +1,168 @@ +//! Test database utilities for in-memory EVM state. +//! This module provides an in-memory database implementation that can be used +//! for testing block simulation without requiring network access. + +use alloy::primitives::{Address, B256, U256}; +use signet_sim::{AcctInfo, InnerDb}; +use std::sync::Arc; +use trevm::revm::{ + database::{CacheDB, EmptyDB}, + database_interface::DatabaseRef, + primitives::KECCAK_EMPTY, + state::AccountInfo, +}; + +/// In-memory database for testing (no network access required). +/// This is a type alias for revm's `CacheDB`, which stores all +/// blockchain state in memory. It implements `DatabaseRef` and can be used +/// with `RollupEnv` and `HostEnv` for offline simulation testing. +pub type TestDb = CacheDB; + +/// A [`StateSource`] backed by a [`TestDb`] for offline testing. +/// +/// This wraps an in-memory database and implements [`signet_sim::StateSource`] +/// so it can be used as the async state source parameter in [`BlockBuild::new`]. +/// +/// [`StateSource`]: signet_sim::StateSource +/// [`BlockBuild::new`]: signet_sim::BlockBuild::new +#[derive(Debug, Clone)] +pub struct TestStateSource { + db: InnerDb, +} + +impl TestStateSource { + /// Create a new [`TestStateSource`] from a [`TestDb`]. + pub fn new(db: TestDb) -> Self { + Self { db: Arc::new(CacheDB::new(db)) } + } + + /// Create a new [`TestStateSource`] from an environment database handle. + pub const fn from_inner_db(db: InnerDb) -> Self { + Self { db } + } +} + +impl signet_sim::StateSource for TestStateSource { + type Error = ::Error; + + async fn account_details(&self, address: &Address) -> Result { + let info = self.db.basic_ref(*address)?.unwrap_or_default(); + let has_code = info.code_hash() != KECCAK_EMPTY; + Ok(AcctInfo { nonce: info.nonce, balance: info.balance, has_code }) + } +} + +/// Builder for creating pre-populated test databases. +/// Use this builder to set up blockchain state (accounts, contracts, storage) +/// before running simulations. +#[derive(Debug)] +pub struct TestDbBuilder { + db: TestDb, +} + +impl Default for TestDbBuilder { + fn default() -> Self { + Self::new() + } +} + +impl TestDbBuilder { + /// Create a new empty test database builder. + pub fn new() -> Self { + Self { db: CacheDB::new(EmptyDB::default()) } + } + + /// Add an account with the specified balance and nonce. + /// + /// # Arguments + /// + /// * `address` - The account address + /// * `balance` - The account balance in wei + /// * `nonce` - The account nonce (transaction count) + pub fn with_account(mut self, address: Address, balance: U256, nonce: u64) -> Self { + self.db.insert_account_info(address, AccountInfo { balance, nonce, ..Default::default() }); + self + } + + /// Set a storage slot for an account. + /// + /// # Arguments + /// + /// * `address` - The account address + /// * `slot` - The storage slot index + /// * `value` - The value to store + pub fn with_storage(mut self, address: Address, slot: U256, value: U256) -> Self { + // Ensure the account exists before setting storage + if !self.db.cache.accounts.contains_key(&address) { + self.db.insert_account_info(address, AccountInfo::default()); + } + let _ = self.db.insert_account_storage(address, slot, value); + self + } + + /// Insert a block hash for a specific block number. + /// + /// This is useful for testing contracts that use the BLOCKHASH opcode. + /// + /// # Arguments + /// + /// * `number` - The block number + /// * `hash` - The block hash + pub fn with_block_hash(mut self, number: u64, hash: B256) -> Self { + self.db.cache.block_hashes.insert(U256::from(number), hash); + self + } + + /// Build the test database. + pub fn build(self) -> TestDb { + self.db + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_db_builder_creates_empty_db() { + let db = TestDbBuilder::new().build(); + assert!(db.cache.accounts.is_empty()); + } + + #[test] + fn test_db_builder_adds_account() { + let address = Address::repeat_byte(0x01); + let balance = U256::from(1000u64); + let nonce = 5u64; + + let db = TestDbBuilder::new().with_account(address, balance, nonce).build(); + + let account = db.cache.accounts.get(&address).unwrap(); + assert_eq!(account.info.balance, balance); + assert_eq!(account.info.nonce, nonce); + } + + #[test] + fn test_db_builder_adds_storage() { + let address = Address::repeat_byte(0x01); + let slot = U256::from(42u64); + let value = U256::from(123u64); + + let db = TestDbBuilder::new().with_storage(address, slot, value).build(); + + let account = db.cache.accounts.get(&address).unwrap(); + let stored = account.storage.get(&slot).unwrap(); + assert_eq!(*stored, value); + } + + #[test] + fn test_db_builder_adds_block_hash() { + let number = 100u64; + let hash = B256::repeat_byte(0xab); + + let db = TestDbBuilder::new().with_block_hash(number, hash).build(); + + let stored = db.cache.block_hashes.get(&U256::from(number)).unwrap(); + assert_eq!(*stored, hash); + } +} diff --git a/src/test_utils/env.rs b/src/test_utils/env.rs new file mode 100644 index 00000000..d1d53ef6 --- /dev/null +++ b/src/test_utils/env.rs @@ -0,0 +1,186 @@ +//! Test simulation environment utilities. +//! This module provides builders for creating `RollupEnv` and `HostEnv` +//! instances with in-memory databases for offline testing. + +use super::db::{TestDb, TestDbBuilder, TestStateSource}; +use crate::tasks::block::cfg::SignetCfgEnv; +use alloy::primitives::{Address, B256, U256}; +use signet_constants::SignetSystemConstants; +use signet_sim::{HostEnv, RollupEnv}; +use trevm::revm::{ + context::BlockEnv, context_interface::block::BlobExcessGasAndPrice, inspector::NoOpInspector, +}; + +/// Test rollup environment using in-memory database. +pub type TestRollupEnv = RollupEnv; + +/// Test host environment using in-memory database. +pub type TestHostEnv = HostEnv; + +/// Builder for creating test simulation environments. +/// This allows you to configure both rollup and host environments +/// with pre-populated in-memory databases for testing block simulation +/// without network access. +#[derive(Debug)] +pub struct TestSimEnvBuilder { + /// The in-memory database for the rollup environment. + rollup_db: TestDb, + /// The in-memory database for the host environment. + host_db: TestDb, + /// The block environment configuration for the rollup. + rollup_block_env: BlockEnv, + /// The block environment configuration for the host. + host_block_env: BlockEnv, + /// The unified system constants to use for both environments. + constants: SignetSystemConstants, +} + +impl Default for TestSimEnvBuilder { + fn default() -> Self { + Self::new() + } +} + +impl TestSimEnvBuilder { + /// Create a new builder with default Parmigiana constants and empty databases. + pub fn new() -> Self { + // Share one default block template so the rollup and host builders start aligned. + let default_block_env = Self::default_block_env(); + Self { + rollup_db: TestDbBuilder::new().build(), + host_db: TestDbBuilder::new().build(), + rollup_block_env: default_block_env.clone(), + host_block_env: default_block_env, + constants: SignetSystemConstants::parmigiana(), + } + } + + /// Create a default block environment suitable for testing. + fn default_block_env() -> BlockEnv { + BlockEnv { + number: U256::from(100u64), + beneficiary: Address::repeat_byte(0x01), + timestamp: U256::from(1_700_000_000u64), + gas_limit: 3_000_000_000, + basefee: 1_000_000_000, // 1 gwei + difficulty: U256::ZERO, + prevrandao: Some(B256::random()), + blob_excess_gas_and_price: Some(BlobExcessGasAndPrice { + excess_blob_gas: 0, + blob_gasprice: 0, + }), + } + } + + /// Set the rollup database. + pub fn with_rollup_db(mut self, db: TestDb) -> Self { + self.rollup_db = db; + self + } + + /// Set the host database. + pub fn with_host_db(mut self, db: TestDb) -> Self { + self.host_db = db; + self + } + + /// Set the rollup block environment. + pub const fn with_rollup_block_env(mut self, env: BlockEnv) -> Self { + self.rollup_block_env = env; + self + } + + /// Set the host block environment. + pub const fn with_host_block_env(mut self, env: BlockEnv) -> Self { + self.host_block_env = env; + self + } + + /// Set both rollup and host block environments to the same value. + pub fn with_block_env(mut self, env: BlockEnv) -> Self { + self.rollup_block_env = env.clone(); + self.host_block_env = env; + self + } + + /// Set the system constants. + pub const fn with_constants(mut self, constants: SignetSystemConstants) -> Self { + self.constants = constants; + self + } + + /// Build the test RollupEnv. + pub fn build_rollup_env(&self) -> TestRollupEnv { + let timestamp = self.rollup_block_env.timestamp.to::(); + let cfg = SignetCfgEnv::new(self.constants.ru_chain_id(), timestamp); + RollupEnv::new(self.rollup_db.clone(), self.constants.clone(), &cfg, &self.rollup_block_env) + } + + /// Build the test HostEnv. + pub fn build_host_env(&self) -> TestHostEnv { + let timestamp = self.host_block_env.timestamp.to::(); + let cfg = SignetCfgEnv::new(self.constants.host_chain_id(), timestamp); + HostEnv::new(self.host_db.clone(), self.constants.clone(), &cfg, &self.host_block_env) + } + + /// Build [`TestStateSource`] instances from the current databases. + pub fn build_state_sources(&self) -> (TestStateSource, TestStateSource) { + // Match the environment internals so explicit env injection can reuse the same source type. + (TestStateSource::new(self.rollup_db.clone()), TestStateSource::new(self.host_db.clone())) + } + + /// Build both environments as a tuple. + pub fn build(self) -> (TestRollupEnv, TestHostEnv) { + let rollup = self.build_rollup_env(); + let host = self.build_host_env(); + (rollup, host) + } + + /// Build environments and state sources together. + pub fn build_with_sources( + &self, + ) -> (TestRollupEnv, TestHostEnv, TestStateSource, TestStateSource) { + let rollup = self.build_rollup_env(); + let host = self.build_host_env(); + let (ru_source, host_source) = self.build_state_sources(); + (rollup, host, ru_source, host_source) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_sim_env_builder_creates_environments() { + // The default builder should produce both environments without any extra setup. + let builder = TestSimEnvBuilder::new(); + let (rollup_env, host_env) = builder.build(); + + // Verify environments were created (we can't easily inspect internals, + // but we can verify they don't panic during creation) + let _ = rollup_env; + let _ = host_env; + } + + #[test] + fn test_sim_env_builder_with_custom_block_env() { + // Override the shared block env to verify both environments accept custom settings. + let custom_env = BlockEnv { + number: U256::from(500u64), + beneficiary: Address::repeat_byte(0x42), + timestamp: U256::from(1800000000u64), + gas_limit: 5_000_000_000, + basefee: 2_000_000_000, + difficulty: U256::ZERO, + prevrandao: Some(B256::repeat_byte(0x11)), + blob_excess_gas_and_price: None, + }; + + let builder = TestSimEnvBuilder::new().with_block_env(custom_env); + let (rollup_env, host_env) = builder.build(); + + let _ = rollup_env; + let _ = host_env; + } +} diff --git a/src/test_utils.rs b/src/test_utils/mod.rs similarity index 85% rename from src/test_utils.rs rename to src/test_utils/mod.rs index 1a2c9e53..2e708e32 100644 --- a/src/test_utils.rs +++ b/src/test_utils/mod.rs @@ -1,4 +1,25 @@ //! Test utilities for testing builder tasks +//! +//! This module provides utilities for testing the block builder without +//! requiring network access or full chain state setup. +#![allow(dead_code, unreachable_pub, unused_imports)] + +mod block; +mod db; +mod env; +mod scenarios; +mod tx; + +// Re-export test harness components +pub use block::{TestBlockBuild, TestBlockBuildBuilder, quick_build_block}; +pub use db::{TestDb, TestDbBuilder, TestStateSource}; +pub use env::{TestHostEnv, TestRollupEnv, TestSimEnvBuilder}; +pub use scenarios::{ + DEFAULT_BALANCE, DEFAULT_BASEFEE, basic_scenario, custom_funded_scenario, funded_test_db, + gas_limit_scenario, priority_ordering_scenario, test_block_env as scenarios_test_block_env, +}; +pub use tx::{TestAccounts, create_call_tx, create_transfer_tx}; + use crate::config::BuilderConfig; use alloy::{ consensus::{SignableTransaction, TxEip1559, TxEnvelope}, @@ -20,7 +41,6 @@ use init4_bin_base::{ }, }; use signet_constants::SignetSystemConstants; -use std::env; use trevm::revm::{context::BlockEnv, context_interface::block::BlobExcessGasAndPrice}; /// Set up a block builder with test values @@ -40,7 +60,7 @@ pub fn setup_test_config() -> &'static BuilderConfig { submit_endpoints: vec!["https://relay-sepolia.flashbots.net:443".to_string()], quincey_url: "http://localhost:8080".into(), sequencer_key: None, - builder_key: env::var("SEPOLIA_ETH_PRIV_KEY") + builder_key: std::env::var("SEPOLIA_ETH_PRIV_KEY") .unwrap_or_else(|_| B256::repeat_byte(0x42).to_string()), builder_port: 8080, builder_rewards_address: Address::default(), diff --git a/src/test_utils/scenarios.rs b/src/test_utils/scenarios.rs new file mode 100644 index 00000000..4eec47a6 --- /dev/null +++ b/src/test_utils/scenarios.rs @@ -0,0 +1,187 @@ +//! Pre-configured test scenarios. +//! This module provides ready-to-use test scenarios that configure databases, +//! environments, and builders for common testing needs. + +use super::{ + block::TestBlockBuildBuilder, db::TestDbBuilder, env::TestSimEnvBuilder, tx::TestAccounts, +}; +use alloy::primitives::{Address, B256, U256}; +use signet_sim::SimCache; +use trevm::revm::{context::BlockEnv, context_interface::block::BlobExcessGasAndPrice}; + +/// Default test balance: 100 ETH in wei. +pub const DEFAULT_BALANCE: u128 = 100_000_000_000_000_000_000; + +/// Default basefee: 1 gwei. +pub const DEFAULT_BASEFEE: u64 = 1_000_000_000; + +/// Create a test database with pre-funded accounts. +/// +/// # Arguments +/// +/// * `accounts` - The test accounts to fund +/// * `balance` - The balance to give each account +pub fn funded_test_db(accounts: &TestAccounts, balance: U256) -> TestDbBuilder { + TestDbBuilder::new() + .with_account(accounts.alice_address(), balance, 0) + .with_account(accounts.bob_address(), balance, 0) + .with_account(accounts.charlie_address(), balance, 0) +} + +/// Create a standard test block environment. +/// +/// # Arguments +/// +/// * `block_number` - The block number +/// * `basefee` - The base fee per gas +/// * `timestamp` - The block timestamp +/// * `gas_limit` - The block gas limit +pub fn test_block_env(block_number: u64, basefee: u64, timestamp: u64, gas_limit: u64) -> BlockEnv { + BlockEnv { + number: U256::from(block_number), + beneficiary: Address::repeat_byte(0x01), + timestamp: U256::from(timestamp), + gas_limit, + basefee, + difficulty: U256::ZERO, + prevrandao: Some(B256::random()), + blob_excess_gas_and_price: Some(BlobExcessGasAndPrice { + excess_blob_gas: 0, + blob_gasprice: 0, + }), + } +} + +/// Basic multi-transaction block building scenario. +/// +/// Creates a scenario with: +/// - Three pre-funded test accounts (100 ETH each) +/// - Default block environment +/// - Empty SimCache ready for transactions +/// +/// # Returns +/// +/// A tuple of (builder, accounts, cache) ready for adding transactions and building. +pub fn basic_scenario() -> (TestBlockBuildBuilder, TestAccounts, SimCache) { + let accounts = TestAccounts::new(); + let balance = U256::from(DEFAULT_BALANCE); + + let rollup_db = funded_test_db(&accounts, balance).build(); + let host_db = funded_test_db(&accounts, balance).build(); + + let block_env = test_block_env(100, DEFAULT_BASEFEE, 1700000000, 3_000_000_000); + + let sim_env = TestSimEnvBuilder::new() + .with_rollup_db(rollup_db) + .with_host_db(host_db) + .with_block_env(block_env); + + let cache = SimCache::new(); + + let builder = TestBlockBuildBuilder::new().with_sim_env_builder(sim_env); + + (builder, accounts, cache) +} + +/// Scenario for testing transaction priority ordering. +/// +/// Similar to `basic_scenario` but with a longer deadline to ensure +/// all transactions can be processed and ordered. +/// +/// # Returns +/// +/// A tuple of (builder, accounts, cache) configured for priority testing. +pub fn priority_ordering_scenario() -> (TestBlockBuildBuilder, TestAccounts, SimCache) { + let (builder, accounts, cache) = basic_scenario(); + + // Use a longer deadline for ordering tests + let builder = builder.with_deadline(std::time::Duration::from_secs(5)); + + (builder, accounts, cache) +} + +/// Scenario for testing gas limit enforcement. +/// +/// Creates a scenario with a configurable gas limit to test that +/// block building respects the maximum gas constraint. +/// +/// # Arguments +/// +/// * `max_gas` - The maximum gas limit for the block +/// +/// # Returns +/// +/// A tuple of (builder, accounts, cache) with the specified gas limit. +pub fn gas_limit_scenario(max_gas: u64) -> (TestBlockBuildBuilder, TestAccounts, SimCache) { + let (builder, accounts, cache) = basic_scenario(); + + let builder = builder.with_max_gas(max_gas); + + (builder, accounts, cache) +} + +/// Scenario with custom funded addresses. +/// +/// Use this when you need specific addresses to be funded +/// (e.g., for testing contract interactions). +/// +/// # Arguments +/// +/// * `addresses` - List of (address, balance, nonce) tuples to fund +/// +/// # Returns +/// +/// A TestBlockBuildBuilder configured with the funded accounts. +pub fn custom_funded_scenario( + addresses: &[(Address, U256, u64)], +) -> (TestBlockBuildBuilder, SimCache) { + let mut db_builder = TestDbBuilder::new(); + + for (addr, balance, nonce) in addresses { + db_builder = db_builder.with_account(*addr, *balance, *nonce); + } + + let db = db_builder.build(); + + let sim_env = TestSimEnvBuilder::new().with_rollup_db(db.clone()).with_host_db(db); + + let cache = SimCache::new(); + let builder = TestBlockBuildBuilder::new().with_sim_env_builder(sim_env); + + (builder, cache) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_basic_scenario_creates_funded_accounts() { + let (_, accounts, _) = basic_scenario(); + + // Verify accounts are created with unique addresses + let addresses = accounts.addresses(); + assert_eq!(addresses.len(), 3); + assert_ne!(addresses[0], addresses[1]); + } + + #[test] + fn test_gas_limit_scenario_creates_builder() { + // Verify gas limit scenario creates a valid builder + let (_, _, _) = gas_limit_scenario(100_000); + // Builder creation succeeds (gas limit is applied internally) + } + + #[test] + fn test_custom_funded_scenario() { + let addr1 = Address::repeat_byte(0x11); + let addr2 = Address::repeat_byte(0x22); + + let (_, _) = custom_funded_scenario(&[ + (addr1, U256::from(1000u64), 5), + (addr2, U256::from(2000u64), 10), + ]); + + // Scenario creation succeeds + } +} diff --git a/src/test_utils/tx.rs b/src/test_utils/tx.rs new file mode 100644 index 00000000..eeb856ad --- /dev/null +++ b/src/test_utils/tx.rs @@ -0,0 +1,193 @@ +//! Test transaction utilities. +//! This module provides helpers for creating test transactions and accounts +//! for use in simulation tests. + +use alloy::{ + consensus::{ + SignableTransaction, TxEip1559, TxEnvelope, transaction::Recovered, + transaction::SignerRecoverable, + }, + primitives::{Address, TxKind, U256}, + signers::{SignerSync, local::PrivateKeySigner}, +}; +use eyre::Result; + +/// Pre-funded test accounts for simulation testing. +/// These accounts can be used to create and sign test transactions. +/// Use `TestDbBuilder` to fund these accounts in the test database. +#[derive(Debug, Clone)] +pub struct TestAccounts { + /// First test account (Alice) + pub alice: PrivateKeySigner, + /// Second test account (Bob) + pub bob: PrivateKeySigner, + /// Third test account (Charlie) + pub charlie: PrivateKeySigner, +} + +impl Default for TestAccounts { + fn default() -> Self { + Self::new() + } +} + +impl TestAccounts { + /// Create new random test accounts. + pub fn new() -> Self { + Self { + alice: PrivateKeySigner::random(), + bob: PrivateKeySigner::random(), + charlie: PrivateKeySigner::random(), + } + } + + /// Get all account addresses. + pub fn addresses(&self) -> Vec
{ + vec![self.alice.address(), self.bob.address(), self.charlie.address()] + } + + /// Get Alice's address. + pub const fn alice_address(&self) -> Address { + self.alice.address() + } + + /// Get Bob's address. + pub const fn bob_address(&self) -> Address { + self.bob.address() + } + + /// Get Charlie's address. + pub const fn charlie_address(&self) -> Address { + self.charlie.address() + } +} + +/// Create a signed EIP-1559 transfer transaction. +/// +/// # Arguments +/// +/// * `signer` - The account signing the transaction +/// * `to` - The recipient address +/// * `value` - The amount of wei to transfer +/// * `nonce` - The sender's nonce (transaction count) +/// * `chain_id` - The chain ID (e.g., signet_constants::parmigiana::RU_CHAIN_ID) +/// * `max_priority_fee_per_gas` - The priority fee (tip) per gas unit +/// +/// # Returns +/// +/// A recovered transaction envelope ready to be added to a SimCache. +pub fn create_transfer_tx( + signer: &PrivateKeySigner, + to: Address, + value: U256, + nonce: u64, + chain_id: u64, + max_priority_fee_per_gas: u128, +) -> Result> { + let tx = TxEip1559 { + chain_id, + nonce, + max_fee_per_gas: 100_000_000_000, // 100 gwei max fee + max_priority_fee_per_gas, + gas_limit: 21_000, // Standard transfer gas + to: TxKind::Call(to), + value, + ..Default::default() + }; + + let signature = signer.sign_hash_sync(&tx.signature_hash())?; + let signed = TxEnvelope::Eip1559(tx.into_signed(signature)); + let recovered = signed.try_into_recovered()?; + Ok(recovered) +} + +/// Create a signed EIP-1559 contract call transaction. +/// +/// # Arguments +/// +/// * `signer` - The account signing the transaction +/// * `to` - The contract address +/// * `input` - The calldata for the contract call +/// * `value` - The amount of wei to send with the call +/// * `nonce` - The sender's nonce +/// * `chain_id` - The chain ID +/// * `gas_limit` - The gas limit for the transaction +/// * `max_priority_fee_per_gas` - The priority fee per gas unit +#[allow(clippy::too_many_arguments)] +pub fn create_call_tx( + signer: &PrivateKeySigner, + to: Address, + input: alloy::primitives::Bytes, + value: U256, + nonce: u64, + chain_id: u64, + gas_limit: u64, + max_priority_fee_per_gas: u128, +) -> Result> { + let tx = TxEip1559 { + chain_id, + nonce, + max_fee_per_gas: 100_000_000_000, + max_priority_fee_per_gas, + gas_limit, + to: TxKind::Call(to), + value, + input, + ..Default::default() + }; + + let signature = signer.sign_hash_sync(&tx.signature_hash())?; + let signed = TxEnvelope::Eip1559(tx.into_signed(signature)); + let recovered = signed.try_into_recovered()?; + Ok(recovered) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_accounts_creates_unique_addresses() { + let accounts = TestAccounts::new(); + let addresses = accounts.addresses(); + + assert_eq!(addresses.len(), 3); + assert_ne!(addresses[0], addresses[1]); + assert_ne!(addresses[1], addresses[2]); + assert_ne!(addresses[0], addresses[2]); + } + + #[test] + fn test_create_transfer_tx_succeeds() { + let accounts = TestAccounts::new(); + let tx = create_transfer_tx( + &accounts.alice, + accounts.bob_address(), + U256::from(1_000_000_000_000_000_000u128), // 1 ETH + 0, + 1, // Mainnet chain ID for testing + 10_000, + ); + + assert!(tx.is_ok()); + let recovered = tx.unwrap(); + assert_eq!(recovered.signer(), accounts.alice_address()); + } + + #[test] + fn test_create_call_tx_succeeds() { + let accounts = TestAccounts::new(); + let tx = create_call_tx( + &accounts.alice, + accounts.bob_address(), + alloy::primitives::Bytes::from_static(&[0x12, 0x34]), + U256::ZERO, + 0, + 1, + 50_000, + 10_000, + ); + + assert!(tx.is_ok()); + } +} diff --git a/tests/block_builder_test.rs b/tests/block_builder_test.rs index 38db7772..7992912e 100644 --- a/tests/block_builder_test.rs +++ b/tests/block_builder_test.rs @@ -1,6 +1,6 @@ -//! Tests for the block building task. - +#![cfg(feature = "test-utils")] #![recursion_limit = "256"] +//! Tests for the block building task. use alloy::{ consensus::transaction::SignerRecoverable, eips::BlockId, node_bindings::Anvil, @@ -21,7 +21,6 @@ use std::time::{Duration, Instant}; /// This test sets up a simulated environment using Anvil, creates a block builder, /// and verifies that the block builder can successfully build a block containing /// transactions from multiple senders. -#[ignore = "integration test"] #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_handle_build() { setup_logging(); diff --git a/tests/bundle_poller_test.rs b/tests/bundle_poller_test.rs index 440e0572..9acfe483 100644 --- a/tests/bundle_poller_test.rs +++ b/tests/bundle_poller_test.rs @@ -1,7 +1,8 @@ +#![cfg(feature = "test-utils")] + use builder::test_utils::{setup_logging, setup_test_config}; use eyre::Result; -#[ignore = "integration test"] #[tokio::test] async fn test_bundle_poller_roundtrip() -> Result<()> { setup_logging(); diff --git a/tests/cache.rs b/tests/cache.rs index 9173ad08..d37cd7e9 100644 --- a/tests/cache.rs +++ b/tests/cache.rs @@ -1,3 +1,4 @@ +#![cfg(feature = "test-utils")] #![recursion_limit = "256"] use builder::{ @@ -7,7 +8,6 @@ use builder::{ use init4_bin_base::deps::tracing::warn; use std::time::Duration; -#[ignore = "integration test. This test will take >12 seconds to run, and requires Authz configuration env vars."] #[tokio::test] async fn test_bundle_poller_roundtrip() -> eyre::Result<()> { setup_logging(); diff --git a/tests/env.rs b/tests/env.rs index 89fa6a04..06f78f05 100644 --- a/tests/env.rs +++ b/tests/env.rs @@ -1,3 +1,4 @@ +#![cfg(feature = "test-utils")] #![recursion_limit = "256"] use builder::{ @@ -5,7 +6,6 @@ use builder::{ test_utils::{setup_logging, setup_test_config}, }; -#[ignore = "integration test. This test will take between 0 and 12 seconds to run."] #[tokio::test] async fn test_bundle_poller_roundtrip() -> eyre::Result<()> { setup_logging(); diff --git a/tests/tx_poller_test.rs b/tests/tx_poller_test.rs index bca37e3c..d607d8c6 100644 --- a/tests/tx_poller_test.rs +++ b/tests/tx_poller_test.rs @@ -1,3 +1,5 @@ +#![cfg(feature = "test-utils")] + use alloy::{primitives::U256, signers::local::PrivateKeySigner}; use builder::{ tasks::cache::TxPoller, @@ -5,7 +7,6 @@ use builder::{ }; use eyre::{Ok, Result}; -#[ignore = "integration test"] #[tokio::test] async fn test_tx_roundtrip() -> Result<()> { setup_logging(); From 70a85484daab479e60699c9c1b7ba0da8557bfd9 Mon Sep 17 00:00:00 2001 From: James Prestwich Date: Wed, 8 Apr 2026 11:40:23 -0400 Subject: [PATCH 02/10] Add Claude pre-push hooks for clippy and doc checks (#262) Adds a Claude Code hook that runs before every `git push`: - make fmt - make clippy (with -D warnings) - RUSTDOCFLAGS="-D warnings" cargo doc Clippy and doc warnings are hard failures that block the push. Co-authored-by: Claude Opus 4.6 (1M context) --- .claude/CLAUDE.md | 11 +++++++++++ .claude/hooks/pre-push.sh | 27 +++++++++++++++++++++++++++ .claude/settings.json | 17 +++++++++++++++++ .gitignore | 1 - 4 files changed, 55 insertions(+), 1 deletion(-) create mode 100755 .claude/hooks/pre-push.sh create mode 100644 .claude/settings.json diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index c1497f36..d50cf2ca 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -18,6 +18,17 @@ make clippy # Lint with warnings denied Always lint before committing. The Makefile provides shortcuts (`make fmt`, `make clippy`, `make test`) +### Pre-push Checks (enforced by Claude hook) + +A Claude hook in `.claude/settings.json` runs `.claude/hooks/pre-push.sh` +before every `git push`. The push is blocked if any check fails. The checks: + +- `make fmt` +- `make clippy` (runs clippy with `-D warnings`) +- `RUSTDOCFLAGS="-D warnings" cargo doc --no-deps` + +Clippy and doc warnings are hard failures. + ### Running Individual Tests ```bash diff --git a/.claude/hooks/pre-push.sh b/.claude/hooks/pre-push.sh new file mode 100755 index 00000000..189df81c --- /dev/null +++ b/.claude/hooks/pre-push.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Consume stdin (hook protocol) +cat > /dev/null + +cd "$(dirname "$0")/../.." + +echo "Running pre-push checks..." >&2 + +if ! make fmt 2>&1; then + echo "Format check failed. Run 'make fmt' to fix." >&2 + exit 2 +fi + +if ! make clippy 2>&1; then + echo "Clippy failed." >&2 + exit 2 +fi + +if ! RUSTDOCFLAGS="-D warnings" cargo doc --no-deps 2>&1; then + echo "Doc check failed." >&2 + exit 2 +fi + +echo "All pre-push checks passed." >&2 +exit 0 diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 00000000..cc3faa1e --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,17 @@ +{ + "hooks": { + "PreToolUse": [ + { + "matcher": "Bash", + "hooks": [ + { + "type": "command", + "if": "Bash(git push *)", + "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/pre-push.sh", + "timeout": 600 + } + ] + } + ] + } +} diff --git a/.gitignore b/.gitignore index c716535f..c2857905 100644 --- a/.gitignore +++ b/.gitignore @@ -25,5 +25,4 @@ target/ # Claude configs .claude/*.local.* -.claude/settings.json CLAUDE.local.md From 42fbe08d9ac8a21e5b6d78101e95d11485f63a0f Mon Sep 17 00:00:00 2001 From: dylan Date: Wed, 8 Apr 2026 16:44:16 -0600 Subject: [PATCH 03/10] tests: add load tests to the cache ingestion and simulation loop (#236) # tests: add load tests to the cache ingestion and simulation loop Per discussions with @Fraser999 I load tested the builder simulation loop and was able to reproduce the same error they saw - the build function deadlocks over some limit of bundles, which also prevents the simulation deadline from being respected. ![image.png](https://app.graphite.com/user-attachments/assets/05e096cc-ec36-4d45-822f-a4754effc441.png) The screenshot shows the test running and taking over 60 seconds, but with the deadline configured for 12 seconds, which should terminate the build loop and return a block with `tx_count > 0`. --- Cargo.lock | 3 +- Cargo.toml | 1 + src/test_utils/block.rs | 29 ++-- src/test_utils/db.rs | 41 +++-- src/test_utils/env.rs | 24 ++- tests/bundle_load_test.rs | 314 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 361 insertions(+), 51 deletions(-) create mode 100644 tests/bundle_load_test.rs diff --git a/Cargo.lock b/Cargo.lock index f52111e4..eb52dc55 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2358,7 +2358,7 @@ dependencies = [ [[package]] name = "builder" -version = "1.0.0-rc.7" +version = "1.0.0-rc.8" dependencies = [ "alloy", "alloy-chains", @@ -2374,6 +2374,7 @@ dependencies = [ "reqwest", "reth-chainspec", "signet-block-processor", + "signet-bundle", "signet-constants", "signet-genesis", "signet-sim", diff --git a/Cargo.toml b/Cargo.toml index 3794c386..16daabb2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -66,6 +66,7 @@ url = "2.5.4" [dev-dependencies] alloy-hardforks = "0.4.0" alloy-chains = "0.2" +signet-bundle = "0.16.0-rc.11" # comment / uncomment for local dev # [patch.crates-io] diff --git a/src/test_utils/block.rs b/src/test_utils/block.rs index 2ce13f09..872439a5 100644 --- a/src/test_utils/block.rs +++ b/src/test_utils/block.rs @@ -115,17 +115,24 @@ impl TestBlockBuildBuilder { /// Build the test `BlockBuild` instance. /// This creates a `BlockBuild` ready for simulation. /// Call `.build().await` on the result to execute the simulation and get a `BuiltBlock`. - pub async fn into_block_build(self) -> BuiltBlock { - // Keep the async state sources aligned with whichever environment pair we use. - let (rollup_env, host_env, ru_source, host_source) = match self.env { - TestBlockBuildEnv::Builder(sim_env_builder) => sim_env_builder.build_with_sources(), + pub fn build(self) -> TestBlockBuild { + let (rollup_env, host_env, rollup_db, host_db) = match self.env { + TestBlockBuildEnv::Builder(builder) => { + let rollup_db = builder.rollup_db(); + let host_db = builder.host_db(); + let (rollup, host) = builder.build(); + (rollup, host, rollup_db, host_db) + } TestBlockBuildEnv::Built { rollup, host } => { - let ru_source = TestStateSource::from_inner_db(rollup.db().clone()); - let host_source = TestStateSource::from_inner_db(host.db().clone()); - (rollup, host, ru_source, host_source) + let rollup_db = rollup.db().db.clone(); + let host_db = host.db().db.clone(); + (rollup, host, rollup_db, host_db) } }; + let ru_state_source = TestStateSource::new(rollup_db); + let host_state_source = TestStateSource::new(host_db); + // Convert the relative deadline into the absolute instant expected by `BlockBuild`. let finish_by = Instant::now() + self.deadline_duration; @@ -137,11 +144,9 @@ impl TestBlockBuildBuilder { self.sim_cache, self.max_gas, self.max_host_gas, - ru_source, - host_source, + ru_state_source, + host_state_source, ) - .build() - .await } } @@ -149,7 +154,7 @@ impl TestBlockBuildBuilder { /// This is useful for simple test cases where you just want to simulate /// some transactions quickly. pub async fn quick_build_block(cache: SimCache, deadline: Duration) -> BuiltBlock { - TestBlockBuildBuilder::new().with_cache(cache).with_deadline(deadline).into_block_build().await + TestBlockBuildBuilder::new().with_cache(cache).with_deadline(deadline).build().build().await } #[cfg(test)] diff --git a/src/test_utils/db.rs b/src/test_utils/db.rs index 4c3b87ad..ef6ac1f6 100644 --- a/src/test_utils/db.rs +++ b/src/test_utils/db.rs @@ -3,12 +3,10 @@ //! for testing block simulation without requiring network access. use alloy::primitives::{Address, B256, U256}; -use signet_sim::{AcctInfo, InnerDb}; -use std::sync::Arc; +use signet_sim::{AcctInfo, StateSource}; use trevm::revm::{ database::{CacheDB, EmptyDB}, database_interface::DatabaseRef, - primitives::KECCAK_EMPTY, state::AccountInfo, }; @@ -18,37 +16,34 @@ use trevm::revm::{ /// with `RollupEnv` and `HostEnv` for offline simulation testing. pub type TestDb = CacheDB; -/// A [`StateSource`] backed by a [`TestDb`] for offline testing. -/// -/// This wraps an in-memory database and implements [`signet_sim::StateSource`] -/// so it can be used as the async state source parameter in [`BlockBuild::new`]. -/// -/// [`StateSource`]: signet_sim::StateSource -/// [`BlockBuild::new`]: signet_sim::BlockBuild::new +/// A [`StateSource`] for testing backed by an in-memory [`TestDb`]. +/// Returns actual account info (nonce, balance) from the database, +/// which is required for preflight validity checks during simulation. #[derive(Debug, Clone)] pub struct TestStateSource { - db: InnerDb, + db: TestDb, } impl TestStateSource { - /// Create a new [`TestStateSource`] from a [`TestDb`]. - pub fn new(db: TestDb) -> Self { - Self { db: Arc::new(CacheDB::new(db)) } - } - - /// Create a new [`TestStateSource`] from an environment database handle. - pub const fn from_inner_db(db: InnerDb) -> Self { + /// Create a new `TestStateSource` backed by the given database. + pub const fn new(db: TestDb) -> Self { Self { db } } } -impl signet_sim::StateSource for TestStateSource { - type Error = ::Error; +impl StateSource for TestStateSource { + type Error = std::convert::Infallible; async fn account_details(&self, address: &Address) -> Result { - let info = self.db.basic_ref(*address)?.unwrap_or_default(); - let has_code = info.code_hash() != KECCAK_EMPTY; - Ok(AcctInfo { nonce: info.nonce, balance: info.balance, has_code }) + match self.db.basic_ref(*address) { + Ok(Some(info)) => Ok(AcctInfo { + nonce: info.nonce, + balance: info.balance, + has_code: info.code_hash != trevm::revm::primitives::KECCAK_EMPTY, + }), + Ok(None) => Ok(AcctInfo { nonce: 0, balance: U256::ZERO, has_code: false }), + Err(_) => unreachable!("error type is infallible"), + } } } diff --git a/src/test_utils/env.rs b/src/test_utils/env.rs index d1d53ef6..730d1ddb 100644 --- a/src/test_utils/env.rs +++ b/src/test_utils/env.rs @@ -2,7 +2,7 @@ //! This module provides builders for creating `RollupEnv` and `HostEnv` //! instances with in-memory databases for offline testing. -use super::db::{TestDb, TestDbBuilder, TestStateSource}; +use super::db::{TestDb, TestDbBuilder}; use crate::tasks::block::cfg::SignetCfgEnv; use alloy::primitives::{Address, B256, U256}; use signet_constants::SignetSystemConstants; @@ -123,10 +123,14 @@ impl TestSimEnvBuilder { HostEnv::new(self.host_db.clone(), self.constants.clone(), &cfg, &self.host_block_env) } - /// Build [`TestStateSource`] instances from the current databases. - pub fn build_state_sources(&self) -> (TestStateSource, TestStateSource) { - // Match the environment internals so explicit env injection can reuse the same source type. - (TestStateSource::new(self.rollup_db.clone()), TestStateSource::new(self.host_db.clone())) + /// Get a clone of the rollup database. + pub fn rollup_db(&self) -> TestDb { + self.rollup_db.clone() + } + + /// Get a clone of the host database. + pub fn host_db(&self) -> TestDb { + self.host_db.clone() } /// Build both environments as a tuple. @@ -135,16 +139,6 @@ impl TestSimEnvBuilder { let host = self.build_host_env(); (rollup, host) } - - /// Build environments and state sources together. - pub fn build_with_sources( - &self, - ) -> (TestRollupEnv, TestHostEnv, TestStateSource, TestStateSource) { - let rollup = self.build_rollup_env(); - let host = self.build_host_env(); - let (ru_source, host_source) = self.build_state_sources(); - (rollup, host, ru_source, host_source) - } } #[cfg(test)] diff --git a/tests/bundle_load_test.rs b/tests/bundle_load_test.rs new file mode 100644 index 00000000..e5c515dc --- /dev/null +++ b/tests/bundle_load_test.rs @@ -0,0 +1,314 @@ +#![cfg(feature = "test-utils")] +//! Load tests for bundle simulation. +//! +//! These tests exercise the block building loop with high volumes of bundles +//! and transactions to verify correctness and deadline compliance under stress. + +use alloy::{ + primitives::{Address, U256}, + serde::OtherFields, + signers::local::PrivateKeySigner, +}; +use builder::test_utils::{ + DEFAULT_BALANCE, DEFAULT_BASEFEE, TestBlockBuildBuilder, TestDbBuilder, TestSimEnvBuilder, + create_transfer_tx, scenarios_test_block_env, +}; +use signet_bundle::RecoveredBundle; +use signet_sim::{BuiltBlock, SimCache}; +use std::collections::HashSet; +use std::time::Duration; + +/// Block number used for all test environments and bundles. +const BLOCK_NUMBER: u64 = 100; + +/// Block timestamp used for all test environments and bundles. +const BLOCK_TIMESTAMP: u64 = 1_700_000_000; + +/// Parmigiana rollup chain ID. +const RU_CHAIN_ID: u64 = 88888; + +/// Default max priority fee used for transfer bundles in tests. +const DEFAULT_PRIORITY_FEE: u128 = 10_000_000_000; + +/// Generate N random funded signers and a database builder with all of them funded. +fn generate_funded_accounts(n: usize) -> (Vec, TestDbBuilder) { + let signers: Vec = (0..n).map(|_| PrivateKeySigner::random()).collect(); + let balance = U256::from(DEFAULT_BALANCE); + + let mut db_builder = TestDbBuilder::new(); + for signer in &signers { + db_builder = db_builder.with_account(signer.address(), balance, 0); + } + + (signers, db_builder) +} + +/// Create a `RecoveredBundle` with one transfer transaction. +fn make_bundle( + signer: &PrivateKeySigner, + to: Address, + uuid: String, + max_priority_fee: u128, +) -> RecoveredBundle { + let tx = create_transfer_tx(signer, to, U256::from(1_000u64), 0, RU_CHAIN_ID, max_priority_fee) + .unwrap(); + + RecoveredBundle::new_unchecked( + vec![tx], + vec![], + BLOCK_NUMBER, + Some(BLOCK_TIMESTAMP - 100), + Some(BLOCK_TIMESTAMP + 100), + vec![], + Some(uuid), + vec![], + None, + None, + vec![], + OtherFields::default(), + ) +} + +/// Build a `TestBlockBuildBuilder` from a pre-funded db builder. +fn build_env(db_builder: TestDbBuilder) -> TestBlockBuildBuilder { + let db = db_builder.build(); + let block_env = + scenarios_test_block_env(BLOCK_NUMBER, DEFAULT_BASEFEE, BLOCK_TIMESTAMP, 3_000_000_000); + let sim_env = TestSimEnvBuilder::new() + .with_rollup_db(db.clone()) + .with_host_db(db) + .with_block_env(block_env); + TestBlockBuildBuilder::new().with_sim_env_builder(sim_env) +} + +/// 50 bundles each containing 1 transfer tx. Verify block builds and includes txs. +#[tokio::test(flavor = "multi_thread", worker_threads = 4)] +async fn test_load_many_bundles() { + let count = 50; + let (signers, db_builder) = generate_funded_accounts(count); + let recipient = Address::repeat_byte(0xAA); + + let cache = SimCache::with_capacity(count); + let bundles: Vec = signers + .iter() + .enumerate() + .map(|(i, signer)| { + make_bundle(signer, recipient, format!("bundle-{i}"), DEFAULT_PRIORITY_FEE) + }) + .collect(); + + cache.add_bundles(bundles, DEFAULT_BASEFEE); + assert_eq!(cache.len(), count); + + let builder = build_env(db_builder).with_cache(cache).with_deadline(Duration::from_secs(5)); + let built: BuiltBlock = builder.build().build().await; + + assert!(built.tx_count() > 0, "expected transactions in built block, got 0"); + assert_eq!( + built.tx_count(), + count, + "expected all {count} bundle txs to be included, got {}", + built.tx_count() + ); +} + +/// 5k bundles each containing 1 transfer tx. Verify block builds with non-zero count of included txs. +#[tokio::test(flavor = "multi_thread", worker_threads = 4)] +async fn test_load_5k_bundles() { + let count = 5_000; + let (signers, db_builder) = generate_funded_accounts(count); + let recipient = Address::repeat_byte(0xAA); + + let cache = SimCache::with_capacity(count); + let bundles: Vec = signers + .iter() + .enumerate() + .map(|(i, signer)| { + // Keep ranks distinct to avoid pathological cache insertion cost at high volume. + make_bundle(signer, recipient, format!("bundle-{i}"), DEFAULT_PRIORITY_FEE + i as u128) + }) + .collect(); + + cache.add_bundles(bundles, DEFAULT_BASEFEE); + assert_eq!(cache.len(), count); + + let builder = build_env(db_builder).with_cache(cache).with_deadline(Duration::from_secs(12)); + let built: BuiltBlock = builder.build().build().await; + + assert!(built.tx_count() > 0, "expected transactions in built block, got 0"); +} + +/// 30 bundles + 30 standalone txs. Verify both types land in the built block. +#[tokio::test(flavor = "multi_thread", worker_threads = 4)] +async fn test_load_bundles_and_txs_mixed() { + let bundle_count = 30; + let tx_count = 30; + let total = bundle_count + tx_count; + + let (signers, db_builder) = generate_funded_accounts(total); + let recipient = Address::repeat_byte(0xBB); + + let cache = SimCache::with_capacity(total); + + let bundles: Vec = signers[..bundle_count] + .iter() + .enumerate() + .map(|(i, signer)| { + make_bundle(signer, recipient, format!("mix-bundle-{i}"), DEFAULT_PRIORITY_FEE) + }) + .collect(); + cache.add_bundles(bundles, DEFAULT_BASEFEE); + + for signer in &signers[bundle_count..] { + let tx = create_transfer_tx( + signer, + recipient, + U256::from(1_000u64), + 0, + RU_CHAIN_ID, + 10_000_000_000, + ) + .unwrap(); + cache.add_tx(tx, DEFAULT_BASEFEE); + } + + assert_eq!(cache.len(), total); + + let builder = build_env(db_builder).with_cache(cache).with_deadline(Duration::from_secs(5)); + let built: BuiltBlock = builder.build().build().await; + + assert!(built.tx_count() > 0, "expected transactions in built block"); + assert_eq!( + built.tx_count(), + total, + "expected all {total} items included, got {}", + built.tx_count() + ); +} + +/// Many bundles with a constrained gas limit. Verify gas cap is respected. +#[tokio::test(flavor = "multi_thread", worker_threads = 4)] +async fn test_load_saturate_gas_limit() { + let count = 50; + let (signers, db_builder) = generate_funded_accounts(count); + let recipient = Address::repeat_byte(0xCC); + + let cache = SimCache::with_capacity(count); + let bundles: Vec = signers + .iter() + .enumerate() + .map(|(i, signer)| { + make_bundle(signer, recipient, format!("gas-bundle-{i}"), DEFAULT_PRIORITY_FEE) + }) + .collect(); + cache.add_bundles(bundles, DEFAULT_BASEFEE); + + // Each transfer costs 21,000 gas. Allow room for ~10 transfers. + let max_gas: u64 = 21_000 * 10; + + let builder = build_env(db_builder) + .with_cache(cache) + .with_deadline(Duration::from_secs(5)) + .with_max_gas(max_gas); + let built: BuiltBlock = builder.build().build().await; + + assert!( + built.tx_count() <= 10, + "expected at most 10 txs within gas limit, got {}", + built.tx_count() + ); + assert!(built.tx_count() > 0, "expected at least some txs to be included"); +} + +/// Many bundles with a tight deadline. Verify block completes within time. +#[tokio::test(flavor = "multi_thread", worker_threads = 4)] +async fn test_load_deadline_pressure() { + let count = 1000; + let (signers, db_builder) = generate_funded_accounts(count); + let recipient = Address::repeat_byte(0xDD); + + let cache = SimCache::with_capacity(count); + let bundles: Vec = signers + .iter() + .enumerate() + .map(|(i, signer)| { + make_bundle(signer, recipient, format!("deadline-bundle-{i}"), DEFAULT_PRIORITY_FEE) + }) + .collect(); + cache.add_bundles(bundles, DEFAULT_BASEFEE); + + let deadline = Duration::from_millis(500); + let start = std::time::Instant::now(); + + let builder = build_env(db_builder).with_cache(cache).with_deadline(deadline); + let built: BuiltBlock = builder.build().build().await; + + let elapsed = start.elapsed(); + + assert!(built.tx_count() > 0, "expected at least some txs under deadline pressure"); + assert!( + built.tx_count() < count, + "expected fewer than {count} txs under deadline pressure, got {}", + built.tx_count() + ); + + // Should complete within a reasonable margin of the deadline. + assert!(elapsed < deadline * 3, "block build took {elapsed:?}, expected within ~{deadline:?}"); +} + +/// Gas-constrained block: verify the builder selects the highest-fee bundles first. +/// +/// 10 low-fee bundles + 10 high-fee bundles, with a gas cap that can only fit 10. +/// Every included transaction must originate from a high-fee sender. +#[tokio::test(flavor = "multi_thread", worker_threads = 4)] +async fn test_load_fee_priority_ordering() { + let low_count = 10usize; + let high_count = 10usize; + let total = low_count + high_count; + + let (signers, db_builder) = generate_funded_accounts(total); + let recipient = Address::repeat_byte(0xEE); + + let cache = SimCache::with_capacity(total); + + let low_fee = DEFAULT_PRIORITY_FEE; + let high_fee = 90_000_000_000u128; // 90 Gwei — valid (<= max_fee_per_gas=100 Gwei), 9× above low_fee + + let low_fee_senders: HashSet
= + signers[..low_count].iter().map(|s| s.address()).collect(); + + let bundles: Vec = signers + .iter() + .enumerate() + .map(|(i, signer)| { + let fee = if i < low_count { low_fee } else { high_fee }; + make_bundle(signer, recipient, format!("priority-bundle-{i}"), fee) + }) + .collect(); + + cache.add_bundles(bundles, DEFAULT_BASEFEE); + + // Gas limit exactly fits the 10 high-fee bundles (21,000 gas each). + let max_gas: u64 = 21_000 * high_count as u64; + + let builder = build_env(db_builder) + .with_cache(cache) + .with_deadline(Duration::from_secs(5)) + .with_max_gas(max_gas); + let built: BuiltBlock = builder.build().build().await; + + assert_eq!( + built.tx_count(), + high_count, + "expected exactly {high_count} txs, got {}", + built.tx_count() + ); + + for tx in built.transactions() { + assert!( + !low_fee_senders.contains(&tx.signer()), + "low-fee sender {} was included instead of a high-fee sender", + tx.signer() + ); + } +} From 91132a53b4497f8251b8d35bcafe22b3cd654e30 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison <190532+Fraser999@users.noreply.github.com> Date: Thu, 9 Apr 2026 16:48:29 +0100 Subject: [PATCH 04/10] centralize metrics functions (#263) --- bin/builder.rs | 1 + src/lib.rs | 9 + src/metrics.rs | 405 ++++++++++++++++++++++++++++++++++++++ src/tasks/block/sim.rs | 9 +- src/tasks/cache/bundle.rs | 11 +- src/tasks/cache/task.rs | 13 +- src/tasks/cache/tx.rs | 9 +- src/tasks/metrics.rs | 11 +- src/tasks/submit/prep.rs | 5 +- src/tasks/submit/task.rs | 30 +-- 10 files changed, 454 insertions(+), 49 deletions(-) create mode 100644 src/metrics.rs diff --git a/bin/builder.rs b/bin/builder.rs index 77573233..e9e3ee3e 100644 --- a/bin/builder.rs +++ b/bin/builder.rs @@ -58,6 +58,7 @@ async fn main() -> eyre::Result<()> { } let config = builder::config_from_env(); + builder::init_metrics(); let init_span_guard = info_span!("builder initialization").entered(); info!(pkg_version = PKG_VERSION, git_commit = GIT_COMMIT, "starting builder"); diff --git a/src/lib.rs b/src/lib.rs index c5f48db0..ef8e73f0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,6 +16,9 @@ #[macro_use] mod macros; +/// Centralized metrics for the builder. +pub(crate) mod metrics; + /// Configuration for the Builder binary. pub mod config; @@ -72,6 +75,12 @@ pub fn config() -> &'static config::BuilderConfig { &CONFIG_AND_GUARD.get().expect("Builder config not initialized").config } +/// Register all metric descriptions. Call once at startup after the metrics +/// recorder is installed. +pub fn init_metrics() { + metrics::init(); +} + /// Get a reference to the Signet system constants from the global Builder /// configuration. /// diff --git a/src/metrics.rs b/src/metrics.rs new file mode 100644 index 00000000..14c57dbd --- /dev/null +++ b/src/metrics.rs @@ -0,0 +1,405 @@ +//! Centralized metrics for the builder. +//! +//! All metrics are defined and described here so that callers never need to +//! use bare `counter!` / `histogram!` macros directly. This prevents +//! metric-name typos and provides a single place to survey every metric the +//! builder emits. +use init4_bin_base::deps::metrics::{counter, describe_counter, describe_histogram, histogram}; +use std::sync::LazyLock; + +// --------------------------------------------------------------------------- +// Metric names and help text +// --------------------------------------------------------------------------- + +// -- Block building -- + +const BUILT_BLOCKS: &str = "signet.builder.built_blocks"; +const BUILT_BLOCKS_HELP: &str = "Number of blocks built by the simulator."; + +const BUILT_BLOCKS_TX_COUNT: &str = "signet.builder.built_blocks.tx_count"; +const BUILT_BLOCKS_TX_COUNT_HELP: &str = "Transaction count per built block."; + +// -- Cache polling -- + +const TX_NONCE_STALE: &str = "signet.builder.cache.tx_nonce_stale"; +const TX_NONCE_STALE_HELP: &str = "Transactions dropped due to stale nonce."; + +const TX_POLL_COUNT: &str = "signet.builder.cache.tx_poll_count"; +const TX_POLL_COUNT_HELP: &str = "Transaction cache poll attempts."; + +const TX_POLL_ERRORS: &str = "signet.builder.cache.tx_poll_errors"; +const TX_POLL_ERRORS_HELP: &str = "Transaction cache poll errors."; + +const TXS_FETCHED: &str = "signet.builder.cache.txs_fetched"; +const TXS_FETCHED_HELP: &str = "Transactions fetched per poll cycle."; + +const BUNDLE_POLL_COUNT: &str = "signet.builder.cache.bundle_poll_count"; +const BUNDLE_POLL_COUNT_HELP: &str = "Bundle cache poll attempts."; + +const BUNDLE_POLL_ERRORS: &str = "signet.builder.cache.bundle_poll_errors"; +const BUNDLE_POLL_ERRORS_HELP: &str = "Bundle cache poll errors."; + +const BUNDLES_FETCHED: &str = "signet.builder.cache.bundles_fetched"; +const BUNDLES_FETCHED_HELP: &str = "Bundles fetched per poll cycle."; + +// -- Cache ingestion -- + +const CACHE_CLEANS: &str = "signet.builder.cache.cache_cleans"; +const CACHE_CLEANS_HELP: &str = "Cache clean operations triggered by new block environments."; + +const BUNDLES_SKIPPED: &str = "signet.builder.cache.bundles_skipped"; +const BUNDLES_SKIPPED_HELP: &str = "Bundles skipped because they target a past block."; + +const BUNDLE_ADD_ERRORS: &str = "signet.builder.cache.bundle_add_errors"; +const BUNDLE_ADD_ERRORS_HELP: &str = "Errors adding bundles to the simulation cache."; + +const BUNDLES_INGESTED: &str = "signet.builder.cache.bundles_ingested"; +const BUNDLES_INGESTED_HELP: &str = "Bundles successfully ingested into the simulation cache."; + +const TXS_INGESTED: &str = "signet.builder.cache.txs_ingested"; +const TXS_INGESTED_HELP: &str = "Transactions successfully ingested into the simulation cache."; + +const TX_RECOVER_FAILURES: &str = "signet.builder.cache.tx_recover_failures"; +const TX_RECOVER_FAILURES_HELP: &str = "Transaction signature recovery failures."; + +// -- Tx monitoring -- + +const TX_MINE_TIME: &str = "signet.builder.tx_mine_time"; +const TX_MINE_TIME_HELP: &str = "Time in milliseconds for a submitted transaction to be mined."; + +const TX_SUCCEEDED: &str = "signet.builder.tx_succeeded"; +const TX_SUCCEEDED_HELP: &str = "Submitted transactions that succeeded on-chain."; + +const TX_REVERTED: &str = "signet.builder.tx_reverted"; +const TX_REVERTED_HELP: &str = "Submitted transactions that reverted on-chain."; + +const TX_NOT_MINED: &str = "signet.builder.tx_not_mined"; +const TX_NOT_MINED_HELP: &str = "Submitted transactions that were not mined within the timeout."; + +const RPC_ERROR: &str = "signet.builder.rpc_error"; +const RPC_ERROR_HELP: &str = "RPC errors encountered while watching submitted transactions."; + +// -- Quincey signing -- + +const QUINCEY_SIGNATURES: &str = "signet.builder.quincey_signatures"; +const QUINCEY_SIGNATURES_HELP: &str = "Successful Quincey signature responses."; + +const QUINCEY_SIGNATURE_FAILURES: &str = "signet.builder.quincey_signature_failures"; +const QUINCEY_SIGNATURE_FAILURES_HELP: &str = "Failed Quincey signature requests."; + +// -- Submit -- + +const TRANSACTIONS_PREPARED: &str = "signet.builder.submit.transactions_prepared"; +const TRANSACTIONS_PREPARED_HELP: &str = "Signed rollup block transactions ready for submission."; + +const EMPTY_BLOCKS: &str = "signet.builder.submit.empty_blocks"; +const EMPTY_BLOCKS_HELP: &str = "Empty blocks skipped during submission."; + +const BUNDLE_PREP_FAILURES: &str = "signet.builder.submit.bundle_prep_failures"; +const BUNDLE_PREP_FAILURES_HELP: &str = "Bundle preparation errors."; + +const RELAY_SUBMISSIONS: &str = "signet.builder.submit.relay_submissions"; +const RELAY_SUBMISSIONS_HELP: &str = "Relay submission attempts (incremented per relay)."; + +const DEADLINE_MISSED_BEFORE_SEND: &str = "signet.builder.submit.deadline_missed_before_send"; +const DEADLINE_MISSED_BEFORE_SEND_HELP: &str = + "Submissions that started after the slot deadline had already passed."; + +const RELAY_SUCCESSES: &str = "signet.builder.submit.relay_successes"; +const RELAY_SUCCESSES_HELP: &str = "Per-relay successful bundle submissions."; + +const RELAY_FAILURES: &str = "signet.builder.submit.relay_failures"; +const RELAY_FAILURES_HELP: &str = "Per-relay bundle submission errors."; + +const RELAY_TIMEOUTS: &str = "signet.builder.submit.relay_timeouts"; +const RELAY_TIMEOUTS_HELP: &str = "Per-relay bundle submission deadline timeouts."; + +const ALL_RELAYS_FAILED: &str = "signet.builder.submit.all_relays_failed"; +const ALL_RELAYS_FAILED_HELP: &str = "Bundles where no relay accepted the submission."; + +const BUNDLES_SUBMITTED: &str = "signet.builder.submit.bundles_submitted"; +const BUNDLES_SUBMITTED_HELP: &str = "Bundles accepted by at least one relay."; + +const DEADLINE_MISSED: &str = "signet.builder.submit.deadline_missed"; +const DEADLINE_MISSED_HELP: &str = "Bundles accepted by relays but after the slot deadline."; + +const DEADLINE_MET: &str = "signet.builder.submit.deadline_met"; +const DEADLINE_MET_HELP: &str = "Bundles accepted by relays within the slot deadline."; + +// -- Pylon -- + +const PYLON_SUBMISSION_FAILURES: &str = "signet.builder.pylon.submission_failures"; +const PYLON_SUBMISSION_FAILURES_HELP: &str = "Pylon sidecar submission errors."; + +const PYLON_SIDECARS_SUBMITTED: &str = "signet.builder.pylon.sidecars_submitted"; +const PYLON_SIDECARS_SUBMITTED_HELP: &str = "Successful Pylon sidecar submissions."; + +// --------------------------------------------------------------------------- +// Lazy description registration +// --------------------------------------------------------------------------- + +static DESCRIPTIONS: LazyLock<()> = LazyLock::new(|| { + // Block building + describe_counter!(BUILT_BLOCKS, BUILT_BLOCKS_HELP); + describe_histogram!(BUILT_BLOCKS_TX_COUNT, BUILT_BLOCKS_TX_COUNT_HELP); + + // Cache polling + describe_counter!(TX_NONCE_STALE, TX_NONCE_STALE_HELP); + describe_counter!(TX_POLL_COUNT, TX_POLL_COUNT_HELP); + describe_counter!(TX_POLL_ERRORS, TX_POLL_ERRORS_HELP); + describe_histogram!(TXS_FETCHED, TXS_FETCHED_HELP); + describe_counter!(BUNDLE_POLL_COUNT, BUNDLE_POLL_COUNT_HELP); + describe_counter!(BUNDLE_POLL_ERRORS, BUNDLE_POLL_ERRORS_HELP); + describe_histogram!(BUNDLES_FETCHED, BUNDLES_FETCHED_HELP); + + // Cache ingestion + describe_counter!(CACHE_CLEANS, CACHE_CLEANS_HELP); + describe_counter!(BUNDLES_SKIPPED, BUNDLES_SKIPPED_HELP); + describe_counter!(BUNDLE_ADD_ERRORS, BUNDLE_ADD_ERRORS_HELP); + describe_counter!(BUNDLES_INGESTED, BUNDLES_INGESTED_HELP); + describe_counter!(TXS_INGESTED, TXS_INGESTED_HELP); + describe_counter!(TX_RECOVER_FAILURES, TX_RECOVER_FAILURES_HELP); + + // Tx monitoring + describe_histogram!(TX_MINE_TIME, TX_MINE_TIME_HELP); + describe_counter!(TX_SUCCEEDED, TX_SUCCEEDED_HELP); + describe_counter!(TX_REVERTED, TX_REVERTED_HELP); + describe_counter!(TX_NOT_MINED, TX_NOT_MINED_HELP); + describe_counter!(RPC_ERROR, RPC_ERROR_HELP); + + // Quincey signing + describe_counter!(QUINCEY_SIGNATURES, QUINCEY_SIGNATURES_HELP); + describe_counter!(QUINCEY_SIGNATURE_FAILURES, QUINCEY_SIGNATURE_FAILURES_HELP); + + // Submit + describe_counter!(TRANSACTIONS_PREPARED, TRANSACTIONS_PREPARED_HELP); + describe_counter!(EMPTY_BLOCKS, EMPTY_BLOCKS_HELP); + describe_counter!(BUNDLE_PREP_FAILURES, BUNDLE_PREP_FAILURES_HELP); + describe_counter!(RELAY_SUBMISSIONS, RELAY_SUBMISSIONS_HELP); + describe_counter!(DEADLINE_MISSED_BEFORE_SEND, DEADLINE_MISSED_BEFORE_SEND_HELP); + describe_counter!(RELAY_SUCCESSES, RELAY_SUCCESSES_HELP); + describe_counter!(RELAY_FAILURES, RELAY_FAILURES_HELP); + describe_counter!(RELAY_TIMEOUTS, RELAY_TIMEOUTS_HELP); + describe_counter!(ALL_RELAYS_FAILED, ALL_RELAYS_FAILED_HELP); + describe_counter!(BUNDLES_SUBMITTED, BUNDLES_SUBMITTED_HELP); + describe_counter!(DEADLINE_MISSED, DEADLINE_MISSED_HELP); + describe_counter!(DEADLINE_MET, DEADLINE_MET_HELP); + + // Pylon + describe_counter!(PYLON_SUBMISSION_FAILURES, PYLON_SUBMISSION_FAILURES_HELP); + describe_counter!(PYLON_SIDECARS_SUBMITTED, PYLON_SIDECARS_SUBMITTED_HELP); +}); + +/// Register all metric descriptions. Call once at startup (e.g. after +/// initializing the metrics recorder). +pub(crate) fn init() { + LazyLock::force(&DESCRIPTIONS); +} + +// --------------------------------------------------------------------------- +// Public API -- Block building +// --------------------------------------------------------------------------- + +/// Increment the built-blocks counter. +pub(crate) fn inc_built_blocks() { + counter!(BUILT_BLOCKS).increment(1); +} + +/// Record the transaction count of a built block. +pub(crate) fn record_built_block_tx_count(count: usize) { + histogram!(BUILT_BLOCKS_TX_COUNT).record(count as f64); +} + +// --------------------------------------------------------------------------- +// Public API -- Cache polling +// --------------------------------------------------------------------------- + +/// Increment the stale-nonce transaction counter. +pub(crate) fn inc_tx_nonce_stale() { + counter!(TX_NONCE_STALE).increment(1); +} + +/// Increment the transaction poll attempt counter. +pub(crate) fn inc_tx_poll_count() { + counter!(TX_POLL_COUNT).increment(1); +} + +/// Increment the transaction poll error counter. +pub(crate) fn inc_tx_poll_errors() { + counter!(TX_POLL_ERRORS).increment(1); +} + +/// Record the number of transactions fetched in a poll cycle. +pub(crate) fn record_txs_fetched(count: usize) { + histogram!(TXS_FETCHED).record(count as f64); +} + +/// Increment the bundle poll attempt counter. +pub(crate) fn inc_bundle_poll_count() { + counter!(BUNDLE_POLL_COUNT).increment(1); +} + +/// Increment the bundle poll error counter. +pub(crate) fn inc_bundle_poll_errors() { + counter!(BUNDLE_POLL_ERRORS).increment(1); +} + +/// Record the number of bundles fetched in a poll cycle. +pub(crate) fn record_bundles_fetched(count: usize) { + histogram!(BUNDLES_FETCHED).record(count as f64); +} + +// --------------------------------------------------------------------------- +// Public API -- Cache ingestion +// --------------------------------------------------------------------------- + +/// Increment the cache-clean counter. +pub(crate) fn inc_cache_cleans() { + counter!(CACHE_CLEANS).increment(1); +} + +/// Increment the skipped-bundle counter (bundle targets a past block). +pub(crate) fn inc_bundles_skipped() { + counter!(BUNDLES_SKIPPED).increment(1); +} + +/// Increment the bundle-add-error counter. +pub(crate) fn inc_bundle_add_errors() { + counter!(BUNDLE_ADD_ERRORS).increment(1); +} + +/// Increment the bundles-ingested counter. +pub(crate) fn inc_bundles_ingested() { + counter!(BUNDLES_INGESTED).increment(1); +} + +/// Increment the transactions-ingested counter. +pub(crate) fn inc_txs_ingested() { + counter!(TXS_INGESTED).increment(1); +} + +/// Increment the transaction signature recovery failure counter. +pub(crate) fn inc_tx_recover_failures() { + counter!(TX_RECOVER_FAILURES).increment(1); +} + +// --------------------------------------------------------------------------- +// Public API -- Tx monitoring +// --------------------------------------------------------------------------- + +/// Record the time for a submitted transaction to be mined. +pub(crate) fn record_tx_mine_time(duration: std::time::Duration) { + histogram!(TX_MINE_TIME).record(duration.as_millis() as f64); +} + +/// Increment the succeeded-transaction counter. +pub(crate) fn inc_tx_succeeded() { + counter!(TX_SUCCEEDED).increment(1); +} + +/// Increment the reverted-transaction counter. +pub(crate) fn inc_tx_reverted() { + counter!(TX_REVERTED).increment(1); +} + +/// Increment the not-mined-transaction counter. +pub(crate) fn inc_tx_not_mined() { + counter!(TX_NOT_MINED).increment(1); +} + +/// Increment the RPC error counter. +pub(crate) fn inc_rpc_error() { + counter!(RPC_ERROR).increment(1); +} + +// --------------------------------------------------------------------------- +// Public API -- Quincey signing +// --------------------------------------------------------------------------- + +/// Increment the successful Quincey signature counter. +pub(crate) fn inc_quincey_signatures() { + counter!(QUINCEY_SIGNATURES).increment(1); +} + +/// Increment the failed Quincey signature counter. +pub(crate) fn inc_quincey_signature_failures() { + counter!(QUINCEY_SIGNATURE_FAILURES).increment(1); +} + +// --------------------------------------------------------------------------- +// Public API -- Submit +// --------------------------------------------------------------------------- + +/// Increment the transactions-prepared counter. +pub(crate) fn inc_transactions_prepared() { + counter!(TRANSACTIONS_PREPARED).increment(1); +} + +/// Increment the empty-blocks counter. +pub(crate) fn inc_empty_blocks() { + counter!(EMPTY_BLOCKS).increment(1); +} + +/// Increment the bundle-prep-failures counter. +pub(crate) fn inc_bundle_prep_failures() { + counter!(BUNDLE_PREP_FAILURES).increment(1); +} + +/// Increment the relay submission attempt counter by `count`. +pub(crate) fn inc_relay_submissions(count: usize) { + counter!(RELAY_SUBMISSIONS).increment(count as u64); +} + +/// Increment the deadline-missed-before-send counter. +pub(crate) fn inc_deadline_missed_before_send() { + counter!(DEADLINE_MISSED_BEFORE_SEND).increment(1); +} + +/// Increment the per-relay success counter. +pub(crate) fn inc_relay_successes() { + counter!(RELAY_SUCCESSES).increment(1); +} + +/// Increment the per-relay failure counter. +pub(crate) fn inc_relay_failures() { + counter!(RELAY_FAILURES).increment(1); +} + +/// Increment the per-relay timeout counter. +pub(crate) fn inc_relay_timeouts() { + counter!(RELAY_TIMEOUTS).increment(1); +} + +/// Increment the all-relays-failed counter. +pub(crate) fn inc_all_relays_failed() { + counter!(ALL_RELAYS_FAILED).increment(1); +} + +/// Increment the bundles-submitted counter. +pub(crate) fn inc_bundles_submitted() { + counter!(BUNDLES_SUBMITTED).increment(1); +} + +/// Increment the deadline-missed counter. +pub(crate) fn inc_deadline_missed() { + counter!(DEADLINE_MISSED).increment(1); +} + +/// Increment the deadline-met counter. +pub(crate) fn inc_deadline_met() { + counter!(DEADLINE_MET).increment(1); +} + +// --------------------------------------------------------------------------- +// Public API -- Pylon +// --------------------------------------------------------------------------- + +/// Increment the Pylon submission failure counter. +pub(crate) fn inc_pylon_submission_failures() { + counter!(PYLON_SUBMISSION_FAILURES).increment(1); +} + +/// Increment the Pylon sidecars-submitted counter. +pub(crate) fn inc_pylon_sidecars_submitted() { + counter!(PYLON_SIDECARS_SUBMITTED).increment(1); +} diff --git a/src/tasks/block/sim.rs b/src/tasks/block/sim.rs index 4fd32e91..f6edc5c1 100644 --- a/src/tasks/block/sim.rs +++ b/src/tasks/block/sim.rs @@ -6,10 +6,7 @@ use crate::{ tasks::env::SimEnv, }; use alloy::{consensus::Header, eips::Encodable2718, primitives::Bytes}; -use init4_bin_base::{ - deps::metrics::{counter, histogram}, - utils::calc::SlotCalculator, -}; +use init4_bin_base::utils::calc::SlotCalculator; use signet_sim::{BlockBuild, BuiltBlock, SimCache}; use signet_types::constants::SignetSystemConstants; use std::time::{Duration, Instant}; @@ -168,8 +165,8 @@ impl SimulatorTask { block_number = built_block.block_number(), "block simulation completed", ); - counter!("signet.builder.built_blocks").increment(1); - histogram!("signet.builder.built_blocks.tx_count").record(built_block.tx_count() as u32); + crate::metrics::inc_built_blocks(); + crate::metrics::record_built_block_tx_count(built_block.tx_count()); Ok(built_block) } diff --git a/src/tasks/cache/bundle.rs b/src/tasks/cache/bundle.rs index 8b6a4416..a45fff03 100644 --- a/src/tasks/cache/bundle.rs +++ b/src/tasks/cache/bundle.rs @@ -1,10 +1,7 @@ //! Bundler service responsible for fetching bundles and sending them to the simulator. use crate::config::BuilderConfig; use futures_util::{TryFutureExt, TryStreamExt}; -use init4_bin_base::{ - deps::metrics::{counter, histogram}, - perms::tx_cache::{BuilderTxCache, BuilderTxCacheError}, -}; +use init4_bin_base::perms::tx_cache::{BuilderTxCache, BuilderTxCacheError}; use signet_tx_cache::{TxCacheError, types::CachedBundle}; use tokio::{ sync::mpsc::{UnboundedReceiver, UnboundedSender, unbounded_channel}, @@ -70,7 +67,7 @@ impl BundlePoller { break; } - counter!("signet.builder.cache.bundle_poll_count").increment(1); + crate::metrics::inc_bundle_poll_count(); let Ok(bundles) = self .check_bundle_cache() .inspect_err(|error| match error { @@ -78,7 +75,7 @@ impl BundlePoller { trace!("Not our slot to fetch bundles"); } _ => { - counter!("signet.builder.cache.bundle_poll_errors").increment(1); + crate::metrics::inc_bundle_poll_errors(); warn!(%error, "Failed to fetch bundles from tx-cache"); } }) @@ -91,7 +88,7 @@ impl BundlePoller { { let _guard = span.entered(); - histogram!("signet.builder.cache.bundles_fetched").record(bundles.len() as f64); + crate::metrics::record_bundles_fetched(bundles.len()); trace!(count = bundles.len(), "fetched bundles from tx-cache"); for bundle in bundles { if let Err(err) = outbound.send(bundle) { diff --git a/src/tasks/cache/task.rs b/src/tasks/cache/task.rs index aec1a22e..927ff50d 100644 --- a/src/tasks/cache/task.rs +++ b/src/tasks/cache/task.rs @@ -1,6 +1,5 @@ use crate::tasks::{cache::tx::ReceivedTx, env::SimEnv}; use alloy::consensus::transaction::SignerRecoverable; -use init4_bin_base::deps::metrics::counter; use signet_sim::SimCache; use signet_tx_cache::types::CachedBundle; use tokio::{ @@ -65,7 +64,7 @@ impl CacheTask { cache.clean( sim_env.number.to(), sim_env.timestamp.to() ); - counter!("signet.builder.cache.cache_cleans").increment(1); + crate::metrics::inc_cache_cleans(); } } Some(bundle) = self.bundles.recv() => { @@ -85,7 +84,7 @@ impl CacheTask { %bundle.id, "skipping bundle insert" ); - counter!("signet.builder.cache.bundles_skipped").increment(1); + crate::metrics::inc_bundles_skipped(); summary.bundles_skipped_stale += 1; continue; } @@ -93,11 +92,11 @@ impl CacheTask { let res = cache.add_bundle(bundle.bundle, basefee); // Skip bundles that fail to be added to the cache if let Err(e) = res { - counter!("signet.builder.cache.bundle_add_errors").increment(1); + crate::metrics::inc_bundle_add_errors(); debug!(?e, "Failed to add bundle to cache"); continue; } - counter!("signet.builder.cache.bundles_ingested").increment(1); + crate::metrics::inc_bundles_ingested(); summary.bundles_accepted += 1; } Some(received_txn) = self.txns.recv() => { @@ -110,11 +109,11 @@ impl CacheTask { match txn.try_into_recovered() { Ok(recovered_tx) => { cache.add_tx(recovered_tx, basefee); - counter!("signet.builder.cache.txs_ingested").increment(1); + crate::metrics::inc_txs_ingested(); summary.txs_accepted += 1; } Err(_) => { - counter!("signet.builder.cache.tx_recover_failures").increment(1); + crate::metrics::inc_tx_recover_failures(); debug!("Failed to recover transaction signature"); } } diff --git a/src/tasks/cache/tx.rs b/src/tasks/cache/tx.rs index def47090..25a481d9 100644 --- a/src/tasks/cache/tx.rs +++ b/src/tasks/cache/tx.rs @@ -5,7 +5,6 @@ use alloy::{ providers::Provider, }; use futures_util::{TryFutureExt, TryStreamExt}; -use init4_bin_base::deps::metrics::{counter, histogram}; use signet_tx_cache::{TxCache, TxCacheError}; use std::time::Duration; use tokio::{sync::mpsc, task::JoinHandle, time}; @@ -82,7 +81,7 @@ impl TxPoller { }; if tx.nonce() < tx_count { - counter!("signet.builder.cache.tx_nonce_stale").increment(1); + crate::metrics::inc_tx_nonce_stale(); if outbound.send(ReceivedTx::StaleNonce).is_err() { span_warn!(span, "Outbound channel closed, stopping NonceChecker task."); } @@ -112,18 +111,18 @@ impl TxPoller { break; } - counter!("signet.builder.cache.tx_poll_count").increment(1); + crate::metrics::inc_tx_poll_count(); if let Ok(transactions) = self .check_tx_cache() .inspect_err(|error| { - counter!("signet.builder.cache.tx_poll_errors").increment(1); + crate::metrics::inc_tx_poll_errors(); debug!(%error, "Error fetching transactions"); }) .instrument(span.clone()) .await { let _guard = span.entered(); - histogram!("signet.builder.cache.txs_fetched").record(transactions.len() as f64); + crate::metrics::record_txs_fetched(transactions.len()); trace!(count = transactions.len(), "found transactions"); for tx in transactions.into_iter() { self.spawn_check_nonce(tx, outbound.clone()); diff --git a/src/tasks/metrics.rs b/src/tasks/metrics.rs index 699978c8..702c2deb 100644 --- a/src/tasks/metrics.rs +++ b/src/tasks/metrics.rs @@ -3,7 +3,6 @@ use alloy::{ primitives::TxHash, providers::{PendingTransactionBuilder, PendingTransactionError, Provider as _, WatchTxError}, }; -use init4_bin_base::deps::metrics::{counter, histogram}; use std::time::{Duration, Instant}; use tokio::{sync::mpsc, task::JoinHandle}; use tracing::{Instrument, debug, error, info_span}; @@ -50,24 +49,24 @@ impl MetricsTask { Ok(receipt) => { // record how long it took to mine the transaction // potential improvement: use the block timestamp to calculate the time elapsed - histogram!("metrics.tx_mine_time").record(start.elapsed().as_millis() as f64); + crate::metrics::record_tx_mine_time(start.elapsed()); // log whether the transaction reverted if receipt.status() { - counter!("metrics.tx_succeeded").increment(1); + crate::metrics::inc_tx_succeeded(); debug!("tx succeeded"); } else { - counter!("metrics.tx_reverted").increment(1); + crate::metrics::inc_tx_reverted(); debug!("tx reverted"); } } Err(PendingTransactionError::TxWatcher(WatchTxError::Timeout)) => { // log that the transaction timed out - counter!("metrics.tx_not_mined").increment(1); + crate::metrics::inc_tx_not_mined(); debug!("tx not mined"); } Err(e) => { - counter!("metrics.rpc_error").increment(1); + crate::metrics::inc_rpc_error(); error!(error = ?e, "rpc error"); } } diff --git a/src/tasks/submit/prep.rs b/src/tasks/submit/prep.rs index 7e97ecda..265c1cdb 100644 --- a/src/tasks/submit/prep.rs +++ b/src/tasks/submit/prep.rs @@ -14,7 +14,6 @@ use alloy::{ sol_types::SolCall, }; use futures_util::FutureExt; -use init4_bin_base::deps::metrics::counter; use signet_sim::BuiltBlock; use signet_types::{SignRequest, SignResponse}; use signet_zenith::Zenith; @@ -83,9 +82,9 @@ impl<'a> SubmitPrep<'a> { self.quincey .get_signature(sig_request) .await - .inspect(|_| counter!("signet.builder.quincey_signatures").increment(1)) + .inspect(|_| crate::metrics::inc_quincey_signatures()) .inspect_err(|err| { - counter!("signet.builder.quincey_signature_failures").increment(1); + crate::metrics::inc_quincey_signature_failures(); if let QuinceyError::NotOurSlot = err { warn!("Quincey indicated not our slot to sign"); } else { diff --git a/src/tasks/submit/task.rs b/src/tasks/submit/task.rs index a0911155..6721a27b 100644 --- a/src/tasks/submit/task.rs +++ b/src/tasks/submit/task.rs @@ -31,7 +31,7 @@ use alloy::{ rpc::types::mev::EthSendBundle, }; use futures_util::stream::{FuturesUnordered, StreamExt}; -use init4_bin_base::{deps::metrics::counter, utils::signer::LocalOrAws}; +use init4_bin_base::utils::signer::LocalOrAws; use std::{ sync::Arc, time::{Duration, Instant}, @@ -159,7 +159,7 @@ impl SubmitTask { /// Tracks the outbound transaction hash and increments submission metrics. fn track_outbound_tx(&self, envelope: &TxEnvelope) { - counter!("signet.builder.submit.transactions_prepared").increment(1); + crate::metrics::inc_transactions_prepared(); let hash = *envelope.tx_hash(); if self.outbound.send(hash).is_err() { debug!("outbound channel closed, could not track tx hash"); @@ -189,7 +189,7 @@ impl SubmitTask { let deadline = self.calculate_submit_deadline(); if sim_result.block.is_empty() { - counter!("signet.builder.submit.empty_blocks").increment(1); + crate::metrics::inc_empty_blocks(); span_debug!(span, "received empty block - skipping"); continue; } @@ -198,7 +198,7 @@ impl SubmitTask { let bundle = match self.prepare(&sim_result).instrument(span.clone()).await { Ok(bundle) => bundle, Err(error) => { - counter!("signet.builder.submit.bundle_prep_failures").increment(1); + crate::metrics::inc_bundle_prep_failures(); span_debug!(span, %error, "bundle preparation failed"); continue; } @@ -333,13 +333,13 @@ impl Submission { /// results from faster relays. async fn submit_to_relays(&self) -> Vec { let n_relays = self.relays.len(); - counter!("signet.builder.submit.relay_submissions").increment(n_relays as u64); + crate::metrics::inc_relay_submissions(n_relays); let now = Instant::now(); let timeout_dur = if now > self.deadline { let late_by = now.duration_since(self.deadline); warn!(?late_by, "submission started AFTER deadline; attempting anyway"); - counter!("signet.builder.submit.deadline_missed_before_send").increment(1); + crate::metrics::inc_deadline_missed_before_send(); LATE_SUBMISSION_TIMEOUT } else { self.deadline.duration_since(now) @@ -375,33 +375,33 @@ impl Submission { for outcome in outcomes { match outcome { RelayOutcome::Success => { - counter!("signet.builder.submit.relay_successes").increment(1); + crate::metrics::inc_relay_successes(); successes += 1; } RelayOutcome::Failure => { - counter!("signet.builder.submit.relay_failures").increment(1); + crate::metrics::inc_relay_failures(); failures += 1; } RelayOutcome::Timeout => { - counter!("signet.builder.submit.relay_timeouts").increment(1); + crate::metrics::inc_relay_timeouts(); timeouts += 1; } } } if successes == 0 { - counter!("signet.builder.submit.all_relays_failed").increment(1); + crate::metrics::inc_all_relays_failed(); error!( failures, timeouts, n_relays, "all relay submissions failed - bundle may not land" ); } else { - counter!("signet.builder.submit.bundles_submitted").increment(1); + crate::metrics::inc_bundles_submitted(); if Instant::now() > self.deadline { - counter!("signet.builder.submit.deadline_missed").increment(1); + crate::metrics::inc_deadline_missed(); warn!(successes, failures, timeouts, "bundle accepted by relays AFTER deadline"); } else { - counter!("signet.builder.submit.deadline_met").increment(1); + crate::metrics::inc_deadline_met(); info!( successes, failures, timeouts, n_relays, "bundle submitted to relays within deadline" @@ -416,12 +416,12 @@ impl Submission { /// submission failed or timed out. async fn submit_to_pylon(&self) { if let Err(err) = self.pylon.post_blob_tx(self.block_tx.clone()).await { - counter!("signet.builder.pylon.submission_failures").increment(1); + crate::metrics::inc_pylon_submission_failures(); warn!(%err, "pylon submission failed"); return; } - counter!("signet.builder.pylon.sidecars_submitted").increment(1); + crate::metrics::inc_pylon_sidecars_submitted(); debug!("posted sidecar to pylon"); } } From 48890cfe79971fa3359f9bf9dae7549908c17ad9 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison <190532+Fraser999@users.noreply.github.com> Date: Thu, 9 Apr 2026 17:00:20 +0100 Subject: [PATCH 05/10] perf: add benchmarks for sim_round (#242) --- Cargo.lock | 506 +++++++++++++++++++++------------ Cargo.toml | 7 + benches/sim/bundles.rs | 111 ++++++++ benches/sim/complex_bundles.rs | 61 ++++ benches/sim/failed_bundles.rs | 53 ++++ benches/sim/fixture.rs | 429 ++++++++++++++++++++++++++++ benches/sim/main.rs | 22 ++ benches/sim/txs.rs | 55 ++++ src/test_utils/db.rs | 121 ++++---- src/test_utils/mod.rs | 2 +- 10 files changed, 1128 insertions(+), 239 deletions(-) create mode 100644 benches/sim/bundles.rs create mode 100644 benches/sim/complex_bundles.rs create mode 100644 benches/sim/failed_bundles.rs create mode 100644 benches/sim/fixture.rs create mode 100644 benches/sim/main.rs create mode 100644 benches/sim/txs.rs diff --git a/Cargo.lock b/Cargo.lock index eb52dc55..b22f708a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -89,6 +89,15 @@ dependencies = [ "alloc-no-stdlib", ] +[[package]] +name = "alloca" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7d05ea6aea7e9e64d25b9156ba2fee3fdd659e34e41063cd2fc7cd020d7f4" +dependencies = [ + "cc", +] + [[package]] name = "allocator-api2" version = "0.2.21" @@ -126,9 +135,9 @@ dependencies = [ [[package]] name = "alloy-chains" -version = "0.2.32" +version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9247f0a399ef71aeb68f497b2b8fb348014f742b50d3b83b1e00dfe1b7d64b3d" +checksum = "f4e9e31d834fe25fe991b8884e4b9f0e59db4a97d86e05d1464d6899c013cd62" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -488,7 +497,7 @@ dependencies = [ "foldhash 0.2.0", "getrandom 0.4.2", "hashbrown 0.16.1", - "indexmap 2.13.0", + "indexmap 2.13.1", "itoa", "k256", "keccak-asm", @@ -576,9 +585,9 @@ dependencies = [ [[package]] name = "alloy-rlp" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e93e50f64a77ad9c5470bf2ad0ca02f228da70c792a8f06634801e202579f35e" +checksum = "dc90b1e703d3c03f4ff7f48e82dd0bc1c8211ab7d079cd836a06fcfeb06651cb" dependencies = [ "alloy-rlp-derive", "arrayvec", @@ -587,9 +596,9 @@ dependencies = [ [[package]] name = "alloy-rlp-derive" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce8849c74c9ca0f5a03da1c865e3eb6f768df816e67dd3721a398a8a7e398011" +checksum = "f36834a5c0a2fa56e171bf256c34d70fca07d0c0031583edea1c4946b7889c9e" dependencies = [ "proc-macro2", "quote", @@ -881,7 +890,7 @@ dependencies = [ "alloy-sol-macro-input", "const-hex", "heck", - "indexmap 2.13.0", + "indexmap 2.13.1", "proc-macro-error2", "proc-macro2", "quote", @@ -1047,6 +1056,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + [[package]] name = "anstream" version = "1.0.0" @@ -1575,9 +1590,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.39.0" +version = "0.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa7e52a4c5c547c741610a2c6f123f3881e409b714cd27e6798ef020c514f0a" +checksum = "83a25cf98105baa966497416dbd42565ce3a8cf8dbfd59803ec9ad46f3126399" dependencies = [ "cc", "cmake", @@ -2153,24 +2168,24 @@ dependencies = [ [[package]] name = "boa_ast" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc119a5ad34c3f459062a96907f53358989b173d104258891bb74f95d93747e8" +checksum = "6339a700715bda376f5ea65c76e8fe8fc880930d8b0638cea68e7f3da6538e0a" dependencies = [ "bitflags 2.11.0", "boa_interner", "boa_macros", "boa_string", - "indexmap 2.13.0", + "indexmap 2.13.1", "num-bigint", "rustc-hash", ] [[package]] name = "boa_engine" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e637ec52ea66d76b0ca86180c259d6c7bb6e6a6e14b2f36b85099306d8b00cc3" +checksum = "1521be326f8a5c8887e95d4ce7f002917a002a23f7b93b9a6a2bf50ed4157824" dependencies = [ "aligned-vec", "arrayvec", @@ -2193,7 +2208,7 @@ dependencies = [ "futures-lite", "hashbrown 0.16.1", "icu_normalizer", - "indexmap 2.13.0", + "indexmap 2.13.1", "intrusive-collections", "itertools 0.14.0", "num-bigint", @@ -2220,9 +2235,9 @@ dependencies = [ [[package]] name = "boa_gc" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1179f690cbfcbe5364cceee5f1cb577265bb6f07b0be6f210aabe270adcf9da" +checksum = "17323a98cf2e631afacf1a6d659c1212c48a68bacfa85afab0a66ade80582e51" dependencies = [ "boa_macros", "boa_string", @@ -2232,14 +2247,14 @@ dependencies = [ [[package]] name = "boa_interner" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9626505d33dc63d349662437297df1d3afd9d5fc4a2b3ad34e5e1ce879a78848" +checksum = "20510b8b02bcde9b0a01cf34c0c308c56156503d1d91cdab4c8cfbd292b747ea" dependencies = [ "boa_gc", "boa_macros", "hashbrown 0.16.1", - "indexmap 2.13.0", + "indexmap 2.13.1", "once_cell", "phf", "rustc-hash", @@ -2248,9 +2263,9 @@ dependencies = [ [[package]] name = "boa_macros" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f36418a46544b152632c141b0a0b7a453cd69ca150caeef83aee9e2f4b48b7d" +checksum = "5822cb4f146d243060e588bc5a5f2e709683fdad3d7111f42c48e6b5c921d23d" dependencies = [ "cfg-if", "cow-utils", @@ -2262,9 +2277,9 @@ dependencies = [ [[package]] name = "boa_parser" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02f99bf5b684f0de946378fcfe5f38c3a0fbd51cbf83a0f39ff773a0e218541f" +checksum = "35bd957fa9fa93e3a001a8aba5a5cd40c2bbfde486378be4c4b472fd304aaddb" dependencies = [ "bitflags 2.11.0", "boa_ast", @@ -2280,9 +2295,9 @@ dependencies = [ [[package]] name = "boa_string" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45ce9d7aa5563a2e14eab111e2ae1a06a69a812f6c0c3d843196c9d03fbef440" +checksum = "ca2da1d7f4a76fd9040788a122f0d807910800a7b86f5952e9244848c36511de" dependencies = [ "fast-float2", "itoa", @@ -2365,6 +2380,7 @@ dependencies = [ "alloy-hardforks 0.4.7", "axum 0.7.9", "backon", + "criterion", "eyre", "futures-util", "git-version", @@ -2499,12 +2515,18 @@ checksum = "ef987d17b0a113becdd19d3d0022d04d7ef41f9efe4f3fb63ac44ba61df3ade9" dependencies = [ "camino", "cargo-platform", - "semver 1.0.27", + "semver 1.0.28", "serde", "serde_json", "thiserror 2.0.18", ] +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + [[package]] name = "castaway" version = "0.2.4" @@ -2516,9 +2538,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.57" +version = "1.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423" +checksum = "b7a4d3ec6524d28a329fc53654bbadc9bdd7b0431f5d65f1a56ffb28a1ee5283" dependencies = [ "find-msvc-tools", "jobserver", @@ -2567,6 +2589,33 @@ dependencies = [ "windows-link", ] +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "cipher" version = "0.4.4" @@ -2630,9 +2679,9 @@ checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "cmake" -version = "0.1.57" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" dependencies = [ "cc", ] @@ -2885,6 +2934,42 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "criterion" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "950046b2aa2492f9a536f5f4f9a3de7b9e2476e575e05bd6c333371add4d98f3" +dependencies = [ + "alloca", + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "itertools 0.13.0", + "num-traits", + "oorandom", + "page_size", + "plotters", + "rayon", + "regex", + "serde", + "serde_json", + "tinytemplate", + "tokio", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8d80a2f4f5b554395e47b5d8305bc3d27813bacb73493eb1001e8f76dae29ea" +dependencies = [ + "cast", + "itertools 0.13.0", +] + [[package]] name = "critical-section" version = "1.2.0" @@ -3720,9 +3805,9 @@ checksum = "f8eb564c5c7423d25c886fb561d1e4ee69f72354d16918afa32c08811f6b6a55" [[package]] name = "fastrand" -version = "2.3.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "fastrlp" @@ -4249,13 +4334,24 @@ dependencies = [ "futures-core", "futures-sink", "http 1.4.0", - "indexmap 2.13.0", + "indexmap 2.13.1", "slab", "tokio", "tokio-util", "tracing", ] +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -4506,9 +4602,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" dependencies = [ "atomic-waker", "bytes", @@ -4521,7 +4617,6 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "pin-utils", "smallvec", "tokio", "want", @@ -4639,9 +4734,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" dependencies = [ "displaydoc", "litemap", @@ -4698,9 +4793,9 @@ checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" [[package]] name = "icu_provider" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" dependencies = [ "displaydoc", "icu_locale_core", @@ -4814,9 +4909,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.13.0" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff" dependencies = [ "arbitrary", "equivalent", @@ -4836,9 +4931,9 @@ dependencies = [ [[package]] name = "init4-bin-base" -version = "0.18.0-rc.13" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "054d4b927194b1e73c85945a93254b19772fee2c627b190c9ae7c72da0b40eaf" +checksum = "f94c64278d765503d752783c7a1f1052f0d41cff51cd1fd258958d94a9a03010" dependencies = [ "alloy", "async-trait", @@ -4952,14 +5047,15 @@ dependencies = [ [[package]] name = "ipconfig" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d72a21f6a71a6c4c3160e095e8925861f5119dd26ef71acee1b9146f74f76c8" +checksum = "4d40460c0ce33d6ce4b0630ad68ff63d6661961c48b6dba35e5a4d81cfb48222" dependencies = [ "socket2", "widestring", + "windows-registry", + "windows-result", "windows-sys 0.61.2", - "winreg", ] [[package]] @@ -4970,9 +5066,9 @@ checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "iri-string" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8e7418f59cc01c88316161279a7f665217ae316b388e58a0d10e29f54f1e5eb" +checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" dependencies = [ "memchr", "serde", @@ -5073,10 +5169,12 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.91" +version = "0.3.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c" +checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9" dependencies = [ + "cfg-if", + "futures-util", "once_cell", "wasm-bindgen", ] @@ -5305,9 +5403,9 @@ dependencies = [ [[package]] name = "keccak-asm" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b646a74e746cd25045aa0fd42f4f7f78aa6d119380182c7e63a5593c4ab8df6f" +checksum = "fa468878266ad91431012b3e5ef1bf9b170eab22883503a318d46857afa4579a" dependencies = [ "digest 0.10.7", "sha3-asm", @@ -5347,9 +5445,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.183" +version = "0.2.184" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" +checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" [[package]] name = "libgit2-sys" @@ -5411,9 +5509,9 @@ dependencies = [ [[package]] name = "libredox" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a" +checksum = "7ddbf48fd451246b1f8c2610bd3b4ac0cc6e149d89832867093ab69a17194f08" dependencies = [ "bitflags 2.11.0", "libc", @@ -5439,9 +5537,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.25" +version = "1.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52f4c29e2a68ac30c9087e1b772dc9f44a2b66ed44edf2266cf2be9b03dafc1" +checksum = "fc3a226e576f50782b3305c5ccf458698f92798987f551c6a02efe8276721e22" dependencies = [ "cc", "libc", @@ -5451,9 +5549,9 @@ dependencies = [ [[package]] name = "line-clipping" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4de44e98ddbf09375cbf4d17714d18f39195f4f4894e8524501726fd9a8a4a" +checksum = "3f50e8f47623268b5407192d26876c4d7f89d686ca130fdc53bced4814cd29f8" dependencies = [ "bitflags 2.11.0", ] @@ -5482,9 +5580,9 @@ checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "litrs" @@ -5662,7 +5760,7 @@ dependencies = [ "hyper", "hyper-rustls", "hyper-util", - "indexmap 2.13.0", + "indexmap 2.13.1", "ipnet", "metrics", "metrics-util", @@ -5739,9 +5837,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", "log", @@ -5942,9 +6040,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" +checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" [[package]] name = "num-integer" @@ -6098,6 +6196,12 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +[[package]] +name = "oorandom" +version = "11.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" + [[package]] name = "op-alloy" version = "0.23.1" @@ -6253,9 +6357,9 @@ checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "openssl-src" -version = "300.5.5+3.5.5" +version = "300.6.0+3.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f1787d533e03597a7934fd0a765f0d28e94ecc5fb7789f8053b1e699a56f709" +checksum = "a8e8cbfd3a4a8c8f089147fd7aaa33cf8c7450c4d09f8f80698a0cf093abeff4" dependencies = [ "cc", ] @@ -6684,6 +6788,34 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" +[[package]] +name = "plotters" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" + +[[package]] +name = "plotters-svg" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" +dependencies = [ + "plotters-backend", +] + [[package]] name = "polyval" version = "0.6.2" @@ -6704,9 +6836,9 @@ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "potential_utf" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" dependencies = [ "zerovec", ] @@ -10264,9 +10396,9 @@ checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" [[package]] name = "rustc-hash" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" dependencies = [ "rand 0.8.5", ] @@ -10301,7 +10433,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver 1.0.27", + "semver 1.0.28", ] [[package]] @@ -10582,9 +10714,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" dependencies = [ "serde", "serde_core", @@ -10653,7 +10785,7 @@ version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.13.1", "itoa", "memchr", "serde", @@ -10674,9 +10806,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876ac351060d4f882bb1032b6369eb0aef79ad9df1ea8bc404874d8cc3d0cd98" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" dependencies = [ "serde_core", ] @@ -10703,7 +10835,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.13.0", + "indexmap 2.13.1", "schemars 0.9.0", "schemars 1.2.1", "serde_core", @@ -10768,9 +10900,9 @@ dependencies = [ [[package]] name = "sha3-asm" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b31139435f327c93c6038ed350ae4588e2c70a13d50599509fee6349967ba35a" +checksum = "59cbb88c189d6352cc8ae96a39d19c7ecad8f7330b29461187f2587fdc2988d5" dependencies = [ "cc", "cfg-if", @@ -10889,9 +11021,9 @@ dependencies = [ [[package]] name = "signet-bundle" -version = "0.16.0-rc.16" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9bd62b011781950089d31f742d90b3d62ba00f374db0dfe0d3ba1f1358b45c" +checksum = "dafb04a643cee29180ce8ae2067c81691417bc6ca6ac350146652a3f84576685" dependencies = [ "alloy", "serde", @@ -10905,9 +11037,9 @@ dependencies = [ [[package]] name = "signet-constants" -version = "0.16.0-rc.16" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9a4bb305179fc7461eb5cbee914344067ef03dccc267b20dfc1eaea9db1459" +checksum = "f4360f5a5706c7a9d6ddea3b3d8ab7721f7341c5242bc7f3857967f28090568d" dependencies = [ "alloy", "serde", @@ -10941,9 +11073,9 @@ dependencies = [ [[package]] name = "signet-evm" -version = "0.16.0-rc.16" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55caa1277f82e8854b9daf275d20deb8a78d57fa1babdcdeed8dd2976dfca18c" +checksum = "05cd7eb4c1a23f8b3742084283c690d04fda828f8c7aaa232b0d0a8d89861267" dependencies = [ "alloy", "bitflags 2.11.0", @@ -10958,9 +11090,9 @@ dependencies = [ [[package]] name = "signet-extract" -version = "0.16.0-rc.16" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a1e5c76e9c86d5e3cc8d321e41022cf2a6658e6346119fd4c29f894d8513a1c" +checksum = "6f23779af433acdbac5fb7a5e1489f5a1caab72f5337e2ee640c030a3bdcfb6b" dependencies = [ "alloy", "signet-types", @@ -10983,9 +11115,9 @@ dependencies = [ [[package]] name = "signet-journal" -version = "0.16.0-rc.16" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89519bce0c6d3143593cdab0501852741f66b641d048d65ec87cb095a803bd0a" +checksum = "f4c3c665f734b1cb68ee2a0263032fd171a3737927b4793d11377b8e917f05e7" dependencies = [ "alloy", "futures-util", @@ -11011,9 +11143,9 @@ dependencies = [ [[package]] name = "signet-sim" -version = "0.16.0-rc.16" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f6fe279a15c70233025257536f405c1f4c502525ef533c852f918933e0b5084" +checksum = "8002d4b0a83bdab1568d77de5790a70a1bd2c8d58bb43649299b7b319b5f67e4" dependencies = [ "alloy", "lru", @@ -11030,9 +11162,9 @@ dependencies = [ [[package]] name = "signet-tx-cache" -version = "0.16.0-rc.16" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95529a7f5a351bf5daee91a4c25a317fcb815b0fc4a26aa7099629d619eb51b" +checksum = "ba06dc92c72b877f042ba141c7ee553c68aab1c6e077a3ba1adb2eae17fdaff4" dependencies = [ "alloy", "futures-util", @@ -11049,9 +11181,9 @@ dependencies = [ [[package]] name = "signet-types" -version = "0.16.0-rc.16" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10dff727bb17387f043999bca9dafef6c0ba8e10e8d7c5f5fd8e53b708ea959" +checksum = "9ad0d5db88367e5f2433e1cdd74017cf399dd985906be905032cba1ad314c30f" dependencies = [ "alloy", "chrono", @@ -11063,9 +11195,9 @@ dependencies = [ [[package]] name = "signet-zenith" -version = "0.16.0-rc.16" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c96ff57c3b9d32a452d96cbf0bd852c987688721c84877ec6218e1ceed87ed" +checksum = "4cafc152356fad0f4461af607af6e4151a3a577b55007a60ce5587969127a6e5" dependencies = [ "alloy", "alloy-core", @@ -11075,9 +11207,9 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" [[package]] name = "simple_asn1" @@ -11348,9 +11480,9 @@ dependencies = [ [[package]] name = "thin-vec" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "144f754d318415ac792f9d69fc87abbbfc043ce2ef041c60f16ad828f638717d" +checksum = "da322882471314edc77fa5232c587bcb87c9df52bfd0d7d4826f8868ead61899" [[package]] name = "thiserror" @@ -11449,7 +11581,6 @@ checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa", - "js-sys", "libc", "num-conv", "num_threads", @@ -11477,15 +11608,25 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" dependencies = [ "displaydoc", "serde_core", "zerovec", ] +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "tinyvec" version = "1.11.0" @@ -11503,9 +11644,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.50.0" +version = "1.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" +checksum = "f66bf9585cda4b724d3e78ab34b73fb2bbaba9011b9bfdf69dc836382ea13b8c" dependencies = [ "bytes", "libc", @@ -11520,9 +11661,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.6.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", @@ -11610,7 +11751,7 @@ version = "0.9.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.13.1", "serde_core", "serde_spanned", "toml_datetime 0.7.5+spec-1.1.0", @@ -11630,39 +11771,39 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "1.1.0+spec-1.1.0" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97251a7c317e03ad83774a8752a7e81fb6067740609f75ea2b585b569a59198f" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.25.8+spec-1.1.0" +version = "0.25.11+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16bff38f1d86c47f9ff0647e6838d7bb362522bdf44006c7068c2b1e606f1f3c" +checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" dependencies = [ - "indexmap 2.13.0", - "toml_datetime 1.1.0+spec-1.1.0", + "indexmap 2.13.1", + "toml_datetime 1.1.1+spec-1.1.0", "toml_parser", - "winnow 1.0.0", + "winnow 1.0.1", ] [[package]] name = "toml_parser" -version = "1.1.0+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2334f11ee363607eb04df9b8fc8a13ca1715a72ba8662a26ac285c98aabb4011" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow 1.0.0", + "winnow 1.0.1", ] [[package]] name = "toml_writer" -version = "1.1.0+spec-1.1.0" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d282ade6016312faf3e41e57ebbba0c073e4056dab1232ab1cb624199648f8ed" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" [[package]] name = "tonic" @@ -11731,7 +11872,7 @@ dependencies = [ "futures-core", "futures-util", "hdrhistogram", - "indexmap 2.13.0", + "indexmap 2.13.1", "pin-project-lite", "slab", "sync_wrapper", @@ -11991,9 +12132,9 @@ dependencies = [ [[package]] name = "trevm" -version = "0.34.1" +version = "0.34.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904819c7508930edfc3c1ea7e47871aa8c6a4e0c913de5c56b7d73006845c5ae" +checksum = "bb4a80f4985c7b8aefee9fe1ba48b6b37c617f8b5ffd88f67adbfef78d77c894" dependencies = [ "alloy", "dashmap", @@ -12107,9 +12248,9 @@ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-segmentation" -version = "1.12.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" [[package]] name = "unicode-truncate" @@ -12201,9 +12342,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.22.0" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37" +checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" dependencies = [ "getrandom 0.4.2", "js-sys", @@ -12330,9 +12471,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.114" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e" +checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0" dependencies = [ "cfg-if", "once_cell", @@ -12343,23 +12484,19 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.64" +version = "0.4.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9c5522b3a28661442748e09d40924dfb9ca614b21c00d3fd135720e48b67db8" +checksum = "03623de6905b7206edd0a75f69f747f134b7f0a2323392d664448bf2d3c5d87e" dependencies = [ - "cfg-if", - "futures-util", "js-sys", - "once_cell", "wasm-bindgen", - "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.114" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6" +checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -12367,9 +12504,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.114" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3" +checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2" dependencies = [ "bumpalo", "proc-macro2", @@ -12380,9 +12517,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.114" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16" +checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b" dependencies = [ "unicode-ident", ] @@ -12404,7 +12541,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" dependencies = [ "anyhow", - "indexmap 2.13.0", + "indexmap 2.13.1", "wasm-encoder", "wasmparser", ] @@ -12430,8 +12567,8 @@ checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ "bitflags 2.11.0", "hashbrown 0.15.5", - "indexmap 2.13.0", - "semver 1.0.27", + "indexmap 2.13.1", + "semver 1.0.28", ] [[package]] @@ -12450,9 +12587,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.91" +version = "0.3.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9" +checksum = "cd70027e39b12f0849461e08ffc50b9cd7688d942c1c8e3c7b22273236b4dd0a" dependencies = [ "js-sys", "wasm-bindgen", @@ -12904,23 +13041,13 @@ dependencies = [ [[package]] name = "winnow" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a90e88e4667264a994d34e6d1ab2d26d398dcdca8b7f52bec8668957517fc7d8" +checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.55.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb5a765337c50e9ec252c2069be9bf91c7df47afb103b642ba3a53bf8101be97" -dependencies = [ - "cfg-if", - "windows-sys 0.59.0", -] - [[package]] name = "wit-bindgen" version = "0.51.0" @@ -12949,7 +13076,7 @@ checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" dependencies = [ "anyhow", "heck", - "indexmap 2.13.0", + "indexmap 2.13.1", "prettyplease", "syn 2.0.117", "wasm-metadata", @@ -12980,7 +13107,7 @@ checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", "bitflags 2.11.0", - "indexmap 2.13.0", + "indexmap 2.13.1", "log", "serde", "serde_derive", @@ -12999,9 +13126,9 @@ checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" dependencies = [ "anyhow", "id-arena", - "indexmap 2.13.0", + "indexmap 2.13.1", "log", - "semver 1.0.27", + "semver 1.0.28", "serde", "serde_derive", "serde_json", @@ -13017,9 +13144,9 @@ checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" [[package]] name = "writeable" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "ws_stream_wasm" @@ -13079,9 +13206,9 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "yoke" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -13090,9 +13217,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", @@ -13102,18 +13229,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.47" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efbb2a062be311f2ba113ce66f697a4dc589f85e78a4aea276200804cea0ed87" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.47" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e8bc7269b54418e7aeeef514aa68f8690b8c0489a06b0136e5f57c4c5ccab89" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", @@ -13122,18 +13249,18 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", @@ -13163,20 +13290,21 @@ dependencies = [ [[package]] name = "zerotrie" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" dependencies = [ "displaydoc", "yoke", "zerofrom", + "zerovec", ] [[package]] name = "zerovec" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ "serde", "yoke", @@ -13186,9 +13314,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 16daabb2..f2e39007 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -66,8 +66,15 @@ url = "2.5.4" [dev-dependencies] alloy-hardforks = "0.4.0" alloy-chains = "0.2" +criterion = { version = "0.8.2", features = ["async_tokio"] } signet-bundle = "0.16.0-rc.11" +[[bench]] +name = "sim" +path = "benches/sim/main.rs" +harness = false +required-features = ["test-utils"] + # comment / uncomment for local dev # [patch.crates-io] # signet-constants = { path = "../signet-sdk/crates/constants" } diff --git a/benches/sim/bundles.rs b/benches/sim/bundles.rs new file mode 100644 index 00000000..e065126c --- /dev/null +++ b/benches/sim/bundles.rs @@ -0,0 +1,111 @@ +//! Benchmarks for bundle simulation: varying counts, DB latency, and concurrency. + +use crate::fixture::{Fixture, LATENCIES, set_up_bundle_sim, set_up_sender_distribution_sim}; +use builder::test_utils::setup_test_config; +use criterion::{BatchSize, Bencher, BenchmarkId, Criterion}; +use std::time::Duration; + +pub fn bench_bundle_counts(criterion: &mut Criterion) { + const LATENCY: Duration = Duration::ZERO; + const CONCURRENCY: usize = 4; + + setup_test_config(); + let runtime = tokio::runtime::Runtime::new().unwrap(); + + let mut group = criterion.benchmark_group("sim_varying_simple_bundle_counts_no_db_latency"); + group.sample_size(10); + + for bundle_count in [1, 10, 100, 1000] { + group.bench_with_input( + BenchmarkId::new("bundle_count", bundle_count), + &bundle_count, + |bench: &mut Bencher, &bundle_count| { + bench.to_async(&runtime).iter_batched( + || set_up_bundle_sim(bundle_count, LATENCY, CONCURRENCY), + Fixture::run, + BatchSize::PerIteration, + ); + }, + ); + } + group.finish(); +} + +pub fn bench_bundle_db_latency(criterion: &mut Criterion) { + const BUNDLE_COUNT: usize = 10; + const CONCURRENCY: usize = 4; + + setup_test_config(); + let runtime = tokio::runtime::Runtime::new().unwrap(); + + let mut group = + criterion.benchmark_group(format!("sim_{BUNDLE_COUNT}_simple_bundles_varying_db_latency")); + group.sample_size(10); + + for (label, latency) in LATENCIES { + group.bench_with_input(BenchmarkId::new("latency", label), &latency, |bench, &lat| { + bench.to_async(&runtime).iter_batched( + || set_up_bundle_sim(BUNDLE_COUNT, lat, CONCURRENCY), + Fixture::run, + BatchSize::PerIteration, + ); + }); + } + group.finish(); +} + +pub fn bench_bundle_concurrency(criterion: &mut Criterion) { + const BUNDLE_COUNT: usize = 100; + const LATENCY: Duration = Duration::ZERO; + + setup_test_config(); + let runtime = tokio::runtime::Runtime::new().unwrap(); + + let mut group = criterion.benchmark_group(format!( + "sim_{BUNDLE_COUNT}_simple_bundles_no_db_latency_varying_concurrency" + )); + group.sample_size(10); + + for concurrency in [1, 2, 4, 8, 16] { + group.bench_with_input( + BenchmarkId::new("thread_count", concurrency), + &concurrency, + |bench, &conc| { + bench.to_async(&runtime).iter_batched( + || set_up_bundle_sim(BUNDLE_COUNT, LATENCY, conc), + Fixture::run, + BatchSize::PerIteration, + ); + }, + ); + } + group.finish(); +} + +pub fn bench_bundle_sender_distribution(criterion: &mut Criterion) { + const BUNDLE_COUNT: usize = 100; + const CONCURRENCY: usize = 4; + + setup_test_config(); + let runtime = tokio::runtime::Runtime::new().unwrap(); + + let mut group = criterion.benchmark_group(format!( + "sim_{BUNDLE_COUNT}_simple_bundles_no_db_latency_varying_sender_count" + )); + group.sample_size(10); + + for num_senders in [1, 5, 20, 100] { + group.bench_with_input( + BenchmarkId::new("sender_count", num_senders), + &num_senders, + |bench, &senders| { + bench.to_async(&runtime).iter_batched( + || set_up_sender_distribution_sim(BUNDLE_COUNT, senders, CONCURRENCY), + Fixture::run, + BatchSize::PerIteration, + ); + }, + ); + } + group.finish(); +} diff --git a/benches/sim/complex_bundles.rs b/benches/sim/complex_bundles.rs new file mode 100644 index 00000000..24ba2653 --- /dev/null +++ b/benches/sim/complex_bundles.rs @@ -0,0 +1,61 @@ +//! Benchmarks for complex bundle shapes: multi-tx bundles and bundles with host transactions. + +use crate::fixture::{Fixture, set_up_host_tx_bundle_sim, set_up_multi_tx_bundle_sim}; +use builder::test_utils::setup_test_config; +use criterion::{BatchSize, BenchmarkId, Criterion}; + +pub fn bench_multi_tx_bundles(criterion: &mut Criterion) { + const BUNDLE_COUNT: usize = 100; + const CONCURRENCY: usize = 4; + + setup_test_config(); + let runtime = tokio::runtime::Runtime::new().unwrap(); + + let mut group = criterion.benchmark_group(format!( + "sim_{BUNDLE_COUNT}_bundles_no_db_latency_varying_txs_per_bundle" + )); + group.sample_size(10); + + for txs_per_bundle in [1, 3, 5, 10] { + group.bench_with_input( + BenchmarkId::new("txs_per_bundle", txs_per_bundle), + &txs_per_bundle, + |bench, &tpb| { + bench.to_async(&runtime).iter_batched( + || set_up_multi_tx_bundle_sim(BUNDLE_COUNT, tpb, CONCURRENCY), + Fixture::run, + BatchSize::PerIteration, + ); + }, + ); + } + group.finish(); +} + +pub fn bench_host_tx_bundles(criterion: &mut Criterion) { + const BUNDLE_COUNT: usize = 100; + const CONCURRENCY: usize = 4; + + setup_test_config(); + let runtime = tokio::runtime::Runtime::new().unwrap(); + + let mut group = criterion.benchmark_group(format!( + "sim_{BUNDLE_COUNT}_bundles_no_db_latency_varying_host_txs_per_bundle" + )); + group.sample_size(10); + + for host_txs in [0, 1, 3, 5] { + group.bench_with_input( + BenchmarkId::new("host_txs_per_bundle", host_txs), + &host_txs, + |bench, &htpb| { + bench.to_async(&runtime).iter_batched( + || set_up_host_tx_bundle_sim(BUNDLE_COUNT, htpb, CONCURRENCY), + Fixture::run, + BatchSize::PerIteration, + ); + }, + ); + } + group.finish(); +} diff --git a/benches/sim/failed_bundles.rs b/benches/sim/failed_bundles.rs new file mode 100644 index 00000000..324adfac --- /dev/null +++ b/benches/sim/failed_bundles.rs @@ -0,0 +1,53 @@ +//! Benchmarks for bundles that fail: preflight validation failures and EVM execution reverts. + +use crate::fixture::{ + Fixture, LATENCIES, set_up_execution_failure_sim, set_up_preflight_failure_sim, +}; +use builder::test_utils::setup_test_config; +use criterion::{BatchSize, BenchmarkId, Criterion}; + +pub fn bench_preflight_failure(criterion: &mut Criterion) { + const COUNT: usize = 10; + const CONCURRENCY: usize = 4; + + setup_test_config(); + let runtime = tokio::runtime::Runtime::new().unwrap(); + + let mut group = + criterion.benchmark_group(format!("sim_{COUNT}_simple_bundles_all_failing_preflight")); + group.sample_size(10); + + for (label, latency) in LATENCIES { + group.bench_with_input(BenchmarkId::new("latency", label), &latency, |bench, &lat| { + bench.to_async(&runtime).iter_batched( + || set_up_preflight_failure_sim(COUNT, lat, CONCURRENCY), + Fixture::run, + BatchSize::PerIteration, + ); + }); + } + group.finish(); +} + +pub fn bench_execution_failure(criterion: &mut Criterion) { + const COUNT: usize = 10; + const CONCURRENCY: usize = 4; + + setup_test_config(); + let runtime = tokio::runtime::Runtime::new().unwrap(); + + let mut group = + criterion.benchmark_group(format!("sim_{COUNT}_simple_bundles_all_failing_execution")); + group.sample_size(10); + + for (label, latency) in LATENCIES { + group.bench_with_input(BenchmarkId::new("latency", label), &latency, |bench, &lat| { + bench.to_async(&runtime).iter_batched( + || set_up_execution_failure_sim(COUNT, lat, CONCURRENCY), + Fixture::run, + BatchSize::PerIteration, + ); + }); + } + group.finish(); +} diff --git a/benches/sim/fixture.rs b/benches/sim/fixture.rs new file mode 100644 index 00000000..472dce26 --- /dev/null +++ b/benches/sim/fixture.rs @@ -0,0 +1,429 @@ +//! Shared fixtures and setup functions for simulation benchmarks. + +use alloy::{ + primitives::{Address, Bytes, U256}, + serde::OtherFields, + signers::local::PrivateKeySigner, +}; +use builder::test_utils::{ + DEFAULT_BALANCE, DEFAULT_BASEFEE, TestDb, TestDbBuilder, TestHostEnv, TestRollupEnv, + TestSimEnvBuilder, TestStateSource, create_call_tx, create_transfer_tx, + scenarios_test_block_env, +}; +use signet_bundle::RecoveredBundle; +use signet_sim::{SharedSimEnv, SimCache}; +use std::time::Duration; +use tokio::time::Instant; +use trevm::revm::bytecode::Bytecode; +use trevm::revm::inspector::NoOpInspector; + +pub const BLOCK_NUMBER: u64 = 100; +pub const BLOCK_TIMESTAMP: u64 = 1_700_000_000; +pub const RU_CHAIN_ID: u64 = 88888; +pub const DEFAULT_PRIORITY_FEE: u128 = 10_000_000_000; +pub const MAX_GAS: u64 = 3_000_000_000; +pub const MAX_HOST_GAS: u64 = 24_000_000; +pub const REVERTING_CONTRACT: Address = Address::repeat_byte(0xBB); +/// Latency values based on real-world RPC provider benchmarks: +/// - 0ms: baseline, no network simulation +/// - 50ms: good provider, same-region (p50 for top providers) +/// - 200ms: cross-region or average provider +pub const LATENCIES: [(&str, Duration); 3] = [ + ("0ms", Duration::ZERO), + ("50ms", Duration::from_millis(50)), + ("200ms", Duration::from_millis(200)), +]; + +/// Type alias for the shared simulation environment used in benchmarks. +pub type BenchSimEnv = SharedSimEnv; + +/// Everything needed to run a benchmark iteration: the simulation environment +/// plus state sources for preflight validity checks. +pub struct Fixture { + env: BenchSimEnv, + rollup_source: TestStateSource, + host_source: TestStateSource, +} + +impl Fixture { + fn new(envs: Envs, concurrency: usize, cache: SimCache) -> Self { + let Envs { rollup_env, host_env, rollup_source, host_source } = envs; + // Set a deadline far in the future so that `sim_round()` never short-circuits. + let finish_by = Instant::now() + Duration::from_secs(3600); + let env = SharedSimEnv::new(rollup_env, host_env, finish_by, concurrency, cache); + Fixture { env, rollup_source, host_source } + } + + /// Drain all items from the sim env via repeated `sim_round()` calls. + pub async fn run(self) { + let Fixture { mut env, rollup_source, host_source } = self; + while env.sim_round(MAX_GAS, MAX_HOST_GAS, &rollup_source, &host_source).await.is_some() {} + } +} + +struct Envs { + rollup_env: TestRollupEnv, + host_env: TestHostEnv, + rollup_source: TestStateSource, + host_source: TestStateSource, +} + +impl Envs { + /// Build simulation environments and state sources from a shared database. + fn new(db: TestDb) -> Self { + let block_env = + scenarios_test_block_env(BLOCK_NUMBER, DEFAULT_BASEFEE, BLOCK_TIMESTAMP, MAX_GAS); + + let sim_env = TestSimEnvBuilder::new() + .with_rollup_db(db.clone()) + .with_host_db(db.clone()) + .with_block_env(block_env); + + let rollup_source = TestStateSource::new(db.clone()); + let host_source = TestStateSource::new(db); + let (rollup_env, host_env) = sim_env.build(); + Envs { rollup_env, host_env, rollup_source, host_source } + } +} + +/// Generate `count` random funded signers. +fn generate_signers(count: usize) -> Vec { + (0..count).map(|_| PrivateKeySigner::random()).collect() +} + +/// Create a `TestDbBuilder` with accounts funded from the given signers. +fn fund_accounts(signers: &[PrivateKeySigner]) -> TestDbBuilder { + let balance = U256::from(DEFAULT_BALANCE); + let mut builder = TestDbBuilder::new(); + for signer in signers { + builder = builder.with_account(signer.address(), balance, 0); + } + builder +} + +/// Create a `RecoveredBundle` with one transfer transaction. +fn make_bundle( + signer: &PrivateKeySigner, + to: Address, + nonce: u64, + uuid: String, + max_priority_fee: u128, +) -> RecoveredBundle { + let tx = + create_transfer_tx(signer, to, U256::from(1_000u64), nonce, RU_CHAIN_ID, max_priority_fee) + .unwrap(); + + RecoveredBundle::new_unchecked( + vec![tx], + vec![], + BLOCK_NUMBER, + Some(BLOCK_TIMESTAMP - 100), + Some(BLOCK_TIMESTAMP + 100), + vec![], + Some(uuid), + vec![], + None, + None, + vec![], + OtherFields::default(), + ) +} + +/// Build a [`SharedSimEnv`] and state sources with bundles in the cache. +/// +/// All databases use the same latency to model production RPC round-trips +/// (both simulation environments and preflight state sources hit the RPC). +pub fn set_up_bundle_sim(count: usize, latency: Duration, concurrency: usize) -> Fixture { + let signers = generate_signers(count); + let db = fund_accounts(&signers).with_latency(latency).build(); + let envs = Envs::new(db); + + let cache = SimCache::with_capacity(count); + let recipient = Address::repeat_byte(0xAA); + let bundles: Vec = signers + .iter() + .enumerate() + .map(|(idx, signer)| { + make_bundle(signer, recipient, 0, format!("bench-{idx}"), DEFAULT_PRIORITY_FEE) + }) + .collect(); + cache.add_bundles(bundles, DEFAULT_BASEFEE); + + Fixture::new(envs, concurrency, cache) +} + +/// Build a [`SharedSimEnv`] and state sources with standalone txs in the cache. +pub fn set_up_tx_sim(count: usize, latency: Duration, concurrency: usize) -> Fixture { + let signers = generate_signers(count); + let db = fund_accounts(&signers).with_latency(latency).build(); + let envs = Envs::new(db); + + let cache = SimCache::with_capacity(count); + let recipient = Address::repeat_byte(0xAA); + for signer in &signers { + let tx = create_transfer_tx( + signer, + recipient, + U256::from(1_000u64), + 0, + RU_CHAIN_ID, + DEFAULT_PRIORITY_FEE, + ) + .unwrap(); + cache.add_tx(tx, DEFAULT_BASEFEE); + } + + Fixture::new(envs, concurrency, cache) +} + +/// Build a [`SharedSimEnv`] with bundles that all fail preflight validation. +/// +/// Accounts are funded with nonce 1, but all bundles use nonce 0. Since +/// `state_nonce > tx_nonce`, every item is marked `Never` and removed from the +/// cache on the first `sim_round()` call. +pub fn set_up_preflight_failure_sim( + count: usize, + latency: Duration, + concurrency: usize, +) -> Fixture { + let signers = generate_signers(count); + + let balance = U256::from(DEFAULT_BALANCE); + let mut db_builder = TestDbBuilder::new(); + for signer in &signers { + db_builder = db_builder.with_account(signer.address(), balance, 1); + } + let db = db_builder.with_latency(latency).build(); + let envs = Envs::new(db); + + let cache = SimCache::with_capacity(count); + let recipient = Address::repeat_byte(0xAA); + let bundles: Vec = signers + .iter() + .enumerate() + .map(|(idx, signer)| { + make_bundle(signer, recipient, 0, format!("bench-{idx}"), DEFAULT_PRIORITY_FEE) + }) + .collect(); + cache.add_bundles(bundles, DEFAULT_BASEFEE); + + Fixture::new(envs, concurrency, cache) +} + +/// Build a [`SharedSimEnv`] with bundles that pass preflight but revert during +/// EVM execution. +/// +/// A contract at [`REVERTING_CONTRACT`] contains `PUSH0 PUSH0 REVERT` (always +/// reverts with empty data). All bundles call this contract, so they pass +/// preflight (valid nonce + sufficient balance) but fail during simulation. +pub fn set_up_execution_failure_sim( + count: usize, + latency: Duration, + concurrency: usize, +) -> Fixture { + let signers = generate_signers(count); + + // PUSH0 PUSH0 REVERT — always reverts with empty returndata. + let revert_bytecode = Bytecode::new_raw(Bytes::from_static(&[0x5F, 0x5F, 0xFD])); + + let balance = U256::from(DEFAULT_BALANCE); + let mut db_builder = TestDbBuilder::new().with_contract(REVERTING_CONTRACT, revert_bytecode); + for signer in &signers { + db_builder = db_builder.with_account(signer.address(), balance, 0); + } + let db = db_builder.with_latency(latency).build(); + let envs = Envs::new(db); + + let cache = SimCache::with_capacity(count); + let bundles: Vec = signers + .iter() + .enumerate() + .map(|(idx, signer)| { + let tx = create_call_tx( + signer, + REVERTING_CONTRACT, + Bytes::new(), + U256::ZERO, + 0, + RU_CHAIN_ID, + 50_000, + DEFAULT_PRIORITY_FEE, + ) + .unwrap(); + RecoveredBundle::new_unchecked( + vec![tx], + vec![], + BLOCK_NUMBER, + Some(BLOCK_TIMESTAMP - 100), + Some(BLOCK_TIMESTAMP + 100), + vec![], + Some(format!("bench-{idx}")), + vec![], + None, + None, + vec![], + OtherFields::default(), + ) + }) + .collect(); + cache.add_bundles(bundles, DEFAULT_BASEFEE); + + Fixture::new(envs, concurrency, cache) +} + +/// Build a [`SharedSimEnv`] with `bundle_count` bundles spread across `num_senders` signers. +/// +/// Each signer sends `bundle_count / num_senders` bundles with incrementing nonces. +pub fn set_up_sender_distribution_sim( + bundle_count: usize, + num_senders: usize, + concurrency: usize, +) -> Fixture { + let signers = generate_signers(num_senders); + let bundles_per_sender = bundle_count / num_senders; + + let balance = U256::from(DEFAULT_BALANCE); + let mut db_builder = TestDbBuilder::new(); + for signer in &signers { + db_builder = db_builder.with_account(signer.address(), balance, 0); + } + let db = db_builder.build(); + let envs = Envs::new(db); + + let cache = SimCache::with_capacity(bundle_count); + let recipient = Address::repeat_byte(0xAA); + let bundles: Vec = signers + .iter() + .enumerate() + .flat_map(|(sender_idx, signer)| { + (0..bundles_per_sender).map(move |nonce| { + make_bundle( + signer, + recipient, + nonce as u64, + format!("bench-{sender_idx}-{nonce}"), + DEFAULT_PRIORITY_FEE, + ) + }) + }) + .collect(); + cache.add_bundles(bundles, DEFAULT_BASEFEE); + + Fixture::new(envs, concurrency, cache) +} + +/// Build a [`SharedSimEnv`] with bundles containing multiple rollup transactions each. +/// +/// Each bundle has `txs_per_bundle` transfer transactions from the same sender with +/// incrementing nonces. This measures the cost of simulating larger bundles where +/// all transactions must succeed atomically. +pub fn set_up_multi_tx_bundle_sim( + bundle_count: usize, + txs_per_bundle: usize, + concurrency: usize, +) -> Fixture { + let signers = generate_signers(bundle_count); + let db = fund_accounts(&signers).build(); + let envs = Envs::new(db); + + let cache = SimCache::with_capacity(bundle_count); + let recipient = Address::repeat_byte(0xAA); + let bundles: Vec = signers + .iter() + .enumerate() + .map(|(idx, signer)| { + let txs: Vec<_> = (0..txs_per_bundle) + .map(|nonce| { + create_transfer_tx( + signer, + recipient, + U256::from(1_000u64), + nonce as u64, + RU_CHAIN_ID, + DEFAULT_PRIORITY_FEE, + ) + .unwrap() + }) + .collect(); + RecoveredBundle::new_unchecked( + txs, + vec![], + BLOCK_NUMBER, + Some(BLOCK_TIMESTAMP - 100), + Some(BLOCK_TIMESTAMP + 100), + vec![], + Some(format!("bench-{idx}")), + vec![], + None, + None, + vec![], + OtherFields::default(), + ) + }) + .collect(); + cache.add_bundles(bundles, DEFAULT_BASEFEE); + + Fixture::new(envs, concurrency, cache) +} + +/// Build a [`SharedSimEnv`] with bundles that include host-chain transactions. +/// +/// Each bundle has one rollup transfer plus `host_txs_per_bundle` host-chain transfers. +/// This measures the overhead of bundles that carry cross-chain transactions. +pub fn set_up_host_tx_bundle_sim( + bundle_count: usize, + host_txs_per_bundle: usize, + concurrency: usize, +) -> Fixture { + let signers = generate_signers(bundle_count); + let db = fund_accounts(&signers).build(); + let envs = Envs::new(db); + + let cache = SimCache::with_capacity(bundle_count); + let recipient = Address::repeat_byte(0xAA); + let bundles: Vec = signers + .iter() + .enumerate() + .map(|(idx, signer)| { + let rollup_tx = create_transfer_tx( + signer, + recipient, + U256::from(1_000u64), + 0, + RU_CHAIN_ID, + DEFAULT_PRIORITY_FEE, + ) + .unwrap(); + let host_txs: Vec<_> = (0..host_txs_per_bundle) + .map(|nonce| { + create_transfer_tx( + signer, + recipient, + U256::from(1_000u64), + (nonce + 1) as u64, + RU_CHAIN_ID, + DEFAULT_PRIORITY_FEE, + ) + .unwrap() + }) + .collect(); + RecoveredBundle::new_unchecked( + vec![rollup_tx], + host_txs, + BLOCK_NUMBER, + Some(BLOCK_TIMESTAMP - 100), + Some(BLOCK_TIMESTAMP + 100), + vec![], + Some(format!("bench-{idx}")), + vec![], + None, + None, + vec![], + OtherFields::default(), + ) + }) + .collect(); + cache.add_bundles(bundles, DEFAULT_BASEFEE); + + Fixture::new(envs, concurrency, cache) +} diff --git a/benches/sim/main.rs b/benches/sim/main.rs new file mode 100644 index 00000000..01aba87f --- /dev/null +++ b/benches/sim/main.rs @@ -0,0 +1,22 @@ +mod bundles; +mod complex_bundles; +mod failed_bundles; +mod fixture; +mod txs; + +use criterion::{criterion_group, criterion_main}; + +criterion_group!( + benches, + bundles::bench_bundle_counts, + bundles::bench_bundle_db_latency, + bundles::bench_bundle_concurrency, + bundles::bench_bundle_sender_distribution, + complex_bundles::bench_multi_tx_bundles, + complex_bundles::bench_host_tx_bundles, + txs::bench_tx_counts, + txs::bench_tx_db_latency, + failed_bundles::bench_preflight_failure, + failed_bundles::bench_execution_failure, +); +criterion_main!(benches); diff --git a/benches/sim/txs.rs b/benches/sim/txs.rs new file mode 100644 index 00000000..d124818c --- /dev/null +++ b/benches/sim/txs.rs @@ -0,0 +1,55 @@ +//! Benchmarks for standalone transaction simulation: varying counts and DB latency. + +use crate::fixture::{Fixture, LATENCIES, set_up_tx_sim}; +use builder::test_utils::setup_test_config; +use criterion::{BatchSize, Bencher, BenchmarkId, Criterion}; +use std::time::Duration; + +pub fn bench_tx_counts(criterion: &mut Criterion) { + const LATENCY: Duration = Duration::ZERO; + const CONCURRENCY: usize = 4; + + setup_test_config(); + let runtime = tokio::runtime::Runtime::new().unwrap(); + + let mut group = criterion.benchmark_group("sim_varying_tx_counts_with_no_db_latency"); + group.sample_size(10); + + for tx_count in [1, 10, 100, 1000] { + group.bench_with_input( + BenchmarkId::new("tx_count", tx_count), + &tx_count, + |bench: &mut Bencher, &tx_count| { + bench.to_async(&runtime).iter_batched( + || set_up_tx_sim(tx_count, LATENCY, CONCURRENCY), + Fixture::run, + BatchSize::PerIteration, + ); + }, + ); + } + group.finish(); +} + +pub fn bench_tx_db_latency(criterion: &mut Criterion) { + const TX_COUNT: usize = 10; + const CONCURRENCY: usize = 4; + + setup_test_config(); + let runtime = tokio::runtime::Runtime::new().unwrap(); + + let mut group = + criterion.benchmark_group(format!("sim_{TX_COUNT}_txs_with_varying_db_latency")); + group.sample_size(10); + + for (label, latency) in LATENCIES { + group.bench_with_input(BenchmarkId::new("latency", label), &latency, |bench, &lat| { + bench.to_async(&runtime).iter_batched( + || set_up_tx_sim(TX_COUNT, lat, CONCURRENCY), + Fixture::run, + BatchSize::PerIteration, + ); + }); + } + group.finish(); +} diff --git a/src/test_utils/db.rs b/src/test_utils/db.rs index ef6ac1f6..90bfe6ef 100644 --- a/src/test_utils/db.rs +++ b/src/test_utils/db.rs @@ -4,17 +4,20 @@ use alloy::primitives::{Address, B256, U256}; use signet_sim::{AcctInfo, StateSource}; +use std::time::Duration; use trevm::revm::{ + bytecode::Bytecode, database::{CacheDB, EmptyDB}, database_interface::DatabaseRef, + primitives::{StorageKey, StorageValue}, state::AccountInfo, }; -/// In-memory database for testing (no network access required). -/// This is a type alias for revm's `CacheDB`, which stores all -/// blockchain state in memory. It implements `DatabaseRef` and can be used -/// with `RollupEnv` and `HostEnv` for offline simulation testing. -pub type TestDb = CacheDB; +/// Mirrors the production `CacheDB` stack: the outer [`CacheDB`] starts +/// empty and caches on the mutable `Database` path, while the inner [`LatencyDb`] +/// holds all state in-memory and applies configurable sleep on every read to +/// simulate RPC round-trip cost. +pub type TestDb = CacheDB; /// A [`StateSource`] for testing backed by an in-memory [`TestDb`]. /// Returns actual account info (nonce, balance) from the database, @@ -52,7 +55,7 @@ impl StateSource for TestStateSource { /// before running simulations. #[derive(Debug)] pub struct TestDbBuilder { - db: TestDb, + latency_db: LatencyDb, } impl Default for TestDbBuilder { @@ -64,7 +67,7 @@ impl Default for TestDbBuilder { impl TestDbBuilder { /// Create a new empty test database builder. pub fn new() -> Self { - Self { db: CacheDB::new(EmptyDB::default()) } + Self { latency_db: LatencyDb::default() } } /// Add an account with the specified balance and nonce. @@ -75,7 +78,9 @@ impl TestDbBuilder { /// * `balance` - The account balance in wei /// * `nonce` - The account nonce (transaction count) pub fn with_account(mut self, address: Address, balance: U256, nonce: u64) -> Self { - self.db.insert_account_info(address, AccountInfo { balance, nonce, ..Default::default() }); + self.latency_db + .in_mem_db + .insert_account_info(address, AccountInfo { balance, nonce, ..Default::default() }); self } @@ -88,10 +93,10 @@ impl TestDbBuilder { /// * `value` - The value to store pub fn with_storage(mut self, address: Address, slot: U256, value: U256) -> Self { // Ensure the account exists before setting storage - if !self.db.cache.accounts.contains_key(&address) { - self.db.insert_account_info(address, AccountInfo::default()); + if !self.latency_db.in_mem_db.cache.accounts.contains_key(&address) { + self.latency_db.in_mem_db.insert_account_info(address, AccountInfo::default()); } - let _ = self.db.insert_account_storage(address, slot, value); + let _ = self.latency_db.in_mem_db.insert_account_storage(address, slot, value); self } @@ -104,60 +109,78 @@ impl TestDbBuilder { /// * `number` - The block number /// * `hash` - The block hash pub fn with_block_hash(mut self, number: u64, hash: B256) -> Self { - self.db.cache.block_hashes.insert(U256::from(number), hash); + self.latency_db.in_mem_db.cache.block_hashes.insert(U256::from(number), hash); + self + } + + /// Add a contract account with the specified bytecode. + pub fn with_contract(mut self, address: Address, bytecode: Bytecode) -> Self { + self.latency_db.in_mem_db.insert_account_info( + address, + AccountInfo { code: Some(bytecode), ..Default::default() }, + ); + self + } + + /// Apply the given latency to every call to the wrapped, in-memory DB. + pub const fn with_latency(mut self, latency: Duration) -> Self { + self.latency_db.latency = Some(latency); self } /// Build the test database. pub fn build(self) -> TestDb { - self.db + CacheDB::new(self.latency_db) } } -#[cfg(test)] -mod tests { - use super::*; +/// In-memory database with configurable per-access latency. +/// +/// Holds all state (accounts, storage, block hashes) in plain hash maps and +/// calls [`std::thread::sleep`] before every read through [`DatabaseRef`]. +/// This simulates production conditions where the backing store (e.g. `AlloyDB`) +/// sends an RPC for each state lookup. +/// +/// Intended to be wrapped in a [`CacheDB`] so that the `CacheDB` provides real +/// mutable-path caching while this type represents the slow backing store behind it. +#[derive(Debug, Clone, Default)] +pub struct LatencyDb { + in_mem_db: CacheDB, + latency: Option, +} - #[test] - fn test_db_builder_creates_empty_db() { - let db = TestDbBuilder::new().build(); - assert!(db.cache.accounts.is_empty()); +impl LatencyDb { + fn sleep(&self) { + if let Some(latency) = self.latency { + std::thread::sleep(latency); + } } +} - #[test] - fn test_db_builder_adds_account() { - let address = Address::repeat_byte(0x01); - let balance = U256::from(1000u64); - let nonce = 5u64; - - let db = TestDbBuilder::new().with_account(address, balance, nonce).build(); +impl DatabaseRef for LatencyDb { + type Error = core::convert::Infallible; - let account = db.cache.accounts.get(&address).unwrap(); - assert_eq!(account.info.balance, balance); - assert_eq!(account.info.nonce, nonce); + fn basic_ref(&self, address: Address) -> Result, Self::Error> { + self.sleep(); + Ok(self.in_mem_db.basic_ref(address).unwrap()) } - #[test] - fn test_db_builder_adds_storage() { - let address = Address::repeat_byte(0x01); - let slot = U256::from(42u64); - let value = U256::from(123u64); - - let db = TestDbBuilder::new().with_storage(address, slot, value).build(); - - let account = db.cache.accounts.get(&address).unwrap(); - let stored = account.storage.get(&slot).unwrap(); - assert_eq!(*stored, value); + fn code_by_hash_ref(&self, code_hash: B256) -> Result { + self.sleep(); + Ok(self.in_mem_db.code_by_hash_ref(code_hash).unwrap()) } - #[test] - fn test_db_builder_adds_block_hash() { - let number = 100u64; - let hash = B256::repeat_byte(0xab); - - let db = TestDbBuilder::new().with_block_hash(number, hash).build(); + fn storage_ref( + &self, + address: Address, + index: StorageKey, + ) -> Result { + self.sleep(); + Ok(self.in_mem_db.storage_ref(address, index).unwrap()) + } - let stored = db.cache.block_hashes.get(&U256::from(number)).unwrap(); - assert_eq!(*stored, hash); + fn block_hash_ref(&self, number: u64) -> Result { + self.sleep(); + Ok(self.in_mem_db.block_hash_ref(number).unwrap()) } } diff --git a/src/test_utils/mod.rs b/src/test_utils/mod.rs index 2e708e32..d8cae7c8 100644 --- a/src/test_utils/mod.rs +++ b/src/test_utils/mod.rs @@ -12,7 +12,7 @@ mod tx; // Re-export test harness components pub use block::{TestBlockBuild, TestBlockBuildBuilder, quick_build_block}; -pub use db::{TestDb, TestDbBuilder, TestStateSource}; +pub use db::{LatencyDb, TestDb, TestDbBuilder, TestStateSource}; pub use env::{TestHostEnv, TestRollupEnv, TestSimEnvBuilder}; pub use scenarios::{ DEFAULT_BALANCE, DEFAULT_BASEFEE, basic_scenario, custom_funded_scenario, funded_test_db, From 52e7aa6267adee7cb37fad2b31a04d6560f93af8 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison <190532+Fraser999@users.noreply.github.com> Date: Tue, 14 Apr 2026 19:53:32 +0100 Subject: [PATCH 06/10] ignore new cargo audit warning (#266) --- .cargo/audit.toml | 5 + Cargo.lock | 263 +++++++++++++++++++++++----------------------- 2 files changed, 139 insertions(+), 129 deletions(-) diff --git a/.cargo/audit.toml b/.cargo/audit.toml index 7266adc5..f29b16a4 100644 --- a/.cargo/audit.toml +++ b/.cargo/audit.toml @@ -18,4 +18,9 @@ ignore = [ # `lru` IterMut unsoundness; transitive dep via reth's `discv5` and `ratatui`. # Neither crate calls `iter_mut()` on the LruCache, so the affected code path is never hit. "RUSTSEC-2026-0002", + + # `rand` 0.8.5 unsoundness when `log` + `thread_rng` features are both enabled and a custom + # logger calls `rand::rng()` during reseeding. Our 0.8.5 (transitive via alloy-consensus) + # has neither feature enabled; our 0.9.4 is already patched. + "RUSTSEC-2026-0097", ] diff --git a/Cargo.lock b/Cargo.lock index b22f708a..020bbb54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -135,9 +135,9 @@ dependencies = [ [[package]] name = "alloy-chains" -version = "0.2.33" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4e9e31d834fe25fe991b8884e4b9f0e59db4a97d86e05d1464d6899c013cd62" +checksum = "84e0378e959aa6a885897522080a990e80eb317f1e9a222a604492ea50e13096" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -497,14 +497,14 @@ dependencies = [ "foldhash 0.2.0", "getrandom 0.4.2", "hashbrown 0.16.1", - "indexmap 2.13.1", + "indexmap 2.14.0", "itoa", "k256", "keccak-asm", "paste", "proptest", "proptest-derive", - "rand 0.9.2", + "rand 0.9.4", "rapidhash", "ruint", "rustc-hash", @@ -890,7 +890,7 @@ dependencies = [ "alloy-sol-macro-input", "const-hex", "heck", - "indexmap 2.13.1", + "indexmap 2.14.0", "proc-macro-error2", "proc-macro2", "quote", @@ -1906,9 +1906,9 @@ dependencies = [ [[package]] name = "axum" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" +checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" dependencies = [ "axum-core 0.5.6", "bytes", @@ -2065,7 +2065,7 @@ version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "cexpr", "clang-sys", "itertools 0.13.0", @@ -2116,9 +2116,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" dependencies = [ "serde_core", ] @@ -2172,11 +2172,11 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6339a700715bda376f5ea65c76e8fe8fc880930d8b0638cea68e7f3da6538e0a" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "boa_interner", "boa_macros", "boa_string", - "indexmap 2.13.1", + "indexmap 2.14.0", "num-bigint", "rustc-hash", ] @@ -2189,7 +2189,7 @@ checksum = "1521be326f8a5c8887e95d4ce7f002917a002a23f7b93b9a6a2bf50ed4157824" dependencies = [ "aligned-vec", "arrayvec", - "bitflags 2.11.0", + "bitflags 2.11.1", "boa_ast", "boa_gc", "boa_interner", @@ -2208,7 +2208,7 @@ dependencies = [ "futures-lite", "hashbrown 0.16.1", "icu_normalizer", - "indexmap 2.13.1", + "indexmap 2.14.0", "intrusive-collections", "itertools 0.14.0", "num-bigint", @@ -2217,7 +2217,7 @@ dependencies = [ "num_enum", "paste", "portable-atomic", - "rand 0.9.2", + "rand 0.9.4", "regress", "rustc-hash", "ryu-js", @@ -2254,7 +2254,7 @@ dependencies = [ "boa_gc", "boa_macros", "hashbrown 0.16.1", - "indexmap 2.13.1", + "indexmap 2.14.0", "once_cell", "phf", "rustc-hash", @@ -2281,7 +2281,7 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35bd957fa9fa93e3a001a8aba5a5cd40c2bbfde486378be4c4b472fd304aaddb" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "boa_ast", "boa_interner", "boa_macros", @@ -2538,9 +2538,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.59" +version = "1.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7a4d3ec6524d28a329fc53654bbadc9bdd7b0431f5d65f1a56ffb28a1ee5283" +checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" dependencies = [ "find-msvc-tools", "jobserver", @@ -3016,7 +3016,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "crossterm_winapi", "derive_more", "document-features", @@ -3750,9 +3750,9 @@ dependencies = [ [[package]] name = "ethereum_ssz" -version = "0.10.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2128a84f7a3850d54ee343334e3392cca61f9f6aa9441eec481b9394b43c238b" +checksum = "368a4a4e4273b0135111fe9464e35465067766a8f664615b5a86338b73864407" dependencies = [ "alloy-primitives", "ethereum_serde_utils", @@ -3777,9 +3777,9 @@ dependencies = [ [[package]] name = "ethereum_ssz_derive" -version = "0.10.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd596f91cff004fc8d02be44c21c0f9b93140a04b66027ae052f5f8e05b48eba" +checksum = "f2cd82c68120c89361e1a457245cf212f7d9f541bffaffed530c8f2d54a160b2" dependencies = [ "darling 0.23.0", "proc-macro2", @@ -4240,7 +4240,7 @@ version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b88256088d75a56f8ecfa070513a775dd9107f6530ef14919dac831af9cfe2b" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "libc", "libgit2-sys", "log", @@ -4334,7 +4334,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.4.0", - "indexmap 2.13.1", + "indexmap 2.14.0", "slab", "tokio", "tokio-util", @@ -4393,6 +4393,12 @@ dependencies = [ "serde_core", ] +[[package]] +name = "hashbrown" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" + [[package]] name = "hashlink" version = "0.11.0" @@ -4455,7 +4461,7 @@ dependencies = [ "idna", "ipnet", "once_cell", - "rand 0.9.2", + "rand 0.9.4", "ring", "serde", "thiserror 2.0.18", @@ -4478,7 +4484,7 @@ dependencies = [ "moka", "once_cell", "parking_lot", - "rand 0.9.2", + "rand 0.9.4", "resolv-conf", "serde", "smallvec", @@ -4624,9 +4630,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.7" +version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ "http 1.4.0", "hyper", @@ -4634,7 +4640,6 @@ dependencies = [ "log", "rustls", "rustls-native-certs", - "rustls-pki-types", "tokio", "tokio-rustls", "tower-service", @@ -4909,13 +4914,13 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.13.1" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "arbitrary", "equivalent", - "hashbrown 0.16.1", + "hashbrown 0.17.0", "serde", "serde_core", ] @@ -4939,7 +4944,7 @@ dependencies = [ "async-trait", "aws-config", "aws-sdk-kms", - "axum 0.8.8", + "axum 0.8.9", "chrono", "eyre", "futures-util", @@ -4984,7 +4989,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd5b3eaf1a28b758ac0faa5a4254e8ab2705605496f1b1f3fbbc3988ad73d199" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "inotify-sys", "libc", ] @@ -5169,9 +5174,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.94" +version = "0.3.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9" +checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" dependencies = [ "cfg-if", "futures-util", @@ -5238,7 +5243,7 @@ dependencies = [ "jsonrpsee-types", "parking_lot", "pin-project", - "rand 0.9.2", + "rand 0.9.4", "rustc-hash", "serde", "serde_json", @@ -5445,9 +5450,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.184" +version = "0.2.185" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" +checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f" [[package]] name = "libgit2-sys" @@ -5509,14 +5514,14 @@ dependencies = [ [[package]] name = "libredox" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ddbf48fd451246b1f8c2610bd3b4ac0cc6e149d89832867093ab69a17194f08" +checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "libc", "plain", - "redox_syscall 0.7.3", + "redox_syscall 0.7.4", ] [[package]] @@ -5553,7 +5558,7 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f50e8f47623268b5407192d26876c4d7f89d686ca130fdc53bced4814cd29f8" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", ] [[package]] @@ -5608,9 +5613,9 @@ checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "lru" -version = "0.16.3" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593" +checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39" dependencies = [ "hashbrown 0.16.1", ] @@ -5760,7 +5765,7 @@ dependencies = [ "hyper", "hyper-rustls", "hyper-util", - "indexmap 2.13.1", + "indexmap 2.14.0", "ipnet", "metrics", "metrics-util", @@ -5798,7 +5803,7 @@ dependencies = [ "hashbrown 0.16.1", "metrics", "quanta", - "rand 0.9.2", + "rand 0.9.4", "rand_xoshiro", "sketches-ddsketch", ] @@ -5965,7 +5970,7 @@ version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "fsevent-sys", "inotify", "kqueue", @@ -5983,7 +5988,7 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42b8cfee0e339a0337359f3c88165702ac6e600dc01c0cc9579a92d62b08477a" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", ] [[package]] @@ -6167,7 +6172,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", ] [[package]] @@ -6325,11 +6330,11 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.76" +version = "0.10.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "951c002c75e16ea2c65b8c7e4d3d51d5530d8dfa7d060b4776828c88cfb18ecf" +checksum = "bfe4646e360ec77dff7dde40ed3d6c5fee52d156ef4a62f53973d38294dad87f" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "cfg-if", "foreign-types", "libc", @@ -6366,9 +6371,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.112" +version = "0.9.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d55af3b3e226502be1526dfdba67ab0e9c96fc293004e79576b2b9edb0dbdb" +checksum = "ad2f2c0eba47118757e4c6d2bff2838f3e0523380021356e7875e858372ce644" dependencies = [ "cc", "libc", @@ -6527,7 +6532,7 @@ dependencies = [ "futures-util", "opentelemetry 0.30.0", "percent-encoding", - "rand 0.9.2", + "rand 0.9.4", "serde_json", "thiserror 2.0.18", ] @@ -6543,7 +6548,7 @@ dependencies = [ "futures-util", "opentelemetry 0.31.0", "percent-encoding", - "rand 0.9.2", + "rand 0.9.4", "thiserror 2.0.18", ] @@ -6778,9 +6783,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" [[package]] name = "plain" @@ -6944,7 +6949,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25485360a54d6861439d60facef26de713b1e126bf015ec8f98239467a2b82f7" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "chrono", "flate2", "procfs-core", @@ -6957,7 +6962,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6401bf7b6af22f78b563665d15a22e9aef27775b79b149a66ca022468a4e405" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "chrono", "hex", ] @@ -6970,9 +6975,9 @@ checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.11.0", + "bitflags 2.11.1", "num-traits", - "rand 0.9.2", + "rand 0.9.4", "rand_chacha 0.9.0", "rand_xorshift", "regex-syntax", @@ -7097,7 +7102,7 @@ dependencies = [ "bytes", "getrandom 0.3.4", "lru-slab", - "rand 0.9.2", + "rand 0.9.4", "ring", "rustc-hash", "rustls", @@ -7164,9 +7169,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.2" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.5", @@ -7236,7 +7241,7 @@ version = "4.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e48930979c155e2f33aa36ab3119b5ee81332beb6482199a8ecd6029b80b59" dependencies = [ - "rand 0.9.2", + "rand 0.9.4", "rustversion", ] @@ -7258,7 +7263,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ef8dea09a92caaf73bff7adb70b76162e5937524058a7e5bff37869cbbec293" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "compact_str", "hashbrown 0.16.1", "indoc", @@ -7290,7 +7295,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7dbfa023cd4e604c2553483820c5fe8aa9d71a42eea5aa77c6e7f35756612db" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "hashbrown 0.16.1", "indoc", "instability", @@ -7309,14 +7314,14 @@ version = "11.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", ] [[package]] name = "rayon" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" dependencies = [ "either", "rayon-core", @@ -7344,16 +7349,16 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", ] [[package]] name = "redox_syscall" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16" +checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", ] [[package]] @@ -7574,7 +7579,7 @@ dependencies = [ "metrics", "parking_lot", "pin-project", - "rand 0.9.2", + "rand 0.9.4", "rayon", "reth-chainspec", "reth-errors", @@ -7962,7 +7967,7 @@ dependencies = [ "futures", "itertools 0.14.0", "metrics", - "rand 0.9.2", + "rand 0.9.4", "reth-chainspec", "reth-ethereum-forks", "reth-metrics", @@ -8215,8 +8220,8 @@ dependencies = [ "alloy-eips", "alloy-primitives", "alloy-rlp", - "ethereum_ssz 0.10.1", - "ethereum_ssz_derive 0.10.1", + "ethereum_ssz 0.10.3", + "ethereum_ssz_derive 0.10.3", "snap", "thiserror 2.0.18", ] @@ -8638,7 +8643,7 @@ name = "reth-libmdbx" version = "1.11.3" source = "git+https://github.com/paradigmxyz/reth?tag=v1.11.3#d6324d63e27ef6b7c49cdc9b1977c1b808234c7b" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "byteorder", "dashmap", "derive_more", @@ -8713,7 +8718,7 @@ dependencies = [ "parking_lot", "pin-project", "rand 0.8.5", - "rand 0.9.2", + "rand 0.9.4", "rayon", "reth-chainspec", "reth-consensus", @@ -8951,7 +8956,7 @@ dependencies = [ "futures", "humantime", "ipnet", - "rand 0.9.2", + "rand 0.9.4", "reth-chainspec", "reth-cli-util", "reth-config", @@ -9585,7 +9590,7 @@ dependencies = [ "jsonrpsee-core", "jsonrpsee-types", "metrics", - "rand 0.9.2", + "rand 0.9.4", "reqwest", "reth-chain-state", "reth-chainspec", @@ -9879,12 +9884,12 @@ dependencies = [ "alloy-rlp", "aquamarine", "auto_impl", - "bitflags 2.11.0", + "bitflags 2.11.1", "futures-util", "metrics", "parking_lot", "pin-project", - "rand 0.9.2", + "rand 0.9.4", "reth-chain-state", "reth-chainspec", "reth-eth-wire-types", @@ -10241,7 +10246,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "311720d4f0f239b041375e7ddafdbd20032a33b7bae718562ea188e188ed9fd3" dependencies = [ "alloy-eip7928", - "bitflags 2.11.0", + "bitflags 2.11.1", "revm-bytecode", "revm-primitives", "serde", @@ -10380,7 +10385,7 @@ dependencies = [ "primitive-types", "proptest", "rand 0.8.5", - "rand 0.9.2", + "rand 0.9.4", "rlp", "ruint-macro", "serde_core", @@ -10442,7 +10447,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "errno", "libc", "linux-raw-sys", @@ -10451,9 +10456,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.37" +version = "0.23.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" +checksum = "69f9466fb2c14ea04357e91413efb882e2a6d4a406e625449bc0a5d360d53a21" dependencies = [ "aws-lc-rs", "log", @@ -10516,9 +10521,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.10" +version = "0.103.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" +checksum = "8279bb85272c9f10811ae6a6c547ff594d6a7f3c6c6b02ee9726d1d0dcfcdd06" dependencies = [ "aws-lc-rs", "ring", @@ -10649,7 +10654,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c3c81b43dc2d8877c216a3fccf76677ee1ebccd429566d3e67447290d0c42b2" dependencies = [ "bitcoin_hashes", - "rand 0.9.2", + "rand 0.9.4", "secp256k1-sys 0.11.0", ] @@ -10677,7 +10682,7 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -10785,7 +10790,7 @@ version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ - "indexmap 2.13.1", + "indexmap 2.14.0", "itoa", "memchr", "serde", @@ -10835,7 +10840,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.13.1", + "indexmap 2.14.0", "schemars 0.9.0", "schemars 1.2.1", "serde_core", @@ -11078,7 +11083,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05cd7eb4c1a23f8b3742084283c690d04fda828f8c7aaa232b0d0a8d89861267" dependencies = [ "alloy", - "bitflags 2.11.0", + "bitflags 2.11.1", "signet-extract", "signet-journal", "signet-types", @@ -11421,7 +11426,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -11480,9 +11485,9 @@ dependencies = [ [[package]] name = "thin-vec" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da322882471314edc77fa5232c587bcb87c9df52bfd0d7d4826f8868ead61899" +checksum = "259cdf8ed4e4aca6f1e9d011e10bd53f524a2d0637d7b28450f6c64ac298c4c6" [[package]] name = "thiserror" @@ -11751,7 +11756,7 @@ version = "0.9.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" dependencies = [ - "indexmap 2.13.1", + "indexmap 2.14.0", "serde_core", "serde_spanned", "toml_datetime 0.7.5+spec-1.1.0", @@ -11784,7 +11789,7 @@ version = "0.25.11+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" dependencies = [ - "indexmap 2.13.1", + "indexmap 2.14.0", "toml_datetime 1.1.1+spec-1.1.0", "toml_parser", "winnow 1.0.1", @@ -11872,7 +11877,7 @@ dependencies = [ "futures-core", "futures-util", "hdrhistogram", - "indexmap 2.13.1", + "indexmap 2.14.0", "pin-project-lite", "slab", "sync_wrapper", @@ -11891,7 +11896,7 @@ checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ "async-compression", "base64 0.22.1", - "bitflags 2.11.0", + "bitflags 2.11.1", "bytes", "futures-core", "futures-util", @@ -12161,7 +12166,7 @@ dependencies = [ "http 1.4.0", "httparse", "log", - "rand 0.9.2", + "rand 0.9.4", "rustls", "rustls-pki-types", "sha1", @@ -12180,7 +12185,7 @@ dependencies = [ "http 1.4.0", "httparse", "log", - "rand 0.9.2", + "rand 0.9.4", "sha1", "thiserror 2.0.18", "utf-8", @@ -12471,9 +12476,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.117" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0" +checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" dependencies = [ "cfg-if", "once_cell", @@ -12484,9 +12489,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.67" +version = "0.4.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03623de6905b7206edd0a75f69f747f134b7f0a2323392d664448bf2d3c5d87e" +checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8" dependencies = [ "js-sys", "wasm-bindgen", @@ -12494,9 +12499,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.117" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be" +checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -12504,9 +12509,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.117" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2" +checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" dependencies = [ "bumpalo", "proc-macro2", @@ -12517,9 +12522,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.117" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b" +checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" dependencies = [ "unicode-ident", ] @@ -12541,7 +12546,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" dependencies = [ "anyhow", - "indexmap 2.13.1", + "indexmap 2.14.0", "wasm-encoder", "wasmparser", ] @@ -12565,9 +12570,9 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "hashbrown 0.15.5", - "indexmap 2.13.1", + "indexmap 2.14.0", "semver 1.0.28", ] @@ -12587,9 +12592,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.94" +version = "0.3.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd70027e39b12f0849461e08ffc50b9cd7688d942c1c8e3c7b22273236b4dd0a" +checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d" dependencies = [ "js-sys", "wasm-bindgen", @@ -13076,7 +13081,7 @@ checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" dependencies = [ "anyhow", "heck", - "indexmap 2.13.1", + "indexmap 2.14.0", "prettyplease", "syn 2.0.117", "wasm-metadata", @@ -13106,8 +13111,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags 2.11.0", - "indexmap 2.13.1", + "bitflags 2.11.1", + "indexmap 2.14.0", "log", "serde", "serde_derive", @@ -13126,7 +13131,7 @@ checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" dependencies = [ "anyhow", "id-arena", - "indexmap 2.13.1", + "indexmap 2.14.0", "log", "semver 1.0.28", "serde", From dcadae94fbc3fbca56924522ec548987004a59ba Mon Sep 17 00:00:00 2001 From: Fraser Hutchison <190532+Fraser999@users.noreply.github.com> Date: Wed, 15 Apr 2026 13:14:39 +0100 Subject: [PATCH 07/10] fix: update lockfile to fix cargo audit warning (#267) --- Cargo.lock | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 020bbb54..9d957e5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2886,15 +2886,6 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" -[[package]] -name = "core2" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" -dependencies = [ - "memchr", -] - [[package]] name = "cow-utils" version = "0.1.3" @@ -5929,11 +5920,11 @@ dependencies = [ [[package]] name = "multihash" -version = "0.19.3" +version = "0.19.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b430e7953c29dd6a09afc29ff0bb69c6e306329ee6794700aee27b76a1aea8d" +checksum = "89ace881e3f514092ce9efbcb8f413d0ad9763860b828981c2de51ddc666936c" dependencies = [ - "core2", + "no_std_io2", "unsigned-varint", ] @@ -5954,6 +5945,15 @@ dependencies = [ "tempfile", ] +[[package]] +name = "no_std_io2" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a3564ce7035b1e4778d8cb6cacebb5d766b5e8fe5a75b9e441e33fb61a872c6" +dependencies = [ + "memchr", +] + [[package]] name = "nom" version = "7.1.3" @@ -11649,9 +11649,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.51.1" +version = "1.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f66bf9585cda4b724d3e78ab34b73fb2bbaba9011b9bfdf69dc836382ea13b8c" +checksum = "a91135f59b1cbf38c91e73cf3386fca9bb77915c45ce2771460c9d92f0f3d776" dependencies = [ "bytes", "libc", From 71a9ecfddba7268e5babcd65e43fc169f72f73d6 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison <190532+Fraser999@users.noreply.github.com> Date: Wed, 22 Apr 2026 14:45:05 +0100 Subject: [PATCH 08/10] chore: update lockfile (#268) --- Cargo.lock | 174 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 102 insertions(+), 72 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9d957e5d..93d1ce79 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -166,7 +166,7 @@ dependencies = [ "either", "k256", "once_cell", - "rand 0.8.5", + "rand 0.8.6", "secp256k1 0.30.0", "serde", "serde_json", @@ -254,7 +254,7 @@ dependencies = [ "alloy-rlp", "arbitrary", "crc", - "rand 0.8.5", + "rand 0.8.6", "serde", "thiserror 2.0.18", ] @@ -269,7 +269,7 @@ dependencies = [ "alloy-rlp", "arbitrary", "borsh", - "rand 0.8.5", + "rand 0.8.6", "serde", ] @@ -284,7 +284,7 @@ dependencies = [ "arbitrary", "borsh", "k256", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde_with", "thiserror 2.0.18", @@ -292,14 +292,15 @@ dependencies = [ [[package]] name = "alloy-eip7928" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8222b1d88f9a6d03be84b0f5e76bb60cd83991b43ad8ab6477f0e4a7809b98d" +checksum = "407510740da514b694fecb44d8b3cebdc60d448f70cc5d24743e8ba273448a6e" dependencies = [ "alloy-primitives", "alloy-rlp", "arbitrary", "borsh", + "once_cell", "serde", ] @@ -473,7 +474,7 @@ dependencies = [ "alloy-signer-local", "k256", "libc", - "rand 0.8.5", + "rand 0.8.6", "serde_json", "tempfile", "thiserror 2.0.18", @@ -733,7 +734,7 @@ dependencies = [ "ethereum_ssz 0.9.1", "ethereum_ssz_derive 0.9.1", "jsonwebtoken", - "rand 0.8.5", + "rand 0.8.6", "serde", "strum", ] @@ -861,7 +862,7 @@ dependencies = [ "coins-bip32", "coins-bip39", "k256", - "rand 0.8.5", + "rand 0.8.6", "thiserror 2.0.18", "zeroize", ] @@ -1408,7 +1409,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" dependencies = [ "num-traits", - "rand 0.8.5", + "rand 0.8.6", ] [[package]] @@ -1418,7 +1419,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ "num-traits", - "rand 0.8.5", + "rand 0.8.6", ] [[package]] @@ -1428,7 +1429,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" dependencies = [ "num-traits", - "rand 0.8.5", + "rand 0.8.6", ] [[package]] @@ -1580,9 +1581,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.16.2" +version = "1.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a054912289d18629dc78375ba2c3726a3afe3ff71b4edba9dedfca0e3446d1fc" +checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f" dependencies = [ "aws-lc-sys", "zeroize", @@ -1590,9 +1591,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.39.1" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a25cf98105baa966497416dbd42565ce3a8cf8dbfd59803ec9ad46f3126399" +checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7" dependencies = [ "cc", "cmake", @@ -2639,9 +2640,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.6.0" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" dependencies = [ "clap_builder", "clap_derive", @@ -2661,9 +2662,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.6.0" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a" +checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" dependencies = [ "heck", "proc-macro2", @@ -2713,7 +2714,7 @@ dependencies = [ "hmac", "once_cell", "pbkdf2", - "rand 0.8.5", + "rand 0.8.6", "sha2", "thiserror 1.0.69", ] @@ -2833,11 +2834,12 @@ checksum = "2f421161cb492475f1661ddc9815a745a1c894592070661180fdec3d4872e9c3" [[package]] name = "const_format" -version = "0.2.35" +version = "0.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" +checksum = "4481a617ad9a412be3b97c5d403fef8ed023103368908b9c50af598ff467cc1e" dependencies = [ "const_format_proc_macros", + "konst", ] [[package]] @@ -3455,7 +3457,7 @@ dependencies = [ "more-asserts", "multiaddr", "parking_lot", - "rand 0.8.5", + "rand 0.8.6", "smallvec", "socket2", "tokio", @@ -3625,7 +3627,7 @@ dependencies = [ "hex", "k256", "log", - "rand 0.8.5", + "rand 0.8.6", "secp256k1 0.30.0", "serde", "sha3", @@ -3883,7 +3885,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ "byteorder", - "rand 0.8.5", + "rand 0.8.6", "rustc-hex", "static_assertions", ] @@ -4634,7 +4636,7 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", - "webpki-roots 1.0.6", + "webpki-roots 1.0.7", ] [[package]] @@ -5019,9 +5021,9 @@ dependencies = [ [[package]] name = "interprocess" -version = "2.4.0" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6be5e5c847dbdb44564bd85294740d031f4f8aeb3464e5375ef7141f7538db69" +checksum = "069323743400cb7ab06a8fe5c1ed911d36b6919ec531661d034c89083629595b" dependencies = [ "doctest-file", "futures-core", @@ -5029,7 +5031,7 @@ dependencies = [ "recvmsg", "tokio", "widestring", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -5407,6 +5409,21 @@ dependencies = [ "sha3-asm", ] +[[package]] +name = "konst" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128133ed7824fcd73d6e7b17957c5eb7bacb885649bd8c69708b2331a10bcefb" +dependencies = [ + "konst_macro_rules", +] + +[[package]] +name = "konst_macro_rules" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37" + [[package]] name = "kqueue" version = "1.1.1" @@ -6156,7 +6173,7 @@ dependencies = [ "chrono", "getrandom 0.2.17", "http 1.4.0", - "rand 0.8.5", + "rand 0.8.6", "reqwest", "serde", "serde_json", @@ -6330,9 +6347,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.77" +version = "0.10.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe4646e360ec77dff7dde40ed3d6c5fee52d156ef4a62f53973d38294dad87f" +checksum = "f38c4372413cdaaf3cc79dd92d29d7d9f5ab09b51b10dded508fb90bb70b9222" dependencies = [ "bitflags 2.11.1", "cfg-if", @@ -6371,9 +6388,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.113" +version = "0.9.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad2f2c0eba47118757e4c6d2bff2838f3e0523380021356e7875e858372ce644" +checksum = "13ce1245cd07fcc4cfdb438f7507b0c7e4f3849a69fd84d52374c66d83741bb6" dependencies = [ "cc", "libc", @@ -7157,9 +7174,9 @@ checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "rand" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" dependencies = [ "libc", "rand_chacha 0.3.1", @@ -7494,7 +7511,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 1.0.6", + "webpki-roots 1.0.7", ] [[package]] @@ -7731,7 +7748,7 @@ dependencies = [ "cfg-if", "eyre", "libc", - "rand 0.8.5", + "rand 0.8.6", "reth-fs-util", "secp256k1 0.30.0", "serde", @@ -7940,7 +7957,7 @@ dependencies = [ "enr", "itertools 0.14.0", "parking_lot", - "rand 0.8.5", + "rand 0.8.6", "reth-ethereum-forks", "reth-net-banlist", "reth-net-nat", @@ -8050,7 +8067,7 @@ dependencies = [ "futures", "hmac", "pin-project", - "rand 0.8.5", + "rand 0.8.6", "reth-network-peers", "secp256k1 0.30.0", "sha2", @@ -8717,7 +8734,7 @@ dependencies = [ "metrics", "parking_lot", "pin-project", - "rand 0.8.5", + "rand 0.8.6", "rand 0.9.4", "rayon", "reth-chainspec", @@ -10384,7 +10401,7 @@ dependencies = [ "parity-scale-codec", "primitive-types", "proptest", - "rand 0.8.5", + "rand 0.8.6", "rand 0.9.4", "rlp", "ruint-macro", @@ -10405,7 +10422,7 @@ version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" dependencies = [ - "rand 0.8.5", + "rand 0.8.6", ] [[package]] @@ -10521,9 +10538,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.12" +version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8279bb85272c9f10811ae6a6c547ff594d6a7f3c6c6b02ee9726d1d0dcfcdd06" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ "aws-lc-rs", "ring", @@ -10642,7 +10659,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b50c5943d326858130af85e049f2661ba3c78b26589b8ab98e65e80ae44a1252" dependencies = [ "bitcoin_hashes", - "rand 0.8.5", + "rand 0.8.6", "secp256k1-sys 0.10.1", "serde", ] @@ -10895,9 +10912,9 @@ dependencies = [ [[package]] name = "sha3" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" dependencies = [ "digest 0.10.7", "keccak", @@ -11293,7 +11310,7 @@ dependencies = [ "http 1.4.0", "httparse", "log", - "rand 0.8.5", + "rand 0.8.6", "sha1", ] @@ -11352,6 +11369,12 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "symlink" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7973cce6668464ea31f176d85b13c7ab3bba2cb3b77a2ed26abd7801688010a" + [[package]] name = "syn" version = "1.0.109" @@ -11649,9 +11672,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.52.0" +version = "1.52.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91135f59b1cbf38c91e73cf3386fca9bb77915c45ce2771460c9d92f0f3d776" +checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" dependencies = [ "bytes", "libc", @@ -11792,7 +11815,7 @@ dependencies = [ "indexmap 2.14.0", "toml_datetime 1.1.1+spec-1.1.0", "toml_parser", - "winnow 1.0.1", + "winnow 1.0.2", ] [[package]] @@ -11801,7 +11824,7 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow 1.0.1", + "winnow 1.0.2", ] [[package]] @@ -11945,11 +11968,12 @@ dependencies = [ [[package]] name = "tracing-appender" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" +checksum = "050686193eb999b4bb3bc2acfa891a13da00f79734704c4b8b4ef1a10b368a3c" dependencies = [ "crossbeam-channel", + "symlink", "thiserror 2.0.18", "time", "tracing-subscriber 0.3.23", @@ -12199,9 +12223,9 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typenum" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" [[package]] name = "ucd-trie" @@ -12347,9 +12371,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.23.0" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" +checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" dependencies = [ "getrandom 0.4.2", "js-sys", @@ -12458,11 +12482,11 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.2+wasi-0.2.9" +version = "1.0.3+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" dependencies = [ - "wit-bindgen", + "wit-bindgen 0.57.1", ] [[package]] @@ -12471,7 +12495,7 @@ version = "0.4.0+wasi-0.3.0-rc-2026-01-06" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" dependencies = [ - "wit-bindgen", + "wit-bindgen 0.51.0", ] [[package]] @@ -12616,14 +12640,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75c7f0ef91146ebfb530314f5f1d24528d7f0767efbfd31dce919275413e393e" dependencies = [ - "webpki-root-certs 1.0.6", + "webpki-root-certs 1.0.7", ] [[package]] name = "webpki-root-certs" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca" +checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c" dependencies = [ "rustls-pki-types", ] @@ -12634,14 +12658,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.6", + "webpki-roots 1.0.7", ] [[package]] name = "webpki-roots" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d" dependencies = [ "rustls-pki-types", ] @@ -13046,9 +13070,9 @@ dependencies = [ [[package]] name = "winnow" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" +checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0" dependencies = [ "memchr", ] @@ -13062,6 +13086,12 @@ dependencies = [ "wit-bindgen-rust-macro", ] +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + [[package]] name = "wit-bindgen-core" version = "0.51.0" From 85dcd6d2e3f1c6d7897f2f35c936f26c63a0ee12 Mon Sep 17 00:00:00 2001 From: init4samwise Date: Tue, 28 Apr 2026 09:47:22 -0400 Subject: [PATCH 09/10] feat(bundle): filter bundles with stale host tx nonces before SimCache (#235) * feat(bundle): filter bundles with stale host tx nonces before SimCache Adds nonce checking for host transactions in BundlePoller, similar to the existing TxPoller pattern. Bundles with stale host tx nonces are dropped before entering SimCache to prevent: - Wasted simulation cycles on bundles that will fail - ERROR log spam from nonce-too-low failures - Re-ingestion churn (~1s poll cycle) Each host transaction's nonce is compared against the sender's current nonce from the host provider. If any host tx has a stale nonce, the entire bundle is dropped with DEBUG-level logging. Closes ENG-1937 * refactor: use FuturesUnordered and reuse validity checks - Refactored bundle processing to use FuturesUnordered for concurrent execution - Added cancellation on first failure - Reused validity checks from crates/sim/src/cache/item.rs Addresses PR review feedback from prestwich * address review feedback * use check_bundle_tx_list from sdk * address review comments --------- Co-authored-by: Fraser Hutchison <190532+Fraser999@users.noreply.github.com> --- Cargo.toml | 10 +++--- src/tasks/cache/bundle.rs | 65 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 65 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f2e39007..73b80026 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,11 +23,11 @@ path = "bin/builder.rs" [dependencies] init4-bin-base = { version = "0.18.0-rc.13", features = ["perms", "aws", "pylon"] } -signet-constants = { version = "0.16.0-rc.16" } -signet-sim = { version = "0.16.0-rc.16" } -signet-tx-cache = { version = "0.16.0-rc.16" } -signet-types = { version = "0.16.0-rc.16" } -signet-zenith = { version = "0.16.0-rc.16" } +signet-constants = { version = "0.16.0-rc.17" } +signet-sim = { version = "0.16.0-rc.17" } +signet-tx-cache = { version = "0.16.0-rc.17" } +signet-types = { version = "0.16.0-rc.17" } +signet-zenith = { version = "0.16.0-rc.17" } signet-block-processor = { git = "https://github.com/init4tech/node-components", tag = "v0.16.0-rc.10" } signet-genesis = { git = "https://github.com/init4tech/node-components", tag = "v0.16.0-rc.10" } diff --git a/src/tasks/cache/bundle.rs b/src/tasks/cache/bundle.rs index a45fff03..4397046c 100644 --- a/src/tasks/cache/bundle.rs +++ b/src/tasks/cache/bundle.rs @@ -2,13 +2,14 @@ use crate::config::BuilderConfig; use futures_util::{TryFutureExt, TryStreamExt}; use init4_bin_base::perms::tx_cache::{BuilderTxCache, BuilderTxCacheError}; +use signet_sim::{ProviderStateSource, SimItemValidity, check_bundle_tx_list}; use signet_tx_cache::{TxCacheError, types::CachedBundle}; use tokio::{ sync::mpsc::{UnboundedReceiver, UnboundedSender, unbounded_channel}, task::JoinHandle, time::{self, Duration}, }; -use tracing::{Instrument, debug, trace, trace_span, warn}; +use tracing::{Instrument, debug_span, trace, trace_span, warn}; /// Poll interval for the bundle poller in milliseconds. const POLL_INTERVAL_MS: u64 = 1000; @@ -56,6 +57,63 @@ impl BundlePoller { self.tx_cache.stream_bundles().try_collect().await } + /// Spawns a tokio task to check the validity of all host transactions in a + /// bundle before sending it to the cache task via the outbound channel. + /// + /// Uses [`check_bundle_tx_list`] from `signet-sim` to validate host tx nonces + /// and balance against the host chain. Drops bundles that are not currently valid. + fn spawn_check_bundle_nonces(bundle: CachedBundle, outbound: UnboundedSender) { + let span = debug_span!("check_bundle_nonces", bundle_id = %bundle.id); + tokio::spawn(async move { + let recovered = match bundle.bundle.try_to_recovered() { + Ok(recovered) => recovered, + Err(error) => { + span_debug!(span, ?error, "Failed to recover bundle, dropping"); + return; + } + }; + + if recovered.host_txs().is_empty() { + let _ = outbound.send(bundle).inspect_err(|_| { + span_debug!(span, "Outbound channel closed"); + }); + return; + } + + // Check if the receiver is still alive before doing expensive nonce validation over + // the network. + if outbound.is_closed() { + span_debug!(span, "Outbound channel closed, skipping nonce validation"); + return; + } + + let Ok(host_provider) = + crate::config().connect_host_provider().instrument(span.clone()).await + else { + span_debug!(span, "Failed to connect to host provider, dropping bundle"); + return; + }; + + let source = ProviderStateSource(host_provider); + match check_bundle_tx_list(recovered.host_tx_reqs(), &source) + .instrument(span.clone()) + .await + { + Ok(SimItemValidity::Now) | Ok(SimItemValidity::Future) => { + let _ = outbound.send(bundle).inspect_err(|_| { + span_debug!(span, "Outbound channel closed"); + }); + } + Ok(SimItemValidity::Never) => { + span_debug!(span, "Dropping bundle: host txs will never be valid"); + } + Err(error) => { + span_debug!(span, %error, "Failed to check bundle validity, dropping"); + } + } + }); + } + async fn task_future(self, outbound: UnboundedSender) { loop { let span = trace_span!("BundlePoller::loop", url = %self.config.tx_pool_url); @@ -91,10 +149,7 @@ impl BundlePoller { crate::metrics::record_bundles_fetched(bundles.len()); trace!(count = bundles.len(), "fetched bundles from tx-cache"); for bundle in bundles { - if let Err(err) = outbound.send(bundle) { - debug!(?err, "Failed to send bundle - channel is dropped"); - break; - } + Self::spawn_check_bundle_nonces(bundle, outbound.clone()); } } From 7cf675fc6693f66f203ed5ce08163fe464e1617f Mon Sep 17 00:00:00 2001 From: Fraser Hutchison <190532+Fraser999@users.noreply.github.com> Date: Wed, 29 Apr 2026 22:20:47 +0100 Subject: [PATCH 10/10] bump versions to 1.0.0 (#270) --- Cargo.lock | 170 +++++++++++++++++++++++++++++++++++------------------ Cargo.toml | 2 +- 2 files changed, 113 insertions(+), 59 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 93d1ce79..c868afab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1455,9 +1455,9 @@ checksum = "4858a9d740c5007a9069007c3b4e91152d0506f13c1b31dd49051fd537656156" [[package]] name = "async-compression" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0f9ee0f6e02ffd7ad5816e9464499fba7b3effd01123b515c41d1697c43dad1" +checksum = "e79b3f8a79cccc2898f31920fc69f304859b3bd567490f75ebf51ae1c792a9ac" dependencies = [ "compression-codecs", "compression-core", @@ -2374,7 +2374,7 @@ dependencies = [ [[package]] name = "builder" -version = "1.0.0-rc.8" +version = "1.0.0" dependencies = [ "alloy", "alloy-chains", @@ -2539,9 +2539,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.60" +version = "1.2.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" +checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" dependencies = [ "find-msvc-tools", "jobserver", @@ -2781,9 +2781,9 @@ dependencies = [ [[package]] name = "compression-codecs" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb7b51a7d9c967fc26773061ba86150f19c50c0d65c887cb1fbe295fd16619b7" +checksum = "ce2548391e9c1929c21bf6aa2680af86fe4c1b33e6cea9ac1cfeec0bd11218cf" dependencies = [ "brotli", "compression-core", @@ -2795,9 +2795,9 @@ dependencies = [ [[package]] name = "compression-core" -version = "0.4.31" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d" +checksum = "cc14f565cf027a105f7a44ccf9e5b424348421a1d8952a8fc9d499d313107789" [[package]] name = "concat-kdf" @@ -2914,9 +2914,9 @@ dependencies = [ [[package]] name = "crc-catalog" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" +checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" [[package]] name = "crc32fast" @@ -3217,15 +3217,15 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" +checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" [[package]] name = "data-encoding-macro" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8142a83c17aa9461d637e649271eae18bf2edd00e91f2e105df36c3c16355bdb" +checksum = "3259c913752a86488b501ed8680446a5ed2d5aeac6e596cb23ba3800768ea32c" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -3233,9 +3233,9 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab67060fc6b8ef687992d439ca0fa36e7ed17e9a0b16b25b601e8757df720de" +checksum = "ccc2776f0c61eca1ca32528f85548abd1a4be8fb53d1b21c013e4f18da1e7090" dependencies = [ "data-encoding", "syn 2.0.117", @@ -3780,6 +3780,17 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "evmap" +version = "11.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8874945f036109c72242964c1174cf99434e30cfa45bf45fedc983f50046f8" +dependencies = [ + "hashbag", + "left-right", + "smallvec", +] + [[package]] name = "eyre" version = "0.6.12" @@ -4146,6 +4157,21 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42012b0f064e01aa58b545fe3727f90f7dd4020f4a3ea735b50344965f5a57e9" +[[package]] +name = "generator" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52f04ae4152da20c76fe800fa48659201d5cf627c5149ca0b707b69d7eef6cf9" +dependencies = [ + "cc", + "cfg-if", + "libc", + "log", + "rustversion", + "windows-link", + "windows-result", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -4345,6 +4371,12 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "hashbag" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7040a10f52cba493ddb09926e15d10a9d8a28043708a405931fe4c6f19fac064" + [[package]] name = "hashbrown" version = "0.12.3" @@ -5167,9 +5199,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.95" +version = "0.3.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" +checksum = "a1840c94c045fbcf8ba2812c95db44499f7c64910a912551aaaa541decebcacf" dependencies = [ "cfg-if", "futures-util", @@ -5456,11 +5488,22 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" +[[package]] +name = "left-right" +version = "0.11.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f0c21e4c8ff95f487fb34e6f9182875f42c84cef966d29216bf115d9bba835a" +dependencies = [ + "crossbeam-utils", + "loom", + "slab", +] + [[package]] name = "libc" -version = "0.2.185" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libgit2-sys" @@ -5619,6 +5662,19 @@ version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber 0.3.23", +] + [[package]] name = "lru" version = "0.16.4" @@ -5743,12 +5799,12 @@ dependencies = [ [[package]] name = "metrics" -version = "0.24.3" +version = "0.24.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d5312e9ba3771cfa961b585728215e3d972c950a3eed9252aa093d6301277e8" +checksum = "ff56c2e7dce6bd462e3b8919986a617027481b1dcc703175b58cf9dd98a2f071" dependencies = [ - "ahash", "portable-atomic", + "rapidhash", ] [[package]] @@ -5764,11 +5820,12 @@ dependencies = [ [[package]] name = "metrics-exporter-prometheus" -version = "0.18.1" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3589659543c04c7dc5526ec858591015b87cd8746583b51b48ef4353f99dbcda" +checksum = "5c0ca2990f7f78a72c4000ddce186db7d1b700477426563ee851c95ea3c0d0c4" dependencies = [ "base64 0.22.1", + "evmap", "http-body-util", "hyper", "hyper-rustls", @@ -5802,9 +5859,9 @@ dependencies = [ [[package]] name = "metrics-util" -version = "0.20.1" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdfb1365fea27e6dd9dc1dbc19f570198bc86914533ad639dae939635f096be4" +checksum = "55ff5c12b797ebf094dc7c1d87e905efc0329cba332f96d51db03875441012b5" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -5813,6 +5870,7 @@ dependencies = [ "quanta", "rand 0.9.4", "rand_xoshiro", + "rapidhash", "sketches-ddsketch", ] @@ -5937,11 +5995,10 @@ dependencies = [ [[package]] name = "multihash" -version = "0.19.4" +version = "0.19.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ace881e3f514092ce9efbcb8f413d0ad9763860b828981c2de51ddc666936c" +checksum = "577c63b00ad74d57e8c9aa870b5fccebf2fd64a308a5aee9f1bb88e4aea19447" dependencies = [ - "no_std_io2", "unsigned-varint", ] @@ -5962,15 +6019,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "no_std_io2" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a3564ce7035b1e4778d8cb6cacebb5d766b5e8fe5a75b9e441e33fb61a872c6" -dependencies = [ - "memchr", -] - [[package]] name = "nom" version = "7.1.3" @@ -10473,9 +10521,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.38" +version = "0.23.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f9466fb2c14ea04357e91413efb882e2a6d4a406e625449bc0a5d360d53a21" +checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" dependencies = [ "aws-lc-rs", "log", @@ -10501,9 +10549,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.0" +version = "1.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" dependencies = [ "web-time", "zeroize", @@ -10631,6 +10679,12 @@ dependencies = [ "hashbrown 0.13.2", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" @@ -11508,9 +11562,9 @@ dependencies = [ [[package]] name = "thin-vec" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "259cdf8ed4e4aca6f1e9d011e10bd53f524a2d0637d7b28450f6c64ac298c4c6" +checksum = "b0f7e269b48f0a7dd0146680fa24b50cc67fc0373f086a5b2f99bd084639b482" [[package]] name = "thiserror" @@ -12500,9 +12554,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.118" +version = "0.2.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" +checksum = "df52b6d9b87e0c74c9edfa1eb2d9bf85e5d63515474513aa50fa181b3c4f5db1" dependencies = [ "cfg-if", "once_cell", @@ -12513,9 +12567,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.68" +version = "0.4.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8" +checksum = "af934872acec734c2d80e6617bbb5ff4f12b052dd8e6332b0817bce889516084" dependencies = [ "js-sys", "wasm-bindgen", @@ -12523,9 +12577,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.118" +version = "0.2.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" +checksum = "78b1041f495fb322e64aca85f5756b2172e35cd459376e67f2a6c9dffcedb103" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -12533,9 +12587,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.118" +version = "0.2.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" +checksum = "9dcd0ff20416988a18ac686d4d4d0f6aae9ebf08a389ff5d29012b05af2a1b41" dependencies = [ "bumpalo", "proc-macro2", @@ -12546,9 +12600,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.118" +version = "0.2.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" +checksum = "49757b3c82ebf16c57d69365a142940b384176c24df52a087fb748e2085359ea" dependencies = [ "unicode-ident", ] @@ -12616,9 +12670,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.95" +version = "0.3.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d" +checksum = "2eadbac71025cd7b0834f20d1fe8472e8495821b4e9801eb0a60bd1f19827602" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/Cargo.toml b/Cargo.toml index 73b80026..79bdf6f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "builder" -version = "1.0.0-rc.8" +version = "1.0.0" description = "signet builder example" edition = "2024"