From 130762c3d9687b5b65f67eaa1cc5d4d9f3369790 Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Wed, 4 Dec 2024 15:31:54 -0700 Subject: [PATCH 01/59] wip: eth_sendRawTransactionConditional --- world-chain-builder/Cargo.lock | 1 + world-chain-builder/Cargo.toml | 2 +- world-chain-builder/src/rpc/bundle.rs | 40 +++++++++++++++++++++++++++ world-chain-builder/src/rpc/mod.rs | 6 ++-- 4 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 world-chain-builder/src/rpc/bundle.rs diff --git a/world-chain-builder/Cargo.lock b/world-chain-builder/Cargo.lock index a0bd3279..8c84e87f 100644 --- a/world-chain-builder/Cargo.lock +++ b/world-chain-builder/Cargo.lock @@ -13537,6 +13537,7 @@ dependencies = [ "ethers-core 2.0.14 (git+https://github.com/gakonst/ethers-rs)", "futures", "hex", + "jsonrpsee", "op-alloy-consensus", "op-alloy-network", "op-alloy-rpc-types", diff --git a/world-chain-builder/Cargo.toml b/world-chain-builder/Cargo.toml index 0a88413b..1bdfabe4 100644 --- a/world-chain-builder/Cargo.toml +++ b/world-chain-builder/Cargo.toml @@ -62,7 +62,6 @@ alloy-rlp = "0.3.4" alloy-eips = { version = "0.5.4", default-features = false } alloy-genesis = { version = "0.5.4", default-features = false } -# revm # revm revm = { version = "17.0.0", features = ["std"], default-features = false } revm-inspectors = "0.10.0" @@ -74,6 +73,7 @@ revm-precompile = "11" # 3rd party +jsonrpsee = { version = "0.24", features = ["server", "macros"] } tokio = { version = "1", features = ["full"] } futures = "0.3" chrono = "0.4" diff --git a/world-chain-builder/src/rpc/bundle.rs b/world-chain-builder/src/rpc/bundle.rs new file mode 100644 index 00000000..53da808d --- /dev/null +++ b/world-chain-builder/src/rpc/bundle.rs @@ -0,0 +1,40 @@ +use alloy_rpc_types::erc4337::ConditionalOptions; +use jsonrpsee::{core::RpcResult, proc_macros::rpc}; +use reth::{ + rpc::{api::eth::helpers::LoadTransaction, eth::RpcNodeCore}, + transaction_pool::TransactionPool, +}; +use reth_provider::BlockReaderIdExt; +use revm_primitives::{Bytes, B256}; + +use crate::pool::tx::WorldChainPooledTransaction; + +use super::WorldChainEthApi; + +/// Trait interface for `eth_sendRawTransactionConditional` +#[cfg_attr(not(test), rpc(server, namespace = "eth"))] +#[cfg_attr(test, rpc(server, client, namespace = "eth"))] +pub trait EthTransactionsExt: LoadTransaction { + #[method(name = "sendRawTransactionConditional")] + fn send_raw_transaction_conditional(&self, tx: Bytes, options: ConditionalOptions) -> RpcResult; +} + +/// WorldChainEthApi Extension for ERC-4337 Conditionally Included +/// +/// Bundled Transactions +pub struct WorldChainEthApiExt { + inner: WorldChainEthApi, +} + +impl EthTransactionsExtServer for WorldChainEthApiExt +where + Self: LoadTransaction< + Pool: TransactionPool, + Provider: BlockReaderIdExt, + >, + N: RpcNodeCore, +{ + fn send_raw_transaction_conditional(&self, tx: Bytes, options: ConditionalOptions) -> RpcResult { + Ok(B256::default()) + } +} diff --git a/world-chain-builder/src/rpc/mod.rs b/world-chain-builder/src/rpc/mod.rs index d098c3bf..00effe91 100644 --- a/world-chain-builder/src/rpc/mod.rs +++ b/world-chain-builder/src/rpc/mod.rs @@ -1,11 +1,11 @@ //! OP-Reth `eth_` endpoint implementation. -pub mod receipt; -pub mod transaction; - mod block; +pub mod bundle; mod call; mod pending_block; +pub mod receipt; +pub mod transaction; use alloy_primitives::U256; use alloy_rpc_types::TransactionInfo; use derive_more::derive::Deref; From cabf7bf34e1dfc53e611db14aac0e2362f2c4cf8 Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Thu, 5 Dec 2024 11:12:20 -0700 Subject: [PATCH 02/59] more complete implementation --- world-chain-builder/src/rpc/bundle.rs | 141 ++++++++++++++++++++++---- 1 file changed, 122 insertions(+), 19 deletions(-) diff --git a/world-chain-builder/src/rpc/bundle.rs b/world-chain-builder/src/rpc/bundle.rs index 53da808d..3897f172 100644 --- a/world-chain-builder/src/rpc/bundle.rs +++ b/world-chain-builder/src/rpc/bundle.rs @@ -1,40 +1,143 @@ -use alloy_rpc_types::erc4337::ConditionalOptions; -use jsonrpsee::{core::RpcResult, proc_macros::rpc}; +use crate::pool::tx::WorldChainPooledTransaction; +use alloy_eips::BlockId; +use alloy_rpc_types::erc4337::{AccountStorage, ConditionalOptions}; +use derive_more::derive::Deref; +use jsonrpsee::{ + core::{async_trait, RpcResult}, + proc_macros::rpc, + types::{ErrorCode, ErrorObjectOwned}, +}; + use reth::{ - rpc::{api::eth::helpers::LoadTransaction, eth::RpcNodeCore}, + rpc::{api::eth::helpers::{EthTransactions, LoadTransaction}, eth::RpcNodeCore}, transaction_pool::TransactionPool, }; -use reth_provider::BlockReaderIdExt; -use revm_primitives::{Bytes, B256}; - -use crate::pool::tx::WorldChainPooledTransaction; - -use super::WorldChainEthApi; +use reth_provider::{BlockReaderIdExt, StateProviderFactory}; +use revm_primitives::{Address, Bytes, FixedBytes, HashMap, B256}; /// Trait interface for `eth_sendRawTransactionConditional` #[cfg_attr(not(test), rpc(server, namespace = "eth"))] #[cfg_attr(test, rpc(server, client, namespace = "eth"))] +#[async_trait] pub trait EthTransactionsExt: LoadTransaction { #[method(name = "sendRawTransactionConditional")] - fn send_raw_transaction_conditional(&self, tx: Bytes, options: ConditionalOptions) -> RpcResult; + async fn send_raw_transaction_conditional( + &self, + tx: Bytes, + options: ConditionalOptions, + ) -> RpcResult; } -/// WorldChainEthApi Extension for ERC-4337 Conditionally Included -/// +/// WorldChainEthApi Extension for ERC-4337 Conditionally Included +/// /// Bundled Transactions -pub struct WorldChainEthApiExt { - inner: WorldChainEthApi, +#[derive(Clone, Deref, Debug)] +pub struct WorldChainEthApiExt { + #[deref] + inner: S, +} + +#[async_trait] +impl EthTransactionsExtServer for WorldChainEthApiExt +where + Self: LoadTransaction< + Pool: TransactionPool, + Provider: BlockReaderIdExt + StateProviderFactory, + >, + S: EthTransactions, + ::Provider: StateProviderFactory +{ + async fn send_raw_transaction_conditional( + &self, + tx: Bytes, + options: ConditionalOptions, + ) -> RpcResult { + self.validate_options(options)?; + self.inner + .send_raw_transaction(tx) + .await + .map_err(Into::into) + } } -impl EthTransactionsExtServer for WorldChainEthApiExt +impl WorldChainEthApiExt where Self: LoadTransaction< Pool: TransactionPool, - Provider: BlockReaderIdExt, + Provider: BlockReaderIdExt + StateProviderFactory, >, - N: RpcNodeCore, + S: EthTransactions, + ::Provider: StateProviderFactory { - fn send_raw_transaction_conditional(&self, tx: Bytes, options: ConditionalOptions) -> RpcResult { - Ok(B256::default()) + pub fn new(inner: S) -> Self { + Self { inner } + } + + /// Validates the conditional inclusion options provided by the client. + /// + /// reference for the implementation + /// See also + pub fn validate_options(&self, options: ConditionalOptions) -> RpcResult<()> { + let latest = self + .provider() + .block_by_id(BlockId::latest()) + .map_err(|_| ErrorObjectOwned::from(ErrorCode::InternalError))? + .ok_or(ErrorObjectOwned::from(ErrorCode::InternalError))?; + + if let Some(min_block) = options.block_number_min { + if min_block > latest.number { + return Err(ErrorObjectOwned::from(ErrorCode::from(-32003))); + } + } + + if let Some(max_block) = options.block_number_max { + if max_block <= latest.number { + return Err(ErrorObjectOwned::from(ErrorCode::from(-32003))); + } + } + + if let Some(min_timestamp) = options.timestamp_min { + if min_timestamp > latest.timestamp { + return Err(ErrorObjectOwned::from(ErrorCode::from(-32003))); + } + } + + if let Some(max_timestamp) = options.timestamp_max { + if max_timestamp <= latest.timestamp { + return Err(ErrorObjectOwned::from(ErrorCode::from(-32003))); + } + } + + Ok(()) + } + + /// Validates the account storage slots/storage root provided by the client + /// + /// Matches the current state of the account storage slots/storage root. + /// TODO: We need to throttle the number of accounts that can be validated at once for DOS protection. + pub fn validate_known_accounts(&self, known_accounts: HashMap) -> RpcResult<()> { + let state = self + .provider().state_by_block_id(BlockId::latest()).map_err(|_| ErrorObjectOwned::from(ErrorCode::InternalError))?; + + for (address, storage) in known_accounts.iter() { + match storage { + AccountStorage::Slots(slots) => { + for (slot, value) in slots.iter() { + let current = state.storage(*address, slot.clone().into()).map_err(|_| ErrorObjectOwned::from(ErrorCode::InternalError))?; + if let Some(current) = current { + if FixedBytes::<32>::from_slice(¤t.to_be_bytes::<32>()) != *value { + return Err(ErrorObjectOwned::from(ErrorCode::from(-32003))); + } + } else { + return Err(ErrorObjectOwned::from(ErrorCode::from(-32003))); + } + } + } + AccountStorage::RootHash(root) => { + + } + } + } + Ok(()) } } From f57a95b52f4f3faad2c9fccfd797bf5c889ca02b Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Thu, 5 Dec 2024 15:41:02 -0700 Subject: [PATCH 03/59] full conditional evaluation within rpc --- .../bin/world-chain-builder.rs | 10 +- world-chain-builder/src/rpc/bundle.rs | 96 +++++++++++-------- 2 files changed, 65 insertions(+), 41 deletions(-) diff --git a/world-chain-builder/bin/world-chain-builder.rs b/world-chain-builder/bin/world-chain-builder.rs index 4d98cb22..90f74d7c 100644 --- a/world-chain-builder/bin/world-chain-builder.rs +++ b/world-chain-builder/bin/world-chain-builder.rs @@ -3,6 +3,8 @@ use reth_optimism_cli::chainspec::OpChainSpecParser; use reth_optimism_cli::Cli; use world_chain_builder::node::args::ExtArgs; use world_chain_builder::node::builder::WorldChainBuilder; +use world_chain_builder::rpc::bundle::EthTransactionsExtServer; +use world_chain_builder::rpc::bundle::WorldChainEthApiExt; #[cfg(all(feature = "jemalloc", unix))] #[global_allocator] @@ -23,7 +25,6 @@ fn main() { if std::env::var_os("RUST_LOG").is_none() { std::env::set_var("RUST_LOG", "info,reth=info"); } - if let Err(err) = Cli::::parse().run(|builder, builder_args| async move { let data_dir = builder.config().datadir(); @@ -32,6 +33,13 @@ fn main() { builder_args.clone(), data_dir.data_dir(), )?) + .extend_rpc_modules(move |ctx| { + let provider = ctx.provider().clone(); + let pool = ctx.pool().clone(); // Can we clone here? + let eth_api_ext = WorldChainEthApiExt::new(pool, provider); + ctx.modules.merge_configured(eth_api_ext.into_rpc())?; + Ok(()) + }) .launch() .await?; diff --git a/world-chain-builder/src/rpc/bundle.rs b/world-chain-builder/src/rpc/bundle.rs index 3897f172..0ec579b8 100644 --- a/world-chain-builder/src/rpc/bundle.rs +++ b/world-chain-builder/src/rpc/bundle.rs @@ -1,17 +1,13 @@ -use crate::pool::tx::WorldChainPooledTransaction; +use crate::{pool::tx::WorldChainPooledTransaction, primitives::recover_raw_transaction}; use alloy_eips::BlockId; use alloy_rpc_types::erc4337::{AccountStorage, ConditionalOptions}; -use derive_more::derive::Deref; use jsonrpsee::{ core::{async_trait, RpcResult}, proc_macros::rpc, types::{ErrorCode, ErrorObjectOwned}, }; -use reth::{ - rpc::{api::eth::helpers::{EthTransactions, LoadTransaction}, eth::RpcNodeCore}, - transaction_pool::TransactionPool, -}; +use reth::transaction_pool::{PoolTransaction, TransactionOrigin, TransactionPool}; use reth_provider::{BlockReaderIdExt, StateProviderFactory}; use revm_primitives::{Address, Bytes, FixedBytes, HashMap, B256}; @@ -19,7 +15,7 @@ use revm_primitives::{Address, Bytes, FixedBytes, HashMap, B256}; #[cfg_attr(not(test), rpc(server, namespace = "eth"))] #[cfg_attr(test, rpc(server, client, namespace = "eth"))] #[async_trait] -pub trait EthTransactionsExt: LoadTransaction { +pub trait EthTransactionsExt { #[method(name = "sendRawTransactionConditional")] async fn send_raw_transaction_conditional( &self, @@ -31,21 +27,17 @@ pub trait EthTransactionsExt: LoadTransaction { /// WorldChainEthApi Extension for ERC-4337 Conditionally Included /// /// Bundled Transactions -#[derive(Clone, Deref, Debug)] -pub struct WorldChainEthApiExt { - #[deref] - inner: S, +#[derive(Clone, Debug)] +pub struct WorldChainEthApiExt { + pool: Pool, + client: Client, } #[async_trait] -impl EthTransactionsExtServer for WorldChainEthApiExt +impl EthTransactionsExtServer for WorldChainEthApiExt where - Self: LoadTransaction< - Pool: TransactionPool, - Provider: BlockReaderIdExt + StateProviderFactory, - >, - S: EthTransactions, - ::Provider: StateProviderFactory + Pool: TransactionPool + Clone + 'static, + Client: BlockReaderIdExt + StateProviderFactory + 'static, { async fn send_raw_transaction_conditional( &self, @@ -53,28 +45,39 @@ where options: ConditionalOptions, ) -> RpcResult { self.validate_options(options)?; - self.inner - .send_raw_transaction(tx) + let (recovered, _) = recover_raw_transaction(tx.clone())?; + let pool_transaction = WorldChainPooledTransaction::from_pooled(recovered); + + // submit the transaction to the pool with a `Local` origin + let hash = self + .pool() + .add_transaction(TransactionOrigin::Local, pool_transaction) .await - .map_err(Into::into) + .map_err(|_| ErrorObjectOwned::from(ErrorCode::InternalError))?; + + Ok(hash) } } -impl WorldChainEthApiExt +impl WorldChainEthApiExt where - Self: LoadTransaction< - Pool: TransactionPool, - Provider: BlockReaderIdExt + StateProviderFactory, - >, - S: EthTransactions, - ::Provider: StateProviderFactory + Pool: TransactionPool + Clone + 'static, + Client: BlockReaderIdExt + StateProviderFactory + 'static, { - pub fn new(inner: S) -> Self { - Self { inner } + pub fn new(pool: Pool, client: Client) -> Self { + Self { pool, client } + } + + pub fn provider(&self) -> &Client { + &self.client + } + + pub fn pool(&self) -> &Pool { + &self.pool } /// Validates the conditional inclusion options provided by the client. - /// + /// /// reference for the implementation /// See also pub fn validate_options(&self, options: ConditionalOptions) -> RpcResult<()> { @@ -112,29 +115,42 @@ where } /// Validates the account storage slots/storage root provided by the client - /// + /// /// Matches the current state of the account storage slots/storage root. /// TODO: We need to throttle the number of accounts that can be validated at once for DOS protection. - pub fn validate_known_accounts(&self, known_accounts: HashMap) -> RpcResult<()> { + pub fn validate_known_accounts( + &self, + known_accounts: HashMap, + ) -> RpcResult<()> { let state = self - .provider().state_by_block_id(BlockId::latest()).map_err(|_| ErrorObjectOwned::from(ErrorCode::InternalError))?; + .provider() + .state_by_block_id(BlockId::latest()) + .map_err(|_| ErrorObjectOwned::from(ErrorCode::InternalError))?; for (address, storage) in known_accounts.iter() { match storage { AccountStorage::Slots(slots) => { for (slot, value) in slots.iter() { - let current = state.storage(*address, slot.clone().into()).map_err(|_| ErrorObjectOwned::from(ErrorCode::InternalError))?; + let current = state + .storage(*address, slot.clone().into()) + .map_err(|_| ErrorObjectOwned::from(ErrorCode::InternalError))?; if let Some(current) = current { - if FixedBytes::<32>::from_slice(¤t.to_be_bytes::<32>()) != *value { - return Err(ErrorObjectOwned::from(ErrorCode::from(-32003))); + if FixedBytes::<32>::from_slice(¤t.to_be_bytes::<32>()) != *value + { + return Err(ErrorCode::from(-32003).into()); } } else { - return Err(ErrorObjectOwned::from(ErrorCode::from(-32003))); + return Err(ErrorCode::from(-32003).into()); } } } - AccountStorage::RootHash(root) => { - + AccountStorage::RootHash(expected) => { + let root = state + .storage_root(*address, Default::default()) + .map_err(|_| ErrorObjectOwned::from(ErrorCode::InternalError))?; + if *expected != root { + return Err(ErrorCode::from(-32003).into()); + } } } } From 65abe7135b01faadff04d8306a9ab4f2a723b2c2 Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Mon, 9 Dec 2024 11:16:03 -0700 Subject: [PATCH 04/59] cleanup --- .../bin/world-chain-builder.rs | 2 +- world-chain-builder/src/rpc/bundle.rs | 6 +++-- world-chain-builder/src/test/e2e/mod.rs | 23 +++++++++++++++++-- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/world-chain-builder/bin/world-chain-builder.rs b/world-chain-builder/bin/world-chain-builder.rs index 90f74d7c..7da708a1 100644 --- a/world-chain-builder/bin/world-chain-builder.rs +++ b/world-chain-builder/bin/world-chain-builder.rs @@ -35,7 +35,7 @@ fn main() { )?) .extend_rpc_modules(move |ctx| { let provider = ctx.provider().clone(); - let pool = ctx.pool().clone(); // Can we clone here? + let pool = ctx.pool().clone(); let eth_api_ext = WorldChainEthApiExt::new(pool, provider); ctx.modules.merge_configured(eth_api_ext.into_rpc())?; Ok(()) diff --git a/world-chain-builder/src/rpc/bundle.rs b/world-chain-builder/src/rpc/bundle.rs index 0ec579b8..851eb6d8 100644 --- a/world-chain-builder/src/rpc/bundle.rs +++ b/world-chain-builder/src/rpc/bundle.rs @@ -4,7 +4,7 @@ use alloy_rpc_types::erc4337::{AccountStorage, ConditionalOptions}; use jsonrpsee::{ core::{async_trait, RpcResult}, proc_macros::rpc, - types::{ErrorCode, ErrorObjectOwned}, + types::{ErrorCode, ErrorObject, ErrorObjectOwned}, }; use reth::transaction_pool::{PoolTransaction, TransactionOrigin, TransactionPool}; @@ -84,7 +84,9 @@ where let latest = self .provider() .block_by_id(BlockId::latest()) - .map_err(|_| ErrorObjectOwned::from(ErrorCode::InternalError))? + .map_err(|e| { + ErrorObject::owned(ErrorCode::InternalError.code(), e.to_string(), Some("")) + })? .ok_or(ErrorObjectOwned::from(ErrorCode::InternalError))?; if let Some(min_block) = options.block_number_min { diff --git a/world-chain-builder/src/test/e2e/mod.rs b/world-chain-builder/src/test/e2e/mod.rs index f843de8c..1b728083 100644 --- a/world-chain-builder/src/test/e2e/mod.rs +++ b/world-chain-builder/src/test/e2e/mod.rs @@ -16,6 +16,7 @@ use crate::{ validator::WorldChainTransactionValidator, }, primitives::WorldChainPooledTransactionsElement, + rpc::bundle::{EthTransactionsExtServer, WorldChainEthApiExt}, }; use alloy_eips::eip2718::Decodable2718; use alloy_genesis::{Genesis, GenesisAccount}; @@ -24,7 +25,6 @@ use alloy_network::{Ethereum, EthereumWallet, TransactionBuilder}; use alloy_rpc_types::{TransactionInput, TransactionRequest}; use alloy_signer_local::PrivateKeySigner; use chrono::Utc; -use reth::builder::{NodeAdapter, NodeBuilder, NodeConfig, NodeHandle}; use reth::payload::{EthPayloadBuilderAttributes, PayloadId}; use reth::tasks::TaskManager; use reth::transaction_pool::{blobstore::DiskFileBlobStore, TransactionValidationTaskExecutor}; @@ -32,6 +32,10 @@ use reth::{ api::{FullNodeTypesAdapter, NodeTypesWithDBAdapter}, builder::components::Components, }; +use reth::{ + builder::{NodeAdapter, NodeBuilder, NodeConfig, NodeHandle}, + transaction_pool::Pool, +}; use reth_db::{ test_utils::{tempdir_path, TempDatabase}, DatabaseEnv, @@ -77,7 +81,7 @@ type NodeAdapterType = NodeAdapter< NodeTypesWithDBAdapter>>, >, >, - reth::transaction_pool::Pool< + Pool< TransactionValidationTaskExecutor< WorldChainTransactionValidator< BlockchainProvider< @@ -147,6 +151,13 @@ impl WorldChainBuilderTestContext { }, &path, )?) + .extend_rpc_modules(move |ctx| { + let provider = ctx.provider().clone(); + let pool = ctx.pool().clone(); + let eth_api_ext = WorldChainEthApiExt::new(pool, provider); + ctx.modules.merge_configured(eth_api_ext.into_rpc())?; + Ok(()) + }) .launch() .await?; let test_ctx = NodeTestContext::new(node, optimism_payload_attributes).await?; @@ -309,6 +320,14 @@ async fn test_invalidate_dup_tx_and_nullifier() -> eyre::Result<()> { Ok(()) } +#[tokio::test] +#[serial] +async fn test_send_raw_transaction_conditional() -> eyre::Result<()> { + let ctx = WorldChainBuilderTestContext::setup().await?; + println!("{:?}", ctx.node.rpc.inner.methods()); + Ok(()) +} + #[tokio::test] #[serial] async fn test_dup_pbh_nonce() -> eyre::Result<()> { From c49fc8d21d58602e111471fd3b5049660c33345c Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Mon, 9 Dec 2024 14:36:23 -0700 Subject: [PATCH 05/59] integration tests in k8's --- devnet/fixtures.sh | 1 - devnet/fixtures/fixture.json | 60 +++++++++---------- devnet/src/contracts/contract_deployer.star | 2 +- .../crates/assertor/src/main.rs | 25 ++++++-- world-chain-builder/src/rpc/bundle.rs | 51 ++++++++++------ world-chain-builder/src/test/e2e/mod.rs | 10 ++++ 6 files changed, 94 insertions(+), 55 deletions(-) diff --git a/devnet/fixtures.sh b/devnet/fixtures.sh index ad42edee..6b175f5e 100755 --- a/devnet/fixtures.sh +++ b/devnet/fixtures.sh @@ -1,7 +1,6 @@ #!/bin/bash set -e MNEMONIC="test test test test test test test test test test test junk" -# This needs to be configured to the enclave (public rpc ports are non-deterministic) export IDENTITY=11ff11 export INCLUSION_PROOF_URL="https://signup-orb-ethereum.stage-crypto.worldcoin.dev/inclusionProof" kurtosis_port=$(kurtosis port print world-chain wc-admin-world-chain-builder rpc) diff --git a/devnet/fixtures/fixture.json b/devnet/fixtures/fixture.json index b5f0d5fc..e20ae5f0 100644 --- a/devnet/fixtures/fixture.json +++ b/devnet/fixtures/fixture.json @@ -1,34 +1,34 @@ { "fixture": [ - "02f8698320d5e4800184335ed22382520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a052d7c7417dfc658695270cd2defb50c66e523a353d7b9bb3b9f87e0be290ce1fa07c5845922ced3eeebfde93a27758ad717c1ef9a2ca7449bb2a2b4655ebf050e8f901518b76312d3131323032342d30a007a8f6d5e120ce6f4c56e2b16a2894c7f550d2c42ae7ab8b6c7d66b054c15770a01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b901002a22b040c7972181464148b5310b4aef9d07385ed55b8625d7726a78737b54de09105cbb9dc790ceceb6d0b4b4b045d7928f9f53aabc0beb6b8382e5893ca8c111162106c047dd73c41f2a70f61439c5122f49c429d62f814d8b97fe7e13d37e04a9093763eecbfa2c8317441998d3ac4a6b0b9800eb606a98c2b606f7b9872508d08c99327482e690f7a2c2f09f5f334584c3059a48996d202732b13cb893f90cd7666efe1c4f53a6c88c118ff12c071888b373079be868da0b1c8887adfc5405d397f973c2d185db4fb2956d53553fa9846a9afb969f9a6e7902553db14f1c0effbc15efead6128249c4c8b3888f91495222d7f3d60f2086317365d8ec1c6b", - "02f8698320d5e4010184332aadb782520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a07d6689ed58ab599f16ce12faec878de1201467a9b81cca1b82080324ca26615fa0426ee71380d3d891ca0412ae784bba7ebf9a7b84220ca9f0b239f9ee2a4ce078f901518b76312d3131323032342d31a00a53f1f84232a7f8504dce48e4a7386aff2df5615a823fd3e26e6f39c1542bc0a01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b9010017a56966e9f5c126eba254a8fcc7fcaedcbadd3d5a6f8ea543d62c0eb1ab1e0f29d8fa3a2b3ca8991be01d066841bd1222c7a8ca0a1ad981c4bfa73ffda1aa9f0f787d0dc019f51f1fd5e049fa135e376d26e0faa94060a2f9cce9621c44313a20fd0d2514d732dcb68300110d11eb4c1b924cad4aac4c7a2e18819523eaa21829a5de1b9266bbdf99ef911db0155a1cd6cf220c92249f36d2ae6efda83633860b3feb4ee23cc4ab13456e5a3e09b95adb9573c1de218328e10ecda46cc17bed2472cdda9b1b7658dc92ca96ea1e6739a17c451de8606f4cc8db83039ace8dd71439547bf4e61c2f1d2133ff92e083b8288577e8bfb0809dabfffb2d841b3dfd", - "02f8698320d5e4020184332aadb782520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a0370b9d10a3205f5582dd2449efc5fda3f3e151effac3a74c702ffd968f227628a019c507ceb50746c66915f5ce52a87a2194143fae4096aeea1738e4c74a184d4ff901518b76312d3131323032342d32a021de698a79147d903dd5ac0677eb6768dd8cc6b42bf53aea80622e16c0796bdda01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b901001ffe4bd9371aba86e192f90fd852f85b239d2b6436a5328642780e5afe954bf323bf88e9668ec9dd62b40de7fd7472b2c761d7f641c55a07ce10bca222b1132e201e8a895c3a2d8b8910106ece52bba2acec6b65e36149e3f48afc57d1b38c3401d21853825b6a0910866630f62060cee2947d9442b77ab6d6690ec1ad62a4540a4ad502c20519c00f888cd78c2f1447efc137bcd4a5d8bd2725295b9e61843909bef3f13a882a2e316e8400c27053f163574b326923cb7068a653abc10dd34a0f5c6de7a450acb660163ef7182a40652c99a183d192e92d38c88088cda92a510e04ac4481abae33bb90ebe28b7770e69cd014f4bc22cec4937215c1eba5176e", - "02f8698320d5e4030184332aadb782520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a07d5ffd6da04f0121c08155f561f2d57e4746e1a6df445fb1d0d1cc0999247d2ba0587748970171e533193b30404d2aad8632a990905362e5eb9f562711eec89026f901518b76312d3131323032342d33a01dd98036fc23f133e024d061a1a0e73dc07ea082c864ec0ffcab192d6ec29024a01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b901002db45881c20f1f3c4095555aeb47d156de1a9adfefa38668be11135cce2047721cfc543f38c1d5f6cc7afae8b387c3428645baf6cb13f41fd2a0ba858a1e6bc1022e7e4ab00e77338fe42aac459ec0b45ae499de9e109cdb35a59bf4ac6a1bd7134e84a89f38278555b86db9304d17b26ee2bce882a6e66408c969828683395f0ccdebcc2b4b704bac1f5e379d801088160486b6cbf325c422d9b3d71839a84115f3c5ef0e6aab8e6711ab2714b8b98dcf70f7b1c1140b7e4e33d8a85b07b6582056c5a908b60590d47891692e556a8086e83570deeac10e1e6be4407418821b0d2ca10cd3573de0d5ec32404e09b34316e70339844e1b259d20513acb1f768b", - "02f8698320d5e404018432f6d4b982520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a01347e5c7729e7dca04dabf7a051ccf62bae35f0e5dd337c667c63d691ef98ae6a022c4f89d68c475e3dbf625410236cb67023332086d2be79c96a79384dd57f218f901518b76312d3131323032342d34a014adaa29be379eabbb6954f64d07242325f059aee63089d1f8c2633e007314eca01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b9010009902982c94b7c12d5a8a648c3bc3a9c2cad6f277e3b04500d9957435f930ee90456aa08779577eb14c1415f9c371cb1c3fb49a567db29b293e09f324856ec130b5f91e3a3db48ee5e3a233a314418d72d542c30c7b3ad01be8af43f57432ec326889156b2e292b612f2475f1a9c7392b32422435aa9b5728671e0e4863f07431f085649572ca01248c5f991ccbe1bd4dd5d5c544e6a3d2c656cdfcab0601470024053384b98214631be0ca676c4e0befba5176ae1ce3edad1ba8be19db7a8cb0667540efc35dba53765920e488a64a9ba45eed1625a36b20cf92c4895baa06b07a5a43e950133d756afb163e5a027a4b2e6933d6306e57409f94076f7a50ec6", - "02f8698320d5e405018432f6d4b982520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a03ab58bd23a7ec9bf47b55a3b39ac65d14da9635279595b51dcc7d1993b0582eda0673e39aadc625b03da2c7b189c599217fc617dc0f522440e2e6f664fee24812cf901518b76312d3131323032342d35a00f0c78c9423d85c1993699d1cbd06f2085b78ca7168ad99696c7d387c1a199d9a01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b901000c5dbf98247ff9bebb4b4d4cbe41fff50596ebc61dbcdba9186f037407393b1b0e75d9e4fce8d0b1e29163dc02b9baf2dd8320b36c84db02c968c68712fa6f482723450fa7a5b8037c065d4e22639604966d458fd8263ef3b921f9ec8871946020d4bd1d5be7dcf3f31625b030d960aebf5c267c829022543a5cce3c8c7793570e3ed038dee228da7f465dd3525514adc3363dd4123ab694ab7601017bc52e6c2e8c9cf8d1c7f845ae04ebc8c4d028f1fcc33d21f93ca3e3d6af0c368ccbbc1f19bc24b21f61498e80091822b5c86b4cc5dbd7546fab091722f733509629f2a318fa23339e94e2ba3f730e56d20f45cff82d88b288a5c3e223182d735be6eb11", - "02f8698320d5e406018432f6d4b982520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a0fd19f30d49f00758c2257ad1b81e89ac8e32dfdb78bc632da836ca3547742adca067e1a3b9fb5889f9e55a72e1a8a2015cdf1b209f9147c55707e2d30aaebc0daaf901518b76312d3131323032342d36a018812daf64da7ce18cd101dbbc110bbf2fb9bc7aa6dbb9d66010d5e59ccf1443a01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b90100146ba56c79b7ad5ee895600b5247f62611e46f0e046e268796bd66c7aa9dc5862c22b9ba60e6552d3bf8c7be29ba9d7c47dac33e5ffa38503ef4c337120fe7390daf489e7b22d28ae974afb5b871e86d03fe8bfc8a3a39ef68c0fecca011698c0df65f021a13dbddbcdc9324ffe8526613f8823914191b0df38db7ec595b27901eadc025bdfc437900abe79fcd906638d4f6a370572fb9db5295d1f3116649a00389b18820223d7366808450344cc73ee19e0e77e25faef84839421fc0e8fb2f052e1bdbeac923556202eaaf5e43121b250e5e8a82a00390df4a57bcf755f0fb2b74205667c7fd71aaef16bfaa43404ef37e6f88b44ca8a2de5035788a7d02a9", - "02f8698320d5e407018432c328c982520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a04d05edb2d55cef4b8db8d71cdb5a06e6041deba8d19cd9eb62a5a8ad00b0a2a6a041ba97e3be27baa6af04409739c0d8f744b0810846b86298ae0a3cceb2236c15f901518b76312d3131323032342d37a0286b4fd2cd5ecf8cb65ce8cf390a316317096056cce4ded6e9608657ad26ff41a01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b9010006f1984e0d9ae129a0684f12594e3e7d6a6d3f43da483036db00336d913a394f2409e8ff8e27b8d219f26393d1ddcbe55c9a8a6626b00f1353dfd0279242458b122791bf1c0630ddb5d5d067426125a814b285ecfa0a42899dba4fc0a07105d0078c301e559afd358a54f3972595bab29b70e90d7cef2432fcd28457582aab3f071d0e4d7268f587e27bfc31f03c23675650ddc3480de1ed10b399b87a28a0141304f36d7df254332f3165edb82f6cbbed414f06395a53792df6b2fa4021c1d21cbe96fc2c7b813ba656a5a3a052ea35c5f6edf6319f12de50553236c575f2b20e6502623a4db2137525a334f6bfcd69667d9be40c891dfcea3348296c125daa", - "02f8698320d5e408018432c328c982520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a076d8476eb319e712b121bd08a2e93a6a346912be04bd822f16cfdbe237a8f361a07577f820dab2fe3d41401825b57feed95247421c68e3bd262fe63fb434156c22f901518b76312d3131323032342d38a00f7fc141389a0bc890ec14be608f97794bbb712dff506e2abd9a0614c1ba1e32a01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b901002be531877cdb26f3f4c68cac91b28c2e1c00796b4f8b12a8cbd2c2621d4b0c611bf3211f7a9e34c7b4070f20b7435ad2bc2bbbe676b39be8b44f5a84f0f3c0e4018d5541d390e25ca0dbd0425441e59ab1b5654ccdc31ff6cd8c502dca9233c607916c5524c04860faec98ae3e907e74c389f227e096729af09bbb338daa3f880c6e6c28c51c23a8df5e73240f9ad6908db362149e8cee20e5d5fcf81d3bb6f62aa50bbac1c00b593436387e08e71036fcff266c0765d5c15d7eb12613e574ea1d8142a58f14cf5e183193723fded29eab4825a8fe5ebe0e5ad709f51600b8df0d202f5684d3c9103c5742911b5e17e5dc7865d91db0f73607dbf064b987ecb5", - "02f8698320d5e409018432c328c982520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a02eddd704c1d8926ff1e4ca08ad92b62499b2ba8314288314331d01f7461a47eaa025d15d70fac40c54d3afd8a4b64a3a08ab3a57455b9a1c3fcbe5e2ed225e2da6f901518b76312d3131323032342d39a004d77335edbc57aa710e7b5a4652a16d809619e767027c5ff61b7c088f812e82a01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b90100133d44a85fc3cfe07c5e156aaf2de901bf1ecf9573e4f1467626f86e704bcc122fa1e98306354aa521bc6d07867002776f231e910b6a6ff4de9b80096e11429a1154e8f7d4a15c4c2c510d3d3ca26e230382a1c1a87b81dda692cfcce8212c28067fb3f616d1dbfe859a90b54da6d86d6252650b8c7b37c4b50a7f1fce455ffa0c7958435aa50ba8f948fe46f095e543c1fa02b1693bc64e4c858e4c91033747145c3c053092a656803f8eab5c8724eed88e8863cbdf61940412ba95df5705db132e0769621a5e985e557de605fbe3b9f5756e7dfdbd5614c92590000642a2e3052d737e56c1e98310468a8a6e3eb526bc079d520852b0b4c2518c197c855135", - "02f8698320d5e40a018432c328c982520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a0b7c3c22691bb8a0a519b3cb65697f2805485a444500064604855a3877502a1c4a04ec90ab0d3d502327a03e5a74a7cc8f7a1b19cd366016497fe1a5185e7dc2ccff901528c76312d3131323032342d3130a02a43e5e5b7d2768ba398b8097c50a8982a5b282419184a4b3f9cd7eb063bb579a01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b901000fa8cce01bb12cd6cc8d88f0740e8450eab25e537851a3cc9859fbb178b1dccd2b2b3aa45fa8e4b2709642027a2863f29939d199fd94a3fe15fc8d81b1808f952b5650125b548f0402b3d06670bc35c8f419b2d6245732c18ad5579bafadca7a003c76c957d4c2f02b37f57f48ef308124abd202a662fbe92d8bf836812888cf19aaa8bfc7e4a5d4ff52096754ab6255542cc5af1ff671ca350e3c7279fd44c62fda62e90adce8c4fc49d87b37ae5def31459414e94a0016dcca395d42d0be371dc43293ca823226b2b75658217d793c6f8921292cbc74a42eab8aad4bb53fc41d9e19fd294d62bb45cfcd1fed26c5516a8afc1b688672fdddbb63f349c151d1", - "02f8698320d5e40b0184328fa25d82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a0e8eb4be37e75d7be2281b19646c5ff005fd3e47a4161a93c4a59990c402454e0a04c4add2450e513449c44e6b7d47d2104b7a17b1cef8961684ccee8d797be4c2af901528c76312d3131323032342d3131a0092c64295c623a2699fc9190ee99bb79ed577c692ab87f7a34e2a68b84fd163ba01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b901000df501049e5975605df97d7e3278dd9abb95c3a7ae2e0fe410a04b29864dabda1887982e37a25cf3b2159a40892f3896497a10a856fbe192aa27640462da13bc05692275a44d69359165d3aecff40c41cdad373b5a37f4ebcab1b703b4463bd31611b99007a39f8c9d16b91d836b53e04a34594c6cd79e775795e74411cf52302bec4645ff688ddc18f85221d5dd892bb3cfa9a048abc7ce24f0d7de32bde3692d917a96b8f9449fa8c77a78ae6d0148bb4738c37f39d9465e8c5daa80b4f4c816cb6b94d9aa18892f955ec29f3c6555eed6d66baade8458ed0e9132c11cdfa109899c43e91379ad59c9ff9dd4ef3c8bdb7dbbc55ac21e49895bbca7c77f8802", - "02f8698320d5e40c0184328fa25d82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a0f859a8f1afb054dfbf36282721410818a938c32088858b42e3e128686aa8bea0a07dc939ed55fa314150bb7ce6884cb8e57481617ff82e9f3257551fe3aa7c1dc7f901528c76312d3131323032342d3132a0226d0c3af958aeec10d7ea6974a403b6e0e602a9bdd0aed1700eca663968cbb3a01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b9010021adb5b4759cf8781f6691d384e44acae0b90963e9f4d72b5ea5dab1a79373202fac968abbfcb3203e70cc0fda55a2bc3541a28de8caf25df7d36681a1ea9a360df5e7647c8726bb072349d5e60f62d7ae2ea3f4d342999cd348c892d916153c24e345c06cc9a685bb8c3b02f36a610d8a67174d7eb18afe7fd15f36a791c2d2072fd422640d56d7d58a0cdf549a861992401c67ea3ca6788cdceb81b402b4200229e70372c4d548038843ef5e9e5e714cfb9f8c90f6312600176d8fa35f910b1ae28e03745635e02167ad61c35817f32dcd8c5b7f3116a1e59b5a453bfeaf2701e3bd92497fccc4a4e78fa1dc6e81e6eadb5b5985df44aad8940f1c30d1a2c8", - "02f8698320d5e40d0184328fa25d82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a00201614b6abb8687819115c69ed1d8edd72b82f6b9edc7b792f66cdb6c7356c2a010875b88cb080719cc827fb5ff82d6cdc06a792431da01936a3c9b58cf61acdaf901528c76312d3131323032342d3133a00d4eeae1727c0fd4969680e770ed1fbf1c5b380c6dc137585450addea220d4cea01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b901000bd66a2b05abc5641b9be8b44376dc4da258cf8f8a0b8b575bc5e9d72c1420df29a2da3a2234919b510a15b030aea5501fd482b88ab8d7bc1c6165a724fd7a8e17ca7c90dc24cd95379c6721c17a000ba153c8265e639981acc0bfaa011943a814fef351f31bf5dbf25d2d1cf3406acd26c561b4255e6fda0e4029f2c385bf87162f4e5c495452749cd62947169afc07535bf2e07b06443cfb8a7e09470322421d9247f616dc1ffa2fe945e59bcf860abec711682e85da6eaff22100bb6d434c1ebffcfa780dfe14ac6f8863491367b013efc21aefad84278d5ff1c4a13b0e22152012cacbe1cad446b80740370ed08ef82aa51bff28e0731096524376919441", - "02f8698320d5e40e0184325c503d82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a03cca819bc0690c2a5e435e1183ce304c6f7ec2f0c70f45fce201f1619f1d0c7ba06b47c00db3c6121f9f007c395d78e19b33f1bd8d2fbbe828cf624c821fbb23e1f901528c76312d3131323032342d3134a0297d91a79b39c2828f1263918a608310e2c0b215d8d8bf3d796acf7eb91b144fa01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b9010013b14b768f7c98f20207b5328bbf52ef4576ff0ea53fa51b0c928dc0d38452f607bddd41868edc5a3dd563816c688f94485be72bea170a7dbfe1588f4ad2752714de10540e526cd7977ad747b2c799d3d7d94caec03b089c5b47c1da2e696a5d0ccffa71acfcc6ba82ff128ffc618ba3963d016b8ba6d53ec122aa678b2e00942edea055d07968d99bc1e4e0f0898a1919d5c8e7fadf205f23b0b34b8a596a0d12955d9579bf68221502b6893b63eec2f23be8e4347840dedef685a50e182e0e0f9d139b3dc3a75134144ab89fcf82cd61bccb21e2a982de435b558aeab8b88926ae50a10b0e907feb77ec2a94c2d9a3e65b445b87c09f8e92e33fe45cdaec03", - "02f8698320d5e40f0184325c503d82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a0836695e588ffe492837829732b4a915f4fc611cdcd0a67acfcbe083a7d68b114a0774f6ae0d3839ded42b65321a8dc5175b5f4822761736bcaa0ef841dff38d27af901528c76312d3131323032342d3135a01f4bf02b9a4e8a9b35d9abb004e1528c5fb4cad63d83b712a7d4b56321397f6ba01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b901001c4ca6953bfc94f4a3a320388279a831cae77e6bc66d0c0e5f67352c5fff11d808357efe458cd8d21322c479b7527b457639d259b82bc92982140927fce90a75092ad4e2011dfdd39237913791ed6f9642b28915a44749c4b450fb813c8200fa05e69192b74b6d105445f866ae895db02188ed52c169112e1b1236e67134e5660d5f411fa061432455129730a226328689f0f9853a339c5370612d884cc7ed8b22f60d0debc446bff7e1cb94a830d2bb4a82daec5bee4ea41034e43ede179f2617f8c4a1a99545f3405fa50da2f4e3077f6bfc936d064cb4b4c41789b081856b12e3c4eea74737e0be80355603f5e08cab125d6a1551b2904036b93fd09b8e7b", - "02f8698320d5e4100184325c503d82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a0d9f2554b303656edd236195d84b4ee932d38fd5813fb00597208646bca55dd35a0793ee62f362a69e9a14e622741cd0de8722349b3ce8860bfa7115eb0305f1276f901528c76312d3131323032342d3136a0198c05615dd38da811c142af7a34d10c72b4b0fe49e28b54573072538b1c3178a01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b9010003e0512fe85656efa1284237c83a5ac4c2d244239261029fdc9ec1ea9cfff4950358f95ab11dcae444f8fcf5f3544eb0c52d1c4b4581ddff0a7d59b93afec13a2fa71ac1f8c45084d05a376e8ddb82bfe989c890f3e1eab5d12a8a51cd4a6b761049ac49d7c2a393bdb990feabdaf3e883b74fc9ca0b988c845b1d822a7c7f781a58b2d595ab3d68ca3c5329afeaa59dbcf23579fd849d796837af281686d1131d3a9f6aa23ad07f3113125cc0b2fce3a2ae01b994a11b0fa3adb11b3c2ab1750ea177199535a86631c89daa70779fbecc6d4a41d47273e5dad255cf47f81b7b08ea2062cf6c385b07f1eb45ff3b33827a4b85e3bf6a5f596c28afa3450880a6", - "02f8698320d5e41101843229323582520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a0821696c6f3c7debdf1012fb4072d62bf7bcdb10fb2ef2407479d6db00445ee3ba0690a84e97005890ae0bd42494768694ff2032fc9a170d241baa9b78fc2707171f901528c76312d3131323032342d3137a009231c99d81685d2db253c3e0f856c631321f65f0d99c0cde09512fb0d6a6530a01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b901002acd52d9c700fe70a56b561a3458d2ec69df071c461351f3f7cd771597b82ed61243e5835e5d43fe881ad8c24558ecfd9e96b931efac9e6db718b9a9d07111f40ad68cf2991386d3c06023020438aa08f6451264fc6790e8ab610fdbbfc23cc313084ae6494a7b11a69f63a4b96dfdee135df0b7993eb3de78d383d0cba4c4e80f87e9db7cc08acbcf8072972e3227a9ca4dfacfa48627ad5babc57747507d942f262021e76c8528776ee79726408256b192c1ac7d665eae5def36597d6406a71ef28c94df343b247a651b5e98da9fa1bef7143e4b0a5bef7e0582c7bfdb252a06ac7ef9218588286339c2542e19789f5598c797364740ed66f3f736dc0911d5", - "02f8698320d5e41201843229323582520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a045aa736b2fa8e80ec5df1c2f2e277f4446fa592d1a732fc612399e4665f5808aa017fbaf947c1ca5040256ed055cd2d783cf0db07b75e5596777d6e8bb4ab290ccf901528c76312d3131323032342d3138a016f48f5f963c8faf3286abd01fca8809ed31f3d6680f7f0ca6bb4bfd8b26c17aa01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b9010017f5bd3f363c890afa4b28b7e7f84af275b3c1fa928a487375a8dc17f16be86e2d98774b78f732f16c291a10017786ef167e854f4c7d689a3c03e894cbaefe6b0a0daea31b58c5687711edebf64505e2b29f335d2d32671394be17df78b3f2a60c0d63f0e597d0c9e89e42d299b84c282b64335f7666872415e00fd311f71eab27848adbdcbdcebcdcd774108cb6cf8c1ba25a9b835b6466d1e7dec3a8597d9b06e1098bfdc5a8f48cad22acdbcda1d9c2911bfe7e25dcebaccf62f6a4eb49200f8150aa02722e2b222afe9eac3cf19c441444c5c3b39544fe8f28b7e353815f2855077ffec1d1f79a0495b1d72c0d1ca366c181dd0da91935c0a51c2afe20f3", - "02f8698320d5e41301843229323582520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a01c689d218a489ea07b04ea25671831c3f093a5d9bc6066123a3342f6994dcc52a040786307e461bd99ba31e5e20640aac4a8d0b907d5bd93973979328ae048a260f901528c76312d3131323032342d3139a026d71f2f1d8425e68de33996abd3a4ffd86fb605ecb5b699955fc4bf8db34ccca01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b90100084282c3aeaf395583eddbc2a4a57094829fcd1d3302ca699b899bf52fc2a6112eb0f059943c28dbe96ca2bc8cdb6ca7af942e3f18dd3a95dc7e2c431dd729050368adc47221cc941ab5510cf9a142977d96a7e9bd564cbd19732af6219c6fa61242dfc437a79beff12b77c63e546599e49e81319d9e24aa7c4c92acd59628dc20cf265258f0d6751df996c12bb96ebc3c19beb64f5cc1030082644882d162131ab8840424824d66265be57307bee7e6da779a9545969c48e9fe0507817527f8013a447397e219cd2438b70517785ac7762da9c3b5fb87b29835486c406176bf0c438ece40f0779a564a1458268c1e5bfa2d6b6eb9a7ee25f965449969935778", - "02f8698320d5e41401843229323582520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a06b438fe3af2c54c70a2fd561feb343903b7c99e136f7446d0b4dd2cb6af46ff3a030ce316aa75052e02240162824ad1097a7f96a020a92273b8f3e1206bd94c4b5f901528c76312d3131323032342d3230a025ca3a9fb73bfc95ced301e055c30841e9e8900baa8fd8eb9cc05dd953c28b8ea01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b901000a687747c2eba62f4dd43a3b5e602cbe6f4a469c158c156819703bad066548df16180bbfe0b6257f08eda14d77c1abf5473d8ef698f6d9c93c41a90d9b8c36d410b17e8f736958a5e70ec2a7335acebc51e9d15aca27e7e034ea934a208efa6d174094c7d93376ceebe4196fb13d97d79c19d8b69d80f6db85e995ada61e6e011acba1dbe5f95e2c9719366476f98f44f21e25f51528a71298c392611f405dd7229db448b1d36650d9241c4ff8c6c09bf67a8b7f56fc20279acb7627c71f05922ea8fb7d501728d6f179030ee3772bf9701f798f220aef7f369837fe5bc4c2b500bc306db8e76100dcc5b952d0cf448f3a589de4abd07375b34fb167ba77acbc", - "02f8698320d5e415018431f6480f82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a027ec764ebfbaf1db67cce38f2e4593b0872e52d1f4d4c69c7a9c48ec7b118a7da03b5a1ccb024b5acee5305c52dffb5662f1bcc305106d60d69c0e9d05afbd8931f901528c76312d3131323032342d3231a02576defe21b53aec866b22bf0101981cc372bad99afd14c4d5732cf26059e90da01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b90100257b175dc5a0e8a47f51335e9a4f39c59c04dd640ec12e00c58143444a64387b010f30c3cb8c03c65a4f71ab5cd48d668c41e79439fc4da6b36cfb94c89a7371049c057462d8da974a8c6cd60bbbcfcd043132ecf660ba717c36b7d9ddffe19f1bccce3a56203e053992d615c05c5d78ad796a253a328f3cf51f027c5a4300d61d7d47773716adab7f919c64d5033455940d74a11f25049ed65bd7fc385794c3197577ae45c85ba08aa506c5b41906d7353dc7bfeda8e2ecb679303679a17f91172c9e73a4c287b4160393ea9406451db92027dd877b042e6d68fbc63cf205602388cb0a0eb40cd54627e6fbd703ecec0df56a6c8972b095a4d7152f41767181", - "02f8698320d5e416018431f6480f82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a02798941597378868330229a7a1730a9bcd65d0c2f44542eb393894d77e368700a03e3f255b217a6c2bb219f710f5f9236dacad17037a88dd9ad4d78381c4495438f901528c76312d3131323032342d3232a0026b6ff1b607164dfcae7192cc8936455d28d546c27b6a4c04e9f89ad0fabb28a01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b9010020060a1dc489d1b7492b2da9dfd0866f424ba24c26e2c2dc8c4bd3a939fc356d0f1f45fc4fae9d780577de0d23aec00754792532b9ddfcdd593659c1688546a503cc2fde21311ccfab5b431bb2a3953d1f7337ed0688f29d96aa657845757fd90f957a52870813666df05821062d01dc1cd067b01139314986d9bef33a9e19f623a1996c2b17ddc8a28a3014474f905b9b3b753aecfe90f75a0bc74cbd7d21821c138773779413e3d08925ca046002e657122777098bba85b57e62bdf3ee052814516c2b1c96d3917e9f8042072d39053cce989bb3d6d244a571c2c0a64c64142f3eb287b6f5ea20f3e684a3042bde2fc4d221657d63457dab56330888c27a34", - "02f8698320d5e417018431f6480f82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a01f86447951077fb8451a35c48b2f248d3baa657c5260786dd60132d7aaff6d73a049a7e69e348d8221df61af87fab350e775427aa87b670523b2a23544e35b3a7cf901528c76312d3131323032342d3233a0118b0adc80f69e7c754cb9a03bc9bf3c5be4076b78705e3e09c1993fcc9d7c7ca01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b901001729e030605d46f20a86bee565c07404f89e0b2908b0e0d5de47a351bc51810329efbb7b7a10c8a1a711cf75eb98842266000d078b3f9827f6a58c76b12201a92b46a3842d46565af1869807468adafc8005385ee958598744f15b6042472630290943fa44712a790e3246d5bba49fabc28d1c830de7a2996e81a7f566d482d802f2676f21a5a9fa81c7c7deee662958dbc12fe7808ad07ad671296c2887fe212b8e417dfce012ed130dc683119ca5ae2cfe0d0e92fe49c63a88df8a48c6a34c27eb87bf5a65184a025227f0a2d544eba0c63b651b8468c99f805e5f0a8be3ca1afe2c1384618f0aedea218f36bac1c94e5969663924e29af05947ed26e8386c", - "02f8698320d5e418018431c3a79182520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a0436a71ced8891580c08d2c3204897af45ac55c26a37c9ee1d0f45dd5882e15e8a05501ae37809a234e7eb3fc27f86102847d17b895983fbd9b1f2a5a5d6445b5d4f901528c76312d3131323032342d3234a01a57f7b7e6b5adbeff8bc715704d8f4950ebf9c5ec90d75952db62c8a89e4deea01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b9010008e429a284ed392a6d3bbc938bf6fa788494cf667f0a799f5bb204d8179680802555ea0b7cbc86235220115b222aabb703b62b9056eebc2ed2d5ea28950f45c80ef68e0db285c890d8e111c6ea0acdec2e2238b5e491ee90d652b72fb91dfccb0020c83ab9aff7fa99ebf9c8a32444875ad7ad5c2f4fb900d514effdf580b4fa0200ecd524130b7177cdb22ad13b3c80bac6f677e2b0456149758728486fe2842171ee90b4ff4974a1e9cb974c5f1b8a03f6a52dc70304ec74e54e3b1824e6cf07802cd403594c8f234730528d4e21aa51131331053ae0bf47a3e6cb0564766308c46c0ffdd48f40aeef1ff34b5eee1abd1e4126c06c3f13fa340b49e6b2eb49", - "02f8698320d5e419018431c3a79182520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a06b47ed0b4eef8c81691e2b01ccafa27d12bbd158fb063206f805796285772957a0074c6f786709019c201a85189ddd0e68a700fa9f23e181d455557232ae2ec5a6f901528c76312d3131323032342d3235a00157b36db14b188511954c2b4af998047cfb71e468189f7aa943e8ce0ea5d290a01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b9010004b073333c08d29772170af8f7c067c7a309127c53cce3d686339529876d76d304407ea06587f1b2c47d9f2a3b4528d289d302eafe71dec9c714bd11cfa3a467184689b90346ff4efb8cf572c1c4ab3ef62bc366301546a38d3c3ef92ce51a541d45cd0bd3295f057710e950943f9213092d55c78d33130bb9ccc8518aa8d4871cf8180fdc8171756ba1842bdda6fa39fdd2e551dd002ce716ffb8e899ec03082ba36d0dccb6cd137ec36b7ab1d47d71d1bdf7fafd5556a8cc281d2324c5a4212503bf26908e3838acd140d692896461ab2264a5fdfd1eb13625c05be26e94c10cbc3b82c16b8c5ecfb819411b16c7b1f801a0776cf4e6f92c75ad7465dd062c", - "02f8698320d5e41a018431c3a79182520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a049df6c7f2e595e2a9f06ef4ca8a8663800782db85265589dcd58c5cfecce13b3a03e2213d901ba52e15e9317db0fb9adee778bdc57af21c25cb51c07f9ecb998aaf901528c76312d3131323032342d3236a022748979d55430811d95750e0bb932f02dd8df2c1cc3ec0f30c62f6d6d4482c2a01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b901002cacfeec180bfd748d91cecc4f4b14b661225476df13a2dacce37a8ecd86cc012828624b0c1595589475c0b89345248d27c31ffdbe3f811b24b4c9ea8db03f352ecd92d0b209a331bf69fec14f469671994c994727f95cca5ea89198280669c10ae754d3571996f3b01d25e4217e0ec4830044724c8ef5307cc5dd84cd3b46881472d9ddf8bd72a4e380180cbcf98800deb19733cdaf37d3ece6a066924779471e0452b93e51f38a22aaad70aef1e9f05e45a4ef244c820a847ee1505d4bed4905fa1e3571cb7446bf9a32a22f818210ba81630af9e7b96d12233eae9d6088f90ffa537b40b5d9fe13266d0bcf440d992a87ac6c427652b296ee4b8b25501e2e", - "02f8698320d5e41b018431c3a79182520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a0dd8fc96a7187e31e160c3405fe60dbfc1853a731b0e3abf526340cd1167a78c5a0783cdc1a43c2aa88b56e302aae228a51904b4a76834e68da869b0107462e1e06f901528c76312d3131323032342d3237a020efc9deb626a7fdd2ec18f82ea765722eb369c8d2044e0cf218e7d587c1806fa01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b9010001298b1d9d29b222d790021095eac66d3972bd40c9f5765e5a373e78ea16cf301445c56024e988b4103cd44b1a5cc033a7e3c83c5c40218be279f79ce471d42520ec266ae8a9ed11b1bbdbd98f08f27073918f5c155cce9a056a0d88639eff7f167d5e16ace6d004104f990d212699dc953958ea2babbab3317934ee39d7338905d602106fb68998db9467047483ed8d7f93364d8767994ce933abf7ff138dc717b676888520d05895d81e02fdd48c8fa0d8fac6941eb7c4f04c2e92e1d6ad7620d817f331c1d0abac7150186cc4786fa7185512a8e0932228cf53c9a27faad218cd521c087a455ca69e3693c5f350c31cbdd34baccfd6a9aae750cc3fe9dcc2", - "02f8698320d5e41c01843191330982520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a04dec185c5f83a04f113b5069ccb5d9e0cc6091a4327d64f875e201a45b564b44a04d1bb130063c133ce3fb8266c4f5c5b2e058b4564c26f4902f7d67714d1a6c10f901528c76312d3131323032342d3238a021e3d8efd16cd943b55e4902333421c64203f5549391dbb1527935172bd746d8a01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b9010009e031a653fc0f42bdaae1e7637b13eba0504c78f39e1cf1f7d4d214aba291af13e3c52c2e223f54cd56e8836436f0159ede277d7d93bad1dfa767c768ac5219013e595fc0efcc817d59c2bb6819e20b945051490aa22b6bd86bf53cb7cfe846046eb21b3f32671910de57d1df3050e53799669812f3e73bf167833f2c906a900b6c3a0ede835e4d2328881d49415c5b20647bb8be3c70eeed0d1bc9d7c5c29105a247574e7755c80ac470fbee3bd08a2155c14b986a85ffd5055eb383ed7e4625ff6023ee23dc9d30a078607a03f73b0c48b1196462f08bbdcaab127716c42713b135b53b362fa433496c63c94b6183d1e143f46f348e32ea2501419923ece8", - "02f8698320d5e41d01843191330982520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a043667837b757064426e1aa013c684e3c45e27c3c0dc6856d249c534ca849d000a0224007dce6ff72238283ace3eee933ba4c828627cc8f3cb6490c21ae6f5ff46af901528c76312d3131323032342d3239a013780c3c452806557ad04b660cc6e063fc6aef06fb2501d60d37d0b0108176d5a01ea570c7faa4c051bc7625539d1e215f2b9d699110139bce6b10c4b6e9a012a3b9010000d5c2def8b8469ec9cbbb3157457928f2e8eb05ce74a7062c6ddf69949f1a3d16ff78f1845f4fc1d0676de46579f5eddb03d645bd88610266d6606bf0b7d2162599b7833e39595fef5b9583880c350da12e98e6e2fd4616beabef594109226704c66c535c37f9aac9b26b55539d1e575b51d2f247949c3aa708f04544ae6a702fd3720783a380d1358802e7e6452639384cffc36c411c1159629bf351763c3b08f2c915317fb9050d1160204fc6e76c99ddc2b865b30dc34ab09f74170650a507c5a7019b6f1eba2f3b0f01593aa6b4b31e9edd41be5c4d4cf17c2f8be660d22fd4802b0b0088bb0ee1fdcc543cd8806b86f315354e88d8794d703988583917" + "02f8698320d5e4800184516d19dd82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a081ad5010d3f502b279540af054216ceb8fc929e919022088e766cf2ceced894ea053a971501c8e2b426cf5c043f390b9e454d92794562a60029605d397f02bb27ff901518b76312d3132323032342d30a00192a1143ac457fab0cf5a07a852c15db32a1825d9048a2eb406e8aaffadb742a00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb901002b0592638030cd0a68b32ea2a7461d3dc1cfa78280091ec9688d97698011a47b283d6fac359cd0140f11d105b6a01978bd06b47d5eb6f15991ea2916008534e81e5f13adcf1dab880a7b5d9ee6dca817effff98f27e9699bf6071bf1643fb91a27f772e9311c6dfbd4446e83c18c2ebb4eee2df64e4f5a584a70d96ea0637e2f2fc48dfa438fba778bcdbb3b125e4d56b82c4475ee899924c044b5f24ba795de12ee755d5c96bf31dde93857f790db06fda0d0c2262d75fab74ea840c12381cc1857ee75d5ee27fef42ad0f46e54ac8e7dd05d9bb99af3aafc5c13cbab370a61069e42d444daada4fb0a907ee9b9abf22ffb2d21ca4b064de8647cd94586b2fd", + "02f8698320d5e4010184511a975b82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a0788100f34dcacf41b7c0770f3a500245cb5f90554cd49419f3cfd7473d98ca9ea0107120778f3d3d6098d329b38f588df689da65a8b6167865e47d9173276d82a0f901518b76312d3132323032342d31a011fae0ab401dd065265afce57285dcc8fb0bacadfdd59951047805096ab751e9a00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb90100253396c539fdb0274bb57fd2f712390d6f43f60a321e8e1a93034b5d5331f4aa07ad46bb35a69b4fad39c608c97d015117358ea16dbf1e15e2b9bd5cffdb9c7e2ee6a98bdc9b8c6e8132cf0bf086f4a91eea85e2a4df44e9a1a12e4218d9a08520367b4e7359a8e77130564ee2c7c037a9b853a587792c2835920a670e395dec01f6ef7af50310b1339e6d195aebccd84c563d84c8bef1a0c61d76c6303abb180aead01ad2de63f7b6c173c514603aee62c6e38837faf512c585c54f94fdf98f00bef5808d0b78d4d6c640ddb41734cf62272e7c16a52b720350408ffca50bd50a2a8ba86cbc4219f9b5ef2d9c93b70e043d7b3e8001b129ab7a638d53fe1c00", + "02f8698320d5e4020184511a975b82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a07974fd0ec141dd5df7bce98963d0229f2014f80aa035d1714519079d24b5bc09a0568efa36007e3ac576122c8baf1281ca091dc8688aaeb5267b3a902216d8c37cf901518b76312d3132323032342d32a0109a97ca0a9e6b158d8983bbd1a95e4dafe6f3179745ec89bb121027846935fba00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb90100202f35ea4fa7e94b5231beafb9e63f981751faa53c904330cdeffe03828862760a7b18452a1a1665d41db47ecbbf2deb0dedc76d7e90715995e268f9f3d041360e55d996efa8327218fcc423312387fb0648ad69c09dd35dd2dc5e5e712e7dbb232f4c9cb9c24f9e28d9f9ce8c8f748d7ca54cf6bc3d8f397ad8b3f27d18a45f06329dc9f273c508b505c2c673c6240767abd61553d50ae8f0b465b6127210c9045481e27458bf6f01e55bdbe7ac4c87ece65d1c6b4460e5d2fef143367ff40d04ab6a5ddbd1d101a3eb3ceb7f891c01ec1f24271dd248013109b93765795cc2134be67304935ec9f60832a71b03e8eb3459ed5786559f13ccce1ebfe1fe9e52", + "02f8698320d5e4030184511a975b82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a083db5efafdefedac4d14b946d2aa3b3ea076fcb87c4db9fb49d2611f36707ddca0168fb617febd2b61304044841cfbdd7054450426eb8b7bb7185cc1f4ed87981bf901518b76312d3132323032342d33a008185622b6090dd868b645cda8fedba886f91e084195c15302bb5dd3d5e67c1ca00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb9010010057c23527b8c3292e78982b4496a94566ca49b7ac591860ff776eb31ee5ddb2923c14a6bb4577435bf205aab7eda967746fe9241a72df8723ff11fc31a89472a66f8b315d5a46062a7489e5b05e6f072c381b4c1fdc4bb719e31fde82c3d341a573261c81d1bde7a78b2aae15cd42b5fe4f369239d20f1aab379a9ef17f7f31e7e1cc8c2044b93dfefc6700ab3e94661ae933d4899b1369607050c86cb255a13f74bd01c527ff1dc4560624823775a79e2adda5e33d7eca76fd4301aa6443408a9bf0c2d72210214b62d35c8bed427b487d87f5735d125aaadcefb87a67f1730274625f697a766518d1711a4c9a2d8e739004a424822113d5aa8020982504e", + "02f8698320d5e404018450c85c8d82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a0e8bdc25a559aa2d3d6991c16ba9aaa58cde553a058a221a8184e8132ad296844a049e3e9e681ff9bf7b1044386e4f1f00a0204ca29fe7c6c31720d0e97069a8b0cf901518b76312d3132323032342d34a012f229749c8e6f19606b56269ae1edbfa1bb1ffd1b56f1581a73c1f8f9c0023da00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb9010013e0a26e803cd409290446996e13773acfd21c29041646aab0a7fef54aad866b0ead55836c5beb0fa136a3f30f1b5ce7f12dc02a49273088d20428b8c52b59b72e3cf1455784c9e1d9bbe977d2a819f7c6c7a5562e0fcd8b98792e918b6c9dc227f0858318ab9eff187f406654f1c47f32a3c2a32d981987a81909aacff3d2be07eabcf61414e6486759f9664216999da16503265286d8b0121df49bd13cd146278433095b7059d8ad07667bf7fac82c91c2139b5ce67a4a86aba1317079ffa81484128d9aef692d8e97fac08e2ffc55903611a16fee6d7d2a5c65bfbff1e7412a9b2f2c41c5935c129dcdbcdf2952cdd4b70ac0d8bc5a3fad4e1ca051e4e5a7", + "02f8698320d5e405018450c85c8d82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a049ecb84d42b81150ed4cb1541c65af98803db078b33096e603e5bc34ee420731a0230ddd4cf0904325d5f96012c7fa0c92d297e9362976fe786ab5d5e1c430a897f901518b76312d3132323032342d35a02d9de007d1ac83511aed61911a33ad2df58e55e5f6999b3611c1da13d46ac143a00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb9010011ad8f39f9cc07b3bd21eada225183a509cdbd0ce237c3d55f4cd27c8771b6c127ce54d1406c67ec5a3558ac4d79787125e31272b0e0922c4ce83bfee56673b42241448a88e723e1052554c50a073e763f0505d1b8f1559f91741ebe5aacd2451b7c5d5978a2047c9b5170737cd2446630d1b0eb0562cc319ea1d86127b861d71975878117b5074d551cfd8baaaffe1452996eda07adf045e26a132b194a8a5919dc58c9131293db0e58096fb7cce8bb3933248c60abdb0e61a9af62acfada23208cc3a9d821d0c21b6b6de124e2b53359b6203477841a4c0e6f7445057f43b11f8349a654da35190e138bc12b0746dc5adde7ca57a3d46506f28dc312ba12c3", + "02f8698320d5e406018450765d7382520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a07d7f6ea86d3b06baccfb0d2c4951e93a767165a0a71df87c80dafd42c9aa7b22a03c499b419365ad8e3b278a19f99d08281b8bf672b3d03db97003c04c58cec246f901518b76312d3132323032342d36a02f59b83c641c79344c19dd0cd4d69f4e72cf7f18209a7d591ece03114b384c7fa00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb9010001d7601c887c2c64c77685a29e3304404af62df467e871c34f92418801e7955704218b713dc382f4d98ed7b7643bfea1888e55240c1f946d750b80cf223c89ca26d8eb5cfbc16136db62589f9c6898ab2a459a36fcdcd9fead1700b1380bf67a21c1cd3592fc1cc55fd9fcc5d9204cb63fb7cfb932195230421f998ebf3ff511192467db6fa98ff5fa8d55e4e68a1db9c77ea79be499a96d9c6532ca6f4d31df2612f2d1d949ccde3b6cfa6cac979cd29ffc545e84f86641c3c8aa782b931cad251faee26caa497993c4486c5e7750d43c0d617211fe8a7426bbd867e82841972e5044c32b3fbd352fdb1dc9f882830a75ee28409ad011820f2efe250aaf4815", + "02f8698320d5e407018450765d7382520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a0260285d9e6cc42aa7458fe190dc418ecc6fa3b4d24295708baef596aaa680d58a02225391988a328c95f65b223da65f1db16d957fa268a05a99d6e0bb100efbf38f901518b76312d3132323032342d37a016e127bde24c21bc505bb49f277f25c1e3d57a605832d88bcdce851a402c7d7fa00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb901000642cc0a2ff8bdde7ae287d91da21523f325ae9b054585eab130ceb965f74eae2af561df179a62bcf6ccbbdf2f162d416082e47a2390f0e4bb459ab6e90f594b2bdb5e625225c7f1e9f8f672f1794f8de41ab4ba63ecf68947bb36168f00e9241ffee9fb99d5db69a58c1a921886febf391b14e026af5e4a7fb969aae2a9c1932c87c4e78ac0bc35e7d795b545978ed2fa1dcc4f52cae182d390fc09539af9af0ae98a1c4021eaf39f2a39d14693ca0554305413003df50507660d2df77ef83928ad5c180ff4d8272f83c6eff610b6088a21641339ff59619fc8a2b96bbb5a4720cca93aafbfb413b5847bb7dcc68579d082859f6568022096a4c0c0e1e5958e", + "02f8698320d5e408018450765d7382520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a09014f3ecbebf1e9c0cbc9ef3385f9498128664c2a6749620b2596d803ce4e741a024b5f70fc3359f2573d8d93885eed32fb3d9f13ef44656d14cf228ea51a15ba8f901518b76312d3132323032342d38a02ec58bf106d0263448caf38e7ed8bfb7778686f8075b507296f114e6f0c9169da00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb901001a5d3d7ded4313449245e7460de533fcf4eda55d64d2c92eaf8b2e733a196af9167712d001df31c53548db2478ce55fbd149e83796f94f51e14d169fa94c0de30999e4ba1909c0d1e1211e1c1a2e57b55d62377b7e6aae8e0670369dee5bc61f02d2da565b8ae7a1ec1c539b3dbade6a246572b7340c4673dc6c862f50d82a5d00076230a5f02d28f67e76a5979e848777cdf51a82ddcdb8fde828c51e06bc431f99f1d4a55907f0b97bf6956312488cca64edf753824c19ada405aeb6fa9ed2272f5a32bf5e784a4d9098b6a8d978c1482a20cbd05ba51306008a6f8353628803a762fd391a90ab0901f8f323e11e2be290c1c10406d46c06fd26c85eb40952", + "02f8698320d5e40901845024b19382520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a0770a6a0aa1db9a15dceec2e9a2c105d33a4a6f7d2d8e36c39a34058fbdc0fb9fa008f74e48aa525866f0501c1c506440f76c44eb26ab6b54f251835375114d3d0af901518b76312d3132323032342d39a01abc863ce0eb0fe969a983d232c4c68532dd95b571a39086e7924d1374d1adbda00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb901000f15057ba48853b1e7c89d3fa6c456b82dc31d4cbabb04ab0f1ffa5dd087c91a1396ce3a2da22ceae407211b3afb3be5a5f1f13c3d8582fb3467cd2ab396b40b2bc997cf2a0e5fce137221f87e4dfd53fe4f99c78b043aa7d0da84bb57ad8f55161615eb36b18f00dcefdea064735742ad00e115ea41688c2d51e38e645f6c56047674a44a02a6d441eefd6be9f80bfc7df67f8ac2446bbd06ba5270ee7cdee82dcaaa39419417ddae5a0971fc720991ac08c266f3819739e0e02de562fdf011217ff962fd58b11f1faa766631490e6fd76ca28a1aca7b94c571a9e318af390c135ebfc65f254023e7116df07050004bd24d3ad5c993692a320bc01722ee9bf9", + "02f8698320d5e40a01845024b19382520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a089ca8690de28e4ac27bbf2c669a59dd282b5026f085ba5d08f3aca07723c654ca04b1433d867846bfa41ffc3005cf2150e82c2d5117ae31ac86e437b6a0796c0d9f901528c76312d3132323032342d3130a01285c9ad4e14884865ea6f13e1029b819b5f63ca36f90b15e03d7d49dd764045a00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb9010025c7d9d596fc44ee4df02e8b63c21f5d10476e424a481fe8911e67481b8dacb407bad3392ca8697f5b1d064d2d9ed68a26c8c2992ad528dccd19d2fa1eee34e2115c344af8d0b75484a594582f41cfe611ed44131a785409b6f425d3ee8ab1c1203559eba363e95d79f24b88b0c473345bac6f98f2b7b17f4b3e4bc54b1fdf1d10c9773726c95a0f7aed606d00aa858666cca9a1a11726be2b5a5c2cd286e22c165d192164659fed3a5c1275dc7c5a92bde1a496ca2c8269197405a20dd6ca45186ed6819b7b1fcd10f2ac1c2f59fb8c90fc6039c74b1f93247d25eacf84eea613281a1218101513cb70bd18312040b4baa4699480f06a9141f5ffb41e8116db", + "02f8698320d5e40b01845024b19382520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a0203eff4fdf68e821be9b528cd7bd47b0a3a7ac044139bad51aff1f962a503a34a037b05a655ce8124f199f14cbe85cec7bcf6a76013b5e9a8748828ebab0584916f901528c76312d3132323032342d3131a02fdc8d6b5d1e9ff67ed3869cddf7627be4594eb434d5bbb3932d72a3ba80718ca00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb901000f172778dbedcfbac52f97744df07a9a964f573d7c9254c8b26590e8ef8be32c04204fb87933954ab9c3b2511c346d3469fe8cb69aa4e29a844d5a86bd0381780af25aff41a10e9c11e52c0d59745cccb9795a0c367a55f6b2cf63da30d930c3075b72ccb94ec2b27fe1fb3e57786c9a5bafe723ce13d035ea3ca7e27033aa2504b3d8a044f1739c1b71d8b207744361e1d43029cbc9b7aa2ce1a3c836757383101dde1bbd934d42e55d2bb41241067a0d1c61e98e467d8ee2f5c100354963b622342847c86784eee5a5956aab86964e97905ab921627114337a657fbab682c626dcfe5f71a32b4a55c1006c95a2b97bebe9fec1ca54ff693d63acaa5a9dcf71", + "02f8698320d5e40c01844fd3589982520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a0f1be470892321b15178a31b591867f8bc6de7919f6e42eeeb56d5c76fde192cfa0331bb64c405322f994671afa743bb72fb0cdde90d7474161bce46297c78ee950f901528c76312d3132323032342d3132a00e6af5ae8aa6ccbb59ab1e1ea1defc204c79bc3acd11eb526508c25cfd7d8a7ca00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb901001c3574c272c3e295e125b014ee4c56c1f082d27e1cd8b34a3551395567d1394c28e430d5df0d0433650c21c457fe98de2590d02e83203f9b0b6e04d966bec87200876bc2bba01cf3b51dfe01a3de86c6cc4730c32ef3316ccf3028210a7b79ad18c819ad2fc84b80d539de2255c0b9e500957652086672c8ecbfdc1ff524204024119fd179820cefe15f309bfb80cdc1bbd5cfad196a1cbf59a50b12d27c4ec10dfd8db6ba544e0b63726d3936a2bf799f3056f16a30ad1e23e08744fdeae5fe049019693dae5d41b16de6faeaacdec3eb7ab676f4c1efd4ad12b692df8f91cb2379633a2ad0127a856b887f8079eb7dd0040eb3b2b3ae3d5a7820fe78a1100a", + "02f8698320d5e40d01844fd3589982520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a0ef9eaf3433ee22aea11ecdcc9c3ebdbcffabf3719c751dfbb0396c6d43afcad5a01492b7512dd6eb7633d65c11c2de1e9de48d80531e487bc9ff77185d409c2fd9f901528c76312d3132323032342d3133a00af1365ebc35404d36de88a9675293999bc05af7f0ce02073ca6ec4ab3c1e8efa00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb9010004b177d0260ca80ab2da2bc50af0f118a3115433d372a0aedcf93c98fe7b812418e0eb62a6a231cc8c351b42ee14b4dd9a0d11ee29ee9630bfeff28e808de0c81e4ed04aafee21e036be19a4665ef9ee83a271492495425732a40f7f1a933dd804c7c6f22a51525961ef97efb376ded06eb25e59c889eae7e542067f92c9dcfd05a9f507a9c1052b76c51b587c251566281c52ebf07edebffda2f2d60faa4c842d3c5f2d35e9af12eb1c0e133e49532fd8e76d5ee45ef928eae4e58a39b340e01738109a953b956bf5b52b74a3dbc1c26162f4ddc6e1bfc0571a040aac62102c10ef90be744148d659666be451aa5ae5b87254b1753f76ed3f168d4ed721fec7", + "02f8698320d5e40e01844f82523182520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a03ccd8607124f5592252b5eb436deae7d4c7749138f973ebcdb0e06fe3d01d7dca07401dbd5192dbee685bab2713c38c7e2ed099f658354ff2e0743805ea9661296f901528c76312d3132323032342d3134a02f98fbd2bddfcbae1923cc29bd40e9bffeea2b6111f39456c6a032170d79c4b5a00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb90100301b798eb42a5e5dbae43b3f76d9e0e679ba665418b9e27baab9e98b3d315f662eb39ba82c4968b300175f35d632586974587ce90201b432116ac556bbe4809c11515197d7464f7f062bac7ae5d8a7af6bcb3ace7bb5f58b0439053cb860f8bd107248606ac458bfe595e16301b9170b58278b21738dd80c1c3eab066fc97e751c73f94f34bd652d990c83a5b400af05a442a549ac4c0ee4ec56468c0678c0f21870da8b14995b9fa9050041df090d6ca0c6a85f17c76f79dcf7edaf3b86cb501de92eb5a0709e754d4cfe1b1d76612bb94ba95ddc3515bc91580b7632e8de0a0de6084d26342fed2d66d1b8a13032632b904e4412c1e614ad3896e645cad231", + "02f8698320d5e40f01844f82523182520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a08e788357cc43c8af77448cf55f4c2e4b1df221c757e53ea4a960ef9535859ce8a04c47674443d46c581d9747d1574153fd4ec4c1c83fa2f7fc3feef81b63ad9374f901528c76312d3132323032342d3135a0012c63e86bb9b7b7e934b97e091899086c182a06210eb7b6f441254d9f1d3f99a00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb901001e0b6797e8602a89aae818bf81755c210403a5b86d083281a9223abb1a255b0c2ce18463f82cc70b45b9d539c34b5f7bdf7808a6ae88b287b03c640f41f0c3c2132d1bd32eb418af3ba6bd181e57a098e3edc21721ad831781eb6404b091951626bd29671ca45791b3fecfbeed661396a3b7a3689e73e1a0e2db4e4ef4677fcb184b9167c52e8e694b7dc17439cca7e490bb7a086c1c2feb3e3da7fcc0910519019c5286d3e7bdb567b64515603dc221850281890aa469a80af7456709e44f7b0d40257b5b0e46acf09929222e5c8aa04f737cf9a2812710e69a691935f6199d0fdab22106cb84749ce7507baf80e3a53e0e0cb26b7896ad7ddbbb02d5da59f8", + "02f8698320d5e41001844f82523182520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a0d7251e2d425b02b1041886036713b029d0ace29ab0bfb71f006b1ebcaf63822fa02ba17e96f4bec0a2c4ac356c336bbd3fda497e14a40adb33514d9d5d4a701999f901528c76312d3132323032342d3136a0294e28101b4d9bc5f5cb05e05d2dbab5b45d2faeb4c43825a3099ea7dab85b47a00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb90100004d5ec055435810fb7da7ba5cb15ae39b407e308e256611e462eb85d36374db1fa7b0ec5339845cd24f87371c5839ed5aa5d05fc08c73414be4a2f5ae03ac531fb704c487f03b3bfc2df8b24b032162e6df4a58b2a129074ae75f39dfb6f99b295298f7ff4c9f504ecdbf953200bfbf9ff8501bbdc0a202d2a61946f40af5760be025dc07cf940ce4a66b957a469ffb52545ebbef02905c8b8f6db0aca99732195b7d7cbf9dd1c2b3cca4b0e18a56022df2b8490e6fe40bcb6a5de5eaaf9d252e1dd32f2af1eb13dcf2a713ebe97eae8cff54c0596fc3a44327504af12320e627ad4c1ed7ba52c675c1ee358224c19fe1f08577c15628534778b99e7fb72583", + "02f8698320d5e41101844f31c0ff82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a01ad2c7c198f6bb8ec4784cd9348e0f791125106759ed3c3a2ba6df6c34b26363a032d067a75785f61b39966dcd637351e7b5e6633d643ec040de5425cd68b77cd5f901518c76312d3132323032342d31379f99f3d8a5685715979c8073de20727f33db7b262c142e7b553cdb0ca5164e05a00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb901002080284ce7c799c7152dc676f3426d67cc06afaebfa0a2f55a2065d9d1f81f9627984c903c8830067b0e096ef95f398493cb051e7568f6746ca2964399b1f1f21347b4e19f7c3cc4770b084e6aefd31647329bfb335db8cc4976f9723500b5d124f462ad23a795f4e8cde619da9c94d8d8f997c04b347bcd19daa0e8bfb9afd2097dd7cee69b9a10382250a12bfd50d22d4f9d22ede56b852c3667df026a9e2b1f34b274b93fb7f9191f2d0227aa0325fff50eeb6e49302ad10944a834cfddc71d35a249959bbf6106d01e50c5ada8b8d3de9c1ab8ab68d565663daa72572ffe12148f9953f64326bb493b6f1a918d0392fd879b6fe67c30c6f701809cc2fd2a", + "02f8698320d5e41201844f31c0ff82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a0e58f6613194c945107e5fd43d6e83758d1d9f23e4f7705f4c701656d57669230a02b1db3ff0d39a8a4dc692d9074c5317b043408b4bff210ba74f48042b49cbeeef901528c76312d3132323032342d3138a0227a3aba806029e7901757109cef978f489e1f86745f0986c4cec3797f4aa670a00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb9010001b3732acef6388529e3de2bb5cc57b3b3e33b87b78518618f97fe589d0241e9184caaa2867dadc0c330838dc7971db1f45f0ce83bc0e5c34dd61e190d2eb06312773b572653bbfcc78d94ca11126b1b9b857f694b3ecb9c8667aaa83989cb320fcdf8b673cb50ac7fce5bbefc8a90a708a1bf6ce3500ba7d7c6591a1f45d97b1262178c085614e568409672fcac596978f65d7efda64611112d8e47e7c41c471a3acdf816abac1a6dc9245c5434d08d2412bc3d3809ff35052e0b5da418902900ed790c879b8aec9d21aed5e72e16bc4ecf957d76c0e39949f7c426714ff5b31983d85519321344f0c08e4f14a0a57fa85026f43fc756d3c602430d60f099d3", + "02f8698320d5e41301844f31c0ff82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a0d99a1b487b6c530f6c22d8ab805928d68f63c14202c30ae5ffcbca725f68dac8a05948d98a31ed05ebc8c952dca1795cf9431b872297540662ce22ee43394e46e7f901528c76312d3132323032342d3139a009718da9d69b925356dae24193b0129cfba6f3d4f3b3d1c6cc87fe1bdeef54c8a00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb9010019e53e0f550228e20ef9a69153243cffbf8d7f6ee296a6858eeeb894fb5bcf7907eed8bc12d05616cdb07ba02bb6d08496a77671f6eb03caf0c1bcf4517155e80b9eaff5f0fc13b64e82422fa50d0fd4800ccd2b1ce43d09632ad5b208ef2116134df581d82775d08012e51c4ff6cf0cded7ed1283108a99a06c969485120c462ce7f9270a24d89b330944ef200ee20a4173d08b40146e861eeb6cf9d84d0a7e264bd2fa706bd67fa72dff8d2c74e4073416bc9196c07b17a6671597523399cf26c5c6469cddfd4ef9492bbca0bb330a0b2eb0e0c736d7d33ce76b7bb9b64e1c15a46e1b0650d4e8eb1cd24c9cfa489b3a629b8a53ab24ed4d4860760d194585", + "02f8698320d5e41401844ee175d182520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a0c4b3bb48e2f8ac8d3decdf9a5f0a4d942f97bd01e02f22e260d80a59104779c9a02ab3359d437c8c3b867cb367d59df58820f09887a4a6fc7fbd0d4a2b1eedb323f901528c76312d3132323032342d3230a0267f16b41c976a2e799fbe838b2c888488f2c812d080ef119d37111c1b860855a00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb9010024cdd37710642eae65952fde676144a37e3e9a41239418ae51c834525e05cc9725fde8b58a1fba2a1ce18e0c03b509ad7d50efb1cf9a18f05714f622a1e1e29f0ed067c81c9e14f60b102c59280f3896dd110ea2fd75c31dd4f101521fb9402b0a7b4b159e5a08d03b146d2d46dc7d79a82557059059d0294fc6e1006b8d8aec0ff874458fb366050561636ca0a7ce1217987c3b19af67049c6fd4283e56830b1c37c894f7ae6ee263e7afbec15196d05c360ce5f3b34c1e5b22e585829fa11316d3723e4d09983f901197e7ab500fb3578cb96033509098c83786266dab7cf8266769238eec9d0b2c77b95fd7e37133d82b983e87784277e0292e0ceae02758", + "02f8698320d5e41501844ee175d182520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a08ef6f7fc24e16917d97b95edb80d4600556cc3206b458a133fb24e48d895a276a055ad35abce5866593ebb5fbeae66db7adb54c520cccf7dbd392a884f19ada7f9f901528c76312d3132323032342d3231a00822ae04e13eaf49a21a8eff6c10449d91d9bc089784340386d2674fb2082994a00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb9010018a7647f45dca7c7f514101f119c3a65d6514f808c533a66a5f8ee4eeaa3c3720a08ba68a2d21cd006f9b3cea09cb23bb77d03efc36f81db02dbe34a840565090627233c2ba358573e604b98a6f8f40170b2863b7bc1a54e9f16fad3684bd552271020246b742f86612fc23b89febf1788e1483a21a115d751c75361547993f803b7c9a84bde9ea4fd679fccd29539c39ba8a7ea46bd60ee1e6c21da68a8162d16e39697cc2e0dbca8045836c8fd1f576b8982d1290deac991fda224dc7327dd01c736ca8b4fff03bde19bdf4212887ba0e6cb5fac2628cbaf575fff93e1fa0f2663029872d135cd5c2e0034b2805f8388e6a98ad73047fe685c8fc3c559d301", + "02f8698320d5e41601844ee175d182520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a0c2cbf1fb40969717de4c1250eb3c2cd2f0f387e144695e08b77c1077f3f279b8a02e56f13543b51490b38107deab2b67c6f2e320e403acdf884c36298b2bc9944af901528c76312d3132323032342d3232a00512b43b72f23e9500c6d9aabaae6c41b743d2e6fb2ef677e9f5c25616aee680a00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb901002434ddfafd648161105d6069cae1f605b589d27f9b0c559737bd50ef40f7ac4f0bcc7a2bb92d2f64710c740f5f99ad23d8d1a63b5c9edeefe1fabbe11be832242d8f7b54334643a34f8af02c26cc47f0b8392d5af13c9fd7a58ac7eb22b831701da241a156f6b834384f9fd9e75a32b98c98e2f98f82b5c1077357cedbee75b51f53b71601be3f36534bf5e08ef006c950b774865292b89f9d219c34d4c1d9520e23684f7e76db4928b75e55810be54656aa8a0d6e226c28aa877747c65c1f16240e78be89305c4632ec1cadbd089782ff75fcc1dea1ec7915aa463a65e58e152302509d334648cea6577ad4775f2b2c9d7aa7ae2da141b468d5b5181652cf0b", + "02f8698320d5e41701844e9164ef82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a0d0af30635e06e047034cee26264e8caff221f449e42da7628709246fd9973d12a06eeeb1b8b3666eb1cda5364ddba01673941c232aaf5c5022464c4a0891865284f901518c76312d3132323032342d32339f9981d8918f13f3d17e66c91f08f792d939215ab9d77c10ddb9bc169f87b7d4a00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb901002e270c6bfd7e1b50f5f0a795c5aa57effbb38e9c7ef3b5c257932489c6c559180b09fd9d212cacece693bce4fb9f351a292e71e5e0928414f0eb08f7a2484c691d8a6a4c1a64e5bb7af02649e7fefc992d58abb072f80b8776bdafea6817c9ce15c903778d314ef76434cac511daafc9abc148491c96bf46caa897655fcd30b821390fe49e459cf237e08842fd742aa4b8b70965bd3abc190079f6743f3373a21ecfb1d0d7fde9ca1b03058761ef35a29ed56af1b37e82f6f988d5ae6132d9ba1d529c6ad6a5728fa2114a9fc2e99972754019a0d5805e7fb6e809f77fbcb65c1c80e32f7b14c82bf8b8674c2d12f94882eb3c1759e7566f8019461da3c6c466", + "02f8698320d5e41801844e9164ef82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a07098dffa82d684ef5d5d31c82b0735507cbdc87767f39e257f09162b26977c0ca00cec066c071afb1ec19a1c645e9acff2e187748dc5b93baa6ef4adf2cc7b80f2f901528c76312d3132323032342d3234a0108a3e328ddc1e19cbeb06a79c1ed34cf82485532dda0f350228d2ad75b3b422a00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb9010005d88c9d484542131819843958a75489d5ddf383690abd9dbed859e182086aa2044b14d8dbf6c307b1a0e095f35f3239fc065c8461e2d2798f9ebb9b0d87fb450dca2d2131966c3cc054f85b11b8814fe994870f012c410e2bd0ae1ef8b743821738f72497b3f06b1ab676663b51dc4b766f7dd668e0ada42302d7bd293ab5a72f7452c62b4d5a578ab12508b463729713b88ebf6a32eb41bda59fba17eb3ba902958280d03d02fc529c14030e0f004221ff811e1c75bea83d9d8305131e0aa61656855dea45cd0b8e86b8955d6183b752bebfdad16ecf7866cb62bc88b447381e21ed42f3b484c57a10d108887266c4b09cbd37ed26eee11b390c64ec000bd4", + "02f8698320d5e41901844e41a55182520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a0d7fc9e3aa8794fe78a47d31d8e83012b8a89d55936ce95b18f038250a21d0ac3a06db758b8bcfee200f9438fb8de669b9075a5046db5f66625264b12eb9eb34931f901528c76312d3132323032342d3235a01c95a988e7906fb4c16a15127f653a64083c6caf09e329f90d23013b65d84f9ea00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb90100107fbcbbf39c329ea026aa41aeb61bb7dae2c126b007eaff46e3aca1e51869820640e36c03a05766ff8ba76472f9f45b2019ec371301e4be8a4c406b909c0ee422d16d9a99e817257def915c65018e35cee8bd0ce8c867083c5fc376898bd0db1af205a8b62235a9bdc37314046c0155c65262e33b4c3b7e1c9f6833fa4db9c80015cb718c9e3d07aa06378d02f1770324605689788c71d1447f58d4df11758d30081f34f415744065aa2ee8cb9d082f77dc1654ea1ea7694c77b887f4ac2123149504eb8d711b6e5e734212f48822555762abbd50a9f401660b88ca98a263932d713f1be2b1bb6f730a4c05d6b6b233a3c99b8689274141e0a6be638132cc69", + "02f8698320d5e41a01844e41a55182520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c001a0fa071597df6c0a73d5f47606d9f094f8dc58aac0dfcbd4f44a9cdcf052871b10a00cd11d3d31f8b90ea488d99d445b684567eef11e2da41631276f5c41f697f196f901528c76312d3132323032342d3236a00cc73d56023e424d05580e6783329deb95f740b448edfb6b135b3bbdd9e241fea00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb901001d3524669fb950fecaa832a4e7ad13011cf45417ceac9c09836f315666cf608e00c732a9b2d46d63653c7dcec540de0ee0c146083e12852e79e1945fc0a5d3ef1fdb3f79cfd46cb977176a1803723a5fe8ad9166170a513163b30762d841dae72a18108f02feaee5ae8cf4facf02e6e5aeb8c756c4c92c7eca773a93f019ba581ae1dc81ef04938783fcd2193c54ae757a75f3205c3ad561ea017cec030d1a6c02a236d767dd4be9c6e15deb6f9456385fbadbaf2592c454e2f4109b4fa5ab380c8ee9bf0bca0639a7d780d050faf3820bbcc3541670d1039c83fc3464e6b8c500cd8c29de4ac1940285c79ed36ad4b82b8a88483d27f0737a192e01cd325d89", + "02f8698320d5e41b01844e41a55182520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a0a399b77877a2032536847e0062b0cee3ac2144602bf9f1f007c67a448c86a23fa01ac8fe523bc61c095681244a3b9625dcb58de81eca3627fb06b05d13d81b4002f901528c76312d3132323032342d3237a0033c66d85985be24de2c3b41a5071444ea46cfc8a23d172a3a9dd1b0e80c777fa00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb90100087eaed3bffd4684afbd17137f5e7125cc0285f29b892b0ec5e59aaa8d791c290c325d57419bb9f193f0684a36b9784c07e07d9d54f91e3a3f4123448de6a20610e025f7ef20cbb55cd4ae01a23dde918c229920a263ff79cbfcbdb5f13366ec1ec284498f900c83d2f16f86b1e9623eeb82ee77525dd2851edde58c4f9223db147245a6b3ae53a840fd8c630f1b178bed39c4b9ee3b7e26afdc58929201f5b201ba67ec829d246afb2e378d005a2b0b60bd5a5dd12ae89ee730e008f1bb4bd40e90adf900376364fe499ca8e2e9a4b53ec0842ec5885146b9c6aa1317b563771b0f0740ff7862a0478a5bde4996902c948c3832b6b9c0dcb66db8a3084ecd5a", + "02f8698320d5e41c01844df236a582520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a0f0db60c788d03673c1ce89c39ee29f521d8e0a1a22713f5e18a24163bc339276a04f6ced0891c9171b92c5dae67321f45ad713fbba9373a561deebab51f88d9852f901528c76312d3132323032342d3238a029e15025c4375de75f4ff462b423d6a6e4574c316bfce6386ae84f951b2125daa00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb9010003632fa9555238c3ec4ac0af6d4471ec52bbe2688671b71dec47b6554315111d1c2c04f988f1637fc7eca632b48d67a763417cc4444d35eb323ae5fcc081c2110aaeb2f47a2274b19ed2dc875cdbb94fe90910c57572d2b6dec924bf41bdcd7c2d3d0fc61dd2b8f5fc5318f5c1252cf9627f4ae4a2dd278a8b49b73de78b1a0f214055e02e4b31fa6e5bd546d29a0b99d63c16a4f30da16be9bb69d5391675931060467cc9378caf59c5fea3d235a751725b63af7f9da3ebacdccc2876f1ca6a08b84d78f3b288f82955428fa8dc8c1b696a2c767ae96b285f9cd6565fc1189e1d6c50f9bf7f8ad6385fcbeba7e461005896fd17fb10a5149b51d860429ce75a", + "02f8698320d5e41d01844df236a582520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a0b18a61e03d5c96a30ee426b03092f1e8b70bbedcc9235e667ef0081d36431ec0a076cf791010d228ec260ce55ec8c2cb2dd64a7f89f7c294def82afe4fed319e9af901528c76312d3132323032342d3239a0203b14f383af06a989f7ca6a0b0dd7cb69d20f1a87ee1e32606931d20a2ae5dfa00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb90100233080bc918e26b5589b21962a044e6b3effcbea41fda2dc8b6049b8e44a8b99100165fe1850bf2e5d3c2d3cad2590df1700437c2dbf3e0cc007cfbe6cae60a92535e85e116ad6f53a0e7ae1c1f135004be81ae224cb9ff8aacb11cdc00da52c25b7f081fee209f3032fd9a37568cafb3d90c14b18c231a764301765579f7e1e2b6a16f0cd80729cb1ce9dc36f874a1cb2f91288d418d6b9f38779d4d898d10208d0a15adb60dd5af7f081199c40c0c524f1750f0152b9dc70d4cce18567aab81739ed4aff1fb55b5691d0cf4b1bb77d2cc2bc03a26994e1cc7b0e2821bcaf7216143fd23f48394832a763ac552789d0e07ed3334f5b38ab8ad049b0a4253bb5" ] } \ No newline at end of file diff --git a/devnet/src/contracts/contract_deployer.star b/devnet/src/contracts/contract_deployer.star index 6038c852..cedf790d 100644 --- a/devnet/src/contracts/contract_deployer.star +++ b/devnet/src/contracts/contract_deployer.star @@ -94,7 +94,7 @@ def deploy_l2_contracts( 'jq \'. + {"fundDevAccounts": true, "useInterop": true}\' $DEPLOY_CONFIG_PATH > tmp.$$.json && mv tmp.$$.json $DEPLOY_CONFIG_PATH', "forge script scripts/deploy/Deploy.s.sol:Deploy --private-key $GS_ADMIN_PRIVATE_KEY --broadcast --rpc-url $L1_RPC_URL", "CONTRACT_ADDRESSES_PATH=$DEPLOYMENT_OUTFILE forge script scripts/L2Genesis.s.sol:L2Genesis --sig 'runWithStateDump()' --chain-id $L2_CHAIN_ID", - 'cat $STATE_DUMP_PATH | jq \'. |= . + {"0x4e59b44847b379578588920ca78fbf26c0b4956c": {"nonce": "0x0","balance": "0x0","code": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3","storage": {}},"0x047eE5313F98E26Cc8177fA38877cB36292D2364": {"nonce": "0x2","balance": "0x0","code": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c8063b242e53411610081578063f1c621ee1161005b578063f1c621ee146101c9578063f2fde38b1461021c578063fbde929b1461022f57600080fd5b8063b242e5341461019b578063c70aa727146101ae578063d7b0fef1146101c157600080fd5b80638da5cb5b116100b25780638da5cb5b146101305780638e5cdd5014610158578063b0d690791461018957600080fd5b80630ee04629146100d9578063354ca12014610113578063715018a614610128575b600080fd5b6004546100fe9074010000000000000000000000000000000000000000900460ff1681565b60405190151581526020015b60405180910390f35b610126610121366004610afe565b610242565b005b6101266102f9565b60045460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161010a565b60405160ff7f000000000000000000000000000000000000000000000000000000000000001e16815260200161010a565b6000545b60405190815260200161010a565b6101266101a9366004610b73565b61030d565b6101266101bc366004610bb1565b61048c565b61018d6104a0565b6101fb6101d7366004610bb1565b6002602052600090815260409020546fffffffffffffffffffffffffffffffff1681565b6040516fffffffffffffffffffffffffffffffff909116815260200161010a565b61012661022a366004610bca565b6104e5565b61012661023d366004610bb1565b610599565b61024b856105d1565b60035460408051608081018252878152602081018690528082018790526060810185905290517f2357251100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909216916323572511916102c291859190600401610bee565b60006040518083038186803b1580156102da57600080fd5b505afa1580156102ee573d6000803e3d6000fd5b505050505050505050565b610301610693565b61030b6000610964565b565b610315610693565b73ffffffffffffffffffffffffffffffffffffffff82166103bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f43726f7373446f6d61696e4f776e61626c65333a206e6577206f776e6572206960448201527f7320746865207a65726f2061646472657373000000000000000000000000000060648201526084015b60405180910390fd5b60006103de60045473ffffffffffffffffffffffffffffffffffffffff1690565b90506103e983610964565b6004805483151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90911617905560405173ffffffffffffffffffffffffffffffffffffffff80851691908316907f7fdc2a4b6eb39ec3363d710d188620bd1e97b3c434161f187b4d0dc0544faa589061047f90861515815260200190565b60405180910390a3505050565b610494610693565b61049d816109db565b50565b60006001546000036104de576040517f5b8dabb700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060015490565b6104ed610693565b73ffffffffffffffffffffffffffffffffffffffff8116610590576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103b4565b61049d81610964565b6105a1610693565b61049d81610a16565b60006010602060ff841682118015906105c957508060ff168460ff1611155b949350505050565b60015481036105dd5750565b6000818152600260205260408120546fffffffffffffffffffffffffffffffff1690819003610638576040517fddae3b7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000546106576fffffffffffffffffffffffffffffffff831642610c2e565b111561068f576040517f3ae7359e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60045474010000000000000000000000000000000000000000900460ff161561077957336106d660045473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff161461030b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f43726f7373446f6d61696e4f776e61626c65333a2063616c6c6572206973206e60448201527f6f7420746865206f776e6572000000000000000000000000000000000000000060648201526084016103b4565b73420000000000000000000000000000000000000733811461081d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4f776e61626c65333a2063616c6c6572206973206e60448201527f6f7420746865206d657373656e6765720000000000000000000000000000000060648201526084016103b4565b8073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610868573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088c9190610c6c565b73ffffffffffffffffffffffffffffffffffffffff166108c160045473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff161461049d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f43726f7373446f6d61696e4f776e61626c65333a2063616c6c6572206973206e60448201527f6f7420746865206f776e6572000000000000000000000000000000000000000060648201526084016103b4565b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60008190556040518181527f147b815b6a3a8dd5d49310410e089f6b5e9f3782e944772edc938c8bb48ef1219060200160405180910390a150565b6000818152600260205260409020546fffffffffffffffffffffffffffffffff168015610a6f576040517f6650c4d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600182905560008281526002602090815260409182902080547fffffffffffffffffffffffffffffffff0000000000000000000000000000000016426fffffffffffffffffffffffffffffffff8116918217909255835186815292830152917fe97c89cbb137505b36f55ebfc9732fd6c4c73ff43d49db239fc25f6e7a534145910160405180910390a1505050565b6000806000806000610180808789031215610b1857600080fd5b86359550602087013594506040870135935060608701359250878188011115610b4057600080fd5b506080860190509295509295909350565b73ffffffffffffffffffffffffffffffffffffffff8116811461049d57600080fd5b60008060408385031215610b8657600080fd5b8235610b9181610b51565b915060208301358015158114610ba657600080fd5b809150509250929050565b600060208284031215610bc357600080fd5b5035919050565b600060208284031215610bdc57600080fd5b8135610be781610b51565b9392505050565b610180810161010080858437600090830181815284915b6004811015610c24578251825260209283019290910190600101610c05565b5050509392505050565b600082821015610c67577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500390565b600060208284031215610c7e57600080fd5b8151610be781610b5156fea164736f6c634300080f000a","storage": {"0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000093a80","0x0000000000000000000000000000000000000000000000000000000000000002": "0x1EA570C7FAA4C051BC7625539D1E215F2B9D699110139BCE6B10C4B6E9A012A3","0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000a16e02e87b7454126e5e10d957a927a7f5b5d2be","0x0000000000000000000000000000000000000000000000000000000000000004": "0x000000000000000000000001f39fd6e51aad88f6f4ce6ab8827279cfffb92266"}}}\' > tmp.$$.json && mv tmp.$$.json $STATE_DUMP_PATH', + 'cat $STATE_DUMP_PATH | jq \'. |= . + {"0x4e59b44847b379578588920ca78fbf26c0b4956c": {"nonce": "0x0","balance": "0x0","code": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3","storage": {}},"0x047eE5313F98E26Cc8177fA38877cB36292D2364": {"nonce": "0x2","balance": "0x0","code": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c8063b242e53411610081578063f1c621ee1161005b578063f1c621ee146101c9578063f2fde38b1461021c578063fbde929b1461022f57600080fd5b8063b242e5341461019b578063c70aa727146101ae578063d7b0fef1146101c157600080fd5b80638da5cb5b116100b25780638da5cb5b146101305780638e5cdd5014610158578063b0d690791461018957600080fd5b80630ee04629146100d9578063354ca12014610113578063715018a614610128575b600080fd5b6004546100fe9074010000000000000000000000000000000000000000900460ff1681565b60405190151581526020015b60405180910390f35b610126610121366004610afe565b610242565b005b6101266102f9565b60045460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161010a565b60405160ff7f000000000000000000000000000000000000000000000000000000000000001e16815260200161010a565b6000545b60405190815260200161010a565b6101266101a9366004610b73565b61030d565b6101266101bc366004610bb1565b61048c565b61018d6104a0565b6101fb6101d7366004610bb1565b6002602052600090815260409020546fffffffffffffffffffffffffffffffff1681565b6040516fffffffffffffffffffffffffffffffff909116815260200161010a565b61012661022a366004610bca565b6104e5565b61012661023d366004610bb1565b610599565b61024b856105d1565b60035460408051608081018252878152602081018690528082018790526060810185905290517f2357251100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909216916323572511916102c291859190600401610bee565b60006040518083038186803b1580156102da57600080fd5b505afa1580156102ee573d6000803e3d6000fd5b505050505050505050565b610301610693565b61030b6000610964565b565b610315610693565b73ffffffffffffffffffffffffffffffffffffffff82166103bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f43726f7373446f6d61696e4f776e61626c65333a206e6577206f776e6572206960448201527f7320746865207a65726f2061646472657373000000000000000000000000000060648201526084015b60405180910390fd5b60006103de60045473ffffffffffffffffffffffffffffffffffffffff1690565b90506103e983610964565b6004805483151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90911617905560405173ffffffffffffffffffffffffffffffffffffffff80851691908316907f7fdc2a4b6eb39ec3363d710d188620bd1e97b3c434161f187b4d0dc0544faa589061047f90861515815260200190565b60405180910390a3505050565b610494610693565b61049d816109db565b50565b60006001546000036104de576040517f5b8dabb700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060015490565b6104ed610693565b73ffffffffffffffffffffffffffffffffffffffff8116610590576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103b4565b61049d81610964565b6105a1610693565b61049d81610a16565b60006010602060ff841682118015906105c957508060ff168460ff1611155b949350505050565b60015481036105dd5750565b6000818152600260205260408120546fffffffffffffffffffffffffffffffff1690819003610638576040517fddae3b7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000546106576fffffffffffffffffffffffffffffffff831642610c2e565b111561068f576040517f3ae7359e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60045474010000000000000000000000000000000000000000900460ff161561077957336106d660045473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff161461030b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f43726f7373446f6d61696e4f776e61626c65333a2063616c6c6572206973206e60448201527f6f7420746865206f776e6572000000000000000000000000000000000000000060648201526084016103b4565b73420000000000000000000000000000000000000733811461081d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4f776e61626c65333a2063616c6c6572206973206e60448201527f6f7420746865206d657373656e6765720000000000000000000000000000000060648201526084016103b4565b8073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610868573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088c9190610c6c565b73ffffffffffffffffffffffffffffffffffffffff166108c160045473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff161461049d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f43726f7373446f6d61696e4f776e61626c65333a2063616c6c6572206973206e60448201527f6f7420746865206f776e6572000000000000000000000000000000000000000060648201526084016103b4565b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60008190556040518181527f147b815b6a3a8dd5d49310410e089f6b5e9f3782e944772edc938c8bb48ef1219060200160405180910390a150565b6000818152600260205260409020546fffffffffffffffffffffffffffffffff168015610a6f576040517f6650c4d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600182905560008281526002602090815260409182902080547fffffffffffffffffffffffffffffffff0000000000000000000000000000000016426fffffffffffffffffffffffffffffffff8116918217909255835186815292830152917fe97c89cbb137505b36f55ebfc9732fd6c4c73ff43d49db239fc25f6e7a534145910160405180910390a1505050565b6000806000806000610180808789031215610b1857600080fd5b86359550602087013594506040870135935060608701359250878188011115610b4057600080fd5b506080860190509295509295909350565b73ffffffffffffffffffffffffffffffffffffffff8116811461049d57600080fd5b60008060408385031215610b8657600080fd5b8235610b9181610b51565b915060208301358015158114610ba657600080fd5b809150509250929050565b600060208284031215610bc357600080fd5b5035919050565b600060208284031215610bdc57600080fd5b8135610be781610b51565b9392505050565b610180810161010080858437600090830181815284915b6004811015610c24578251825260209283019290910190600101610c05565b5050509392505050565b600082821015610c67577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500390565b600060208284031215610c7e57600080fd5b8151610be781610b5156fea164736f6c634300080f000a","storage": {"0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000093a80","0x0000000000000000000000000000000000000000000000000000000000000002": "0x0AC9D5995841E9D09387685C7155E6F08B2A92D984A8A2F282C48D6CC08DB3CE","0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000a16e02e87b7454126e5e10d957a927a7f5b5d2be","0x0000000000000000000000000000000000000000000000000000000000000004": "0x000000000000000000000001f39fd6e51aad88f6f4ce6ab8827279cfffb92266"}}}\' > tmp.$$.json && mv tmp.$$.json $STATE_DUMP_PATH', "cd /workspace/optimism/op-node/bin", "./op-node genesis l2 \ --l1-rpc $L1_RPC_URL \ diff --git a/world-chain-builder/crates/assertor/src/main.rs b/world-chain-builder/crates/assertor/src/main.rs index 3f53ebd7..8e003918 100644 --- a/world-chain-builder/crates/assertor/src/main.rs +++ b/world-chain-builder/crates/assertor/src/main.rs @@ -6,9 +6,9 @@ use std::{ time::{Duration, Instant}, }; -use alloy_primitives::Bytes; -use alloy_provider::{Provider, ProviderBuilder}; -use alloy_rpc_types_eth::BlockNumberOrTag; +use alloy_primitives::{hex, Bytes}; +use alloy_provider::{PendingTransactionBuilder, Provider, ProviderBuilder}; +use alloy_rpc_types_eth::{erc4337::ConditionalOptions, BlockNumberOrTag}; use alloy_transport::Transport; use clap::Parser; use eyre::eyre::{eyre, Result}; @@ -128,11 +128,28 @@ where { let fixture = serde_json::from_str::(PBH_FIXTURE)?; let mut queue = vec![]; - for transaction in fixture.fixture.iter() { + + // Send half with `eth_sendRawTransaction` and the other half with `eth_sendRawTransactionConditional` + for transaction in fixture.fixture.iter().take(fixture.fixture.len() / 2) { let tx = builder_provider.send_raw_transaction(transaction).await?; queue.push(tx); } + for transaction in fixture.fixture.iter().skip(fixture.fixture.len() / 2) { + let rlp_hex = hex::encode_prefixed(transaction); + let tx_hash = builder_provider + .client() + .request( + "eth_sendRawTransactionConditional", + (rlp_hex, ConditionalOptions::default(),), + ) + .await?; + queue.push(PendingTransactionBuilder::new( + builder_provider.root(), + tx_hash, + )); + } + let futs = queue.into_iter().map(|builder| async { let hash = builder.tx_hash().clone(); let receipt = builder.get_receipt().await; diff --git a/world-chain-builder/src/rpc/bundle.rs b/world-chain-builder/src/rpc/bundle.rs index 851eb6d8..ebdf21de 100644 --- a/world-chain-builder/src/rpc/bundle.rs +++ b/world-chain-builder/src/rpc/bundle.rs @@ -1,15 +1,15 @@ use crate::{pool::tx::WorldChainPooledTransaction, primitives::recover_raw_transaction}; use alloy_eips::BlockId; +use alloy_primitives::map::HashMap; use alloy_rpc_types::erc4337::{AccountStorage, ConditionalOptions}; use jsonrpsee::{ core::{async_trait, RpcResult}, proc_macros::rpc, types::{ErrorCode, ErrorObject, ErrorObjectOwned}, }; - use reth::transaction_pool::{PoolTransaction, TransactionOrigin, TransactionPool}; use reth_provider::{BlockReaderIdExt, StateProviderFactory}; -use revm_primitives::{Address, Bytes, FixedBytes, HashMap, B256}; +use revm_primitives::{map::FbBuildHasher, Address, Bytes, FixedBytes, B256}; /// Trait interface for `eth_sendRawTransactionConditional` #[cfg_attr(not(test), rpc(server, namespace = "eth"))] @@ -89,27 +89,29 @@ where })? .ok_or(ErrorObjectOwned::from(ErrorCode::InternalError))?; + self.validate_known_accounts(options.known_accounts, latest.header.number.into())?; + if let Some(min_block) = options.block_number_min { if min_block > latest.number { - return Err(ErrorObjectOwned::from(ErrorCode::from(-32003))); + return Err(ErrorCode::from(-32003).into()); } } if let Some(max_block) = options.block_number_max { if max_block <= latest.number { - return Err(ErrorObjectOwned::from(ErrorCode::from(-32003))); + return Err(ErrorCode::from(-32003).into()); } } if let Some(min_timestamp) = options.timestamp_min { if min_timestamp > latest.timestamp { - return Err(ErrorObjectOwned::from(ErrorCode::from(-32003))); + return Err(ErrorCode::from(-32003).into()); } } if let Some(max_timestamp) = options.timestamp_max { if max_timestamp <= latest.timestamp { - return Err(ErrorObjectOwned::from(ErrorCode::from(-32003))); + return Err(ErrorCode::from(-32003).into()); } } @@ -119,26 +121,31 @@ where /// Validates the account storage slots/storage root provided by the client /// /// Matches the current state of the account storage slots/storage root. - /// TODO: We need to throttle the number of accounts that can be validated at once for DOS protection. pub fn validate_known_accounts( &self, - known_accounts: HashMap, + known_accounts: HashMap>, + latest: BlockId, ) -> RpcResult<()> { let state = self .provider() - .state_by_block_id(BlockId::latest()) - .map_err(|_| ErrorObjectOwned::from(ErrorCode::InternalError))?; + .state_by_block_id(latest) + .map_err(|e| { + ErrorObject::owned(ErrorCode::InternalError.code(), e.to_string(), Some("")) + })?; - for (address, storage) in known_accounts.iter() { + for (address, storage) in known_accounts.into_iter() { match storage { AccountStorage::Slots(slots) => { - for (slot, value) in slots.iter() { - let current = state - .storage(*address, slot.clone().into()) - .map_err(|_| ErrorObjectOwned::from(ErrorCode::InternalError))?; + for (slot, value) in slots.into_iter() { + let current = state.storage(address, slot.into()).map_err(|e| { + ErrorObject::owned( + ErrorCode::InternalError.code(), + e.to_string(), + Some(""), + ) + })?; if let Some(current) = current { - if FixedBytes::<32>::from_slice(¤t.to_be_bytes::<32>()) != *value - { + if FixedBytes::<32>::from_slice(¤t.to_be_bytes::<32>()) != value { return Err(ErrorCode::from(-32003).into()); } } else { @@ -148,8 +155,14 @@ where } AccountStorage::RootHash(expected) => { let root = state - .storage_root(*address, Default::default()) - .map_err(|_| ErrorObjectOwned::from(ErrorCode::InternalError))?; + .storage_root(address, Default::default()) + .map_err(|e| { + ErrorObject::owned( + ErrorCode::InternalError.code(), + e.to_string(), + Some(""), + ) + })?; if *expected != root { return Err(ErrorCode::from(-32003).into()); } diff --git a/world-chain-builder/src/test/e2e/mod.rs b/world-chain-builder/src/test/e2e/mod.rs index 1b728083..6f37b33a 100644 --- a/world-chain-builder/src/test/e2e/mod.rs +++ b/world-chain-builder/src/test/e2e/mod.rs @@ -18,6 +18,7 @@ use crate::{ primitives::WorldChainPooledTransactionsElement, rpc::bundle::{EthTransactionsExtServer, WorldChainEthApiExt}, }; +use alloy_primitives::bytes; use alloy_eips::eip2718::Decodable2718; use alloy_genesis::{Genesis, GenesisAccount}; use alloy_network::eip2718::Encodable2718; @@ -266,6 +267,15 @@ async fn test_can_build_pbh_payload() -> eyre::Result<()> { Ok(()) } +#[tokio::test] +async fn test_decode_transaction() -> eyre::Result<()> { + let tx = bytes!("02f8698320d5e4800184516d19dd82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a081ad5010d3f502b279540af054216ceb8fc929e919022088e766cf2ceced894ea053a971501c8e2b426cf5c043f390b9e454d92794562a60029605d397f02bb27ff901518b76312d3132323032342d30a00192a1143ac457fab0cf5a07a852c15db32a1825d9048a2eb406e8aaffadb742a00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb901002b0592638030cd0a68b32ea2a7461d3dc1cfa78280091ec9688d97698011a47b283d6fac359cd0140f11d105b6a01978bd06b47d5eb6f15991ea2916008534e81e5f13adcf1dab880a7b5d9ee6dca817effff98f27e9699bf6071bf1643fb91a27f772e9311c6dfbd4446e83c18c2ebb4eee2df64e4f5a584a70d96ea0637e2f2fc48dfa438fba778bcdbb3b125e4d56b82c4475ee899924c044b5f24ba795de12ee755d5c96bf31dde93857f790db06fda0d0c2262d75fab74ea840c12381cc1857ee75d5ee27fef42ad0f46e54ac8e7dd05d9bb99af3aafc5c13cbab370a61069e42d444daada4fb0a907ee9b9abf22ffb2d21ca4b064de8647cd94586b2fd"); + let pooled_tx = WorldChainPooledTransactionsElement::decode_2718(&mut &tx[..])?; + let root = pooled_tx.pbh_payload.unwrap().root; + println!("{:?}", root); + Ok(()) +} + #[tokio::test] #[serial] async fn test_transaction_pool_ordering() -> eyre::Result<()> { From 85aed124e4f1f557b53c8582c6754350c904706e Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Tue, 10 Dec 2024 08:55:08 -0700 Subject: [PATCH 06/59] pr suggestion --- .../crates/assertor/src/main.rs | 71 ++++++++++--------- world-chain-builder/src/rpc/bundle.rs | 9 +-- world-chain-builder/src/test/e2e/mod.rs | 6 +- 3 files changed, 44 insertions(+), 42 deletions(-) diff --git a/world-chain-builder/crates/assertor/src/main.rs b/world-chain-builder/crates/assertor/src/main.rs index 8e003918..c1f54c4a 100644 --- a/world-chain-builder/crates/assertor/src/main.rs +++ b/world-chain-builder/crates/assertor/src/main.rs @@ -12,12 +12,13 @@ use alloy_rpc_types_eth::{erc4337::ConditionalOptions, BlockNumberOrTag}; use alloy_transport::Transport; use clap::Parser; use eyre::eyre::{eyre, Result}; +use futures::{stream, StreamExt, TryStreamExt}; use serde::Deserialize; use tokio::time::sleep; use tracing::{debug, info}; const PBH_FIXTURE: &str = include_str!("../../../../devnet/fixtures/fixture.json"); - +const CONCURRENCY_LIMIT: usize = 50; #[derive(Deserialize, Clone)] pub struct PbhFixture { pub fixture: Vec, @@ -127,38 +128,42 @@ where P: Provider, { let fixture = serde_json::from_str::(PBH_FIXTURE)?; - let mut queue = vec![]; - - // Send half with `eth_sendRawTransaction` and the other half with `eth_sendRawTransactionConditional` - for transaction in fixture.fixture.iter().take(fixture.fixture.len() / 2) { - let tx = builder_provider.send_raw_transaction(transaction).await?; - queue.push(tx); - } - - for transaction in fixture.fixture.iter().skip(fixture.fixture.len() / 2) { - let rlp_hex = hex::encode_prefixed(transaction); - let tx_hash = builder_provider - .client() - .request( - "eth_sendRawTransactionConditional", - (rlp_hex, ConditionalOptions::default(),), - ) - .await?; - queue.push(PendingTransactionBuilder::new( - builder_provider.root(), - tx_hash, - )); - } - - let futs = queue.into_iter().map(|builder| async { - let hash = builder.tx_hash().clone(); - let receipt = builder.get_receipt().await; - assert!(receipt.is_ok()); - debug!(receipt = ?receipt.unwrap(), hash = ?hash, "Transaction Receipt Received"); - }); - - futures::future::join_all(futs).await; - + let num_transactions = fixture.fixture.len(); + let half = num_transactions / 2; + let builder_provider_clone = builder_provider.clone(); + stream::iter(fixture.fixture.iter().enumerate()) + .map(Ok) + .try_for_each_concurrent(CONCURRENCY_LIMIT, move |(index, transaction)| { + let builder_provider = builder_provider_clone.clone(); + async move { + let tx = if index < half { + // First half, use eth_sendRawTransaction + builder_provider.send_raw_transaction(transaction).await? + } else { + // Second half, use eth_sendRawTransactionConditional + let rlp_hex = hex::encode_prefixed(transaction); + let tx_hash = builder_provider + .client() + .request( + "eth_sendRawTransactionConditional", + (rlp_hex, ConditionalOptions::default()), + ) + .await?; + PendingTransactionBuilder::new(builder_provider.root(), tx_hash) + }; + let hash = *tx.tx_hash(); + let receipt = tx.get_receipt().await; + assert!(receipt.is_ok()); + debug!( + receipt = ?receipt.unwrap(), + hash = ?hash, + index = index, + "Transaction Receipt Received" + ); + Ok::<(), eyre::Report>(()) + } + }) + .await?; Ok(()) } diff --git a/world-chain-builder/src/rpc/bundle.rs b/world-chain-builder/src/rpc/bundle.rs index ebdf21de..03a896f7 100644 --- a/world-chain-builder/src/rpc/bundle.rs +++ b/world-chain-builder/src/rpc/bundle.rs @@ -126,12 +126,9 @@ where known_accounts: HashMap>, latest: BlockId, ) -> RpcResult<()> { - let state = self - .provider() - .state_by_block_id(latest) - .map_err(|e| { - ErrorObject::owned(ErrorCode::InternalError.code(), e.to_string(), Some("")) - })?; + let state = self.provider().state_by_block_id(latest).map_err(|e| { + ErrorObject::owned(ErrorCode::InternalError.code(), e.to_string(), Some("")) + })?; for (address, storage) in known_accounts.into_iter() { match storage { diff --git a/world-chain-builder/src/test/e2e/mod.rs b/world-chain-builder/src/test/e2e/mod.rs index 6f37b33a..6296344d 100644 --- a/world-chain-builder/src/test/e2e/mod.rs +++ b/world-chain-builder/src/test/e2e/mod.rs @@ -18,11 +18,11 @@ use crate::{ primitives::WorldChainPooledTransactionsElement, rpc::bundle::{EthTransactionsExtServer, WorldChainEthApiExt}, }; -use alloy_primitives::bytes; use alloy_eips::eip2718::Decodable2718; use alloy_genesis::{Genesis, GenesisAccount}; use alloy_network::eip2718::Encodable2718; use alloy_network::{Ethereum, EthereumWallet, TransactionBuilder}; +use alloy_primitives::bytes; use alloy_rpc_types::{TransactionInput, TransactionRequest}; use alloy_signer_local::PrivateKeySigner; use chrono::Utc; @@ -269,8 +269,8 @@ async fn test_can_build_pbh_payload() -> eyre::Result<()> { #[tokio::test] async fn test_decode_transaction() -> eyre::Result<()> { - let tx = bytes!("02f8698320d5e4800184516d19dd82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a081ad5010d3f502b279540af054216ceb8fc929e919022088e766cf2ceced894ea053a971501c8e2b426cf5c043f390b9e454d92794562a60029605d397f02bb27ff901518b76312d3132323032342d30a00192a1143ac457fab0cf5a07a852c15db32a1825d9048a2eb406e8aaffadb742a00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb901002b0592638030cd0a68b32ea2a7461d3dc1cfa78280091ec9688d97698011a47b283d6fac359cd0140f11d105b6a01978bd06b47d5eb6f15991ea2916008534e81e5f13adcf1dab880a7b5d9ee6dca817effff98f27e9699bf6071bf1643fb91a27f772e9311c6dfbd4446e83c18c2ebb4eee2df64e4f5a584a70d96ea0637e2f2fc48dfa438fba778bcdbb3b125e4d56b82c4475ee899924c044b5f24ba795de12ee755d5c96bf31dde93857f790db06fda0d0c2262d75fab74ea840c12381cc1857ee75d5ee27fef42ad0f46e54ac8e7dd05d9bb99af3aafc5c13cbab370a61069e42d444daada4fb0a907ee9b9abf22ffb2d21ca4b064de8647cd94586b2fd"); - let pooled_tx = WorldChainPooledTransactionsElement::decode_2718(&mut &tx[..])?; + let tx = bytes!("02f8698320d5e4800184516d19dd82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a081ad5010d3f502b279540af054216ceb8fc929e919022088e766cf2ceced894ea053a971501c8e2b426cf5c043f390b9e454d92794562a60029605d397f02bb27ff901518b76312d3132323032342d30a00192a1143ac457fab0cf5a07a852c15db32a1825d9048a2eb406e8aaffadb742a00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb901002b0592638030cd0a68b32ea2a7461d3dc1cfa78280091ec9688d97698011a47b283d6fac359cd0140f11d105b6a01978bd06b47d5eb6f15991ea2916008534e81e5f13adcf1dab880a7b5d9ee6dca817effff98f27e9699bf6071bf1643fb91a27f772e9311c6dfbd4446e83c18c2ebb4eee2df64e4f5a584a70d96ea0637e2f2fc48dfa438fba778bcdbb3b125e4d56b82c4475ee899924c044b5f24ba795de12ee755d5c96bf31dde93857f790db06fda0d0c2262d75fab74ea840c12381cc1857ee75d5ee27fef42ad0f46e54ac8e7dd05d9bb99af3aafc5c13cbab370a61069e42d444daada4fb0a907ee9b9abf22ffb2d21ca4b064de8647cd94586b2fd"); + let pooled_tx = WorldChainPooledTransactionsElement::decode_2718(&mut &tx[..])?; let root = pooled_tx.pbh_payload.unwrap().root; println!("{:?}", root); Ok(()) From 9dc6734a4d0de39c95cd83f95b4147ba644dfac7 Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Tue, 10 Dec 2024 09:59:31 -0700 Subject: [PATCH 07/59] rm superflouos tests --- world-chain-builder/src/test/e2e/mod.rs | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/world-chain-builder/src/test/e2e/mod.rs b/world-chain-builder/src/test/e2e/mod.rs index 6296344d..68302f4e 100644 --- a/world-chain-builder/src/test/e2e/mod.rs +++ b/world-chain-builder/src/test/e2e/mod.rs @@ -267,15 +267,6 @@ async fn test_can_build_pbh_payload() -> eyre::Result<()> { Ok(()) } -#[tokio::test] -async fn test_decode_transaction() -> eyre::Result<()> { - let tx = bytes!("02f8698320d5e4800184516d19dd82520894deadbeefdeadbeefdeadbeefdeadbeefdeadbeef8080c080a081ad5010d3f502b279540af054216ceb8fc929e919022088e766cf2ceced894ea053a971501c8e2b426cf5c043f390b9e454d92794562a60029605d397f02bb27ff901518b76312d3132323032342d30a00192a1143ac457fab0cf5a07a852c15db32a1825d9048a2eb406e8aaffadb742a00ac9d5995841e9d09387685c7155e6f08b2a92d984a8a2f282c48d6cc08db3ceb901002b0592638030cd0a68b32ea2a7461d3dc1cfa78280091ec9688d97698011a47b283d6fac359cd0140f11d105b6a01978bd06b47d5eb6f15991ea2916008534e81e5f13adcf1dab880a7b5d9ee6dca817effff98f27e9699bf6071bf1643fb91a27f772e9311c6dfbd4446e83c18c2ebb4eee2df64e4f5a584a70d96ea0637e2f2fc48dfa438fba778bcdbb3b125e4d56b82c4475ee899924c044b5f24ba795de12ee755d5c96bf31dde93857f790db06fda0d0c2262d75fab74ea840c12381cc1857ee75d5ee27fef42ad0f46e54ac8e7dd05d9bb99af3aafc5c13cbab370a61069e42d444daada4fb0a907ee9b9abf22ffb2d21ca4b064de8647cd94586b2fd"); - let pooled_tx = WorldChainPooledTransactionsElement::decode_2718(&mut &tx[..])?; - let root = pooled_tx.pbh_payload.unwrap().root; - println!("{:?}", root); - Ok(()) -} - #[tokio::test] #[serial] async fn test_transaction_pool_ordering() -> eyre::Result<()> { @@ -330,14 +321,6 @@ async fn test_invalidate_dup_tx_and_nullifier() -> eyre::Result<()> { Ok(()) } -#[tokio::test] -#[serial] -async fn test_send_raw_transaction_conditional() -> eyre::Result<()> { - let ctx = WorldChainBuilderTestContext::setup().await?; - println!("{:?}", ctx.node.rpc.inner.methods()); - Ok(()) -} - #[tokio::test] #[serial] async fn test_dup_pbh_nonce() -> eyre::Result<()> { From 89a3f2b6a494d83a3a341810fab2b9558da6afcb Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Tue, 10 Dec 2024 09:59:47 -0700 Subject: [PATCH 08/59] unused imports --- world-chain-builder/src/test/e2e/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/world-chain-builder/src/test/e2e/mod.rs b/world-chain-builder/src/test/e2e/mod.rs index 68302f4e..d43ca667 100644 --- a/world-chain-builder/src/test/e2e/mod.rs +++ b/world-chain-builder/src/test/e2e/mod.rs @@ -22,7 +22,6 @@ use alloy_eips::eip2718::Decodable2718; use alloy_genesis::{Genesis, GenesisAccount}; use alloy_network::eip2718::Encodable2718; use alloy_network::{Ethereum, EthereumWallet, TransactionBuilder}; -use alloy_primitives::bytes; use alloy_rpc_types::{TransactionInput, TransactionRequest}; use alloy_signer_local::PrivateKeySigner; use chrono::Utc; From 18acd94f46a8c78a3f2b8ebd42ee02039962e7bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Tr=C4=85d?= Date: Wed, 11 Dec 2024 15:41:33 +0100 Subject: [PATCH 09/59] Use tables macro (#75) --- world-chain-builder/Cargo.lock | 1 + world-chain-builder/Cargo.toml | 1 + world-chain-builder/src/pbh/db.rs | 36 ++++++++++------------- world-chain-builder/src/pool/validator.rs | 6 ++-- 4 files changed, 21 insertions(+), 23 deletions(-) diff --git a/world-chain-builder/Cargo.lock b/world-chain-builder/Cargo.lock index 8c84e87f..bc871846 100644 --- a/world-chain-builder/Cargo.lock +++ b/world-chain-builder/Cargo.lock @@ -13549,6 +13549,7 @@ dependencies = [ "reth-cli-util", "reth-consensus", "reth-db", + "reth-db-api", "reth-e2e-test-utils", "reth-eth-wire-types", "reth-evm", diff --git a/world-chain-builder/Cargo.toml b/world-chain-builder/Cargo.toml index 1bdfabe4..52be3af1 100644 --- a/world-chain-builder/Cargo.toml +++ b/world-chain-builder/Cargo.toml @@ -14,6 +14,7 @@ reth = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } reth-cli-util = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } reth-evm = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } reth-db = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } +reth-db-api = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } reth-provider = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda", features = [ "test-utils", ] } diff --git a/world-chain-builder/src/pbh/db.rs b/world-chain-builder/src/pbh/db.rs index e643cacd..341d7b57 100644 --- a/world-chain-builder/src/pbh/db.rs +++ b/world-chain-builder/src/pbh/db.rs @@ -1,32 +1,28 @@ +use std::fmt; +use std::path::Path; +use std::sync::Arc; + use bytes::BufMut; use reth_db::cursor::DbCursorRW; use reth_db::mdbx::tx::Tx; use reth_db::mdbx::{DatabaseArguments, DatabaseFlags, RW}; use reth_db::table::{Compress, Decompress, Table}; use reth_db::transaction::DbTxMut; -use reth_db::{create_db, DatabaseError}; +use reth_db::{create_db, tables, DatabaseError, TableType, TableViewer}; +use reth_db_api; use revm_primitives::{FixedBytes, B256}; use semaphore::Field; use serde::{Deserialize, Serialize}; -use std::path::Path; -use std::sync::Arc; use tracing::info; -/// Table to store PBH validated transactions along with their nullifiers. -/// -/// When a trasnaction is validated before being inserted into the pool, -/// a mapping is created from the transaction hash to the nullifier here. -/// This is primarily used as a caching mechanism to avoid certain types of -/// DoS attacks. -#[derive(Debug, Clone, Default)] -pub struct ValidatedPbhTransactionTable; - -impl Table for ValidatedPbhTransactionTable { - const NAME: &'static str = "ValidatedPbhTransactions"; - - type Key = B256; - - type Value = EmptyValue; +tables! { + /// Table to store PBH validated transactions along with their nullifiers. + /// + /// When a trasnaction is validated before being inserted into the pool, + /// a mapping is created from the transaction hash to the nullifier here. + /// This is primarily used as a caching mechanism to avoid certain types of + /// DoS attacks. + table ValidatedPbhTransaction; } #[derive(Debug, Clone, Default, Serialize, Deserialize)] @@ -49,7 +45,7 @@ impl Compress for EmptyValue { /// don't forget to call db_tx.commit() at the very end pub fn set_pbh_nullifier(db_tx: &Tx, nullifier: Field) -> Result<(), DatabaseError> { let bytes: FixedBytes<32> = nullifier.into(); - let mut cursor = db_tx.cursor_write::()?; + let mut cursor = db_tx.cursor_write::()?; cursor.insert(bytes, EmptyValue)?; Ok(()) } @@ -72,7 +68,7 @@ pub fn load_world_chain_db( .map_err(|e| DatabaseError::InitTx(e.into()))?; tx.create_db( - Some(ValidatedPbhTransactionTable::NAME), + Some(ValidatedPbhTransaction::NAME), DatabaseFlags::default(), ) .map_err(|e| DatabaseError::CreateTable(e.into()))?; diff --git a/world-chain-builder/src/pool/validator.rs b/world-chain-builder/src/pool/validator.rs index 332de204..3c32df0e 100644 --- a/world-chain-builder/src/pool/validator.rs +++ b/world-chain-builder/src/pool/validator.rs @@ -19,7 +19,7 @@ use super::ordering::WorldChainOrdering; use super::root::WorldChainRootValidator; use super::tx::{WorldChainPoolTransaction, WorldChainPooledTransaction}; use crate::pbh::date_marker::DateMarker; -use crate::pbh::db::{EmptyValue, ValidatedPbhTransactionTable}; +use crate::pbh::db::{EmptyValue, ValidatedPbhTransaction}; use crate::pbh::external_nullifier::ExternalNullifier; use crate::pbh::payload::{PbhPayload, TREE_DEPTH}; @@ -71,7 +71,7 @@ where pub fn set_validated(&self, pbh_payload: &PbhPayload) -> Result<(), DatabaseError> { let db_tx = self.pbh_db.tx_mut()?; - let mut cursor = db_tx.cursor_write::()?; + let mut cursor = db_tx.cursor_write::()?; cursor.insert(pbh_payload.nullifier_hash.to_be_bytes().into(), EmptyValue)?; db_tx.commit()?; Ok(()) @@ -138,7 +138,7 @@ where // Create db transaction and insert the nullifier hash // We do this first to prevent repeatedly validating the same transaction let db_tx = self.pbh_db.tx_mut()?; - let mut cursor = db_tx.cursor_write::()?; + let mut cursor = db_tx.cursor_write::()?; cursor.insert(payload.nullifier_hash.to_be_bytes().into(), EmptyValue)?; let res = verify_proof( From dbe930ea6027948ac11a928b388ad2f0b2af60bc Mon Sep 17 00:00:00 2001 From: 0xKitsune <0xkitsune@protonmail.com> Date: Wed, 11 Dec 2024 13:44:21 -0500 Subject: [PATCH 10/59] add conditional options to pooled tx --- world-chain-builder/src/pool/tx.rs | 7 ++++- world-chain-builder/src/rpc/bundle.rs | 39 +++++++++++++++------------ world-chain-builder/src/test/mod.rs | 2 ++ 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/world-chain-builder/src/pool/tx.rs b/world-chain-builder/src/pool/tx.rs index 8bd2064e..aecd8322 100644 --- a/world-chain-builder/src/pool/tx.rs +++ b/world-chain-builder/src/pool/tx.rs @@ -1,4 +1,5 @@ use alloy_primitives::TxHash; +use alloy_rpc_types::erc4337::ConditionalOptions; use reth::transaction_pool::{EthPoolTransaction, EthPooledTransaction, PoolTransaction}; use reth_primitives::transaction::TryFromRecoveredTransactionError; use reth_primitives::{PooledTransactionsElementEcRecovered, TransactionSignedEcRecovered}; @@ -11,10 +12,11 @@ pub trait WorldChainPoolTransaction: EthPoolTransaction { fn pbh_payload(&self) -> Option<&PbhPayload>; } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone)] pub struct WorldChainPooledTransaction { pub inner: EthPooledTransaction, pub pbh_payload: Option, + pub conditional_options: Option, } impl EthPoolTransaction for WorldChainPooledTransaction { @@ -58,6 +60,7 @@ impl TryFrom for WorldChainPooledTransaction { Ok(Self { inner: EthPooledTransaction::try_from(tx)?, pbh_payload: None, + conditional_options: None, }) } } @@ -67,6 +70,7 @@ impl From for WorldChainPooledTr Self { inner: EthPooledTransaction::from_pooled(tx.inner), pbh_payload: tx.pbh_payload, + conditional_options: None, } } } @@ -99,6 +103,7 @@ impl PoolTransaction for WorldChainPooledTransaction { EthPooledTransaction::try_from_consensus(tx).map(|inner| Self { inner, pbh_payload: None, + conditional_options: None, }) } diff --git a/world-chain-builder/src/rpc/bundle.rs b/world-chain-builder/src/rpc/bundle.rs index 03a896f7..7873f2ee 100644 --- a/world-chain-builder/src/rpc/bundle.rs +++ b/world-chain-builder/src/rpc/bundle.rs @@ -1,6 +1,6 @@ use crate::{pool::tx::WorldChainPooledTransaction, primitives::recover_raw_transaction}; use alloy_eips::BlockId; -use alloy_primitives::map::HashMap; +use alloy_primitives::{map::HashMap, StorageKey}; use alloy_rpc_types::erc4337::{AccountStorage, ConditionalOptions}; use jsonrpsee::{ core::{async_trait, RpcResult}, @@ -44,9 +44,10 @@ where tx: Bytes, options: ConditionalOptions, ) -> RpcResult { - self.validate_options(options)?; + self.validate_options(&options)?; let (recovered, _) = recover_raw_transaction(tx.clone())?; - let pool_transaction = WorldChainPooledTransaction::from_pooled(recovered); + let mut pool_transaction = WorldChainPooledTransaction::from_pooled(recovered); + pool_transaction.conditional_options = Some(options); // submit the transaction to the pool with a `Local` origin let hash = self @@ -80,7 +81,7 @@ where /// /// reference for the implementation /// See also - pub fn validate_options(&self, options: ConditionalOptions) -> RpcResult<()> { + pub fn validate_options(&self, options: &ConditionalOptions) -> RpcResult<()> { let latest = self .provider() .block_by_id(BlockId::latest()) @@ -89,7 +90,7 @@ where })? .ok_or(ErrorObjectOwned::from(ErrorCode::InternalError))?; - self.validate_known_accounts(options.known_accounts, latest.header.number.into())?; + self.validate_known_accounts(&options.known_accounts, latest.header.number.into())?; if let Some(min_block) = options.block_number_min { if min_block > latest.number { @@ -123,26 +124,30 @@ where /// Matches the current state of the account storage slots/storage root. pub fn validate_known_accounts( &self, - known_accounts: HashMap>, + known_accounts: &HashMap>, latest: BlockId, ) -> RpcResult<()> { let state = self.provider().state_by_block_id(latest).map_err(|e| { ErrorObject::owned(ErrorCode::InternalError.code(), e.to_string(), Some("")) })?; - for (address, storage) in known_accounts.into_iter() { + for (address, storage) in known_accounts.iter() { match storage { AccountStorage::Slots(slots) => { - for (slot, value) in slots.into_iter() { - let current = state.storage(address, slot.into()).map_err(|e| { - ErrorObject::owned( - ErrorCode::InternalError.code(), - e.to_string(), - Some(""), - ) - })?; + for (slot, value) in slots.iter() { + let current = + state + .storage(*address, StorageKey::from(*slot)) + .map_err(|e| { + ErrorObject::owned( + ErrorCode::InternalError.code(), + e.to_string(), + Some(""), + ) + })?; if let Some(current) = current { - if FixedBytes::<32>::from_slice(¤t.to_be_bytes::<32>()) != value { + if FixedBytes::<32>::from_slice(¤t.to_be_bytes::<32>()) != *value + { return Err(ErrorCode::from(-32003).into()); } } else { @@ -152,7 +157,7 @@ where } AccountStorage::RootHash(expected) => { let root = state - .storage_root(address, Default::default()) + .storage_root(*address, Default::default()) .map_err(|e| { ErrorObject::owned( ErrorCode::InternalError.code(), diff --git a/world-chain-builder/src/test/mod.rs b/world-chain-builder/src/test/mod.rs index 309ca205..53fc0d08 100644 --- a/world-chain-builder/src/test/mod.rs +++ b/world-chain-builder/src/test/mod.rs @@ -39,6 +39,7 @@ pub fn get_non_pbh_transaction() -> WorldChainPooledTransaction { WorldChainPooledTransaction { inner: eth_tx, pbh_payload: None, + conditional_options: None, } } @@ -53,6 +54,7 @@ pub fn get_pbh_transaction(nonce: u16) -> WorldChainPooledTransaction { WorldChainPooledTransaction { inner: eth_tx, pbh_payload: Some(pbh_payload), + conditional_options: None, } } From 68d8a6ac279fa6a99e1c5519bacbcc6000b0dc1c Mon Sep 17 00:00:00 2001 From: 0xKitsune <0xkitsune@protonmail.com> Date: Wed, 11 Dec 2024 14:07:37 -0500 Subject: [PATCH 11/59] validate conditional options in the builder --- world-chain-builder/src/payload/builder.rs | 10 ++ world-chain-builder/src/pool/tx.rs | 5 + world-chain-builder/src/rpc/bundle.rs | 166 +++++++++++---------- 3 files changed, 101 insertions(+), 80 deletions(-) diff --git a/world-chain-builder/src/payload/builder.rs b/world-chain-builder/src/payload/builder.rs index 82fac64e..a6e59eb2 100644 --- a/world-chain-builder/src/payload/builder.rs +++ b/world-chain-builder/src/payload/builder.rs @@ -45,6 +45,7 @@ use tracing::{debug, trace, warn}; use crate::pool::noop::NoopWorldChainTransactionPool; use crate::pool::tx::WorldChainPoolTransaction; +use crate::rpc::bundle::validate_conditional_options; /// Priority blockspace for humans builder #[derive(Debug, Clone)] @@ -408,6 +409,14 @@ where if !attributes.no_tx_pool { let verified_gas_limit = (verified_blockspace_capacity as u64 * block_gas_limit) / 100; while let Some(pool_tx) = best_txs.next() { + if let Some(conditional_options) = pool_tx.transaction.conditional_options() { + if let Err(_) = validate_conditional_options(conditional_options, provider) { + // best_txs.mark_invalid(&pool_tx); + + continue; + } + } + // If the transaction is verified, check if it can be added within the verified gas limit if pool_tx.transaction.pbh_payload().is_some() && cumulative_gas_used + pool_tx.gas_limit() > verified_gas_limit @@ -995,6 +1004,7 @@ mod tests { WorldChainPooledTransaction { inner: pooled_tx, pbh_payload, + conditional_options: None, } }) .collect::>() diff --git a/world-chain-builder/src/pool/tx.rs b/world-chain-builder/src/pool/tx.rs index aecd8322..c2697953 100644 --- a/world-chain-builder/src/pool/tx.rs +++ b/world-chain-builder/src/pool/tx.rs @@ -10,6 +10,7 @@ use crate::primitives::WorldChainPooledTransactionsElementEcRecovered; pub trait WorldChainPoolTransaction: EthPoolTransaction { fn pbh_payload(&self) -> Option<&PbhPayload>; + fn conditional_options(&self) -> Option<&ConditionalOptions>; } #[derive(Debug, Clone)] @@ -45,6 +46,10 @@ impl WorldChainPoolTransaction for WorldChainPooledTransaction { fn pbh_payload(&self) -> Option<&PbhPayload> { self.pbh_payload.as_ref() } + + fn conditional_options(&self) -> Option<&ConditionalOptions> { + self.conditional_options.as_ref() + } } impl From for TransactionSignedEcRecovered { diff --git a/world-chain-builder/src/rpc/bundle.rs b/world-chain-builder/src/rpc/bundle.rs index 7873f2ee..d2bdf596 100644 --- a/world-chain-builder/src/rpc/bundle.rs +++ b/world-chain-builder/src/rpc/bundle.rs @@ -44,7 +44,8 @@ where tx: Bytes, options: ConditionalOptions, ) -> RpcResult { - self.validate_options(&options)?; + validate_conditional_options(&options, self.provider())?; + let (recovered, _) = recover_raw_transaction(tx.clone())?; let mut pool_transaction = WorldChainPooledTransaction::from_pooled(recovered); pool_transaction.conditional_options = Some(options); @@ -76,101 +77,106 @@ where pub fn pool(&self) -> &Pool { &self.pool } +} - /// Validates the conditional inclusion options provided by the client. - /// - /// reference for the implementation - /// See also - pub fn validate_options(&self, options: &ConditionalOptions) -> RpcResult<()> { - let latest = self - .provider() - .block_by_id(BlockId::latest()) - .map_err(|e| { - ErrorObject::owned(ErrorCode::InternalError.code(), e.to_string(), Some("")) - })? - .ok_or(ErrorObjectOwned::from(ErrorCode::InternalError))?; - - self.validate_known_accounts(&options.known_accounts, latest.header.number.into())?; - - if let Some(min_block) = options.block_number_min { - if min_block > latest.number { - return Err(ErrorCode::from(-32003).into()); - } +/// Validates the conditional inclusion options provided by the client. +/// +/// reference for the implementation +/// See also +pub fn validate_conditional_options( + options: &ConditionalOptions, + provider: &Client, +) -> RpcResult<()> +where + Client: BlockReaderIdExt + StateProviderFactory, +{ + let latest = provider + .block_by_id(BlockId::latest()) + .map_err(|e| ErrorObject::owned(ErrorCode::InternalError.code(), e.to_string(), Some("")))? + .ok_or(ErrorObjectOwned::from(ErrorCode::InternalError))?; + + validate_known_accounts( + &options.known_accounts, + latest.header.number.into(), + provider, + )?; + + if let Some(min_block) = options.block_number_min { + if min_block > latest.number { + return Err(ErrorCode::from(-32003).into()); } + } - if let Some(max_block) = options.block_number_max { - if max_block <= latest.number { - return Err(ErrorCode::from(-32003).into()); - } + if let Some(max_block) = options.block_number_max { + if max_block <= latest.number { + return Err(ErrorCode::from(-32003).into()); } + } - if let Some(min_timestamp) = options.timestamp_min { - if min_timestamp > latest.timestamp { - return Err(ErrorCode::from(-32003).into()); - } + if let Some(min_timestamp) = options.timestamp_min { + if min_timestamp > latest.timestamp { + return Err(ErrorCode::from(-32003).into()); } + } - if let Some(max_timestamp) = options.timestamp_max { - if max_timestamp <= latest.timestamp { - return Err(ErrorCode::from(-32003).into()); - } + if let Some(max_timestamp) = options.timestamp_max { + if max_timestamp <= latest.timestamp { + return Err(ErrorCode::from(-32003).into()); } - - Ok(()) } - /// Validates the account storage slots/storage root provided by the client - /// - /// Matches the current state of the account storage slots/storage root. - pub fn validate_known_accounts( - &self, - known_accounts: &HashMap>, - latest: BlockId, - ) -> RpcResult<()> { - let state = self.provider().state_by_block_id(latest).map_err(|e| { - ErrorObject::owned(ErrorCode::InternalError.code(), e.to_string(), Some("")) - })?; - - for (address, storage) in known_accounts.iter() { - match storage { - AccountStorage::Slots(slots) => { - for (slot, value) in slots.iter() { - let current = - state - .storage(*address, StorageKey::from(*slot)) - .map_err(|e| { - ErrorObject::owned( - ErrorCode::InternalError.code(), - e.to_string(), - Some(""), - ) - })?; - if let Some(current) = current { - if FixedBytes::<32>::from_slice(¤t.to_be_bytes::<32>()) != *value - { - return Err(ErrorCode::from(-32003).into()); - } - } else { + Ok(()) +} + +/// Validates the account storage slots/storage root provided by the client +/// +/// Matches the current state of the account storage slots/storage root. +pub fn validate_known_accounts( + known_accounts: &HashMap>, + latest: BlockId, + provider: &Client, +) -> RpcResult<()> +where + Client: BlockReaderIdExt + StateProviderFactory, +{ + let state = provider.state_by_block_id(latest).map_err(|e| { + ErrorObject::owned(ErrorCode::InternalError.code(), e.to_string(), Some("")) + })?; + + for (address, storage) in known_accounts.iter() { + match storage { + AccountStorage::Slots(slots) => { + for (slot, value) in slots.iter() { + let current = + state + .storage(*address, StorageKey::from(*slot)) + .map_err(|e| { + ErrorObject::owned( + ErrorCode::InternalError.code(), + e.to_string(), + Some(""), + ) + })?; + if let Some(current) = current { + if FixedBytes::<32>::from_slice(¤t.to_be_bytes::<32>()) != *value { return Err(ErrorCode::from(-32003).into()); } - } - } - AccountStorage::RootHash(expected) => { - let root = state - .storage_root(*address, Default::default()) - .map_err(|e| { - ErrorObject::owned( - ErrorCode::InternalError.code(), - e.to_string(), - Some(""), - ) - })?; - if *expected != root { + } else { return Err(ErrorCode::from(-32003).into()); } } } + AccountStorage::RootHash(expected) => { + let root = state + .storage_root(*address, Default::default()) + .map_err(|e| { + ErrorObject::owned(ErrorCode::InternalError.code(), e.to_string(), Some("")) + })?; + if *expected != root { + return Err(ErrorCode::from(-32003).into()); + } + } } - Ok(()) } + Ok(()) } From bdf098f7abde4031677987aa74bffa0b6298a799 Mon Sep 17 00:00:00 2001 From: 0xKitsune <0xkitsune@protonmail.com> Date: Wed, 11 Dec 2024 14:15:58 -0500 Subject: [PATCH 12/59] mark pooled tx invalid if it fails conditional checks --- world-chain-builder/src/payload/builder.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/world-chain-builder/src/payload/builder.rs b/world-chain-builder/src/payload/builder.rs index a6e59eb2..e61f1519 100644 --- a/world-chain-builder/src/payload/builder.rs +++ b/world-chain-builder/src/payload/builder.rs @@ -33,7 +33,8 @@ use reth_optimism_payload_builder::error::OptimismPayloadBuilderError; use reth_primitives::{proofs, BlockBody}; use reth_primitives::{Block, Header, Receipt, TxType}; use reth_provider::{ - CanonStateSubscriptions, ChainSpecProvider, ExecutionOutcome, StateProviderFactory, + BlockReaderIdExt, CanonStateSubscriptions, ChainSpecProvider, ExecutionOutcome, + StateProviderFactory, }; use reth_trie::HashedPostState; use revm_primitives::calc_excess_blob_gas; @@ -73,7 +74,7 @@ where /// Implementation of the [`PayloadBuilder`] trait for [`WorldChainPayloadBuilder`]. impl PayloadBuilder for WorldChainPayloadBuilder where - Client: StateProviderFactory + ChainSpecProvider, + Client: StateProviderFactory + ChainSpecProvider + BlockReaderIdExt, Pool: TransactionPool, EvmConfig: ConfigureEvm
, { @@ -219,7 +220,7 @@ pub(crate) fn worldchain_payload( ) -> Result, PayloadBuilderError> where EvmConfig: ConfigureEvm
, - Client: StateProviderFactory + ChainSpecProvider, + Client: StateProviderFactory + ChainSpecProvider + BlockReaderIdExt, Pool: TransactionPool, { let BuildArguments { @@ -410,9 +411,8 @@ where let verified_gas_limit = (verified_blockspace_capacity as u64 * block_gas_limit) / 100; while let Some(pool_tx) = best_txs.next() { if let Some(conditional_options) = pool_tx.transaction.conditional_options() { - if let Err(_) = validate_conditional_options(conditional_options, provider) { - // best_txs.mark_invalid(&pool_tx); - + if let Err(_) = validate_conditional_options(conditional_options, &client) { + best_txs.mark_invalid(&pool_tx); continue; } } From 9a684c2b6d96f89f99a28f64c3dbd9dd17cf1cbe Mon Sep 17 00:00:00 2001 From: 0xKitsune <0xkitsune@protonmail.com> Date: Wed, 11 Dec 2024 14:24:16 -0500 Subject: [PATCH 13/59] remove any txs from the mempool that fail conditional options checks --- world-chain-builder/src/payload/builder.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/world-chain-builder/src/payload/builder.rs b/world-chain-builder/src/payload/builder.rs index e61f1519..d939488b 100644 --- a/world-chain-builder/src/payload/builder.rs +++ b/world-chain-builder/src/payload/builder.rs @@ -408,11 +408,13 @@ where } if !attributes.no_tx_pool { + let mut invalid_txs = vec![]; let verified_gas_limit = (verified_blockspace_capacity as u64 * block_gas_limit) / 100; while let Some(pool_tx) = best_txs.next() { if let Some(conditional_options) = pool_tx.transaction.conditional_options() { if let Err(_) = validate_conditional_options(conditional_options, &client) { best_txs.mark_invalid(&pool_tx); + invalid_txs.push(pool_tx.hash().clone()); continue; } } @@ -512,6 +514,10 @@ where executed_senders.push(tx.signer()); executed_txs.push(tx.into_signed()); } + + if !invalid_txs.is_empty() { + pool.remove_transactions(invalid_txs); + } } // check if we have a better block From d4b34194990d194a3d3068dcd64186ac47c28ce2 Mon Sep 17 00:00:00 2001 From: 0xKitsune <0xkitsune@protonmail.com> Date: Wed, 11 Dec 2024 14:35:31 -0500 Subject: [PATCH 14/59] evaluate conditional checks on BlockId::pending() --- world-chain-builder/src/rpc/bundle.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/world-chain-builder/src/rpc/bundle.rs b/world-chain-builder/src/rpc/bundle.rs index d2bdf596..14e8331b 100644 --- a/world-chain-builder/src/rpc/bundle.rs +++ b/world-chain-builder/src/rpc/bundle.rs @@ -91,7 +91,7 @@ where Client: BlockReaderIdExt + StateProviderFactory, { let latest = provider - .block_by_id(BlockId::latest()) + .block_by_id(BlockId::pending()) .map_err(|e| ErrorObject::owned(ErrorCode::InternalError.code(), e.to_string(), Some("")))? .ok_or(ErrorObjectOwned::from(ErrorCode::InternalError))?; @@ -108,7 +108,7 @@ where } if let Some(max_block) = options.block_number_max { - if max_block <= latest.number { + if max_block < latest.number { return Err(ErrorCode::from(-32003).into()); } } @@ -120,7 +120,7 @@ where } if let Some(max_timestamp) = options.timestamp_max { - if max_timestamp <= latest.timestamp { + if max_timestamp < latest.timestamp { return Err(ErrorCode::from(-32003).into()); } } From 7efba8eb9d7742274071d9c23faf3ea3f48ce761 Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Thu, 12 Dec 2024 13:12:24 -0700 Subject: [PATCH 15/59] bump reth in toml --- world-chain-builder/Cargo.lock | 3313 ++++++++++++++++++-------------- world-chain-builder/Cargo.toml | 82 +- 2 files changed, 1947 insertions(+), 1448 deletions(-) diff --git a/world-chain-builder/Cargo.lock b/world-chain-builder/Cargo.lock index bc871846..6edaffdd 100644 --- a/world-chain-builder/Cargo.lock +++ b/world-chain-builder/Cargo.lock @@ -108,16 +108,17 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.18" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy-chains" -version = "0.1.36" +version = "0.1.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94c225801d42099570d0674701dddd4142f0ef715282aeb5985042e2ec962df7" +checksum = "a0161082e0edd9013d23083465cc04b20e44b7a15646d36ba7b0cdb7cd6fe18f" dependencies = [ + "alloy-primitives", "alloy-rlp", "arbitrary", "num_enum 0.7.3", @@ -152,7 +153,7 @@ dependencies = [ "alloy-serde 0.4.2", "auto_impl", "c-kzg", - "derive_more 1.0.0", + "derive_more", "serde", ] @@ -166,26 +167,58 @@ dependencies = [ "alloy-primitives", "alloy-rlp", "alloy-serde 0.5.4", + "auto_impl", + "c-kzg", + "derive_more", + "serde", +] + +[[package]] +name = "alloy-consensus" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a101d4d016f47f13890a74290fdd17b05dd175191d9337bc600791fb96e4dea8" +dependencies = [ + "alloy-eips 0.7.3", + "alloy-primitives", + "alloy-rlp", + "alloy-serde 0.7.3", + "alloy-trie", "arbitrary", "auto_impl", "c-kzg", - "derive_more 1.0.0", + "derive_more", + "rand", "serde", "serde_with", ] +[[package]] +name = "alloy-consensus-any" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa60357dda9a3d0f738f18844bd6d0f4a5924cc5cf00bfad2ff1369897966123" +dependencies = [ + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", + "alloy-primitives", + "alloy-rlp", + "alloy-serde 0.7.3", + "serde", +] + [[package]] name = "alloy-dyn-abi" -version = "0.8.6" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1109c57718022ac84c194f775977a534e1b3969b405e55693a61c42187cc0612" +checksum = "41056bde53ae10ffbbf11618efbe1e0290859e5eab0fe9ef82ebdb62f12a866f" dependencies = [ "alloy-json-abi", "alloy-primitives", "alloy-sol-type-parser", "alloy-sol-types", "const-hex", - "derive_more 1.0.0", + "derive_more", "itoa", "serde", "serde_json", @@ -222,11 +255,23 @@ name = "alloy-eip7702" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64ffc577390ce50234e02d841214b3dc0bea6aaaae8e04bbf3cb82e9a45da9eb" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "derive_more", + "serde", +] + +[[package]] +name = "alloy-eip7702" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c986539255fb839d1533c128e190e557e52ff652c9ef62939e233a81dd93f7e" dependencies = [ "alloy-primitives", "alloy-rlp", "arbitrary", - "derive_more 1.0.0", + "derive_more", "k256", "rand", "serde", @@ -245,7 +290,7 @@ dependencies = [ "alloy-rlp", "alloy-serde 0.3.6", "c-kzg", - "derive_more 1.0.0", + "derive_more", "once_cell", "serde", "sha2 0.10.8", @@ -263,7 +308,7 @@ dependencies = [ "alloy-rlp", "alloy-serde 0.4.2", "c-kzg", - "derive_more 1.0.0", + "derive_more", "once_cell", "serde", "sha2 0.10.8", @@ -280,9 +325,27 @@ dependencies = [ "alloy-primitives", "alloy-rlp", "alloy-serde 0.5.4", + "c-kzg", + "derive_more", + "once_cell", + "serde", + "sha2 0.10.8", +] + +[[package]] +name = "alloy-eips" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6755b093afef5925f25079dd5a7c8d096398b804ba60cb5275397b06b31689" +dependencies = [ + "alloy-eip2930", + "alloy-eip7702 0.4.2", + "alloy-primitives", + "alloy-rlp", + "alloy-serde 0.7.3", "arbitrary", "c-kzg", - "derive_more 1.0.0", + "derive_more", "ethereum_ssz", "ethereum_ssz_derive", "once_cell", @@ -292,20 +355,21 @@ dependencies = [ [[package]] name = "alloy-genesis" -version = "0.5.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde15e14944a88bd6a57d325e9a49b75558746fe16aaccc79713ae50a6a9574c" +checksum = "aeec8e6eab6e52b7c9f918748c9b811e87dbef7312a2e3a2ca1729a92966a6af" dependencies = [ "alloy-primitives", - "alloy-serde 0.5.4", + "alloy-serde 0.7.3", + "alloy-trie", "serde", ] [[package]] name = "alloy-json-abi" -version = "0.8.6" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cc0e59c803dd44d14fc0cfa9fea1f74cfa8fd9fb60ca303ced390c58c28d4e" +checksum = "c357da577dfb56998d01f574d81ad7a1958d248740a7981b205d69d65a7da404" dependencies = [ "alloy-primitives", "alloy-sol-type-parser", @@ -323,7 +387,7 @@ dependencies = [ "alloy-sol-types", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tracing", ] @@ -337,7 +401,7 @@ dependencies = [ "alloy-sol-types", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tracing", ] @@ -351,7 +415,21 @@ dependencies = [ "alloy-sol-types", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", + "tracing", +] + +[[package]] +name = "alloy-json-rpc" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fa077efe0b834bcd89ff4ba547f48fb081e4fdc3673dd7da1b295a2cf2bb7b7" +dependencies = [ + "alloy-primitives", + "alloy-sol-types", + "serde", + "serde_json", + "thiserror 2.0.6", "tracing", ] @@ -373,7 +451,7 @@ dependencies = [ "async-trait", "auto_impl", "futures-utils-wasm", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -394,7 +472,7 @@ dependencies = [ "async-trait", "auto_impl", "futures-utils-wasm", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -415,7 +493,32 @@ dependencies = [ "async-trait", "auto_impl", "futures-utils-wasm", - "thiserror", + "thiserror 1.0.69", +] + +[[package]] +name = "alloy-network" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "209a1882a08e21aca4aac6e2a674dc6fcf614058ef8cb02947d63782b1899552" +dependencies = [ + "alloy-consensus 0.7.3", + "alloy-consensus-any", + "alloy-eips 0.7.3", + "alloy-json-rpc 0.7.3", + "alloy-network-primitives 0.7.3", + "alloy-primitives", + "alloy-rpc-types-any", + "alloy-rpc-types-eth 0.7.3", + "alloy-serde 0.7.3", + "alloy-signer 0.7.3", + "alloy-sol-types", + "async-trait", + "auto_impl", + "futures-utils-wasm", + "serde", + "serde_json", + "thiserror 2.0.6", ] [[package]] @@ -456,11 +559,24 @@ dependencies = [ "serde", ] +[[package]] +name = "alloy-network-primitives" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20219d1ad261da7a6331c16367214ee7ded41d001fabbbd656fbf71898b2773" +dependencies = [ + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", + "alloy-primitives", + "alloy-serde 0.7.3", + "serde", +] + [[package]] name = "alloy-primitives" -version = "0.8.10" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8edae627382349b56cd6a7a2106f4fd69b243a9233e560c55c2e03cabb7e1d3c" +checksum = "6259a506ab13e1d658796c31e6e39d2e2ee89243bcc505ddc613b35732e0a430" dependencies = [ "alloy-rlp", "arbitrary", @@ -468,12 +584,12 @@ dependencies = [ "cfg-if", "const-hex", "derive_arbitrary", - "derive_more 1.0.0", + "derive_more", "foldhash", "getrandom", - "hashbrown 0.15.0", + "hashbrown 0.15.2", "hex-literal", - "indexmap 2.6.0", + "indexmap 2.7.0", "itoa", "k256", "keccak-asm", @@ -482,7 +598,7 @@ dependencies = [ "proptest-derive", "rand", "ruint", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "serde", "sha3", "tiny-keccak", @@ -513,10 +629,10 @@ dependencies = [ "futures-utils-wasm", "lru", "pin-project", - "reqwest 0.12.8", + "reqwest 0.12.9", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", "url", @@ -524,22 +640,22 @@ dependencies = [ [[package]] name = "alloy-provider" -version = "0.5.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4814d141ede360bb6cd1b4b064f1aab9de391e7c4d0d4d50ac89ea4bc1e25fbd" +checksum = "9eefa6f4c798ad01f9b4202d02cea75f5ec11fa180502f4701e2b47965a8c0bb" dependencies = [ "alloy-chains", - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", - "alloy-json-rpc 0.5.4", - "alloy-network 0.5.4", - "alloy-network-primitives 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", + "alloy-json-rpc 0.7.3", + "alloy-network 0.7.3", + "alloy-network-primitives 0.7.3", "alloy-primitives", "alloy-pubsub", - "alloy-rpc-client 0.5.4", - "alloy-rpc-types-eth 0.5.4", - "alloy-transport 0.5.4", - "alloy-transport-http 0.5.4", + "alloy-rpc-client 0.7.3", + "alloy-rpc-types-eth 0.7.3", + "alloy-transport 0.7.3", + "alloy-transport-http 0.7.3", "alloy-transport-ws", "async-stream", "async-trait", @@ -550,11 +666,11 @@ dependencies = [ "lru", "parking_lot", "pin-project", - "reqwest 0.12.8", + "reqwest 0.12.9", "schnellru", "serde", "serde_json", - "thiserror", + "thiserror 2.0.6", "tokio", "tracing", "url", @@ -563,28 +679,28 @@ dependencies = [ [[package]] name = "alloy-pubsub" -version = "0.5.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ba46eb69ddf7a9925b81f15229cb74658e6eebe5dd30a5b74e2cd040380573" +checksum = "aac9a7210e0812b1d814118f426f57eb7fc260a419224dd1c76d169879c06907" dependencies = [ - "alloy-json-rpc 0.5.4", + "alloy-json-rpc 0.7.3", "alloy-primitives", - "alloy-transport 0.5.4", + "alloy-transport 0.7.3", "bimap", "futures", "serde", "serde_json", "tokio", "tokio-stream", - "tower 0.5.1", + "tower 0.5.2", "tracing", ] [[package]] name = "alloy-rlp" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26154390b1d205a4a7ac7352aa2eb4f81f391399d4e2f546fb81a2f8bb383f62" +checksum = "f542548a609dca89fcd72b3b9f355928cf844d4363c5eed9c5273a3dd225e097" dependencies = [ "alloy-rlp-derive", "arrayvec", @@ -593,13 +709,13 @@ dependencies = [ [[package]] name = "alloy-rlp-derive" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d0f2d905ebd295e7effec65e5f6868d153936130ae718352771de3e7d03c75c" +checksum = "5a833d97bf8a5f0f878daf2c8451fff7de7f9de38baa5a45d936ec718d81255a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -614,36 +730,36 @@ dependencies = [ "alloy-transport-http 0.4.2", "futures", "pin-project", - "reqwest 0.12.8", + "reqwest 0.12.9", "serde", "serde_json", "tokio", "tokio-stream", - "tower 0.5.1", + "tower 0.5.2", "tracing", "url", ] [[package]] name = "alloy-rpc-client" -version = "0.5.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc2bd1e7403463a5f2c61e955bcc9d3072b63aa177442b0f9aa6a6d22a941e3" +checksum = "ed30bf1041e84cabc5900f52978ca345dd9969f2194a945e6fdec25b0620705c" dependencies = [ - "alloy-json-rpc 0.5.4", + "alloy-json-rpc 0.7.3", "alloy-primitives", "alloy-pubsub", - "alloy-transport 0.5.4", - "alloy-transport-http 0.5.4", + "alloy-transport 0.7.3", + "alloy-transport-http 0.7.3", "alloy-transport-ws", "futures", "pin-project", - "reqwest 0.12.8", + "reqwest 0.12.9", "serde", "serde_json", "tokio", "tokio-stream", - "tower 0.5.1", + "tower 0.5.2", "tracing", "url", "wasmtimer", @@ -651,22 +767,22 @@ dependencies = [ [[package]] name = "alloy-rpc-types" -version = "0.5.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eea9bf1abdd506f985a53533f5ac01296bcd6102c5e139bbc5d40bc468d2c916" +checksum = "5ab686b0fa475d2a4f5916c5f07797734a691ec58e44f0f55d4746ea39cbcefb" dependencies = [ "alloy-primitives", "alloy-rpc-types-engine", - "alloy-rpc-types-eth 0.5.4", - "alloy-serde 0.5.4", + "alloy-rpc-types-eth 0.7.3", + "alloy-serde 0.7.3", "serde", ] [[package]] name = "alloy-rpc-types-admin" -version = "0.5.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea02c25541fb19eaac4278aa5c41d2d7e0245898887e54a74bfc0f3103e99415" +checksum = "1f0874a976ccdf83a178ad93b64bec5b8c91a47428d714d544ca70258acfa07b" dependencies = [ "alloy-genesis", "alloy-primitives", @@ -676,34 +792,47 @@ dependencies = [ [[package]] name = "alloy-rpc-types-anvil" -version = "0.5.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2382fc63fb0cf3e02818d547b80cb66cc49a31f8803d0c328402b2008bc13650" +checksum = "d33bc190844626c08e21897736dbd7956ab323c09e6f141b118d1c8b7aff689e" dependencies = [ "alloy-primitives", - "alloy-serde 0.5.4", + "alloy-rpc-types-eth 0.7.3", + "alloy-serde 0.7.3", "serde", ] +[[package]] +name = "alloy-rpc-types-any" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200661999b6e235d9840be5d60a6e8ae2f0af9eb2a256dd378786744660e36ec" +dependencies = [ + "alloy-consensus-any", + "alloy-rpc-types-eth 0.7.3", + "alloy-serde 0.7.3", +] + [[package]] name = "alloy-rpc-types-beacon" -version = "0.5.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45357a642081c8ce235c0ad990c4e9279f5f18a723545076b38cfcc05cc25234" +checksum = "cc37861dc8cbf5da35d346139fbe6e03ee7823cc21138a2c4a590d3b0b4b24be" dependencies = [ - "alloy-eips 0.5.4", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rpc-types-engine", + "alloy-serde 0.7.3", "serde", "serde_with", - "thiserror", + "thiserror 2.0.6", ] [[package]] name = "alloy-rpc-types-debug" -version = "0.5.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5afe3ab1038f90faf56304aa0adf1e6a8c9844615d8f83967f932f3a70390b1" +checksum = "f0294b553785eb3fa7fff2e8aec45e82817258e7e6c9365c034a90cb6baeebc9" dependencies = [ "alloy-primitives", "serde", @@ -711,16 +840,16 @@ dependencies = [ [[package]] name = "alloy-rpc-types-engine" -version = "0.5.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "886d22d41992287a235af2f3af4299b5ced2bcafb81eb835572ad35747476946" +checksum = "5d297268357e3eae834ddd6888b15f764cbc0f4b3be9265f5f6ec239013f3d68" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rlp", - "alloy-serde 0.5.4", - "derive_more 1.0.0", + "alloy-serde 0.7.3", + "derive_more", "ethereum_ssz", "ethereum_ssz_derive", "jsonrpsee-types", @@ -744,7 +873,7 @@ dependencies = [ "alloy-serde 0.3.6", "alloy-sol-types", "cfg-if", - "derive_more 1.0.0", + "derive_more", "hashbrown 0.14.5", "itertools 0.13.0", "serde", @@ -764,7 +893,7 @@ dependencies = [ "alloy-rlp", "alloy-serde 0.4.2", "alloy-sol-types", - "derive_more 1.0.0", + "derive_more", "itertools 0.13.0", "serde", "serde_json", @@ -783,8 +912,28 @@ dependencies = [ "alloy-rlp", "alloy-serde 0.5.4", "alloy-sol-types", + "derive_more", + "itertools 0.13.0", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-rpc-types-eth" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0600b8b5e2dc0cab12cbf91b5a885c35871789fb7b3a57b434bd4fced5b7a8b" +dependencies = [ + "alloy-consensus 0.7.3", + "alloy-consensus-any", + "alloy-eips 0.7.3", + "alloy-network-primitives 0.7.3", + "alloy-primitives", + "alloy-rlp", + "alloy-serde 0.7.3", + "alloy-sol-types", "arbitrary", - "derive_more 1.0.0", + "derive_more", "itertools 0.13.0", "jsonrpsee-types", "serde", @@ -793,40 +942,41 @@ dependencies = [ [[package]] name = "alloy-rpc-types-mev" -version = "0.5.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3246948dfa5f5060a9abe04233d741ea656ef076b12958f3242416ce9f375058" +checksum = "093d618d5a42808e7ae26062f415a1e816fc27d3d32662c6ed52d0871b154894" dependencies = [ - "alloy-eips 0.5.4", + "alloy-eips 0.7.3", "alloy-primitives", - "alloy-serde 0.5.4", + "alloy-rpc-types-eth 0.7.3", + "alloy-serde 0.7.3", "serde", "serde_json", ] [[package]] name = "alloy-rpc-types-trace" -version = "0.5.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e5fb6c5c401321f802f69dcdb95b932f30f8158f6798793f914baac5995628e" +checksum = "4e073ab0e67429c60be281e181731132fd07d82e091c10c29ace6935101034bb" dependencies = [ "alloy-primitives", - "alloy-rpc-types-eth 0.5.4", - "alloy-serde 0.5.4", + "alloy-rpc-types-eth 0.7.3", + "alloy-serde 0.7.3", "serde", "serde_json", - "thiserror", + "thiserror 2.0.6", ] [[package]] name = "alloy-rpc-types-txpool" -version = "0.5.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ad066b49c3b1b5f64cdd2399177a19926a6a15db2dbf11e2098de621f9e7480" +checksum = "7435f6bfb93912f16d64bb61f4278fa698469e054784f477337ef87ec0b2527b" dependencies = [ "alloy-primitives", - "alloy-rpc-types-eth 0.5.4", - "alloy-serde 0.5.4", + "alloy-rpc-types-eth 0.7.3", + "alloy-serde 0.7.3", "serde", ] @@ -857,6 +1007,17 @@ name = "alloy-serde" version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "028e72eaa9703e4882344983cfe7636ce06d8cce104a78ea62fd19b46659efc4" +dependencies = [ + "alloy-primitives", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-serde" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afa753a97002a33b2ccb707d9f15f31c81b8c1b786c95b73cc62bb1d1fd0c3f" dependencies = [ "alloy-primitives", "arbitrary", @@ -875,7 +1036,7 @@ dependencies = [ "auto_impl", "elliptic-curve", "k256", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -889,7 +1050,7 @@ dependencies = [ "auto_impl", "elliptic-curve", "k256", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -903,7 +1064,21 @@ dependencies = [ "auto_impl", "elliptic-curve", "k256", - "thiserror", + "thiserror 1.0.69", +] + +[[package]] +name = "alloy-signer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2cbff01a673936c2efd7e00d4c0e9a4dbbd6d600e2ce298078d33efbb19cd7" +dependencies = [ + "alloy-primitives", + "async-trait", + "auto_impl", + "elliptic-curve", + "k256", + "thiserror 2.0.6", ] [[package]] @@ -917,65 +1092,81 @@ dependencies = [ "alloy-primitives", "alloy-signer 0.5.4", "async-trait", + "k256", + "rand", + "thiserror 1.0.69", +] + +[[package]] +name = "alloy-signer-local" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6d988cb6cd7d2f428a74476515b1a6e901e08c796767f9f93311ab74005c8b" +dependencies = [ + "alloy-consensus 0.7.3", + "alloy-network 0.7.3", + "alloy-primitives", + "alloy-signer 0.7.3", + "async-trait", "coins-bip32", "coins-bip39", "k256", "rand", - "thiserror", + "thiserror 2.0.6", ] [[package]] name = "alloy-sol-macro" -version = "0.8.6" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0409e3ba5d1de409997a7db8b8e9d679d52088c1dee042a85033affd3cadeab4" +checksum = "d9d64f851d95619233f74b310f12bcf16e0cbc27ee3762b6115c14a84809280a" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] name = "alloy-sol-macro-expander" -version = "0.8.6" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18372ef450d59f74c7a64a738f546ba82c92f816597fed1802ef559304c81f1" +checksum = "6bf7ed1574b699f48bf17caab4e6e54c6d12bc3c006ab33d58b1e227c1c3559f" dependencies = [ "alloy-sol-macro-input", "const-hex", "heck 0.5.0", - "indexmap 2.6.0", + "indexmap 2.7.0", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", "syn-solidity", "tiny-keccak", ] [[package]] name = "alloy-sol-macro-input" -version = "0.8.6" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7bad89dd0d5f109e8feeaf787a9ed7a05a91a9a0efc6687d147a70ebca8eff7" +checksum = "8c02997ccef5f34f9c099277d4145f183b422938ed5322dc57a089fe9b9ad9ee" dependencies = [ "const-hex", "dunce", "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", "syn-solidity", ] [[package]] name = "alloy-sol-type-parser" -version = "0.8.6" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbd3548d5262867c2c4be6223fe4f2583e21ade0ca1c307fd23bc7f28fca479e" +checksum = "ce13ff37285b0870d0a0746992a4ae48efaf34b766ae4c2640fa15e5305f8e73" dependencies = [ "serde", "winnow 0.6.20", @@ -983,9 +1174,9 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "0.8.6" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4aa666f1036341b46625e72bd36878bf45ad0185f1b88601223e1ec6ed4b72b1" +checksum = "1174cafd6c6d810711b4e00383037bdb458efc4fe3dbafafa16567e0320c54d8" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -1006,28 +1197,28 @@ dependencies = [ "futures-utils-wasm", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", - "tower 0.5.1", + "tower 0.5.2", "tracing", "url", ] [[package]] name = "alloy-transport" -version = "0.5.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be77579633ebbc1266ae6fd7694f75c408beb1aeb6865d0b18f22893c265a061" +checksum = "d69d36982b9e46075ae6b792b0f84208c6c2c15ad49f6c500304616ef67b70e0" dependencies = [ - "alloy-json-rpc 0.5.4", + "alloy-json-rpc 0.7.3", "base64 0.22.1", "futures-util", "futures-utils-wasm", "serde", "serde_json", - "thiserror", + "thiserror 2.0.6", "tokio", - "tower 0.5.1", + "tower 0.5.2", "tracing", "url", "wasmtimer", @@ -1041,38 +1232,38 @@ checksum = "b367dcccada5b28987c2296717ee04b9a5637aacd78eacb1726ef211678b5212" dependencies = [ "alloy-json-rpc 0.4.2", "alloy-transport 0.4.2", - "reqwest 0.12.8", + "reqwest 0.12.9", "serde_json", - "tower 0.5.1", + "tower 0.5.2", "tracing", "url", ] [[package]] name = "alloy-transport-http" -version = "0.5.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fd1a5d0827939847983b46f2f79510361f901dc82f8e3c38ac7397af142c6e" +checksum = "2e02ffd5d93ffc51d72786e607c97de3b60736ca3e636ead0ec1f7dce68ea3fd" dependencies = [ - "alloy-json-rpc 0.5.4", - "alloy-transport 0.5.4", - "reqwest 0.12.8", + "alloy-json-rpc 0.7.3", + "alloy-transport 0.7.3", + "reqwest 0.12.9", "serde_json", - "tower 0.5.1", + "tower 0.5.2", "tracing", "url", ] [[package]] name = "alloy-transport-ws" -version = "0.5.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61f27837bb4a1d6c83a28231c94493e814882f0e9058648a97e908a5f3fc9fcf" +checksum = "9c085c4e1e7680b723ffc558f61a22c061ed3f70eb3436f93f3936779c59cec1" dependencies = [ "alloy-pubsub", - "alloy-transport 0.5.4", + "alloy-transport 0.7.3", "futures", - "http 1.1.0", + "http 1.2.0", "rustls", "serde_json", "tokio", @@ -1083,16 +1274,16 @@ dependencies = [ [[package]] name = "alloy-trie" -version = "0.7.2" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdd7f8b3a7c65ca09b3c7bdd7c7d72d7423d026f5247eda96af53d24e58315c1" +checksum = "3a5fd8fea044cc9a8c8a50bb6f28e31f0385d820f116c5b98f6f4e55d6e5590b" dependencies = [ "alloy-primitives", "alloy-rlp", "arbitrary", "arrayvec", "derive_arbitrary", - "derive_more 1.0.0", + "derive_more", "nybbles", "proptest", "proptest-derive", @@ -1124,9 +1315,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -1139,36 +1330,36 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1179,9 +1370,9 @@ checksum = "70033777eb8b5124a81a1889416543dddef2de240019b674c81285a2635a7e1e" [[package]] name = "anyhow" -version = "1.0.89" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" [[package]] name = "aquamarine" @@ -1194,14 +1385,14 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] name = "arbitrary" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" dependencies = [ "derive_arbitrary", ] @@ -1241,7 +1432,7 @@ dependencies = [ "num", "num-bigint", "num-traits", - "thiserror", + "thiserror 1.0.69", "wasmer", "wasmer-wasix", ] @@ -1523,21 +1714,21 @@ dependencies = [ "alloy-provider 0.4.2", "alloy-rpc-types-eth 0.4.2", "alloy-transport 0.4.2", - "clap 4.5.19", + "clap 4.5.23", "color-eyre", "futures", "serde", "serde_json", "tokio", "tracing", - "tracing-subscriber 0.3.18", + "tracing-subscriber 0.3.19", ] [[package]] name = "async-compression" -version = "0.4.13" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e614738943d3f68c628ae3dbce7c3daffb196665f82f8c8ea6b65de73c79429" +checksum = "df895a515f70646414f4b45c0b79082783b80552b373a68283012928df56f522" dependencies = [ "brotli", "flate2", @@ -1549,6 +1740,17 @@ dependencies = [ "zstd-safe", ] +[[package]] +name = "async-recursion" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "async-stream" version = "0.3.6" @@ -1568,7 +1770,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -1579,7 +1781,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -1637,7 +1839,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -1648,9 +1850,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backon" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4fa97bb310c33c811334143cf64c5bb2b7b3c06e453db6b095d7061eff8f113" +checksum = "ba5289ec98f68f28dd809fd601059e6aa908bb8f6108620930828283d4ee23d7" dependencies = [ "fastrand", "tokio", @@ -1743,7 +1945,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -1801,9 +2003,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.5.4" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82033247fd8e890df8f740e407ad4d038debb9eb1f40533fffb32e7d17dc6f7" +checksum = "b8ee0c1824c4dea5b5f81736aff91bae041d2c07ee1192bec91054e10e3e601e" dependencies = [ "arrayref", "arrayvec", @@ -1860,9 +2062,9 @@ dependencies = [ "bitflags 2.6.0", "boa_interner", "boa_macros", - "indexmap 2.6.0", + "indexmap 2.7.0", "num-bigint", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", ] [[package]] @@ -1886,7 +2088,7 @@ dependencies = [ "fast-float", "hashbrown 0.14.5", "icu_normalizer", - "indexmap 2.6.0", + "indexmap 2.7.0", "intrusive-collections", "itertools 0.13.0", "num-bigint", @@ -1898,7 +2100,7 @@ dependencies = [ "portable-atomic", "rand", "regress", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "ryu-js", "serde", "serde_json", @@ -1906,7 +2108,7 @@ dependencies = [ "static_assertions", "tap", "thin-vec", - "thiserror", + "thiserror 1.0.69", "time", ] @@ -1932,10 +2134,10 @@ dependencies = [ "boa_gc", "boa_macros", "hashbrown 0.14.5", - "indexmap 2.6.0", + "indexmap 2.7.0", "once_cell", "phf", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "static_assertions", ] @@ -1947,7 +2149,7 @@ checksum = "240f4126219a83519bad05c9a40bfc0303921eeb571fc2d7e44c17ffac99d3f1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", "synstructure", ] @@ -1967,7 +2169,7 @@ dependencies = [ "num-bigint", "num-traits", "regress", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", ] [[package]] @@ -1984,7 +2186,7 @@ checksum = "ae85205289bab1f2c7c8a30ddf0541cf89ba2ff7dbd144feef50bbfa664288d4" dependencies = [ "fast-float", "paste", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "sptr", "static_assertions", ] @@ -2031,12 +2233,12 @@ dependencies = [ [[package]] name = "bstr" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" +checksum = "786a307d683a5bf92e6fd5fd69a7eb613751668d1d8d67d802846dfe367c62c8" dependencies = [ "memchr", - "regex-automata 0.4.8", + "regex-automata 0.4.9", "serde", ] @@ -2076,22 +2278,22 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.18.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc8b54b395f2fcfbb3d90c47b01c7f444d94d05bdeb775811dec868ac3bbc26" +checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -2102,9 +2304,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" dependencies = [ "serde", ] @@ -2144,9 +2346,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" dependencies = [ "serde", ] @@ -2162,7 +2364,7 @@ dependencies = [ "semver 1.0.23", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2188,9 +2390,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.28" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e80e3b6a3ab07840e1cae9b0666a63970dc28e8ed5ffbcdacbfc760c281bfc1" +checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d" dependencies = [ "jobserver", "libc", @@ -2218,11 +2420,17 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", @@ -2289,14 +2497,14 @@ checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "bitflags 1.3.2", "textwrap", - "unicode-width", + "unicode-width 0.1.14", ] [[package]] name = "clap" -version = "4.5.19" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" +checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" dependencies = [ "clap_builder", "clap_derive", @@ -2304,9 +2512,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.19" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" +checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" dependencies = [ "anstream", "anstyle", @@ -2323,14 +2531,14 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "cobs" @@ -2345,7 +2553,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" dependencies = [ "termcolor", - "unicode-width", + "unicode-width 0.1.14", ] [[package]] @@ -2361,7 +2569,7 @@ dependencies = [ "k256", "serde", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2377,7 +2585,7 @@ dependencies = [ "pbkdf2", "rand", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2396,7 +2604,7 @@ dependencies = [ "serde", "sha2 0.10.8", "sha3", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2428,9 +2636,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "combine" @@ -2444,14 +2652,14 @@ dependencies = [ [[package]] name = "comfy-table" -version = "7.1.1" +version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b34115915337defe99b2aff5c2ce6771e5fbc4079f4b506301f5cf394c8452f7" +checksum = "24f165e7b643266ea80cb858aed492ad9280e3e05ce24d4a99d7d7b889b6a4d9" dependencies = [ - "crossterm 0.27.0", + "crossterm", "strum", "strum_macros", - "unicode-width", + "unicode-width 0.2.0", ] [[package]] @@ -2491,9 +2699,9 @@ dependencies = [ [[package]] name = "const-hex" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0121754e84117e65f9d90648ee6aa4882a6e63110307ab73967a4c5e7e69e586" +checksum = "4b0485bab839b018a8f1723fc5391819fea5f8f0f32288ef8a735fd096b6160c" dependencies = [ "cfg-if", "cpufeatures", @@ -2510,9 +2718,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const_format" -version = "0.2.33" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c655d81ff1114fb0dcdea9225ea9f0cc712a6f8d189378e82bdf62a473a64b" +checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" dependencies = [ "const_format_proc_macros", "konst", @@ -2520,9 +2728,9 @@ dependencies = [ [[package]] name = "const_format_proc_macros" -version = "0.2.33" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff1a44b93f47b1bac19a27932f5c591e43d1ba357ee4f61526c8a25603f0eb1" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" dependencies = [ "proc-macro2", "quote", @@ -2560,6 +2768,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -2590,9 +2808,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] @@ -2739,7 +2957,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.5.19", + "clap 4.5.23", "criterion-plot 0.5.0", "futures", "is-terminal", @@ -2780,9 +2998,9 @@ dependencies = [ [[package]] name = "critical-section" -version = "1.1.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f64009896348fc5af4222e9cf7d7d82a95a256c634ebcf61c53e4ea461422242" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] name = "crossbeam-channel" @@ -2829,26 +3047,13 @@ checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crossterm" -version = "0.27.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ "bitflags 2.6.0", "crossterm_winapi", - "libc", - "parking_lot", - "winapi", -] - -[[package]] -name = "crossterm" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" -dependencies = [ - "bitflags 2.6.0", - "crossterm_winapi", - "mio 1.0.2", + "mio 1.0.3", "parking_lot", "rustix", "signal-hook", @@ -2906,9 +3111,9 @@ dependencies = [ [[package]] name = "csv" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf" dependencies = [ "csv-core", "itoa", @@ -2958,51 +3163,66 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] name = "cxx" -version = "1.0.128" +version = "1.0.134" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54ccead7d199d584d139148b04b4a368d1ec7556a1d9ea2548febb1b9d49f9a4" +checksum = "a5a32d755fe20281b46118ee4b507233311fb7a48a0cfd42f554b93640521a2f" dependencies = [ "cc", + "cxxbridge-cmd", "cxxbridge-flags", "cxxbridge-macro", + "foldhash", "link-cplusplus", ] [[package]] name = "cxx-build" -version = "1.0.128" +version = "1.0.134" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77953e99f01508f89f55c494bfa867171ef3a6c8cea03d26975368f2121a5c1" +checksum = "11645536ada5d1c8804312cbffc9ab950f2216154de431de930da47ca6955199" dependencies = [ "cc", "codespan-reporting", - "once_cell", "proc-macro2", "quote", "scratch", - "syn 2.0.79", + "syn 2.0.90", +] + +[[package]] +name = "cxxbridge-cmd" +version = "1.0.134" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcc9c78e3c7289665aab921a2b394eaffe8bdb369aa18d81ffc0f534fd49385" +dependencies = [ + "clap 4.5.23", + "codespan-reporting", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] name = "cxxbridge-flags" -version = "1.0.128" +version = "1.0.134" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65777e06cc48f0cb0152024c77d6cf9e4bdb4408e7b48bea993d42fa0f5b02b6" +checksum = "3a22a87bd9e78d7204d793261470a4c9d585154fddd251828d8aefbb5f74c3bf" [[package]] name = "cxxbridge-macro" -version = "1.0.128" +version = "1.0.134" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98532a60dedaebc4848cb2cba5023337cc9ea3af16a5b062633fabfd9f18fb60" +checksum = "1dfdb020ff8787c5daf6e0dca743005cc8782868faeadfbabb8824ede5cb1c72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "rustversion", + "syn 2.0.90", ] [[package]] @@ -3050,7 +3270,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -3072,7 +3292,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core 0.20.10", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -3100,7 +3320,6 @@ dependencies = [ "lock_api", "once_cell", "parking_lot_core", - "serde", ] [[package]] @@ -3185,18 +3404,18 @@ checksum = "62d671cc41a825ebabc75757b62d3d168c577f9149b2d49ece1dad1f72119d25" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] name = "derive_arbitrary" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -3230,17 +3449,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derive_more" -version = "0.99.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.79", -] - [[package]] name = "derive_more" version = "1.0.0" @@ -3259,7 +3467,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", "unicode-xid", ] @@ -3358,7 +3566,7 @@ dependencies = [ "parking_lot", "rand", "smallvec", - "socket2 0.5.7", + "socket2 0.5.8", "tokio", "tracing", "uint 0.10.0", @@ -3373,7 +3581,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -3493,9 +3701,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.34" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] @@ -3529,7 +3737,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -3560,7 +3768,7 @@ checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -3581,7 +3789,7 @@ dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -3592,12 +3800,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3613,7 +3821,7 @@ dependencies = [ "serde", "serde_json", "sha3", - "thiserror", + "thiserror 1.0.69", "uint 0.9.5", ] @@ -3663,12 +3871,11 @@ dependencies = [ [[package]] name = "ethereum_ssz" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfbba28f4f3f32d92c06a64f5bf6c4537b5d4e21f28c689bd2bbaecfea4e0d3e" +checksum = "036c84bd29bff35e29bbee3c8fc0e2fb95db12b6f2f3cae82a827fbc97256f3a" dependencies = [ "alloy-primitives", - "derivative", "ethereum_serde_utils", "itertools 0.13.0", "serde", @@ -3679,14 +3886,14 @@ dependencies = [ [[package]] name = "ethereum_ssz_derive" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d37845ba7c16bf4be8be4b5786f03a2ba5f2fda0d7f9e7cb2282f69cff420d7" +checksum = "9dc8e67e1f770f5aa4c2c2069aaaf9daee7ac21bed357a71b911b37a58966cfb" dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -3711,7 +3918,7 @@ dependencies = [ "serde_json", "strum", "tempfile", - "thiserror", + "thiserror 1.0.69", "tiny-keccak", "unicode-xid", ] @@ -3737,7 +3944,7 @@ dependencies = [ "serde_json", "strum", "tempfile", - "thiserror", + "thiserror 1.0.69", "tiny-keccak", "unicode-xid", ] @@ -3766,9 +3973,9 @@ checksum = "95765f67b4b18863968b4a1bd5bb576f732b29a4a28c7cd84c09fa3e2875f33c" [[package]] name = "fastrand" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fastrlp" @@ -3788,7 +3995,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e182f7dbc2ef73d9ef67351c5fbbea084729c48362d3ce9dd44c28e32e277fe5" dependencies = [ "libc", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3858,14 +4065,14 @@ checksum = "7693d9dd1ec1c54f52195dfe255b627f7cec7da33b679cd56de949e662b3db10" dependencies = [ "flame", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] name = "flate2" -version = "1.0.34" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", "miniz_oxide 0.8.0", @@ -3984,7 +4191,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -4109,7 +4316,7 @@ dependencies = [ "aho-corasick", "bstr", "log", - "regex-automata 0.4.8", + "regex-automata 0.4.9", "regex-syntax 0.8.5", ] @@ -4123,12 +4330,12 @@ dependencies = [ "futures-core", "futures-sink", "gloo-utils", - "http 1.1.0", + "http 1.2.0", "js-sys", "pin-project", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -4182,7 +4389,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.6.0", + "indexmap 2.7.0", "slab", "tokio", "tokio-util", @@ -4191,17 +4398,17 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" dependencies = [ "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "http 1.1.0", - "indexmap 2.6.0", + "http 1.2.0", + "indexmap 2.7.0", "slab", "tokio", "tokio-util", @@ -4270,9 +4477,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ "allocator-api2", "equivalent", @@ -4371,6 +4578,54 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" +[[package]] +name = "hickory-proto" +version = "0.25.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d063c0692ee669aa6d261988aa19ca5510f1cc40e4f211024f50c888499a35d7" +dependencies = [ + "async-recursion", + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna", + "ipnet", + "once_cell", + "rand", + "serde", + "thiserror 2.0.6", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "hickory-resolver" +version = "0.25.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42bc352e4412fb657e795f79b4efcf2bd60b59ee5ca0187f3554194cd1107a27" +dependencies = [ + "cfg-if", + "futures-util", + "hickory-proto", + "ipconfig", + "moka", + "once_cell", + "parking_lot", + "rand", + "resolv-conf", + "serde", + "smallvec", + "thiserror 2.0.6", + "tokio", + "tracing", +] + [[package]] name = "hkdf" version = "0.12.4" @@ -4434,9 +4689,9 @@ dependencies = [ [[package]] name = "http" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" dependencies = [ "bytes", "fnv", @@ -4461,7 +4716,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.1.0", + "http 1.2.0", ] [[package]] @@ -4472,16 +4727,16 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", "pin-project-lite", ] [[package]] name = "http-range-header" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08a397c49fec283e3d6211adbe480be95aae5f304cfb923e9970e08956d5168a" +checksum = "9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c" [[package]] name = "httparse" @@ -4519,9 +4774,9 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.30" +version = "0.14.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" dependencies = [ "bytes", "futures-channel", @@ -4534,7 +4789,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.7", + "socket2 0.5.8", "tokio", "tower-service", "tracing", @@ -4543,15 +4798,15 @@ dependencies = [ [[package]] name = "hyper" -version = "1.4.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.6", - "http 1.1.0", + "h2 0.4.7", + "http 1.2.0", "http-body 1.0.1", "httparse", "httpdate", @@ -4569,12 +4824,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", - "http 1.1.0", - "hyper 1.4.1", + "http 1.2.0", + "hyper 1.5.1", "hyper-util", "log", "rustls", - "rustls-native-certs 0.8.0", + "rustls-native-certs 0.8.1", "rustls-pki-types", "tokio", "tokio-rustls", @@ -4589,7 +4844,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper 0.14.30", + "hyper 0.14.31", "native-tls", "tokio", "tokio-native-tls", @@ -4603,7 +4858,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.4.1", + "hyper 1.5.1", "hyper-util", "native-tls", "tokio", @@ -4613,18 +4868,18 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", - "hyper 1.4.1", + "hyper 1.5.1", "pin-project-lite", - "socket2 0.5.7", + "socket2 0.5.8", "tokio", "tower-service", "tracing", @@ -4768,7 +5023,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -4785,22 +5040,23 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.4.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", ] [[package]] -name = "idna" -version = "0.5.0" +name = "idna_adapter" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "icu_normalizer", + "icu_properties", ] [[package]] @@ -4823,7 +5079,7 @@ dependencies = [ "globset", "log", "memchr", - "regex-automata 0.4.8", + "regex-automata 0.4.9", "same-file", "walkdir", "winapi-util", @@ -4858,13 +5114,13 @@ dependencies = [ [[package]] name = "impl-trait-for-tuples" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.90", ] [[package]] @@ -4905,16 +5161,22 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "arbitrary", "equivalent", - "hashbrown 0.15.0", + "hashbrown 0.15.2", "serde", ] +[[package]] +name = "indoc" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" + [[package]] name = "inotify" version = "0.9.6" @@ -4947,19 +5209,23 @@ dependencies = [ [[package]] name = "instability" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b23a0c8dfe501baac4adf6ebbfa6eddf8f0c07f56b058cc1288017e32397846c" +checksum = "b829f37dead9dc39df40c2d3376c179fdfd2ac771f53f55d3c30dc096a3c0c6e" dependencies = [ + "darling 0.20.10", + "indoc", + "pretty_assertions", + "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] name = "interprocess" -version = "2.2.1" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f4e4a06d42fab3e85ab1b419ad32b09eab58b901d40c57935ff92db3287a13" +checksum = "894148491d817cb36b6f778017b8ac46b17408d522dd90f539d677ea938362eb" dependencies = [ "doctest-file", "futures-core", @@ -4985,7 +5251,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2 0.5.7", + "socket2 0.5.8", "widestring", "windows-sys 0.48.0", "winreg", @@ -4999,9 +5265,9 @@ checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" [[package]] name = "iri-string" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44bd7eced44cfe2cebc674adb2a7124a754a4b5269288d22e9f39f8fada3562d" +checksum = "dc0f0a572e8ffe56e2ff4f769f32ffe919282c3916799f8b68688b6030063bea" dependencies = [ "memchr", "serde", @@ -5044,9 +5310,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jni" @@ -5058,7 +5324,7 @@ dependencies = [ "combine", "jni-sys", "log", - "thiserror", + "thiserror 1.0.69", "walkdir", ] @@ -5079,18 +5345,19 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ + "once_cell", "wasm-bindgen", ] [[package]] name = "jsonrpsee" -version = "0.24.5" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126b48a5acc3c52fbd5381a77898cb60e145123179588a29e7ac48f9c06e401b" +checksum = "c5c71d8c1a731cc4227c2f698d377e7848ca12c8a48866fc5e6951c43a4db843" dependencies = [ "jsonrpsee-client-transport", "jsonrpsee-core", @@ -5106,22 +5373,22 @@ dependencies = [ [[package]] name = "jsonrpsee-client-transport" -version = "0.24.5" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf679a8e0e083c77997f7c4bb4ca826577105906027ae462aac70ff348d02c6a" +checksum = "548125b159ba1314104f5bb5f38519e03a41862786aa3925cf349aae9cdd546e" dependencies = [ "base64 0.22.1", "futures-channel", "futures-util", "gloo-net", - "http 1.1.0", + "http 1.2.0", "jsonrpsee-core", "pin-project", "rustls", "rustls-pki-types", "rustls-platform-verifier", "soketto", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-rustls", "tokio-util", @@ -5131,25 +5398,25 @@ dependencies = [ [[package]] name = "jsonrpsee-core" -version = "0.24.5" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0e503369a76e195b65af35058add0e6900b794a4e9a9316900ddd3a87a80477" +checksum = "f2882f6f8acb9fdaec7cefc4fd607119a9bd709831df7d7672a1d3b644628280" dependencies = [ "async-trait", "bytes", "futures-timer", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", "http-body-util", "jsonrpsee-types", "parking_lot", "pin-project", "rand", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tracing", @@ -5158,14 +5425,14 @@ dependencies = [ [[package]] name = "jsonrpsee-http-client" -version = "0.24.5" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2c0caba4a6a8efbafeec9baa986aa22a75a96c29d3e4b0091b0098d6470efb5" +checksum = "b3638bc4617f96675973253b3a45006933bde93c2fd8a6170b33c777cc389e5b" dependencies = [ "async-trait", "base64 0.22.1", "http-body 1.0.1", - "hyper 1.4.1", + "hyper 1.5.1", "hyper-rustls", "hyper-util", "jsonrpsee-core", @@ -5174,7 +5441,7 @@ dependencies = [ "rustls-platform-verifier", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tower 0.4.13", "tracing", @@ -5183,28 +5450,28 @@ dependencies = [ [[package]] name = "jsonrpsee-proc-macros" -version = "0.24.5" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc660a9389e2748e794a40673a4155d501f32db667757cdb80edeff0306b489b" +checksum = "c06c01ae0007548e73412c08e2285ffe5d723195bf268bce67b1b77c3bb2a14d" dependencies = [ "heck 0.5.0", "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] name = "jsonrpsee-server" -version = "0.24.5" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af6e6c9b6d975edcb443565d648b605f3e85a04ec63aa6941811a8894cc9cded" +checksum = "82ad8ddc14be1d4290cd68046e7d1d37acd408efed6d3ca08aefcc3ad6da069c" dependencies = [ "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", "http-body-util", - "hyper 1.4.1", + "hyper 1.5.1", "hyper-util", "jsonrpsee-core", "jsonrpsee-types", @@ -5213,7 +5480,7 @@ dependencies = [ "serde", "serde_json", "soketto", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tokio-util", @@ -5223,21 +5490,21 @@ dependencies = [ [[package]] name = "jsonrpsee-types" -version = "0.24.5" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8fb16314327cbc94fdf7965ef7e4422509cd5597f76d137bd104eb34aeede67" +checksum = "a178c60086f24cc35bb82f57c651d0d25d99c4742b4d335de04e97fa1f08a8a1" dependencies = [ - "http 1.1.0", + "http 1.2.0", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "jsonrpsee-wasm-client" -version = "0.24.5" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0da62b43702bd5640ea305d35df95da30abc878e79a7b4b01feda3beaf35d3c" +checksum = "1a01cd500915d24ab28ca17527e23901ef1be6d659a2322451e1045532516c25" dependencies = [ "jsonrpsee-client-transport", "jsonrpsee-core", @@ -5246,11 +5513,11 @@ dependencies = [ [[package]] name = "jsonrpsee-ws-client" -version = "0.24.5" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39aabf5d6c6f22da8d5b808eea1fab0736059f11fb42f71f141b14f404e5046a" +checksum = "0fe322e0896d0955a3ebdd5bf813571c53fea29edd713bc315b76620b327e86d" dependencies = [ - "http 1.1.0", + "http 1.2.0", "jsonrpsee-client-transport", "jsonrpsee-core", "jsonrpsee-types", @@ -5381,15 +5648,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.159" +version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" [[package]] name = "libloading" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", "windows-targets 0.52.6", @@ -5397,15 +5664,15 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "libp2p-identity" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cca1eb2bc1fd29f099f3daaab7effd01e1a54b7c577d0ed082521034d912e8" +checksum = "257b5621d159b32282eac446bed6670c39c7dc68a200a992d8f056afa0066f6d" dependencies = [ "asn1_der", "bs58", @@ -5415,7 +5682,7 @@ dependencies = [ "multihash", "quick-protobuf", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.69", "tracing", "zeroize", ] @@ -5439,7 +5706,7 @@ checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ "bitflags 2.6.0", "libc", - "redox_syscall 0.5.7", + "redox_syscall 0.5.8", ] [[package]] @@ -5523,9 +5790,9 @@ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "litemap" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" [[package]] name = "litrs" @@ -5556,16 +5823,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.0", -] - -[[package]] -name = "lru-cache" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" -dependencies = [ - "linked-hash-map", + "hashbrown 0.15.2", ] [[package]] @@ -5660,19 +5918,9 @@ dependencies = [ [[package]] name = "metrics" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884adb57038347dfbaf2d5065887b6cf4312330dc8e94bc30a1a839bd79d3261" -dependencies = [ - "ahash 0.8.11", - "portable-atomic", -] - -[[package]] -name = "metrics" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae428771d17306715c5091d446327d1cfdedc82185c65ba8423ab404e45bf10" +checksum = "7a7deb012b3b2767169ff203fadb4c6b0b82b947512e5eb9e0b78c2e186ad9e3" dependencies = [ "ahash 0.8.11", "portable-atomic", @@ -5687,7 +5935,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -5697,26 +5945,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85b6f8152da6d7892ff1b7a1c0fa3f435e92b5918ad67035c3bb432111d9a29b" dependencies = [ "base64 0.22.1", - "indexmap 2.6.0", - "metrics 0.24.0", + "indexmap 2.7.0", + "metrics", "metrics-util", "quanta", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "metrics-process" -version = "2.1.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb524e5438255eaa8aa74214d5a62713b77b2c3c6e3c0bbeee65cfd9a58948ba" +checksum = "4a82c8add4382f29a122fa64fff1891453ed0f6b2867d971e7d60cb8dfa322ff" dependencies = [ + "libc", "libproc", "mach2", - "metrics 0.23.0", + "metrics", "once_cell", - "procfs", + "procfs 0.17.0", "rlimit", - "windows 0.57.0", + "windows 0.58.0", ] [[package]] @@ -5727,8 +5976,8 @@ checksum = "15b482df36c13dd1869d73d14d28cd4855fbd6cfc32294bee109908a9f4a4ed7" dependencies = [ "crossbeam-epoch", "crossbeam-utils", - "hashbrown 0.15.0", - "metrics 0.24.0", + "hashbrown 0.15.2", + "metrics", "quanta", "sketches-ddsketch", ] @@ -5787,11 +6036,10 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ - "hermit-abi 0.3.9", "libc", "log", "wasi", @@ -5810,7 +6058,7 @@ dependencies = [ "mach2", "nix", "sysctl", - "thiserror", + "thiserror 1.0.69", "widestring", "windows 0.48.0", ] @@ -5836,6 +6084,26 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "moka" +version = "0.12.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cf62eb4dd975d2dde76432fb1075c49e3ee2331cf36f1f8fd4b66550d32b6f" +dependencies = [ + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "once_cell", + "parking_lot", + "quanta", + "rustc_version 0.4.1", + "smallvec", + "tagptr", + "thiserror 1.0.69", + "triomphe", + "uuid", +] + [[package]] name = "more-asserts" version = "0.2.2" @@ -5863,7 +6131,7 @@ dependencies = [ "percent-encoding", "serde", "static_assertions", - "unsigned-varint 0.8.0", + "unsigned-varint", "url", ] @@ -5880,12 +6148,12 @@ dependencies = [ [[package]] name = "multihash" -version = "0.19.1" +version = "0.19.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076d548d76a0e2a0d4ab471d0b1c36c577786dfc4471242035d97a12a735c492" +checksum = "6b430e7953c29dd6a09afc29ff0bb69c6e306329ee6794700aee27b76a1aea8d" dependencies = [ "core2", - "unsigned-varint 0.7.2", + "unsigned-varint", ] [[package]] @@ -5900,7 +6168,7 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "security-framework", + "security-framework 2.11.1", "security-framework-sys", "tempfile", ] @@ -5942,7 +6210,6 @@ dependencies = [ "libc", "log", "mio 0.8.11", - "serde", "walkdir", "windows-sys 0.48.0", ] @@ -6097,7 +6364,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -6150,80 +6417,103 @@ checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "op-alloy-consensus" -version = "0.5.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba7c98055fd048073738df0cc6d6537e992a0d8828f39d99a469e870db126dbd" +checksum = "78f0daa0d0936d436a21b57571b1e27c5663aa2ab62f6edae5ba5be999f9f93e" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rlp", - "alloy-serde 0.5.4", + "alloy-serde 0.7.3", "arbitrary", - "derive_more 1.0.0", + "derive_more", "serde", "serde_with", - "spin", + "thiserror 2.0.6", ] [[package]] name = "op-alloy-genesis" -version = "0.5.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d631e8113cf88d30e621022677209caa148a9ca3ccb590fd34bbd1c731e3aff3" +checksum = "3eb0964932faa7050b74689f017aca66ffa3e52501080278a81bb0a43836c8dd" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-sol-types", "serde", "serde_repr", + "thiserror 2.0.6", ] [[package]] name = "op-alloy-network" -version = "0.5.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1eabe7683d7e19c7cc5171d664e49fc449176cf1334ffff82808e2a7eea5933a" +checksum = "cd9a690fcc404e44c3589dd39cf22895df42f7ef8671a07828b8c376c39be46a" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-network 0.5.4", + "alloy-consensus 0.7.3", + "alloy-network 0.7.3", "alloy-primitives", - "alloy-rpc-types-eth 0.5.4", + "alloy-rpc-types-eth 0.7.3", + "alloy-signer 0.7.3", "op-alloy-consensus", "op-alloy-rpc-types", ] [[package]] name = "op-alloy-protocol" -version = "0.5.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b39574acb1873315e6bd89df174f6223e897188fb87eeea2ad1eda04f7d28eb" +checksum = "6d8c057c1a5bdf72d1f86c470a4d90f2d2ad1b273caa547c04cd6affe45b466d" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloc-no-stdlib", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rlp", - "alloy-serde 0.5.4", - "derive_more 1.0.0", + "alloy-serde 0.7.3", + "async-trait", + "brotli", + "cfg-if", + "miniz_oxide 0.8.0", "op-alloy-consensus", "op-alloy-genesis", "serde", + "thiserror 2.0.6", + "tracing", + "unsigned-varint", +] + +[[package]] +name = "op-alloy-rpc-jsonrpsee" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a98debc5266443e64e03195cd1a3b6cdbe8d8679e9d8c4b76a3670d24b2e267a" +dependencies = [ + "alloy-eips 0.7.3", + "alloy-primitives", + "jsonrpsee", + "op-alloy-rpc-types", + "op-alloy-rpc-types-engine", ] [[package]] name = "op-alloy-rpc-types" -version = "0.5.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919e9b69212d61f3c8932bfb717c7ad458ea3fc52072b3433d99994f8223d555" +checksum = "73741855ffaa2041b33cb616d7db7180c1149b648c68c23bee9e15501073fb32" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", - "alloy-network-primitives 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", + "alloy-network-primitives 0.7.3", "alloy-primitives", - "alloy-rpc-types-eth 0.5.4", - "alloy-serde 0.5.4", + "alloy-rpc-types-eth 0.7.3", + "alloy-serde 0.7.3", "arbitrary", + "derive_more", "op-alloy-consensus", "serde", "serde_json", @@ -6231,18 +6521,22 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types-engine" -version = "0.5.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e3a47ea24cee189b4351be247fd138c68571704ee57060cf5a722502f44412c" +checksum = "ebedc32e24013c8b3faea62d091bccbb90f871286fe2238c6f7e2ff29974df8e" dependencies = [ + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rpc-types-engine", - "alloy-serde 0.5.4", - "derive_more 1.0.0", + "alloy-serde 0.7.3", + "derive_more", "ethereum_ssz", + "op-alloy-consensus", + "op-alloy-genesis", "op-alloy-protocol", "serde", "snap", + "thiserror 2.0.6", ] [[package]] @@ -6278,9 +6572,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.66" +version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ "bitflags 2.6.0", "cfg-if", @@ -6299,7 +6593,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -6310,9 +6604,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.103" +version = "0.9.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ "cc", "libc", @@ -6406,7 +6700,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.7", + "redox_syscall 0.5.8", "smallvec", "windows-targets 0.52.6", ] @@ -6451,12 +6745,12 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.13" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" +checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" dependencies = [ "memchr", - "thiserror", + "thiserror 2.0.6", "ucd-trie", ] @@ -6467,7 +6761,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.6.0", + "indexmap 2.7.0", ] [[package]] @@ -6510,7 +6804,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -6524,29 +6818,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -6627,9 +6921,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" +checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" [[package]] name = "poseidon" @@ -6645,9 +6939,9 @@ dependencies = [ [[package]] name = "postcard" -version = "1.0.10" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f7f0a8d620d71c457dd1d47df76bb18960378da56af4527aaa10f515eee732e" +checksum = "170a2601f67cc9dba8edd8c4870b15f71a6a2dc196daec8c83f72b59dff628a8" dependencies = [ "cobs", "embedded-io 0.4.0", @@ -6765,14 +7059,14 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -6788,7 +7082,19 @@ dependencies = [ "flate2", "hex", "lazy_static 1.5.0", - "procfs-core", + "procfs-core 0.16.0", + "rustix", +] + +[[package]] +name = "procfs" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc5b72d8145275d844d4b5f6d4e1eef00c8cd889edb6035c21675d1bb1f45c9f" +dependencies = [ + "bitflags 2.6.0", + "hex", + "procfs-core 0.17.0", "rustix", ] @@ -6803,6 +7109,16 @@ dependencies = [ "hex", ] +[[package]] +name = "procfs-core" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "239df02d8349b06fc07398a3a1697b06418223b1c7725085e801e7c0fc6a12ec" +dependencies = [ + "bitflags 2.6.0", + "hex", +] + [[package]] name = "proptest" version = "1.5.0" @@ -6841,7 +7157,7 @@ checksum = "6ff7ff745a347b87471d859a377a9a404361e7efc2a971d73424a6d183c0fc77" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -6907,48 +7223,52 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" +checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" dependencies = [ "bytes", "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "rustls", - "socket2 0.5.7", - "thiserror", + "socket2 0.5.8", + "thiserror 2.0.6", "tokio", "tracing", ] [[package]] name = "quinn-proto" -version = "0.11.8" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" +checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" dependencies = [ "bytes", + "getrandom", "rand", "ring", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "rustls", + "rustls-pki-types", "slab", - "thiserror", + "thiserror 2.0.6", "tinyvec", "tracing", + "web-time", ] [[package]] name = "quinn-udp" -version = "0.5.5" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fe68c2e9e1a1234e218683dbdf9f9dfcb094113c5ac2b938dfcb9bab4c4140b" +checksum = "52cd4b1eff68bf27940dd39811292c49e007f4d0b4c357358dc9b0197be6b527" dependencies = [ + "cfg_aliases", "libc", "once_cell", - "socket2 0.5.7", + "socket2 0.5.8", "tracing", "windows-sys 0.59.0", ] @@ -7017,7 +7337,7 @@ dependencies = [ "bitflags 2.6.0", "cassowary", "compact_str", - "crossterm 0.28.1", + "crossterm", "instability", "itertools 0.13.0", "lru", @@ -7026,7 +7346,7 @@ dependencies = [ "strum_macros", "unicode-segmentation", "unicode-truncate", - "unicode-width", + "unicode-width 0.1.14", ] [[package]] @@ -7072,9 +7392,9 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_syscall" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ "bitflags 2.6.0", ] @@ -7087,7 +7407,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -7104,13 +7424,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.8", + "regex-automata 0.4.9", "regex-syntax 0.8.5", ] @@ -7125,9 +7445,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -7197,7 +7517,7 @@ dependencies = [ "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.30", + "hyper 0.14.31", "hyper-tls 0.5.0", "ipnet", "js-sys", @@ -7225,9 +7545,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.8" +version = "0.12.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" +checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" dependencies = [ "base64 0.22.1", "bytes", @@ -7235,11 +7555,11 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.4.6", - "http 1.1.0", + "h2 0.4.7", + "http 1.2.0", "http-body 1.0.1", "http-body-util", - "hyper 1.4.1", + "hyper 1.5.1", "hyper-rustls", "hyper-tls 0.6.0", "hyper-util", @@ -7253,13 +7573,13 @@ dependencies = [ "pin-project-lite", "quinn", "rustls", - "rustls-native-certs 0.8.0", + "rustls-native-certs 0.8.1", "rustls-pemfile 2.2.0", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "system-configuration 0.6.1", "tokio", "tokio-native-tls", @@ -7288,17 +7608,17 @@ dependencies = [ [[package]] name = "reth" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rlp", "alloy-rpc-types", "aquamarine", "backon", - "clap 4.5.19", + "clap 4.5.23", "eyre", "futures", "reth-basic-payload-builder", @@ -7336,6 +7656,7 @@ dependencies = [ "reth-payload-primitives", "reth-payload-validator", "reth-primitives", + "reth-primitives-traits", "reth-provider", "reth-prune", "reth-revm", @@ -7359,56 +7680,27 @@ dependencies = [ ] [[package]] -name = "reth-auto-seal-consensus" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +name = "reth-basic-payload-builder" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", - "alloy-rpc-types-engine", + "alloy-rlp", + "futures-core", "futures-util", - "reth-beacon-consensus", - "reth-chainspec", - "reth-consensus", - "reth-engine-primitives", - "reth-evm", - "reth-execution-errors", - "reth-execution-types", - "reth-network-p2p", - "reth-network-peers", - "reth-optimism-consensus", - "reth-primitives", - "reth-provider", - "reth-revm", - "reth-stages-api", - "reth-tokio-util", - "reth-transaction-pool", - "reth-trie", - "revm-primitives 13.0.0", - "tokio", - "tokio-stream", - "tracing", -] - -[[package]] -name = "reth-basic-payload-builder" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" -dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", - "alloy-primitives", - "alloy-rlp", - "futures-core", - "futures-util", - "metrics 0.24.0", + "metrics", "reth-chainspec", "reth-evm", "reth-metrics", "reth-payload-builder", + "reth-payload-builder-primitives", "reth-payload-primitives", "reth-primitives", + "reth-primitives-traits", "reth-provider", + "reth-revm", "reth-tasks", "reth-transaction-pool", "revm", @@ -7418,17 +7710,20 @@ dependencies = [ [[package]] name = "reth-beacon-consensus" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rpc-types-engine", "futures", "itertools 0.13.0", - "metrics 0.24.0", + "metrics", "reth-blockchain-tree-api", "reth-chainspec", + "reth-codecs", + "reth-db-api", "reth-engine-primitives", "reth-errors", "reth-ethereum-consensus", @@ -7436,9 +7731,11 @@ dependencies = [ "reth-network-p2p", "reth-node-types", "reth-payload-builder", + "reth-payload-builder-primitives", "reth-payload-primitives", "reth-payload-validator", "reth-primitives", + "reth-primitives-traits", "reth-provider", "reth-prune", "reth-stages-api", @@ -7446,7 +7743,7 @@ dependencies = [ "reth-tasks", "reth-tokio-util", "schnellru", - "thiserror", + "thiserror 2.0.6", "tokio", "tokio-stream", "tracing", @@ -7454,14 +7751,15 @@ dependencies = [ [[package]] name = "reth-blockchain-tree" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "aquamarine", "linked_hash_set", - "metrics 0.24.0", + "metrics", "parking_lot", "reth-blockchain-tree-api", "reth-consensus", @@ -7487,30 +7785,32 @@ dependencies = [ [[package]] name = "reth-blockchain-tree-api" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "reth-consensus", "reth-execution-errors", "reth-primitives", + "reth-primitives-traits", "reth-storage-errors", - "thiserror", + "thiserror 2.0.6", ] [[package]] name = "reth-chain-state" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", - "alloy-signer 0.5.4", - "alloy-signer-local", - "auto_impl", - "derive_more 1.0.0", - "metrics 0.24.0", + "alloy-signer 0.7.3", + "alloy-signer-local 0.7.3", + "derive_more", + "metrics", "parking_lot", "pin-project", "rand", @@ -7519,6 +7819,7 @@ dependencies = [ "reth-execution-types", "reth-metrics", "reth-primitives", + "reth-primitives-traits", "reth-storage-api", "reth-trie", "revm", @@ -7529,16 +7830,16 @@ dependencies = [ [[package]] name = "reth-chainspec" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-chains", - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-genesis", "alloy-primitives", "auto_impl", - "derive_more 1.0.0", + "derive_more", "once_cell", "reth-ethereum-forks", "reth-network-peers", @@ -7549,11 +7850,11 @@ dependencies = [ [[package]] name = "reth-cli" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-genesis", - "clap 4.5.19", + "clap 4.5.23", "eyre", "reth-cli-runner", "reth-db", @@ -7563,16 +7864,18 @@ dependencies = [ [[package]] name = "reth-cli-commands" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "ahash 0.8.11", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", + "alloy-rlp", "backon", - "clap 4.5.19", + "clap 4.5.23", "comfy-table", - "crossterm 0.28.1", + "crossterm", "eyre", "fdlimit", "futures", @@ -7584,6 +7887,7 @@ dependencies = [ "reth-cli", "reth-cli-runner", "reth-cli-util", + "reth-codecs", "reth-config", "reth-consensus", "reth-db", @@ -7599,6 +7903,7 @@ dependencies = [ "reth-network", "reth-network-p2p", "reth-network-peers", + "reth-node-api", "reth-node-builder", "reth-node-core", "reth-node-events", @@ -7621,8 +7926,8 @@ dependencies = [ [[package]] name = "reth-cli-runner" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "reth-tasks", "tokio", @@ -7631,10 +7936,10 @@ dependencies = [ [[package]] name = "reth-cli-util" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-eips 0.5.4", + "alloy-eips 0.7.3", "alloy-primitives", "cfg-if", "eyre", @@ -7642,17 +7947,18 @@ dependencies = [ "rand", "reth-fs-util", "secp256k1", - "thiserror", + "serde", + "thiserror 2.0.6", "tikv-jemallocator", ] [[package]] name = "reth-codecs" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-genesis", "alloy-primitives", "alloy-trie", @@ -7667,19 +7973,19 @@ dependencies = [ [[package]] name = "reth-codecs-derive" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "convert_case", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] name = "reth-config" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "eyre", "humantime-serde", @@ -7692,45 +7998,48 @@ dependencies = [ [[package]] name = "reth-consensus" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "auto_impl", - "derive_more 1.0.0", + "derive_more", "reth-primitives", + "reth-primitives-traits", ] [[package]] name = "reth-consensus-common" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "reth-chainspec", "reth-consensus", "reth-primitives", - "revm-primitives 13.0.0", + "reth-primitives-traits", + "revm-primitives 14.0.0", ] [[package]] name = "reth-consensus-debug-client" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", - "alloy-provider 0.5.4", - "alloy-rpc-types", + "alloy-provider 0.7.3", "alloy-rpc-types-engine", + "alloy-rpc-types-eth 0.7.3", "auto_impl", "eyre", "futures", - "reqwest 0.12.8", + "reqwest 0.12.9", "reth-node-api", "reth-rpc-api", "reth-rpc-builder", @@ -7742,17 +8051,17 @@ dependencies = [ [[package]] name = "reth-db" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ + "alloy-consensus 0.7.3", "alloy-primitives", "bytes", - "derive_more 1.0.0", + "derive_more", "eyre", - "metrics 0.24.0", + "metrics", "page_size", "parking_lot", - "paste", "reth-db-api", "reth-fs-util", "reth-libmdbx", @@ -7765,25 +8074,26 @@ dependencies = [ "reth-storage-errors", "reth-tracing", "reth-trie-common", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "serde", "strum", "sysinfo", "tempfile", - "thiserror", + "thiserror 2.0.6", ] [[package]] name = "reth-db-api" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ + "alloy-consensus 0.7.3", "alloy-genesis", "alloy-primitives", "arbitrary", "bytes", - "derive_more 1.0.0", - "metrics 0.24.0", + "derive_more", + "metrics", "modular-bitfield", "parity-scale-codec", "proptest", @@ -7795,14 +8105,16 @@ dependencies = [ "reth-stages-types", "reth-storage-errors", "reth-trie-common", + "roaring", "serde", ] [[package]] name = "reth-db-common" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ + "alloy-consensus 0.7.3", "alloy-genesis", "alloy-primitives", "boyer-moore-magiclen", @@ -7822,35 +8134,37 @@ dependencies = [ "reth-trie-db", "serde", "serde_json", - "thiserror", + "thiserror 2.0.6", "tracing", ] [[package]] name = "reth-db-models" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ + "alloy-eips 0.7.3", "alloy-primitives", "arbitrary", "bytes", "modular-bitfield", "proptest", "reth-codecs", - "reth-primitives", + "reth-primitives-traits", "serde", ] [[package]] name = "reth-discv4" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-primitives", "alloy-rlp", "discv5", "enr", "generic-array", + "itertools 0.13.0", "parking_lot", "rand", "reth-ethereum-forks", @@ -7860,7 +8174,7 @@ dependencies = [ "schnellru", "secp256k1", "serde", - "thiserror", + "thiserror 2.0.6", "tokio", "tokio-stream", "tracing", @@ -7868,36 +8182,37 @@ dependencies = [ [[package]] name = "reth-discv5" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-primitives", "alloy-rlp", - "derive_more 1.0.0", + "derive_more", "discv5", "enr", "futures", "itertools 0.13.0", - "metrics 0.24.0", + "metrics", "rand", "reth-chainspec", "reth-ethereum-forks", "reth-metrics", "reth-network-peers", "secp256k1", - "thiserror", + "thiserror 2.0.6", "tokio", "tracing", ] [[package]] name = "reth-dns-discovery" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-primitives", "data-encoding", "enr", + "hickory-resolver", "linked_hash_set", "parking_lot", "reth-ethereum-forks", @@ -7907,25 +8222,25 @@ dependencies = [ "secp256k1", "serde", "serde_with", - "thiserror", + "thiserror 2.0.6", "tokio", "tokio-stream", "tracing", - "trust-dns-resolver", ] [[package]] name = "reth-downloaders" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rlp", "futures", "futures-util", "itertools 0.13.0", - "metrics 0.24.0", + "metrics", "pin-project", "rayon", "reth-config", @@ -7936,11 +8251,12 @@ dependencies = [ "reth-network-p2p", "reth-network-peers", "reth-primitives", + "reth-primitives-traits", "reth-storage-api", "reth-tasks", "reth-testing-utils", "tempfile", - "thiserror", + "thiserror 2.0.6", "tokio", "tokio-stream", "tokio-util", @@ -7949,32 +8265,44 @@ dependencies = [ [[package]] name = "reth-e2e-test-utils" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", - "alloy-network 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", + "alloy-network 0.7.3", "alloy-primitives", - "alloy-rpc-types", - "alloy-signer 0.5.4", - "alloy-signer-local", - "derive_more 1.0.0", + "alloy-rlp", + "alloy-rpc-types-engine", + "alloy-rpc-types-eth 0.7.3", + "alloy-signer 0.7.3", + "alloy-signer-local 0.7.3", + "derive_more", "eyre", "futures-util", "jsonrpsee", "op-alloy-rpc-types-engine", - "reth", "reth-chainspec", "reth-db", "reth-engine-local", + "reth-network", + "reth-network-api", "reth-network-peers", + "reth-node-api", "reth-node-builder", + "reth-node-core", + "reth-optimism-primitives", "reth-payload-builder", + "reth-payload-builder-primitives", "reth-payload-primitives", + "reth-primitives", "reth-provider", + "reth-rpc-api", + "reth-rpc-eth-api", "reth-rpc-layer", + "reth-rpc-server-types", "reth-stages-types", + "reth-tasks", "reth-tokio-util", "reth-tracing", "serde_json", @@ -7986,8 +8314,8 @@ dependencies = [ [[package]] name = "reth-ecies" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "aes", "alloy-primitives", @@ -8007,7 +8335,7 @@ dependencies = [ "secp256k1", "sha2 0.10.8", "sha3", - "thiserror", + "thiserror 2.0.6", "tokio", "tokio-stream", "tokio-util", @@ -8017,9 +8345,10 @@ dependencies = [ [[package]] name = "reth-engine-local" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ + "alloy-consensus 0.7.3", "alloy-primitives", "alloy-rpc-types-engine", "eyre", @@ -8033,9 +8362,10 @@ dependencies = [ "reth-engine-tree", "reth-ethereum-engine-primitives", "reth-evm", + "reth-node-types", "reth-payload-builder", + "reth-payload-builder-primitives", "reth-payload-primitives", - "reth-payload-validator", "reth-provider", "reth-prune", "reth-rpc-types-compat", @@ -8048,50 +8378,62 @@ dependencies = [ [[package]] name = "reth-engine-primitives" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ + "alloy-consensus 0.7.3", "alloy-primitives", + "alloy-rpc-types-engine", + "futures", + "reth-errors", "reth-execution-types", + "reth-payload-builder-primitives", "reth-payload-primitives", "reth-primitives", + "reth-primitives-traits", "reth-trie", "serde", + "thiserror 2.0.6", + "tokio", ] [[package]] name = "reth-engine-service" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "futures", "pin-project", "reth-beacon-consensus", "reth-chainspec", "reth-consensus", + "reth-engine-primitives", "reth-engine-tree", "reth-evm", "reth-network-p2p", "reth-node-types", "reth-payload-builder", - "reth-payload-validator", + "reth-primitives", "reth-provider", "reth-prune", "reth-stages-api", "reth-tasks", - "thiserror", + "thiserror 2.0.6", ] [[package]] name = "reth-engine-tree" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", + "alloy-rlp", "alloy-rpc-types-engine", "futures", - "metrics 0.24.0", + "metrics", + "rayon", "reth-beacon-consensus", "reth-blockchain-tree", "reth-blockchain-tree-api", @@ -8104,9 +8446,10 @@ dependencies = [ "reth-metrics", "reth-network-p2p", "reth-payload-builder", + "reth-payload-builder-primitives", "reth-payload-primitives", - "reth-payload-validator", "reth-primitives", + "reth-primitives-traits", "reth-provider", "reth-prune", "reth-prune-types", @@ -8117,26 +8460,29 @@ dependencies = [ "reth-tasks", "reth-tracing", "reth-trie", + "reth-trie-db", "reth-trie-parallel", - "thiserror", + "reth-trie-sparse", + "revm-primitives 14.0.0", + "thiserror 2.0.6", "tokio", "tracing", ] [[package]] name = "reth-engine-util" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rpc-types-engine", "eyre", "futures", "itertools 0.13.0", "pin-project", - "reth-beacon-consensus", + "reth-consensus-common", "reth-engine-primitives", "reth-errors", "reth-ethereum-forks", @@ -8148,7 +8494,7 @@ dependencies = [ "reth-revm", "reth-rpc-types-compat", "reth-trie", - "revm-primitives 13.0.0", + "revm-primitives 14.0.0", "serde", "serde_json", "tokio", @@ -8158,38 +8504,39 @@ dependencies = [ [[package]] name = "reth-errors" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "reth-blockchain-tree-api", "reth-consensus", "reth-execution-errors", "reth-fs-util", "reth-storage-errors", - "thiserror", + "thiserror 2.0.6", ] [[package]] name = "reth-eth-wire" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ + "alloy-chains", "alloy-primitives", "alloy-rlp", "bytes", - "derive_more 1.0.0", + "derive_more", "futures", "pin-project", - "reth-chainspec", "reth-codecs", "reth-ecies", "reth-eth-wire-types", + "reth-ethereum-forks", "reth-metrics", "reth-network-peers", - "reth-primitives", + "reth-primitives-traits", "serde", "snap", - "thiserror", + "thiserror 2.0.6", "tokio", "tokio-stream", "tokio-util", @@ -8198,26 +8545,29 @@ dependencies = [ [[package]] name = "reth-eth-wire-types" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-chains", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rlp", "bytes", - "derive_more 1.0.0", + "derive_more", "reth-chainspec", "reth-codecs-derive", + "reth-ethereum-forks", "reth-primitives", + "reth-primitives-traits", "serde", - "thiserror", + "thiserror 2.0.6", ] [[package]] name = "reth-ethereum-cli" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "eyre", "reth-chainspec", @@ -8226,25 +8576,26 @@ dependencies = [ [[package]] name = "reth-ethereum-consensus" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "reth-chainspec", "reth-consensus", "reth-consensus-common", "reth-primitives", + "reth-primitives-traits", "tracing", ] [[package]] name = "reth-ethereum-engine-primitives" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-eips 0.5.4", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rlp", "alloy-rpc-types-engine", @@ -8252,6 +8603,7 @@ dependencies = [ "reth-chainspec", "reth-engine-primitives", "reth-payload-primitives", + "reth-payload-validator", "reth-primitives", "reth-rpc-types-compat", "serde", @@ -8260,8 +8612,8 @@ dependencies = [ [[package]] name = "reth-ethereum-forks" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-chains", "alloy-primitives", @@ -8273,18 +8625,18 @@ dependencies = [ "once_cell", "proptest", "proptest-derive", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "serde", - "thiserror-no-std", + "thiserror 2.0.6", ] [[package]] name = "reth-ethereum-payload-builder" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "reth-basic-payload-builder", "reth-chain-state", @@ -8294,21 +8646,20 @@ dependencies = [ "reth-evm-ethereum", "reth-execution-types", "reth-payload-builder", + "reth-payload-builder-primitives", "reth-payload-primitives", "reth-primitives", "reth-provider", "reth-revm", "reth-transaction-pool", - "reth-trie", "revm", - "revm-primitives 13.0.0", "tracing", ] [[package]] name = "reth-etl" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "rayon", "reth-db-api", @@ -8317,14 +8668,15 @@ dependencies = [ [[package]] name = "reth-evm" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "auto_impl", "futures-util", - "metrics 0.24.0", + "metrics", "parking_lot", "reth-chainspec", "reth-consensus", @@ -8338,16 +8690,16 @@ dependencies = [ "reth-revm", "reth-storage-errors", "revm", - "revm-primitives 13.0.0", + "revm-primitives 14.0.0", ] [[package]] name = "reth-evm-ethereum" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-sol-types", "reth-chainspec", @@ -8357,35 +8709,38 @@ dependencies = [ "reth-evm", "reth-primitives", "reth-revm", - "revm-primitives 13.0.0", + "revm-primitives 14.0.0", ] [[package]] name = "reth-execution-errors" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-eips 0.5.4", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rlp", - "derive_more 1.0.0", "nybbles", "reth-consensus", "reth-prune-types", "reth-storage-errors", - "revm-primitives 13.0.0", + "revm-primitives 14.0.0", + "thiserror 2.0.6", ] [[package]] name = "reth-execution-types" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "reth-execution-errors", "reth-primitives", + "reth-primitives-traits", "reth-trie", + "reth-trie-common", "revm", "serde", "serde_with", @@ -8393,15 +8748,16 @@ dependencies = [ [[package]] name = "reth-exex" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "eyre", "futures", "itertools 0.13.0", - "metrics 0.24.0", + "metrics", "parking_lot", "reth-chain-state", "reth-chainspec", @@ -8412,7 +8768,6 @@ dependencies = [ "reth-metrics", "reth-node-api", "reth-node-core", - "reth-payload-builder", "reth-primitives", "reth-primitives-traits", "reth-provider", @@ -8429,32 +8784,35 @@ dependencies = [ [[package]] name = "reth-exex-types" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-eips 0.5.4", + "alloy-eips 0.7.3", "alloy-primitives", "reth-chain-state", "reth-execution-types", + "reth-primitives", + "reth-primitives-traits", "serde", "serde_with", ] [[package]] name = "reth-fs-util" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "serde", "serde_json", - "thiserror", + "thiserror 2.0.6", ] [[package]] name = "reth-invalid-block-hooks" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ + "alloy-consensus 0.7.3", "alloy-primitives", "alloy-rlp", "alloy-rpc-types-debug", @@ -8466,6 +8824,7 @@ dependencies = [ "reth-engine-primitives", "reth-evm", "reth-primitives", + "reth-primitives-traits", "reth-provider", "reth-revm", "reth-rpc-api", @@ -8477,8 +8836,8 @@ dependencies = [ [[package]] name = "reth-ipc" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "async-trait", "bytes", @@ -8488,7 +8847,7 @@ dependencies = [ "jsonrpsee", "pin-project", "serde_json", - "thiserror", + "thiserror 2.0.6", "tokio", "tokio-stream", "tokio-util", @@ -8498,25 +8857,25 @@ dependencies = [ [[package]] name = "reth-libmdbx" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "bitflags 2.6.0", "byteorder", "dashmap 6.1.0", - "derive_more 1.0.0", - "indexmap 2.6.0", + "derive_more", + "indexmap 2.7.0", "parking_lot", "reth-mdbx-sys", "smallvec", - "thiserror", + "thiserror 2.0.6", "tracing", ] [[package]] name = "reth-mdbx-sys" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "bindgen", "cc", @@ -8524,11 +8883,11 @@ dependencies = [ [[package]] name = "reth-metrics" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "futures", - "metrics 0.24.0", + "metrics", "metrics-derive", "tokio", "tokio-util", @@ -8536,42 +8895,43 @@ dependencies = [ [[package]] name = "reth-net-banlist" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-primitives", ] [[package]] name = "reth-net-nat" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "futures-util", "if-addrs", - "reqwest 0.12.8", + "reqwest 0.12.9", "serde_with", - "thiserror", + "thiserror 2.0.6", "tokio", "tracing", ] [[package]] name = "reth-network" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rlp", "aquamarine", "auto_impl", - "derive_more 1.0.0", + "derive_more", "discv5", "enr", "futures", "itertools 0.13.0", - "metrics 0.24.0", + "metrics", "parking_lot", "pin-project", "rand", @@ -8582,6 +8942,8 @@ dependencies = [ "reth-dns-discovery", "reth-ecies", "reth-eth-wire", + "reth-eth-wire-types", + "reth-ethereum-forks", "reth-fs-util", "reth-metrics", "reth-net-banlist", @@ -8590,18 +8952,18 @@ dependencies = [ "reth-network-peers", "reth-network-types", "reth-primitives", - "reth-provider", + "reth-primitives-traits", "reth-storage-api", "reth-tasks", "reth-tokio-util", "reth-transaction-pool", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "schnellru", "secp256k1", "serde", "smallvec", "tempfile", - "thiserror", + "thiserror 2.0.6", "tokio", "tokio-stream", "tokio-util", @@ -8610,13 +8972,13 @@ dependencies = [ [[package]] name = "reth-network-api" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-primitives", "alloy-rpc-types-admin", "auto_impl", - "derive_more 1.0.0", + "derive_more", "enr", "futures", "reth-eth-wire-types", @@ -8626,20 +8988,21 @@ dependencies = [ "reth-network-types", "reth-tokio-util", "serde", - "thiserror", + "thiserror 2.0.6", "tokio", "tokio-stream", ] [[package]] name = "reth-network-p2p" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "auto_impl", - "derive_more 1.0.0", + "derive_more", "futures", "parking_lot", "reth-consensus", @@ -8647,6 +9010,7 @@ dependencies = [ "reth-network-peers", "reth-network-types", "reth-primitives", + "reth-primitives-traits", "reth-storage-errors", "tokio", "tracing", @@ -8654,23 +9018,23 @@ dependencies = [ [[package]] name = "reth-network-peers" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-primitives", "alloy-rlp", "enr", "secp256k1", "serde_with", - "thiserror", + "thiserror 2.0.6", "tokio", "url", ] [[package]] name = "reth-network-types" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "humantime-serde", "reth-ethereum-forks", @@ -8683,25 +9047,25 @@ dependencies = [ [[package]] name = "reth-nippy-jar" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "anyhow", "bincode", - "derive_more 1.0.0", + "derive_more", "lz4_flex", "memmap2 0.9.5", "reth-fs-util", "serde", - "thiserror", + "thiserror 2.0.6", "tracing", "zstd", ] [[package]] name = "reth-node-api" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-rpc-types-engine", "eyre", @@ -8712,9 +9076,8 @@ dependencies = [ "reth-network-api", "reth-node-core", "reth-node-types", - "reth-payload-builder", + "reth-payload-builder-primitives", "reth-payload-primitives", - "reth-primitives", "reth-provider", "reth-tasks", "reth-transaction-pool", @@ -8722,9 +9085,10 @@ dependencies = [ [[package]] name = "reth-node-builder" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ + "alloy-consensus 0.7.3", "alloy-primitives", "alloy-rpc-types", "aquamarine", @@ -8733,7 +9097,6 @@ dependencies = [ "futures", "jsonrpsee", "rayon", - "reth-auto-seal-consensus", "reth-beacon-consensus", "reth-blockchain-tree", "reth-chain-state", @@ -8762,7 +9125,6 @@ dependencies = [ "reth-node-events", "reth-node-metrics", "reth-payload-builder", - "reth-payload-primitives", "reth-payload-validator", "reth-primitives", "reth-provider", @@ -8779,6 +9141,7 @@ dependencies = [ "reth-tokio-util", "reth-tracing", "reth-transaction-pool", + "revm-primitives 14.0.0", "secp256k1", "tokio", "tokio-stream", @@ -8787,16 +9150,16 @@ dependencies = [ [[package]] name = "reth-node-core" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rpc-types-engine", - "clap 4.5.19", + "clap 4.5.23", "const_format", - "derive_more 1.0.0", + "derive_more", "dirs-next", "eyre", "futures", @@ -8805,15 +9168,17 @@ dependencies = [ "reth-chainspec", "reth-cli-util", "reth-config", - "reth-consensus-common", + "reth-consensus", "reth-db", "reth-discv4", "reth-discv5", + "reth-ethereum-forks", "reth-net-nat", "reth-network", "reth-network-p2p", "reth-network-peers", "reth-primitives", + "reth-primitives-traits", "reth-prune-types", "reth-rpc-eth-types", "reth-rpc-server-types", @@ -8827,7 +9192,7 @@ dependencies = [ "serde", "shellexpand", "strum", - "thiserror", + "thiserror 2.0.6", "toml", "tracing", "vergen", @@ -8835,11 +9200,10 @@ dependencies = [ [[package]] name = "reth-node-ethereum" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "eyre", - "reth-auto-seal-consensus", "reth-basic-payload-builder", "reth-beacon-consensus", "reth-chainspec", @@ -8858,49 +9222,48 @@ dependencies = [ "reth-rpc", "reth-tracing", "reth-transaction-pool", + "reth-trie-db", "revm", ] [[package]] name = "reth-node-events" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rpc-types-engine", "futures", "humantime", "pin-project", "reth-beacon-consensus", - "reth-network", + "reth-engine-primitives", "reth-network-api", "reth-primitives-traits", - "reth-provider", - "reth-prune", + "reth-prune-types", "reth-stages", - "reth-static-file", + "reth-static-file-types", + "reth-storage-api", "tokio", "tracing", ] [[package]] name = "reth-node-metrics" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "eyre", - "http 1.1.0", - "jsonrpsee", - "metrics 0.24.0", + "http 1.2.0", + "jsonrpsee-server", + "metrics", "metrics-exporter-prometheus", "metrics-process", "metrics-util", - "procfs", - "reth-db-api", + "procfs 0.16.0", "reth-metrics", - "reth-provider", "reth-tasks", "tikv-jemalloc-ctl", "tokio", @@ -8911,27 +9274,27 @@ dependencies = [ [[package]] name = "reth-node-types" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "reth-chainspec", "reth-db-api", "reth-engine-primitives", - "reth-primitives", "reth-primitives-traits", + "reth-trie-db", ] [[package]] name = "reth-optimism-chainspec" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-chains", - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-genesis", "alloy-primitives", - "derive_more 1.0.0", + "derive_more", "once_cell", "op-alloy-rpc-types", "reth-chainspec", @@ -8944,14 +9307,18 @@ dependencies = [ [[package]] name = "reth-optimism-cli" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rlp", - "clap 4.5.19", + "clap 4.5.23", + "derive_more", "eyre", "futures-util", + "op-alloy-consensus", "reth-chainspec", "reth-cli", "reth-cli-commands", @@ -8964,6 +9331,7 @@ dependencies = [ "reth-downloaders", "reth-errors", "reth-execution-types", + "reth-fs-util", "reth-network-p2p", "reth-node-builder", "reth-node-core", @@ -8981,6 +9349,7 @@ dependencies = [ "reth-static-file", "reth-static-file-types", "reth-tracing", + "serde", "tokio", "tokio-util", "tracing", @@ -8988,16 +9357,19 @@ dependencies = [ [[package]] name = "reth-optimism-consensus" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", + "alloy-trie", "reth-chainspec", "reth-consensus", "reth-consensus-common", "reth-optimism-chainspec", "reth-optimism-forks", + "reth-optimism-primitives", "reth-primitives", "reth-trie-common", "tracing", @@ -9005,16 +9377,17 @@ dependencies = [ [[package]] name = "reth-optimism-evm" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", - "derive_more 1.0.0", + "derive_more", "op-alloy-consensus", "reth-chainspec", "reth-consensus", + "reth-consensus-common", "reth-ethereum-forks", "reth-evm", "reth-execution-errors", @@ -9022,18 +9395,20 @@ dependencies = [ "reth-optimism-chainspec", "reth-optimism-consensus", "reth-optimism-forks", + "reth-optimism-primitives", "reth-primitives", + "reth-primitives-traits", "reth-prune-types", "reth-revm", "revm", - "revm-primitives 13.0.0", + "revm-primitives 14.0.0", "tracing", ] [[package]] name = "reth-optimism-forks" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-chains", "alloy-primitives", @@ -9044,21 +9419,22 @@ dependencies = [ [[package]] name = "reth-optimism-node" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rpc-types-engine", - "clap 4.5.19", + "clap 4.5.23", "eyre", "op-alloy-rpc-types-engine", "parking_lot", - "reth-auto-seal-consensus", "reth-basic-payload-builder", "reth-beacon-consensus", "reth-chainspec", "reth-consensus", + "reth-db", "reth-engine-local", "reth-evm", "reth-network", @@ -9069,13 +9445,18 @@ dependencies = [ "reth-optimism-evm", "reth-optimism-forks", "reth-optimism-payload-builder", + "reth-optimism-primitives", "reth-optimism-rpc", "reth-payload-builder", + "reth-payload-util", + "reth-payload-validator", "reth-primitives", "reth-provider", "reth-revm", + "reth-rpc-server-types", "reth-tracing", "reth-transaction-pool", + "reth-trie-db", "revm", "serde", "serde_json", @@ -9083,14 +9464,16 @@ dependencies = [ [[package]] name = "reth-optimism-payload-builder" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rlp", + "alloy-rpc-types-debug", "alloy-rpc-types-engine", + "op-alloy-consensus", "op-alloy-rpc-types-engine", "reth-basic-payload-builder", "reth-chain-state", @@ -9102,46 +9485,61 @@ dependencies = [ "reth-optimism-evm", "reth-optimism-forks", "reth-payload-builder", + "reth-payload-builder-primitives", "reth-payload-primitives", + "reth-payload-util", "reth-primitives", "reth-provider", "reth-revm", "reth-rpc-types-compat", "reth-transaction-pool", - "reth-trie", "revm", "sha2 0.10.8", - "thiserror", + "thiserror 2.0.6", "tracing", ] [[package]] name = "reth-optimism-primitives" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", + "alloy-rlp", + "arbitrary", + "bytes", + "derive_more", + "op-alloy-consensus", + "rand", + "reth-codecs", "reth-primitives", + "reth-primitives-traits", + "revm-primitives 14.0.0", + "secp256k1", + "serde", ] [[package]] name = "reth-optimism-rpc" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", - "alloy-rpc-types", - "alloy-rpc-types-eth 0.5.4", - "derive_more 1.0.0", + "alloy-rpc-types-debug", + "alloy-rpc-types-eth 0.7.3", + "jsonrpsee-core", "jsonrpsee-types", "op-alloy-consensus", "op-alloy-network", + "op-alloy-rpc-jsonrpsee", "op-alloy-rpc-types", + "op-alloy-rpc-types-engine", "parking_lot", - "reqwest 0.12.8", + "reqwest 0.12.9", "reth-chainspec", "reth-evm", "reth-network-api", @@ -9151,9 +9549,12 @@ dependencies = [ "reth-optimism-consensus", "reth-optimism-evm", "reth-optimism-forks", + "reth-optimism-payload-builder", + "reth-optimism-primitives", "reth-primitives", "reth-provider", "reth-rpc", + "reth-rpc-api", "reth-rpc-eth-api", "reth-rpc-eth-types", "reth-rpc-server-types", @@ -9161,27 +9562,41 @@ dependencies = [ "reth-transaction-pool", "revm", "serde_json", - "thiserror", + "thiserror 2.0.6", "tokio", "tracing", ] [[package]] name = "reth-payload-builder" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-primitives", "alloy-rpc-types", "async-trait", "futures-util", - "metrics 0.24.0", + "metrics", "reth-chain-state", "reth-ethereum-engine-primitives", "reth-metrics", + "reth-payload-builder-primitives", "reth-payload-primitives", "reth-primitives", - "reth-provider", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "reth-payload-builder-primitives" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" +dependencies = [ + "alloy-rpc-types-engine", + "async-trait", + "pin-project", + "reth-payload-primitives", "tokio", "tokio-stream", "tracing", @@ -9189,31 +9604,37 @@ dependencies = [ [[package]] name = "reth-payload-primitives" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-eips 0.5.4", + "alloy-eips 0.7.3", "alloy-primitives", - "alloy-rpc-types", - "async-trait", + "alloy-rpc-types-engine", "op-alloy-rpc-types-engine", - "pin-project", "reth-chain-state", "reth-chainspec", "reth-errors", "reth-primitives", - "reth-transaction-pool", + "revm-primitives 14.0.0", "serde", - "thiserror", + "thiserror 2.0.6", "tokio", - "tokio-stream", - "tracing", +] + +[[package]] +name = "reth-payload-util" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" +dependencies = [ + "alloy-consensus 0.7.3", + "alloy-primitives", + "reth-primitives", ] [[package]] name = "reth-payload-validator" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-rpc-types", "reth-chainspec", @@ -9223,19 +9644,21 @@ dependencies = [ [[package]] name = "reth-primitives" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", + "alloy-network 0.7.3", "alloy-primitives", "alloy-rlp", "alloy-rpc-types", - "alloy-serde 0.5.4", + "alloy-serde 0.7.3", + "alloy-trie", "arbitrary", "bytes", "c-kzg", - "derive_more 1.0.0", + "derive_more", "k256", "modular-bitfield", "once_cell", @@ -9247,51 +9670,51 @@ dependencies = [ "reth-ethereum-forks", "reth-primitives-traits", "reth-static-file-types", - "reth-trie-common", - "revm-primitives 13.0.0", + "reth-zstd-compressors", + "revm-primitives 14.0.0", "secp256k1", "serde", "serde_with", - "zstd", ] [[package]] name = "reth-primitives-traits" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-genesis", "alloy-primitives", "alloy-rlp", "arbitrary", + "auto_impl", "byteorder", "bytes", - "derive_more 1.0.0", + "derive_more", "modular-bitfield", + "op-alloy-consensus", "proptest", "proptest-arbitrary-interop", "reth-codecs", - "revm-primitives 13.0.0", - "roaring", + "revm-primitives 14.0.0", "serde", "serde_with", ] [[package]] name = "reth-provider" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rpc-types-engine", "auto_impl", "dashmap 6.1.0", "itertools 0.13.0", - "metrics 0.24.0", + "metrics", "notify", "parking_lot", "rayon", @@ -9312,6 +9735,7 @@ dependencies = [ "reth-node-types", "reth-optimism-primitives", "reth-primitives", + "reth-primitives-traits", "reth-prune-types", "reth-stages-types", "reth-storage-api", @@ -9326,12 +9750,14 @@ dependencies = [ [[package]] name = "reth-prune" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "itertools 0.13.0", - "metrics 0.24.0", + "metrics", "rayon", "reth-chainspec", "reth-config", @@ -9340,40 +9766,42 @@ dependencies = [ "reth-errors", "reth-exex-types", "reth-metrics", + "reth-primitives-traits", "reth-provider", "reth-prune-types", "reth-static-file-types", "reth-tokio-util", - "rustc-hash 2.0.0", - "thiserror", + "rustc-hash 2.1.0", + "thiserror 2.0.6", "tokio", "tracing", ] [[package]] name = "reth-prune-types" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-primitives", "arbitrary", "bytes", - "derive_more 1.0.0", + "derive_more", "modular-bitfield", "reth-codecs", "serde", - "thiserror", + "thiserror 2.0.6", ] [[package]] name = "reth-revm" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-eips 0.5.4", + "alloy-eips 0.7.3", "alloy-primitives", "reth-execution-errors", "reth-primitives", + "reth-primitives-traits", "reth-prune-types", "reth-storage-api", "reth-storage-errors", @@ -9383,46 +9811,51 @@ dependencies = [ [[package]] name = "reth-rpc" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", + "alloy-consensus 0.7.3", "alloy-dyn-abi", - "alloy-eips 0.5.4", + "alloy-eips 0.7.3", "alloy-genesis", - "alloy-network 0.5.4", + "alloy-network 0.7.3", "alloy-primitives", "alloy-rlp", "alloy-rpc-types", "alloy-rpc-types-admin", "alloy-rpc-types-beacon", "alloy-rpc-types-debug", - "alloy-rpc-types-eth 0.5.4", + "alloy-rpc-types-engine", + "alloy-rpc-types-eth 0.7.3", "alloy-rpc-types-mev", "alloy-rpc-types-trace", "alloy-rpc-types-txpool", - "alloy-serde 0.5.4", - "alloy-signer 0.5.4", - "alloy-signer-local", + "alloy-serde 0.7.3", + "alloy-signer 0.7.3", + "alloy-signer-local 0.7.3", "async-trait", - "derive_more 1.0.0", + "derive_more", "futures", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", - "hyper 1.4.1", + "hyper 1.5.1", "jsonrpsee", "jsonwebtoken", "parking_lot", "pin-project", "rand", "reth-chainspec", + "reth-consensus", "reth-consensus-common", + "reth-engine-primitives", "reth-errors", + "reth-ethereum-consensus", "reth-evm", "reth-network-api", "reth-network-peers", "reth-network-types", "reth-primitives", + "reth-primitives-traits", "reth-provider", "reth-revm", "reth-rpc-api", @@ -9433,13 +9866,12 @@ dependencies = [ "reth-rpc-types-compat", "reth-tasks", "reth-transaction-pool", - "reth-trie", "revm", "revm-inspectors", - "revm-primitives 13.0.0", + "revm-primitives 14.0.0", "serde", "serde_json", - "thiserror", + "thiserror 2.0.6", "tokio", "tokio-stream", "tower 0.4.13", @@ -9449,11 +9881,11 @@ dependencies = [ [[package]] name = "reth-rpc-api" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-eips 0.5.4", - "alloy-json-rpc 0.5.4", + "alloy-eips 0.7.3", + "alloy-json-rpc 0.7.3", "alloy-primitives", "alloy-rpc-types", "alloy-rpc-types-admin", @@ -9461,31 +9893,28 @@ dependencies = [ "alloy-rpc-types-beacon", "alloy-rpc-types-debug", "alloy-rpc-types-engine", - "alloy-rpc-types-eth 0.5.4", + "alloy-rpc-types-eth 0.7.3", "alloy-rpc-types-mev", "alloy-rpc-types-trace", "alloy-rpc-types-txpool", - "alloy-serde 0.5.4", + "alloy-serde 0.7.3", "jsonrpsee", "reth-engine-primitives", "reth-network-peers", - "reth-primitives", "reth-rpc-eth-api", ] [[package]] name = "reth-rpc-builder" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-network 0.5.4", - "alloy-rpc-types", - "alloy-serde 0.5.4", - "http 1.1.0", + "http 1.2.0", "jsonrpsee", - "metrics 0.24.0", + "metrics", "pin-project", "reth-chainspec", + "reth-consensus", "reth-engine-primitives", "reth-evm", "reth-ipc", @@ -9503,7 +9932,7 @@ dependencies = [ "reth-tasks", "reth-transaction-pool", "serde", - "thiserror", + "thiserror 2.0.6", "tokio", "tokio-util", "tower 0.4.13", @@ -9513,22 +9942,24 @@ dependencies = [ [[package]] name = "reth-rpc-engine-api" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-eips 0.5.4", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rpc-types-engine", "async-trait", "jsonrpsee-core", "jsonrpsee-types", - "metrics 0.24.0", + "metrics", + "parking_lot", "reth-beacon-consensus", "reth-chainspec", "reth-engine-primitives", "reth-evm", "reth-metrics", "reth-payload-builder", + "reth-payload-builder-primitives", "reth-payload-primitives", "reth-primitives", "reth-rpc-api", @@ -9537,25 +9968,26 @@ dependencies = [ "reth-tasks", "reth-transaction-pool", "serde", - "thiserror", + "thiserror 2.0.6", "tokio", "tracing", ] [[package]] name = "reth-rpc-eth-api" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", + "alloy-consensus 0.7.3", "alloy-dyn-abi", - "alloy-eips 0.5.4", - "alloy-json-rpc 0.5.4", - "alloy-network 0.5.4", + "alloy-eips 0.7.3", + "alloy-json-rpc 0.7.3", + "alloy-network 0.7.3", "alloy-primitives", - "alloy-rpc-types", - "alloy-rpc-types-eth 0.5.4", + "alloy-rlp", + "alloy-rpc-types-eth 0.7.3", "alloy-rpc-types-mev", + "alloy-serde 0.7.3", "async-trait", "auto_impl", "dyn-clone", @@ -9566,10 +9998,10 @@ dependencies = [ "reth-chainspec", "reth-errors", "reth-evm", - "reth-execution-types", "reth-network-api", "reth-node-api", "reth-primitives", + "reth-primitives-traits", "reth-provider", "reth-revm", "reth-rpc-eth-types", @@ -9577,40 +10009,38 @@ dependencies = [ "reth-rpc-types-compat", "reth-tasks", "reth-transaction-pool", - "reth-trie", + "reth-trie-common", "revm", "revm-inspectors", - "revm-primitives 13.0.0", + "revm-primitives 14.0.0", "tokio", "tracing", ] [[package]] name = "reth-rpc-eth-types" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", - "alloy-rpc-types", - "alloy-rpc-types-eth 0.5.4", - "alloy-serde 0.5.4", + "alloy-rpc-types-eth 0.7.3", "alloy-sol-types", - "derive_more 1.0.0", + "derive_more", "futures", "itertools 0.13.0", "jsonrpsee-core", "jsonrpsee-types", - "metrics 0.24.0", + "metrics", "rand", "reth-chain-state", "reth-chainspec", "reth-errors", - "reth-evm", "reth-execution-types", "reth-metrics", "reth-primitives", + "reth-primitives-traits", "reth-revm", "reth-rpc-server-types", "reth-rpc-types-compat", @@ -9620,10 +10050,10 @@ dependencies = [ "reth-trie", "revm", "revm-inspectors", - "revm-primitives 13.0.0", + "revm-primitives 14.0.0", "schnellru", "serde", - "thiserror", + "thiserror 2.0.6", "tokio", "tokio-stream", "tracing", @@ -9631,56 +10061,58 @@ dependencies = [ [[package]] name = "reth-rpc-layer" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-rpc-types-engine", - "http 1.1.0", + "http 1.2.0", "jsonrpsee-http-client", "pin-project", "tower 0.4.13", + "tower-http", "tracing", ] [[package]] name = "reth-rpc-server-types" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rpc-types-engine", "jsonrpsee-core", "jsonrpsee-types", "reth-errors", "reth-network-api", - "reth-primitives", "serde", "strum", ] [[package]] name = "reth-rpc-types-compat" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rlp", - "alloy-rpc-types", "alloy-rpc-types-engine", - "alloy-rpc-types-eth 0.5.4", - "alloy-serde 0.5.4", + "alloy-rpc-types-eth 0.7.3", + "jsonrpsee-types", "reth-primitives", - "reth-trie-common", + "reth-primitives-traits", "serde", ] [[package]] name = "reth-stages" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "bincode", "futures-util", @@ -9710,21 +10142,22 @@ dependencies = [ "reth-trie", "reth-trie-db", "tempfile", - "thiserror", + "thiserror 2.0.6", "tokio", "tracing", ] [[package]] name = "reth-stages-api" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ + "alloy-eips 0.7.3", "alloy-primitives", "aquamarine", "auto_impl", "futures-util", - "metrics 0.24.0", + "metrics", "reth-consensus", "reth-errors", "reth-metrics", @@ -9736,15 +10169,15 @@ dependencies = [ "reth-static-file", "reth-static-file-types", "reth-tokio-util", - "thiserror", + "thiserror 2.0.6", "tokio", "tracing", ] [[package]] name = "reth-stages-types" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-primitives", "arbitrary", @@ -9757,14 +10190,16 @@ dependencies = [ [[package]] name = "reth-static-file" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-primitives", "parking_lot", "rayon", + "reth-codecs", "reth-db", "reth-db-api", + "reth-primitives-traits", "reth-provider", "reth-prune-types", "reth-stages-types", @@ -9776,62 +10211,68 @@ dependencies = [ [[package]] name = "reth-static-file-types" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-primitives", - "clap 4.5.19", - "derive_more 1.0.0", + "clap 4.5.23", + "derive_more", "serde", "strum", ] [[package]] name = "reth-storage-api" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", + "alloy-rpc-types-engine", "auto_impl", "reth-chainspec", + "reth-db", "reth-db-api", "reth-db-models", "reth-execution-types", "reth-primitives", + "reth-primitives-traits", "reth-prune-types", "reth-stages-types", "reth-storage-errors", "reth-trie", + "reth-trie-db", + "revm", ] [[package]] name = "reth-storage-errors" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-eips 0.5.4", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rlp", - "derive_more 1.0.0", + "derive_more", "reth-fs-util", - "reth-primitives", + "reth-primitives-traits", + "reth-static-file-types", ] [[package]] name = "reth-tasks" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "auto_impl", "dyn-clone", "futures-util", - "metrics 0.24.0", + "metrics", "pin-project", "rayon", "reth-metrics", - "thiserror", + "thiserror 2.0.6", "tokio", "tracing", "tracing-futures", @@ -9839,10 +10280,11 @@ dependencies = [ [[package]] name = "reth-testing-utils" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-genesis", "alloy-primitives", "rand", @@ -9852,8 +10294,8 @@ dependencies = [ [[package]] name = "reth-tokio-util" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "tokio", "tokio-stream", @@ -9862,33 +10304,33 @@ dependencies = [ [[package]] name = "reth-tracing" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "clap 4.5.19", + "clap 4.5.23", "eyre", "rolling-file", "tracing", "tracing-appender", "tracing-journald", "tracing-logfmt", - "tracing-subscriber 0.3.18", + "tracing-subscriber 0.3.19", ] [[package]] name = "reth-transaction-pool" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rlp", "aquamarine", "auto_impl", "bitflags 2.6.0", "futures-util", - "metrics 0.24.0", + "metrics", "parking_lot", "paste", "rand", @@ -9898,15 +10340,17 @@ dependencies = [ "reth-execution-types", "reth-fs-util", "reth-metrics", + "reth-payload-util", "reth-primitives", + "reth-primitives-traits", "reth-storage-api", "reth-tasks", "revm", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "schnellru", "serde", "smallvec", - "thiserror", + "thiserror 2.0.6", "tokio", "tokio-stream", "tracing", @@ -9914,15 +10358,17 @@ dependencies = [ [[package]] name = "reth-trie" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-primitives", "alloy-rlp", + "alloy-trie", "auto_impl", "itertools 0.13.0", - "metrics 0.24.0", + "metrics", "rayon", "reth-execution-errors", "reth-metrics", @@ -9930,45 +10376,47 @@ dependencies = [ "reth-stages-types", "reth-storage-errors", "reth-trie-common", + "reth-trie-sparse", "revm", - "serde", - "serde_with", "tracing", "triehash", ] [[package]] name = "reth-trie-common" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ - "alloy-consensus 0.5.4", + "alloy-consensus 0.7.3", "alloy-genesis", "alloy-primitives", "alloy-rlp", + "alloy-rpc-types-eth 0.7.3", + "alloy-serde 0.7.3", "alloy-trie", "arbitrary", "bytes", - "derive_more 1.0.0", + "derive_more", "hash-db", "itertools 0.13.0", "nybbles", "plain_hasher", "reth-codecs", "reth-primitives-traits", - "revm-primitives 13.0.0", + "revm-primitives 14.0.0", "serde", + "serde_with", ] [[package]] name = "reth-trie-db" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-primitives", "alloy-rlp", - "derive_more 1.0.0", - "metrics 0.24.0", + "derive_more", + "metrics", "reth-db", "reth-db-api", "reth-execution-errors", @@ -9976,23 +10424,21 @@ dependencies = [ "reth-primitives", "reth-storage-errors", "reth-trie", - "reth-trie-common", "revm", - "serde", "tracing", "triehash", ] [[package]] name = "reth-trie-parallel" -version = "1.1.0" -source = "git+https://github.com/paradigmxyz/reth?rev=ddc9bda#ddc9bda315c0815369794f51bc232dff0ac9f43e" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" dependencies = [ "alloy-primitives", "alloy-rlp", - "derive_more 1.0.0", + "derive_more", "itertools 0.13.0", - "metrics 0.24.0", + "metrics", "rayon", "reth-db", "reth-execution-errors", @@ -10000,34 +10446,58 @@ dependencies = [ "reth-primitives", "reth-provider", "reth-trie", + "reth-trie-common", "reth-trie-db", - "thiserror", + "thiserror 2.0.6", "tracing", ] +[[package]] +name = "reth-trie-sparse" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "reth-execution-errors", + "reth-primitives-traits", + "reth-tracing", + "reth-trie-common", + "smallvec", + "thiserror 2.0.6", +] + +[[package]] +name = "reth-zstd-compressors" +version = "1.1.4" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2e605bfba17bedcd7a6084" +dependencies = [ + "zstd", +] + [[package]] name = "revm" -version = "17.1.0" +version = "18.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "055bee6a81aaeee8c2389ae31f0d4de87f44df24f4444a1116f9755fd87a76ad" +checksum = "15689a3c6a8d14b647b4666f2e236ef47b5a5133cdfd423f545947986fff7013" dependencies = [ "auto_impl", "cfg-if", "dyn-clone", - "revm-interpreter 13.0.0", - "revm-precompile 14.0.0", + "revm-interpreter 14.0.0", + "revm-precompile 15.0.0", "serde", "serde_json", ] [[package]] name = "revm-inspectors" -version = "0.10.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e29c662f7887f3b659d4b0fd234673419a8fcbeaa1ecc29bf7034c0a75cc8ea" +checksum = "0b7f5f8a2deafb3c76f357bbf9e71b73bddb915c4994bbbe3208fbfbe8fc7f8e" dependencies = [ "alloy-primitives", - "alloy-rpc-types-eth 0.5.4", + "alloy-rpc-types-eth 0.7.3", "alloy-rpc-types-trace", "alloy-sol-types", "anstyle", @@ -10036,7 +10506,7 @@ dependencies = [ "colorchoice", "revm", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -10053,11 +10523,11 @@ dependencies = [ [[package]] name = "revm-interpreter" -version = "13.0.0" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fac2034454f8bc69dc7d3c94cdb1b57559e27f5ef0518771f1787de543d7d6a1" +checksum = "74e3f11d0fed049a4a10f79820c59113a79b38aed4ebec786a79d5c667bfeb51" dependencies = [ - "revm-primitives 13.0.0", + "revm-primitives 14.0.0", "serde", ] @@ -10082,9 +10552,9 @@ dependencies = [ [[package]] name = "revm-precompile" -version = "14.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a88c8c7c5f9b988a9e65fc0990c6ce859cdb74114db705bd118a96d22d08027" +checksum = "e381060af24b750069a2b2d2c54bba273d84e8f5f9e8026fc9262298e26cc336" dependencies = [ "aurora-engine-modexp", "blst", @@ -10093,7 +10563,7 @@ dependencies = [ "k256", "once_cell", "p256", - "revm-primitives 13.0.0", + "revm-primitives 14.0.0", "ripemd", "secp256k1", "sha2 0.10.8", @@ -10122,12 +10592,12 @@ dependencies = [ [[package]] name = "revm-primitives" -version = "13.0.0" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d11fa1e195b0bebaf3fb18596f314a13ba3a4cb1fdd16d3465934d812fd921e" +checksum = "3702f132bb484f4f0d0ca4f6fbde3c82cfd745041abbedd6eda67730e1868ef0" dependencies = [ "alloy-eip2930", - "alloy-eip7702 0.3.2", + "alloy-eip7702 0.4.2", "alloy-primitives", "auto_impl", "bitflags 2.6.0", @@ -10265,9 +10735,9 @@ dependencies = [ [[package]] name = "roaring" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4b84ba6e838ceb47b41de5194a60244fac43d9fe03b71dbe8c5a201081d6d1" +checksum = "395b0c39c00f9296f3937624c1fa4e0ee44f8c0e4b2c49408179ef381c6c2e6e" dependencies = [ "bytemuck", "byteorder", @@ -10334,9 +10804,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" dependencies = [ "rand", ] @@ -10367,22 +10837,22 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "rustls" -version = "0.23.14" +version = "0.23.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8" +checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" dependencies = [ "log", "once_cell", @@ -10403,20 +10873,19 @@ dependencies = [ "rustls-pemfile 2.2.0", "rustls-pki-types", "schannel", - "security-framework", + "security-framework 2.11.1", ] [[package]] name = "rustls-native-certs" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a" +checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" dependencies = [ "openssl-probe", - "rustls-pemfile 2.2.0", "rustls-pki-types", "schannel", - "security-framework", + "security-framework 3.0.1", ] [[package]] @@ -10439,9 +10908,12 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" +dependencies = [ + "web-time", +] [[package]] name = "rustls-platform-verifier" @@ -10449,7 +10921,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afbb878bdfdf63a336a5e63561b1835e7a8c91524f51621db870169eac84b490" dependencies = [ - "core-foundation", + "core-foundation 0.9.4", "core-foundation-sys", "jni", "log", @@ -10458,7 +10930,7 @@ dependencies = [ "rustls-native-certs 0.7.3", "rustls-platform-verifier-android", "rustls-webpki", - "security-framework", + "security-framework 2.11.1", "security-framework-sys", "webpki-roots", "winapi", @@ -10483,9 +10955,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "rusty-fork" @@ -10535,42 +11007,42 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.11.3" +version = "2.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" +checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b" dependencies = [ "cfg-if", - "derive_more 0.99.18", + "derive_more", "parity-scale-codec", "scale-info-derive", ] [[package]] name = "scale-info-derive" -version = "2.11.3" +version = "2.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" +checksum = "c6630024bf739e2179b91fb424b28898baf819414262c5d376677dbff1fe7ebf" dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.90", ] [[package]] name = "scc" -version = "2.2.0" +version = "2.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836f1e0f4963ef5288b539b643b35e043e76a32d0f4e47e67febf69576527f50" +checksum = "66b202022bb57c049555430e11fc22fea12909276a80a4c3d368da36ac1d88ed" dependencies = [ "sdd", ] [[package]] name = "schannel" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ "windows-sys 0.59.0", ] @@ -10597,7 +11069,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -10625,9 +11097,9 @@ checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152" [[package]] name = "sdd" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a7b59a5d9b0099720b417b6325d91a52cbf5b3dcb5041d864be53eefa58abc" +checksum = "49c1eeaf4b6a87c7479688c6d52b9f1153cedd3c489300564f932b065c6eab95" [[package]] name = "seahash" @@ -10676,18 +11148,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags 2.6.0", - "core-foundation", + "core-foundation 0.9.4", "core-foundation-sys", "libc", "num-bigint", "security-framework-sys", ] +[[package]] +name = "security-framework" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1415a607e92bec364ea2cf9264646dcce0f91e6d65281bd6f2819cca3bf39c8" +dependencies = [ + "bitflags 2.6.0", + "core-foundation 0.10.0", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + [[package]] name = "security-framework-sys" -version = "2.12.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" +checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" dependencies = [ "core-foundation-sys", "libc", @@ -10695,9 +11180,9 @@ dependencies = [ [[package]] name = "self_cell" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a" +checksum = "c2fdfc24bc566f839a2da4c4295b82db7d25a24253867d5c64355abb5799bdbe" [[package]] name = "semaphore" @@ -10735,7 +11220,7 @@ dependencies = [ "serde", "sha2 0.10.8", "storage", - "thiserror", + "thiserror 1.0.69", "tiny-keccak", "trees", "witness", @@ -10756,7 +11241,7 @@ dependencies = [ "proc-macro2", "quote", "semaphore-depth-config", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -10779,9 +11264,9 @@ dependencies = [ [[package]] name = "semver-parser" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +checksum = "9900206b54a3527fdc7b8a938bffd94a568bac4f4aa8113b209df75a09c0dec2" dependencies = [ "pest", ] @@ -10800,9 +11285,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.210" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" dependencies = [ "serde_derive", ] @@ -10830,13 +11315,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -10847,16 +11332,16 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "itoa", "memchr", "ryu", @@ -10871,7 +11356,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -10905,7 +11390,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.6.0", + "indexmap 2.7.0", "serde", "serde_derive", "serde_json", @@ -10922,7 +11407,7 @@ dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -10931,7 +11416,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "itoa", "ryu", "serde", @@ -10940,9 +11425,9 @@ dependencies = [ [[package]] name = "serial_test" -version = "3.1.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b4b487fe2acf240a021cf57c6b2b4903b1e78ca0ecd862a71b71d2a51fed77d" +checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9" dependencies = [ "futures", "log", @@ -10954,13 +11439,13 @@ dependencies = [ [[package]] name = "serial_test_derive" -version = "3.1.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82fe9db325bcef1fbcde82e078a5cc4efdf787e96b3b9cf45b50b529f2083d67" +checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -11069,7 +11554,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" dependencies = [ "libc", - "mio 1.0.2", + "mio 1.0.3", "signal-hook", ] @@ -11127,7 +11612,7 @@ checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" dependencies = [ "num-bigint", "num-traits", - "thiserror", + "thiserror 1.0.69", "time", ] @@ -11197,9 +11682,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", "windows-sys 0.52.0", @@ -11207,14 +11692,14 @@ dependencies = [ [[package]] name = "soketto" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37468c595637c10857701c990f93a40ce0e357cedb0953d1c26c8d8027f9bb53" +checksum = "2e859df029d160cb88608f5d7df7fb4753fd20fdfb4de5644f3d8b8440841721" dependencies = [ "base64 0.22.1", "bytes", "futures", - "http 1.1.0", + "http 1.2.0", "httparse", "log", "rand", @@ -11300,7 +11785,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -11335,9 +11820,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.79" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -11346,14 +11831,14 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.8.6" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a850d65181df41b83c6be01a7d91f5e9377c43d48faa5af7d95816f437f5a3" +checksum = "219389c1ebe89f8333df8bdfb871f6631c552ff399c23cac02480b6088aad8f0" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -11364,9 +11849,9 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "sync_wrapper" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" dependencies = [ "futures-core", ] @@ -11379,7 +11864,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -11392,15 +11877,15 @@ dependencies = [ "byteorder", "enum-as-inner", "libc", - "thiserror", + "thiserror 1.0.69", "walkdir", ] [[package]] name = "sysinfo" -version = "0.31.4" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "355dbe4f8799b304b05e1b0f05fc59b2a18d36645cf169607da45bde2f69a1be" +checksum = "4c33cd241af0f2e9e3b5c32163b873b29956890b5342e6745b917ce9d490f4af" dependencies = [ "core-foundation-sys", "libc", @@ -11416,7 +11901,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", "system-configuration-sys 0.5.0", ] @@ -11427,7 +11912,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ "bitflags 2.6.0", - "core-foundation", + "core-foundation 0.9.4", "system-configuration-sys 0.6.0", ] @@ -11451,6 +11936,12 @@ dependencies = [ "libc", ] +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + [[package]] name = "tap" version = "1.0.1" @@ -11459,9 +11950,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.42" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ff6c40d3aedb5e06b57c6f669ad17ab063dd1e63d977c6a88e7f4dfa4f04020" +checksum = "c65998313f8e17d0d553d28f91a0df93e4dbbbf770279c7bc21ca0f09ea1a1f6" dependencies = [ "filetime", "libc", @@ -11476,9 +11967,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tempfile" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", @@ -11533,7 +12024,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -11544,7 +12035,7 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", "test-case-core", ] @@ -11554,7 +12045,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ - "unicode-width", + "unicode-width 0.1.14", ] [[package]] @@ -11565,42 +12056,42 @@ checksum = "a38c90d48152c236a3ab59271da4f4ae63d678c5d7ad6b7714d7cb9760be5e4b" [[package]] name = "thiserror" -version = "1.0.64" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", ] [[package]] -name = "thiserror-impl" -version = "1.0.64" +name = "thiserror" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "8fec2a1820ebd077e2b90c4df007bebf344cd394098a13c563957d0afc83ea47" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.79", + "thiserror-impl 2.0.6", ] [[package]] -name = "thiserror-impl-no-std" -version = "2.0.2" +name = "thiserror-impl" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58e6318948b519ba6dc2b442a6d0b904ebfb8d411a3ad3e07843615a72249758" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.90", ] [[package]] -name = "thiserror-no-std" -version = "2.0.2" +name = "thiserror-impl" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3ad459d94dd517257cc96add8a43190ee620011bb6e6cdc82dafd97dfafafea" +checksum = "d65750cab40f4ff1929fb1ba509e9914eb756131cef4210da8d5d700d26f6312" dependencies = [ - "thiserror-impl-no-std", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] @@ -11666,9 +12157,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", "itoa", @@ -11690,9 +12181,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" dependencies = [ "num-conv", "time-core", @@ -11744,18 +12235,18 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.40.0" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ "backtrace", "bytes", "libc", - "mio 1.0.2", + "mio 1.0.3", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.7", + "socket2 0.5.8", "tokio-macros", "windows-sys 0.52.0", ] @@ -11768,7 +12259,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -11783,12 +12274,11 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" dependencies = [ "rustls", - "rustls-pki-types", "tokio", ] @@ -11800,15 +12290,15 @@ checksum = "0d4770b8024672c1101b3f6733eab95b18007dbe0847a8afe341fcf79e06043f" dependencies = [ "either", "futures-util", - "thiserror", + "thiserror 1.0.69", "tokio", ] [[package]] name = "tokio-stream" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" dependencies = [ "futures-core", "pin-project-lite", @@ -11834,9 +12324,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.12" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" dependencies = [ "bytes", "futures-core", @@ -11874,7 +12364,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "toml_datetime", "winnow 0.5.40", ] @@ -11885,7 +12375,7 @@ version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "serde", "serde_spanned", "toml_datetime", @@ -11902,12 +12392,12 @@ dependencies = [ "alloy-rlp", "bytes", "chrono", - "clap 4.5.19", + "clap 4.5.23", "color-eyre", "dotenvy", "hex", "rand", - "reqwest 0.12.8", + "reqwest 0.12.9", "semaphore", "serde", "serde_json", @@ -11938,31 +12428,31 @@ dependencies = [ [[package]] name = "tower" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", "pin-project-lite", - "sync_wrapper 0.1.2", + "sync_wrapper 1.0.2", "tower-layer", "tower-service", ] [[package]] name = "tower-http" -version = "0.5.2" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" +checksum = "403fa3b783d4b626a8ad51d766ab03cb6d2dbfc46b1c5d4448395e6628dc9697" dependencies = [ "async-compression", - "base64 0.21.7", + "base64 0.22.1", "bitflags 2.6.0", "bytes", "futures-core", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", "http-body-util", "http-range-header", @@ -11974,7 +12464,7 @@ dependencies = [ "pin-project-lite", "tokio", "tokio-util", - "tower 0.4.13", + "tower 0.5.2", "tower-layer", "tower-service", "tracing", @@ -11995,9 +12485,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "log", "pin-project-lite", @@ -12012,27 +12502,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" dependencies = [ "crossbeam-channel", - "thiserror", + "thiserror 1.0.69", "time", - "tracing-subscriber 0.3.18", + "tracing-subscriber 0.3.19", ] [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -12040,12 +12530,12 @@ dependencies = [ [[package]] name = "tracing-error" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db" dependencies = [ "tracing", - "tracing-subscriber 0.3.18", + "tracing-subscriber 0.3.19", ] [[package]] @@ -12060,13 +12550,13 @@ dependencies = [ [[package]] name = "tracing-journald" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba316a74e8fc3c3896a850dba2375928a9fa171b085ecddfc7c054d39970f3fd" +checksum = "fc0b4143302cf1022dac868d521e36e8b27691f72c84b3311750d5188ebba657" dependencies = [ "libc", "tracing-core", - "tracing-subscriber 0.3.18", + "tracing-subscriber 0.3.19", ] [[package]] @@ -12089,14 +12579,14 @@ dependencies = [ "time", "tracing", "tracing-core", - "tracing-subscriber 0.3.18", + "tracing-subscriber 0.3.19", ] [[package]] name = "tracing-serde" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" dependencies = [ "serde", "tracing-core", @@ -12113,9 +12603,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", "nu-ansi-term", @@ -12157,7 +12647,7 @@ dependencies = [ "ruint", "serde", "storage", - "thiserror", + "thiserror 1.0.69", "tiny-keccak", ] @@ -12172,51 +12662,10 @@ dependencies = [ ] [[package]] -name = "trust-dns-proto" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3119112651c157f4488931a01e586aa459736e9d6046d3bd9105ffb69352d374" -dependencies = [ - "async-trait", - "cfg-if", - "data-encoding", - "enum-as-inner", - "futures-channel", - "futures-io", - "futures-util", - "idna 0.4.0", - "ipnet", - "once_cell", - "rand", - "smallvec", - "thiserror", - "tinyvec", - "tokio", - "tracing", - "url", -] - -[[package]] -name = "trust-dns-resolver" -version = "0.23.2" +name = "triomphe" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a3e6c3aff1718b3c73e395d1f35202ba2ffa847c6a62eea0db8fb4cfe30be6" -dependencies = [ - "cfg-if", - "futures-util", - "ipconfig", - "lru-cache", - "once_cell", - "parking_lot", - "rand", - "resolv-conf", - "serde", - "smallvec", - "thiserror", - "tokio", - "tracing", - "trust-dns-proto", -] +checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" [[package]] name = "try-lock" @@ -12233,14 +12682,14 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 1.1.0", + "http 1.2.0", "httparse", "log", "rand", "rustls", "rustls-pki-types", "sha1", - "thiserror", + "thiserror 1.0.69", "utf-8", ] @@ -12298,24 +12747,15 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicase" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.17" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" +checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-normalization" @@ -12340,7 +12780,7 @@ checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf" dependencies = [ "itertools 0.13.0", "unicode-segmentation", - "unicode-width", + "unicode-width 0.1.14", ] [[package]] @@ -12349,6 +12789,12 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + [[package]] name = "unicode-xid" version = "0.2.6" @@ -12371,12 +12817,6 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" -[[package]] -name = "unsigned-varint" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" - [[package]] name = "unsigned-varint" version = "0.8.0" @@ -12391,12 +12831,12 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.2" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", - "idna 0.5.0", + "idna", "percent-encoding", "serde", ] @@ -12433,9 +12873,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" dependencies = [ "getrandom", ] @@ -12495,7 +12935,7 @@ dependencies = [ "replace_with", "shared-buffer", "slab", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", "webc", @@ -12514,7 +12954,7 @@ dependencies = [ "mio 0.8.11", "serde", "socket2 0.4.10", - "thiserror", + "thiserror 1.0.69", "tracing", ] @@ -12539,7 +12979,7 @@ dependencies = [ "serde", "smoltcp", "socket2 0.4.10", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", "virtual-mio", @@ -12553,7 +12993,7 @@ checksum = "d674d135b4a8c1d7e813e2f8d1c9a58308aee4a680323066025e53132218bd91" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -12664,9 +13104,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", "once_cell", @@ -12675,36 +13115,36 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.43" +version = "0.4.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -12712,22 +13152,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "wasm-encoder" @@ -12740,9 +13180,9 @@ dependencies = [ [[package]] name = "wasm-streams" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e072d4e72f700fb3443d8fe94a39315df013eef1104903cdb0a2abd322bbecd" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" dependencies = [ "futures-util", "js-sys", @@ -12768,7 +13208,7 @@ dependencies = [ "serde-wasm-bindgen", "shared-buffer", "target-lexicon", - "thiserror", + "thiserror 1.0.69", "tracing", "wasm-bindgen", "wasmer-compiler", @@ -12801,7 +13241,7 @@ dependencies = [ "self_cell", "shared-buffer", "smallvec", - "thiserror", + "thiserror 1.0.69", "wasmer-types", "wasmer-vm", "wasmparser", @@ -12839,13 +13279,13 @@ dependencies = [ "ciborium", "derive_builder", "hex", - "indexmap 2.6.0", + "indexmap 2.7.0", "schemars", "semver 1.0.23", "serde", "serde_json", "serde_yaml", - "thiserror", + "thiserror 1.0.69", "toml", "url", ] @@ -12881,7 +13321,7 @@ dependencies = [ "serde", "serde_json", "shared-buffer", - "thiserror", + "thiserror 1.0.69", "tracing", "virtual-fs", "virtual-net", @@ -12906,7 +13346,7 @@ dependencies = [ "serde", "sha2 0.10.8", "target-lexicon", - "thiserror", + "thiserror 1.0.69", "xxhash-rust", ] @@ -12933,7 +13373,7 @@ dependencies = [ "more-asserts 0.2.2", "region", "scopeguard", - "thiserror", + "thiserror 1.0.69", "wasmer-types", "windows-sys 0.59.0", ] @@ -12960,7 +13400,7 @@ dependencies = [ "getrandom", "heapless", "hex", - "http 1.1.0", + "http 1.2.0", "lazy_static 1.5.0", "libc", "linked_hash_set", @@ -12971,7 +13411,7 @@ dependencies = [ "pin-project", "pin-utils", "rand", - "reqwest 0.12.8", + "reqwest 0.12.9", "rkyv", "rusty_pool", "semver 1.0.23", @@ -12984,7 +13424,7 @@ dependencies = [ "tempfile", "terminal_size", "termios", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "toml", @@ -13037,15 +13477,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dbe55c8f9d0dbd25d9447a5a889ff90c0cc3feaa7395310d3d826b2c703eaab" dependencies = [ "bitflags 2.6.0", - "indexmap 2.6.0", + "indexmap 2.7.0", "semver 1.0.23", ] [[package]] name = "wasmtimer" -version = "0.2.1" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7ed9d8b15c7fb594d72bfb4b5a276f3d2029333cd93a932f376f5937f6f80ee" +checksum = "0048ad49a55b9deb3953841fa1fc5858f0efbcb7a18868c899a360269fac1b23" dependencies = [ "futures", "js-sys", @@ -13063,7 +13503,7 @@ checksum = "a259b226fd6910225aa7baeba82f9d9933b6d00f2ce1b49b80fa4214328237cc" dependencies = [ "leb128", "memchr", - "unicode-width", + "unicode-width 0.1.14", "wasm-encoder", ] @@ -13078,9 +13518,19 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.70" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", @@ -13114,7 +13564,7 @@ dependencies = [ "shared-buffer", "tar", "tempfile", - "thiserror", + "thiserror 1.0.69", "toml", "url", "wasmer-config", @@ -13122,9 +13572,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.6" +version = "0.26.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" +checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" dependencies = [ "rustls-pki-types", ] @@ -13191,6 +13641,16 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-core" version = "0.52.0" @@ -13206,12 +13666,25 @@ version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" dependencies = [ - "windows-implement", - "windows-interface", + "windows-implement 0.57.0", + "windows-interface 0.57.0", "windows-result 0.1.2", "windows-targets 0.52.6", ] +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings", + "windows-targets 0.52.6", +] + [[package]] name = "windows-implement" version = "0.57.0" @@ -13220,7 +13693,18 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] @@ -13231,7 +13715,18 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] @@ -13516,23 +14011,23 @@ dependencies = [ name = "world-chain-builder" version = "0.1.0" dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", "alloy-genesis", - "alloy-network 0.5.4", + "alloy-network 0.7.3", "alloy-primitives", "alloy-rlp", "alloy-rpc-types", - "alloy-rpc-types-eth 0.5.4", + "alloy-rpc-types-eth 0.7.3", "alloy-signer 0.5.4", - "alloy-signer-local", + "alloy-signer-local 0.5.4", "bytemuck", "bytes", "chrono", - "clap 4.5.19", + "clap 4.5.23", "color-eyre", "criterion 0.5.1", - "derive_more 1.0.0", + "derive_more", "dotenvy", "ethers-core 2.0.14 (git+https://github.com/gakonst/ethers-rs)", "futures", @@ -13561,6 +14056,7 @@ dependencies = [ "reth-optimism-forks", "reth-optimism-node", "reth-optimism-payload-builder", + "reth-optimism-primitives", "reth-optimism-rpc", "reth-primitives", "reth-provider", @@ -13568,11 +14064,12 @@ dependencies = [ "reth-stages-types", "reth-tracing", "reth-trie", + "reth-trie-db", "revm", "revm-inspectors", "revm-interpreter 10.0.3", "revm-precompile 11.0.3", - "revm-primitives 13.0.0", + "revm-primitives 14.0.0", "semaphore", "serde", "serde_json", @@ -13581,7 +14078,7 @@ dependencies = [ "strum_macros", "tempfile", "test-case", - "thiserror", + "thiserror 1.0.69", "tikv-jemallocator", "tokio", "tracing", @@ -13612,7 +14109,7 @@ dependencies = [ "pharos", "rustc_version 0.4.1", "send_wrapper 0.6.0", - "thiserror", + "thiserror 1.0.69", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -13652,9 +14149,9 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "yoke" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ "serde", "stable_deref_trait", @@ -13664,13 +14161,13 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", "synstructure", ] @@ -13692,27 +14189,27 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] name = "zerofrom" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", "synstructure", ] @@ -13733,7 +14230,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -13755,7 +14252,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] diff --git a/world-chain-builder/Cargo.toml b/world-chain-builder/Cargo.toml index 52be3af1..9b69c998 100644 --- a/world-chain-builder/Cargo.toml +++ b/world-chain-builder/Cargo.toml @@ -10,63 +10,65 @@ members = ["crates/*"] [dependencies] # reth -reth = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } -reth-cli-util = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } -reth-evm = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } -reth-db = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } -reth-db-api = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } -reth-provider = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda", features = [ +reth = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-cli-util = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-evm = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-db = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-db-api = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-provider = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4", features = [ "test-utils", ] } -reth-basic-payload-builder = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } -reth-prune-types = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } -reth-trie = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } -reth-chain-state = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } -reth-eth-wire-types = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } -reth-stages-types = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } +reth-basic-payload-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-prune-types = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-trie = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-chain-state = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-eth-wire-types = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-stages-types = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-trie-db = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } # reth-optimism -reth-primitives = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda", features = [ +reth-primitives = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4", features = [ "optimism", ] } -reth-optimism-evm = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda", features = [ +reth-optimism-evm = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4", features = [ "optimism", ] } -reth-optimism-node = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda", features = [ +reth-optimism-node = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4", features = [ "optimism", ] } -reth-optimism-cli = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda", features = [ +reth-optimism-cli = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4", features = [ "optimism", ] } -reth-optimism-rpc = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda", features = [ +reth-optimism-rpc = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4", features = [ "optimism", ] } -reth-optimism-consensus = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda", features = [ +reth-optimism-consensus = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4", features = [ "optimism", ] } -reth-optimism-chainspec = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } -reth-optimism-payload-builder = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } -reth-optimism-forks = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } +reth-optimism-chainspec = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-optimism-payload-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-optimism-forks = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-optimism-primitives = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } # alloy -op-alloy-consensus = "0.5" -op-alloy-rpc-types = "0.5" -op-alloy-network = "0.5" -alloy-consensus = { version = "0.5.4", default-features = false } -alloy-network = { version = "0.5.4", default-features = false } -alloy-primitives = { version = "0.8.9", default-features = false } -alloy-rpc-types-eth = { version = "0.5.4", default-features = false } -alloy-rpc-types = { version = "0.5.4", features = [ +op-alloy-consensus = "0.7.3" +op-alloy-rpc-types = "0.7.3" +op-alloy-network = "0.7.3" +alloy-consensus = { version = "0.7.3", default-features = false } +alloy-network = { version = "0.7.3", default-features = false } +alloy-primitives = { version = "0.8.11", default-features = false } +alloy-rpc-types-eth = { version = "0.7.3", default-features = false } +alloy-rpc-types = { version = "0.7.3", features = [ "eth", ], default-features = false } -alloy-rlp = "0.3.4" -alloy-eips = { version = "0.5.4", default-features = false } -alloy-genesis = { version = "0.5.4", default-features = false } +alloy-rlp = "0.3.10" +alloy-eips = { version = "0.7.3", default-features = false } +alloy-genesis = { version = "0.7.3", default-features = false } # revm -revm = { version = "17.0.0", features = ["std"], default-features = false } -revm-inspectors = "0.10.0" -revm-primitives = { version = "13.0.0", features = [ +revm = { version = "18.0.0", features = ["std"], default-features = false } +revm-inspectors = "0.12.0" +revm-primitives = { version = "14.0.0", features = [ "std", ], default-features = false } revm-interpreter = "10" @@ -105,10 +107,10 @@ ethers-core = { git = "https://github.com/gakonst/ethers-rs", default-features = alloy-primitives = "0.8" serde_json = "1" rand = "0.8" -reth-e2e-test-utils = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } -reth-consensus = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } -reth-node-core = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } -reth-tracing = { git = "https://github.com/paradigmxyz/reth", rev = "ddc9bda" } +reth-e2e-test-utils = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4"} +reth-consensus = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-node-core = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-tracing = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } alloy-signer = { version = "0.5.4", default-features = false } alloy-signer-local = { version = "0.5.4", default-features = false } @@ -121,4 +123,4 @@ path = "bin/world-chain-builder.rs" [[bench]] name = "validate_transaction" -harness = false +harness = false \ No newline at end of file From c348ea09d2ba7be0f5402a9a74da0d5eb057e7a6 Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Thu, 12 Dec 2024 14:07:42 -0700 Subject: [PATCH 16/59] wip --- world-chain-builder/src/node/builder.rs | 156 ++-- world-chain-builder/src/node/test_utils.rs | 93 ++- world-chain-builder/src/pool/builder.rs | 3 +- world-chain-builder/src/pool/noop.rs | 41 +- world-chain-builder/src/pool/root.rs | 170 ++-- world-chain-builder/src/pool/tx.rs | 223 ++++-- world-chain-builder/src/pool/validator.rs | 536 ++++++------- world-chain-builder/src/primitives.rs | 178 ++--- world-chain-builder/src/rpc/block.rs | 46 -- world-chain-builder/src/rpc/bundle.rs | 24 +- world-chain-builder/src/rpc/call.rs | 43 - world-chain-builder/src/rpc/mod.rs | 269 ------- world-chain-builder/src/rpc/pending_block.rs | 51 -- world-chain-builder/src/rpc/receipt.rs | 26 - world-chain-builder/src/rpc/transaction.rs | 71 -- world-chain-builder/src/test/e2e/mod.rs | 792 +++++++++---------- 16 files changed, 1166 insertions(+), 1556 deletions(-) delete mode 100644 world-chain-builder/src/rpc/block.rs delete mode 100644 world-chain-builder/src/rpc/call.rs delete mode 100644 world-chain-builder/src/rpc/pending_block.rs delete mode 100644 world-chain-builder/src/rpc/receipt.rs delete mode 100644 world-chain-builder/src/rpc/transaction.rs diff --git a/world-chain-builder/src/node/builder.rs b/world-chain-builder/src/node/builder.rs index cfc1b28c..e40ddfd7 100644 --- a/world-chain-builder/src/node/builder.rs +++ b/world-chain-builder/src/node/builder.rs @@ -1,25 +1,27 @@ use std::{path::Path, sync::Arc}; use eyre::eyre::Result; -use reth::api::{EngineValidator, FullNodeComponents, NodeAddOns}; -use reth::builder::rpc::{RethRpcAddOns, RpcAddOns, RpcHandle, RpcHooks}; -use reth::builder::AddOnsContext; +use reth::builder::components::{ConsensusBuilder, ExecutorBuilder, NetworkBuilder, PoolBuilder}; use reth::builder::{ components::ComponentsBuilder, FullNodeTypes, Node, NodeTypes, NodeTypesWithEngine, }; use reth::builder::{NodeAdapter, NodeComponentsBuilder}; -use reth::rpc::eth::FullEthApiServer; +use reth::transaction_pool::blobstore::DiskFileBlobStore; +use reth::transaction_pool::{Pool, TransactionValidationTaskExecutor}; use reth_db::DatabaseEnv; use reth_optimism_chainspec::OpChainSpec; -use reth_optimism_node::engine::OptimismEngineValidator; -use reth_optimism_node::node::{OpPrimitives, OptimismEngineValidatorBuilder}; -use reth_optimism_node::{ - args::RollupArgs, - node::{OptimismConsensusBuilder, OptimismExecutorBuilder, OptimismNetworkBuilder}, - OptimismEngineTypes, +use reth_optimism_node::args::RollupArgs; +use reth_optimism_node::node::{ + OpAddOns, OpConsensusBuilder, OpExecutorBuilder, OpNetworkBuilder, OpStorage, }; - -use crate::rpc::WorldChainEthApi; +use reth_optimism_node::OpEngineTypes; +use reth_optimism_payload_builder::config::OpDAConfig; +use reth_optimism_primitives::OpPrimitives; +use reth_trie_db::MerklePatriciaTrie; + +use crate::pool::ordering::WorldChainOrdering; +use crate::pool::tx::WorldChainPooledTransaction; +use crate::pool::validator::WorldChainTransactionValidator; use crate::{ payload::builder::WorldChainPayloadServiceBuilder, pbh::db::load_world_chain_db, pool::builder::WorldChainPoolBuilder, @@ -31,6 +33,13 @@ use super::args::{ExtArgs, WorldChainBuilderArgs}; pub struct WorldChainBuilder { /// Additional Optimism args pub args: ExtArgs, + /// Data availability configuration for the OP builder. + /// + /// Used to throttle the size of the data availability payloads (configured by the batcher via + /// the `miner_` api). + /// + /// By default no throttling is applied. + pub da_config: OpDAConfig, /// The World Chain database pub db: Arc, } @@ -38,7 +47,17 @@ pub struct WorldChainBuilder { impl WorldChainBuilder { pub fn new(args: ExtArgs, data_dir: &Path) -> Result { let db = load_world_chain_db(data_dir, args.builder_args.clear_nullifiers)?; - Ok(Self { args, db }) + Ok(Self { + args, + db, + da_config: OpDAConfig::default(), + }) + } + + /// Configure the data availability configuration for the OP builder. + pub fn with_da_config(mut self, da_config: OpDAConfig) -> Self { + self.da_config = da_config; + self } /// Returns the components for the given [`RollupArgs`]. @@ -49,14 +68,30 @@ impl WorldChainBuilder { Node, WorldChainPoolBuilder, WorldChainPayloadServiceBuilder, - OptimismNetworkBuilder, - OptimismExecutorBuilder, - OptimismConsensusBuilder, + OpNetworkBuilder, + OpExecutorBuilder, + OpConsensusBuilder, > where Node: FullNodeTypes< - Types: NodeTypesWithEngine, + Types: NodeTypesWithEngine, + >, + OpNetworkBuilder: NetworkBuilder< + Node, + Pool< + TransactionValidationTaskExecutor< + WorldChainTransactionValidator< + ::Provider, + WorldChainPooledTransaction, + >, + >, + WorldChainOrdering, + DiskFileBlobStore, + >, >, + OpExecutorBuilder: ExecutorBuilder, + OpConsensusBuilder: ConsensusBuilder, + WorldChainPoolBuilder: PoolBuilder, { let WorldChainBuilderArgs { clear_nullifiers, @@ -83,96 +118,63 @@ impl WorldChainBuilder { verified_blockspace_capacity, db.clone(), )) - .network(OptimismNetworkBuilder { + .network(OpNetworkBuilder { disable_txpool_gossip, disable_discovery_v4: !discovery_v4, }) - .executor(OptimismExecutorBuilder::default()) - .consensus(OptimismConsensusBuilder::default()) + .executor(OpExecutorBuilder::default()) + .consensus(OpConsensusBuilder::default()) } } impl Node for WorldChainBuilder where N: FullNodeTypes< - Types: NodeTypesWithEngine, + Types: NodeTypesWithEngine< + Engine = OpEngineTypes, + ChainSpec = OpChainSpec, + Primitives = OpPrimitives, + Storage = OpStorage, + >, >, { type ComponentsBuilder = ComponentsBuilder< N, WorldChainPoolBuilder, WorldChainPayloadServiceBuilder, - OptimismNetworkBuilder, - OptimismExecutorBuilder, - OptimismConsensusBuilder, + OpNetworkBuilder, + OpExecutorBuilder, + OpConsensusBuilder, >; - type AddOns = WorldChainAddOns< - NodeAdapter>::Components>, - >; + type AddOns = + OpAddOns>::Components>>; fn components_builder(&self) -> Self::ComponentsBuilder { - let Self { args, db } = self; + let Self { args, db, .. } = self; Self::components(args.clone(), db.clone()) } fn add_ons(&self) -> Self::AddOns { - WorldChainAddOns::new(self.args.rollup_args.sequencer_http.clone()) + let Self { + args, + db, + da_config, + } = self; + Self::AddOns::builder() + .with_sequencer(args.rollup_args.sequencer_http.clone()) + .with_da_config(da_config.clone()) + .build() } } impl NodeTypes for WorldChainBuilder { + type Storage = OpStorage; type Primitives = OpPrimitives; type ChainSpec = OpChainSpec; + type StateCommitment = MerklePatriciaTrie; } impl NodeTypesWithEngine for WorldChainBuilder { - type Engine = OptimismEngineTypes; -} - -#[derive(Debug)] -pub struct WorldChainAddOns( - pub RpcAddOns, OptimismEngineValidatorBuilder>, -); - -impl Default for WorldChainAddOns { - fn default() -> Self { - Self::new(Default::default()) - } -} - -impl WorldChainAddOns { - /// Create a new instance with the given `sequencer_http` URL. - pub fn new(sequencer_http: Option) -> Self { - Self(RpcAddOns::new( - move |ctx| WorldChainEthApi::new(ctx, sequencer_http), - Default::default(), - )) - } -} - -impl NodeAddOns for WorldChainAddOns -where - N: FullNodeComponents>, - OptimismEngineValidator: EngineValidator<::Engine>, - WorldChainEthApi: FullEthApiServer, -{ - type Handle = RpcHandle>; - - async fn launch_add_ons(self, ctx: AddOnsContext<'_, N>) -> eyre::Result { - self.0.launch_add_ons(ctx).await - } -} - -impl RethRpcAddOns for WorldChainAddOns -where - N: FullNodeComponents>, - OptimismEngineValidator: EngineValidator<::Engine>, - WorldChainEthApi: FullEthApiServer, -{ - type EthApi = WorldChainEthApi; - - fn hooks_mut(&mut self) -> &mut RpcHooks { - self.0.hooks_mut() - } + type Engine = OpEngineTypes; } diff --git a/world-chain-builder/src/node/test_utils.rs b/world-chain-builder/src/node/test_utils.rs index e0b8c88f..bdb6aea6 100644 --- a/world-chain-builder/src/node/test_utils.rs +++ b/world-chain-builder/src/node/test_utils.rs @@ -1,11 +1,13 @@ -use alloy_eips::{BlockHashOrNumber, BlockId, BlockNumberOrTag}; +use alloy_eips::{BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag}; use alloy_primitives::{ map::{HashMap, HashSet}, Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, TxHash, TxNumber, B256, U256, }; +use alloy_rpc_types::{Withdrawal, Withdrawals}; use futures::future::join_all; use reth::api::ConfigureEvmEnv; use reth::chainspec::{ChainInfo, MAINNET}; +use reth::revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg}; use reth::transaction_pool::{ validate::ValidTransaction, TransactionOrigin, TransactionValidationOutcome, TransactionValidator, @@ -17,24 +19,23 @@ use reth_chain_state::{ use reth_db::models::{AccountBeforeTx, StoredBlockBodyIndices}; use reth_optimism_chainspec::OpChainSpec; use reth_primitives::{ - Account, Block, BlockWithSenders, Bytecode, Header, Receipt, SealedBlock, + Account, Block, BlockWithSenders, Bytecode, EthPrimitives, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, TransactionMeta, TransactionSigned, - TransactionSignedNoHash, Withdrawal, Withdrawals, }; use reth_provider::{ providers::StaticFileProvider, AccountReader, BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt, BlockSource, ChainSpecProvider, ChangeSetReader, EvmEnvProvider, - HeaderProvider, ProviderError, ProviderResult, PruneCheckpointReader, ReceiptProvider, - ReceiptProviderIdExt, StateProofProvider, StateProvider, StateProviderBox, - StateProviderFactory, StateRootProvider, StaticFileProviderFactory, StorageRootProvider, - TransactionVariant, TransactionsProvider, WithdrawalsProvider, + HashedPostStateProvider, HeaderProvider, NodePrimitivesProvider, ProviderError, ProviderResult, + PruneCheckpointReader, ReceiptProvider, ReceiptProviderIdExt, StateProofProvider, + StateProvider, StateProviderBox, StateProviderFactory, StateRootProvider, + StaticFileProviderFactory, StorageRootProvider, TransactionVariant, TransactionsProvider, + WithdrawalsProvider, }; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_trie::{ - updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, StorageProof, - TrieInput, + updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, + StorageMultiProof, StorageProof, TrieInput, }; -use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg}; use std::{ ops::{RangeBounds, RangeInclusive}, path::PathBuf, @@ -95,6 +96,7 @@ impl BlockNumReader for WorldChainNoopProvider { } impl BlockReader for WorldChainNoopProvider { + type Block = Block; fn find_block_by_hash( &self, hash: B256, @@ -160,6 +162,14 @@ impl BlockReader for WorldChainNoopProvider { ) -> ProviderResult> { Ok(vec![]) } + + fn block_by_hash(&self, _hash: B256) -> ProviderResult> { + Ok(None) + } + + fn block_by_number(&self, _num: u64) -> ProviderResult> { + Ok(None) + } } impl BlockReaderIdExt for WorldChainNoopProvider { @@ -181,32 +191,34 @@ impl BlockReaderIdExt for WorldChainNoopProvider { } impl BlockIdReader for WorldChainNoopProvider { - fn pending_block_num_hash(&self) -> ProviderResult> { + fn pending_block_num_hash(&self) -> ProviderResult> { Ok(None) } - fn safe_block_num_hash(&self) -> ProviderResult> { + fn safe_block_num_hash(&self) -> ProviderResult> { Ok(None) } - fn finalized_block_num_hash(&self) -> ProviderResult> { + fn finalized_block_num_hash(&self) -> ProviderResult> { Ok(None) } } impl TransactionsProvider for WorldChainNoopProvider { - fn transaction_id(&self, _tx_hash: TxHash) -> ProviderResult> { + type Transaction = TransactionSigned; + + fn transaction_by_id_unhashed( + &self, + _id: TxNumber, + ) -> ProviderResult> { Ok(None) } - fn transaction_by_id(&self, _id: TxNumber) -> ProviderResult> { + fn transaction_id(&self, _tx_hash: TxHash) -> ProviderResult> { Ok(None) } - fn transaction_by_id_no_hash( - &self, - _id: TxNumber, - ) -> ProviderResult> { + fn transaction_by_id(&self, _id: TxNumber) -> ProviderResult> { Ok(None) } @@ -242,7 +254,7 @@ impl TransactionsProvider for WorldChainNoopProvider { fn transactions_by_tx_range( &self, _range: impl RangeBounds, - ) -> ProviderResult> { + ) -> ProviderResult> { Ok(Vec::default()) } @@ -259,6 +271,7 @@ impl TransactionsProvider for WorldChainNoopProvider { } impl ReceiptProvider for WorldChainNoopProvider { + type Receipt = Receipt; fn receipt(&self, _id: TxNumber) -> ProviderResult> { Ok(None) } @@ -282,6 +295,8 @@ impl ReceiptProvider for WorldChainNoopProvider { impl ReceiptProviderIdExt for WorldChainNoopProvider {} impl HeaderProvider for WorldChainNoopProvider { + type Header = Header; + fn header(&self, _block_hash: &BlockHash) -> ProviderResult> { Ok(None) } @@ -355,6 +370,15 @@ impl StateRootProvider for WorldChainNoopProvider { } impl StorageRootProvider for WorldChainNoopProvider { + fn storage_multiproof( + &self, + _address: Address, + _slots: &[B256], + _hashed_storage: HashedStorage, + ) -> ProviderResult { + Ok(StorageMultiProof::empty()) + } + fn storage_root( &self, _address: Address, @@ -414,20 +438,13 @@ impl StateProvider for WorldChainNoopProvider { } } -impl EvmEnvProvider for WorldChainNoopProvider { - fn fill_env_at( - &self, - _cfg: &mut CfgEnvWithHandlerCfg, - _block_env: &mut BlockEnv, - _at: BlockHashOrNumber, - _evm_config: EvmConfig, - ) -> ProviderResult<()> - where - EvmConfig: ConfigureEvmEnv
, - { - Ok(()) +impl HashedPostStateProvider for WorldChainNoopProvider { + fn hashed_post_state(&self, _bundle_state: &reth::revm::db::BundleState) -> HashedPostState { + HashedPostState::default() } +} +impl EvmEnvProvider for WorldChainNoopProvider { fn fill_env_with_header( &self, _cfg: &mut CfgEnvWithHandlerCfg, @@ -547,8 +564,11 @@ impl PruneCheckpointReader for WorldChainNoopProvider { } } +impl NodePrimitivesProvider for WorldChainNoopProvider { + type Primitives = EthPrimitives; +} impl StaticFileProviderFactory for WorldChainNoopProvider { - fn static_file_provider(&self) -> StaticFileProvider { + fn static_file_provider(&self) -> StaticFileProvider { StaticFileProvider::read_only(PathBuf::default(), false).unwrap() } } @@ -560,6 +580,7 @@ impl CanonStateSubscriptions for WorldChainNoopProvider { } impl ForkChoiceSubscriptions for WorldChainNoopProvider { + type Header = Header; fn subscribe_safe_block(&self) -> ForkChoiceNotifications { let (_, rx) = watch::channel(None); ForkChoiceNotifications(rx) @@ -598,12 +619,6 @@ where _origin: TransactionOrigin, transaction: Self::Transaction, ) -> TransactionValidationOutcome { - if let Some(pbh_paylaod) = transaction.pbh_payload() { - self.inner - .set_validated(pbh_paylaod) - .expect("Error when writing to the db"); - } - TransactionValidationOutcome::Valid { balance: U256::ZERO, state_nonce: 0, diff --git a/world-chain-builder/src/pool/builder.rs b/world-chain-builder/src/pool/builder.rs index b3fc6593..dc94a5af 100644 --- a/world-chain-builder/src/pool/builder.rs +++ b/world-chain-builder/src/pool/builder.rs @@ -9,6 +9,7 @@ use reth::transaction_pool::TransactionValidationTaskExecutor; use reth_db::DatabaseEnv; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_node::txpool::OpTransactionValidator; +use reth_optimism_primitives::OpPrimitives; use reth_provider::CanonStateSubscriptions; use std::sync::Arc; use tracing::{debug, info}; @@ -27,7 +28,7 @@ pub struct WorldChainPoolBuilder { impl PoolBuilder for WorldChainPoolBuilder where - Node: FullNodeTypes>, + Node: FullNodeTypes>, { type Pool = WorldChainTransactionPool; diff --git a/world-chain-builder/src/pool/noop.rs b/world-chain-builder/src/pool/noop.rs index 6aa1433e..e3bd1424 100644 --- a/world-chain-builder/src/pool/noop.rs +++ b/world-chain-builder/src/pool/noop.rs @@ -12,7 +12,7 @@ use reth::transaction_pool::{ ValidPoolTransaction, }; use reth_eth_wire_types::HandleMempoolData; -use reth_primitives::PooledTransactionsElement; +use reth_primitives::{PooledTransactionsElement, RecoveredTx}; use revm_primitives::B256; use tokio::sync::mpsc::{self, Receiver}; @@ -25,6 +25,19 @@ pub struct NoopWorldChainTransactionPool { impl TransactionPool for NoopWorldChainTransactionPool { type Transaction = WorldChainPooledTransaction; + fn get_pending_transactions_with_predicate( + &self, + _predicate: impl FnMut(&ValidPoolTransaction) -> bool, + ) -> Vec>> { + vec![] + } + fn pending_transactions_max( + &self, + _max: usize, + ) -> Vec>> { + vec![] + } + fn pool_size(&self) -> PoolSize { Default::default() } @@ -120,7 +133,8 @@ impl TransactionPool for NoopWorldChainTransactionPool { fn get_pooled_transaction_element( &self, _tx_hash: TxHash, - ) -> Option { + ) -> Option::Pooled>> + { None } @@ -130,13 +144,6 @@ impl TransactionPool for NoopWorldChainTransactionPool { Box::new(std::iter::empty()) } - fn best_transactions_with_base_fee( - &self, - _: u64, - ) -> Box>>> { - Box::new(std::iter::empty()) - } - fn best_transactions_with_attributes( &self, _: BestTransactionsAttributes, @@ -212,25 +219,25 @@ impl TransactionPool for NoopWorldChainTransactionPool { Default::default() } - fn get_blob(&self, _tx_hash: TxHash) -> Result, BlobStoreError> { + fn get_blob( + &self, + _tx_hash: TxHash, + ) -> Result>, BlobStoreError> { Ok(None) } fn get_all_blobs( &self, _tx_hashes: Vec, - ) -> Result, BlobStoreError> { + ) -> Result)>, BlobStoreError> { Ok(vec![]) } fn get_all_blobs_exact( &self, - tx_hashes: Vec, - ) -> Result, BlobStoreError> { - if tx_hashes.is_empty() { - return Ok(vec![]); - } - Err(BlobStoreError::MissingSidecar(tx_hashes[0])) + _tx_hashes: Vec, + ) -> Result>, BlobStoreError> { + Ok(vec![]) } fn get_blobs_for_versioned_hashes( diff --git a/world-chain-builder/src/pool/root.rs b/world-chain-builder/src/pool/root.rs index a11255bd..12730915 100644 --- a/world-chain-builder/src/pool/root.rs +++ b/world-chain-builder/src/pool/root.rs @@ -1,6 +1,8 @@ use std::{collections::BTreeMap, sync::Arc}; +use alloy_consensus::{BlockHeader, Header, Sealable, Sealed}; use parking_lot::RwLock; +use reth::api::Block; use reth_primitives::SealedBlock; use reth_provider::{BlockReaderIdExt, StateProviderFactory}; use revm_primitives::{address, Address, U256}; @@ -55,11 +57,13 @@ where if let Ok(latest) = this.client.last_block_number() { let block = this.client.block(latest.into())?; if let Some(block) = block { - let state = this.client.state_by_block_hash(block.hash_slow())?; + let state = this + .client + .state_by_block_hash(block.header().hash_slow())?; let latest_root = state.storage(OP_WORLD_ID, LATEST_ROOT_SLOT.into())?; if let Some(latest) = latest_root { this.latest_root = latest; - this.valid_roots.insert(block.timestamp, latest); + this.valid_roots.insert(block.header().timestamp(), latest); }; } } @@ -79,9 +83,9 @@ where let root = state .storage(OP_WORLD_ID, LATEST_ROOT_SLOT.into()) .map_err(WorldChainTransactionPoolError::RootProvider)?; - self.latest_valid_timestamp = block.header.timestamp; + self.latest_valid_timestamp = block.timestamp; if let Some(root) = root { - self.valid_roots.insert(block.header.timestamp, root); + self.valid_roots.insert(block.timestamp, root); } self.prune_invalid(); @@ -163,83 +167,83 @@ where #[cfg(test)] mod tests { - use reth_primitives::Header; - use reth_provider::test_utils::{ExtendedAccount, MockEthProvider}; - - use super::*; - use reth_primitives::Block; - pub fn world_chain_root_validator() -> eyre::Result> { - let client = MockEthProvider::default(); - let root_validator = WorldChainRootValidator::new(client)?; - Ok(root_validator) - } - - fn add_block_with_root_with_timestamp( - validator: &WorldChainRootValidator, - timestamp: u64, - root: Field, - ) { - let header = Header { - timestamp, - ..Default::default() - }; - let block = Block { - header, - ..Default::default() - }; - validator.cache.read().client().add_account( - OP_WORLD_ID, - ExtendedAccount::new(0, U256::ZERO) - .extend_storage(vec![(LATEST_ROOT_SLOT.into(), root)]), - ); - validator - .cache - .read() - .client() - .add_block(block.hash_slow(), block.clone()); - let hash = block.hash_slow(); - let block = block.seal(hash); - validator.on_new_block(&block); - } - - #[test] - fn test_validate_root() -> eyre::Result<()> { - let validator = world_chain_root_validator()?; - let root_1 = Field::from(1u64); - let timestamp = 1000000000; - add_block_with_root_with_timestamp(&validator, timestamp, root_1); - assert!(validator.validate_root(root_1)); - let root_2 = Field::from(2u64); - add_block_with_root_with_timestamp(&validator, timestamp + 3601, root_2); - assert!(validator.validate_root(root_2)); - assert!(!validator.validate_root(root_1)); - let root_3 = Field::from(3u64); - add_block_with_root_with_timestamp(&validator, timestamp + 3600 + 3600, root_3); - assert!(validator.validate_root(root_3)); - assert!(validator.validate_root(root_2)); - assert!(!validator.validate_root(root_1)); - Ok(()) - } - - impl WorldChainRootValidator - where - Client: StateProviderFactory + BlockReaderIdExt, - { - pub fn set_client(&mut self, client: Client) { - self.cache.write().set_client(client); - } - } - - impl RootProvider - where - Client: StateProviderFactory + BlockReaderIdExt, - { - pub fn set_client(&mut self, client: Client) { - self.client = client; - } - - pub fn client(&self) -> &Client { - &self.client - } - } + // use reth_primitives::Header; + // use reth_provider::test_utils::{ExtendedAccount, MockEthProvider}; + + // use super::*; + // use reth_primitives::Block; + // pub fn world_chain_root_validator() -> eyre::Result> { + // let client = MockEthProvider::default(); + // let root_validator = WorldChainRootValidator::new(client)?; + // Ok(root_validator) + // } + + // fn add_block_with_root_with_timestamp( + // validator: &WorldChainRootValidator, + // timestamp: u64, + // root: Field, + // ) { + // let header = Header { + // timestamp, + // ..Default::default() + // }; + // let block = Block { + // header, + // ..Default::default() + // }; + // validator.cache.read().client().add_account( + // OP_WORLD_ID, + // ExtendedAccount::new(0, U256::ZERO) + // .extend_storage(vec![(LATEST_ROOT_SLOT.into(), root)]), + // ); + // validator + // .cache + // .read() + // .client() + // .add_block(block.hash_slow(), block.clone()); + // let hash = block.hash_slow(); + // let block = block.clone(); + // validator.on_new_block(&block.seal(hash).clone()); + // } + + // #[test] + // fn test_validate_root() -> eyre::Result<()> { + // let validator = world_chain_root_validator()?; + // let root_1 = Field::from(1u64); + // let timestamp = 1000000000; + // add_block_with_root_with_timestamp(&validator, timestamp, root_1); + // assert!(validator.validate_root(root_1)); + // let root_2 = Field::from(2u64); + // add_block_with_root_with_timestamp(&validator, timestamp + 3601, root_2); + // assert!(validator.validate_root(root_2)); + // assert!(!validator.validate_root(root_1)); + // let root_3 = Field::from(3u64); + // add_block_with_root_with_timestamp(&validator, timestamp + 3600 + 3600, root_3); + // assert!(validator.validate_root(root_3)); + // assert!(validator.validate_root(root_2)); + // assert!(!validator.validate_root(root_1)); + // Ok(()) + // } + + // impl WorldChainRootValidator + // where + // Client: StateProviderFactory + BlockReaderIdExt, + // { + // pub fn set_client(&mut self, client: Client) { + // self.cache.write().set_client(client); + // } + // } + + // impl RootProvider + // where + // Client: StateProviderFactory + BlockReaderIdExt, + // { + // pub fn set_client(&mut self, client: Client) { + // self.client = client; + // } + + // pub fn client(&self) -> &Client { + // &self.client + // } + // } } diff --git a/world-chain-builder/src/pool/tx.rs b/world-chain-builder/src/pool/tx.rs index c2697953..bcd59d4d 100644 --- a/world-chain-builder/src/pool/tx.rs +++ b/world-chain-builder/src/pool/tx.rs @@ -1,12 +1,24 @@ +use std::sync::Arc; + +use alloy_consensus::{BlobTransactionSidecar, BlobTransactionValidationError, Transaction}; use alloy_primitives::TxHash; use alloy_rpc_types::erc4337::ConditionalOptions; -use reth::transaction_pool::{EthPoolTransaction, EthPooledTransaction, PoolTransaction}; -use reth_primitives::transaction::TryFromRecoveredTransactionError; -use reth_primitives::{PooledTransactionsElementEcRecovered, TransactionSignedEcRecovered}; -use revm_primitives::{AccessList, Address, TxKind, U256}; +use reth::{ + core::primitives::SignedTransaction, + transaction_pool::{ + EthBlobTransactionSidecar, EthPoolTransaction, EthPooledTransaction, PoolTransaction, + }, +}; +use reth_primitives::{ + transaction::{SignedTransactionIntoRecoveredExt, TryFromRecoveredTransactionError}, + Transaction as RethTransaction, +}; +use reth_primitives::{ + PooledTransactionsElement, PooledTransactionsElementEcRecovered, RecoveredTx, TransactionSigned, +}; +use revm_primitives::{AccessList, Address, KzgSettings, TxKind, U256}; use crate::pbh::payload::PbhPayload; -use crate::primitives::WorldChainPooledTransactionsElementEcRecovered; pub trait WorldChainPoolTransaction: EthPoolTransaction { fn pbh_payload(&self) -> Option<&PbhPayload>; @@ -21,7 +33,7 @@ pub struct WorldChainPooledTransaction { } impl EthPoolTransaction for WorldChainPooledTransaction { - fn take_blob(&mut self) -> reth::transaction_pool::EthBlobTransactionSidecar { + fn take_blob(&mut self) -> EthBlobTransactionSidecar { self.inner.take_blob() } @@ -29,16 +41,48 @@ impl EthPoolTransaction for WorldChainPooledTransaction { self.inner.blob_count() } + fn try_into_pooled_eip4844( + self, + sidecar: Arc, + ) -> Option> { + self.inner.try_into_pooled_eip4844(sidecar) + } + + fn try_from_eip4844( + tx: RecoveredTx, + sidecar: BlobTransactionSidecar, + ) -> Option { + let (tx, signer) = tx.to_components(); + let pooled = PooledTransactionsElement::try_from_blob_transaction(tx, sidecar) + .ok() + .map(|tx| tx.with_signer(signer)) + .map(|tx| EthPooledTransaction::from_pooled(tx)); + + pooled.map(|inner| Self { + inner, + pbh_payload: None, + conditional_options: None, + }) + } + fn validate_blob( &self, - blob: &reth_primitives::BlobTransactionSidecar, - settings: &reth_primitives::kzg::KzgSettings, - ) -> Result<(), reth_primitives::BlobTransactionValidationError> { - self.inner.validate_blob(blob, settings) + sidecar: &BlobTransactionSidecar, + settings: &KzgSettings, + ) -> Result<(), BlobTransactionValidationError> { + match &self.inner.transaction().transaction { + RethTransaction::Eip4844(tx) => tx.validate_blob(sidecar, settings), + _ => Err(BlobTransactionValidationError::NotBlobTransaction( + self.inner.tx_type(), + )), + } } fn authorization_count(&self) -> usize { - self.inner.authorization_count() + match &self.inner.transaction().transaction { + RethTransaction::Eip7702(tx) => tx.authorization_list.len(), + _ => 0, + } } } @@ -46,145 +90,182 @@ impl WorldChainPoolTransaction for WorldChainPooledTransaction { fn pbh_payload(&self) -> Option<&PbhPayload> { self.pbh_payload.as_ref() } - fn conditional_options(&self) -> Option<&ConditionalOptions> { self.conditional_options.as_ref() } } -impl From for TransactionSignedEcRecovered { - fn from(tx: WorldChainPooledTransaction) -> Self { - tx.inner.into_consensus() - } -} - -impl TryFrom for WorldChainPooledTransaction { - type Error = TryFromRecoveredTransactionError; - - fn try_from(tx: TransactionSignedEcRecovered) -> Result { - Ok(Self { - inner: EthPooledTransaction::try_from(tx)?, +impl From for WorldChainPooledTransaction { + fn from(tx: EthPooledTransaction) -> Self { + Self { + inner: tx, pbh_payload: None, conditional_options: None, - }) + } } } -impl From for WorldChainPooledTransaction { - fn from(tx: WorldChainPooledTransactionsElementEcRecovered) -> Self { +/// Conversion from the network transaction type to the pool transaction type. +impl From for WorldChainPooledTransaction { + fn from(tx: PooledTransactionsElementEcRecovered) -> Self { + let inner = EthPooledTransaction::from(tx); Self { - inner: EthPooledTransaction::from_pooled(tx.inner), - pbh_payload: tx.pbh_payload, + inner, + pbh_payload: None, conditional_options: None, } } } -impl From for WorldChainPooledTransactionsElementEcRecovered { - fn from(value: PooledTransactionsElementEcRecovered) -> Self { - Self { - inner: value, - // Incoming consensus transactions do not have a semaphore proof - // Is this problematic? +impl TryFrom for WorldChainPooledTransaction { + type Error = TryFromRecoveredTransactionError; + + fn try_from(tx: RecoveredTx) -> Result { + let inner = EthPooledTransaction::try_from(tx)?; + Ok(Self { + inner, pbh_payload: None, - } + conditional_options: None, + }) } } -impl From for PooledTransactionsElementEcRecovered { - fn from(value: WorldChainPooledTransactionsElementEcRecovered) -> Self { - value.inner +impl Into for WorldChainPooledTransaction { + fn into(self) -> RecoveredTx { + self.inner.into() } } impl PoolTransaction for WorldChainPooledTransaction { - type TryFromConsensusError = ::TryFromConsensusError; + type TryFromConsensusError = TryFromRecoveredTransactionError; - type Consensus = TransactionSignedEcRecovered; + type Consensus = TransactionSigned; - type Pooled = WorldChainPooledTransactionsElementEcRecovered; + type Pooled = PooledTransactionsElement; - fn try_from_consensus(tx: Self::Consensus) -> Result { - EthPooledTransaction::try_from_consensus(tx).map(|inner| Self { - inner, - pbh_payload: None, - conditional_options: None, - }) - } - - fn into_consensus(self) -> Self::Consensus { - self.inner.into_consensus() + fn clone_into_consensus(&self) -> RecoveredTx { + self.inner.transaction().clone() } - fn from_pooled(pooled: Self::Pooled) -> Self { - Self::from(pooled) + fn try_consensus_into_pooled( + tx: RecoveredTx, + ) -> Result, Self::TryFromConsensusError> { + let (tx, signer) = tx.to_components(); + let pooled = tx + .try_into_pooled() + .map_err(|_| TryFromRecoveredTransactionError::BlobSidecarMissing)?; + Ok(RecoveredTx::from_signed_transaction(pooled, signer)) } + /// Returns hash of the transaction. fn hash(&self) -> &TxHash { - self.inner.hash() + let transaction = self.inner.transaction(); + &transaction.tx_hash() } + /// Returns the Sender of the transaction. fn sender(&self) -> Address { - self.inner.sender() + self.inner.transaction().signer() + } + + /// Returns a reference to the Sender of the transaction. + fn sender_ref(&self) -> &Address { + self.inner.transaction().signer_ref() } + /// Returns the nonce for this transaction. fn nonce(&self) -> u64 { - self.inner.nonce() + self.inner.transaction().nonce() } - fn cost(&self) -> U256 { - self.inner.cost() + /// Returns the cost that this transaction is allowed to consume: + /// + /// For EIP-1559 transactions: `max_fee_per_gas * gas_limit + tx_value`. + /// For legacy transactions: `gas_price * gas_limit + tx_value`. + /// For EIP-4844 blob transactions: `max_fee_per_gas * gas_limit + tx_value + + /// max_blob_fee_per_gas * blob_gas_used`. + fn cost(&self) -> &U256 { + &self.inner.cost() } + /// Amount of gas that should be used in executing this transaction. This is paid up-front. fn gas_limit(&self) -> u64 { - self.inner.gas_limit() + self.inner.transaction().gas_limit() } + /// Returns the EIP-1559 Max base fee the caller is willing to pay. + /// + /// For legacy transactions this is `gas_price`. + /// + /// This is also commonly referred to as the "Gas Fee Cap" (`GasFeeCap`). fn max_fee_per_gas(&self) -> u128 { - self.inner.max_fee_per_gas() + self.inner.transaction().transaction.max_fee_per_gas() } fn access_list(&self) -> Option<&AccessList> { - self.inner.access_list() + self.inner.transaction().access_list() } + /// Returns the EIP-1559 Priority fee the caller is paying to the block author. + /// + /// This will return `None` for non-EIP1559 transactions fn max_priority_fee_per_gas(&self) -> Option { - self.inner.max_priority_fee_per_gas() + self.inner + .transaction() + .transaction + .max_priority_fee_per_gas() } fn max_fee_per_blob_gas(&self) -> Option { - self.inner.max_fee_per_blob_gas() + self.inner.transaction().max_fee_per_blob_gas() } + /// Returns the effective tip for this transaction. + /// + /// For EIP-1559 transactions: `min(max_fee_per_gas - base_fee, max_priority_fee_per_gas)`. + /// For legacy transactions: `gas_price - base_fee`. fn effective_tip_per_gas(&self, base_fee: u64) -> Option { - self.inner.effective_tip_per_gas(base_fee) + self.inner.transaction().effective_tip_per_gas(base_fee) } + /// Returns the max priority fee per gas if the transaction is an EIP-1559 transaction, and + /// otherwise returns the gas price. fn priority_fee_or_price(&self) -> u128 { - self.inner.priority_fee_or_price() + self.inner.transaction().priority_fee_or_price() } + /// Returns the transaction's [`TxKind`], which is the address of the recipient or + /// [`TxKind::Create`] if the transaction is a contract creation. fn kind(&self) -> TxKind { - self.inner.kind() + self.inner.transaction().kind() + } + + /// Returns true if the transaction is a contract creation. + fn is_create(&self) -> bool { + self.inner.transaction().is_create() } fn input(&self) -> &[u8] { - self.inner.input() + self.inner.transaction().input() } + /// Returns a measurement of the heap usage of this type and all its internals. fn size(&self) -> usize { - self.inner.size() + self.inner.transaction().transaction.input().len() } + /// Returns the transaction type fn tx_type(&self) -> u8 { - self.inner.tx_type() + self.inner.transaction().tx_type().into() } + /// Returns the length of the rlp encoded object fn encoded_length(&self) -> usize { self.inner.encoded_length() } + /// Returns `chain_id` fn chain_id(&self) -> Option { - self.inner.chain_id() + self.inner.transaction().chain_id() } } diff --git a/world-chain-builder/src/pool/validator.rs b/world-chain-builder/src/pool/validator.rs index 3c32df0e..c0834d14 100644 --- a/world-chain-builder/src/pool/validator.rs +++ b/world-chain-builder/src/pool/validator.rs @@ -9,7 +9,7 @@ use reth_db::cursor::DbCursorRW; use reth_db::transaction::{DbTx, DbTxMut}; use reth_db::{Database, DatabaseEnv, DatabaseError}; use reth_optimism_node::txpool::OpTransactionValidator; -use reth_primitives::SealedBlock; +use reth_primitives::{SealedBlock, TransactionSigned}; use reth_provider::{BlockReaderIdExt, StateProviderFactory}; use semaphore::hash_to_field; use semaphore::protocol::verify_proof; @@ -46,8 +46,8 @@ where impl WorldChainTransactionValidator where - Client: StateProviderFactory + BlockReaderIdExt, - Tx: WorldChainPoolTransaction, + Client: StateProviderFactory + BlockReaderIdExt, + Tx: WorldChainPoolTransaction, { /// Create a new [`WorldChainTransactionValidator`]. pub fn new( @@ -195,8 +195,8 @@ where impl TransactionValidator for WorldChainTransactionValidator where - Client: StateProviderFactory + BlockReaderIdExt, - Tx: WorldChainPoolTransaction, + Client: StateProviderFactory + BlockReaderIdExt, + Tx: WorldChainPoolTransaction, { type Transaction = Tx; @@ -224,267 +224,267 @@ where #[cfg(test)] pub mod tests { - use chrono::{TimeZone, Utc}; - use ethers_core::types::U256; - use reth::transaction_pool::blobstore::InMemoryBlobStore; - use reth::transaction_pool::{ - Pool, PoolTransaction as _, TransactionPool, TransactionValidator, - }; - use reth_primitives::{BlockBody, SealedBlock, SealedHeader}; - use reth_provider::test_utils::{ExtendedAccount, MockEthProvider}; - use semaphore::Field; - use test_case::test_case; - - use crate::pbh::payload::{PbhPayload, Proof}; - use crate::pool::ordering::WorldChainOrdering; - use crate::pool::root::{LATEST_ROOT_SLOT, OP_WORLD_ID}; - use crate::test::{get_pbh_transaction, world_chain_validator}; - - #[tokio::test] - async fn validate_pbh_transaction() { - let validator = world_chain_validator(); - let transaction = get_pbh_transaction(0); - validator.inner.client().add_account( - transaction.sender(), - ExtendedAccount::new(transaction.nonce(), alloy_primitives::U256::MAX), - ); - // Insert a world id root into the OpWorldId Account - validator.inner.client().add_account( - OP_WORLD_ID, - ExtendedAccount::new(0, alloy_primitives::U256::ZERO).extend_storage(vec![( - LATEST_ROOT_SLOT.into(), - transaction.pbh_payload.clone().unwrap().root, - )]), - ); - let header = SealedHeader::default(); - let body = BlockBody::default(); - let block = SealedBlock::new(header, body); - - // Propogate the block to the root validator - validator.on_new_head_block(&block); - - let ordering = WorldChainOrdering::default(); - - let pool = Pool::new( - validator, - ordering, - InMemoryBlobStore::default(), - Default::default(), - ); - - let start = chrono::Utc::now(); - let res = pool.add_external_transaction(transaction.clone()).await; - let first_insert = chrono::Utc::now() - start; - println!("first_insert: {first_insert:?}"); - - assert!(res.is_ok()); - let tx = pool.get(transaction.hash()); - assert!(tx.is_some()); - - let start = chrono::Utc::now(); - let res = pool.add_external_transaction(transaction.clone()).await; - - let second_insert = chrono::Utc::now() - start; - println!("second_insert: {second_insert:?}"); - - // Check here that we're properly caching the transaction - assert!(first_insert > second_insert * 10); - assert!(res.is_err()); - } - - #[tokio::test] - async fn invalid_external_nullifier_hash() { - let validator = world_chain_validator(); - let transaction = get_pbh_transaction(0); - - validator.inner.client().add_account( - transaction.sender(), - ExtendedAccount::new(transaction.nonce(), alloy_primitives::U256::MAX), - ); - - let ordering = WorldChainOrdering::default(); - - let pool = Pool::new( - validator, - ordering, - InMemoryBlobStore::default(), - Default::default(), - ); - - let res = pool.add_external_transaction(transaction.clone()).await; - assert!(res.is_err()); - } - - #[tokio::test] - async fn invalid_signal_hash() { - let validator = world_chain_validator(); - let transaction = get_pbh_transaction(0); - - validator.inner.client().add_account( - transaction.sender(), - ExtendedAccount::new(transaction.nonce(), alloy_primitives::U256::MAX), - ); - - let ordering = WorldChainOrdering::default(); - - let pool = Pool::new( - validator, - ordering, - InMemoryBlobStore::default(), - Default::default(), - ); - - let res = pool.add_external_transaction(transaction.clone()).await; - assert!(res.is_err()); - } - - #[test] - fn test_validate_root() { - let mut validator = world_chain_validator(); - let root = Field::from(1u64); - let proof = Proof(semaphore::protocol::Proof( - (U256::from(1u64), U256::from(2u64)), - ( - [U256::from(3u64), U256::from(4u64)], - [U256::from(5u64), U256::from(6u64)], - ), - (U256::from(7u64), U256::from(8u64)), - )); - let payload = PbhPayload { - external_nullifier: "0-012025-11".to_string(), - nullifier_hash: Field::from(10u64), - root, - proof, - }; - let header = SealedHeader::default(); - let body = BlockBody::default(); - let block = SealedBlock::new(header, body); - let client = MockEthProvider::default(); - // Insert a world id root into the OpWorldId Account - client.add_account( - OP_WORLD_ID, - ExtendedAccount::new(0, alloy_primitives::U256::ZERO) - .extend_storage(vec![(LATEST_ROOT_SLOT.into(), Field::from(1u64))]), - ); - validator.root_validator.set_client(client); - validator.on_new_head_block(&block); - let res = validator.validate_root(&payload); - assert!(res.is_ok()); - } - - #[test] - fn test_invalidate_root() { - let mut validator = world_chain_validator(); - let root = Field::from(0); - let proof = Proof(semaphore::protocol::Proof( - (U256::from(1u64), U256::from(2u64)), - ( - [U256::from(3u64), U256::from(4u64)], - [U256::from(5u64), U256::from(6u64)], - ), - (U256::from(7u64), U256::from(8u64)), - )); - let payload = PbhPayload { - external_nullifier: "0-012025-11".to_string(), - nullifier_hash: Field::from(10u64), - root, - proof, - }; - let header = SealedHeader::default(); - let body = BlockBody::default(); - let block = SealedBlock::new(header, body); - let client = MockEthProvider::default(); - // Insert a world id root into the OpWorldId Account - client.add_account( - OP_WORLD_ID, - ExtendedAccount::new(0, alloy_primitives::U256::ZERO) - .extend_storage(vec![(LATEST_ROOT_SLOT.into(), Field::from(1u64))]), - ); - validator.root_validator.set_client(client); - validator.on_new_head_block(&block); - let res = validator.validate_root(&payload); - assert!(res.is_err()); - } - - #[test_case("v1-012025-0")] - #[test_case("v1-012025-1")] - #[test_case("v1-012025-29")] - fn validate_external_nullifier_valid(external_nullifier: &str) { - let validator = world_chain_validator(); - let date = chrono::Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).unwrap(); - - let payload = PbhPayload { - external_nullifier: external_nullifier.to_string(), - nullifier_hash: Field::ZERO, - root: Field::ZERO, - proof: Default::default(), - }; - - validator - .validate_external_nullifier(date, &payload) - .unwrap(); - } - - #[test_case("v1-012025-0", "2024-12-31 23:59:30Z" ; "a minute early")] - #[test_case("v1-012025-0", "2025-02-01 00:00:30Z" ; "a minute late")] - fn validate_external_nullifier_at_time(external_nullifier: &str, time: &str) { - let validator = world_chain_validator(); - let date: chrono::DateTime = time.parse().unwrap(); - - let payload = PbhPayload { - external_nullifier: external_nullifier.to_string(), - nullifier_hash: Field::ZERO, - root: Field::ZERO, - proof: Default::default(), - }; - - validator - .validate_external_nullifier(date, &payload) - .unwrap(); - } - - #[test_case("v0-012025-0")] - #[test_case("v1-022025-0")] - #[test_case("v1-122024-0")] - #[test_case("v1-002025-0")] - #[test_case("v1-012025-30")] - #[test_case("v1-012025")] - #[test_case("12025-0")] - #[test_case("v1-012025-0-0")] - fn validate_external_nullifier_invalid(external_nullifier: &str) { - let validator = world_chain_validator(); - let date = chrono::Utc.with_ymd_and_hms(2025, 1, 1, 12, 0, 0).unwrap(); - - let payload = PbhPayload { - external_nullifier: external_nullifier.to_string(), - nullifier_hash: Field::ZERO, - root: Field::ZERO, - proof: Default::default(), - }; - - let res = validator.validate_external_nullifier(date, &payload); - assert!(res.is_err()); - } - - #[test] - fn test_set_validated() { - let validator = world_chain_validator(); - - let proof = Proof(semaphore::protocol::Proof( - (U256::from(1u64), U256::from(2u64)), - ( - [U256::from(3u64), U256::from(4u64)], - [U256::from(5u64), U256::from(6u64)], - ), - (U256::from(7u64), U256::from(8u64)), - )); - let payload = PbhPayload { - external_nullifier: "0-012025-11".to_string(), - nullifier_hash: Field::from(10u64), - root: Field::from(12u64), - proof, - }; - - validator.set_validated(&payload).unwrap(); - } + // use chrono::{TimeZone, Utc}; + // use ethers_core::types::U256; + // use reth::transaction_pool::blobstore::InMemoryBlobStore; + // use reth::transaction_pool::{ + // Pool, PoolTransaction as _, TransactionPool, TransactionValidator, + // }; + // use reth_primitives::{BlockBody, SealedBlock, SealedHeader}; + // use reth_provider::test_utils::{ExtendedAccount, MockEthProvider}; + // use semaphore::Field; + // use test_case::test_case; + + // use crate::pbh::payload::{PbhPayload, Proof}; + // use crate::pool::ordering::WorldChainOrdering; + // use crate::pool::root::{LATEST_ROOT_SLOT, OP_WORLD_ID}; + // use crate::test::{get_pbh_transaction, world_chain_validator}; + + // #[tokio::test] + // async fn validate_pbh_transaction() { + // let validator = world_chain_validator(); + // let transaction = get_pbh_transaction(0); + // validator.inner.client().add_account( + // transaction.sender(), + // ExtendedAccount::new(transaction.nonce(), alloy_primitives::U256::MAX), + // ); + // // Insert a world id root into the OpWorldId Account + // validator.inner.client().add_account( + // OP_WORLD_ID, + // ExtendedAccount::new(0, alloy_primitives::U256::ZERO).extend_storage(vec![( + // LATEST_ROOT_SLOT.into(), + // transaction.pbh_payload.clone().unwrap().root, + // )]), + // ); + // let header = SealedHeader::default(); + // let body = BlockBody::default(); + // let block = SealedBlock::new(header, body); + + // // Propogate the block to the root validator + // validator.on_new_head_block(&block); + + // let ordering = WorldChainOrdering::default(); + + // let pool = Pool::new( + // validator, + // ordering, + // InMemoryBlobStore::default(), + // Default::default(), + // ); + + // let start = chrono::Utc::now(); + // let res = pool.add_external_transaction(transaction.clone()).await; + // let first_insert = chrono::Utc::now() - start; + // println!("first_insert: {first_insert:?}"); + + // assert!(res.is_ok()); + // let tx = pool.get(transaction.hash()); + // assert!(tx.is_some()); + + // let start = chrono::Utc::now(); + // let res = pool.add_external_transaction(transaction.clone()).await; + + // let second_insert = chrono::Utc::now() - start; + // println!("second_insert: {second_insert:?}"); + + // // Check here that we're properly caching the transaction + // assert!(first_insert > second_insert * 10); + // assert!(res.is_err()); + // } + + // #[tokio::test] + // async fn invalid_external_nullifier_hash() { + // let validator = world_chain_validator(); + // let transaction = get_pbh_transaction(0); + + // validator.inner.client().add_account( + // transaction.sender(), + // ExtendedAccount::new(transaction.nonce(), alloy_primitives::U256::MAX), + // ); + + // let ordering = WorldChainOrdering::default(); + + // let pool = Pool::new( + // validator, + // ordering, + // InMemoryBlobStore::default(), + // Default::default(), + // ); + + // let res = pool.add_external_transaction(transaction.clone()).await; + // assert!(res.is_err()); + // } + + // #[tokio::test] + // async fn invalid_signal_hash() { + // let validator = world_chain_validator(); + // let transaction = get_pbh_transaction(0); + + // validator.inner.client().add_account( + // transaction.sender(), + // ExtendedAccount::new(transaction.nonce(), alloy_primitives::U256::MAX), + // ); + + // let ordering = WorldChainOrdering::default(); + + // let pool = Pool::new( + // validator, + // ordering, + // InMemoryBlobStore::default(), + // Default::default(), + // ); + + // let res = pool.add_external_transaction(transaction.clone()).await; + // assert!(res.is_err()); + // } + + // #[test] + // fn test_validate_root() { + // let mut validator = world_chain_validator(); + // let root = Field::from(1u64); + // let proof = Proof(semaphore::protocol::Proof( + // (U256::from(1u64), U256::from(2u64)), + // ( + // [U256::from(3u64), U256::from(4u64)], + // [U256::from(5u64), U256::from(6u64)], + // ), + // (U256::from(7u64), U256::from(8u64)), + // )); + // let payload = PbhPayload { + // external_nullifier: "0-012025-11".to_string(), + // nullifier_hash: Field::from(10u64), + // root, + // proof, + // }; + // let header = SealedHeader::default(); + // let body = BlockBody::default(); + // let block = SealedBlock::new(header, body); + // let client = MockEthProvider::default(); + // // Insert a world id root into the OpWorldId Account + // client.add_account( + // OP_WORLD_ID, + // ExtendedAccount::new(0, alloy_primitives::U256::ZERO) + // .extend_storage(vec![(LATEST_ROOT_SLOT.into(), Field::from(1u64))]), + // ); + // validator.root_validator.set_client(client); + // validator.on_new_head_block(&block); + // let res = validator.validate_root(&payload); + // assert!(res.is_ok()); + // } + + // #[test] + // fn test_invalidate_root() { + // let mut validator = world_chain_validator(); + // let root = Field::from(0); + // let proof = Proof(semaphore::protocol::Proof( + // (U256::from(1u64), U256::from(2u64)), + // ( + // [U256::from(3u64), U256::from(4u64)], + // [U256::from(5u64), U256::from(6u64)], + // ), + // (U256::from(7u64), U256::from(8u64)), + // )); + // let payload = PbhPayload { + // external_nullifier: "0-012025-11".to_string(), + // nullifier_hash: Field::from(10u64), + // root, + // proof, + // }; + // let header = SealedHeader::default(); + // let body = BlockBody::default(); + // let block = SealedBlock::new(header, body); + // let client = MockEthProvider::default(); + // // Insert a world id root into the OpWorldId Account + // client.add_account( + // OP_WORLD_ID, + // ExtendedAccount::new(0, alloy_primitives::U256::ZERO) + // .extend_storage(vec![(LATEST_ROOT_SLOT.into(), Field::from(1u64))]), + // ); + // validator.root_validator.set_client(client); + // validator.on_new_head_block(&block); + // let res = validator.validate_root(&payload); + // assert!(res.is_err()); + // } + + // #[test_case("v1-012025-0")] + // #[test_case("v1-012025-1")] + // #[test_case("v1-012025-29")] + // fn validate_external_nullifier_valid(external_nullifier: &str) { + // let validator = world_chain_validator(); + // let date = chrono::Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).unwrap(); + + // let payload = PbhPayload { + // external_nullifier: external_nullifier.to_string(), + // nullifier_hash: Field::ZERO, + // root: Field::ZERO, + // proof: Default::default(), + // }; + + // validator + // .validate_external_nullifier(date, &payload) + // .unwrap(); + // } + + // #[test_case("v1-012025-0", "2024-12-31 23:59:30Z" ; "a minute early")] + // #[test_case("v1-012025-0", "2025-02-01 00:00:30Z" ; "a minute late")] + // fn validate_external_nullifier_at_time(external_nullifier: &str, time: &str) { + // let validator = world_chain_validator(); + // let date: chrono::DateTime = time.parse().unwrap(); + + // let payload = PbhPayload { + // external_nullifier: external_nullifier.to_string(), + // nullifier_hash: Field::ZERO, + // root: Field::ZERO, + // proof: Default::default(), + // }; + + // validator + // .validate_external_nullifier(date, &payload) + // .unwrap(); + // } + + // #[test_case("v0-012025-0")] + // #[test_case("v1-022025-0")] + // #[test_case("v1-122024-0")] + // #[test_case("v1-002025-0")] + // #[test_case("v1-012025-30")] + // #[test_case("v1-012025")] + // #[test_case("12025-0")] + // #[test_case("v1-012025-0-0")] + // fn validate_external_nullifier_invalid(external_nullifier: &str) { + // let validator = world_chain_validator(); + // let date = chrono::Utc.with_ymd_and_hms(2025, 1, 1, 12, 0, 0).unwrap(); + + // let payload = PbhPayload { + // external_nullifier: external_nullifier.to_string(), + // nullifier_hash: Field::ZERO, + // root: Field::ZERO, + // proof: Default::default(), + // }; + + // let res = validator.validate_external_nullifier(date, &payload); + // assert!(res.is_err()); + // } + + // #[test] + // fn test_set_validated() { + // let validator = world_chain_validator(); + + // let proof = Proof(semaphore::protocol::Proof( + // (U256::from(1u64), U256::from(2u64)), + // ( + // [U256::from(3u64), U256::from(4u64)], + // [U256::from(5u64), U256::from(6u64)], + // ), + // (U256::from(7u64), U256::from(8u64)), + // )); + // let payload = PbhPayload { + // external_nullifier: "0-012025-11".to_string(), + // nullifier_hash: Field::from(10u64), + // root: Field::from(12u64), + // proof, + // }; + + // validator.set_validated(&payload).unwrap(); + // } } diff --git a/world-chain-builder/src/primitives.rs b/world-chain-builder/src/primitives.rs index b187c0ed..31f1ef3d 100644 --- a/world-chain-builder/src/primitives.rs +++ b/world-chain-builder/src/primitives.rs @@ -152,92 +152,92 @@ pub fn recover_raw_transaction( Ok((ecrecovered, data)) } -#[cfg(test)] -mod tests { - use super::*; - use alloy_primitives::{address, hex}; - - #[test] - fn invalid_legacy_pooled_decoding_input_too_short() { - let input_too_short = [ - // this should fail because the payload length is longer than expected - &hex!("d90b0280808bc5cd028083c5cdfd9e407c56565656")[..], - // these should fail decoding - // - // The `c1` at the beginning is a list header, and the rest is a valid legacy - // transaction, BUT the payload length of the list header is 1, and the payload is - // obviously longer than one byte. - &hex!("c10b02808083c5cd028883c5cdfd9e407c56565656"), - &hex!("c10b0280808bc5cd028083c5cdfd9e407c56565656"), - // this one is 19 bytes, and the buf is long enough, but the transaction will not - // consume that many bytes. - &hex!("d40b02808083c5cdeb8783c5acfd9e407c5656565656"), - &hex!("d30102808083c5cd02887dc5cdfd9e64fd9e407c56"), - ]; - - for hex_data in &input_too_short { - let input_rlp = &mut &hex_data[..]; - let res = WorldChainPooledTransactionsElement::decode_2718(input_rlp); - - assert!( - res.is_err(), - "expected err after decoding rlp input: {:x?}", - Bytes::copy_from_slice(hex_data) - ); - - // this is a legacy tx so we can attempt the same test with decode_enveloped - let input_rlp = &mut &hex_data[..]; - let res = WorldChainPooledTransactionsElement::decode_2718(input_rlp); - - assert!( - res.is_err(), - "expected err after decoding enveloped rlp input: {:x?}", - Bytes::copy_from_slice(hex_data) - ); - } - } - - // - #[test] - fn decode_eip1559_enveloped() { - let data = hex!("02f903d382426882ba09832dc6c0848674742682ed9694714b6a4ea9b94a8a7d9fd362ed72630688c8898c80b90364492d24749189822d8512430d3f3ff7a2ede675ac08265c08e2c56ff6fdaa66dae1cdbe4a5d1d7809f3e99272d067364e597542ac0c369d69e22a6399c3e9bee5da4b07e3f3fdc34c32c3d88aa2268785f3e3f8086df0934b10ef92cfffc2e7f3d90f5e83302e31382e302d64657600000000000000000000000000000000000000000000569e75fc77c1a856f6daaf9e69d8a9566ca34aa47f9133711ce065a571af0cfd000000000000000000000000e1e210594771824dad216568b91c9cb4ceed361c00000000000000000000000000000000000000000000000000000000000546e00000000000000000000000000000000000000000000000000000000000e4e1c00000000000000000000000000000000000000000000000000000000065d6750c00000000000000000000000000000000000000000000000000000000000f288000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002cf600000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000f1628e56fa6d8c50e5b984a58c0df14de31c7b857ce7ba499945b99252976a93d06dcda6776fc42167fbe71cb59f978f5ef5b12577a90b132d14d9c6efa528076f0161d7bf03643cfc5490ec5084f4a041db7f06c50bd97efa08907ba79ddcac8b890f24d12d8db31abbaaf18985d54f400449ee0559a4452afe53de5853ce090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000064ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000c080a01428023fc54a27544abc421d5d017b9a7c5936ad501cbdecd0d9d12d04c1a033a0753104bbf1c87634d6ff3f0ffa0982710612306003eb022363b57994bdef445a"); - - let res = WorldChainPooledTransactionsElement::decode_2718(&mut &data[..]).unwrap(); - assert_eq!( - res.into_transaction().to(), - Some(address!("714b6a4ea9b94a8a7d9fd362ed72630688c8898c")) - ); - } - - #[test] - fn legacy_valid_pooled_decoding() { - // d3 <- payload length, d3 - c0 = 0x13 = 19 - // 0b <- nonce - // 02 <- gas_price - // 80 <- gas_limit - // 80 <- to (Create) - // 83 c5cdeb <- value - // 87 83c5acfd9e407c <- input - // 56 <- v (eip155, so modified with a chain id) - // 56 <- r - // 56 <- s - let data = &hex!("d30b02808083c5cdeb8783c5acfd9e407c565656")[..]; - - let input_rlp = &mut &data[..]; - let res = WorldChainPooledTransactionsElement::decode_2718(input_rlp); - println!("{:?}", res); - assert!(matches!(res, Ok(_tx))); - assert!(input_rlp.is_empty()); - - // this is a legacy tx so we can attempt the same test with - // decode_rlp_legacy_transaction_tuple - let input_rlp = &mut &data[..]; - let res = TransactionSigned::decode_rlp_legacy_transaction(input_rlp); - assert!(matches!(res, Ok(_tx))); - assert!(input_rlp.is_empty()); - - // we can also decode_enveloped - let res = WorldChainPooledTransactionsElement::decode_2718(&mut &data[..]); - assert!(matches!(res, Ok(_tx))); - } -} +// #[cfg(test)] +// mod tests { +// use super::*; +// use alloy_primitives::{address, hex}; + +// #[test] +// fn invalid_legacy_pooled_decoding_input_too_short() { +// let input_too_short = [ +// // this should fail because the payload length is longer than expected +// &hex!("d90b0280808bc5cd028083c5cdfd9e407c56565656")[..], +// // these should fail decoding +// // +// // The `c1` at the beginning is a list header, and the rest is a valid legacy +// // transaction, BUT the payload length of the list header is 1, and the payload is +// // obviously longer than one byte. +// &hex!("c10b02808083c5cd028883c5cdfd9e407c56565656"), +// &hex!("c10b0280808bc5cd028083c5cdfd9e407c56565656"), +// // this one is 19 bytes, and the buf is long enough, but the transaction will not +// // consume that many bytes. +// &hex!("d40b02808083c5cdeb8783c5acfd9e407c5656565656"), +// &hex!("d30102808083c5cd02887dc5cdfd9e64fd9e407c56"), +// ]; + +// for hex_data in &input_too_short { +// let input_rlp = &mut &hex_data[..]; +// let res = WorldChainPooledTransactionsElement::decode_2718(input_rlp); + +// assert!( +// res.is_err(), +// "expected err after decoding rlp input: {:x?}", +// Bytes::copy_from_slice(hex_data) +// ); + +// // this is a legacy tx so we can attempt the same test with decode_enveloped +// let input_rlp = &mut &hex_data[..]; +// let res = WorldChainPooledTransactionsElement::decode_2718(input_rlp); + +// assert!( +// res.is_err(), +// "expected err after decoding enveloped rlp input: {:x?}", +// Bytes::copy_from_slice(hex_data) +// ); +// } +// } + +// // +// #[test] +// fn decode_eip1559_enveloped() { +// let data = hex!("02f903d382426882ba09832dc6c0848674742682ed9694714b6a4ea9b94a8a7d9fd362ed72630688c8898c80b90364492d24749189822d8512430d3f3ff7a2ede675ac08265c08e2c56ff6fdaa66dae1cdbe4a5d1d7809f3e99272d067364e597542ac0c369d69e22a6399c3e9bee5da4b07e3f3fdc34c32c3d88aa2268785f3e3f8086df0934b10ef92cfffc2e7f3d90f5e83302e31382e302d64657600000000000000000000000000000000000000000000569e75fc77c1a856f6daaf9e69d8a9566ca34aa47f9133711ce065a571af0cfd000000000000000000000000e1e210594771824dad216568b91c9cb4ceed361c00000000000000000000000000000000000000000000000000000000000546e00000000000000000000000000000000000000000000000000000000000e4e1c00000000000000000000000000000000000000000000000000000000065d6750c00000000000000000000000000000000000000000000000000000000000f288000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002cf600000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000f1628e56fa6d8c50e5b984a58c0df14de31c7b857ce7ba499945b99252976a93d06dcda6776fc42167fbe71cb59f978f5ef5b12577a90b132d14d9c6efa528076f0161d7bf03643cfc5490ec5084f4a041db7f06c50bd97efa08907ba79ddcac8b890f24d12d8db31abbaaf18985d54f400449ee0559a4452afe53de5853ce090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000064ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000c080a01428023fc54a27544abc421d5d017b9a7c5936ad501cbdecd0d9d12d04c1a033a0753104bbf1c87634d6ff3f0ffa0982710612306003eb022363b57994bdef445a"); + +// let res = WorldChainPooledTransactionsElement::decode_2718(&mut &data[..]).unwrap(); +// assert_eq!( +// res.into_transaction().to(), +// Some(address!("714b6a4ea9b94a8a7d9fd362ed72630688c8898c")) +// ); +// } + +// #[test] +// fn legacy_valid_pooled_decoding() { +// // d3 <- payload length, d3 - c0 = 0x13 = 19 +// // 0b <- nonce +// // 02 <- gas_price +// // 80 <- gas_limit +// // 80 <- to (Create) +// // 83 c5cdeb <- value +// // 87 83c5acfd9e407c <- input +// // 56 <- v (eip155, so modified with a chain id) +// // 56 <- r +// // 56 <- s +// let data = &hex!("d30b02808083c5cdeb8783c5acfd9e407c565656")[..]; + +// let input_rlp = &mut &data[..]; +// let res = WorldChainPooledTransactionsElement::decode_2718(input_rlp); +// println!("{:?}", res); +// assert!(matches!(res, Ok(_tx))); +// assert!(input_rlp.is_empty()); + +// // this is a legacy tx so we can attempt the same test with +// // decode_rlp_legacy_transaction_tuple +// let input_rlp = &mut &data[..]; +// let res = TransactionSigned::decode_rlp_legacy_transaction(input_rlp); +// assert!(matches!(res, Ok(_tx))); +// assert!(input_rlp.is_empty()); + +// // we can also decode_enveloped +// let res = WorldChainPooledTransactionsElement::decode_2718(&mut &data[..]); +// assert!(matches!(res, Ok(_tx))); +// } +// } diff --git a/world-chain-builder/src/rpc/block.rs b/world-chain-builder/src/rpc/block.rs deleted file mode 100644 index c22ea22c..00000000 --- a/world-chain-builder/src/rpc/block.rs +++ /dev/null @@ -1,46 +0,0 @@ -//! Loads and formats OP block RPC response. - -use crate::rpc::WorldChainEthApi; -use alloy_network::Network; -use op_alloy_rpc_types::OpTransactionReceipt; -use reth::rpc::api::eth::helpers::{ - EthBlocks, LoadBlock, LoadPendingBlock, LoadReceipt, SpawnBlocking, -}; -use reth::rpc::api::eth::RpcReceipt; -use reth::rpc::eth::RpcNodeCore; -use reth_optimism_chainspec::OpChainSpec; -use reth_optimism_rpc::{OpEthApi, OpEthApiError}; -use reth_primitives::BlockId; -use reth_provider::{ChainSpecProvider, HeaderProvider}; - -impl EthBlocks for WorldChainEthApi -where - Self: LoadBlock< - Error = OpEthApiError, - NetworkTypes: Network, - >, - OpEthApi: EthBlocks - + LoadBlock< - Error = OpEthApiError, - NetworkTypes: Network, - > + LoadReceipt, - N: RpcNodeCore + HeaderProvider>, -{ - async fn block_receipts( - &self, - block_id: BlockId, - ) -> Result>>, Self::Error> - where - Self: LoadReceipt, - { - self.inner.block_receipts(block_id).await - } -} - -impl LoadBlock for WorldChainEthApi -where - OpEthApi: LoadPendingBlock + SpawnBlocking, - Self: LoadPendingBlock + SpawnBlocking, - N: RpcNodeCore, -{ -} diff --git a/world-chain-builder/src/rpc/bundle.rs b/world-chain-builder/src/rpc/bundle.rs index 14e8331b..5e157125 100644 --- a/world-chain-builder/src/rpc/bundle.rs +++ b/world-chain-builder/src/rpc/bundle.rs @@ -1,4 +1,5 @@ -use crate::{pool::tx::WorldChainPooledTransaction, primitives::recover_raw_transaction}; +use crate::pool::tx::WorldChainPooledTransaction; +use alloy_consensus::BlockHeader; use alloy_eips::BlockId; use alloy_primitives::{map::HashMap, StorageKey}; use alloy_rpc_types::erc4337::{AccountStorage, ConditionalOptions}; @@ -7,7 +8,11 @@ use jsonrpsee::{ proc_macros::rpc, types::{ErrorCode, ErrorObject, ErrorObjectOwned}, }; -use reth::transaction_pool::{PoolTransaction, TransactionOrigin, TransactionPool}; +use reth::{ + api::Block, + rpc::server_types::eth::utils::recover_raw_transaction, + transaction_pool::{EthPooledTransaction, PoolTransaction, TransactionOrigin, TransactionPool}, +}; use reth_provider::{BlockReaderIdExt, StateProviderFactory}; use revm_primitives::{map::FbBuildHasher, Address, Bytes, FixedBytes, B256}; @@ -46,8 +51,9 @@ where ) -> RpcResult { validate_conditional_options(&options, self.provider())?; - let (recovered, _) = recover_raw_transaction(tx.clone())?; - let mut pool_transaction = WorldChainPooledTransaction::from_pooled(recovered); + let recovered = recover_raw_transaction(&tx)?; + let mut pool_transaction: WorldChainPooledTransaction = + EthPooledTransaction::from_pooled(recovered).into(); pool_transaction.conditional_options = Some(options); // submit the transaction to the pool with a `Local` origin @@ -97,30 +103,30 @@ where validate_known_accounts( &options.known_accounts, - latest.header.number.into(), + latest.header().number().into(), provider, )?; if let Some(min_block) = options.block_number_min { - if min_block > latest.number { + if min_block > latest.header().number() { return Err(ErrorCode::from(-32003).into()); } } if let Some(max_block) = options.block_number_max { - if max_block < latest.number { + if max_block < latest.header().number() { return Err(ErrorCode::from(-32003).into()); } } if let Some(min_timestamp) = options.timestamp_min { - if min_timestamp > latest.timestamp { + if min_timestamp > latest.header().timestamp() { return Err(ErrorCode::from(-32003).into()); } } if let Some(max_timestamp) = options.timestamp_max { - if max_timestamp < latest.timestamp { + if max_timestamp < latest.header().timestamp() { return Err(ErrorCode::from(-32003).into()); } } diff --git a/world-chain-builder/src/rpc/call.rs b/world-chain-builder/src/rpc/call.rs deleted file mode 100644 index 039ea137..00000000 --- a/world-chain-builder/src/rpc/call.rs +++ /dev/null @@ -1,43 +0,0 @@ -use crate::rpc::WorldChainEthApi; -use alloy_rpc_types::TransactionRequest; -use reth::api::ConfigureEvm; -use reth::rpc::api::eth::helpers::{Call, EthCall, LoadPendingBlock, LoadState, SpawnBlocking}; -use reth::rpc::eth::{EthApiTypes, RpcNodeCore}; -use reth_optimism_rpc::OpEthApi; -use reth_primitives::{ - revm_primitives::{BlockEnv, TxEnv}, - Header, -}; - -impl EthCall for WorldChainEthApi -where - Self: Call + LoadPendingBlock, - N: RpcNodeCore, -{ -} - -impl Call for WorldChainEthApi -where - Self: LoadState> + SpawnBlocking, - OpEthApi: Call, - Self::Error: From< as EthApiTypes>::Error>, - N: RpcNodeCore, -{ - #[inline] - fn call_gas_limit(&self) -> u64 { - self.inner.call_gas_limit() - } - - #[inline] - fn max_simulate_blocks(&self) -> u64 { - self.inner.max_simulate_blocks() - } - - fn create_txn_env( - &self, - block_env: &BlockEnv, - request: TransactionRequest, - ) -> Result { - Ok(self.inner.create_txn_env(block_env, request)?) - } -} diff --git a/world-chain-builder/src/rpc/mod.rs b/world-chain-builder/src/rpc/mod.rs index 00effe91..ced4c376 100644 --- a/world-chain-builder/src/rpc/mod.rs +++ b/world-chain-builder/src/rpc/mod.rs @@ -1,270 +1 @@ -//! OP-Reth `eth_` endpoint implementation. - -mod block; pub mod bundle; -mod call; -mod pending_block; -pub mod receipt; -pub mod transaction; -use alloy_primitives::U256; -use alloy_rpc_types::TransactionInfo; -use derive_more::derive::Deref; -use op_alloy_network::Optimism; -use op_alloy_rpc_types::Transaction; -use reth::api::{ConfigureEvm, FullNodeComponents}; -use reth::builder::EthApiBuilderCtx; -use reth::chainspec::{EthChainSpec, EthereumHardforks}; - -use reth::network::NetworkInfo; -use reth::rpc::api::eth::helpers::{ - AddDevSigners, EthApiSpec, EthFees, EthState, LoadBlock, LoadFee, LoadState, SpawnBlocking, - Trace, -}; - -use reth::rpc::api::eth::RpcNodeCoreExt; -use reth::rpc::compat::TransactionCompat; -use reth::rpc::eth::{EthApiTypes, RpcNodeCore}; -use reth::rpc::server_types::eth::{EthStateCache, FeeHistoryCache, GasPriceOracle}; -use reth::tasks::{ - pool::{BlockingTaskGuard, BlockingTaskPool}, - TaskSpawner, -}; -use reth::transaction_pool::TransactionPool; -use reth_optimism_rpc::{OpEthApi, OpEthApiError}; -use reth_primitives::{Header, TransactionSignedEcRecovered}; -use reth_provider::{ - BlockNumReader, BlockReaderIdExt, CanonStateSubscriptions, ChainSpecProvider, EvmEnvProvider, - StageCheckpointReader, StateProviderFactory, -}; -use std::fmt; - -/// OP-Reth `Eth` API implementation. -/// -/// This type provides the functionality for handling `eth_` related requests. -/// -/// This wraps a default `Eth` implementation, and provides additional functionality where the -/// optimism spec deviates from the default (ethereum) spec, e.g. transaction forwarding to the -/// sequencer, receipts, additional RPC fields for transaction receipts. -/// -/// This type implements the [`FullEthApi`](reth_rpc_eth_api::helpers::FullEthApi) by implemented -/// all the `Eth` helper traits and prerequisite traits. -#[derive(Clone, Deref)] -pub struct WorldChainEthApi { - #[deref] - inner: OpEthApi, -} - -impl WorldChainEthApi -where - N: RpcNodeCore< - Provider: BlockReaderIdExt + ChainSpecProvider + CanonStateSubscriptions + Clone + 'static, - >, -{ - /// Creates a new instance for given context. - #[allow(clippy::type_complexity)] - pub fn new(ctx: &EthApiBuilderCtx, sequencer_http: Option) -> Self { - let op_builder_ctx = EthApiBuilderCtx:: { - provider: ctx.provider.clone(), - pool: ctx.pool.clone(), - network: ctx.network.clone(), - evm_config: ctx.evm_config.clone(), - config: ctx.config.clone(), - executor: ctx.executor.clone(), - events: ctx.events.clone(), - cache: ctx.cache.clone(), - }; - - let inner = OpEthApi::new(&op_builder_ctx, sequencer_http); - Self { inner } - } -} - -impl EthApiTypes for WorldChainEthApi -where - Self: Send + Sync, - N: RpcNodeCore, -{ - type Error = OpEthApiError; - type NetworkTypes = Optimism; - type TransactionCompat = Self; - - fn tx_resp_builder(&self) -> &Self::TransactionCompat { - self - } -} - -impl EthApiSpec for WorldChainEthApi -where - N: RpcNodeCore< - Provider: ChainSpecProvider - + BlockNumReader - + StageCheckpointReader, - Network: NetworkInfo, - >, -{ - #[inline] - fn starting_block(&self) -> U256 { - self.inner.starting_block() - } - - #[inline] - fn signers( - &self, - ) -> &parking_lot::RwLock>> { - self.inner.signers() - } -} - -impl RpcNodeCore for WorldChainEthApi -where - N: RpcNodeCore, -{ - type Provider = N::Provider; - type Pool = N::Pool; - type Network = ::Network; - type Evm = ::Evm; - - #[inline] - fn pool(&self) -> &Self::Pool { - self.inner.pool() - } - - #[inline] - fn evm_config(&self) -> &Self::Evm { - self.inner.evm_config() - } - - #[inline] - fn network(&self) -> &Self::Network { - self.inner.network() - } - - #[inline] - fn provider(&self) -> &Self::Provider { - self.inner.provider() - } -} - -impl SpawnBlocking for WorldChainEthApi -where - Self: Send + Sync + Clone + 'static, - N: RpcNodeCore, -{ - #[inline] - fn io_task_spawner(&self) -> impl TaskSpawner { - self.inner.io_task_spawner() - } - - #[inline] - fn tracing_task_pool(&self) -> &BlockingTaskPool { - self.inner.tracing_task_pool() - } - - #[inline] - fn tracing_task_guard(&self) -> &BlockingTaskGuard { - self.inner.tracing_task_guard() - } -} - -impl LoadFee for WorldChainEthApi -where - Self: LoadBlock, - N: RpcNodeCore< - Provider: BlockReaderIdExt - + EvmEnvProvider - + ChainSpecProvider - + StateProviderFactory, - >, -{ - #[inline] - fn gas_oracle(&self) -> &GasPriceOracle { - self.inner.gas_oracle() - } - - #[inline] - fn fee_history_cache(&self) -> &FeeHistoryCache { - self.inner.fee_history_cache() - } -} - -impl LoadState for WorldChainEthApi where - N: RpcNodeCore< - Provider: StateProviderFactory + ChainSpecProvider, - Pool: TransactionPool, - > -{ -} - -impl EthState for WorldChainEthApi -where - Self: LoadState + SpawnBlocking, - OpEthApi: LoadState + SpawnBlocking, - N: RpcNodeCore, -{ - #[inline] - fn max_proof_window(&self) -> u64 { - self.inner.max_proof_window() - } -} - -impl EthFees for WorldChainEthApi -where - Self: LoadFee, - N: RpcNodeCore, -{ -} - -impl Trace for WorldChainEthApi -where - Self: LoadState>, - N: RpcNodeCore, -{ -} - -impl TransactionCompat for WorldChainEthApi -where - N: FullNodeComponents, -{ - type Transaction = Transaction; - - fn fill( - &self, - tx: TransactionSignedEcRecovered, - tx_info: TransactionInfo, - ) -> Self::Transaction { - self.inner.fill(tx, tx_info) - } - - fn otterscan_api_truncate_input(tx: &mut Self::Transaction) { - OpEthApi::::otterscan_api_truncate_input(tx) - } - - fn tx_type(tx: &Self::Transaction) -> u8 { - OpEthApi::::tx_type(tx) - } -} - -impl AddDevSigners for WorldChainEthApi -where - N: RpcNodeCore, -{ - fn with_dev_accounts(&self) { - self.inner.with_dev_accounts() - } -} - -impl RpcNodeCoreExt for WorldChainEthApi -where - N: RpcNodeCore, -{ - #[inline] - fn cache(&self) -> &EthStateCache { - self.inner.cache() - } -} - -impl fmt::Debug for WorldChainEthApi { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("WorldChainEthApi").finish_non_exhaustive() - } -} diff --git a/world-chain-builder/src/rpc/pending_block.rs b/world-chain-builder/src/rpc/pending_block.rs deleted file mode 100644 index dbdfa1c9..00000000 --- a/world-chain-builder/src/rpc/pending_block.rs +++ /dev/null @@ -1,51 +0,0 @@ -//! Loads OP pending block for a RPC response. - -use crate::rpc::WorldChainEthApi; -use alloy_primitives::{BlockNumber, B256}; -use reth::api::ConfigureEvm; -use reth::chainspec::{EthChainSpec, EthereumHardforks}; -use reth::rpc::api::eth::helpers::{LoadPendingBlock, SpawnBlocking}; -use reth::rpc::eth::{EthApiTypes, RpcNodeCore}; -use reth::rpc::server_types::eth::PendingBlock; -use reth::transaction_pool::TransactionPool; -use reth_optimism_rpc::OpEthApi; -use reth_primitives::{revm_primitives::BlockEnv, Header, Receipt, SealedBlockWithSenders}; -use reth_provider::{ - BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, ExecutionOutcome, StateProviderFactory, -}; - -impl LoadPendingBlock for WorldChainEthApi -where - Self: SpawnBlocking, - N: RpcNodeCore< - Provider: BlockReaderIdExt - + EvmEnvProvider - + ChainSpecProvider - + StateProviderFactory, - Pool: TransactionPool, - Evm: ConfigureEvm
, - >, - Self::Error: From< as EthApiTypes>::Error>, -{ - #[inline] - fn pending_block(&self) -> &tokio::sync::Mutex> { - self.inner.pending_block() - } - - /// Returns the locally built pending block - async fn local_pending_block( - &self, - ) -> Result)>, Self::Error> { - Ok(self.inner.local_pending_block().await?) - } - - fn receipts_root( - &self, - _block_env: &BlockEnv, - execution_outcome: &ExecutionOutcome, - block_number: BlockNumber, - ) -> B256 { - self.inner - .receipts_root(_block_env, execution_outcome, block_number) - } -} diff --git a/world-chain-builder/src/rpc/receipt.rs b/world-chain-builder/src/rpc/receipt.rs deleted file mode 100644 index 93e72119..00000000 --- a/world-chain-builder/src/rpc/receipt.rs +++ /dev/null @@ -1,26 +0,0 @@ -//! Loads and formats OP receipt RPC response. - -use crate::rpc::WorldChainEthApi; -use reth::{ - api::{FullNodeComponents, NodeTypes}, - rpc::api::eth::{helpers::LoadReceipt, RpcReceipt}, -}; -use reth_optimism_chainspec::OpChainSpec; -use reth_primitives::{Receipt, TransactionMeta, TransactionSigned}; - -impl LoadReceipt for WorldChainEthApi -where - Self: Send + Sync, - N: FullNodeComponents>, -{ - async fn build_transaction_receipt( - &self, - tx: TransactionSigned, - meta: TransactionMeta, - receipt: Receipt, - ) -> Result, Self::Error> { - self.inner - .build_transaction_receipt(tx, meta, receipt) - .await - } -} diff --git a/world-chain-builder/src/rpc/transaction.rs b/world-chain-builder/src/rpc/transaction.rs deleted file mode 100644 index 95550bc4..00000000 --- a/world-chain-builder/src/rpc/transaction.rs +++ /dev/null @@ -1,71 +0,0 @@ -//! Loads and formats OP transaction RPC response. - -use crate::pool::tx::WorldChainPooledTransaction; -use crate::{primitives::recover_raw_transaction, rpc::WorldChainEthApi}; - -use alloy_primitives::{Bytes, B256}; -use reth::rpc::api::eth::helpers::{EthSigner, EthTransactions, LoadTransaction, SpawnBlocking}; -use reth::rpc::api::eth::{FromEthApiError, FullEthApiTypes}; -use reth::rpc::eth::RpcNodeCore; -use reth::transaction_pool::{PoolTransaction, TransactionOrigin, TransactionPool}; -use reth_optimism_rpc::SequencerClient; -use reth_provider::{BlockReaderIdExt, TransactionsProvider}; - -impl EthTransactions for WorldChainEthApi -where - Self: LoadTransaction< - Pool: TransactionPool, - Provider: BlockReaderIdExt, - >, - N: RpcNodeCore, -{ - fn signers(&self) -> &parking_lot::RwLock>> { - self.inner.signers() - } - - /// Decodes and recovers the transaction and submits it to the pool. - /// - /// Returns the hash of the transaction. - async fn send_raw_transaction(&self, tx: Bytes) -> Result { - let (recovered, inner_tx) = recover_raw_transaction(tx.clone())?; - let pool_transaction = ::Transaction::from_pooled(recovered); - let pbh_tx = pool_transaction.pbh_payload.is_some(); - - // submit the transaction to the pool with a `Local` origin - let hash = self - .pool() - .add_transaction(TransactionOrigin::Local, pool_transaction) - .await - .map_err(Self::Error::from_eth_err)?; - - // On optimism, transactions are forwarded directly to the sequencer to be included in - // blocks that it builds. - if let Some(client) = self.raw_tx_forwarder().as_ref() { - if !pbh_tx { - tracing::debug!( target: "rpc::eth", "forwarding raw transaction to"); - let _ = client.forward_raw_transaction(&inner_tx).await.inspect_err(|err| { - tracing::debug!(target: "rpc::eth", %err, hash=?*hash, "failed to forward raw transaction"); - }); - } - } - - Ok(hash) - } -} - -impl LoadTransaction for WorldChainEthApi -where - Self: SpawnBlocking + FullEthApiTypes, - N: RpcNodeCore, -{ -} - -impl WorldChainEthApi -where - N: RpcNodeCore, -{ - /// Returns the [`SequencerClient`] if one is set. - pub fn raw_tx_forwarder(&self) -> Option { - self.inner.raw_tx_forwarder() - } -} diff --git a/world-chain-builder/src/test/e2e/mod.rs b/world-chain-builder/src/test/e2e/mod.rs index d43ca667..11ac593c 100644 --- a/world-chain-builder/src/test/e2e/mod.rs +++ b/world-chain-builder/src/test/e2e/mod.rs @@ -1,396 +1,396 @@ -//! Utilities for running world chain builder end-to-end tests. -use crate::{ - node::{ - args::{ExtArgs, WorldChainBuilderArgs}, - builder::{WorldChainAddOns, WorldChainBuilder}, - }, - pbh::{ - date_marker::DateMarker, - external_nullifier::{ExternalNullifier, Prefix}, - payload::{PbhPayload, Proof}, - }, - pool::{ - ordering::WorldChainOrdering, - root::{LATEST_ROOT_SLOT, OP_WORLD_ID}, - tx::WorldChainPooledTransaction, - validator::WorldChainTransactionValidator, - }, - primitives::WorldChainPooledTransactionsElement, - rpc::bundle::{EthTransactionsExtServer, WorldChainEthApiExt}, -}; -use alloy_eips::eip2718::Decodable2718; -use alloy_genesis::{Genesis, GenesisAccount}; -use alloy_network::eip2718::Encodable2718; -use alloy_network::{Ethereum, EthereumWallet, TransactionBuilder}; -use alloy_rpc_types::{TransactionInput, TransactionRequest}; -use alloy_signer_local::PrivateKeySigner; -use chrono::Utc; -use reth::payload::{EthPayloadBuilderAttributes, PayloadId}; -use reth::tasks::TaskManager; -use reth::transaction_pool::{blobstore::DiskFileBlobStore, TransactionValidationTaskExecutor}; -use reth::{ - api::{FullNodeTypesAdapter, NodeTypesWithDBAdapter}, - builder::components::Components, -}; -use reth::{ - builder::{NodeAdapter, NodeBuilder, NodeConfig, NodeHandle}, - transaction_pool::Pool, -}; -use reth_db::{ - test_utils::{tempdir_path, TempDatabase}, - DatabaseEnv, -}; -use reth_e2e_test_utils::{ - node::NodeTestContext, transaction::TransactionTestContext, wallet::Wallet, -}; -use reth_evm::execute::BasicBlockExecutorProvider; -use reth_node_core::args::RpcServerArgs; -use reth_optimism_chainspec::{OpChainSpec, OpChainSpecBuilder}; -use reth_optimism_evm::{OpExecutionStrategyFactory, OptimismEvmConfig}; -use reth_optimism_node::OptimismPayloadBuilderAttributes; -use reth_primitives::{PooledTransactionsElement, Withdrawals}; -use reth_provider::providers::BlockchainProvider; -use revm_primitives::{Address, Bytes, FixedBytes, TxKind, B256, U256}; -use semaphore::{ - hash_to_field, - identity::Identity, - poseidon_tree::LazyPoseidonTree, - protocol::{generate_nullifier_hash, generate_proof}, - Field, -}; -use serial_test::serial; -use std::{ - collections::{BTreeMap, HashMap}, - sync::Arc, - time::Duration, -}; - -pub const DEV_CHAIN_ID: u64 = 8453; - -type NodeAdapterType = NodeAdapter< - FullNodeTypesAdapter< - NodeTypesWithDBAdapter>>, - BlockchainProvider< - NodeTypesWithDBAdapter>>, - >, - >, - Components< - FullNodeTypesAdapter< - NodeTypesWithDBAdapter>>, - BlockchainProvider< - NodeTypesWithDBAdapter>>, - >, - >, - Pool< - TransactionValidationTaskExecutor< - WorldChainTransactionValidator< - BlockchainProvider< - NodeTypesWithDBAdapter>>, - >, - WorldChainPooledTransaction, - >, - >, - WorldChainOrdering, - DiskFileBlobStore, - >, - OptimismEvmConfig, - BasicBlockExecutorProvider, - Arc<(dyn reth_consensus::Consensus + 'static)>, - >, ->; - -type Adapter = NodeTestContext>; - -pub struct WorldChainBuilderTestContext { - pub pbh_wallets: Vec, - pub tree: LazyPoseidonTree, - pub tasks: TaskManager, - pub node: Adapter, - pub identities: HashMap, -} - -impl WorldChainBuilderTestContext { - pub async fn setup() -> eyre::Result { - let wallets = Wallet::new(20).with_chain_id(DEV_CHAIN_ID).gen(); - let mut tree = LazyPoseidonTree::new(30, Field::from(0)).derived(); - let mut identities = HashMap::new(); - for (i, signer) in wallets.iter().enumerate() { - let address = signer.address(); - identities.insert(address, i); - let identity = Identity::from_secret(signer.address().as_mut_slice(), None); - tree = tree.update(i, &identity.commitment()); - } - - let op_chain_spec = Arc::new(get_chain_spec(tree.root())); - - let tasks = TaskManager::current(); - let exec = tasks.executor(); - - let node_config: NodeConfig = NodeConfig::new(op_chain_spec.clone()) - .with_chain(op_chain_spec.clone()) - .with_unused_ports() - .with_rpc( - RpcServerArgs::default() - .with_unused_ports() - .with_http_unused_port(), - ); - let path = tempdir_path(); - let NodeHandle { - node, - node_exit_future: _, - } = NodeBuilder::new(node_config.clone()) - .testing_node(exec.clone()) - .node(WorldChainBuilder::new( - ExtArgs { - builder_args: WorldChainBuilderArgs { - num_pbh_txs: 30, - verified_blockspace_capacity: 70, - ..Default::default() - }, - ..Default::default() - }, - &path, - )?) - .extend_rpc_modules(move |ctx| { - let provider = ctx.provider().clone(); - let pool = ctx.pool().clone(); - let eth_api_ext = WorldChainEthApiExt::new(pool, provider); - ctx.modules.merge_configured(eth_api_ext.into_rpc())?; - Ok(()) - }) - .launch() - .await?; - let test_ctx = NodeTestContext::new(node, optimism_payload_attributes).await?; - Ok(Self { - pbh_wallets: wallets, - tree, - tasks, - node: test_ctx, - identities, - }) - } - - pub async fn raw_pbh_tx_bytes( - &self, - signer: PrivateKeySigner, - pbh_nonce: u16, - tx_nonce: u64, - ) -> Bytes { - let tx = tx(DEV_CHAIN_ID, None, tx_nonce); - let envelope = TransactionTestContext::sign_tx(signer.clone(), tx).await; - let raw_tx = envelope.encoded_2718(); - let mut data = raw_tx.as_ref(); - let recovered = PooledTransactionsElement::decode_2718(&mut data).unwrap(); - let pbh_payload = self.valid_proof( - signer.address(), - recovered.hash().as_slice(), - chrono::Utc::now(), - pbh_nonce, - ); - - let world_chain_pooled_tx_element = WorldChainPooledTransactionsElement { - inner: recovered, - pbh_payload: Some(pbh_payload.clone()), - }; - - let mut buff = Vec::::new(); - world_chain_pooled_tx_element.encode_2718(&mut buff); - buff.into() - } - - fn valid_proof( - &self, - identity: Address, - tx_hash: &[u8], - time: chrono::DateTime, - pbh_nonce: u16, - ) -> PbhPayload { - let external_nullifier = - ExternalNullifier::new(Prefix::V1, DateMarker::from(time), pbh_nonce).to_string(); - - self.create_proof(identity, external_nullifier, tx_hash) - } - - fn create_proof( - &self, - mut identity: Address, - external_nullifier: String, - signal: &[u8], - ) -> PbhPayload { - let idx = self.identities.get(&identity).unwrap(); - let secret = identity.as_mut_slice(); - // generate identity - let id = Identity::from_secret(secret, None); - let merkle_proof = self.tree.proof(*idx); - - let signal_hash = hash_to_field(signal); - let external_nullifier_hash = hash_to_field(external_nullifier.as_bytes()); - let nullifier_hash = generate_nullifier_hash(&id, external_nullifier_hash); - - let proof = Proof( - generate_proof(&id, &merkle_proof, external_nullifier_hash, signal_hash).unwrap(), - ); - - PbhPayload { - root: self.tree.root(), - nullifier_hash, - external_nullifier, - proof, - } - } -} - -#[tokio::test] -#[serial] -async fn test_can_build_pbh_payload() -> eyre::Result<()> { - tokio::time::sleep(Duration::from_secs(1)).await; - let mut ctx = WorldChainBuilderTestContext::setup().await?; - let mut pbh_tx_hashes = vec![]; - for signer in ctx.pbh_wallets.iter() { - let raw_tx = ctx.raw_pbh_tx_bytes(signer.clone(), 0, 0).await; - let pbh_hash = ctx.node.rpc.inject_tx(raw_tx.clone()).await?; - pbh_tx_hashes.push(pbh_hash); - } - - let (payload, _) = ctx.node.advance_block().await?; - - assert_eq!(payload.block().body.transactions.len(), pbh_tx_hashes.len()); - let block_hash = payload.block().hash(); - let block_number = payload.block().number; - - let tip = pbh_tx_hashes[0]; - ctx.node - .assert_new_block(tip, block_hash, block_number) - .await?; - - Ok(()) -} - -#[tokio::test] -#[serial] -async fn test_transaction_pool_ordering() -> eyre::Result<()> { - tokio::time::sleep(Duration::from_secs(1)).await; - let mut ctx = WorldChainBuilderTestContext::setup().await?; - let non_pbh_tx = tx(ctx.node.inner.chain_spec().chain.id(), None, 0); - let wallet = ctx.pbh_wallets[0].clone(); - let signer = EthereumWallet::from(wallet); - let signed = >::build(non_pbh_tx, &signer) - .await - .unwrap(); - let non_pbh_hash = ctx.node.rpc.inject_tx(signed.encoded_2718().into()).await?; - let mut pbh_tx_hashes = vec![]; - for signer in ctx.pbh_wallets.iter().skip(1) { - let raw_tx = ctx.raw_pbh_tx_bytes(signer.clone(), 0, 0).await; - let pbh_hash = ctx.node.rpc.inject_tx(raw_tx.clone()).await?; - pbh_tx_hashes.push(pbh_hash); - } - - let (payload, _) = ctx.node.advance_block().await?; - - assert_eq!( - payload.block().body.transactions.len(), - pbh_tx_hashes.len() + 1 - ); - // Assert the non-pbh transaction is included in the block last - assert_eq!( - payload.block().body.transactions.last().unwrap().hash(), - non_pbh_hash - ); - let block_hash = payload.block().hash(); - let block_number = payload.block().number; - - let tip = pbh_tx_hashes[0]; - ctx.node - .assert_new_block(tip, block_hash, block_number) - .await?; - - Ok(()) -} - -#[tokio::test] -#[serial] -async fn test_invalidate_dup_tx_and_nullifier() -> eyre::Result<()> { - tokio::time::sleep(Duration::from_secs(1)).await; - let ctx = WorldChainBuilderTestContext::setup().await?; - let signer = ctx.pbh_wallets[0].clone(); - let raw_tx = ctx.raw_pbh_tx_bytes(signer.clone(), 0, 0).await; - ctx.node.rpc.inject_tx(raw_tx.clone()).await?; - let dup_pbh_hash_res = ctx.node.rpc.inject_tx(raw_tx.clone()).await; - assert!(dup_pbh_hash_res.is_err()); - Ok(()) -} - -#[tokio::test] -#[serial] -async fn test_dup_pbh_nonce() -> eyre::Result<()> { - tokio::time::sleep(Duration::from_secs(1)).await; - let mut ctx = WorldChainBuilderTestContext::setup().await?; - let signer = ctx.pbh_wallets[0].clone(); - - let raw_tx_0 = ctx.raw_pbh_tx_bytes(signer.clone(), 0, 0).await; - ctx.node.rpc.inject_tx(raw_tx_0.clone()).await?; - let raw_tx_1 = ctx.raw_pbh_tx_bytes(signer.clone(), 0, 1).await; - - // Now that the nullifier has successfully been stored in - // the `ExecutedPbhNullifierTable`, inserting a new tx with the - // same pbh_nonce should fail to validate. - assert!(ctx.node.rpc.inject_tx(raw_tx_1.clone()).await.is_err()); - - let (payload, _) = ctx.node.advance_block().await?; - - // One transaction should be successfully validated - // and included in the block. - assert_eq!(payload.block().body.transactions.len(), 1); - - Ok(()) -} - -/// Helper function to create a new eth payload attributes -pub fn optimism_payload_attributes(timestamp: u64) -> OptimismPayloadBuilderAttributes { - let attributes = EthPayloadBuilderAttributes { - timestamp, - prev_randao: B256::ZERO, - suggested_fee_recipient: Address::ZERO, - withdrawals: Withdrawals::default(), - parent_beacon_block_root: Some(B256::ZERO), - id: PayloadId(FixedBytes::<8>::random()), - parent: FixedBytes::default(), - }; - - OptimismPayloadBuilderAttributes { - payload_attributes: attributes, - transactions: vec![], - gas_limit: None, - no_tx_pool: false, - } -} - -fn tx(chain_id: u64, data: Option, nonce: u64) -> TransactionRequest { - TransactionRequest { - nonce: Some(nonce), - value: Some(U256::from(100)), - to: Some(TxKind::Call(Address::random())), - gas: Some(210000), - max_fee_per_gas: Some(20e10 as u128), - max_priority_fee_per_gas: Some(20e10 as u128), - chain_id: Some(chain_id), - input: TransactionInput { input: None, data }, - ..Default::default() - } -} - -/// Builds an OP Mainnet chain spec with the given merkle root -/// Populated in the OpWorldID contract. -fn get_chain_spec(merkle_root: Field) -> OpChainSpec { - let genesis: Genesis = serde_json::from_str(include_str!("assets/genesis.json")).unwrap(); - OpChainSpecBuilder::base_mainnet() - .genesis(genesis.extend_accounts(vec![( - OP_WORLD_ID, - GenesisAccount::default().with_storage(Some(BTreeMap::from_iter(vec![( - LATEST_ROOT_SLOT.into(), - merkle_root.into(), - )]))), - )])) - .ecotone_activated() - .build() -} +// //! Utilities for running world chain builder end-to-end tests. +// use crate::{ +// node::{ +// args::{ExtArgs, WorldChainBuilderArgs}, +// builder::{WorldChainAddOns, WorldChainBuilder}, +// }, +// pbh::{ +// date_marker::DateMarker, +// external_nullifier::{ExternalNullifier, Prefix}, +// payload::{PbhPayload, Proof}, +// }, +// pool::{ +// ordering::WorldChainOrdering, +// root::{LATEST_ROOT_SLOT, OP_WORLD_ID}, +// tx::WorldChainPooledTransaction, +// validator::WorldChainTransactionValidator, +// }, +// primitives::WorldChainPooledTransactionsElement, +// rpc::bundle::{EthTransactionsExtServer, WorldChainEthApiExt}, +// }; +// use alloy_eips::eip2718::Decodable2718; +// use alloy_genesis::{Genesis, GenesisAccount}; +// use alloy_network::eip2718::Encodable2718; +// use alloy_network::{Ethereum, EthereumWallet, TransactionBuilder}; +// use alloy_rpc_types::{TransactionInput, TransactionRequest}; +// use alloy_signer_local::PrivateKeySigner; +// use chrono::Utc; +// use reth::payload::{EthPayloadBuilderAttributes, PayloadId}; +// use reth::tasks::TaskManager; +// use reth::transaction_pool::{blobstore::DiskFileBlobStore, TransactionValidationTaskExecutor}; +// use reth::{ +// api::{FullNodeTypesAdapter, NodeTypesWithDBAdapter}, +// builder::components::Components, +// }; +// use reth::{ +// builder::{NodeAdapter, NodeBuilder, NodeConfig, NodeHandle}, +// transaction_pool::Pool, +// }; +// use reth_db::{ +// test_utils::{tempdir_path, TempDatabase}, +// DatabaseEnv, +// }; +// use reth_e2e_test_utils::{ +// node::NodeTestContext, transaction::TransactionTestContext, wallet::Wallet, +// }; +// use reth_evm::execute::BasicBlockExecutorProvider; +// use reth_node_core::args::RpcServerArgs; +// use reth_optimism_chainspec::{OpChainSpec, OpChainSpecBuilder}; +// use reth_optimism_evm::{OpEvmConfig, OpExecutionStrategyFactory}; +// use reth_optimism_node::OpPayloadBuilderAttributes; +// use reth_primitives::PooledTransactionsElement; +// use reth_provider::providers::BlockchainProvider; +// use revm_primitives::{Address, Bytes, FixedBytes, TxKind, B256, U256}; +// use semaphore::{ +// hash_to_field, +// identity::Identity, +// poseidon_tree::LazyPoseidonTree, +// protocol::{generate_nullifier_hash, generate_proof}, +// Field, +// }; +// use serial_test::serial; +// use std::{ +// collections::{BTreeMap, HashMap}, +// sync::Arc, +// time::Duration, +// }; + +// pub const DEV_CHAIN_ID: u64 = 8453; + +// type NodeAdapterType = NodeAdapter< +// FullNodeTypesAdapter< +// NodeTypesWithDBAdapter>>, +// BlockchainProvider< +// NodeTypesWithDBAdapter>>, +// >, +// >, +// Components< +// FullNodeTypesAdapter< +// NodeTypesWithDBAdapter>>, +// BlockchainProvider< +// NodeTypesWithDBAdapter>>, +// >, +// >, +// Pool< +// TransactionValidationTaskExecutor< +// WorldChainTransactionValidator< +// BlockchainProvider< +// NodeTypesWithDBAdapter>>, +// >, +// WorldChainPooledTransaction, +// >, +// >, +// WorldChainOrdering, +// DiskFileBlobStore, +// >, +// OpEvmConfig, +// BasicBlockExecutorProvider, +// Arc<(dyn reth_consensus::Consensus + 'static)>, +// >, +// >; + +// type Adapter = NodeTestContext>; + +// pub struct WorldChainBuilderTestContext { +// pub pbh_wallets: Vec, +// pub tree: LazyPoseidonTree, +// pub tasks: TaskManager, +// pub node: Adapter, +// pub identities: HashMap, +// } + +// impl WorldChainBuilderTestContext { +// pub async fn setup() -> eyre::Result { +// let wallets = Wallet::new(20).with_chain_id(DEV_CHAIN_ID).gen(); +// let mut tree = LazyPoseidonTree::new(30, Field::from(0)).derived(); +// let mut identities = HashMap::new(); +// for (i, signer) in wallets.iter().enumerate() { +// let address = signer.address(); +// identities.insert(address, i); +// let identity = Identity::from_secret(signer.address().as_mut_slice(), None); +// tree = tree.update(i, &identity.commitment()); +// } + +// let op_chain_spec = Arc::new(get_chain_spec(tree.root())); + +// let tasks = TaskManager::current(); +// let exec = tasks.executor(); + +// let node_config: NodeConfig = NodeConfig::new(op_chain_spec.clone()) +// .with_chain(op_chain_spec.clone()) +// .with_unused_ports() +// .with_rpc( +// RpcServerArgs::default() +// .with_unused_ports() +// .with_http_unused_port(), +// ); +// let path = tempdir_path(); +// let NodeHandle { +// node, +// node_exit_future: _, +// } = NodeBuilder::new(node_config.clone()) +// .testing_node(exec.clone()) +// .node(WorldChainBuilder::new( +// ExtArgs { +// builder_args: WorldChainBuilderArgs { +// num_pbh_txs: 30, +// verified_blockspace_capacity: 70, +// ..Default::default() +// }, +// ..Default::default() +// }, +// &path, +// )?) +// .extend_rpc_modules(move |ctx| { +// let provider = ctx.provider().clone(); +// let pool = ctx.pool().clone(); +// let eth_api_ext = WorldChainEthApiExt::new(pool, provider); +// ctx.modules.merge_configured(eth_api_ext.into_rpc())?; +// Ok(()) +// }) +// .launch() +// .await?; +// let test_ctx = NodeTestContext::new(node, optimism_payload_attributes).await?; +// Ok(Self { +// pbh_wallets: wallets, +// tree, +// tasks, +// node: test_ctx, +// identities, +// }) +// } + +// pub async fn raw_pbh_tx_bytes( +// &self, +// signer: PrivateKeySigner, +// pbh_nonce: u16, +// tx_nonce: u64, +// ) -> Bytes { +// let tx = tx(DEV_CHAIN_ID, None, tx_nonce); +// let envelope = TransactionTestContext::sign_tx(signer.clone(), tx).await; +// let raw_tx = envelope.encoded_2718(); +// let mut data = raw_tx.as_ref(); +// let recovered = PooledTransactionsElement::decode_2718(&mut data).unwrap(); +// let pbh_payload = self.valid_proof( +// signer.address(), +// recovered.hash().as_slice(), +// chrono::Utc::now(), +// pbh_nonce, +// ); + +// let world_chain_pooled_tx_element = WorldChainPooledTransactionsElement { +// inner: recovered, +// pbh_payload: Some(pbh_payload.clone()), +// }; + +// let mut buff = Vec::::new(); +// world_chain_pooled_tx_element.encode_2718(&mut buff); +// buff.into() +// } + +// fn valid_proof( +// &self, +// identity: Address, +// tx_hash: &[u8], +// time: chrono::DateTime, +// pbh_nonce: u16, +// ) -> PbhPayload { +// let external_nullifier = +// ExternalNullifier::new(Prefix::V1, DateMarker::from(time), pbh_nonce).to_string(); + +// self.create_proof(identity, external_nullifier, tx_hash) +// } + +// fn create_proof( +// &self, +// mut identity: Address, +// external_nullifier: String, +// signal: &[u8], +// ) -> PbhPayload { +// let idx = self.identities.get(&identity).unwrap(); +// let secret = identity.as_mut_slice(); +// // generate identity +// let id = Identity::from_secret(secret, None); +// let merkle_proof = self.tree.proof(*idx); + +// let signal_hash = hash_to_field(signal); +// let external_nullifier_hash = hash_to_field(external_nullifier.as_bytes()); +// let nullifier_hash = generate_nullifier_hash(&id, external_nullifier_hash); + +// let proof = Proof( +// generate_proof(&id, &merkle_proof, external_nullifier_hash, signal_hash).unwrap(), +// ); + +// PbhPayload { +// root: self.tree.root(), +// nullifier_hash, +// external_nullifier, +// proof, +// } +// } +// } + +// #[tokio::test] +// #[serial] +// async fn test_can_build_pbh_payload() -> eyre::Result<()> { +// tokio::time::sleep(Duration::from_secs(1)).await; +// let mut ctx = WorldChainBuilderTestContext::setup().await?; +// let mut pbh_tx_hashes = vec![]; +// for signer in ctx.pbh_wallets.iter() { +// let raw_tx = ctx.raw_pbh_tx_bytes(signer.clone(), 0, 0).await; +// let pbh_hash = ctx.node.rpc.inject_tx(raw_tx.clone()).await?; +// pbh_tx_hashes.push(pbh_hash); +// } + +// let (payload, _) = ctx.node.advance_block().await?; + +// assert_eq!(payload.block().body.transactions.len(), pbh_tx_hashes.len()); +// let block_hash = payload.block().hash(); +// let block_number = payload.block().number; + +// let tip = pbh_tx_hashes[0]; +// ctx.node +// .assert_new_block(tip, block_hash, block_number) +// .await?; + +// Ok(()) +// } + +// #[tokio::test] +// #[serial] +// async fn test_transaction_pool_ordering() -> eyre::Result<()> { +// tokio::time::sleep(Duration::from_secs(1)).await; +// let mut ctx = WorldChainBuilderTestContext::setup().await?; +// let non_pbh_tx = tx(ctx.node.inner.chain_spec().chain.id(), None, 0); +// let wallet = ctx.pbh_wallets[0].clone(); +// let signer = EthereumWallet::from(wallet); +// let signed = >::build(non_pbh_tx, &signer) +// .await +// .unwrap(); +// let non_pbh_hash = ctx.node.rpc.inject_tx(signed.encoded_2718().into()).await?; +// let mut pbh_tx_hashes = vec![]; +// for signer in ctx.pbh_wallets.iter().skip(1) { +// let raw_tx = ctx.raw_pbh_tx_bytes(signer.clone(), 0, 0).await; +// let pbh_hash = ctx.node.rpc.inject_tx(raw_tx.clone()).await?; +// pbh_tx_hashes.push(pbh_hash); +// } + +// let (payload, _) = ctx.node.advance_block().await?; + +// assert_eq!( +// payload.block().body.transactions.len(), +// pbh_tx_hashes.len() + 1 +// ); +// // Assert the non-pbh transaction is included in the block last +// assert_eq!( +// payload.block().body.transactions.last().unwrap().hash(), +// non_pbh_hash +// ); +// let block_hash = payload.block().hash(); +// let block_number = payload.block().number; + +// let tip = pbh_tx_hashes[0]; +// ctx.node +// .assert_new_block(tip, block_hash, block_number) +// .await?; + +// Ok(()) +// } + +// #[tokio::test] +// #[serial] +// async fn test_invalidate_dup_tx_and_nullifier() -> eyre::Result<()> { +// tokio::time::sleep(Duration::from_secs(1)).await; +// let ctx = WorldChainBuilderTestContext::setup().await?; +// let signer = ctx.pbh_wallets[0].clone(); +// let raw_tx = ctx.raw_pbh_tx_bytes(signer.clone(), 0, 0).await; +// ctx.node.rpc.inject_tx(raw_tx.clone()).await?; +// let dup_pbh_hash_res = ctx.node.rpc.inject_tx(raw_tx.clone()).await; +// assert!(dup_pbh_hash_res.is_err()); +// Ok(()) +// } + +// #[tokio::test] +// #[serial] +// async fn test_dup_pbh_nonce() -> eyre::Result<()> { +// tokio::time::sleep(Duration::from_secs(1)).await; +// let mut ctx = WorldChainBuilderTestContext::setup().await?; +// let signer = ctx.pbh_wallets[0].clone(); + +// let raw_tx_0 = ctx.raw_pbh_tx_bytes(signer.clone(), 0, 0).await; +// ctx.node.rpc.inject_tx(raw_tx_0.clone()).await?; +// let raw_tx_1 = ctx.raw_pbh_tx_bytes(signer.clone(), 0, 1).await; + +// // Now that the nullifier has successfully been stored in +// // the `ExecutedPbhNullifierTable`, inserting a new tx with the +// // same pbh_nonce should fail to validate. +// assert!(ctx.node.rpc.inject_tx(raw_tx_1.clone()).await.is_err()); + +// let (payload, _) = ctx.node.advance_block().await?; + +// // One transaction should be successfully validated +// // and included in the block. +// assert_eq!(payload.block().body.transactions.len(), 1); + +// Ok(()) +// } + +// /// Helper function to create a new eth payload attributes +// pub fn optimism_payload_attributes(timestamp: u64) -> OptimismPayloadBuilderAttributes { +// let attributes = EthPayloadBuilderAttributes { +// timestamp, +// prev_randao: B256::ZERO, +// suggested_fee_recipient: Address::ZERO, +// withdrawals: Withdrawals::default(), +// parent_beacon_block_root: Some(B256::ZERO), +// id: PayloadId(FixedBytes::<8>::random()), +// parent: FixedBytes::default(), +// }; + +// OptimismPayloadBuilderAttributes { +// payload_attributes: attributes, +// transactions: vec![], +// gas_limit: None, +// no_tx_pool: false, +// } +// } + +// fn tx(chain_id: u64, data: Option, nonce: u64) -> TransactionRequest { +// TransactionRequest { +// nonce: Some(nonce), +// value: Some(U256::from(100)), +// to: Some(TxKind::Call(Address::random())), +// gas: Some(210000), +// max_fee_per_gas: Some(20e10 as u128), +// max_priority_fee_per_gas: Some(20e10 as u128), +// chain_id: Some(chain_id), +// input: TransactionInput { input: None, data }, +// ..Default::default() +// } +// } + +// /// Builds an OP Mainnet chain spec with the given merkle root +// /// Populated in the OpWorldID contract. +// fn get_chain_spec(merkle_root: Field) -> OpChainSpec { +// let genesis: Genesis = serde_json::from_str(include_str!("assets/genesis.json")).unwrap(); +// OpChainSpecBuilder::base_mainnet() +// .genesis(genesis.extend_accounts(vec![( +// OP_WORLD_ID, +// GenesisAccount::default().with_storage(Some(BTreeMap::from_iter(vec![( +// LATEST_ROOT_SLOT.into(), +// merkle_root.into(), +// )]))), +// )])) +// .ecotone_activated() +// .build() +// } From fb526895d1e9953b31c3a39e866f04d974607e26 Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Thu, 12 Dec 2024 14:19:28 -0700 Subject: [PATCH 17/59] fix: ValidatedPbhTransactions --- world-chain-builder/src/pbh/db.rs | 7 ++++++- world-chain-builder/src/pool/root.rs | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/world-chain-builder/src/pbh/db.rs b/world-chain-builder/src/pbh/db.rs index 341d7b57..59dbbbb4 100644 --- a/world-chain-builder/src/pbh/db.rs +++ b/world-chain-builder/src/pbh/db.rs @@ -6,8 +6,10 @@ use bytes::BufMut; use reth_db::cursor::DbCursorRW; use reth_db::mdbx::tx::Tx; use reth_db::mdbx::{DatabaseArguments, DatabaseFlags, RW}; +use reth_db::table::TableInfo; use reth_db::table::{Compress, Decompress, Table}; use reth_db::transaction::DbTxMut; +use reth_db::TableSet; use reth_db::{create_db, tables, DatabaseError, TableType, TableViewer}; use reth_db_api; use revm_primitives::{FixedBytes, B256}; @@ -22,7 +24,10 @@ tables! { /// a mapping is created from the transaction hash to the nullifier here. /// This is primarily used as a caching mechanism to avoid certain types of /// DoS attacks. - table ValidatedPbhTransaction; + table ValidatedPbhTransaction { + type Key = B256; + type Value = EmptyValue; + } } #[derive(Debug, Clone, Default, Serialize, Deserialize)] diff --git a/world-chain-builder/src/pool/root.rs b/world-chain-builder/src/pool/root.rs index 12730915..e4d27e8d 100644 --- a/world-chain-builder/src/pool/root.rs +++ b/world-chain-builder/src/pool/root.rs @@ -1,6 +1,6 @@ use std::{collections::BTreeMap, sync::Arc}; -use alloy_consensus::{BlockHeader, Header, Sealable, Sealed}; +use alloy_consensus::{BlockHeader, Sealable}; use parking_lot::RwLock; use reth::api::Block; use reth_primitives::SealedBlock; From 0b2ad0347ebc46e478f6ce9c26f9e019d2c829a5 Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Thu, 12 Dec 2024 15:05:45 -0700 Subject: [PATCH 18/59] patch test API changes --- world-chain-builder/Cargo.lock | 164 +---- world-chain-builder/Cargo.toml | 11 +- world-chain-builder/src/pool/root.rs | 160 ++--- world-chain-builder/src/pool/validator.rs | 526 +++++++------- world-chain-builder/src/test/e2e/mod.rs | 794 +++++++++++----------- 5 files changed, 753 insertions(+), 902 deletions(-) diff --git a/world-chain-builder/Cargo.lock b/world-chain-builder/Cargo.lock index 6edaffdd..6656262a 100644 --- a/world-chain-builder/Cargo.lock +++ b/world-chain-builder/Cargo.lock @@ -157,22 +157,6 @@ dependencies = [ "serde", ] -[[package]] -name = "alloy-consensus" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ed961a48297c732a5d97ee321aa8bb5009ecadbcb077d8bec90cb54e651629" -dependencies = [ - "alloy-eips 0.5.4", - "alloy-primitives", - "alloy-rlp", - "alloy-serde 0.5.4", - "auto_impl", - "c-kzg", - "derive_more", - "serde", -] - [[package]] name = "alloy-consensus" version = "0.7.3" @@ -250,18 +234,6 @@ dependencies = [ "serde", ] -[[package]] -name = "alloy-eip7702" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ffc577390ce50234e02d841214b3dc0bea6aaaae8e04bbf3cb82e9a45da9eb" -dependencies = [ - "alloy-primitives", - "alloy-rlp", - "derive_more", - "serde", -] - [[package]] name = "alloy-eip7702" version = "0.4.2" @@ -314,24 +286,6 @@ dependencies = [ "sha2 0.10.8", ] -[[package]] -name = "alloy-eips" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b69e06cf9c37be824b9d26d6d101114fdde6af0c87de2828b414c05c4b3daa71" -dependencies = [ - "alloy-eip2930", - "alloy-eip7702 0.3.2", - "alloy-primitives", - "alloy-rlp", - "alloy-serde 0.5.4", - "c-kzg", - "derive_more", - "once_cell", - "serde", - "sha2 0.10.8", -] - [[package]] name = "alloy-eips" version = "0.7.3" @@ -405,20 +359,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "alloy-json-rpc" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af5979e0d5a7bf9c7eb79749121e8256e59021af611322aee56e77e20776b4b3" -dependencies = [ - "alloy-primitives", - "alloy-sol-types", - "serde", - "serde_json", - "thiserror 1.0.69", - "tracing", -] - [[package]] name = "alloy-json-rpc" version = "0.7.3" @@ -475,27 +415,6 @@ dependencies = [ "thiserror 1.0.69", ] -[[package]] -name = "alloy-network" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "204237129086ce5dc17a58025e93739b01b45313841f98fa339eb1d780511e57" -dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", - "alloy-json-rpc 0.5.4", - "alloy-network-primitives 0.5.4", - "alloy-primitives", - "alloy-rpc-types-eth 0.5.4", - "alloy-serde 0.5.4", - "alloy-signer 0.5.4", - "alloy-sol-types", - "async-trait", - "auto_impl", - "futures-utils-wasm", - "thiserror 1.0.69", -] - [[package]] name = "alloy-network" version = "0.7.3" @@ -546,19 +465,6 @@ dependencies = [ "serde", ] -[[package]] -name = "alloy-network-primitives" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514f70ee2a953db21631cd817b13a1571474ec77ddc03d47616d5e8203489fde" -dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", - "alloy-primitives", - "alloy-serde 0.5.4", - "serde", -] - [[package]] name = "alloy-network-primitives" version = "0.7.3" @@ -899,25 +805,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "alloy-rpc-types-eth" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b034779a4850b4b03f5be5ea674a1cf7d746b2da762b34d1860ab45e48ca27" -dependencies = [ - "alloy-consensus 0.5.4", - "alloy-eips 0.5.4", - "alloy-network-primitives 0.5.4", - "alloy-primitives", - "alloy-rlp", - "alloy-serde 0.5.4", - "alloy-sol-types", - "derive_more", - "itertools 0.13.0", - "serde", - "serde_json", -] - [[package]] name = "alloy-rpc-types-eth" version = "0.7.3" @@ -1002,17 +889,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "alloy-serde" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "028e72eaa9703e4882344983cfe7636ce06d8cce104a78ea62fd19b46659efc4" -dependencies = [ - "alloy-primitives", - "serde", - "serde_json", -] - [[package]] name = "alloy-serde" version = "0.7.3" @@ -1053,20 +929,6 @@ dependencies = [ "thiserror 1.0.69", ] -[[package]] -name = "alloy-signer" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "592c185d7100258c041afac51877660c7bf6213447999787197db4842f0e938e" -dependencies = [ - "alloy-primitives", - "async-trait", - "auto_impl", - "elliptic-curve", - "k256", - "thiserror 1.0.69", -] - [[package]] name = "alloy-signer" version = "0.7.3" @@ -1081,22 +943,6 @@ dependencies = [ "thiserror 2.0.6", ] -[[package]] -name = "alloy-signer-local" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6614f02fc1d5b079b2a4a5320018317b506fd0a6d67c1fd5542a71201724986c" -dependencies = [ - "alloy-consensus 0.5.4", - "alloy-network 0.5.4", - "alloy-primitives", - "alloy-signer 0.5.4", - "async-trait", - "k256", - "rand", - "thiserror 1.0.69", -] - [[package]] name = "alloy-signer-local" version = "0.7.3" @@ -7808,7 +7654,7 @@ dependencies = [ "alloy-eips 0.7.3", "alloy-primitives", "alloy-signer 0.7.3", - "alloy-signer-local 0.7.3", + "alloy-signer-local", "derive_more", "metrics", "parking_lot", @@ -8276,7 +8122,7 @@ dependencies = [ "alloy-rpc-types-engine", "alloy-rpc-types-eth 0.7.3", "alloy-signer 0.7.3", - "alloy-signer-local 0.7.3", + "alloy-signer-local", "derive_more", "eyre", "futures-util", @@ -9832,7 +9678,7 @@ dependencies = [ "alloy-rpc-types-txpool", "alloy-serde 0.7.3", "alloy-signer 0.7.3", - "alloy-signer-local 0.7.3", + "alloy-signer-local", "async-trait", "derive_more", "futures", @@ -14019,8 +13865,8 @@ dependencies = [ "alloy-rlp", "alloy-rpc-types", "alloy-rpc-types-eth 0.7.3", - "alloy-signer 0.5.4", - "alloy-signer-local 0.5.4", + "alloy-signer 0.7.3", + "alloy-signer-local", "bytemuck", "bytes", "chrono", diff --git a/world-chain-builder/Cargo.toml b/world-chain-builder/Cargo.toml index 9b69c998..fbbbcc1b 100644 --- a/world-chain-builder/Cargo.toml +++ b/world-chain-builder/Cargo.toml @@ -107,12 +107,13 @@ ethers-core = { git = "https://github.com/gakonst/ethers-rs", default-features = alloy-primitives = "0.8" serde_json = "1" rand = "0.8" -reth-e2e-test-utils = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4"} -reth-consensus = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-e2e-test-utils = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-consensus = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-optimism-consensus = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } reth-node-core = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } reth-tracing = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } -alloy-signer = { version = "0.5.4", default-features = false } -alloy-signer-local = { version = "0.5.4", default-features = false } +alloy-signer = { version = "0.7.3", default-features = false } +alloy-signer-local = { version = "0.7.3", default-features = false } [features] jemalloc = ["tikv-jemallocator"] @@ -123,4 +124,4 @@ path = "bin/world-chain-builder.rs" [[bench]] name = "validate_transaction" -harness = false \ No newline at end of file +harness = false diff --git a/world-chain-builder/src/pool/root.rs b/world-chain-builder/src/pool/root.rs index e4d27e8d..6a3d194c 100644 --- a/world-chain-builder/src/pool/root.rs +++ b/world-chain-builder/src/pool/root.rs @@ -167,83 +167,85 @@ where #[cfg(test)] mod tests { - // use reth_primitives::Header; - // use reth_provider::test_utils::{ExtendedAccount, MockEthProvider}; - - // use super::*; - // use reth_primitives::Block; - // pub fn world_chain_root_validator() -> eyre::Result> { - // let client = MockEthProvider::default(); - // let root_validator = WorldChainRootValidator::new(client)?; - // Ok(root_validator) - // } - - // fn add_block_with_root_with_timestamp( - // validator: &WorldChainRootValidator, - // timestamp: u64, - // root: Field, - // ) { - // let header = Header { - // timestamp, - // ..Default::default() - // }; - // let block = Block { - // header, - // ..Default::default() - // }; - // validator.cache.read().client().add_account( - // OP_WORLD_ID, - // ExtendedAccount::new(0, U256::ZERO) - // .extend_storage(vec![(LATEST_ROOT_SLOT.into(), root)]), - // ); - // validator - // .cache - // .read() - // .client() - // .add_block(block.hash_slow(), block.clone()); - // let hash = block.hash_slow(); - // let block = block.clone(); - // validator.on_new_block(&block.seal(hash).clone()); - // } - - // #[test] - // fn test_validate_root() -> eyre::Result<()> { - // let validator = world_chain_root_validator()?; - // let root_1 = Field::from(1u64); - // let timestamp = 1000000000; - // add_block_with_root_with_timestamp(&validator, timestamp, root_1); - // assert!(validator.validate_root(root_1)); - // let root_2 = Field::from(2u64); - // add_block_with_root_with_timestamp(&validator, timestamp + 3601, root_2); - // assert!(validator.validate_root(root_2)); - // assert!(!validator.validate_root(root_1)); - // let root_3 = Field::from(3u64); - // add_block_with_root_with_timestamp(&validator, timestamp + 3600 + 3600, root_3); - // assert!(validator.validate_root(root_3)); - // assert!(validator.validate_root(root_2)); - // assert!(!validator.validate_root(root_1)); - // Ok(()) - // } - - // impl WorldChainRootValidator - // where - // Client: StateProviderFactory + BlockReaderIdExt, - // { - // pub fn set_client(&mut self, client: Client) { - // self.cache.write().set_client(client); - // } - // } - - // impl RootProvider - // where - // Client: StateProviderFactory + BlockReaderIdExt, - // { - // pub fn set_client(&mut self, client: Client) { - // self.client = client; - // } - - // pub fn client(&self) -> &Client { - // &self.client - // } - // } + use reth_primitives::{Header, SealedHeader}; + use reth_provider::test_utils::{ExtendedAccount, MockEthProvider}; + + use super::*; + use reth_primitives::Block; + pub fn world_chain_root_validator() -> eyre::Result> { + let client = MockEthProvider::default(); + let root_validator = WorldChainRootValidator::new(client)?; + Ok(root_validator) + } + + fn add_block_with_root_with_timestamp( + validator: &WorldChainRootValidator, + timestamp: u64, + root: Field, + ) { + let header = Header { + timestamp, + ..Default::default() + }; + let block = Block { + header, + ..Default::default() + }; + validator.cache.read().client().add_account( + OP_WORLD_ID, + ExtendedAccount::new(0, U256::ZERO) + .extend_storage(vec![(LATEST_ROOT_SLOT.into(), root)]), + ); + validator + .cache + .read() + .client() + .add_block(block.hash_slow(), block.clone()); + let block = SealedBlock { + header: SealedHeader::new(block.header.clone(), block.header.hash_slow()), + body: block.body + }; + validator.on_new_block(&block.into()); + } + + #[test] + fn test_validate_root() -> eyre::Result<()> { + let validator = world_chain_root_validator()?; + let root_1 = Field::from(1u64); + let timestamp = 1000000000; + add_block_with_root_with_timestamp(&validator, timestamp, root_1); + assert!(validator.validate_root(root_1)); + let root_2 = Field::from(2u64); + add_block_with_root_with_timestamp(&validator, timestamp + 3601, root_2); + assert!(validator.validate_root(root_2)); + assert!(!validator.validate_root(root_1)); + let root_3 = Field::from(3u64); + add_block_with_root_with_timestamp(&validator, timestamp + 3600 + 3600, root_3); + assert!(validator.validate_root(root_3)); + assert!(validator.validate_root(root_2)); + assert!(!validator.validate_root(root_1)); + Ok(()) + } + + impl WorldChainRootValidator + where + Client: StateProviderFactory + BlockReaderIdExt, + { + pub fn set_client(&mut self, client: Client) { + self.cache.write().set_client(client); + } + } + + impl RootProvider + where + Client: StateProviderFactory + BlockReaderIdExt, + { + pub fn set_client(&mut self, client: Client) { + self.client = client; + } + + pub fn client(&self) -> &Client { + &self.client + } + } } diff --git a/world-chain-builder/src/pool/validator.rs b/world-chain-builder/src/pool/validator.rs index c0834d14..f666f0ca 100644 --- a/world-chain-builder/src/pool/validator.rs +++ b/world-chain-builder/src/pool/validator.rs @@ -224,267 +224,267 @@ where #[cfg(test)] pub mod tests { - // use chrono::{TimeZone, Utc}; - // use ethers_core::types::U256; - // use reth::transaction_pool::blobstore::InMemoryBlobStore; - // use reth::transaction_pool::{ - // Pool, PoolTransaction as _, TransactionPool, TransactionValidator, - // }; - // use reth_primitives::{BlockBody, SealedBlock, SealedHeader}; - // use reth_provider::test_utils::{ExtendedAccount, MockEthProvider}; - // use semaphore::Field; - // use test_case::test_case; - - // use crate::pbh::payload::{PbhPayload, Proof}; - // use crate::pool::ordering::WorldChainOrdering; - // use crate::pool::root::{LATEST_ROOT_SLOT, OP_WORLD_ID}; - // use crate::test::{get_pbh_transaction, world_chain_validator}; - - // #[tokio::test] - // async fn validate_pbh_transaction() { - // let validator = world_chain_validator(); - // let transaction = get_pbh_transaction(0); - // validator.inner.client().add_account( - // transaction.sender(), - // ExtendedAccount::new(transaction.nonce(), alloy_primitives::U256::MAX), - // ); - // // Insert a world id root into the OpWorldId Account - // validator.inner.client().add_account( - // OP_WORLD_ID, - // ExtendedAccount::new(0, alloy_primitives::U256::ZERO).extend_storage(vec![( - // LATEST_ROOT_SLOT.into(), - // transaction.pbh_payload.clone().unwrap().root, - // )]), - // ); - // let header = SealedHeader::default(); - // let body = BlockBody::default(); - // let block = SealedBlock::new(header, body); - - // // Propogate the block to the root validator - // validator.on_new_head_block(&block); - - // let ordering = WorldChainOrdering::default(); - - // let pool = Pool::new( - // validator, - // ordering, - // InMemoryBlobStore::default(), - // Default::default(), - // ); - - // let start = chrono::Utc::now(); - // let res = pool.add_external_transaction(transaction.clone()).await; - // let first_insert = chrono::Utc::now() - start; - // println!("first_insert: {first_insert:?}"); - - // assert!(res.is_ok()); - // let tx = pool.get(transaction.hash()); - // assert!(tx.is_some()); - - // let start = chrono::Utc::now(); - // let res = pool.add_external_transaction(transaction.clone()).await; - - // let second_insert = chrono::Utc::now() - start; - // println!("second_insert: {second_insert:?}"); - - // // Check here that we're properly caching the transaction - // assert!(first_insert > second_insert * 10); - // assert!(res.is_err()); - // } - - // #[tokio::test] - // async fn invalid_external_nullifier_hash() { - // let validator = world_chain_validator(); - // let transaction = get_pbh_transaction(0); - - // validator.inner.client().add_account( - // transaction.sender(), - // ExtendedAccount::new(transaction.nonce(), alloy_primitives::U256::MAX), - // ); - - // let ordering = WorldChainOrdering::default(); - - // let pool = Pool::new( - // validator, - // ordering, - // InMemoryBlobStore::default(), - // Default::default(), - // ); - - // let res = pool.add_external_transaction(transaction.clone()).await; - // assert!(res.is_err()); - // } - - // #[tokio::test] - // async fn invalid_signal_hash() { - // let validator = world_chain_validator(); - // let transaction = get_pbh_transaction(0); - - // validator.inner.client().add_account( - // transaction.sender(), - // ExtendedAccount::new(transaction.nonce(), alloy_primitives::U256::MAX), - // ); - - // let ordering = WorldChainOrdering::default(); - - // let pool = Pool::new( - // validator, - // ordering, - // InMemoryBlobStore::default(), - // Default::default(), - // ); - - // let res = pool.add_external_transaction(transaction.clone()).await; - // assert!(res.is_err()); - // } - - // #[test] - // fn test_validate_root() { - // let mut validator = world_chain_validator(); - // let root = Field::from(1u64); - // let proof = Proof(semaphore::protocol::Proof( - // (U256::from(1u64), U256::from(2u64)), - // ( - // [U256::from(3u64), U256::from(4u64)], - // [U256::from(5u64), U256::from(6u64)], - // ), - // (U256::from(7u64), U256::from(8u64)), - // )); - // let payload = PbhPayload { - // external_nullifier: "0-012025-11".to_string(), - // nullifier_hash: Field::from(10u64), - // root, - // proof, - // }; - // let header = SealedHeader::default(); - // let body = BlockBody::default(); - // let block = SealedBlock::new(header, body); - // let client = MockEthProvider::default(); - // // Insert a world id root into the OpWorldId Account - // client.add_account( - // OP_WORLD_ID, - // ExtendedAccount::new(0, alloy_primitives::U256::ZERO) - // .extend_storage(vec![(LATEST_ROOT_SLOT.into(), Field::from(1u64))]), - // ); - // validator.root_validator.set_client(client); - // validator.on_new_head_block(&block); - // let res = validator.validate_root(&payload); - // assert!(res.is_ok()); - // } - - // #[test] - // fn test_invalidate_root() { - // let mut validator = world_chain_validator(); - // let root = Field::from(0); - // let proof = Proof(semaphore::protocol::Proof( - // (U256::from(1u64), U256::from(2u64)), - // ( - // [U256::from(3u64), U256::from(4u64)], - // [U256::from(5u64), U256::from(6u64)], - // ), - // (U256::from(7u64), U256::from(8u64)), - // )); - // let payload = PbhPayload { - // external_nullifier: "0-012025-11".to_string(), - // nullifier_hash: Field::from(10u64), - // root, - // proof, - // }; - // let header = SealedHeader::default(); - // let body = BlockBody::default(); - // let block = SealedBlock::new(header, body); - // let client = MockEthProvider::default(); - // // Insert a world id root into the OpWorldId Account - // client.add_account( - // OP_WORLD_ID, - // ExtendedAccount::new(0, alloy_primitives::U256::ZERO) - // .extend_storage(vec![(LATEST_ROOT_SLOT.into(), Field::from(1u64))]), - // ); - // validator.root_validator.set_client(client); - // validator.on_new_head_block(&block); - // let res = validator.validate_root(&payload); - // assert!(res.is_err()); - // } - - // #[test_case("v1-012025-0")] - // #[test_case("v1-012025-1")] - // #[test_case("v1-012025-29")] - // fn validate_external_nullifier_valid(external_nullifier: &str) { - // let validator = world_chain_validator(); - // let date = chrono::Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).unwrap(); - - // let payload = PbhPayload { - // external_nullifier: external_nullifier.to_string(), - // nullifier_hash: Field::ZERO, - // root: Field::ZERO, - // proof: Default::default(), - // }; - - // validator - // .validate_external_nullifier(date, &payload) - // .unwrap(); - // } - - // #[test_case("v1-012025-0", "2024-12-31 23:59:30Z" ; "a minute early")] - // #[test_case("v1-012025-0", "2025-02-01 00:00:30Z" ; "a minute late")] - // fn validate_external_nullifier_at_time(external_nullifier: &str, time: &str) { - // let validator = world_chain_validator(); - // let date: chrono::DateTime = time.parse().unwrap(); - - // let payload = PbhPayload { - // external_nullifier: external_nullifier.to_string(), - // nullifier_hash: Field::ZERO, - // root: Field::ZERO, - // proof: Default::default(), - // }; - - // validator - // .validate_external_nullifier(date, &payload) - // .unwrap(); - // } - - // #[test_case("v0-012025-0")] - // #[test_case("v1-022025-0")] - // #[test_case("v1-122024-0")] - // #[test_case("v1-002025-0")] - // #[test_case("v1-012025-30")] - // #[test_case("v1-012025")] - // #[test_case("12025-0")] - // #[test_case("v1-012025-0-0")] - // fn validate_external_nullifier_invalid(external_nullifier: &str) { - // let validator = world_chain_validator(); - // let date = chrono::Utc.with_ymd_and_hms(2025, 1, 1, 12, 0, 0).unwrap(); - - // let payload = PbhPayload { - // external_nullifier: external_nullifier.to_string(), - // nullifier_hash: Field::ZERO, - // root: Field::ZERO, - // proof: Default::default(), - // }; - - // let res = validator.validate_external_nullifier(date, &payload); - // assert!(res.is_err()); - // } - - // #[test] - // fn test_set_validated() { - // let validator = world_chain_validator(); - - // let proof = Proof(semaphore::protocol::Proof( - // (U256::from(1u64), U256::from(2u64)), - // ( - // [U256::from(3u64), U256::from(4u64)], - // [U256::from(5u64), U256::from(6u64)], - // ), - // (U256::from(7u64), U256::from(8u64)), - // )); - // let payload = PbhPayload { - // external_nullifier: "0-012025-11".to_string(), - // nullifier_hash: Field::from(10u64), - // root: Field::from(12u64), - // proof, - // }; - - // validator.set_validated(&payload).unwrap(); - // } + use chrono::{TimeZone, Utc}; + use ethers_core::types::U256; + use reth::transaction_pool::blobstore::InMemoryBlobStore; + use reth::transaction_pool::{ + Pool, PoolTransaction as _, TransactionPool, TransactionValidator, + }; + use reth_primitives::{BlockBody, SealedBlock, SealedHeader}; + use reth_provider::test_utils::{ExtendedAccount, MockEthProvider}; + use semaphore::Field; + use test_case::test_case; + + use crate::pbh::payload::{PbhPayload, Proof}; + use crate::pool::ordering::WorldChainOrdering; + use crate::pool::root::{LATEST_ROOT_SLOT, OP_WORLD_ID}; + use crate::test::{get_pbh_transaction, world_chain_validator}; + + #[tokio::test] + async fn validate_pbh_transaction() { + let validator = world_chain_validator(); + let transaction = get_pbh_transaction(0); + validator.inner.client().add_account( + transaction.sender(), + ExtendedAccount::new(transaction.nonce(), alloy_primitives::U256::MAX), + ); + // Insert a world id root into the OpWorldId Account + validator.inner.client().add_account( + OP_WORLD_ID, + ExtendedAccount::new(0, alloy_primitives::U256::ZERO).extend_storage(vec![( + LATEST_ROOT_SLOT.into(), + transaction.pbh_payload.clone().unwrap().root, + )]), + ); + let header = SealedHeader::default(); + let body = BlockBody::default(); + let block = SealedBlock::new(header, body); + + // Propogate the block to the root validator + validator.on_new_head_block(&block); + + let ordering = WorldChainOrdering::default(); + + let pool = Pool::new( + validator, + ordering, + InMemoryBlobStore::default(), + Default::default(), + ); + + let start = chrono::Utc::now(); + let res = pool.add_external_transaction(transaction.clone()).await; + let first_insert = chrono::Utc::now() - start; + println!("first_insert: {first_insert:?}"); + + assert!(res.is_ok()); + let tx = pool.get(transaction.hash()); + assert!(tx.is_some()); + + let start = chrono::Utc::now(); + let res = pool.add_external_transaction(transaction.clone()).await; + + let second_insert = chrono::Utc::now() - start; + println!("second_insert: {second_insert:?}"); + + // Check here that we're properly caching the transaction + assert!(first_insert > second_insert * 10); + assert!(res.is_err()); + } + + #[tokio::test] + async fn invalid_external_nullifier_hash() { + let validator = world_chain_validator(); + let transaction = get_pbh_transaction(0); + + validator.inner.client().add_account( + transaction.sender(), + ExtendedAccount::new(transaction.nonce(), alloy_primitives::U256::MAX), + ); + + let ordering = WorldChainOrdering::default(); + + let pool = Pool::new( + validator, + ordering, + InMemoryBlobStore::default(), + Default::default(), + ); + + let res = pool.add_external_transaction(transaction.clone()).await; + assert!(res.is_err()); + } + + #[tokio::test] + async fn invalid_signal_hash() { + let validator = world_chain_validator(); + let transaction = get_pbh_transaction(0); + + validator.inner.client().add_account( + transaction.sender(), + ExtendedAccount::new(transaction.nonce(), alloy_primitives::U256::MAX), + ); + + let ordering = WorldChainOrdering::default(); + + let pool = Pool::new( + validator, + ordering, + InMemoryBlobStore::default(), + Default::default(), + ); + + let res = pool.add_external_transaction(transaction.clone()).await; + assert!(res.is_err()); + } + + #[test] + fn test_validate_root() { + let mut validator = world_chain_validator(); + let root = Field::from(1u64); + let proof = Proof(semaphore::protocol::Proof( + (U256::from(1u64), U256::from(2u64)), + ( + [U256::from(3u64), U256::from(4u64)], + [U256::from(5u64), U256::from(6u64)], + ), + (U256::from(7u64), U256::from(8u64)), + )); + let payload = PbhPayload { + external_nullifier: "0-012025-11".to_string(), + nullifier_hash: Field::from(10u64), + root, + proof, + }; + let header = SealedHeader::default(); + let body = BlockBody::default(); + let block = SealedBlock::new(header, body); + let client = MockEthProvider::default(); + // Insert a world id root into the OpWorldId Account + client.add_account( + OP_WORLD_ID, + ExtendedAccount::new(0, alloy_primitives::U256::ZERO) + .extend_storage(vec![(LATEST_ROOT_SLOT.into(), Field::from(1u64))]), + ); + validator.root_validator.set_client(client); + validator.on_new_head_block(&block); + let res = validator.validate_root(&payload); + assert!(res.is_ok()); + } + + #[test] + fn test_invalidate_root() { + let mut validator = world_chain_validator(); + let root = Field::from(0); + let proof = Proof(semaphore::protocol::Proof( + (U256::from(1u64), U256::from(2u64)), + ( + [U256::from(3u64), U256::from(4u64)], + [U256::from(5u64), U256::from(6u64)], + ), + (U256::from(7u64), U256::from(8u64)), + )); + let payload = PbhPayload { + external_nullifier: "0-012025-11".to_string(), + nullifier_hash: Field::from(10u64), + root, + proof, + }; + let header = SealedHeader::default(); + let body = BlockBody::default(); + let block = SealedBlock::new(header, body); + let client = MockEthProvider::default(); + // Insert a world id root into the OpWorldId Account + client.add_account( + OP_WORLD_ID, + ExtendedAccount::new(0, alloy_primitives::U256::ZERO) + .extend_storage(vec![(LATEST_ROOT_SLOT.into(), Field::from(1u64))]), + ); + validator.root_validator.set_client(client); + validator.on_new_head_block(&block); + let res = validator.validate_root(&payload); + assert!(res.is_err()); + } + + #[test_case("v1-012025-0")] + #[test_case("v1-012025-1")] + #[test_case("v1-012025-29")] + fn validate_external_nullifier_valid(external_nullifier: &str) { + let validator = world_chain_validator(); + let date = chrono::Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).unwrap(); + + let payload = PbhPayload { + external_nullifier: external_nullifier.to_string(), + nullifier_hash: Field::ZERO, + root: Field::ZERO, + proof: Default::default(), + }; + + validator + .validate_external_nullifier(date, &payload) + .unwrap(); + } + + #[test_case("v1-012025-0", "2024-12-31 23:59:30Z" ; "a minute early")] + #[test_case("v1-012025-0", "2025-02-01 00:00:30Z" ; "a minute late")] + fn validate_external_nullifier_at_time(external_nullifier: &str, time: &str) { + let validator = world_chain_validator(); + let date: chrono::DateTime = time.parse().unwrap(); + + let payload = PbhPayload { + external_nullifier: external_nullifier.to_string(), + nullifier_hash: Field::ZERO, + root: Field::ZERO, + proof: Default::default(), + }; + + validator + .validate_external_nullifier(date, &payload) + .unwrap(); + } + + #[test_case("v0-012025-0")] + #[test_case("v1-022025-0")] + #[test_case("v1-122024-0")] + #[test_case("v1-002025-0")] + #[test_case("v1-012025-30")] + #[test_case("v1-012025")] + #[test_case("12025-0")] + #[test_case("v1-012025-0-0")] + fn validate_external_nullifier_invalid(external_nullifier: &str) { + let validator = world_chain_validator(); + let date = chrono::Utc.with_ymd_and_hms(2025, 1, 1, 12, 0, 0).unwrap(); + + let payload = PbhPayload { + external_nullifier: external_nullifier.to_string(), + nullifier_hash: Field::ZERO, + root: Field::ZERO, + proof: Default::default(), + }; + + let res = validator.validate_external_nullifier(date, &payload); + assert!(res.is_err()); + } + + #[test] + fn test_set_validated() { + let validator = world_chain_validator(); + + let proof = Proof(semaphore::protocol::Proof( + (U256::from(1u64), U256::from(2u64)), + ( + [U256::from(3u64), U256::from(4u64)], + [U256::from(5u64), U256::from(6u64)], + ), + (U256::from(7u64), U256::from(8u64)), + )); + let payload = PbhPayload { + external_nullifier: "0-012025-11".to_string(), + nullifier_hash: Field::from(10u64), + root: Field::from(12u64), + proof, + }; + + validator.set_validated(&payload).unwrap(); + } } diff --git a/world-chain-builder/src/test/e2e/mod.rs b/world-chain-builder/src/test/e2e/mod.rs index 11ac593c..ba66c63e 100644 --- a/world-chain-builder/src/test/e2e/mod.rs +++ b/world-chain-builder/src/test/e2e/mod.rs @@ -1,396 +1,398 @@ -// //! Utilities for running world chain builder end-to-end tests. -// use crate::{ -// node::{ -// args::{ExtArgs, WorldChainBuilderArgs}, -// builder::{WorldChainAddOns, WorldChainBuilder}, -// }, -// pbh::{ -// date_marker::DateMarker, -// external_nullifier::{ExternalNullifier, Prefix}, -// payload::{PbhPayload, Proof}, -// }, -// pool::{ -// ordering::WorldChainOrdering, -// root::{LATEST_ROOT_SLOT, OP_WORLD_ID}, -// tx::WorldChainPooledTransaction, -// validator::WorldChainTransactionValidator, -// }, -// primitives::WorldChainPooledTransactionsElement, -// rpc::bundle::{EthTransactionsExtServer, WorldChainEthApiExt}, -// }; -// use alloy_eips::eip2718::Decodable2718; -// use alloy_genesis::{Genesis, GenesisAccount}; -// use alloy_network::eip2718::Encodable2718; -// use alloy_network::{Ethereum, EthereumWallet, TransactionBuilder}; -// use alloy_rpc_types::{TransactionInput, TransactionRequest}; -// use alloy_signer_local::PrivateKeySigner; -// use chrono::Utc; -// use reth::payload::{EthPayloadBuilderAttributes, PayloadId}; -// use reth::tasks::TaskManager; -// use reth::transaction_pool::{blobstore::DiskFileBlobStore, TransactionValidationTaskExecutor}; -// use reth::{ -// api::{FullNodeTypesAdapter, NodeTypesWithDBAdapter}, -// builder::components::Components, -// }; -// use reth::{ -// builder::{NodeAdapter, NodeBuilder, NodeConfig, NodeHandle}, -// transaction_pool::Pool, -// }; -// use reth_db::{ -// test_utils::{tempdir_path, TempDatabase}, -// DatabaseEnv, -// }; -// use reth_e2e_test_utils::{ -// node::NodeTestContext, transaction::TransactionTestContext, wallet::Wallet, -// }; -// use reth_evm::execute::BasicBlockExecutorProvider; -// use reth_node_core::args::RpcServerArgs; -// use reth_optimism_chainspec::{OpChainSpec, OpChainSpecBuilder}; -// use reth_optimism_evm::{OpEvmConfig, OpExecutionStrategyFactory}; -// use reth_optimism_node::OpPayloadBuilderAttributes; -// use reth_primitives::PooledTransactionsElement; -// use reth_provider::providers::BlockchainProvider; -// use revm_primitives::{Address, Bytes, FixedBytes, TxKind, B256, U256}; -// use semaphore::{ -// hash_to_field, -// identity::Identity, -// poseidon_tree::LazyPoseidonTree, -// protocol::{generate_nullifier_hash, generate_proof}, -// Field, -// }; -// use serial_test::serial; -// use std::{ -// collections::{BTreeMap, HashMap}, -// sync::Arc, -// time::Duration, -// }; - -// pub const DEV_CHAIN_ID: u64 = 8453; - -// type NodeAdapterType = NodeAdapter< -// FullNodeTypesAdapter< -// NodeTypesWithDBAdapter>>, -// BlockchainProvider< -// NodeTypesWithDBAdapter>>, -// >, -// >, -// Components< -// FullNodeTypesAdapter< -// NodeTypesWithDBAdapter>>, -// BlockchainProvider< -// NodeTypesWithDBAdapter>>, -// >, -// >, -// Pool< -// TransactionValidationTaskExecutor< -// WorldChainTransactionValidator< -// BlockchainProvider< -// NodeTypesWithDBAdapter>>, -// >, -// WorldChainPooledTransaction, -// >, -// >, -// WorldChainOrdering, -// DiskFileBlobStore, -// >, -// OpEvmConfig, -// BasicBlockExecutorProvider, -// Arc<(dyn reth_consensus::Consensus + 'static)>, -// >, -// >; - -// type Adapter = NodeTestContext>; - -// pub struct WorldChainBuilderTestContext { -// pub pbh_wallets: Vec, -// pub tree: LazyPoseidonTree, -// pub tasks: TaskManager, -// pub node: Adapter, -// pub identities: HashMap, -// } - -// impl WorldChainBuilderTestContext { -// pub async fn setup() -> eyre::Result { -// let wallets = Wallet::new(20).with_chain_id(DEV_CHAIN_ID).gen(); -// let mut tree = LazyPoseidonTree::new(30, Field::from(0)).derived(); -// let mut identities = HashMap::new(); -// for (i, signer) in wallets.iter().enumerate() { -// let address = signer.address(); -// identities.insert(address, i); -// let identity = Identity::from_secret(signer.address().as_mut_slice(), None); -// tree = tree.update(i, &identity.commitment()); -// } - -// let op_chain_spec = Arc::new(get_chain_spec(tree.root())); - -// let tasks = TaskManager::current(); -// let exec = tasks.executor(); - -// let node_config: NodeConfig = NodeConfig::new(op_chain_spec.clone()) -// .with_chain(op_chain_spec.clone()) -// .with_unused_ports() -// .with_rpc( -// RpcServerArgs::default() -// .with_unused_ports() -// .with_http_unused_port(), -// ); -// let path = tempdir_path(); -// let NodeHandle { -// node, -// node_exit_future: _, -// } = NodeBuilder::new(node_config.clone()) -// .testing_node(exec.clone()) -// .node(WorldChainBuilder::new( -// ExtArgs { -// builder_args: WorldChainBuilderArgs { -// num_pbh_txs: 30, -// verified_blockspace_capacity: 70, -// ..Default::default() -// }, -// ..Default::default() -// }, -// &path, -// )?) -// .extend_rpc_modules(move |ctx| { -// let provider = ctx.provider().clone(); -// let pool = ctx.pool().clone(); -// let eth_api_ext = WorldChainEthApiExt::new(pool, provider); -// ctx.modules.merge_configured(eth_api_ext.into_rpc())?; -// Ok(()) -// }) -// .launch() -// .await?; -// let test_ctx = NodeTestContext::new(node, optimism_payload_attributes).await?; -// Ok(Self { -// pbh_wallets: wallets, -// tree, -// tasks, -// node: test_ctx, -// identities, -// }) -// } - -// pub async fn raw_pbh_tx_bytes( -// &self, -// signer: PrivateKeySigner, -// pbh_nonce: u16, -// tx_nonce: u64, -// ) -> Bytes { -// let tx = tx(DEV_CHAIN_ID, None, tx_nonce); -// let envelope = TransactionTestContext::sign_tx(signer.clone(), tx).await; -// let raw_tx = envelope.encoded_2718(); -// let mut data = raw_tx.as_ref(); -// let recovered = PooledTransactionsElement::decode_2718(&mut data).unwrap(); -// let pbh_payload = self.valid_proof( -// signer.address(), -// recovered.hash().as_slice(), -// chrono::Utc::now(), -// pbh_nonce, -// ); - -// let world_chain_pooled_tx_element = WorldChainPooledTransactionsElement { -// inner: recovered, -// pbh_payload: Some(pbh_payload.clone()), -// }; - -// let mut buff = Vec::::new(); -// world_chain_pooled_tx_element.encode_2718(&mut buff); -// buff.into() -// } - -// fn valid_proof( -// &self, -// identity: Address, -// tx_hash: &[u8], -// time: chrono::DateTime, -// pbh_nonce: u16, -// ) -> PbhPayload { -// let external_nullifier = -// ExternalNullifier::new(Prefix::V1, DateMarker::from(time), pbh_nonce).to_string(); - -// self.create_proof(identity, external_nullifier, tx_hash) -// } - -// fn create_proof( -// &self, -// mut identity: Address, -// external_nullifier: String, -// signal: &[u8], -// ) -> PbhPayload { -// let idx = self.identities.get(&identity).unwrap(); -// let secret = identity.as_mut_slice(); -// // generate identity -// let id = Identity::from_secret(secret, None); -// let merkle_proof = self.tree.proof(*idx); - -// let signal_hash = hash_to_field(signal); -// let external_nullifier_hash = hash_to_field(external_nullifier.as_bytes()); -// let nullifier_hash = generate_nullifier_hash(&id, external_nullifier_hash); - -// let proof = Proof( -// generate_proof(&id, &merkle_proof, external_nullifier_hash, signal_hash).unwrap(), -// ); - -// PbhPayload { -// root: self.tree.root(), -// nullifier_hash, -// external_nullifier, -// proof, -// } -// } -// } - -// #[tokio::test] -// #[serial] -// async fn test_can_build_pbh_payload() -> eyre::Result<()> { -// tokio::time::sleep(Duration::from_secs(1)).await; -// let mut ctx = WorldChainBuilderTestContext::setup().await?; -// let mut pbh_tx_hashes = vec![]; -// for signer in ctx.pbh_wallets.iter() { -// let raw_tx = ctx.raw_pbh_tx_bytes(signer.clone(), 0, 0).await; -// let pbh_hash = ctx.node.rpc.inject_tx(raw_tx.clone()).await?; -// pbh_tx_hashes.push(pbh_hash); -// } - -// let (payload, _) = ctx.node.advance_block().await?; - -// assert_eq!(payload.block().body.transactions.len(), pbh_tx_hashes.len()); -// let block_hash = payload.block().hash(); -// let block_number = payload.block().number; - -// let tip = pbh_tx_hashes[0]; -// ctx.node -// .assert_new_block(tip, block_hash, block_number) -// .await?; - -// Ok(()) -// } - -// #[tokio::test] -// #[serial] -// async fn test_transaction_pool_ordering() -> eyre::Result<()> { -// tokio::time::sleep(Duration::from_secs(1)).await; -// let mut ctx = WorldChainBuilderTestContext::setup().await?; -// let non_pbh_tx = tx(ctx.node.inner.chain_spec().chain.id(), None, 0); -// let wallet = ctx.pbh_wallets[0].clone(); -// let signer = EthereumWallet::from(wallet); -// let signed = >::build(non_pbh_tx, &signer) -// .await -// .unwrap(); -// let non_pbh_hash = ctx.node.rpc.inject_tx(signed.encoded_2718().into()).await?; -// let mut pbh_tx_hashes = vec![]; -// for signer in ctx.pbh_wallets.iter().skip(1) { -// let raw_tx = ctx.raw_pbh_tx_bytes(signer.clone(), 0, 0).await; -// let pbh_hash = ctx.node.rpc.inject_tx(raw_tx.clone()).await?; -// pbh_tx_hashes.push(pbh_hash); -// } - -// let (payload, _) = ctx.node.advance_block().await?; - -// assert_eq!( -// payload.block().body.transactions.len(), -// pbh_tx_hashes.len() + 1 -// ); -// // Assert the non-pbh transaction is included in the block last -// assert_eq!( -// payload.block().body.transactions.last().unwrap().hash(), -// non_pbh_hash -// ); -// let block_hash = payload.block().hash(); -// let block_number = payload.block().number; - -// let tip = pbh_tx_hashes[0]; -// ctx.node -// .assert_new_block(tip, block_hash, block_number) -// .await?; - -// Ok(()) -// } - -// #[tokio::test] -// #[serial] -// async fn test_invalidate_dup_tx_and_nullifier() -> eyre::Result<()> { -// tokio::time::sleep(Duration::from_secs(1)).await; -// let ctx = WorldChainBuilderTestContext::setup().await?; -// let signer = ctx.pbh_wallets[0].clone(); -// let raw_tx = ctx.raw_pbh_tx_bytes(signer.clone(), 0, 0).await; -// ctx.node.rpc.inject_tx(raw_tx.clone()).await?; -// let dup_pbh_hash_res = ctx.node.rpc.inject_tx(raw_tx.clone()).await; -// assert!(dup_pbh_hash_res.is_err()); -// Ok(()) -// } - -// #[tokio::test] -// #[serial] -// async fn test_dup_pbh_nonce() -> eyre::Result<()> { -// tokio::time::sleep(Duration::from_secs(1)).await; -// let mut ctx = WorldChainBuilderTestContext::setup().await?; -// let signer = ctx.pbh_wallets[0].clone(); - -// let raw_tx_0 = ctx.raw_pbh_tx_bytes(signer.clone(), 0, 0).await; -// ctx.node.rpc.inject_tx(raw_tx_0.clone()).await?; -// let raw_tx_1 = ctx.raw_pbh_tx_bytes(signer.clone(), 0, 1).await; - -// // Now that the nullifier has successfully been stored in -// // the `ExecutedPbhNullifierTable`, inserting a new tx with the -// // same pbh_nonce should fail to validate. -// assert!(ctx.node.rpc.inject_tx(raw_tx_1.clone()).await.is_err()); - -// let (payload, _) = ctx.node.advance_block().await?; - -// // One transaction should be successfully validated -// // and included in the block. -// assert_eq!(payload.block().body.transactions.len(), 1); - -// Ok(()) -// } - -// /// Helper function to create a new eth payload attributes -// pub fn optimism_payload_attributes(timestamp: u64) -> OptimismPayloadBuilderAttributes { -// let attributes = EthPayloadBuilderAttributes { -// timestamp, -// prev_randao: B256::ZERO, -// suggested_fee_recipient: Address::ZERO, -// withdrawals: Withdrawals::default(), -// parent_beacon_block_root: Some(B256::ZERO), -// id: PayloadId(FixedBytes::<8>::random()), -// parent: FixedBytes::default(), -// }; - -// OptimismPayloadBuilderAttributes { -// payload_attributes: attributes, -// transactions: vec![], -// gas_limit: None, -// no_tx_pool: false, -// } -// } - -// fn tx(chain_id: u64, data: Option, nonce: u64) -> TransactionRequest { -// TransactionRequest { -// nonce: Some(nonce), -// value: Some(U256::from(100)), -// to: Some(TxKind::Call(Address::random())), -// gas: Some(210000), -// max_fee_per_gas: Some(20e10 as u128), -// max_priority_fee_per_gas: Some(20e10 as u128), -// chain_id: Some(chain_id), -// input: TransactionInput { input: None, data }, -// ..Default::default() -// } -// } - -// /// Builds an OP Mainnet chain spec with the given merkle root -// /// Populated in the OpWorldID contract. -// fn get_chain_spec(merkle_root: Field) -> OpChainSpec { -// let genesis: Genesis = serde_json::from_str(include_str!("assets/genesis.json")).unwrap(); -// OpChainSpecBuilder::base_mainnet() -// .genesis(genesis.extend_accounts(vec![( -// OP_WORLD_ID, -// GenesisAccount::default().with_storage(Some(BTreeMap::from_iter(vec![( -// LATEST_ROOT_SLOT.into(), -// merkle_root.into(), -// )]))), -// )])) -// .ecotone_activated() -// .build() -// } +//! Utilities for running world chain builder end-to-end tests. +use crate::{ + node::{ + args::{ExtArgs, WorldChainBuilderArgs}, + builder::WorldChainBuilder, + }, + pbh::{ + date_marker::DateMarker, + external_nullifier::{ExternalNullifier, Prefix}, + payload::{PbhPayload, Proof}, + }, + pool::{ + ordering::WorldChainOrdering, + root::{LATEST_ROOT_SLOT, OP_WORLD_ID}, + tx::WorldChainPooledTransaction, + validator::WorldChainTransactionValidator, + }, + primitives::WorldChainPooledTransactionsElement, + rpc::bundle::{EthTransactionsExtServer, WorldChainEthApiExt}, +}; +use alloy_eips::eip2718::Decodable2718; +use alloy_genesis::{Genesis, GenesisAccount}; +use alloy_network::eip2718::Encodable2718; +use alloy_network::{Ethereum, EthereumWallet, TransactionBuilder}; +use alloy_rpc_types::{TransactionInput, TransactionRequest, Withdrawals}; +use alloy_signer_local::PrivateKeySigner; +use chrono::Utc; +use reth::payload::{EthPayloadBuilderAttributes, PayloadId}; +use reth::tasks::TaskManager; +use reth::transaction_pool::{blobstore::DiskFileBlobStore, TransactionValidationTaskExecutor}; +use reth::{ + api::{FullNodeTypesAdapter, NodeTypesWithDBAdapter}, + builder::components::Components, +}; +use reth::{ + builder::{NodeAdapter, NodeBuilder, NodeConfig, NodeHandle}, + transaction_pool::Pool, +}; +use reth_db::{ + test_utils::{tempdir_path, TempDatabase}, + DatabaseEnv, +}; +use reth_e2e_test_utils::{ + node::NodeTestContext, transaction::TransactionTestContext, wallet::Wallet, +}; +use reth_evm::execute::BasicBlockExecutorProvider; +use reth_node_core::args::RpcServerArgs; +use reth_optimism_chainspec::{OpChainSpec, OpChainSpecBuilder}; +use reth_optimism_consensus::OpBeaconConsensus; +use reth_optimism_evm::{OpEvmConfig, OpExecutionStrategyFactory}; +use reth_optimism_node::{node::OpAddOns, OpPayloadBuilderAttributes}; +use reth_primitives::PooledTransactionsElement; +use reth_provider::providers::BlockchainProvider; +use revm_primitives::{Address, Bytes, FixedBytes, TxKind, B256, U256}; +use semaphore::{ + hash_to_field, + identity::Identity, + poseidon_tree::LazyPoseidonTree, + protocol::{generate_nullifier_hash, generate_proof}, + Field, +}; +use serial_test::serial; +use std::{ + collections::{BTreeMap, HashMap}, + sync::Arc, + time::Duration, +}; + +pub const DEV_CHAIN_ID: u64 = 8453; + +type NodeAdapterType = NodeAdapter< + FullNodeTypesAdapter< + NodeTypesWithDBAdapter>>, + BlockchainProvider< + NodeTypesWithDBAdapter>>, + >, + >, + Components< + FullNodeTypesAdapter< + NodeTypesWithDBAdapter>>, + BlockchainProvider< + NodeTypesWithDBAdapter>>, + >, + >, + Pool< + TransactionValidationTaskExecutor< + WorldChainTransactionValidator< + BlockchainProvider< + NodeTypesWithDBAdapter>>, + >, + WorldChainPooledTransaction, + >, + >, + WorldChainOrdering, + DiskFileBlobStore, + >, + OpEvmConfig, + BasicBlockExecutorProvider, + Arc, + >, +>; + +type Adapter = NodeTestContext>; + +pub struct WorldChainBuilderTestContext { + pub pbh_wallets: Vec, + pub tree: LazyPoseidonTree, + pub tasks: TaskManager, + pub node: Adapter, + pub identities: HashMap, +} + +impl WorldChainBuilderTestContext { + pub async fn setup() -> eyre::Result { + let wallets = Wallet::new(20).with_chain_id(DEV_CHAIN_ID).gen(); + let mut tree = LazyPoseidonTree::new(30, Field::from(0)).derived(); + let mut identities = HashMap::new(); + for (i, signer) in wallets.iter().enumerate() { + let address = signer.address(); + identities.insert(address, i); + let identity = Identity::from_secret(signer.address().as_mut_slice(), None); + tree = tree.update(i, &identity.commitment()); + } + + let op_chain_spec = Arc::new(get_chain_spec(tree.root())); + + let tasks = TaskManager::current(); + let exec = tasks.executor(); + + let node_config: NodeConfig = NodeConfig::new(op_chain_spec.clone()) + .with_chain(op_chain_spec.clone()) + .with_unused_ports() + .with_rpc( + RpcServerArgs::default() + .with_unused_ports() + .with_http_unused_port(), + ); + let path = tempdir_path(); + let NodeHandle { + node, + node_exit_future: _, + } = NodeBuilder::new(node_config.clone()) + .testing_node(exec.clone()) + .node(WorldChainBuilder::new( + ExtArgs { + builder_args: WorldChainBuilderArgs { + num_pbh_txs: 30, + verified_blockspace_capacity: 70, + ..Default::default() + }, + ..Default::default() + }, + &path, + )?) + .extend_rpc_modules(move |ctx| { + let provider = ctx.provider().clone(); + let pool = ctx.pool().clone(); + let eth_api_ext = WorldChainEthApiExt::new(pool, provider); + ctx.modules.merge_configured(eth_api_ext.into_rpc())?; + Ok(()) + }) + .launch() + .await?; + let test_ctx = NodeTestContext::new(node, optimism_payload_attributes).await?; + Ok(Self { + pbh_wallets: wallets, + tree, + tasks, + node: test_ctx, + identities, + }) + } + + pub async fn raw_pbh_tx_bytes( + &self, + signer: PrivateKeySigner, + pbh_nonce: u16, + tx_nonce: u64, + ) -> Bytes { + let tx = tx(DEV_CHAIN_ID, None, tx_nonce); + let envelope = TransactionTestContext::sign_tx(signer.clone(), tx).await; + let raw_tx = envelope.encoded_2718(); + let mut data = raw_tx.as_ref(); + let recovered = PooledTransactionsElement::decode_2718(&mut data).unwrap(); + let pbh_payload = self.valid_proof( + signer.address(), + recovered.hash().as_slice(), + chrono::Utc::now(), + pbh_nonce, + ); + + let world_chain_pooled_tx_element = WorldChainPooledTransactionsElement { + inner: recovered, + pbh_payload: Some(pbh_payload.clone()), + }; + + let mut buff = Vec::::new(); + world_chain_pooled_tx_element.encode_2718(&mut buff); + buff.into() + } + + fn valid_proof( + &self, + identity: Address, + tx_hash: &[u8], + time: chrono::DateTime, + pbh_nonce: u16, + ) -> PbhPayload { + let external_nullifier = + ExternalNullifier::new(Prefix::V1, DateMarker::from(time), pbh_nonce).to_string(); + + self.create_proof(identity, external_nullifier, tx_hash) + } + + fn create_proof( + &self, + mut identity: Address, + external_nullifier: String, + signal: &[u8], + ) -> PbhPayload { + let idx = self.identities.get(&identity).unwrap(); + let secret = identity.as_mut_slice(); + // generate identity + let id = Identity::from_secret(secret, None); + let merkle_proof = self.tree.proof(*idx); + + let signal_hash = hash_to_field(signal); + let external_nullifier_hash = hash_to_field(external_nullifier.as_bytes()); + let nullifier_hash = generate_nullifier_hash(&id, external_nullifier_hash); + + let proof = Proof( + generate_proof(&id, &merkle_proof, external_nullifier_hash, signal_hash).unwrap(), + ); + + PbhPayload { + root: self.tree.root(), + nullifier_hash, + external_nullifier, + proof, + } + } +} + +#[tokio::test] +#[serial] +async fn test_can_build_pbh_payload() -> eyre::Result<()> { + tokio::time::sleep(Duration::from_secs(1)).await; + let mut ctx = WorldChainBuilderTestContext::setup().await?; + let mut pbh_tx_hashes = vec![]; + for signer in ctx.pbh_wallets.iter() { + let raw_tx = ctx.raw_pbh_tx_bytes(signer.clone(), 0, 0).await; + let pbh_hash = ctx.node.rpc.inject_tx(raw_tx.clone()).await?; + pbh_tx_hashes.push(pbh_hash); + } + + let (payload, _) = ctx.node.advance_block().await?; + + assert_eq!(payload.block().body.transactions.len(), pbh_tx_hashes.len()); + let block_hash = payload.block().hash(); + let block_number = payload.block().number; + + let tip = pbh_tx_hashes[0]; + ctx.node + .assert_new_block(tip, block_hash, block_number) + .await?; + + Ok(()) +} + +#[tokio::test] +#[serial] +async fn test_transaction_pool_ordering() -> eyre::Result<()> { + tokio::time::sleep(Duration::from_secs(1)).await; + let mut ctx = WorldChainBuilderTestContext::setup().await?; + let non_pbh_tx = tx(ctx.node.inner.chain_spec().chain.id(), None, 0); + let wallet = ctx.pbh_wallets[0].clone(); + let signer = EthereumWallet::from(wallet); + let signed = >::build(non_pbh_tx, &signer) + .await + .unwrap(); + let non_pbh_hash = ctx.node.rpc.inject_tx(signed.encoded_2718().into()).await?; + let mut pbh_tx_hashes = vec![]; + for signer in ctx.pbh_wallets.iter().skip(1) { + let raw_tx = ctx.raw_pbh_tx_bytes(signer.clone(), 0, 0).await; + let pbh_hash = ctx.node.rpc.inject_tx(raw_tx.clone()).await?; + pbh_tx_hashes.push(pbh_hash); + } + + let (payload, _) = ctx.node.advance_block().await?; + + assert_eq!( + payload.block().body.transactions.len(), + pbh_tx_hashes.len() + 1 + ); + // Assert the non-pbh transaction is included in the block last + assert_eq!( + payload.block().body.transactions.last().unwrap().hash(), + non_pbh_hash + ); + let block_hash = payload.block().hash(); + let block_number = payload.block().number; + + let tip = pbh_tx_hashes[0]; + ctx.node + .assert_new_block(tip, block_hash, block_number) + .await?; + + Ok(()) +} + +#[tokio::test] +#[serial] +async fn test_invalidate_dup_tx_and_nullifier() -> eyre::Result<()> { + tokio::time::sleep(Duration::from_secs(1)).await; + let ctx = WorldChainBuilderTestContext::setup().await?; + let signer = ctx.pbh_wallets[0].clone(); + let raw_tx = ctx.raw_pbh_tx_bytes(signer.clone(), 0, 0).await; + ctx.node.rpc.inject_tx(raw_tx.clone()).await?; + let dup_pbh_hash_res = ctx.node.rpc.inject_tx(raw_tx.clone()).await; + assert!(dup_pbh_hash_res.is_err()); + Ok(()) +} + +#[tokio::test] +#[serial] +async fn test_dup_pbh_nonce() -> eyre::Result<()> { + tokio::time::sleep(Duration::from_secs(1)).await; + let mut ctx = WorldChainBuilderTestContext::setup().await?; + let signer = ctx.pbh_wallets[0].clone(); + + let raw_tx_0 = ctx.raw_pbh_tx_bytes(signer.clone(), 0, 0).await; + ctx.node.rpc.inject_tx(raw_tx_0.clone()).await?; + let raw_tx_1 = ctx.raw_pbh_tx_bytes(signer.clone(), 0, 1).await; + + // Now that the nullifier has successfully been stored in + // the `ExecutedPbhNullifierTable`, inserting a new tx with the + // same pbh_nonce should fail to validate. + assert!(ctx.node.rpc.inject_tx(raw_tx_1.clone()).await.is_err()); + + let (payload, _) = ctx.node.advance_block().await?; + + // One transaction should be successfully validated + // and included in the block. + assert_eq!(payload.block().body.transactions.len(), 1); + + Ok(()) +} + +/// Helper function to create a new eth payload attributes +pub fn optimism_payload_attributes(timestamp: u64) -> OpPayloadBuilderAttributes { + let attributes = EthPayloadBuilderAttributes { + timestamp, + prev_randao: B256::ZERO, + suggested_fee_recipient: Address::ZERO, + withdrawals: Withdrawals::default(), + parent_beacon_block_root: Some(B256::ZERO), + id: PayloadId(FixedBytes::<8>::random()), + parent: FixedBytes::default(), + }; + + OpPayloadBuilderAttributes { + payload_attributes: attributes, + transactions: vec![], + gas_limit: None, + no_tx_pool: false, + eip_1559_params: None, + } +} + +fn tx(chain_id: u64, data: Option, nonce: u64) -> TransactionRequest { + TransactionRequest { + nonce: Some(nonce), + value: Some(U256::from(100)), + to: Some(TxKind::Call(Address::random())), + gas: Some(210000), + max_fee_per_gas: Some(20e10 as u128), + max_priority_fee_per_gas: Some(20e10 as u128), + chain_id: Some(chain_id), + input: TransactionInput { input: None, data }, + ..Default::default() + } +} + +/// Builds an OP Mainnet chain spec with the given merkle root +/// Populated in the OpWorldID contract. +fn get_chain_spec(merkle_root: Field) -> OpChainSpec { + let genesis: Genesis = serde_json::from_str(include_str!("assets/genesis.json")).unwrap(); + OpChainSpecBuilder::base_mainnet() + .genesis(genesis.extend_accounts(vec![( + OP_WORLD_ID, + GenesisAccount::default().with_storage(Some(BTreeMap::from_iter(vec![( + LATEST_ROOT_SLOT.into(), + merkle_root.into(), + )]))), + )])) + .ecotone_activated() + .build() +} From 2e4bbeb2259798a1ea84ee4f29749d75d19e759e Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Thu, 12 Dec 2024 15:07:44 -0700 Subject: [PATCH 19/59] fix: tests --- world-chain-builder/src/pool/root.rs | 2 +- world-chain-builder/src/primitives.rs | 179 +++++++++++++------------- 2 files changed, 91 insertions(+), 90 deletions(-) diff --git a/world-chain-builder/src/pool/root.rs b/world-chain-builder/src/pool/root.rs index 6a3d194c..e316cc9d 100644 --- a/world-chain-builder/src/pool/root.rs +++ b/world-chain-builder/src/pool/root.rs @@ -203,7 +203,7 @@ mod tests { .add_block(block.hash_slow(), block.clone()); let block = SealedBlock { header: SealedHeader::new(block.header.clone(), block.header.hash_slow()), - body: block.body + body: block.body, }; validator.on_new_block(&block.into()); } diff --git a/world-chain-builder/src/primitives.rs b/world-chain-builder/src/primitives.rs index 31f1ef3d..73055c8f 100644 --- a/world-chain-builder/src/primitives.rs +++ b/world-chain-builder/src/primitives.rs @@ -152,92 +152,93 @@ pub fn recover_raw_transaction( Ok((ecrecovered, data)) } -// #[cfg(test)] -// mod tests { -// use super::*; -// use alloy_primitives::{address, hex}; - -// #[test] -// fn invalid_legacy_pooled_decoding_input_too_short() { -// let input_too_short = [ -// // this should fail because the payload length is longer than expected -// &hex!("d90b0280808bc5cd028083c5cdfd9e407c56565656")[..], -// // these should fail decoding -// // -// // The `c1` at the beginning is a list header, and the rest is a valid legacy -// // transaction, BUT the payload length of the list header is 1, and the payload is -// // obviously longer than one byte. -// &hex!("c10b02808083c5cd028883c5cdfd9e407c56565656"), -// &hex!("c10b0280808bc5cd028083c5cdfd9e407c56565656"), -// // this one is 19 bytes, and the buf is long enough, but the transaction will not -// // consume that many bytes. -// &hex!("d40b02808083c5cdeb8783c5acfd9e407c5656565656"), -// &hex!("d30102808083c5cd02887dc5cdfd9e64fd9e407c56"), -// ]; - -// for hex_data in &input_too_short { -// let input_rlp = &mut &hex_data[..]; -// let res = WorldChainPooledTransactionsElement::decode_2718(input_rlp); - -// assert!( -// res.is_err(), -// "expected err after decoding rlp input: {:x?}", -// Bytes::copy_from_slice(hex_data) -// ); - -// // this is a legacy tx so we can attempt the same test with decode_enveloped -// let input_rlp = &mut &hex_data[..]; -// let res = WorldChainPooledTransactionsElement::decode_2718(input_rlp); - -// assert!( -// res.is_err(), -// "expected err after decoding enveloped rlp input: {:x?}", -// Bytes::copy_from_slice(hex_data) -// ); -// } -// } - -// // -// #[test] -// fn decode_eip1559_enveloped() { -// let data = hex!("02f903d382426882ba09832dc6c0848674742682ed9694714b6a4ea9b94a8a7d9fd362ed72630688c8898c80b90364492d24749189822d8512430d3f3ff7a2ede675ac08265c08e2c56ff6fdaa66dae1cdbe4a5d1d7809f3e99272d067364e597542ac0c369d69e22a6399c3e9bee5da4b07e3f3fdc34c32c3d88aa2268785f3e3f8086df0934b10ef92cfffc2e7f3d90f5e83302e31382e302d64657600000000000000000000000000000000000000000000569e75fc77c1a856f6daaf9e69d8a9566ca34aa47f9133711ce065a571af0cfd000000000000000000000000e1e210594771824dad216568b91c9cb4ceed361c00000000000000000000000000000000000000000000000000000000000546e00000000000000000000000000000000000000000000000000000000000e4e1c00000000000000000000000000000000000000000000000000000000065d6750c00000000000000000000000000000000000000000000000000000000000f288000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002cf600000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000f1628e56fa6d8c50e5b984a58c0df14de31c7b857ce7ba499945b99252976a93d06dcda6776fc42167fbe71cb59f978f5ef5b12577a90b132d14d9c6efa528076f0161d7bf03643cfc5490ec5084f4a041db7f06c50bd97efa08907ba79ddcac8b890f24d12d8db31abbaaf18985d54f400449ee0559a4452afe53de5853ce090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000064ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000c080a01428023fc54a27544abc421d5d017b9a7c5936ad501cbdecd0d9d12d04c1a033a0753104bbf1c87634d6ff3f0ffa0982710612306003eb022363b57994bdef445a"); - -// let res = WorldChainPooledTransactionsElement::decode_2718(&mut &data[..]).unwrap(); -// assert_eq!( -// res.into_transaction().to(), -// Some(address!("714b6a4ea9b94a8a7d9fd362ed72630688c8898c")) -// ); -// } - -// #[test] -// fn legacy_valid_pooled_decoding() { -// // d3 <- payload length, d3 - c0 = 0x13 = 19 -// // 0b <- nonce -// // 02 <- gas_price -// // 80 <- gas_limit -// // 80 <- to (Create) -// // 83 c5cdeb <- value -// // 87 83c5acfd9e407c <- input -// // 56 <- v (eip155, so modified with a chain id) -// // 56 <- r -// // 56 <- s -// let data = &hex!("d30b02808083c5cdeb8783c5acfd9e407c565656")[..]; - -// let input_rlp = &mut &data[..]; -// let res = WorldChainPooledTransactionsElement::decode_2718(input_rlp); -// println!("{:?}", res); -// assert!(matches!(res, Ok(_tx))); -// assert!(input_rlp.is_empty()); - -// // this is a legacy tx so we can attempt the same test with -// // decode_rlp_legacy_transaction_tuple -// let input_rlp = &mut &data[..]; -// let res = TransactionSigned::decode_rlp_legacy_transaction(input_rlp); -// assert!(matches!(res, Ok(_tx))); -// assert!(input_rlp.is_empty()); - -// // we can also decode_enveloped -// let res = WorldChainPooledTransactionsElement::decode_2718(&mut &data[..]); -// assert!(matches!(res, Ok(_tx))); -// } -// } +#[cfg(test)] +mod tests { + use super::*; + use alloy_consensus::Transaction; + use alloy_primitives::{address, hex}; + + #[test] + fn invalid_legacy_pooled_decoding_input_too_short() { + let input_too_short = [ + // this should fail because the payload length is longer than expected + &hex!("d90b0280808bc5cd028083c5cdfd9e407c56565656")[..], + // these should fail decoding + // + // The `c1` at the beginning is a list header, and the rest is a valid legacy + // transaction, BUT the payload length of the list header is 1, and the payload is + // obviously longer than one byte. + &hex!("c10b02808083c5cd028883c5cdfd9e407c56565656"), + &hex!("c10b0280808bc5cd028083c5cdfd9e407c56565656"), + // this one is 19 bytes, and the buf is long enough, but the transaction will not + // consume that many bytes. + &hex!("d40b02808083c5cdeb8783c5acfd9e407c5656565656"), + &hex!("d30102808083c5cd02887dc5cdfd9e64fd9e407c56"), + ]; + + for hex_data in &input_too_short { + let input_rlp = &mut &hex_data[..]; + let res = WorldChainPooledTransactionsElement::decode_2718(input_rlp); + + assert!( + res.is_err(), + "expected err after decoding rlp input: {:x?}", + Bytes::copy_from_slice(hex_data) + ); + + // this is a legacy tx so we can attempt the same test with decode_enveloped + let input_rlp = &mut &hex_data[..]; + let res = WorldChainPooledTransactionsElement::decode_2718(input_rlp); + + assert!( + res.is_err(), + "expected err after decoding enveloped rlp input: {:x?}", + Bytes::copy_from_slice(hex_data) + ); + } + } + + // + #[test] + fn decode_eip1559_enveloped() { + let data = hex!("02f903d382426882ba09832dc6c0848674742682ed9694714b6a4ea9b94a8a7d9fd362ed72630688c8898c80b90364492d24749189822d8512430d3f3ff7a2ede675ac08265c08e2c56ff6fdaa66dae1cdbe4a5d1d7809f3e99272d067364e597542ac0c369d69e22a6399c3e9bee5da4b07e3f3fdc34c32c3d88aa2268785f3e3f8086df0934b10ef92cfffc2e7f3d90f5e83302e31382e302d64657600000000000000000000000000000000000000000000569e75fc77c1a856f6daaf9e69d8a9566ca34aa47f9133711ce065a571af0cfd000000000000000000000000e1e210594771824dad216568b91c9cb4ceed361c00000000000000000000000000000000000000000000000000000000000546e00000000000000000000000000000000000000000000000000000000000e4e1c00000000000000000000000000000000000000000000000000000000065d6750c00000000000000000000000000000000000000000000000000000000000f288000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002cf600000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000f1628e56fa6d8c50e5b984a58c0df14de31c7b857ce7ba499945b99252976a93d06dcda6776fc42167fbe71cb59f978f5ef5b12577a90b132d14d9c6efa528076f0161d7bf03643cfc5490ec5084f4a041db7f06c50bd97efa08907ba79ddcac8b890f24d12d8db31abbaaf18985d54f400449ee0559a4452afe53de5853ce090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000064ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000c080a01428023fc54a27544abc421d5d017b9a7c5936ad501cbdecd0d9d12d04c1a033a0753104bbf1c87634d6ff3f0ffa0982710612306003eb022363b57994bdef445a"); + + let res = WorldChainPooledTransactionsElement::decode_2718(&mut &data[..]).unwrap(); + assert_eq!( + res.into_transaction().to(), + Some(address!("714b6a4ea9b94a8a7d9fd362ed72630688c8898c")) + ); + } + + #[test] + fn legacy_valid_pooled_decoding() { + // d3 <- payload length, d3 - c0 = 0x13 = 19 + // 0b <- nonce + // 02 <- gas_price + // 80 <- gas_limit + // 80 <- to (Create) + // 83 c5cdeb <- value + // 87 83c5acfd9e407c <- input + // 56 <- v (eip155, so modified with a chain id) + // 56 <- r + // 56 <- s + let data = &hex!("d30b02808083c5cdeb8783c5acfd9e407c565656")[..]; + + let input_rlp = &mut &data[..]; + let res = WorldChainPooledTransactionsElement::decode_2718(input_rlp); + println!("{:?}", res); + assert!(matches!(res, Ok(_tx))); + assert!(input_rlp.is_empty()); + + // this is a legacy tx so we can attempt the same test with + // decode_rlp_legacy_transaction_tuple + let input_rlp = &mut &data[..]; + let res = TransactionSigned::decode_rlp_legacy_transaction(input_rlp); + assert!(matches!(res, Ok(_tx))); + assert!(input_rlp.is_empty()); + + // we can also decode_enveloped + let res = WorldChainPooledTransactionsElement::decode_2718(&mut &data[..]); + assert!(matches!(res, Ok(_tx))); + } +} From 41293aa56aab0e39871b87b5672fc0c282505d80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Tr=C4=85d?= Date: Fri, 13 Dec 2024 16:39:48 +0100 Subject: [PATCH 20/59] Dzejkop/reth-1.1.4 (#79) * add update OP Payload Builder type * wip * add world chain builder * wip, fix imports * fix witness * temp remove tests * Massive reorg (reflects optimism directory within reth) * Fix primitives deps * Remove old bin * wip * wip * wip * Back to square 1 * @0xKitsune's changes * fmt * fix * Code compiles - tests don't * Everything compiles --------- Co-authored-by: 0xKitsune <0xkitsune@protonmail.com> --- world-chain-builder/Cargo.lock | 531 ++++----- world-chain-builder/Cargo.toml | 96 +- world-chain-builder/crates/toolkit/Cargo.toml | 36 +- world-chain-builder/crates/toolkit/src/cli.rs | 2 +- .../crates/toolkit/src/main.rs | 8 +- .../crates/world/bin/Cargo.toml | 93 ++ .../world/bin/src/main.rs} | 7 +- .../crates/world/db/Cargo.toml | 16 + .../pbh/db.rs => crates/world/db/src/lib.rs} | 0 .../crates/world/node/Cargo.toml | 50 + .../node}/benches/validate_transaction.rs | 10 +- .../node => crates/world/node/src}/args.rs | 0 .../crates/world/node/src/lib.rs | 6 + .../crates/world/node/src/node.rs | 287 +++++ .../world/node/src}/test_utils.rs | 2 +- .../world/node/test}/assets/genesis.json | 0 .../mod.rs => crates/world/node/test/e2e.rs} | 79 +- .../crates/world/payload/Cargo.toml | 44 + .../crates/world/payload/src/builder.rs | 514 +++++++++ .../world/payload/src/lib.rs} | 0 .../crates/world/pbh/Cargo.toml | 17 + .../world/pbh/src}/date_marker.rs | 0 .../world/pbh/src}/external_nullifier.rs | 5 +- .../mod.rs => crates/world/pbh/src/lib.rs} | 1 - .../pbh => crates/world/pbh/src}/payload.rs | 0 .../crates/world/pool/Cargo.toml | 53 + .../pool => crates/world/pool/src}/builder.rs | 13 +- .../pool => crates/world/pool/src}/error.rs | 2 +- .../mod.rs => crates/world/pool/src/lib.rs} | 3 + .../pool => crates/world/pool/src}/noop.rs | 0 .../world/pool/src}/ordering.rs | 0 .../pool => crates/world/pool/src}/root.rs | 0 .../world/pool/src/test_utils.rs} | 17 +- .../{src/pool => crates/world/pool/src}/tx.rs | 2 +- .../world/pool/src}/validator.rs | 17 +- .../crates/world/primitives/Cargo.toml | 29 + .../crates/world/primitives/src/lib.rs | 1 + .../world/primitives/src/transaction.rs} | 2 +- .../crates/world/rpc/Cargo.toml | 26 + .../rpc => crates/world/rpc/src}/bundle.rs | 2 +- .../mod.rs => crates/world/rpc/src/lib.rs} | 0 world-chain-builder/src/lib.rs | 7 - world-chain-builder/src/node/builder.rs | 180 --- world-chain-builder/src/node/mod.rs | 5 - world-chain-builder/src/payload/builder.rs | 1018 ----------------- 45 files changed, 1503 insertions(+), 1678 deletions(-) create mode 100644 world-chain-builder/crates/world/bin/Cargo.toml rename world-chain-builder/{bin/world-chain-builder.rs => crates/world/bin/src/main.rs} (87%) create mode 100644 world-chain-builder/crates/world/db/Cargo.toml rename world-chain-builder/{src/pbh/db.rs => crates/world/db/src/lib.rs} (100%) create mode 100644 world-chain-builder/crates/world/node/Cargo.toml rename world-chain-builder/{ => crates/world/node}/benches/validate_transaction.rs (94%) rename world-chain-builder/{src/node => crates/world/node/src}/args.rs (100%) create mode 100644 world-chain-builder/crates/world/node/src/lib.rs create mode 100644 world-chain-builder/crates/world/node/src/node.rs rename world-chain-builder/{src/node => crates/world/node/src}/test_utils.rs (99%) rename world-chain-builder/{src/test/e2e => crates/world/node/test}/assets/genesis.json (100%) rename world-chain-builder/{src/test/e2e/mod.rs => crates/world/node/test/e2e.rs} (88%) create mode 100644 world-chain-builder/crates/world/payload/Cargo.toml create mode 100644 world-chain-builder/crates/world/payload/src/builder.rs rename world-chain-builder/{src/payload/mod.rs => crates/world/payload/src/lib.rs} (100%) create mode 100644 world-chain-builder/crates/world/pbh/Cargo.toml rename world-chain-builder/{src/pbh => crates/world/pbh/src}/date_marker.rs (100%) rename world-chain-builder/{src/pbh => crates/world/pbh/src}/external_nullifier.rs (96%) rename world-chain-builder/{src/pbh/mod.rs => crates/world/pbh/src/lib.rs} (84%) rename world-chain-builder/{src/pbh => crates/world/pbh/src}/payload.rs (100%) create mode 100644 world-chain-builder/crates/world/pool/Cargo.toml rename world-chain-builder/{src/pool => crates/world/pool/src}/builder.rs (96%) rename world-chain-builder/{src/pool => crates/world/pool/src}/error.rs (97%) rename world-chain-builder/{src/pool/mod.rs => crates/world/pool/src/lib.rs} (70%) rename world-chain-builder/{src/pool => crates/world/pool/src}/noop.rs (100%) rename world-chain-builder/{src/pool => crates/world/pool/src}/ordering.rs (100%) rename world-chain-builder/{src/pool => crates/world/pool/src}/root.rs (100%) rename world-chain-builder/{src/test/mod.rs => crates/world/pool/src/test_utils.rs} (97%) rename world-chain-builder/{src/pool => crates/world/pool/src}/tx.rs (99%) rename world-chain-builder/{src/pool => crates/world/pool/src}/validator.rs (97%) create mode 100644 world-chain-builder/crates/world/primitives/Cargo.toml create mode 100644 world-chain-builder/crates/world/primitives/src/lib.rs rename world-chain-builder/{src/primitives.rs => crates/world/primitives/src/transaction.rs} (99%) create mode 100644 world-chain-builder/crates/world/rpc/Cargo.toml rename world-chain-builder/{src/rpc => crates/world/rpc/src}/bundle.rs (99%) rename world-chain-builder/{src/rpc/mod.rs => crates/world/rpc/src/lib.rs} (100%) delete mode 100644 world-chain-builder/src/lib.rs delete mode 100644 world-chain-builder/src/node/builder.rs delete mode 100644 world-chain-builder/src/node/mod.rs delete mode 100644 world-chain-builder/src/payload/builder.rs diff --git a/world-chain-builder/Cargo.lock b/world-chain-builder/Cargo.lock index 6656262a..0b933a72 100644 --- a/world-chain-builder/Cargo.lock +++ b/world-chain-builder/Cargo.lock @@ -127,20 +127,6 @@ dependencies = [ "strum", ] -[[package]] -name = "alloy-consensus" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "629b62e38d471cc15fea534eb7283d2f8a4e8bdb1811bcc5d66dda6cfce6fae1" -dependencies = [ - "alloy-eips 0.3.6", - "alloy-primitives", - "alloy-rlp", - "alloy-serde 0.3.6", - "c-kzg", - "serde", -] - [[package]] name = "alloy-consensus" version = "0.4.2" @@ -230,7 +216,6 @@ checksum = "ea59dc42102bc9a1905dc57901edc6dd48b9f38115df86c7d252acba70d71d04" dependencies = [ "alloy-primitives", "alloy-rlp", - "k256", "serde", ] @@ -250,24 +235,6 @@ dependencies = [ "serde_with", ] -[[package]] -name = "alloy-eips" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f923dd5fca5f67a43d81ed3ebad0880bd41f6dd0ada930030353ac356c54cd0f" -dependencies = [ - "alloy-eip2930", - "alloy-eip7702 0.1.1", - "alloy-primitives", - "alloy-rlp", - "alloy-serde 0.3.6", - "c-kzg", - "derive_more", - "once_cell", - "serde", - "sha2 0.10.8", -] - [[package]] name = "alloy-eips" version = "0.4.2" @@ -331,20 +298,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "alloy-json-rpc" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3c717b5298fad078cd3a418335b266eba91b511383ca9bd497f742d5975d5ab" -dependencies = [ - "alloy-primitives", - "alloy-sol-types", - "serde", - "serde_json", - "thiserror 1.0.69", - "tracing", -] - [[package]] name = "alloy-json-rpc" version = "0.4.2" @@ -373,27 +326,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "alloy-network" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb3705ce7d8602132bcf5ac7a1dd293a42adc2f183abf5907c30ac535ceca049" -dependencies = [ - "alloy-consensus 0.3.6", - "alloy-eips 0.3.6", - "alloy-json-rpc 0.3.6", - "alloy-network-primitives 0.3.6", - "alloy-primitives", - "alloy-rpc-types-eth 0.3.6", - "alloy-serde 0.3.6", - "alloy-signer 0.3.6", - "alloy-sol-types", - "async-trait", - "auto_impl", - "futures-utils-wasm", - "thiserror 1.0.69", -] - [[package]] name = "alloy-network" version = "0.4.2" @@ -440,18 +372,6 @@ dependencies = [ "thiserror 2.0.6", ] -[[package]] -name = "alloy-network-primitives" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94ad40869867ed2d9cd3842b1e800889e5b49e6b92da346e93862b4a741bedf3" -dependencies = [ - "alloy-eips 0.3.6", - "alloy-primitives", - "alloy-serde 0.3.6", - "serde", -] - [[package]] name = "alloy-network-primitives" version = "0.4.2" @@ -744,6 +664,16 @@ dependencies = [ "serde", ] +[[package]] +name = "alloy-rpc-types-debug" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fd14f68a482e67dfba52d404dfff1d3b0d9fc3b4775bd0923f3175d7661c3bd" +dependencies = [ + "alloy-primitives", + "serde", +] + [[package]] name = "alloy-rpc-types-engine" version = "0.7.3" @@ -765,27 +695,6 @@ dependencies = [ "strum", ] -[[package]] -name = "alloy-rpc-types-eth" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83aa984386deda02482660aa31cb8ca1e63d533f1c31a52d7d181ac5ec68e9b8" -dependencies = [ - "alloy-consensus 0.3.6", - "alloy-eips 0.3.6", - "alloy-network-primitives 0.3.6", - "alloy-primitives", - "alloy-rlp", - "alloy-serde 0.3.6", - "alloy-sol-types", - "cfg-if", - "derive_more", - "hashbrown 0.14.5", - "itertools 0.13.0", - "serde", - "serde_json", -] - [[package]] name = "alloy-rpc-types-eth" version = "0.4.2" @@ -867,17 +776,6 @@ dependencies = [ "serde", ] -[[package]] -name = "alloy-serde" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "731f75ec5d383107fd745d781619bd9cedf145836c51ecb991623d41278e71fa" -dependencies = [ - "alloy-primitives", - "serde", - "serde_json", -] - [[package]] name = "alloy-serde" version = "0.4.2" @@ -901,20 +799,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "alloy-signer" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307324cca94354cd654d6713629f0383ec037e1ff9e3e3d547212471209860c0" -dependencies = [ - "alloy-primitives", - "async-trait", - "auto_impl", - "elliptic-curve", - "k256", - "thiserror 1.0.69", -] - [[package]] name = "alloy-signer" version = "0.4.2" @@ -2207,7 +2091,7 @@ checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" dependencies = [ "camino", "cargo-platform", - "semver 1.0.23", + "semver 1.0.24", "serde", "serde_json", "thiserror 1.0.69", @@ -2236,9 +2120,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.3" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d" +checksum = "9157bbaa6b165880c27a4293a474c91cdcf265cc68cc829bf10be0964a391caf" dependencies = [ "jobserver", "libc", @@ -4318,7 +4202,6 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash 0.8.11", "allocator-api2", - "serde", ] [[package]] @@ -7039,9 +6922,9 @@ dependencies = [ [[package]] name = "quanta" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" +checksum = "773ce68d0bb9bc7ef20be3536ffe94e223e1f365bd374108b2659fac0c65cfe6" dependencies = [ "crossbeam-utils", "libc", @@ -7378,7 +7261,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper 0.1.2", - "system-configuration 0.5.1", + "system-configuration", "tokio", "tokio-native-tls", "tower-service", @@ -7397,11 +7280,9 @@ checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" dependencies = [ "base64 0.22.1", "bytes", - "encoding_rs", "futures-channel", "futures-core", "futures-util", - "h2 0.4.7", "http 1.2.0", "http-body 1.0.1", "http-body-util", @@ -7426,7 +7307,6 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper 1.0.2", - "system-configuration 0.6.1", "tokio", "tokio-native-tls", "tokio-rustls", @@ -7868,7 +7748,7 @@ dependencies = [ "reth-consensus", "reth-primitives", "reth-primitives-traits", - "revm-primitives 14.0.0", + "revm-primitives", ] [[package]] @@ -8309,7 +8189,7 @@ dependencies = [ "reth-trie-db", "reth-trie-parallel", "reth-trie-sparse", - "revm-primitives 14.0.0", + "revm-primitives", "thiserror 2.0.6", "tokio", "tracing", @@ -8340,7 +8220,7 @@ dependencies = [ "reth-revm", "reth-rpc-types-compat", "reth-trie", - "revm-primitives 14.0.0", + "revm-primitives", "serde", "serde_json", "tokio", @@ -8536,7 +8416,7 @@ dependencies = [ "reth-revm", "reth-storage-errors", "revm", - "revm-primitives 14.0.0", + "revm-primitives", ] [[package]] @@ -8555,7 +8435,7 @@ dependencies = [ "reth-evm", "reth-primitives", "reth-revm", - "revm-primitives 14.0.0", + "revm-primitives", ] [[package]] @@ -8570,7 +8450,7 @@ dependencies = [ "reth-consensus", "reth-prune-types", "reth-storage-errors", - "revm-primitives 14.0.0", + "revm-primitives", "thiserror 2.0.6", ] @@ -8661,7 +8541,7 @@ dependencies = [ "alloy-consensus 0.7.3", "alloy-primitives", "alloy-rlp", - "alloy-rpc-types-debug", + "alloy-rpc-types-debug 0.7.3", "eyre", "futures", "jsonrpsee", @@ -8987,7 +8867,7 @@ dependencies = [ "reth-tokio-util", "reth-tracing", "reth-transaction-pool", - "revm-primitives 14.0.0", + "revm-primitives", "secp256k1", "tokio", "tokio-stream", @@ -9247,7 +9127,7 @@ dependencies = [ "reth-prune-types", "reth-revm", "revm", - "revm-primitives 14.0.0", + "revm-primitives", "tracing", ] @@ -9270,6 +9150,7 @@ source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.4#15fac0873e91ea29ab2 dependencies = [ "alloy-consensus 0.7.3", "alloy-eips 0.7.3", + "alloy-genesis", "alloy-primitives", "alloy-rpc-types-engine", "clap 4.5.23", @@ -9281,6 +9162,7 @@ dependencies = [ "reth-chainspec", "reth-consensus", "reth-db", + "reth-e2e-test-utils", "reth-engine-local", "reth-evm", "reth-network", @@ -9300,12 +9182,14 @@ dependencies = [ "reth-provider", "reth-revm", "reth-rpc-server-types", + "reth-tasks", "reth-tracing", "reth-transaction-pool", "reth-trie-db", "revm", "serde", "serde_json", + "tokio", ] [[package]] @@ -9317,7 +9201,7 @@ dependencies = [ "alloy-eips 0.7.3", "alloy-primitives", "alloy-rlp", - "alloy-rpc-types-debug", + "alloy-rpc-types-debug 0.7.3", "alloy-rpc-types-engine", "op-alloy-consensus", "op-alloy-rpc-types-engine", @@ -9362,7 +9246,7 @@ dependencies = [ "reth-codecs", "reth-primitives", "reth-primitives-traits", - "revm-primitives 14.0.0", + "revm-primitives", "secp256k1", "serde", ] @@ -9375,7 +9259,7 @@ dependencies = [ "alloy-consensus 0.7.3", "alloy-eips 0.7.3", "alloy-primitives", - "alloy-rpc-types-debug", + "alloy-rpc-types-debug 0.7.3", "alloy-rpc-types-eth 0.7.3", "jsonrpsee-core", "jsonrpsee-types", @@ -9461,7 +9345,7 @@ dependencies = [ "reth-chainspec", "reth-errors", "reth-primitives", - "revm-primitives 14.0.0", + "revm-primitives", "serde", "thiserror 2.0.6", "tokio", @@ -9517,7 +9401,7 @@ dependencies = [ "reth-primitives-traits", "reth-static-file-types", "reth-zstd-compressors", - "revm-primitives 14.0.0", + "revm-primitives", "secp256k1", "serde", "serde_with", @@ -9543,7 +9427,7 @@ dependencies = [ "proptest", "proptest-arbitrary-interop", "reth-codecs", - "revm-primitives 14.0.0", + "revm-primitives", "serde", "serde_with", ] @@ -9670,7 +9554,7 @@ dependencies = [ "alloy-rpc-types", "alloy-rpc-types-admin", "alloy-rpc-types-beacon", - "alloy-rpc-types-debug", + "alloy-rpc-types-debug 0.7.3", "alloy-rpc-types-engine", "alloy-rpc-types-eth 0.7.3", "alloy-rpc-types-mev", @@ -9714,7 +9598,7 @@ dependencies = [ "reth-transaction-pool", "revm", "revm-inspectors", - "revm-primitives 14.0.0", + "revm-primitives", "serde", "serde_json", "thiserror 2.0.6", @@ -9737,7 +9621,7 @@ dependencies = [ "alloy-rpc-types-admin", "alloy-rpc-types-anvil", "alloy-rpc-types-beacon", - "alloy-rpc-types-debug", + "alloy-rpc-types-debug 0.7.3", "alloy-rpc-types-engine", "alloy-rpc-types-eth 0.7.3", "alloy-rpc-types-mev", @@ -9858,7 +9742,7 @@ dependencies = [ "reth-trie-common", "revm", "revm-inspectors", - "revm-primitives 14.0.0", + "revm-primitives", "tokio", "tracing", ] @@ -9896,7 +9780,7 @@ dependencies = [ "reth-trie", "revm", "revm-inspectors", - "revm-primitives 14.0.0", + "revm-primitives", "schnellru", "serde", "thiserror 2.0.6", @@ -10249,7 +10133,7 @@ dependencies = [ "plain_hasher", "reth-codecs", "reth-primitives-traits", - "revm-primitives 14.0.0", + "revm-primitives", "serde", "serde_with", ] @@ -10330,8 +10214,8 @@ dependencies = [ "auto_impl", "cfg-if", "dyn-clone", - "revm-interpreter 14.0.0", - "revm-precompile 15.0.0", + "revm-interpreter", + "revm-precompile", "serde", "serde_json", ] @@ -10355,47 +10239,16 @@ dependencies = [ "thiserror 1.0.69", ] -[[package]] -name = "revm-interpreter" -version = "10.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e5e14002afae20b5bf1566f22316122f42f57517000e559c55b25bf7a49cba2" -dependencies = [ - "paste", - "phf", - "revm-primitives 10.0.0", - "serde", -] - [[package]] name = "revm-interpreter" version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74e3f11d0fed049a4a10f79820c59113a79b38aed4ebec786a79d5c667bfeb51" dependencies = [ - "revm-primitives 14.0.0", + "revm-primitives", "serde", ] -[[package]] -name = "revm-precompile" -version = "11.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3198c06247e8d4ad0d1312591edf049b0de4ddffa9fecb625c318fd67db8639b" -dependencies = [ - "aurora-engine-modexp", - "blst", - "c-kzg", - "cfg-if", - "k256", - "once_cell", - "revm-primitives 10.0.0", - "ripemd", - "secp256k1", - "sha2 0.10.8", - "substrate-bn", -] - [[package]] name = "revm-precompile" version = "15.0.0" @@ -10409,33 +10262,13 @@ dependencies = [ "k256", "once_cell", "p256", - "revm-primitives 14.0.0", + "revm-primitives", "ripemd", "secp256k1", "sha2 0.10.8", "substrate-bn", ] -[[package]] -name = "revm-primitives" -version = "10.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f1525851a03aff9a9d6a1d018b414d76252d6802ab54695b27093ecd7e7a101" -dependencies = [ - "alloy-eip2930", - "alloy-eip7702 0.1.1", - "alloy-primitives", - "auto_impl", - "bitflags 2.6.0", - "bitvec", - "c-kzg", - "cfg-if", - "dyn-clone", - "enumn", - "hex", - "serde", -] - [[package]] name = "revm-primitives" version = "14.0.0" @@ -10581,9 +10414,9 @@ dependencies = [ [[package]] name = "roaring" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395b0c39c00f9296f3937624c1fa4e0ee44f8c0e4b2c49408179ef381c6c2e6e" +checksum = "41589aba99537475bf697f2118357cad1c31590c5a1b9f6d9fc4ad6d07503661" dependencies = [ "bytemuck", "byteorder", @@ -10678,7 +10511,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver 1.0.23", + "semver 1.0.24", ] [[package]] @@ -10875,15 +10708,6 @@ dependencies = [ "syn 2.0.90", ] -[[package]] -name = "scc" -version = "2.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66b202022bb57c049555430e11fc22fea12909276a80a4c3d368da36ac1d88ed" -dependencies = [ - "sdd", -] - [[package]] name = "schannel" version = "0.1.27" @@ -10941,12 +10765,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152" -[[package]] -name = "sdd" -version = "3.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49c1eeaf4b6a87c7479688c6d52b9f1153cedd3c489300564f932b065c6eab95" - [[package]] name = "seahash" version = "4.1.0" @@ -11101,9 +10919,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" dependencies = [ "serde", ] @@ -11269,31 +11087,6 @@ dependencies = [ "unsafe-libyaml", ] -[[package]] -name = "serial_test" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9" -dependencies = [ - "futures", - "log", - "once_cell", - "parking_lot", - "scc", - "serial_test_derive", -] - -[[package]] -name = "serial_test_derive" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.90", -] - [[package]] name = "sha1" version = "0.10.6" @@ -11748,18 +11541,7 @@ checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", "core-foundation 0.9.4", - "system-configuration-sys 0.5.0", -] - -[[package]] -name = "system-configuration" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" -dependencies = [ - "bitflags 2.6.0", - "core-foundation 0.9.4", - "system-configuration-sys 0.6.0", + "system-configuration-sys", ] [[package]] @@ -11772,16 +11554,6 @@ dependencies = [ "libc", ] -[[package]] -name = "system-configuration-sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "tagptr" version = "0.2.0" @@ -12232,8 +12004,8 @@ dependencies = [ name = "toolkit" version = "0.1.0" dependencies = [ - "alloy-consensus 0.3.6", - "alloy-network 0.3.6", + "alloy-consensus 0.7.3", + "alloy-network 0.7.3", "alloy-primitives", "alloy-rlp", "bytes", @@ -12248,7 +12020,7 @@ dependencies = [ "serde", "serde_json", "tokio", - "world-chain-builder", + "world-chain-builder-pbh", ] [[package]] @@ -13127,7 +12899,7 @@ dependencies = [ "hex", "indexmap 2.7.0", "schemars", - "semver 1.0.23", + "semver 1.0.24", "serde", "serde_json", "serde_yaml", @@ -13260,7 +13032,7 @@ dependencies = [ "reqwest 0.12.9", "rkyv", "rusty_pool", - "semver 1.0.23", + "semver 1.0.24", "serde", "serde_derive", "serde_json", @@ -13324,7 +13096,7 @@ checksum = "9dbe55c8f9d0dbd25d9447a5a889ff90c0cc3feaa7395310d3d826b2c703eaab" dependencies = [ "bitflags 2.6.0", "indexmap 2.7.0", - "semver 1.0.23", + "semver 1.0.24", ] [[package]] @@ -13403,7 +13175,7 @@ dependencies = [ "once_cell", "path-clean", "rand", - "semver 1.0.23", + "semver 1.0.24", "serde", "serde_json", "sha2 0.10.8", @@ -13862,38 +13634,22 @@ dependencies = [ "alloy-genesis", "alloy-network 0.7.3", "alloy-primitives", - "alloy-rlp", - "alloy-rpc-types", - "alloy-rpc-types-eth 0.7.3", - "alloy-signer 0.7.3", + "alloy-rpc-types-engine", "alloy-signer-local", - "bytemuck", - "bytes", - "chrono", "clap 4.5.23", "color-eyre", - "criterion 0.5.1", - "derive_more", "dotenvy", - "ethers-core 2.0.14 (git+https://github.com/gakonst/ethers-rs)", "futures", - "hex", - "jsonrpsee", "op-alloy-consensus", - "op-alloy-network", - "op-alloy-rpc-types", + "op-alloy-rpc-types-engine", "parking_lot", - "rand", - "reth", "reth-basic-payload-builder", - "reth-chain-state", "reth-cli-util", "reth-consensus", "reth-db", - "reth-db-api", "reth-e2e-test-utils", - "reth-eth-wire-types", "reth-evm", + "reth-node-builder", "reth-node-core", "reth-optimism-chainspec", "reth-optimism-cli", @@ -13904,30 +13660,175 @@ dependencies = [ "reth-optimism-payload-builder", "reth-optimism-primitives", "reth-optimism-rpc", + "reth-payload-builder", + "reth-payload-util", + "reth-payload-validator", "reth-primitives", "reth-provider", - "reth-prune-types", - "reth-stages-types", + "reth-revm", + "reth-rpc-server-types", + "reth-tasks", "reth-tracing", + "reth-transaction-pool", + "reth-trie-db", + "revm", + "serde", + "serde_json", + "tikv-jemallocator", + "tokio", + "world-chain-builder-node", + "world-chain-builder-rpc", +] + +[[package]] +name = "world-chain-builder-db" +version = "0.1.0" +dependencies = [ + "bytes", + "color-eyre", + "reth-db", + "reth-db-api", + "reth-primitives", + "revm-primitives", + "semaphore", + "serde", + "tracing", +] + +[[package]] +name = "world-chain-builder-node" +version = "0.1.0" +dependencies = [ + "alloy-eips 0.7.3", + "alloy-primitives", + "alloy-rpc-types", + "clap 4.5.23", + "color-eyre", + "criterion 0.5.1", + "futures", + "reth", + "reth-basic-payload-builder", + "reth-chain-state", + "reth-db", + "reth-optimism-chainspec", + "reth-optimism-node", + "reth-optimism-payload-builder", + "reth-optimism-primitives", + "reth-primitives", + "reth-primitives-traits", + "reth-provider", + "reth-prune-types", "reth-trie", "reth-trie-db", + "semaphore", + "tokio", + "world-chain-builder-db", + "world-chain-builder-payload", + "world-chain-builder-pool", +] + +[[package]] +name = "world-chain-builder-payload" +version = "0.1.0" +dependencies = [ + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", + "alloy-rpc-types-debug 0.8.0", + "jsonrpsee", + "reth", + "reth-basic-payload-builder", + "reth-chain-state", + "reth-db", + "reth-evm", + "reth-optimism-chainspec", + "reth-optimism-consensus", + "reth-optimism-node", + "reth-optimism-payload-builder", + "reth-primitives", + "reth-provider", + "reth-transaction-pool", + "reth-trie", "revm", - "revm-inspectors", - "revm-interpreter 10.0.3", - "revm-precompile 11.0.3", - "revm-primitives 14.0.0", + "revm-primitives", + "tracing", + "world-chain-builder-pool", + "world-chain-builder-rpc", +] + +[[package]] +name = "world-chain-builder-pbh" +version = "0.1.0" +dependencies = [ + "alloy-rlp", + "chrono", + "ethers-core 2.0.14 (git+https://github.com/gakonst/ethers-rs)", "semaphore", "serde", - "serde_json", - "serial_test", "strum", - "strum_macros", + "test-case", + "thiserror 1.0.69", +] + +[[package]] +name = "world-chain-builder-pool" +version = "0.1.0" +dependencies = [ + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", + "alloy-primitives", + "alloy-rpc-types", + "chrono", + "color-eyre", + "ethers-core 2.0.14 (git+https://github.com/gakonst/ethers-rs)", + "parking_lot", + "reth", + "reth-db", + "reth-eth-wire-types", + "reth-optimism-chainspec", + "reth-optimism-node", + "reth-optimism-primitives", + "reth-primitives", + "reth-provider", + "revm-primitives", + "semaphore", "tempfile", "test-case", "thiserror 1.0.69", - "tikv-jemallocator", "tokio", "tracing", + "world-chain-builder-db", + "world-chain-builder-pbh", +] + +[[package]] +name = "world-chain-builder-primitives" +version = "0.1.0" +dependencies = [ + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", + "alloy-primitives", + "alloy-rlp", + "bytes", + "reth", + "reth-primitives", + "revm-primitives", + "tracing", + "world-chain-builder-pbh", +] + +[[package]] +name = "world-chain-builder-rpc" +version = "0.1.0" +dependencies = [ + "alloy-consensus 0.7.3", + "alloy-eips 0.7.3", + "alloy-primitives", + "alloy-rpc-types", + "jsonrpsee", + "reth", + "reth-provider", + "revm-primitives", + "world-chain-builder-pool", ] [[package]] diff --git a/world-chain-builder/Cargo.toml b/world-chain-builder/Cargo.toml index fbbbcc1b..52b59863 100644 --- a/world-chain-builder/Cargo.toml +++ b/world-chain-builder/Cargo.toml @@ -1,14 +1,38 @@ -[package] -name = "world-chain-builder" +[workspace.package] version = "0.1.0" edition = "2021" - -default-run = "world-chain-builder" +rust-version = "1.82" +license = "MIT" +homepage = "https://world.org/world-chain" +repository = "https://github.com/worldcoin/world-chain/" [workspace] -members = ["crates/*"] +resolver = "2" +members = [ + "crates/assertor", + "crates/toolkit", + "crates/world/node", + "crates/world/bin", + "crates/world/payload", + "crates/world/rpc", + "crates/world/pbh", + "crates/world/db", + "crates/world/primitives", + "crates/world/pool", +] + +[workspace.lints] + +[workspace.dependencies] +# internal +world-chain-builder-node = { path = "crates/world/node" } +world-chain-builder-db = { path = "crates/world/db" } +world-chain-builder-pbh = { path = "crates/world/pbh" } +world-chain-builder-payload = { path = "crates/world/payload" } +world-chain-builder-primitives = { path = "crates/world/primitives" } +world-chain-builder-rpc = { path = "crates/world/rpc" } +world-chain-builder-pool = { path = "crates/world/pool" } -[dependencies] # reth reth = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } reth-cli-util = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } @@ -19,12 +43,21 @@ reth-provider = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4", f "test-utils", ] } reth-basic-payload-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-transaction-pool = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-rpc-server-types = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } reth-prune-types = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } reth-trie = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } reth-chain-state = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } reth-eth-wire-types = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } reth-stages-types = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } reth-trie-db = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-primitives-traits = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-node-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-payload-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-payload-util = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-payload-validator = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-revm = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4", default-features = false } +reth-tasks = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } # reth-optimism reth-primitives = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4", features = [ @@ -49,11 +82,19 @@ reth-optimism-chainspec = { git = "https://github.com/paradigmxyz/reth", tag = " reth-optimism-payload-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } reth-optimism-forks = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } reth-optimism-primitives = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-e2e-test-utils = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-consensus = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-node-core = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth-tracing = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } -# alloy + +# alloy op op-alloy-consensus = "0.7.3" op-alloy-rpc-types = "0.7.3" +op-alloy-rpc-types-engine = "0.7.3" op-alloy-network = "0.7.3" + +# alloy alloy-consensus = { version = "0.7.3", default-features = false } alloy-network = { version = "0.7.3", default-features = false } alloy-primitives = { version = "0.8.11", default-features = false } @@ -61,28 +102,25 @@ alloy-rpc-types-eth = { version = "0.7.3", default-features = false } alloy-rpc-types = { version = "0.7.3", features = [ "eth", ], default-features = false } +alloy-rpc-types-engine = { version = "0.7.3" } alloy-rlp = "0.3.10" alloy-eips = { version = "0.7.3", default-features = false } alloy-genesis = { version = "0.7.3", default-features = false } +alloy-rpc-types-debug = "0.8.0" +alloy-signer = { version = "0.7.3", default-features = false } +alloy-signer-local = { version = "0.7.3", default-features = false } # revm revm = { version = "18.0.0", features = ["std"], default-features = false } -revm-inspectors = "0.12.0" -revm-primitives = { version = "14.0.0", features = [ - "std", -], default-features = false } -revm-interpreter = "10" -revm-precompile = "11" - +revm-primitives = { version = "14.0.0", default-features = false } # 3rd party -jsonrpsee = { version = "0.24", features = ["server", "macros"] } +jsonrpsee = { version = "0.24", features = ["server", "client", "macros"] } tokio = { version = "1", features = ["full"] } futures = "0.3" chrono = "0.4" thiserror = "1" -strum = "0.26" -strum_macros = "0.26" +strum = { version = "0.26", features = ["derive"] } bytemuck = "1" semaphore = { git = "https://github.com/worldcoin/semaphore-rs", rev = "d0d1f899add7116ccc1228f5e5e5ee2e2e233768", features = [ "depth_30", @@ -94,34 +132,14 @@ tracing = "0.1" parking_lot = "0.12" derive_more = "1" dotenvy = "0.15.7" -tikv-jemallocator = { version = "0.6.0", optional = true } +tikv-jemallocator = { version = "0.6.0" } bytes = "1.7.2" hex = "0.4.3" tempfile = "3" - -[dev-dependencies] criterion = { version = "0.5", features = ["async_tokio"] } serial_test = "3" test-case = "3" ethers-core = { git = "https://github.com/gakonst/ethers-rs", default-features = false } -alloy-primitives = "0.8" serde_json = "1" rand = "0.8" -reth-e2e-test-utils = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } -reth-consensus = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } -reth-optimism-consensus = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } -reth-node-core = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } -reth-tracing = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } -alloy-signer = { version = "0.7.3", default-features = false } -alloy-signer-local = { version = "0.7.3", default-features = false } - -[features] -jemalloc = ["tikv-jemallocator"] - -[[bin]] -name = "world-chain-builder" -path = "bin/world-chain-builder.rs" - -[[bench]] -name = "validate_transaction" -harness = false +reqwest = { version = "0.12", default-features = false } diff --git a/world-chain-builder/crates/toolkit/Cargo.toml b/world-chain-builder/crates/toolkit/Cargo.toml index 232ebc8b..856938b3 100644 --- a/world-chain-builder/crates/toolkit/Cargo.toml +++ b/world-chain-builder/crates/toolkit/Cargo.toml @@ -4,26 +4,24 @@ version = "0.1.0" edition = "2021" [dependencies] -semaphore = { git = "https://github.com/worldcoin/semaphore-rs", rev = "d0d1f899add7116ccc1228f5e5e5ee2e2e233768", features = [ - "depth_30", -] } -world-chain-builder = { path = "../.." } +semaphore = { workspace = true, features = ["depth_30"] } +world-chain-builder-pbh = { workspace = true } # Alloy -alloy-consensus = "0.3" -alloy-network = "0.3" -alloy-primitives = "0.8" -alloy-rlp = "0.3" +alloy-consensus = { workspace = true } +alloy-network = { workspace = true } +alloy-primitives = { workspace = true } +alloy-rlp = { workspace = true } # 3rd party -bytes = "1.7.2" -clap = { version = "4", features = ["derive", "env"] } -eyre = { version = "0.6", package = "color-eyre" } -hex = "0.4.3" -reqwest = "0.12" -serde = { version = "1", features = ["derive"] } -serde_json = "1.0" -tokio = { version = "1", features = ["full"] } -dotenvy = "0.15.7" -chrono = "0.4" -rand = "0.8.5" +bytes = { workspace = true } +clap = { workspace = true, features = ["derive", "env"] } +eyre = { workspace = true } +hex = { workspace = true } +reqwest = { workspace = true } +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true } +tokio = { workspace = true, features = ["full"] } +dotenvy = { workspace = true } +chrono = { workspace = true } +rand = { workspace = true } diff --git a/world-chain-builder/crates/toolkit/src/cli.rs b/world-chain-builder/crates/toolkit/src/cli.rs index 49263df2..61599c35 100644 --- a/world-chain-builder/crates/toolkit/src/cli.rs +++ b/world-chain-builder/crates/toolkit/src/cli.rs @@ -3,7 +3,7 @@ use chrono::NaiveDate; use clap::Parser; use identity_source::IdentitySource; use inclusion_proof_source::InclusionProofSource; -use world_chain_builder::pbh::external_nullifier::Prefix; +use world_chain_builder_pbh::external_nullifier::Prefix; pub mod identity_source; pub mod inclusion_proof_source; diff --git a/world-chain-builder/crates/toolkit/src/main.rs b/world-chain-builder/crates/toolkit/src/main.rs index eb53990d..fc888401 100644 --- a/world-chain-builder/crates/toolkit/src/main.rs +++ b/world-chain-builder/crates/toolkit/src/main.rs @@ -7,9 +7,9 @@ use semaphore::identity::Identity; use semaphore::poseidon_tree::Proof; use semaphore::{hash_to_field, Field}; use serde::{Deserialize, Serialize}; -use world_chain_builder::pbh::date_marker::DateMarker; -use world_chain_builder::pbh::external_nullifier::ExternalNullifier; -use world_chain_builder::pbh::payload::PbhPayload; +use world_chain_builder_pbh::date_marker::DateMarker; +use world_chain_builder_pbh::external_nullifier::ExternalNullifier; +use world_chain_builder_pbh::payload::PbhPayload; mod cli; @@ -69,7 +69,7 @@ async fn main() -> eyre::Result<()> { external_nullifier: external_nullifier.to_string(), nullifier_hash, root: inclusion_proof.root, - proof: world_chain_builder::pbh::payload::Proof(semaphore_proof), + proof: world_chain_builder_pbh::payload::Proof(semaphore_proof), }; let encoded = alloy_rlp::encode(proof); diff --git a/world-chain-builder/crates/world/bin/Cargo.toml b/world-chain-builder/crates/world/bin/Cargo.toml new file mode 100644 index 00000000..846ccbaf --- /dev/null +++ b/world-chain-builder/crates/world/bin/Cargo.toml @@ -0,0 +1,93 @@ +[package] +name = "world-chain-builder" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[lints] +workspace = true + +[dependencies] +# world-chain +world-chain-builder-node.workspace = true +world-chain-builder-rpc.workspace = true + +# reth +reth-db.workspace = true + +reth-primitives.workspace = true +reth-payload-builder.workspace = true +reth-payload-util.workspace = true +reth-payload-validator.workspace = true +reth-basic-payload-builder.workspace = true +reth-consensus.workspace = true +reth-cli-util.workspace = true +reth-node-builder.workspace = true +reth-tracing.workspace = true +reth-provider.workspace = true +reth-transaction-pool.workspace = true + +reth-evm.workspace = true +reth-revm = { workspace = true, features = ["std"] } + +reth-trie-db.workspace = true +reth-rpc-server-types.workspace = true +reth-tasks = { workspace = true, optional = true } + +# op-reth +reth-optimism-cli.workspace = true +reth-optimism-payload-builder.workspace = true +reth-optimism-evm.workspace = true +reth-optimism-rpc.workspace = true +reth-optimism-chainspec.workspace = true +reth-optimism-consensus.workspace = true +reth-optimism-forks.workspace = true +reth-optimism-primitives = { workspace = true, features = ["serde"] } + +# revm with required optimism features +revm = { workspace = true, features = ["secp256k1", "blst", "c-kzg"] } + +# ethereum +alloy-eips.workspace = true +alloy-primitives.workspace = true +op-alloy-rpc-types-engine.workspace = true +alloy-rpc-types-engine.workspace = true +alloy-consensus.workspace = true + +# misc +dotenvy.workspace = true +clap.workspace = true +serde.workspace = true +eyre.workspace = true +parking_lot.workspace = true + +# rpc +serde_json.workspace = true + +# test-utils dependencies +reth-e2e-test-utils = { workspace = true, optional = true } +alloy-genesis = { workspace = true, optional = true } +tokio = { workspace = true, optional = true } +tikv-jemallocator = { workspace = true, optional = true } + +[dev-dependencies] +reth-optimism-node = { workspace = true, features = ["test-utils"] } +reth-db.workspace = true +reth-node-core.workspace = true +reth-node-builder = { workspace = true, features = ["test-utils"] } +reth-provider = { workspace = true, features = ["test-utils"] } +reth-revm = { workspace = true, features = ["test-utils"] } +reth-tasks.workspace = true + +alloy-primitives.workspace = true +op-alloy-consensus.workspace = true +alloy-signer-local.workspace = true +alloy-network.workspace = true +alloy-consensus.workspace = true +futures.workspace = true + +[features] +jemalloc = ["tikv-jemallocator"] diff --git a/world-chain-builder/bin/world-chain-builder.rs b/world-chain-builder/crates/world/bin/src/main.rs similarity index 87% rename from world-chain-builder/bin/world-chain-builder.rs rename to world-chain-builder/crates/world/bin/src/main.rs index 7da708a1..0bb0e026 100644 --- a/world-chain-builder/bin/world-chain-builder.rs +++ b/world-chain-builder/crates/world/bin/src/main.rs @@ -1,10 +1,9 @@ use clap::Parser; use reth_optimism_cli::chainspec::OpChainSpecParser; use reth_optimism_cli::Cli; -use world_chain_builder::node::args::ExtArgs; -use world_chain_builder::node::builder::WorldChainBuilder; -use world_chain_builder::rpc::bundle::EthTransactionsExtServer; -use world_chain_builder::rpc::bundle::WorldChainEthApiExt; +use world_chain_builder_node::args::ExtArgs; +use world_chain_builder_node::node::WorldChainBuilder; +use world_chain_builder_rpc::bundle::{EthTransactionsExtServer, WorldChainEthApiExt}; #[cfg(all(feature = "jemalloc", unix))] #[global_allocator] diff --git a/world-chain-builder/crates/world/db/Cargo.toml b/world-chain-builder/crates/world/db/Cargo.toml new file mode 100644 index 00000000..233e5136 --- /dev/null +++ b/world-chain-builder/crates/world/db/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "world-chain-builder-db" +version.workspace = true +edition.workspace = true + +[dependencies] +reth-db = { workspace = true } +reth-db-api = { workspace = true } +reth-primitives = { workspace = true, features = ["optimism"] } +revm-primitives.workspace = true + +semaphore = { workspace = true } +serde = { workspace = true } +tracing = { workspace = true } +bytes = { workspace = true } +eyre = { workspace = true } diff --git a/world-chain-builder/src/pbh/db.rs b/world-chain-builder/crates/world/db/src/lib.rs similarity index 100% rename from world-chain-builder/src/pbh/db.rs rename to world-chain-builder/crates/world/db/src/lib.rs diff --git a/world-chain-builder/crates/world/node/Cargo.toml b/world-chain-builder/crates/world/node/Cargo.toml new file mode 100644 index 00000000..2be05614 --- /dev/null +++ b/world-chain-builder/crates/world/node/Cargo.toml @@ -0,0 +1,50 @@ +[package] +name = "world-chain-builder-node" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[lints] +workspace = true + +[dependencies] +world-chain-builder-db.workspace = true +world-chain-builder-payload.workspace = true +world-chain-builder-pool.workspace = true + +reth.workspace = true +reth-chain-state.workspace = true +reth-db.workspace = true +reth-optimism-chainspec.workspace = true +reth-optimism-node.workspace = true +reth-optimism-primitives.workspace = true +reth-basic-payload-builder.workspace = true +reth-optimism-payload-builder.workspace = true +reth-primitives.workspace = true +reth-primitives-traits.workspace = true +reth-provider.workspace = true +reth-prune-types.workspace = true +reth-trie.workspace = true +reth-trie-db.workspace = true + +alloy-eips.workspace = true +alloy-primitives.workspace = true +alloy-rpc-types.workspace = true + +tokio.workspace = true +eyre.workspace = true +futures.workspace = true +clap.workspace = true + +[dev-dependencies] +criterion.workspace = true +semaphore.workspace = true + +world-chain-builder-pool = { workspace = true, features = ["test"] } + +[[bench]] +name = "validate_transaction" +harness = false diff --git a/world-chain-builder/benches/validate_transaction.rs b/world-chain-builder/crates/world/node/benches/validate_transaction.rs similarity index 94% rename from world-chain-builder/benches/validate_transaction.rs rename to world-chain-builder/crates/world/node/benches/validate_transaction.rs index cfa60643..c7a8d9e3 100644 --- a/world-chain-builder/benches/validate_transaction.rs +++ b/world-chain-builder/crates/world/node/benches/validate_transaction.rs @@ -7,13 +7,13 @@ use reth_primitives::{BlockBody, SealedBlock, SealedHeader}; use reth_provider::test_utils::{ExtendedAccount, MockEthProvider}; use semaphore::Field; use tokio::runtime::{Builder, Runtime}; -use world_chain_builder::pool::ordering::WorldChainOrdering; -use world_chain_builder::pool::root::{LATEST_ROOT_SLOT, OP_WORLD_ID}; -use world_chain_builder::pool::tx::WorldChainPooledTransaction; -use world_chain_builder::pool::validator::WorldChainTransactionValidator; -use world_chain_builder::test::{ +use world_chain_builder_pool::ordering::WorldChainOrdering; +use world_chain_builder_pool::root::{LATEST_ROOT_SLOT, OP_WORLD_ID}; +use world_chain_builder_pool::test_utils::{ get_non_pbh_transaction, get_pbh_transaction, world_chain_validator, }; +use world_chain_builder_pool::tx::WorldChainPooledTransaction; +use world_chain_builder_pool::validator::WorldChainTransactionValidator; type PoolType = Pool< WorldChainTransactionValidator, diff --git a/world-chain-builder/src/node/args.rs b/world-chain-builder/crates/world/node/src/args.rs similarity index 100% rename from world-chain-builder/src/node/args.rs rename to world-chain-builder/crates/world/node/src/args.rs diff --git a/world-chain-builder/crates/world/node/src/lib.rs b/world-chain-builder/crates/world/node/src/lib.rs new file mode 100644 index 00000000..d8fb03d6 --- /dev/null +++ b/world-chain-builder/crates/world/node/src/lib.rs @@ -0,0 +1,6 @@ +pub mod args; +pub mod node; + +// TODO: Conditional compilation? +// #[cfg(test)] +pub mod test_utils; diff --git a/world-chain-builder/crates/world/node/src/node.rs b/world-chain-builder/crates/world/node/src/node.rs new file mode 100644 index 00000000..0ac6f793 --- /dev/null +++ b/world-chain-builder/crates/world/node/src/node.rs @@ -0,0 +1,287 @@ +use std::path::Path; +use std::sync::Arc; + +use eyre::eyre::Result; +use reth::api::{ConfigureEvm, TxTy}; +use reth::builder::components::{ + ComponentsBuilder, ConsensusBuilder, ExecutorBuilder, NetworkBuilder, PayloadServiceBuilder, + PoolBuilder, +}; +use reth::builder::{ + BuilderContext, FullNodeTypes, Node, NodeAdapter, NodeComponentsBuilder, NodeTypes, + NodeTypesWithEngine, PayloadBuilderConfig, +}; +use reth::payload::{PayloadBuilderHandle, PayloadBuilderService}; +use reth::transaction_pool::blobstore::DiskFileBlobStore; +use reth::transaction_pool::{ + Pool, PoolTransaction, TransactionPool, TransactionValidationTaskExecutor, +}; +use reth_basic_payload_builder::{BasicPayloadJobGenerator, BasicPayloadJobGeneratorConfig}; +use reth_db::DatabaseEnv; +use reth_optimism_chainspec::OpChainSpec; +use reth_optimism_node::args::RollupArgs; +use reth_optimism_node::node::{ + OpAddOns, OpConsensusBuilder, OpExecutorBuilder, OpNetworkBuilder, OpPayloadBuilder, OpStorage, +}; +use reth_optimism_node::{OpEngineTypes, OpEvmConfig}; +use reth_optimism_payload_builder::builder::OpPayloadTransactions; +use reth_optimism_payload_builder::config::OpDAConfig; +use reth_optimism_primitives::OpPrimitives; +use reth_primitives::{Header, NodePrimitives, TransactionSigned}; +use reth_provider::CanonStateSubscriptions; +use reth_trie_db::MerklePatriciaTrie; +use world_chain_builder_db::load_world_chain_db; +use world_chain_builder_pool::builder::WorldChainPoolBuilder; +use world_chain_builder_pool::ordering::WorldChainOrdering; +use world_chain_builder_pool::tx::WorldChainPooledTransaction; +use world_chain_builder_pool::validator::WorldChainTransactionValidator; + +use super::args::{ExtArgs, WorldChainBuilderArgs}; + +#[derive(Debug, Clone)] +pub struct WorldChainBuilder { + /// Additional Optimism args + pub args: ExtArgs, + /// Data availability configuration for the OP builder. + /// + /// Used to throttle the size of the data availability payloads (configured by the batcher via + /// the `miner_` api). + /// + /// By default no throttling is applied. + pub da_config: OpDAConfig, + /// The World Chain database + pub db: Arc, +} + +impl WorldChainBuilder { + pub fn new(args: ExtArgs, data_dir: &Path) -> Result { + let db = load_world_chain_db(data_dir, args.builder_args.clear_nullifiers)?; + Ok(Self { + args, + db, + da_config: OpDAConfig::default(), + }) + } + + /// Configure the data availability configuration for the OP builder. + pub fn with_da_config(mut self, da_config: OpDAConfig) -> Self { + self.da_config = da_config; + self + } + + /// Returns the components for the given [`RollupArgs`]. + pub fn components( + args: ExtArgs, + db: Arc, + ) -> ComponentsBuilder< + Node, + WorldChainPoolBuilder, + WorldChainPayloadBuilder, + OpNetworkBuilder, + OpExecutorBuilder, + OpConsensusBuilder, + > + where + Node: FullNodeTypes< + Types: NodeTypesWithEngine< + Engine = OpEngineTypes, + ChainSpec = OpChainSpec, + Primitives = OpPrimitives, + >, + >, + { + let WorldChainBuilderArgs { + clear_nullifiers, + num_pbh_txs, + verified_blockspace_capacity, + } = args.builder_args; + + let RollupArgs { + disable_txpool_gossip, + compute_pending_block, + discovery_v4, + .. + } = args.rollup_args; + + ComponentsBuilder::default() + .node_types::() + .pool(WorldChainPoolBuilder { + num_pbh_txs, + clear_nullifiers, + db: db.clone(), + }) + .payload(WorldChainPayloadBuilder::new( + compute_pending_block, + verified_blockspace_capacity, + )) + .network(OpNetworkBuilder { + disable_txpool_gossip, + disable_discovery_v4: !discovery_v4, + }) + .executor(OpExecutorBuilder::default()) + .consensus(OpConsensusBuilder::default()) + } +} + +impl Node for WorldChainBuilder +where + N: FullNodeTypes< + Types: NodeTypesWithEngine< + Engine = OpEngineTypes, + ChainSpec = OpChainSpec, + Primitives = OpPrimitives, + Storage = OpStorage, + >, + >, +{ + type ComponentsBuilder = ComponentsBuilder< + N, + WorldChainPoolBuilder, + WorldChainPayloadBuilder, + OpNetworkBuilder, + OpExecutorBuilder, + OpConsensusBuilder, + >; + + type AddOns = + OpAddOns>::Components>>; + + fn components_builder(&self) -> Self::ComponentsBuilder { + let Self { args, db, .. } = self; + Self::components(args.clone(), db.clone()) + } + + fn add_ons(&self) -> Self::AddOns { + let Self { + args, + db, + da_config, + } = self; + Self::AddOns::builder() + .with_sequencer(args.rollup_args.sequencer_http.clone()) + .with_da_config(da_config.clone()) + .build() + } +} + +impl NodeTypes for WorldChainBuilder { + type Storage = OpStorage; + type Primitives = OpPrimitives; + type ChainSpec = OpChainSpec; + type StateCommitment = MerklePatriciaTrie; +} + +impl NodeTypesWithEngine for WorldChainBuilder { + type Engine = OpEngineTypes; +} +/// A basic optimism payload service builder +#[derive(Debug, Default, Clone)] +pub struct WorldChainPayloadBuilder { + // TODO: pub? + pub inner: OpPayloadBuilder, + + // TODO: + pub verified_blockspace_capacity: u8, +} + +impl WorldChainPayloadBuilder { + /// Create a new instance with the given `compute_pending_block` flag. + pub const fn new(compute_pending_block: bool, verified_blockspace_capacity: u8) -> Self { + Self { + inner: OpPayloadBuilder::new(compute_pending_block), + verified_blockspace_capacity, + } + } +} + +impl WorldChainPayloadBuilder +where + Txs: OpPayloadTransactions, +{ + /// Configures the type responsible for yielding the transactions that should be included in the + /// payload. + pub fn with_transactions( + self, + best_transactions: T, + ) -> WorldChainPayloadBuilder { + let WorldChainPayloadBuilder { + inner, + verified_blockspace_capacity, + } = self; + + WorldChainPayloadBuilder { + inner: inner.with_transactions(best_transactions), + verified_blockspace_capacity, + } + } + + /// A helper method to initialize [`PayloadBuilderService`] with the given EVM config. + pub fn spawn( + self, + evm_config: Evm, + ctx: &BuilderContext, + pool: Pool, + ) -> eyre::Result> + where + Node: FullNodeTypes< + Types: NodeTypesWithEngine< + Engine = OpEngineTypes, + ChainSpec = OpChainSpec, + Primitives = OpPrimitives, + >, + >, + Pool: TransactionPool>> + + Unpin + + 'static, + Evm: ConfigureEvm
, + { + let payload_builder = reth_optimism_payload_builder::OpPayloadBuilder::new(evm_config) + .with_transactions(self.inner.best_transactions) + .set_compute_pending_block(self.inner.compute_pending_block); + let conf = ctx.payload_builder_config(); + + let payload_job_config = BasicPayloadJobGeneratorConfig::default() + .interval(conf.interval()) + .deadline(conf.deadline()) + .max_payload_tasks(conf.max_payload_tasks()) + // no extradata for OP + .extradata(Default::default()); + + let payload_generator = BasicPayloadJobGenerator::with_builder( + ctx.provider().clone(), + pool, + ctx.task_executor().clone(), + payload_job_config, + payload_builder, + ); + let (payload_service, payload_builder) = + PayloadBuilderService::new(payload_generator, ctx.provider().canonical_state_stream()); + + ctx.task_executor() + .spawn_critical("payload builder service", Box::pin(payload_service)); + + Ok(payload_builder) + } +} + +impl PayloadServiceBuilder for WorldChainPayloadBuilder +where + N: FullNodeTypes< + Types: NodeTypesWithEngine< + Engine = OpEngineTypes, + ChainSpec = OpChainSpec, + Primitives = OpPrimitives, + >, + >, + Pool: + TransactionPool>> + Unpin + 'static, + Txs: OpPayloadTransactions, +{ + async fn spawn_payload_service( + self, + ctx: &BuilderContext, + pool: Pool, + ) -> eyre::Result> { + self.spawn(OpEvmConfig::new(ctx.chain_spec()), ctx, pool) + } +} diff --git a/world-chain-builder/src/node/test_utils.rs b/world-chain-builder/crates/world/node/src/test_utils.rs similarity index 99% rename from world-chain-builder/src/node/test_utils.rs rename to world-chain-builder/crates/world/node/src/test_utils.rs index bdb6aea6..d8b5a077 100644 --- a/world-chain-builder/src/node/test_utils.rs +++ b/world-chain-builder/crates/world/node/src/test_utils.rs @@ -43,7 +43,7 @@ use std::{ }; use tokio::sync::{broadcast, watch}; -use crate::pool::{ +use world_chain_builder_pool::{ tx::{WorldChainPoolTransaction, WorldChainPooledTransaction}, validator::WorldChainTransactionValidator, }; diff --git a/world-chain-builder/src/test/e2e/assets/genesis.json b/world-chain-builder/crates/world/node/test/assets/genesis.json similarity index 100% rename from world-chain-builder/src/test/e2e/assets/genesis.json rename to world-chain-builder/crates/world/node/test/assets/genesis.json diff --git a/world-chain-builder/src/test/e2e/mod.rs b/world-chain-builder/crates/world/node/test/e2e.rs similarity index 88% rename from world-chain-builder/src/test/e2e/mod.rs rename to world-chain-builder/crates/world/node/test/e2e.rs index ba66c63e..c023cd7b 100644 --- a/world-chain-builder/src/test/e2e/mod.rs +++ b/world-chain-builder/crates/world/node/test/e2e.rs @@ -1,23 +1,8 @@ //! Utilities for running world chain builder end-to-end tests. -use crate::{ - node::{ - args::{ExtArgs, WorldChainBuilderArgs}, - builder::WorldChainBuilder, - }, - pbh::{ - date_marker::DateMarker, - external_nullifier::{ExternalNullifier, Prefix}, - payload::{PbhPayload, Proof}, - }, - pool::{ - ordering::WorldChainOrdering, - root::{LATEST_ROOT_SLOT, OP_WORLD_ID}, - tx::WorldChainPooledTransaction, - validator::WorldChainTransactionValidator, - }, - primitives::WorldChainPooledTransactionsElement, - rpc::bundle::{EthTransactionsExtServer, WorldChainEthApiExt}, -}; +use std::collections::{BTreeMap, HashMap}; +use std::sync::Arc; +use std::time::Duration; + use alloy_eips::eip2718::Decodable2718; use alloy_genesis::{Genesis, GenesisAccount}; use alloy_network::eip2718::Encodable2718; @@ -25,46 +10,44 @@ use alloy_network::{Ethereum, EthereumWallet, TransactionBuilder}; use alloy_rpc_types::{TransactionInput, TransactionRequest, Withdrawals}; use alloy_signer_local::PrivateKeySigner; use chrono::Utc; +use reth::api::{FullNodeTypesAdapter, NodeTypesWithDBAdapter}; +use reth::builder::components::Components; +use reth::builder::{NodeAdapter, NodeBuilder, NodeConfig, NodeHandle}; use reth::payload::{EthPayloadBuilderAttributes, PayloadId}; use reth::tasks::TaskManager; -use reth::transaction_pool::{blobstore::DiskFileBlobStore, TransactionValidationTaskExecutor}; -use reth::{ - api::{FullNodeTypesAdapter, NodeTypesWithDBAdapter}, - builder::components::Components, -}; -use reth::{ - builder::{NodeAdapter, NodeBuilder, NodeConfig, NodeHandle}, - transaction_pool::Pool, -}; -use reth_db::{ - test_utils::{tempdir_path, TempDatabase}, - DatabaseEnv, -}; -use reth_e2e_test_utils::{ - node::NodeTestContext, transaction::TransactionTestContext, wallet::Wallet, -}; +use reth::transaction_pool::blobstore::DiskFileBlobStore; +use reth::transaction_pool::{Pool, TransactionValidationTaskExecutor}; +use reth_db::test_utils::{tempdir_path, TempDatabase}; +use reth_db::DatabaseEnv; +use reth_e2e_test_utils::node::NodeTestContext; +use reth_e2e_test_utils::transaction::TransactionTestContext; +use reth_e2e_test_utils::wallet::Wallet; use reth_evm::execute::BasicBlockExecutorProvider; use reth_node_core::args::RpcServerArgs; use reth_optimism_chainspec::{OpChainSpec, OpChainSpecBuilder}; use reth_optimism_consensus::OpBeaconConsensus; use reth_optimism_evm::{OpEvmConfig, OpExecutionStrategyFactory}; -use reth_optimism_node::{node::OpAddOns, OpPayloadBuilderAttributes}; +use reth_optimism_node::node::OpAddOns; +use reth_optimism_node::OpPayloadBuilderAttributes; use reth_primitives::PooledTransactionsElement; use reth_provider::providers::BlockchainProvider; use revm_primitives::{Address, Bytes, FixedBytes, TxKind, B256, U256}; -use semaphore::{ - hash_to_field, - identity::Identity, - poseidon_tree::LazyPoseidonTree, - protocol::{generate_nullifier_hash, generate_proof}, - Field, -}; +use semaphore::identity::Identity; +use semaphore::poseidon_tree::LazyPoseidonTree; +use semaphore::protocol::{generate_nullifier_hash, generate_proof}; +use semaphore::{hash_to_field, Field}; use serial_test::serial; -use std::{ - collections::{BTreeMap, HashMap}, - sync::Arc, - time::Duration, -}; +use world_chain_builder_node::args::{ExtArgs, WorldChainBuilderArgs}; +use world_chain_builder_node::builder::WorldChainBuilder; +use world_chain_builder_pbh::date_marker::DateMarker; +use world_chain_builder_pbh::external_nullifier::{ExternalNullifier, Prefix}; +use world_chain_builder_pbh::payload::{PbhPayload, Proof}; +use world_chain_builder_pool::ordering::WorldChainOrdering; +use world_chain_builder_pool::root::{LATEST_ROOT_SLOT, OP_WORLD_ID}; +use world_chain_builder_pool::tx::WorldChainPooledTransaction; +use world_chain_builder_pool::validator::WorldChainTransactionValidator; +use world_chain_builder_primitives::WorldChainPooledTransactionsElement; +use world_chain_builder_rpc::bundle::{EthTransactionsExtServer, WorldChainEthApiExt}; pub const DEV_CHAIN_ID: u64 = 8453; diff --git a/world-chain-builder/crates/world/payload/Cargo.toml b/world-chain-builder/crates/world/payload/Cargo.toml new file mode 100644 index 00000000..117fd140 --- /dev/null +++ b/world-chain-builder/crates/world/payload/Cargo.toml @@ -0,0 +1,44 @@ +[package] +name = "world-chain-builder-payload" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[lints] +workspace = true + +[dependencies] +# world-chain +world-chain-builder-pool.workspace = true +world-chain-builder-rpc.workspace = true + +# reth +reth.workspace = true +reth-basic-payload-builder.workspace = true +reth-chain-state.workspace = true +reth-evm.workspace = true +reth-db.workspace = true +reth-optimism-node.workspace = true +reth-optimism-chainspec.workspace = true +reth-optimism-consensus.workspace = true +reth-optimism-payload-builder.workspace = true +reth-provider.workspace = true +reth-primitives.workspace = true +reth-transaction-pool.workspace = true +reth-trie.workspace = true + +# revm +revm.workspace = true +revm-primitives.workspace = true + +# alloy +alloy-consensus.workspace = true +alloy-eips.workspace = true +alloy-rpc-types-debug.workspace = true + +# misc +tracing.workspace = true +jsonrpsee.workspace = true diff --git a/world-chain-builder/crates/world/payload/src/builder.rs b/world-chain-builder/crates/world/payload/src/builder.rs new file mode 100644 index 00000000..3dd1af88 --- /dev/null +++ b/world-chain-builder/crates/world/payload/src/builder.rs @@ -0,0 +1,514 @@ +use alloy_consensus::EMPTY_OMMER_ROOT_HASH; +use alloy_eips::merge::BEACON_NONCE; +use alloy_rpc_types_debug::ExecutionWitness; +use reth::api::PayloadBuilderError; +use reth::builder::components::PayloadServiceBuilder; +use reth::builder::{BuilderContext, FullNodeTypes, NodeTypesWithEngine, PayloadBuilderConfig}; +use reth::chainspec::EthereumHardforks; +use reth::payload::PayloadBuilderAttributes; +use reth::payload::{PayloadBuilderHandle, PayloadBuilderService}; +use reth::revm::database::StateProviderDatabase; +use reth::revm::db::states::bundle_state::BundleRetention; +use reth::revm::witness::ExecutionWitnessRecord; +use reth::revm::DatabaseCommit; +use reth::revm::State; +use reth::transaction_pool::{BestTransactionsAttributes, PoolTransaction, TransactionPool}; +use reth_basic_payload_builder::{ + commit_withdrawals, is_better_payload, BasicPayloadJobGenerator, + BasicPayloadJobGeneratorConfig, BuildArguments, BuildOutcome, BuildOutcomeKind, + MissingPayloadBehaviour, PayloadBuilder, PayloadConfig, +}; +use reth_chain_state::ExecutedBlock; +use reth_db::DatabaseEnv; +use reth_evm::system_calls::SystemCaller; +use reth_evm::{ConfigureEvm, NextBlockEnvAttributes}; +use reth_optimism_chainspec::OpChainSpec; +use reth_optimism_consensus::calculate_receipt_root_no_memo_optimism; +use reth_optimism_node::{OpBuiltPayload, OpPayloadBuilder, OpPayloadBuilderAttributes}; +use reth_optimism_payload_builder::builder::{ + ExecutedPayload, OpBuilder, OpPayloadBuilderCtx, OpPayloadTransactions, +}; +use reth_optimism_payload_builder::config::OpBuilderConfig; +use reth_optimism_payload_builder::OpPayloadAttributes; +use reth_primitives::{proofs, BlockBody, BlockExt, SealedHeader, TransactionSigned}; +use reth_primitives::{Block, Header, Receipt, TxType}; +use reth_provider::{ + BlockReaderIdExt, CanonStateSubscriptions, ChainSpecProvider, ExecutionOutcome, + HashedPostStateProvider, ProviderError, StateProofProvider, StateProviderFactory, + StateRootProvider, +}; +use reth_transaction_pool::{noop::NoopTransactionPool, pool::BestPayloadTransactions}; +use reth_trie::HashedPostState; +use revm::Database; +use revm_primitives::calc_excess_blob_gas; +use revm_primitives::{ + BlockEnv, CfgEnvWithHandlerCfg, EVMError, EnvWithHandlerCfg, InvalidTransaction, + ResultAndState, U256, +}; +use std::sync::Arc; +use tracing::{debug, trace, warn}; + +use world_chain_builder_pool::noop::NoopWorldChainTransactionPool; +use world_chain_builder_pool::tx::WorldChainPoolTransaction; +use world_chain_builder_rpc::bundle::validate_conditional_options; + +/// World Chain payload builder +#[derive(Debug)] +pub struct WorldChainPayloadBuilder { + pub inner: OpPayloadBuilder, + pub verified_blockspace_capacity: u8, +} + +impl WorldChainPayloadBuilder +where + EvmConfig: ConfigureEvm
, +{ + pub fn new(evm_config: EvmConfig, verified_blockspace_capacity: u8) -> Self { + Self::with_builder_config(evm_config, Default::default(), verified_blockspace_capacity) + } + + pub const fn with_builder_config( + evm_config: EvmConfig, + builder_config: OpBuilderConfig, + verified_blockspace_capacity: u8, + ) -> Self { + let inner = OpPayloadBuilder::with_builder_config(evm_config, builder_config); + + Self { + inner, + verified_blockspace_capacity, + } + } +} + +impl WorldChainPayloadBuilder { + /// Sets the rollup's compute pending block configuration option. + pub const fn set_compute_pending_block(mut self, compute_pending_block: bool) -> Self { + self.inner.compute_pending_block = compute_pending_block; + self + } + + pub fn with_transactions( + self, + best_transactions: T, + ) -> WorldChainPayloadBuilder { + let Self { + inner, + verified_blockspace_capacity, + } = self; + + let OpPayloadBuilder { + compute_pending_block, + evm_config, + config, + .. + } = inner; + + WorldChainPayloadBuilder { + inner: OpPayloadBuilder { + compute_pending_block, + evm_config, + best_transactions, + config, + }, + verified_blockspace_capacity, + } + } + + /// Enables the rollup's compute pending block configuration option. + pub const fn compute_pending_block(self) -> Self { + self.set_compute_pending_block(true) + } + + /// Returns the rollup's compute pending block configuration option. + pub const fn is_compute_pending_block(&self) -> bool { + self.inner.compute_pending_block + } +} + +impl WorldChainPayloadBuilder +where + EvmConfig: ConfigureEvm
, + Txs: OpPayloadTransactions, +{ + /// Constructs an Optimism payload from the transactions sent via the + /// Payload attributes by the sequencer. If the `no_tx_pool` argument is passed in + /// the payload attributes, the transaction pool will be ignored and the only transactions + /// included in the payload will be those sent through the attributes. + /// + /// Given build arguments including an Optimism client, transaction pool, + /// and configuration, this function creates a transaction payload. Returns + /// a result indicating success with the payload or an error in case of failure. + fn build_payload( + &self, + args: BuildArguments, + ) -> Result, PayloadBuilderError> + where + Client: StateProviderFactory + ChainSpecProvider, + Pool: TransactionPool>, + { + let (initialized_cfg, initialized_block_env) = self + .cfg_and_block_env(&args.config.attributes, &args.config.parent_header) + .map_err(PayloadBuilderError::other)?; + + let BuildArguments { + client, + pool, + mut cached_reads, + config, + cancel, + best_payload, + } = args; + + let ctx = OpPayloadBuilderCtx { + evm_config: self.inner.evm_config.clone(), + chain_spec: client.chain_spec(), + config, + initialized_cfg, + initialized_block_env, + cancel, + best_payload, + }; + + let builder = WorldChainBuilder { + pool, + best: self.inner.best_transactions.clone(), + }; + + let state_provider = client.state_by_block_hash(ctx.parent().hash())?; + let state = StateProviderDatabase::new(state_provider); + + if ctx.attributes().no_tx_pool { + let db = State::builder() + .with_database(state) + .with_bundle_update() + .build(); + builder.build(db, ctx) + } else { + // sequencer mode we can reuse cachedreads from previous runs + let db = State::builder() + .with_database(cached_reads.as_db_mut(state)) + .with_bundle_update() + .build(); + builder.build(db, ctx) + } + .map(|out| out.with_cached_reads(cached_reads)) + } +} + +impl WorldChainPayloadBuilder +where + EvmConfig: ConfigureEvm
, +{ + /// Returns the configured [`CfgEnvWithHandlerCfg`] and [`BlockEnv`] for the targeted payload + /// (that has the `parent` as its parent). + pub fn cfg_and_block_env( + &self, + attributes: &OpPayloadBuilderAttributes, + parent: &Header, + ) -> Result<(CfgEnvWithHandlerCfg, BlockEnv), EvmConfig::Error> { + let next_attributes = NextBlockEnvAttributes { + timestamp: attributes.timestamp(), + suggested_fee_recipient: attributes.suggested_fee_recipient(), + prev_randao: attributes.prev_randao(), + // gas_limit: attributes.gas_limit.unwrap_or(parent.gas_limit), + }; + self.inner + .evm_config + .next_cfg_and_block_env(parent, next_attributes) + } + + /// Computes the witness for the payload. + pub fn payload_witness( + &self, + client: &Client, + parent: SealedHeader, + attributes: OpPayloadAttributes, + ) -> Result + where + Client: StateProviderFactory + ChainSpecProvider, + { + let attributes = OpPayloadBuilderAttributes::try_new(parent.hash(), attributes, 3) + .map_err(PayloadBuilderError::other)?; + + let (initialized_cfg, initialized_block_env) = self + .cfg_and_block_env(&attributes, &parent) + .map_err(PayloadBuilderError::other)?; + + let config = PayloadConfig { + parent_header: Arc::new(parent), + attributes, + extra_data: Default::default(), + }; + + let ctx = OpPayloadBuilderCtx { + evm_config: self.inner.evm_config.clone(), + chain_spec: client.chain_spec(), + config, + initialized_cfg, + initialized_block_env, + cancel: Default::default(), + best_payload: Default::default(), + }; + + let state_provider = client.state_by_block_hash(ctx.parent().hash())?; + let state = StateProviderDatabase::new(state_provider); + let mut state = State::builder() + .with_database(state) + .with_bundle_update() + .build(); + + let builder = WorldChainBuilder { + pool: NoopTransactionPool::default(), + best: (), + }; + builder.witness(&mut state, &ctx) + } +} + +impl WorldChainBuilder +where + Pool: TransactionPool>, + Txs: OpPayloadTransactions, +{ + /// Executes the payload and returns the outcome. + pub fn execute( + self, + state: &mut State, + ctx: &OpPayloadBuilderCtx, + ) -> Result, PayloadBuilderError> + where + EvmConfig: ConfigureEvm
, + DB: Database, + { + let Self { pool, best } = self; + debug!(target: "payload_builder", id=%ctx.payload_id(), parent_header = ?ctx.parent().hash(), parent_number = ctx.parent().number, "building new payload"); + + // 1. apply eip-4788 pre block contract call + ctx.apply_pre_beacon_root_contract_call(state)?; + + // 2. ensure create2deployer is force deployed + ctx.ensure_create2_deployer(state)?; + + // 3. execute sequencer transactions + let mut info = ctx.execute_sequencer_transactions(state)?; + + // 4. if mem pool transactions are requested we execute them + if !ctx.attributes().no_tx_pool { + //TODO: build pbh payload + + let best_txs = best.best_transactions(pool, ctx.best_transaction_attributes()); + if ctx + .execute_best_transactions::<_, Pool>(&mut info, state, best_txs)? + .is_some() + { + return Ok(BuildOutcomeKind::Cancelled); + } + + // check if the new payload is even more valuable + if !ctx.is_better_payload(info.total_fees) { + // can skip building the block + return Ok(BuildOutcomeKind::Aborted { + fees: info.total_fees, + }); + } + } + + let withdrawals_root = ctx.commit_withdrawals(state)?; + + // merge all transitions into bundle state, this would apply the withdrawal balance changes + // and 4788 contract call + state.merge_transitions(BundleRetention::Reverts); + + Ok(BuildOutcomeKind::Better { + payload: ExecutedPayload { + info, + withdrawals_root, + }, + }) + } + + // TODO: + /// Builds the payload on top of the state. + pub fn build( + self, + mut state: State, + ctx: OpPayloadBuilderCtx, + ) -> Result, PayloadBuilderError> + where + EvmConfig: ConfigureEvm
, + DB: Database + AsRef

, + P: StateRootProvider + HashedPostStateProvider, + { + let ExecutedPayload { + info, + withdrawals_root, + } = match self.execute(&mut state, &ctx)? { + BuildOutcomeKind::Better { payload } | BuildOutcomeKind::Freeze(payload) => payload, + BuildOutcomeKind::Cancelled => return Ok(BuildOutcomeKind::Cancelled), + BuildOutcomeKind::Aborted { fees } => return Ok(BuildOutcomeKind::Aborted { fees }), + }; + + let block_number = ctx.block_number(); + let execution_outcome = ExecutionOutcome::new( + state.take_bundle(), + vec![info.receipts].into(), + block_number, + Vec::new(), + ); + let receipts_root = execution_outcome + .generic_receipts_root_slow(block_number, |receipts| { + calculate_receipt_root_no_memo_optimism( + receipts, + &ctx.chain_spec, + ctx.attributes().timestamp(), + ) + }) + .expect("Number is in range"); + let logs_bloom = execution_outcome + .block_logs_bloom(block_number) + .expect("Number is in range"); + + // // calculate the state root + let state_provider = state.database.as_ref(); + let hashed_state = state_provider.hashed_post_state(execution_outcome.state()); + let (state_root, trie_output) = { + state_provider + .state_root_with_updates(hashed_state.clone()) + .inspect_err(|err| { + warn!(target: "payload_builder", + parent_header=%ctx.parent().hash(), + %err, + "failed to calculate state root for payload" + ); + })? + }; + + // create the block header + let transactions_root = proofs::calculate_transaction_root(&info.executed_transactions); + + // OP doesn't support blobs/EIP-4844. + // https://specs.optimism.io/protocol/exec-engine.html#ecotone-disable-blob-transactions + // Need [Some] or [None] based on hardfork to match block hash. + let (excess_blob_gas, blob_gas_used) = ctx.blob_fields(); + let extra_data = ctx.extra_data()?; + + let header = Header { + parent_hash: ctx.parent().hash(), + ommers_hash: EMPTY_OMMER_ROOT_HASH, + beneficiary: ctx.initialized_block_env.coinbase, + state_root, + transactions_root, + receipts_root, + withdrawals_root, + logs_bloom, + timestamp: ctx.attributes().payload_attributes.timestamp, + mix_hash: ctx.attributes().payload_attributes.prev_randao, + nonce: BEACON_NONCE.into(), + base_fee_per_gas: Some(ctx.base_fee()), + number: ctx.parent().number + 1, + gas_limit: ctx.block_gas_limit(), + difficulty: U256::ZERO, + gas_used: info.cumulative_gas_used, + extra_data, + parent_beacon_block_root: ctx.attributes().payload_attributes.parent_beacon_block_root, + blob_gas_used, + excess_blob_gas, + requests_hash: None, + target_blobs_per_block: None, + }; + + // seal the block + let block = Block { + header, + body: BlockBody { + transactions: info.executed_transactions, + ommers: vec![], + withdrawals: ctx.withdrawals().cloned(), + }, + }; + + let sealed_block = Arc::new(block.seal_slow()); + debug!(target: "payload_builder", id=%ctx.attributes().payload_id(), sealed_block_header = ?sealed_block.header, "sealed built block"); + + // create the executed block data + let executed = ExecutedBlock { + block: sealed_block.clone(), + senders: Arc::new(info.executed_senders), + execution_output: Arc::new(execution_outcome), + hashed_state: Arc::new(hashed_state), + trie: Arc::new(trie_output), + }; + + let no_tx_pool = ctx.attributes().no_tx_pool; + + let payload = OpBuiltPayload::new( + ctx.payload_id(), + sealed_block, + info.total_fees, + ctx.chain_spec.clone(), + ctx.config.attributes, + Some(executed), + ); + + if no_tx_pool { + // if `no_tx_pool` is set only transactions from the payload attributes will be included + // in the payload. In other words, the payload is deterministic and we can + // freeze it once we've successfully built it. + Ok(BuildOutcomeKind::Freeze(payload)) + } else { + Ok(BuildOutcomeKind::Better { payload }) + } + } + + /// Builds the payload and returns its [`ExecutionWitness`] based on the state after execution. + pub fn witness( + self, + state: &mut State, + ctx: &OpPayloadBuilderCtx, + ) -> Result + where + EvmConfig: ConfigureEvm

, + DB: Database + AsRef

, + P: StateProofProvider, + { + let _ = self.execute(state, ctx)?; + let ExecutionWitnessRecord { + hashed_state, + codes, + keys, + } = ExecutionWitnessRecord::from_executed_state(state); + let state = state + .database + .as_ref() + .witness(Default::default(), hashed_state)?; + Ok(ExecutionWitness { + state: state.into_iter().collect(), + codes, + keys, + }) + } +} + +/// The type that builds the payload. +/// +/// Payload building for optimism is composed of several steps. +/// The first steps are mandatory and defined by the protocol. +/// +/// 1. first all System calls are applied. +/// 2. After canyon the forced deployed `create2deployer` must be loaded +/// 3. all sequencer transactions are executed (part of the payload attributes) +/// +/// Depending on whether the node acts as a sequencer and is allowed to include additional +/// transactions (`no_tx_pool == false`): +/// 4. include additional transactions +/// +/// And finally +/// 5. build the block: compute all roots (txs, state) +#[derive(Debug)] +pub struct WorldChainBuilder { + /// The transaction pool + pool: Pool, + /// Yields the best transaction to include if transactions from the mempool are allowed. + best: Txs, +} diff --git a/world-chain-builder/src/payload/mod.rs b/world-chain-builder/crates/world/payload/src/lib.rs similarity index 100% rename from world-chain-builder/src/payload/mod.rs rename to world-chain-builder/crates/world/payload/src/lib.rs diff --git a/world-chain-builder/crates/world/pbh/Cargo.toml b/world-chain-builder/crates/world/pbh/Cargo.toml new file mode 100644 index 00000000..c6df5f4f --- /dev/null +++ b/world-chain-builder/crates/world/pbh/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "world-chain-builder-pbh" +version.workspace = true +edition.workspace = true + +[dependencies] +alloy-rlp.workspace = true + +chrono = { workspace = true } +thiserror = { workspace = true } +semaphore.workspace = true +strum.workspace = true +serde.workspace = true + +[dev-dependencies] +ethers-core.workspace = true +test-case.workspace = true diff --git a/world-chain-builder/src/pbh/date_marker.rs b/world-chain-builder/crates/world/pbh/src/date_marker.rs similarity index 100% rename from world-chain-builder/src/pbh/date_marker.rs rename to world-chain-builder/crates/world/pbh/src/date_marker.rs diff --git a/world-chain-builder/src/pbh/external_nullifier.rs b/world-chain-builder/crates/world/pbh/src/external_nullifier.rs similarity index 96% rename from world-chain-builder/src/pbh/external_nullifier.rs rename to world-chain-builder/crates/world/pbh/src/external_nullifier.rs index 1ee22c0a..b00ab4c8 100644 --- a/world-chain-builder/src/pbh/external_nullifier.rs +++ b/world-chain-builder/crates/world/pbh/src/external_nullifier.rs @@ -1,8 +1,7 @@ -use crate::pbh::date_marker::{DateMarker, DateMarkerParsingError}; +use crate::date_marker::{DateMarker, DateMarkerParsingError}; use semaphore::{hash_to_field, Field}; use std::str::FromStr; -use strum::EnumString; -use strum_macros::Display; +use strum::{Display, EnumString}; use thiserror::Error; #[derive(Display, EnumString, Debug, Clone, Copy, PartialEq, Eq)] diff --git a/world-chain-builder/src/pbh/mod.rs b/world-chain-builder/crates/world/pbh/src/lib.rs similarity index 84% rename from world-chain-builder/src/pbh/mod.rs rename to world-chain-builder/crates/world/pbh/src/lib.rs index 3de7800b..cf3b51ba 100644 --- a/world-chain-builder/src/pbh/mod.rs +++ b/world-chain-builder/crates/world/pbh/src/lib.rs @@ -1,4 +1,3 @@ pub mod date_marker; -pub mod db; pub mod external_nullifier; pub mod payload; diff --git a/world-chain-builder/src/pbh/payload.rs b/world-chain-builder/crates/world/pbh/src/payload.rs similarity index 100% rename from world-chain-builder/src/pbh/payload.rs rename to world-chain-builder/crates/world/pbh/src/payload.rs diff --git a/world-chain-builder/crates/world/pool/Cargo.toml b/world-chain-builder/crates/world/pool/Cargo.toml new file mode 100644 index 00000000..1a84bc25 --- /dev/null +++ b/world-chain-builder/crates/world/pool/Cargo.toml @@ -0,0 +1,53 @@ +[package] +name = "world-chain-builder-pool" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[dependencies] +world-chain-builder-pbh.workspace = true +world-chain-builder-db.workspace = true + +reth.workspace = true +reth-db.workspace = true +reth-optimism-node.workspace = true +reth-primitives.workspace = true +reth-provider.workspace = true +reth-eth-wire-types.workspace = true + +reth-optimism-primitives.workspace = true +reth-optimism-chainspec.workspace = true + +revm-primitives.workspace = true + +alloy-consensus.workspace = true +alloy-primitives.workspace = true +alloy-rpc-types.workspace = true +alloy-eips.workspace = true + +tokio.workspace = true +semaphore.workspace = true +chrono.workspace = true +eyre.workspace = true +thiserror.workspace = true + +tracing.workspace = true +parking_lot.workspace = true + +tempfile = {workspace = true, optional = true} + + +[dev-dependencies] +ethers-core.workspace = true +test-case.workspace = true +tempfile.workspace = true + +[features] +default = [] +test = ["dep:tempfile"] + +[lints] +workspace = true diff --git a/world-chain-builder/src/pool/builder.rs b/world-chain-builder/crates/world/pool/src/builder.rs similarity index 96% rename from world-chain-builder/src/pool/builder.rs rename to world-chain-builder/crates/world/pool/src/builder.rs index dc94a5af..d66ac073 100644 --- a/world-chain-builder/src/pool/builder.rs +++ b/world-chain-builder/crates/world/pool/src/builder.rs @@ -1,7 +1,5 @@ -use super::validator::WorldChainTransactionPool; -use crate::pool::ordering::WorldChainOrdering; -use crate::pool::root::WorldChainRootValidator; -use crate::pool::validator::WorldChainTransactionValidator; +use std::sync::Arc; + use reth::builder::components::PoolBuilder; use reth::builder::{BuilderContext, FullNodeTypes, NodeTypes}; use reth::transaction_pool::blobstore::DiskFileBlobStore; @@ -11,15 +9,18 @@ use reth_optimism_chainspec::OpChainSpec; use reth_optimism_node::txpool::OpTransactionValidator; use reth_optimism_primitives::OpPrimitives; use reth_provider::CanonStateSubscriptions; -use std::sync::Arc; use tracing::{debug, info}; +use super::validator::WorldChainTransactionPool; +use crate::ordering::WorldChainOrdering; +use crate::root::WorldChainRootValidator; +use crate::validator::WorldChainTransactionValidator; + /// A basic World Chain transaction pool. /// /// This contains various settings that can be configured and take precedence over the node's /// config. #[derive(Debug, Clone)] -#[non_exhaustive] pub struct WorldChainPoolBuilder { pub clear_nullifiers: bool, pub num_pbh_txs: u16, diff --git a/world-chain-builder/src/pool/error.rs b/world-chain-builder/crates/world/pool/src/error.rs similarity index 97% rename from world-chain-builder/src/pool/error.rs rename to world-chain-builder/crates/world/pool/src/error.rs index 1468c03c..e2456704 100644 --- a/world-chain-builder/src/pool/error.rs +++ b/world-chain-builder/crates/world/pool/src/error.rs @@ -3,7 +3,7 @@ use reth::transaction_pool::{PoolTransaction, TransactionValidationOutcome}; use reth_db::{DatabaseError, DatabaseWriteOperation}; use reth_provider::ProviderError; -use crate::pbh::external_nullifier::ExternalNullifierParsingError; +use world_chain_builder_pbh::external_nullifier::ExternalNullifierParsingError; #[derive(Debug, thiserror::Error)] pub enum WorldChainTransactionPoolInvalid { diff --git a/world-chain-builder/src/pool/mod.rs b/world-chain-builder/crates/world/pool/src/lib.rs similarity index 70% rename from world-chain-builder/src/pool/mod.rs rename to world-chain-builder/crates/world/pool/src/lib.rs index b130b14f..006c2af0 100644 --- a/world-chain-builder/src/pool/mod.rs +++ b/world-chain-builder/crates/world/pool/src/lib.rs @@ -5,3 +5,6 @@ pub mod ordering; pub mod root; pub mod tx; pub mod validator; + +#[cfg(feature = "test")] +pub mod test_utils; diff --git a/world-chain-builder/src/pool/noop.rs b/world-chain-builder/crates/world/pool/src/noop.rs similarity index 100% rename from world-chain-builder/src/pool/noop.rs rename to world-chain-builder/crates/world/pool/src/noop.rs diff --git a/world-chain-builder/src/pool/ordering.rs b/world-chain-builder/crates/world/pool/src/ordering.rs similarity index 100% rename from world-chain-builder/src/pool/ordering.rs rename to world-chain-builder/crates/world/pool/src/ordering.rs diff --git a/world-chain-builder/src/pool/root.rs b/world-chain-builder/crates/world/pool/src/root.rs similarity index 100% rename from world-chain-builder/src/pool/root.rs rename to world-chain-builder/crates/world/pool/src/root.rs diff --git a/world-chain-builder/src/test/mod.rs b/world-chain-builder/crates/world/pool/src/test_utils.rs similarity index 97% rename from world-chain-builder/src/test/mod.rs rename to world-chain-builder/crates/world/pool/src/test_utils.rs index 53fc0d08..bd68fef3 100644 --- a/world-chain-builder/src/test/mod.rs +++ b/world-chain-builder/crates/world/pool/src/test_utils.rs @@ -1,6 +1,3 @@ -#[cfg(test)] -pub mod e2e; - use alloy_eips::eip2718::Decodable2718; use chrono::Utc; use reth::chainspec::MAINNET; @@ -17,13 +14,13 @@ use semaphore::protocol::{generate_nullifier_hash, generate_proof}; use semaphore::{hash_to_field, Field}; use tempfile::tempdir; -use crate::pbh::date_marker::DateMarker; -use crate::pbh::db::load_world_chain_db; -use crate::pbh::external_nullifier::{ExternalNullifier, Prefix}; -use crate::pbh::payload::{PbhPayload, Proof, TREE_DEPTH}; -use crate::pool::root::WorldChainRootValidator; -use crate::pool::tx::WorldChainPooledTransaction; -use crate::pool::validator::WorldChainTransactionValidator; +use crate::root::WorldChainRootValidator; +use crate::tx::WorldChainPooledTransaction; +use crate::validator::WorldChainTransactionValidator; +use world_chain_builder_db::load_world_chain_db; +use world_chain_builder_pbh::date_marker::DateMarker; +use world_chain_builder_pbh::external_nullifier::{ExternalNullifier, Prefix}; +use world_chain_builder_pbh::payload::{PbhPayload, Proof, TREE_DEPTH}; pub fn get_eth_transaction() -> EthPooledTransaction { let raw = "0x02f914950181ad84b2d05e0085117553845b830f7df88080b9143a6040608081523462000414576200133a803803806200001e8162000419565b9283398101608082820312620004145781516001600160401b03908181116200041457826200004f9185016200043f565b92602092838201519083821162000414576200006d9183016200043f565b8186015190946001600160a01b03821692909183900362000414576060015190805193808511620003145760038054956001938488811c9816801562000409575b89891014620003f3578190601f988981116200039d575b50899089831160011462000336576000926200032a575b505060001982841b1c191690841b1781555b8751918211620003145760049788548481811c9116801562000309575b89821014620002f457878111620002a9575b5087908784116001146200023e5793839491849260009562000232575b50501b92600019911b1c19161785555b6005556007805460ff60a01b19169055600880546001600160a01b0319169190911790553015620001f3575060025469d3c21bcecceda100000092838201809211620001de57506000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9160025530835282815284832084815401905584519384523093a351610e889081620004b28239f35b601190634e487b7160e01b6000525260246000fd5b90606493519262461bcd60e51b845283015260248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152fd5b0151935038806200013a565b9190601f198416928a600052848a6000209460005b8c8983831062000291575050501062000276575b50505050811b0185556200014a565b01519060f884600019921b161c191690553880808062000267565b86860151895590970196948501948893500162000253565b89600052886000208880860160051c8201928b8710620002ea575b0160051c019085905b828110620002dd5750506200011d565b60008155018590620002cd565b92508192620002c4565b60228a634e487b7160e01b6000525260246000fd5b90607f16906200010b565b634e487b7160e01b600052604160045260246000fd5b015190503880620000dc565b90869350601f19831691856000528b6000209260005b8d8282106200038657505084116200036d575b505050811b018155620000ee565b015160001983861b60f8161c191690553880806200035f565b8385015186558a979095019493840193016200034c565b90915083600052896000208980850160051c8201928c8610620003e9575b918891869594930160051c01915b828110620003d9575050620000c5565b60008155859450889101620003c9565b92508192620003bb565b634e487b7160e01b600052602260045260246000fd5b97607f1697620000ae565b600080fd5b6040519190601f01601f191682016001600160401b038111838210176200031457604052565b919080601f84011215620004145782516001600160401b038111620003145760209062000475601f8201601f1916830162000419565b92818452828287010111620004145760005b8181106200049d57508260009394955001015290565b85810183015184820184015282016200048756fe608060408181526004918236101561001657600080fd5b600092833560e01c91826306fdde0314610a1c57508163095ea7b3146109f257816318160ddd146109d35781631b4c84d2146109ac57816323b872dd14610833578163313ce5671461081757816339509351146107c357816370a082311461078c578163715018a6146107685781638124f7ac146107495781638da5cb5b1461072057816395d89b411461061d578163a457c2d714610575578163a9059cbb146104e4578163c9567bf914610120575063dd62ed3e146100d557600080fd5b3461011c578060031936011261011c57806020926100f1610b5a565b6100f9610b75565b6001600160a01b0391821683526001865283832091168252845220549051908152f35b5080fd5b905082600319360112610338576008546001600160a01b039190821633036104975760079283549160ff8360a01c1661045557737a250d5630b4cf539739df2c5dacb4c659f2488d92836bffffffffffffffffffffffff60a01b8092161786553087526020938785528388205430156104065730895260018652848920828a52865280858a205584519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925863092a38554835163c45a015560e01b815290861685828581845afa9182156103dd57849187918b946103e7575b5086516315ab88c960e31b815292839182905afa9081156103dd576044879289928c916103c0575b508b83895196879586946364e329cb60e11b8652308c870152166024850152165af19081156103b6579086918991610389575b50169060065416176006558385541660604730895288865260c4858a20548860085416928751958694859363f305d71960e01b8552308a86015260248501528d60448501528d606485015260848401524260a48401525af1801561037f579084929161034c575b50604485600654169587541691888551978894859363095ea7b360e01b855284015260001960248401525af1908115610343575061030c575b5050805460ff60a01b1916600160a01b17905580f35b81813d831161033c575b6103208183610b8b565b8101031261033857518015150361011c5738806102f6565b8280fd5b503d610316565b513d86823e3d90fd5b6060809293503d8111610378575b6103648183610b8b565b81010312610374578290386102bd565b8580fd5b503d61035a565b83513d89823e3d90fd5b6103a99150863d88116103af575b6103a18183610b8b565b810190610e33565b38610256565b503d610397565b84513d8a823e3d90fd5b6103d79150843d86116103af576103a18183610b8b565b38610223565b85513d8b823e3d90fd5b6103ff919450823d84116103af576103a18183610b8b565b92386101fb565b845162461bcd60e51b81528085018790526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b6020606492519162461bcd60e51b8352820152601760248201527f74726164696e6720697320616c7265616479206f70656e0000000000000000006044820152fd5b608490602084519162461bcd60e51b8352820152602160248201527f4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f6044820152603760f91b6064820152fd5b9050346103385781600319360112610338576104fe610b5a565b9060243593303303610520575b602084610519878633610bc3565b5160018152f35b600594919454808302908382041483151715610562576127109004820391821161054f5750925080602061050b565b634e487b7160e01b815260118552602490fd5b634e487b7160e01b825260118652602482fd5b9050823461061a578260031936011261061a57610590610b5a565b918360243592338152600160205281812060018060a01b03861682526020522054908282106105c9576020856105198585038733610d31565b608490602086519162461bcd60e51b8352820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152fd5b80fd5b83833461011c578160031936011261011c57805191809380549160019083821c92828516948515610716575b6020958686108114610703578589529081156106df5750600114610687575b6106838787610679828c0383610b8b565b5191829182610b11565b0390f35b81529295507f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b8284106106cc57505050826106839461067992820101948680610668565b80548685018801529286019281016106ae565b60ff19168887015250505050151560051b8301019250610679826106838680610668565b634e487b7160e01b845260228352602484fd5b93607f1693610649565b50503461011c578160031936011261011c5760085490516001600160a01b039091168152602090f35b50503461011c578160031936011261011c576020906005549051908152f35b833461061a578060031936011261061a57600880546001600160a01b031916905580f35b50503461011c57602036600319011261011c5760209181906001600160a01b036107b4610b5a565b16815280845220549051908152f35b82843461061a578160031936011261061a576107dd610b5a565b338252600160209081528383206001600160a01b038316845290528282205460243581019290831061054f57602084610519858533610d31565b50503461011c578160031936011261011c576020905160128152f35b83833461011c57606036600319011261011c5761084e610b5a565b610856610b75565b6044359160018060a01b0381169485815260209560018752858220338352875285822054976000198903610893575b505050906105199291610bc3565b85891061096957811561091a5733156108cc5750948481979861051997845260018a528284203385528a52039120558594938780610885565b865162461bcd60e51b8152908101889052602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608490fd5b865162461bcd60e51b81529081018890526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b865162461bcd60e51b8152908101889052601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606490fd5b50503461011c578160031936011261011c5760209060ff60075460a01c1690519015158152f35b50503461011c578160031936011261011c576020906002549051908152f35b50503461011c578060031936011261011c57602090610519610a12610b5a565b6024359033610d31565b92915034610b0d5783600319360112610b0d57600354600181811c9186908281168015610b03575b6020958686108214610af05750848852908115610ace5750600114610a75575b6106838686610679828b0383610b8b565b929550600383527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b828410610abb575050508261068394610679928201019438610a64565b8054868501880152928601928101610a9e565b60ff191687860152505050151560051b83010192506106798261068338610a64565b634e487b7160e01b845260229052602483fd5b93607f1693610a44565b8380fd5b6020808252825181830181905290939260005b828110610b4657505060409293506000838284010152601f8019910116010190565b818101860151848201604001528501610b24565b600435906001600160a01b0382168203610b7057565b600080fd5b602435906001600160a01b0382168203610b7057565b90601f8019910116810190811067ffffffffffffffff821117610bad57604052565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03908116918215610cde5716918215610c8d57600082815280602052604081205491808310610c3957604082827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef958760209652828652038282205586815220818154019055604051908152a3565b60405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608490fd5b6001600160a01b03908116918215610de25716918215610d925760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925918360005260018252604060002085600052825280604060002055604051908152a3565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608490fd5b60405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b90816020910312610b7057516001600160a01b0381168103610b70579056fea2646970667358221220285c200b3978b10818ff576bb83f2dc4a2a7c98dfb6a36ea01170de792aa652764736f6c63430008140033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000d3fd4f95820a9aa848ce716d6c200eaefb9a2e4900000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000003543131000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035431310000000000000000000000000000000000000000000000000000000000c001a04e551c75810ffdfe6caff57da9f5a8732449f42f0f4c57f935b05250a76db3b6a046cd47e6d01914270c1ec0d9ac7fae7dfb240ec9a8b6ec7898c4d6aa174388f2"; diff --git a/world-chain-builder/src/pool/tx.rs b/world-chain-builder/crates/world/pool/src/tx.rs similarity index 99% rename from world-chain-builder/src/pool/tx.rs rename to world-chain-builder/crates/world/pool/src/tx.rs index bcd59d4d..71369096 100644 --- a/world-chain-builder/src/pool/tx.rs +++ b/world-chain-builder/crates/world/pool/src/tx.rs @@ -18,7 +18,7 @@ use reth_primitives::{ }; use revm_primitives::{AccessList, Address, KzgSettings, TxKind, U256}; -use crate::pbh::payload::PbhPayload; +use world_chain_builder_pbh::payload::PbhPayload; pub trait WorldChainPoolTransaction: EthPoolTransaction { fn pbh_payload(&self) -> Option<&PbhPayload>; diff --git a/world-chain-builder/src/pool/validator.rs b/world-chain-builder/crates/world/pool/src/validator.rs similarity index 97% rename from world-chain-builder/src/pool/validator.rs rename to world-chain-builder/crates/world/pool/src/validator.rs index f666f0ca..1b037ed5 100644 --- a/world-chain-builder/src/pool/validator.rs +++ b/world-chain-builder/crates/world/pool/src/validator.rs @@ -13,15 +13,15 @@ use reth_primitives::{SealedBlock, TransactionSigned}; use reth_provider::{BlockReaderIdExt, StateProviderFactory}; use semaphore::hash_to_field; use semaphore::protocol::verify_proof; +use world_chain_builder_db::{EmptyValue, ValidatedPbhTransaction}; +use world_chain_builder_pbh::date_marker::DateMarker; +use world_chain_builder_pbh::external_nullifier::ExternalNullifier; +use world_chain_builder_pbh::payload::{PbhPayload, TREE_DEPTH}; use super::error::{TransactionValidationError, WorldChainTransactionPoolInvalid}; use super::ordering::WorldChainOrdering; use super::root::WorldChainRootValidator; use super::tx::{WorldChainPoolTransaction, WorldChainPooledTransaction}; -use crate::pbh::date_marker::DateMarker; -use crate::pbh::db::{EmptyValue, ValidatedPbhTransaction}; -use crate::pbh::external_nullifier::ExternalNullifier; -use crate::pbh::payload::{PbhPayload, TREE_DEPTH}; /// Type alias for World Chain transaction pool pub type WorldChainTransactionPool = Pool< @@ -234,11 +234,12 @@ pub mod tests { use reth_provider::test_utils::{ExtendedAccount, MockEthProvider}; use semaphore::Field; use test_case::test_case; + use world_chain_builder_pbh::payload::{PbhPayload, Proof}; - use crate::pbh::payload::{PbhPayload, Proof}; - use crate::pool::ordering::WorldChainOrdering; - use crate::pool::root::{LATEST_ROOT_SLOT, OP_WORLD_ID}; - use crate::test::{get_pbh_transaction, world_chain_validator}; + use super::*; + use crate::ordering::WorldChainOrdering; + use crate::root::{LATEST_ROOT_SLOT, OP_WORLD_ID}; + use crate::test_utils::{get_pbh_transaction, world_chain_validator}; #[tokio::test] async fn validate_pbh_transaction() { diff --git a/world-chain-builder/crates/world/primitives/Cargo.toml b/world-chain-builder/crates/world/primitives/Cargo.toml new file mode 100644 index 00000000..ad23e108 --- /dev/null +++ b/world-chain-builder/crates/world/primitives/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "world-chain-builder-primitives" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[lints] +workspace = true + +[dependencies] +world-chain-builder-pbh.workspace = true + +reth.workspace = true +reth-primitives = { workspace = true, features = ["optimism"] } + +revm-primitives.workspace = true + +alloy-eips.workspace = true +alloy-rlp.workspace = true + +tracing.workspace = true +bytes.workspace = true + +[dev-dependencies] +alloy-consensus.workspace = true +alloy-primitives.workspace = true diff --git a/world-chain-builder/crates/world/primitives/src/lib.rs b/world-chain-builder/crates/world/primitives/src/lib.rs new file mode 100644 index 00000000..37f08066 --- /dev/null +++ b/world-chain-builder/crates/world/primitives/src/lib.rs @@ -0,0 +1 @@ +pub mod transaction; diff --git a/world-chain-builder/src/primitives.rs b/world-chain-builder/crates/world/primitives/src/transaction.rs similarity index 99% rename from world-chain-builder/src/primitives.rs rename to world-chain-builder/crates/world/primitives/src/transaction.rs index 73055c8f..656d4fd4 100644 --- a/world-chain-builder/src/primitives.rs +++ b/world-chain-builder/crates/world/primitives/src/transaction.rs @@ -1,4 +1,3 @@ -use crate::pbh::payload::PbhPayload; use alloy_eips::eip2718::Decodable2718; use alloy_eips::eip2718::Encodable2718; use alloy_rlp::{Decodable, Encodable}; @@ -10,6 +9,7 @@ use reth_primitives::{ }; use revm_primitives::Bytes; use tracing::warn; +use world_chain_builder_pbh::payload::PbhPayload; #[derive(Clone, Debug, PartialEq, Eq)] pub struct WorldChainPooledTransactionsElement { diff --git a/world-chain-builder/crates/world/rpc/Cargo.toml b/world-chain-builder/crates/world/rpc/Cargo.toml new file mode 100644 index 00000000..26b8c10e --- /dev/null +++ b/world-chain-builder/crates/world/rpc/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "world-chain-builder-rpc" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[lints] +workspace = true + +[dependencies] +world-chain-builder-pool.workspace = true + +reth.workspace = true + +reth-provider.workspace = true +revm-primitives.workspace = true +alloy-consensus.workspace = true + +alloy-eips.workspace = true +alloy-primitives.workspace = true +alloy-rpc-types.workspace = true + +jsonrpsee.workspace = true diff --git a/world-chain-builder/src/rpc/bundle.rs b/world-chain-builder/crates/world/rpc/src/bundle.rs similarity index 99% rename from world-chain-builder/src/rpc/bundle.rs rename to world-chain-builder/crates/world/rpc/src/bundle.rs index 5e157125..b4e7b8ce 100644 --- a/world-chain-builder/src/rpc/bundle.rs +++ b/world-chain-builder/crates/world/rpc/src/bundle.rs @@ -1,4 +1,3 @@ -use crate::pool::tx::WorldChainPooledTransaction; use alloy_consensus::BlockHeader; use alloy_eips::BlockId; use alloy_primitives::{map::HashMap, StorageKey}; @@ -15,6 +14,7 @@ use reth::{ }; use reth_provider::{BlockReaderIdExt, StateProviderFactory}; use revm_primitives::{map::FbBuildHasher, Address, Bytes, FixedBytes, B256}; +use world_chain_builder_pool::tx::WorldChainPooledTransaction; /// Trait interface for `eth_sendRawTransactionConditional` #[cfg_attr(not(test), rpc(server, namespace = "eth"))] diff --git a/world-chain-builder/src/rpc/mod.rs b/world-chain-builder/crates/world/rpc/src/lib.rs similarity index 100% rename from world-chain-builder/src/rpc/mod.rs rename to world-chain-builder/crates/world/rpc/src/lib.rs diff --git a/world-chain-builder/src/lib.rs b/world-chain-builder/src/lib.rs deleted file mode 100644 index 285a5100..00000000 --- a/world-chain-builder/src/lib.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub mod node; -pub mod payload; -pub mod pbh; -pub mod pool; -pub mod primitives; -pub mod rpc; -pub mod test; diff --git a/world-chain-builder/src/node/builder.rs b/world-chain-builder/src/node/builder.rs deleted file mode 100644 index e40ddfd7..00000000 --- a/world-chain-builder/src/node/builder.rs +++ /dev/null @@ -1,180 +0,0 @@ -use std::{path::Path, sync::Arc}; - -use eyre::eyre::Result; -use reth::builder::components::{ConsensusBuilder, ExecutorBuilder, NetworkBuilder, PoolBuilder}; -use reth::builder::{ - components::ComponentsBuilder, FullNodeTypes, Node, NodeTypes, NodeTypesWithEngine, -}; -use reth::builder::{NodeAdapter, NodeComponentsBuilder}; -use reth::transaction_pool::blobstore::DiskFileBlobStore; -use reth::transaction_pool::{Pool, TransactionValidationTaskExecutor}; -use reth_db::DatabaseEnv; -use reth_optimism_chainspec::OpChainSpec; -use reth_optimism_node::args::RollupArgs; -use reth_optimism_node::node::{ - OpAddOns, OpConsensusBuilder, OpExecutorBuilder, OpNetworkBuilder, OpStorage, -}; -use reth_optimism_node::OpEngineTypes; -use reth_optimism_payload_builder::config::OpDAConfig; -use reth_optimism_primitives::OpPrimitives; -use reth_trie_db::MerklePatriciaTrie; - -use crate::pool::ordering::WorldChainOrdering; -use crate::pool::tx::WorldChainPooledTransaction; -use crate::pool::validator::WorldChainTransactionValidator; -use crate::{ - payload::builder::WorldChainPayloadServiceBuilder, pbh::db::load_world_chain_db, - pool::builder::WorldChainPoolBuilder, -}; - -use super::args::{ExtArgs, WorldChainBuilderArgs}; - -#[derive(Debug, Clone)] -pub struct WorldChainBuilder { - /// Additional Optimism args - pub args: ExtArgs, - /// Data availability configuration for the OP builder. - /// - /// Used to throttle the size of the data availability payloads (configured by the batcher via - /// the `miner_` api). - /// - /// By default no throttling is applied. - pub da_config: OpDAConfig, - /// The World Chain database - pub db: Arc, -} - -impl WorldChainBuilder { - pub fn new(args: ExtArgs, data_dir: &Path) -> Result { - let db = load_world_chain_db(data_dir, args.builder_args.clear_nullifiers)?; - Ok(Self { - args, - db, - da_config: OpDAConfig::default(), - }) - } - - /// Configure the data availability configuration for the OP builder. - pub fn with_da_config(mut self, da_config: OpDAConfig) -> Self { - self.da_config = da_config; - self - } - - /// Returns the components for the given [`RollupArgs`]. - pub fn components( - args: ExtArgs, - db: Arc, - ) -> ComponentsBuilder< - Node, - WorldChainPoolBuilder, - WorldChainPayloadServiceBuilder, - OpNetworkBuilder, - OpExecutorBuilder, - OpConsensusBuilder, - > - where - Node: FullNodeTypes< - Types: NodeTypesWithEngine, - >, - OpNetworkBuilder: NetworkBuilder< - Node, - Pool< - TransactionValidationTaskExecutor< - WorldChainTransactionValidator< - ::Provider, - WorldChainPooledTransaction, - >, - >, - WorldChainOrdering, - DiskFileBlobStore, - >, - >, - OpExecutorBuilder: ExecutorBuilder, - OpConsensusBuilder: ConsensusBuilder, - WorldChainPoolBuilder: PoolBuilder, - { - let WorldChainBuilderArgs { - clear_nullifiers, - num_pbh_txs, - verified_blockspace_capacity, - } = args.builder_args; - - let RollupArgs { - disable_txpool_gossip, - compute_pending_block, - discovery_v4, - .. - } = args.rollup_args; - - ComponentsBuilder::default() - .node_types::() - .pool(WorldChainPoolBuilder { - num_pbh_txs, - clear_nullifiers, - db: db.clone(), - }) - .payload(WorldChainPayloadServiceBuilder::new( - compute_pending_block, - verified_blockspace_capacity, - db.clone(), - )) - .network(OpNetworkBuilder { - disable_txpool_gossip, - disable_discovery_v4: !discovery_v4, - }) - .executor(OpExecutorBuilder::default()) - .consensus(OpConsensusBuilder::default()) - } -} - -impl Node for WorldChainBuilder -where - N: FullNodeTypes< - Types: NodeTypesWithEngine< - Engine = OpEngineTypes, - ChainSpec = OpChainSpec, - Primitives = OpPrimitives, - Storage = OpStorage, - >, - >, -{ - type ComponentsBuilder = ComponentsBuilder< - N, - WorldChainPoolBuilder, - WorldChainPayloadServiceBuilder, - OpNetworkBuilder, - OpExecutorBuilder, - OpConsensusBuilder, - >; - - type AddOns = - OpAddOns>::Components>>; - - fn components_builder(&self) -> Self::ComponentsBuilder { - let Self { args, db, .. } = self; - Self::components(args.clone(), db.clone()) - } - - fn add_ons(&self) -> Self::AddOns { - let Self { - args, - db, - da_config, - } = self; - Self::AddOns::builder() - .with_sequencer(args.rollup_args.sequencer_http.clone()) - .with_da_config(da_config.clone()) - .build() - } -} - -impl NodeTypes for WorldChainBuilder { - type Storage = OpStorage; - type Primitives = OpPrimitives; - type ChainSpec = OpChainSpec; - type StateCommitment = MerklePatriciaTrie; -} - -impl NodeTypesWithEngine for WorldChainBuilder { - type Engine = OpEngineTypes; -} diff --git a/world-chain-builder/src/node/mod.rs b/world-chain-builder/src/node/mod.rs deleted file mode 100644 index 7f751387..00000000 --- a/world-chain-builder/src/node/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod args; -pub mod builder; - -#[cfg(test)] -pub mod test_utils; diff --git a/world-chain-builder/src/payload/builder.rs b/world-chain-builder/src/payload/builder.rs deleted file mode 100644 index d939488b..00000000 --- a/world-chain-builder/src/payload/builder.rs +++ /dev/null @@ -1,1018 +0,0 @@ -use alloy_consensus::EMPTY_OMMER_ROOT_HASH; -use alloy_eips::merge::BEACON_NONCE; -use reth_evm::ConfigureEvm; -use std::sync::Arc; - -use reth::api::PayloadBuilderError; -use reth::builder::components::PayloadServiceBuilder; -use reth::builder::{BuilderContext, FullNodeTypes, NodeTypesWithEngine, PayloadBuilderConfig}; -use reth::chainspec::EthereumHardforks; -use reth::payload::{PayloadBuilderHandle, PayloadBuilderService}; -use reth::revm::database::StateProviderDatabase; -use reth::revm::db::states::bundle_state::BundleRetention; -use reth::revm::DatabaseCommit; -use reth::revm::State; -use reth::transaction_pool::{BestTransactionsAttributes, TransactionPool}; -use reth_basic_payload_builder::{ - commit_withdrawals, is_better_payload, BasicPayloadJobGenerator, - BasicPayloadJobGeneratorConfig, BuildArguments, BuildOutcome, MissingPayloadBehaviour, - PayloadBuilder, PayloadConfig, WithdrawalsOutcome, -}; -use reth_chain_state::ExecutedBlock; -use reth_db::DatabaseEnv; -use reth_evm::system_calls::SystemCaller; -use reth_optimism_chainspec::OpChainSpec; -use reth_optimism_consensus::calculate_receipt_root_no_memo_optimism; -use reth_optimism_evm::OptimismEvmConfig; -use reth_optimism_forks::OptimismHardfork; -use reth_optimism_node::{ - OptimismBuiltPayload, OptimismEngineTypes, OptimismPayloadBuilder, - OptimismPayloadBuilderAttributes, -}; -use reth_optimism_payload_builder::error::OptimismPayloadBuilderError; -use reth_primitives::{proofs, BlockBody}; -use reth_primitives::{Block, Header, Receipt, TxType}; -use reth_provider::{ - BlockReaderIdExt, CanonStateSubscriptions, ChainSpecProvider, ExecutionOutcome, - StateProviderFactory, -}; -use reth_trie::HashedPostState; -use revm_primitives::calc_excess_blob_gas; -use revm_primitives::{ - BlockEnv, CfgEnvWithHandlerCfg, EVMError, EnvWithHandlerCfg, InvalidTransaction, - ResultAndState, U256, -}; -use tracing::{debug, trace, warn}; - -use crate::pool::noop::NoopWorldChainTransactionPool; -use crate::pool::tx::WorldChainPoolTransaction; -use crate::rpc::bundle::validate_conditional_options; - -/// Priority blockspace for humans builder -#[derive(Debug, Clone)] -pub struct WorldChainPayloadBuilder { - inner: OptimismPayloadBuilder, - /// The percentage of the blockspace that should be reserved for verified transactions - verified_blockspace_capacity: u8, -} - -impl WorldChainPayloadBuilder -where - EvmConfig: ConfigureEvm

, -{ - /// `OptimismPayloadBuilder` constructor. - pub const fn new(evm_config: EvmConfig, verified_blockspace_capacity: u8) -> Self { - let inner = OptimismPayloadBuilder::new(evm_config); - - Self { - inner, - verified_blockspace_capacity, - } - } -} - -/// Implementation of the [`PayloadBuilder`] trait for [`WorldChainPayloadBuilder`]. -impl PayloadBuilder for WorldChainPayloadBuilder -where - Client: StateProviderFactory + ChainSpecProvider + BlockReaderIdExt, - Pool: TransactionPool, - EvmConfig: ConfigureEvm
, -{ - type Attributes = OptimismPayloadBuilderAttributes; - type BuiltPayload = OptimismBuiltPayload; - - fn try_build( - &self, - args: BuildArguments, - ) -> Result, PayloadBuilderError> { - let (cfg_env, block_env) = self - .inner - .cfg_and_block_env(&args.config, &args.config.parent_block); - - worldchain_payload( - self.inner.evm_config.clone(), - args, - cfg_env, - block_env, - self.verified_blockspace_capacity, - self.inner.compute_pending_block, - ) - } - - fn on_missing_payload( - &self, - _args: BuildArguments, - ) -> MissingPayloadBehaviour { - MissingPayloadBehaviour::AwaitInProgress - } - - fn build_empty_payload( - &self, - client: &Client, - config: PayloadConfig, - ) -> Result { - let args = BuildArguments { - client, - config, - // we use defaults here because for the empty payload we don't need to execute anything - pool: NoopWorldChainTransactionPool::default(), - cached_reads: Default::default(), - cancel: Default::default(), - best_payload: None, - }; - let (cfg_env, block_env) = self - .inner - .cfg_and_block_env(&args.config, &args.config.parent_block); - - worldchain_payload( - self.inner.evm_config.clone(), - args, - cfg_env, - block_env, - self.verified_blockspace_capacity, - false, - )? - .into_payload() - .ok_or_else(|| PayloadBuilderError::MissingPayload) - } -} - -#[derive(Debug)] -pub struct WorldChainPayloadServiceBuilder { - pub compute_pending_block: bool, - pub verified_blockspace_capacity: u8, - pub pbh_db: Arc, -} - -impl WorldChainPayloadServiceBuilder { - pub const fn new( - compute_pending_block: bool, - verified_blockspace_capacity: u8, - pbh_db: Arc, - ) -> Self { - Self { - compute_pending_block, - verified_blockspace_capacity, - pbh_db, - } - } -} - -impl PayloadServiceBuilder for WorldChainPayloadServiceBuilder -where - Node: FullNodeTypes< - Types: NodeTypesWithEngine, - >, - Pool: TransactionPool + Unpin + 'static, -{ - async fn spawn_payload_service( - self, - ctx: &BuilderContext, - pool: Pool, - ) -> eyre::Result> { - let evm_config = OptimismEvmConfig::new(Arc::new((*ctx.chain_spec()).clone())); - - let payload_builder = - WorldChainPayloadBuilder::new(evm_config, self.verified_blockspace_capacity); - - let conf = ctx.payload_builder_config(); - - let payload_job_config = BasicPayloadJobGeneratorConfig::default() - .interval(conf.interval()) - .deadline(conf.deadline()) - .max_payload_tasks(conf.max_payload_tasks()) - // no extradata for OP - .extradata(Default::default()); - - let payload_generator = BasicPayloadJobGenerator::with_builder( - ctx.provider().clone(), - pool, - ctx.task_executor().clone(), - payload_job_config, - payload_builder, - ); - let (payload_service, payload_builder) = - PayloadBuilderService::new(payload_generator, ctx.provider().canonical_state_stream()); - - ctx.task_executor() - .spawn_critical("payload builder service", Box::pin(payload_service)); - - Ok(payload_builder) - } -} - -/// Constructs an Ethereum transaction payload from the transactions sent through the -/// Payload attributes by the sequencer. If the `no_tx_pool` argument is passed in -/// the payload attributes, the transaction pool will be ignored and the only transactions -/// included in the payload will be those sent through the attributes. -/// -/// Given build arguments including an Ethereum client, transaction pool, -/// and configuration, this function creates a transaction payload. Returns -/// a result indicating success with the payload or an error in case of failure. -#[inline] -pub(crate) fn worldchain_payload( - evm_config: EvmConfig, - args: BuildArguments, - initialized_cfg: CfgEnvWithHandlerCfg, - initialized_block_env: BlockEnv, - verified_blockspace_capacity: u8, - _compute_pending_block: bool, -) -> Result, PayloadBuilderError> -where - EvmConfig: ConfigureEvm
, - Client: StateProviderFactory + ChainSpecProvider + BlockReaderIdExt, - Pool: TransactionPool, -{ - let BuildArguments { - client, - pool, - mut cached_reads, - config, - cancel, - best_payload, - } = args; - - let chain_spec = client.chain_spec(); - - let state_provider = client.state_by_block_hash(config.parent_block.hash())?; - let state = StateProviderDatabase::new(state_provider); - let mut db = State::builder() - .with_database_ref(cached_reads.as_db(state)) - .with_bundle_update() - .build(); - let PayloadConfig { - parent_block, - attributes, - extra_data, - } = config; - - debug!(target: "payload_builder", id=%attributes.payload_attributes.payload_id(), parent_hash = ?parent_block.hash(), parent_number = parent_block.number, "building new payload"); - - let mut cumulative_gas_used = 0; - let block_gas_limit: u64 = attributes.gas_limit.unwrap_or_else(|| { - initialized_block_env - .gas_limit - .try_into() - .unwrap_or(chain_spec.max_gas_limit) - }); - let base_fee = initialized_block_env.basefee.to::(); - - let mut executed_txs = Vec::with_capacity(attributes.transactions.len()); - let mut executed_senders = Vec::with_capacity(attributes.transactions.len()); - - let mut best_txs = pool.best_transactions_with_attributes(BestTransactionsAttributes::new( - base_fee, - initialized_block_env - .get_blob_gasprice() - .map(|gasprice| gasprice as u64), - )); - - let mut total_fees = U256::ZERO; - - let block_number = initialized_block_env.number.to::(); - - let is_regolith = chain_spec.is_fork_active_at_timestamp( - OptimismHardfork::Regolith, - attributes.payload_attributes.timestamp, - ); - - // apply eip-4788 pre block contract call - SystemCaller::new(evm_config.clone(), chain_spec.clone()) - .pre_block_beacon_root_contract_call( - &mut db, - &initialized_cfg, - &initialized_block_env, - attributes.payload_attributes.parent_beacon_block_root, - ) - .map_err(|err| { - warn!(target: "payload_builder", - parent_hash=%parent_block.hash(), - %err, - "failed to apply beacon root contract call for empty payload" - ); - PayloadBuilderError::Internal(err.into()) - })?; - - // Ensure that the create2deployer is force-deployed at the canyon transition. Optimism - // blocks will always have at least a single transaction in them (the L1 info transaction), - // so we can safely assume that this will always be triggered upon the transition and that - // the above check for empty blocks will never be hit on OP chains. - reth_optimism_evm::ensure_create2_deployer( - chain_spec.clone(), - attributes.payload_attributes.timestamp, - &mut db, - ) - .map_err(|err| { - warn!(target: "payload_builder", %err, "missing create2 deployer, skipping block."); - PayloadBuilderError::other(OptimismPayloadBuilderError::ForceCreate2DeployerFail) - })?; - - let mut receipts = Vec::with_capacity(attributes.transactions.len()); - for sequencer_tx in &attributes.transactions { - // Check if the job was cancelled, if so we can exit early. - if cancel.is_cancelled() { - return Ok(BuildOutcome::Cancelled); - } - - // A sequencer's block should never contain blob transactions. - if sequencer_tx.value().is_eip4844() { - return Err(PayloadBuilderError::other( - OptimismPayloadBuilderError::BlobTransactionRejected, - )); - } - - // Convert the transaction to a [TransactionSignedEcRecovered]. This is - // purely for the purposes of utilizing the `evm_config.tx_env`` function. - // Deposit transactions do not have signatures, so if the tx is a deposit, this - // will just pull in its `from` address. - let sequencer_tx = sequencer_tx - .value() - .clone() - .try_into_ecrecovered() - .map_err(|_| { - PayloadBuilderError::other(OptimismPayloadBuilderError::TransactionEcRecoverFailed) - })?; - - // Cache the depositor account prior to the state transition for the deposit nonce. - // - // Note that this *only* needs to be done post-regolith hardfork, as deposit nonces - // were not introduced in Bedrock. In addition, regular transactions don't have deposit - // nonces, so we don't need to touch the DB for those. - let depositor = (is_regolith && sequencer_tx.is_deposit()) - .then(|| { - db.load_cache_account(sequencer_tx.signer()) - .map(|acc| acc.account_info().unwrap_or_default()) - }) - .transpose() - .map_err(|_| { - PayloadBuilderError::other(OptimismPayloadBuilderError::AccountLoadFailed( - sequencer_tx.signer(), - )) - })?; - - let env = EnvWithHandlerCfg::new_with_cfg_env( - initialized_cfg.clone(), - initialized_block_env.clone(), - evm_config.tx_env(&sequencer_tx.as_signed(), sequencer_tx.signer()), - ); - - let mut evm = evm_config.evm_with_env(&mut db, env); - - let ResultAndState { result, state } = match evm.transact() { - Ok(res) => res, - Err(err) => { - match err { - EVMError::Transaction(err) => { - trace!(target: "payload_builder", %err, ?sequencer_tx, "Error in sequencer transaction, skipping."); - continue; - } - err => { - // this is an error that we should treat as fatal for this attempt - return Err(PayloadBuilderError::EvmExecutionError(err)); - } - } - } - }; - - // to release the db reference drop evm. - drop(evm); - // commit changes - db.commit(state); - - let gas_used = result.gas_used(); - - // add gas used by the transaction to cumulative gas used, before creating the receipt - cumulative_gas_used += gas_used; - - // Push transaction changeset and calculate header bloom filter for receipt. - receipts.push(Some(Receipt { - tx_type: sequencer_tx.tx_type(), - success: result.is_success(), - cumulative_gas_used, - logs: result.into_logs().into_iter().map(Into::into).collect(), - deposit_nonce: depositor.map(|account| account.nonce), - // The deposit receipt version was introduced in Canyon to indicate an update to how - // receipt hashes should be computed when set. The state transition process - // ensures this is only set for post-Canyon deposit transactions. - deposit_receipt_version: chain_spec - .is_fork_active_at_timestamp( - OptimismHardfork::Canyon, - attributes.payload_attributes.timestamp, - ) - .then_some(1), - })); - - // append sender and transaction to the respective lists - executed_senders.push(sequencer_tx.signer()); - executed_txs.push(sequencer_tx.into_signed()); - } - - if !attributes.no_tx_pool { - let mut invalid_txs = vec![]; - let verified_gas_limit = (verified_blockspace_capacity as u64 * block_gas_limit) / 100; - while let Some(pool_tx) = best_txs.next() { - if let Some(conditional_options) = pool_tx.transaction.conditional_options() { - if let Err(_) = validate_conditional_options(conditional_options, &client) { - best_txs.mark_invalid(&pool_tx); - invalid_txs.push(pool_tx.hash().clone()); - continue; - } - } - - // If the transaction is verified, check if it can be added within the verified gas limit - if pool_tx.transaction.pbh_payload().is_some() - && cumulative_gas_used + pool_tx.gas_limit() > verified_gas_limit - { - best_txs.mark_invalid(&pool_tx); - continue; - } - - // ensure we still have capacity for this transaction - if cumulative_gas_used + pool_tx.gas_limit() > block_gas_limit { - // we can't fit this transaction into the block, so we need to mark it as - // invalid which also removes all dependent transaction from - // the iterator before we can continue - best_txs.mark_invalid(&pool_tx); - continue; - } - - // A sequencer's block should never contain blob or deposit transactions from the pool. - if pool_tx.is_eip4844() || pool_tx.tx_type() == TxType::Deposit as u8 { - best_txs.mark_invalid(&pool_tx); - continue; - } - - // check if the job was cancelled, if so we can exit early - if cancel.is_cancelled() { - return Ok(BuildOutcome::Cancelled); - } - - // convert tx to a signed transaction - let tx = pool_tx.to_recovered_transaction(); - let env = EnvWithHandlerCfg::new_with_cfg_env( - initialized_cfg.clone(), - initialized_block_env.clone(), - evm_config.tx_env(&tx.as_signed(), tx.signer()), - ); - - // Configure the environment for the block. - let mut evm = evm_config.evm_with_env(&mut db, env); - - let ResultAndState { result, state } = match evm.transact() { - Ok(res) => res, - Err(err) => { - match err { - EVMError::Transaction(err) => { - if let InvalidTransaction::NonceTooLow { .. } = err { - // if the nonce is too low, we can skip this transaction - trace!(target: "payload_builder", %err, ?tx, "skipping nonce too low transaction"); - } else { - // if the transaction is invalid, we can skip it and all of its - // descendants - trace!(target: "payload_builder", %err, ?tx, "skipping invalid transaction and its descendants"); - best_txs.mark_invalid(&pool_tx); - } - - continue; - } - err => { - // this is an error that we should treat as fatal for this attempt - return Err(PayloadBuilderError::EvmExecutionError(err)); - } - } - } - }; - - // drop evm so db is released. - drop(evm); - // commit changes - db.commit(state); - - let gas_used = result.gas_used(); - - // add gas used by the transaction to cumulative gas used, before creating the - // receipt - cumulative_gas_used += gas_used; - - // Push transaction changeset and calculate header bloom filter for receipt. - receipts.push(Some(Receipt { - tx_type: tx.tx_type(), - success: result.is_success(), - cumulative_gas_used, - logs: result.into_logs().into_iter().map(Into::into).collect(), - deposit_nonce: None, - deposit_receipt_version: None, - })); - - // update add to total fees - let miner_fee = tx - .effective_tip_per_gas(Some(base_fee)) - .expect("fee is always valid; execution succeeded"); - total_fees += U256::from(miner_fee) * U256::from(gas_used); - - // append sender and transaction to the respective lists - executed_senders.push(tx.signer()); - executed_txs.push(tx.into_signed()); - } - - if !invalid_txs.is_empty() { - pool.remove_transactions(invalid_txs); - } - } - - // check if we have a better block - if !is_better_payload(best_payload.as_ref(), total_fees) { - // can skip building the block - return Ok(BuildOutcome::Aborted { - fees: total_fees, - cached_reads, - }); - } - - let WithdrawalsOutcome { - withdrawals_root, - withdrawals, - } = commit_withdrawals( - &mut db, - &chain_spec, - attributes.payload_attributes.timestamp, - attributes.clone().payload_attributes.withdrawals, - )?; - - // merge all transitions into bundle state, this would apply the withdrawal balance changes - // and 4788 contract call - db.merge_transitions(BundleRetention::Reverts); - - let execution_outcome = ExecutionOutcome::new( - db.take_bundle(), - vec![receipts.clone()].into(), - block_number, - Vec::new(), - ); - let receipts_root = execution_outcome - .generic_receipts_root_slow(block_number, |receipts| { - calculate_receipt_root_no_memo_optimism( - receipts, - &chain_spec, - attributes.payload_attributes.timestamp, - ) - }) - .expect("Number is in range"); - let logs_bloom = execution_outcome - .block_logs_bloom(block_number) - .expect("Number is in range"); - - // calculate the state root - let hashed_state = HashedPostState::from_bundle_state(&execution_outcome.state().state); - let (state_root, trie_output) = { - let state_provider = db.database.0.inner.borrow_mut(); - state_provider - .db - .state_root_with_updates(hashed_state.clone()) - .inspect_err(|err| { - warn!(target: "payload_builder", - parent_hash=%parent_block.hash(), - %err, - "failed to calculate state root for empty payload" - ); - })? - }; - - // create the block header - let transactions_root = proofs::calculate_transaction_root(&executed_txs); - - // initialize empty blob sidecars. There are no blob transactions on L2. - let blob_sidecars = Vec::new(); - let mut excess_blob_gas = None; - let mut blob_gas_used = None; - - // only determine cancun fields when active - if chain_spec.is_cancun_active_at_timestamp(attributes.payload_attributes.timestamp) { - excess_blob_gas = if chain_spec.is_cancun_active_at_timestamp(parent_block.timestamp) { - let parent_excess_blob_gas = parent_block.excess_blob_gas.unwrap_or_default(); - let parent_blob_gas_used = parent_block.blob_gas_used.unwrap_or_default(); - Some(calc_excess_blob_gas( - parent_excess_blob_gas, - parent_blob_gas_used, - )) - } else { - // for the first post-fork block, both parent.blob_gas_used and - // parent.excess_blob_gas are evaluated as 0 - Some(calc_excess_blob_gas(0, 0)) - }; - - blob_gas_used = Some(0); - } - - let header = Header { - parent_hash: parent_block.hash(), - ommers_hash: EMPTY_OMMER_ROOT_HASH, - beneficiary: initialized_block_env.coinbase, - state_root, - transactions_root, - receipts_root, - withdrawals_root, - logs_bloom, - timestamp: attributes.payload_attributes.timestamp, - mix_hash: attributes.payload_attributes.prev_randao, - nonce: BEACON_NONCE.into(), - base_fee_per_gas: Some(base_fee), - number: parent_block.number + 1, - gas_limit: block_gas_limit, - difficulty: U256::ZERO, - gas_used: cumulative_gas_used, - extra_data, - parent_beacon_block_root: attributes.payload_attributes.parent_beacon_block_root, - blob_gas_used, - excess_blob_gas, - requests_hash: None, - }; - - // seal the block - let block = Block { - header, - body: BlockBody { - transactions: executed_txs, - ommers: vec![], - withdrawals, - }, - }; - - let sealed_block = block.seal_slow(); - debug!(target: "payload_builder", ?sealed_block, "sealed built block"); - - // create the executed block data - let executed = ExecutedBlock { - block: Arc::new(sealed_block.clone()), - senders: Arc::new(executed_senders), - execution_output: Arc::new(execution_outcome), - hashed_state: Arc::new(hashed_state), - trie: Arc::new(trie_output), - }; - - let mut payload = OptimismBuiltPayload::new( - attributes.payload_attributes.id, - sealed_block, - total_fees, - chain_spec, - attributes, - Some(executed), - ); - - // extend the payload with the blob sidecars from the executed txs - payload.extend_sidecars(blob_sidecars); - - Ok(BuildOutcome::Better { - payload, - cached_reads, - }) -} - -#[cfg(test)] -mod tests { - use crate::{ - node::test_utils::{WorldChainNoopProvider, WorldChainNoopValidator}, - pool::{ - ordering::WorldChainOrdering, root::WorldChainRootValidator, - tx::WorldChainPooledTransaction, validator::WorldChainTransactionValidator, - }, - test::get_pbh_transaction, - }; - - use super::*; - use crate::pbh::db::load_world_chain_db; - use alloy_consensus::TxLegacy; - use alloy_primitives::Parity; - use alloy_rlp::Encodable; - use op_alloy_consensus::TxDeposit; - use rand::Rng; - use reth::chainspec::ChainSpec; - use reth::payload::{EthPayloadBuilderAttributes, PayloadId}; - use reth::transaction_pool::{ - blobstore::DiskFileBlobStore, validate::EthTransactionValidatorBuilder, - EthPooledTransaction, PoolConfig, PoolTransaction, TransactionOrigin, - }; - use reth_db::test_utils::tempdir_path; - use reth_optimism_chainspec::OpChainSpec; - use reth_optimism_evm::OptimismEvmConfig; - use reth_optimism_node::txpool::OpTransactionValidator; - use reth_primitives::{ - transaction::WithEncoded, SealedBlock, Signature, TransactionSigned, - TransactionSignedEcRecovered, Withdrawals, - }; - use revm_primitives::{ruint::aliases::U256, Address, Bytes, TxKind, B256}; - use std::sync::Arc; - - #[tokio::test] - async fn test_try_build() -> eyre::Result<()> { - let data_dir = tempdir_path(); - let db = load_world_chain_db(data_dir.as_path(), false)?; - - let gas_limit = 30_000_000; - let chain_spec = Arc::new(ChainSpec::default()); - let evm_config = OptimismEvmConfig::new(Arc::new(OpChainSpec { - inner: (*chain_spec).clone(), - })); - let blob_store = DiskFileBlobStore::open(data_dir.as_path(), Default::default())?; - - // Init the transaction pool - let client = WorldChainNoopProvider::default(); - let eth_tx_validator = EthTransactionValidatorBuilder::new(chain_spec.clone()) - .build(client, blob_store.clone()); - let op_tx_validator = - OpTransactionValidator::new(eth_tx_validator).require_l1_data_gas_fee(false); - let root_validator = WorldChainRootValidator::new(client); - - let wc_validator = WorldChainTransactionValidator::new( - op_tx_validator, - root_validator.unwrap(), - db.clone(), - 30, - ); - - let wc_noop_validator = WorldChainNoopValidator::new(wc_validator); - let ordering = WorldChainOrdering::default(); - - let world_chain_tx_pool = reth::transaction_pool::Pool::new( - wc_noop_validator, - ordering, - blob_store, - PoolConfig::default(), - ); - - // Init the payload builder - let verified_blockspace_cap = 50; - let world_chain_payload_builder = - WorldChainPayloadBuilder::new(evm_config, verified_blockspace_cap); - - // Insert transactions into the pool - let unverified_transactions = generate_mock_pooled_transactions(50, 100000, false); - for transaction in unverified_transactions.iter() { - world_chain_tx_pool - .add_transaction(TransactionOrigin::Local, transaction.clone()) - .await?; - } - - // Insert verifiedtransactions into the pool - let verified_transactions = generate_mock_pooled_transactions(50, 100000, true); - for transaction in verified_transactions.iter() { - world_chain_tx_pool - .add_transaction(TransactionOrigin::Local, transaction.clone()) - .await?; - } - - let sequencer_transactions = generate_mock_deposit_transactions(50, 100000); - - let eth_payload_attributes = EthPayloadBuilderAttributes { - id: PayloadId::new([0; 8]), - parent: B256::ZERO, - timestamp: 0, - suggested_fee_recipient: Address::ZERO, - prev_randao: B256::ZERO, - withdrawals: Withdrawals::default(), - parent_beacon_block_root: None, - }; - - let payload_attributes = OptimismPayloadBuilderAttributes { - gas_limit: Some(gas_limit), - transactions: sequencer_transactions.clone(), - payload_attributes: eth_payload_attributes, - no_tx_pool: false, - }; - - let build_args = BuildArguments { - client: WorldChainNoopProvider::default(), - config: PayloadConfig { - parent_block: Arc::new(SealedBlock::default()), - attributes: payload_attributes, - // chain_spec, - extra_data: Bytes::default(), - }, - pool: world_chain_tx_pool, - cached_reads: Default::default(), - cancel: Default::default(), - best_payload: None, - }; - - let built_payload = world_chain_payload_builder - .try_build(build_args)? - .into_payload() - .expect("Could not build payload"); - - // Collect the transaction hashes in the expected order - let mut expected_order = sequencer_transactions - .iter() - .map(|tx| tx.1.hash()) - .collect::>(); - expected_order.extend(verified_transactions.iter().map(|tx| tx.hash())); - expected_order.extend(unverified_transactions.iter().map(|tx| tx.hash())); - - for (tx, expected_hash) in built_payload - .block() - .body - .transactions - .iter() - .zip(expected_order.iter()) - { - assert_eq!(tx.hash, *expected_hash); - } - - Ok(()) - } - - #[tokio::test] - async fn test_try_build_max_verified_blockspace() -> eyre::Result<()> { - let data_dir = tempdir_path(); - let db = load_world_chain_db(data_dir.as_path(), false)?; - - let gas_limit = 30_000_000; - let chain_spec = Arc::new(ChainSpec::default()); - let evm_config = OptimismEvmConfig::new(Arc::new(OpChainSpec { - inner: (*chain_spec).clone(), - })); - let blob_store = DiskFileBlobStore::open(data_dir.as_path(), Default::default())?; - - // Init the transaction pool - let client = WorldChainNoopProvider::default(); - let eth_tx_validator = EthTransactionValidatorBuilder::new(chain_spec.clone()) - .build(client, blob_store.clone()); - let op_tx_validator = - OpTransactionValidator::new(eth_tx_validator).require_l1_data_gas_fee(false); - let root_validator = WorldChainRootValidator::new(client); - let wc_validator = WorldChainTransactionValidator::new( - op_tx_validator, - root_validator.unwrap(), - db.clone(), - 30, - ); - - let wc_noop_validator = WorldChainNoopValidator::new(wc_validator); - let ordering = WorldChainOrdering::default(); - - let world_chain_tx_pool = reth::transaction_pool::Pool::new( - wc_noop_validator, - ordering, - blob_store, - PoolConfig::default(), - ); - - // Init the payload builder - let verified_blockspace_cap = 10; - let world_chain_payload_builder = - WorldChainPayloadBuilder::new(evm_config, verified_blockspace_cap); - - // Insert transactions into the pool - let unverified_transactions = generate_mock_pooled_transactions(50, 100000, false); - for transaction in unverified_transactions.iter() { - world_chain_tx_pool - .add_transaction(TransactionOrigin::Local, transaction.clone()) - .await?; - } - - // Insert verifiedtransactions into the pool - let verified_transactions = generate_mock_pooled_transactions(50, 3000000, true); - for transaction in verified_transactions.iter() { - world_chain_tx_pool - .add_transaction(TransactionOrigin::Local, transaction.clone()) - .await?; - } - - let sequencer_transactions = generate_mock_deposit_transactions(50, 100000); - - let eth_payload_attributes = EthPayloadBuilderAttributes { - id: PayloadId::new([0; 8]), - parent: B256::ZERO, - timestamp: 0, - suggested_fee_recipient: Address::ZERO, - prev_randao: B256::ZERO, - withdrawals: Withdrawals::default(), - parent_beacon_block_root: None, - }; - - let payload_attributes = OptimismPayloadBuilderAttributes { - gas_limit: Some(gas_limit), - transactions: sequencer_transactions.clone(), - payload_attributes: eth_payload_attributes, - no_tx_pool: false, - }; - - let build_args = BuildArguments { - client: WorldChainNoopProvider::default(), - config: PayloadConfig { - parent_block: Arc::new(SealedBlock::default()), - attributes: payload_attributes, - // chain_spec, - extra_data: Bytes::default(), - }, - pool: world_chain_tx_pool, - cached_reads: Default::default(), - cancel: Default::default(), - best_payload: None, - }; - - let built_payload = world_chain_payload_builder - .try_build(build_args)? - .into_payload() - .expect("Could not build payload"); - - // Collect the transaction hashes in the expected order - let mut expected_order = sequencer_transactions - .iter() - .map(|tx| tx.1.hash()) - .collect::>(); - expected_order.push(*verified_transactions.first().unwrap().hash()); - expected_order.extend(unverified_transactions.iter().map(|tx| tx.hash())); - - for (tx, expected_hash) in built_payload - .block() - .body - .transactions - .iter() - .zip(expected_order.iter()) - { - assert_eq!(tx.hash, *expected_hash); - } - - Ok(()) - } - - fn generate_mock_deposit_transactions( - count: usize, - gas_limit: u64, - ) -> Vec> { - let mut rng = rand::thread_rng(); - - (0..count) - .map(|_| { - let tx = reth_primitives::Transaction::Deposit(TxDeposit { - source_hash: B256::random(), - from: Address::random(), - to: TxKind::Call(Address::random()), - mint: Some(100), // Example value for mint - value: U256::from(100), - gas_limit, - is_system_transaction: true, - input: rng.gen::<[u8; 32]>().into(), - }); - - let signature = Signature::new( - U256::from(rng.gen::()), - U256::from(rng.gen::()), - Parity::Parity(false), - ); - - let tx = TransactionSigned::from_transaction_and_signature(tx, signature); - let mut buf = Vec::new(); - tx.encode(&mut buf); - WithEncoded::new(buf.into(), tx) - }) - .collect::>() - } - - fn generate_mock_pooled_transactions( - count: usize, - gas_limit: u64, - pbh: bool, - ) -> Vec { - let mut rng = rand::thread_rng(); - - (0..count) - .map(|i| { - let tx = reth_primitives::Transaction::Legacy(TxLegacy { - gas_price: 10, - gas_limit, - to: TxKind::Call(Address::random()), - value: U256::from(100), - input: rng.gen::<[u8; 32]>().into(), - nonce: rng.gen(), - ..Default::default() - }); - - let signature = Signature::new( - U256::from(rng.gen::()), - U256::from(rng.gen::()), - Parity::Parity(false), - ); - - let tx = TransactionSigned::from_transaction_and_signature(tx, signature); - let tx_recovered = TransactionSignedEcRecovered::from_signed_transaction( - tx.clone(), - Default::default(), - ); - let pooled_tx = EthPooledTransaction::new(tx_recovered.clone(), 200); - - let pbh_payload = if pbh { - Some(get_pbh_transaction(i as u16).pbh_payload.unwrap()) - } else { - None - }; - - WorldChainPooledTransaction { - inner: pooled_tx, - pbh_payload, - conditional_options: None, - } - }) - .collect::>() - } -} From ddee3a8f46b4fa69fe35ca48e6349012303a01f8 Mon Sep 17 00:00:00 2001 From: Dzejkop Date: Fri, 13 Dec 2024 16:46:34 +0100 Subject: [PATCH 21/59] Bring back e2e tests - faiiling --- world-chain-builder/Cargo.lock | 55 +++++++++++++++++++ .../crates/world/node/Cargo.toml | 22 +++++++- .../node/{test => tests}/assets/genesis.json | 0 .../crates/world/node/{test => tests}/e2e.rs | 4 +- 4 files changed, 77 insertions(+), 4 deletions(-) rename world-chain-builder/crates/world/node/{test => tests}/assets/genesis.json (100%) rename world-chain-builder/crates/world/node/{test => tests}/e2e.rs (98%) diff --git a/world-chain-builder/Cargo.lock b/world-chain-builder/Cargo.lock index 0b933a72..ed00a5c4 100644 --- a/world-chain-builder/Cargo.lock +++ b/world-chain-builder/Cargo.lock @@ -10708,6 +10708,15 @@ dependencies = [ "syn 2.0.90", ] +[[package]] +name = "scc" +version = "2.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66b202022bb57c049555430e11fc22fea12909276a80a4c3d368da36ac1d88ed" +dependencies = [ + "sdd", +] + [[package]] name = "schannel" version = "0.1.27" @@ -10765,6 +10774,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152" +[[package]] +name = "sdd" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49c1eeaf4b6a87c7479688c6d52b9f1153cedd3c489300564f932b065c6eab95" + [[package]] name = "seahash" version = "4.1.0" @@ -11087,6 +11102,31 @@ dependencies = [ "unsafe-libyaml", ] +[[package]] +name = "serial_test" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9" +dependencies = [ + "futures", + "log", + "once_cell", + "parking_lot", + "scc", + "serial_test_derive", +] + +[[package]] +name = "serial_test_derive" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "sha1" version = "0.10.6" @@ -13700,8 +13740,12 @@ name = "world-chain-builder-node" version = "0.1.0" dependencies = [ "alloy-eips 0.7.3", + "alloy-genesis", + "alloy-network 0.7.3", "alloy-primitives", "alloy-rpc-types", + "alloy-signer-local", + "chrono", "clap 4.5.23", "color-eyre", "criterion 0.5.1", @@ -13710,7 +13754,12 @@ dependencies = [ "reth-basic-payload-builder", "reth-chain-state", "reth-db", + "reth-e2e-test-utils", + "reth-evm", + "reth-node-core", "reth-optimism-chainspec", + "reth-optimism-consensus", + "reth-optimism-evm", "reth-optimism-node", "reth-optimism-payload-builder", "reth-optimism-primitives", @@ -13720,11 +13769,17 @@ dependencies = [ "reth-prune-types", "reth-trie", "reth-trie-db", + "revm-primitives", "semaphore", + "serde_json", + "serial_test", "tokio", "world-chain-builder-db", "world-chain-builder-payload", + "world-chain-builder-pbh", "world-chain-builder-pool", + "world-chain-builder-primitives", + "world-chain-builder-rpc", ] [[package]] diff --git a/world-chain-builder/crates/world/node/Cargo.toml b/world-chain-builder/crates/world/node/Cargo.toml index 2be05614..5e51a0d2 100644 --- a/world-chain-builder/crates/world/node/Cargo.toml +++ b/world-chain-builder/crates/world/node/Cargo.toml @@ -40,10 +40,28 @@ futures.workspace = true clap.workspace = true [dev-dependencies] +world-chain-builder-pbh.workspace = true +world-chain-builder-primitives.workspace = true +world-chain-builder-rpc.workspace = true +world-chain-builder-pool = { workspace = true, features = ["test"] } + +reth-e2e-test-utils.workspace = true +reth-evm.workspace = true +reth-node-core.workspace = true +reth-optimism-consensus.workspace = true +reth-optimism-evm.workspace = true +revm-primitives.workspace = true + +alloy-genesis.workspace = true +alloy-network.workspace = true +alloy-signer-local.workspace = true +alloy-eips.workspace = true + criterion.workspace = true semaphore.workspace = true - -world-chain-builder-pool = { workspace = true, features = ["test"] } +serial_test.workspace = true +serde_json.workspace = true +chrono.workspace = true [[bench]] name = "validate_transaction" diff --git a/world-chain-builder/crates/world/node/test/assets/genesis.json b/world-chain-builder/crates/world/node/tests/assets/genesis.json similarity index 100% rename from world-chain-builder/crates/world/node/test/assets/genesis.json rename to world-chain-builder/crates/world/node/tests/assets/genesis.json diff --git a/world-chain-builder/crates/world/node/test/e2e.rs b/world-chain-builder/crates/world/node/tests/e2e.rs similarity index 98% rename from world-chain-builder/crates/world/node/test/e2e.rs rename to world-chain-builder/crates/world/node/tests/e2e.rs index c023cd7b..edf26073 100644 --- a/world-chain-builder/crates/world/node/test/e2e.rs +++ b/world-chain-builder/crates/world/node/tests/e2e.rs @@ -38,7 +38,7 @@ use semaphore::protocol::{generate_nullifier_hash, generate_proof}; use semaphore::{hash_to_field, Field}; use serial_test::serial; use world_chain_builder_node::args::{ExtArgs, WorldChainBuilderArgs}; -use world_chain_builder_node::builder::WorldChainBuilder; +use world_chain_builder_node::node::WorldChainBuilder; use world_chain_builder_pbh::date_marker::DateMarker; use world_chain_builder_pbh::external_nullifier::{ExternalNullifier, Prefix}; use world_chain_builder_pbh::payload::{PbhPayload, Proof}; @@ -46,7 +46,7 @@ use world_chain_builder_pool::ordering::WorldChainOrdering; use world_chain_builder_pool::root::{LATEST_ROOT_SLOT, OP_WORLD_ID}; use world_chain_builder_pool::tx::WorldChainPooledTransaction; use world_chain_builder_pool::validator::WorldChainTransactionValidator; -use world_chain_builder_primitives::WorldChainPooledTransactionsElement; +use world_chain_builder_primitives::transaction::WorldChainPooledTransactionsElement; use world_chain_builder_rpc::bundle::{EthTransactionsExtServer, WorldChainEthApiExt}; pub const DEV_CHAIN_ID: u64 = 8453; From 87b16b7401744462d6aab21ca14ce1c5587ac290 Mon Sep 17 00:00:00 2001 From: Dzejkop Date: Fri, 13 Dec 2024 17:20:58 +0100 Subject: [PATCH 22/59] No more popup & serial_test --- world-chain-builder/Cargo.lock | 41 ---------------- world-chain-builder/Cargo.toml | 1 - .../crates/world/node/Cargo.toml | 1 - .../crates/world/node/tests/e2e.rs | 49 +++++++++++-------- 4 files changed, 29 insertions(+), 63 deletions(-) diff --git a/world-chain-builder/Cargo.lock b/world-chain-builder/Cargo.lock index ed00a5c4..a0107142 100644 --- a/world-chain-builder/Cargo.lock +++ b/world-chain-builder/Cargo.lock @@ -10708,15 +10708,6 @@ dependencies = [ "syn 2.0.90", ] -[[package]] -name = "scc" -version = "2.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66b202022bb57c049555430e11fc22fea12909276a80a4c3d368da36ac1d88ed" -dependencies = [ - "sdd", -] - [[package]] name = "schannel" version = "0.1.27" @@ -10774,12 +10765,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152" -[[package]] -name = "sdd" -version = "3.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49c1eeaf4b6a87c7479688c6d52b9f1153cedd3c489300564f932b065c6eab95" - [[package]] name = "seahash" version = "4.1.0" @@ -11102,31 +11087,6 @@ dependencies = [ "unsafe-libyaml", ] -[[package]] -name = "serial_test" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9" -dependencies = [ - "futures", - "log", - "once_cell", - "parking_lot", - "scc", - "serial_test_derive", -] - -[[package]] -name = "serial_test_derive" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.90", -] - [[package]] name = "sha1" version = "0.10.6" @@ -13772,7 +13732,6 @@ dependencies = [ "revm-primitives", "semaphore", "serde_json", - "serial_test", "tokio", "world-chain-builder-db", "world-chain-builder-payload", diff --git a/world-chain-builder/Cargo.toml b/world-chain-builder/Cargo.toml index 52b59863..e8d3af86 100644 --- a/world-chain-builder/Cargo.toml +++ b/world-chain-builder/Cargo.toml @@ -137,7 +137,6 @@ bytes = "1.7.2" hex = "0.4.3" tempfile = "3" criterion = { version = "0.5", features = ["async_tokio"] } -serial_test = "3" test-case = "3" ethers-core = { git = "https://github.com/gakonst/ethers-rs", default-features = false } serde_json = "1" diff --git a/world-chain-builder/crates/world/node/Cargo.toml b/world-chain-builder/crates/world/node/Cargo.toml index 5e51a0d2..f6e41df2 100644 --- a/world-chain-builder/crates/world/node/Cargo.toml +++ b/world-chain-builder/crates/world/node/Cargo.toml @@ -59,7 +59,6 @@ alloy-eips.workspace = true criterion.workspace = true semaphore.workspace = true -serial_test.workspace = true serde_json.workspace = true chrono.workspace = true diff --git a/world-chain-builder/crates/world/node/tests/e2e.rs b/world-chain-builder/crates/world/node/tests/e2e.rs index edf26073..fd19febd 100644 --- a/world-chain-builder/crates/world/node/tests/e2e.rs +++ b/world-chain-builder/crates/world/node/tests/e2e.rs @@ -1,7 +1,6 @@ //! Utilities for running world chain builder end-to-end tests. use std::collections::{BTreeMap, HashMap}; use std::sync::Arc; -use std::time::Duration; use alloy_eips::eip2718::Decodable2718; use alloy_genesis::{Genesis, GenesisAccount}; @@ -36,7 +35,6 @@ use semaphore::identity::Identity; use semaphore::poseidon_tree::LazyPoseidonTree; use semaphore::protocol::{generate_nullifier_hash, generate_proof}; use semaphore::{hash_to_field, Field}; -use serial_test::serial; use world_chain_builder_node::args::{ExtArgs, WorldChainBuilderArgs}; use world_chain_builder_node::node::WorldChainBuilder; use world_chain_builder_pbh::date_marker::DateMarker; @@ -110,19 +108,25 @@ impl WorldChainBuilderTestContext { let tasks = TaskManager::current(); let exec = tasks.executor(); - let node_config: NodeConfig = NodeConfig::new(op_chain_spec.clone()) + let mut node_config: NodeConfig = NodeConfig::new(op_chain_spec.clone()) .with_chain(op_chain_spec.clone()) - .with_unused_ports() .with_rpc( RpcServerArgs::default() .with_unused_ports() .with_http_unused_port(), - ); + ) + .with_unused_ports(); + + // discv5 ports seem to be clashing + node_config.network.discovery.disable_discovery = true; + node_config.network.discovery.addr = [127, 0, 0, 1].into(); + + // is 0.0.0.0 by default + node_config.network.addr = [127, 0, 0, 1].into(); + let path = tempdir_path(); - let NodeHandle { - node, - node_exit_future: _, - } = NodeBuilder::new(node_config.clone()) + + let builder = NodeBuilder::new(node_config.clone()) .testing_node(exec.clone()) .node(WorldChainBuilder::new( ExtArgs { @@ -141,10 +145,15 @@ impl WorldChainBuilderTestContext { let eth_api_ext = WorldChainEthApiExt::new(pool, provider); ctx.modules.merge_configured(eth_api_ext.into_rpc())?; Ok(()) - }) - .launch() - .await?; + }); + + let NodeHandle { + node, + node_exit_future: _, + } = builder.launch().await?; + let test_ctx = NodeTestContext::new(node, optimism_payload_attributes).await?; + Ok(Self { pbh_wallets: wallets, tree, @@ -225,9 +234,9 @@ impl WorldChainBuilderTestContext { } #[tokio::test] -#[serial] +// #[serial] async fn test_can_build_pbh_payload() -> eyre::Result<()> { - tokio::time::sleep(Duration::from_secs(1)).await; + // tokio::time::sleep(Duration::from_secs(1)).await; let mut ctx = WorldChainBuilderTestContext::setup().await?; let mut pbh_tx_hashes = vec![]; for signer in ctx.pbh_wallets.iter() { @@ -251,9 +260,9 @@ async fn test_can_build_pbh_payload() -> eyre::Result<()> { } #[tokio::test] -#[serial] +// #[serial] async fn test_transaction_pool_ordering() -> eyre::Result<()> { - tokio::time::sleep(Duration::from_secs(1)).await; + // tokio::time::sleep(Duration::from_secs(1)).await; let mut ctx = WorldChainBuilderTestContext::setup().await?; let non_pbh_tx = tx(ctx.node.inner.chain_spec().chain.id(), None, 0); let wallet = ctx.pbh_wallets[0].clone(); @@ -292,9 +301,9 @@ async fn test_transaction_pool_ordering() -> eyre::Result<()> { } #[tokio::test] -#[serial] +// #[serial] async fn test_invalidate_dup_tx_and_nullifier() -> eyre::Result<()> { - tokio::time::sleep(Duration::from_secs(1)).await; + // tokio::time::sleep(Duration::from_secs(1)).await; let ctx = WorldChainBuilderTestContext::setup().await?; let signer = ctx.pbh_wallets[0].clone(); let raw_tx = ctx.raw_pbh_tx_bytes(signer.clone(), 0, 0).await; @@ -305,9 +314,9 @@ async fn test_invalidate_dup_tx_and_nullifier() -> eyre::Result<()> { } #[tokio::test] -#[serial] +// #[serial] async fn test_dup_pbh_nonce() -> eyre::Result<()> { - tokio::time::sleep(Duration::from_secs(1)).await; + // tokio::time::sleep(Duration::from_secs(1)).await; let mut ctx = WorldChainBuilderTestContext::setup().await?; let signer = ctx.pbh_wallets[0].clone(); From 1136be1906633859e9eab6b731a7fabc29e41535 Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Fri, 13 Dec 2024 09:37:14 -0700 Subject: [PATCH 23/59] update pooled tx primitive --- world-chain-builder/Cargo.lock | 28 +++++++++---------- .../node/benches/validate_transaction.rs | 22 ++++++++------- .../crates/world/pool/src/ordering.rs | 2 +- .../crates/world/pool/src/test_utils.rs | 4 +-- .../crates/world/pool/src/tx.rs | 17 +++++------ .../crates/world/pool/src/validator.rs | 26 +++++++++-------- 6 files changed, 52 insertions(+), 47 deletions(-) diff --git a/world-chain-builder/Cargo.lock b/world-chain-builder/Cargo.lock index a0107142..4c44906a 100644 --- a/world-chain-builder/Cargo.lock +++ b/world-chain-builder/Cargo.lock @@ -2091,7 +2091,7 @@ checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" dependencies = [ "camino", "cargo-platform", - "semver 1.0.24", + "semver 1.0.23", "serde", "serde_json", "thiserror 1.0.69", @@ -2120,9 +2120,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.4" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9157bbaa6b165880c27a4293a474c91cdcf265cc68cc829bf10be0964a391caf" +checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d" dependencies = [ "jobserver", "libc", @@ -6922,9 +6922,9 @@ dependencies = [ [[package]] name = "quanta" -version = "0.12.4" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773ce68d0bb9bc7ef20be3536ffe94e223e1f365bd374108b2659fac0c65cfe6" +checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" dependencies = [ "crossbeam-utils", "libc", @@ -10414,9 +10414,9 @@ dependencies = [ [[package]] name = "roaring" -version = "0.10.9" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41589aba99537475bf697f2118357cad1c31590c5a1b9f6d9fc4ad6d07503661" +checksum = "395b0c39c00f9296f3937624c1fa4e0ee44f8c0e4b2c49408179ef381c6c2e6e" dependencies = [ "bytemuck", "byteorder", @@ -10511,7 +10511,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver 1.0.24", + "semver 1.0.23", ] [[package]] @@ -10919,9 +10919,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.24" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] @@ -12899,7 +12899,7 @@ dependencies = [ "hex", "indexmap 2.7.0", "schemars", - "semver 1.0.24", + "semver 1.0.23", "serde", "serde_json", "serde_yaml", @@ -13032,7 +13032,7 @@ dependencies = [ "reqwest 0.12.9", "rkyv", "rusty_pool", - "semver 1.0.24", + "semver 1.0.23", "serde", "serde_derive", "serde_json", @@ -13096,7 +13096,7 @@ checksum = "9dbe55c8f9d0dbd25d9447a5a889ff90c0cc3feaa7395310d3d826b2c703eaab" dependencies = [ "bitflags 2.6.0", "indexmap 2.7.0", - "semver 1.0.24", + "semver 1.0.23", ] [[package]] @@ -13175,7 +13175,7 @@ dependencies = [ "once_cell", "path-clean", "rand", - "semver 1.0.24", + "semver 1.0.23", "serde", "serde_json", "sha2 0.10.8", diff --git a/world-chain-builder/crates/world/node/benches/validate_transaction.rs b/world-chain-builder/crates/world/node/benches/validate_transaction.rs index c7a8d9e3..84449187 100644 --- a/world-chain-builder/crates/world/node/benches/validate_transaction.rs +++ b/world-chain-builder/crates/world/node/benches/validate_transaction.rs @@ -43,13 +43,14 @@ fn validator_setup() -> WorldChainTransactionValidator Setup { fn spoofed_nullifier_setup() -> Setup { let pool = pool_setup(); - let mut transaction = get_pbh_transaction(0); - let pbh_payload = transaction.pbh_payload.as_mut().unwrap(); - pbh_payload.nullifier_hash = Field::default(); + let transaction = get_pbh_transaction(0); + // TODO: + // let pbh_payload = transaction.pbh_payload.as_mut().unwrap(); + // pbh_payload.nullifier_hash = Field::default(); Setup { pool, transaction } } diff --git a/world-chain-builder/crates/world/pool/src/ordering.rs b/world-chain-builder/crates/world/pool/src/ordering.rs index 1df42a8f..b7b52c87 100644 --- a/world-chain-builder/crates/world/pool/src/ordering.rs +++ b/world-chain-builder/crates/world/pool/src/ordering.rs @@ -35,7 +35,7 @@ where let effective_tip_per_gas = transaction.effective_tip_per_gas(base_fee).map(U256::from); Some(WorldChainPriority { - is_pbh: transaction.pbh_payload().is_some(), + is_pbh: transaction.valid_pbh(), effective_tip_per_gas, }) .into() diff --git a/world-chain-builder/crates/world/pool/src/test_utils.rs b/world-chain-builder/crates/world/pool/src/test_utils.rs index bd68fef3..8f7f6e11 100644 --- a/world-chain-builder/crates/world/pool/src/test_utils.rs +++ b/world-chain-builder/crates/world/pool/src/test_utils.rs @@ -35,7 +35,7 @@ pub fn get_non_pbh_transaction() -> WorldChainPooledTransaction { let eth_tx = get_eth_transaction(); WorldChainPooledTransaction { inner: eth_tx, - pbh_payload: None, + valid_pbh: false, conditional_options: None, } } @@ -50,7 +50,7 @@ pub fn get_pbh_transaction(nonce: u16) -> WorldChainPooledTransaction { ); WorldChainPooledTransaction { inner: eth_tx, - pbh_payload: Some(pbh_payload), + valid_pbh: false, conditional_options: None, } } diff --git a/world-chain-builder/crates/world/pool/src/tx.rs b/world-chain-builder/crates/world/pool/src/tx.rs index 71369096..b63f05b9 100644 --- a/world-chain-builder/crates/world/pool/src/tx.rs +++ b/world-chain-builder/crates/world/pool/src/tx.rs @@ -21,14 +21,14 @@ use revm_primitives::{AccessList, Address, KzgSettings, TxKind, U256}; use world_chain_builder_pbh::payload::PbhPayload; pub trait WorldChainPoolTransaction: EthPoolTransaction { - fn pbh_payload(&self) -> Option<&PbhPayload>; + fn valid_pbh(&self) -> bool; fn conditional_options(&self) -> Option<&ConditionalOptions>; } #[derive(Debug, Clone)] pub struct WorldChainPooledTransaction { pub inner: EthPooledTransaction, - pub pbh_payload: Option, + pub valid_pbh: bool, pub conditional_options: Option, } @@ -60,7 +60,7 @@ impl EthPoolTransaction for WorldChainPooledTransaction { pooled.map(|inner| Self { inner, - pbh_payload: None, + valid_pbh: false, conditional_options: None, }) } @@ -87,9 +87,10 @@ impl EthPoolTransaction for WorldChainPooledTransaction { } impl WorldChainPoolTransaction for WorldChainPooledTransaction { - fn pbh_payload(&self) -> Option<&PbhPayload> { - self.pbh_payload.as_ref() + fn valid_pbh(&self) -> bool { + self.valid_pbh } + fn conditional_options(&self) -> Option<&ConditionalOptions> { self.conditional_options.as_ref() } @@ -99,7 +100,7 @@ impl From for WorldChainPooledTransaction { fn from(tx: EthPooledTransaction) -> Self { Self { inner: tx, - pbh_payload: None, + valid_pbh: false, conditional_options: None, } } @@ -111,7 +112,7 @@ impl From for WorldChainPooledTransaction let inner = EthPooledTransaction::from(tx); Self { inner, - pbh_payload: None, + valid_pbh: false, conditional_options: None, } } @@ -124,7 +125,7 @@ impl TryFrom for WorldChainPooledTransaction { let inner = EthPooledTransaction::try_from(tx)?; Ok(Self { inner, - pbh_payload: None, + valid_pbh: false, conditional_options: None, }) } diff --git a/world-chain-builder/crates/world/pool/src/validator.rs b/world-chain-builder/crates/world/pool/src/validator.rs index 1b037ed5..7da5aaae 100644 --- a/world-chain-builder/crates/world/pool/src/validator.rs +++ b/world-chain-builder/crates/world/pool/src/validator.rs @@ -168,11 +168,12 @@ where ) -> TransactionValidationOutcome { let validation_outcome = self.inner.validate_one(origin, transaction.clone()); - if let Some(pbh_payload) = transaction.pbh_payload() { - if let Err(e) = self.validate_pbh_payload(&transaction, pbh_payload) { - return e.to_outcome(transaction); - } - }; + // TODO: Extend Validation logic for 4337 Architecture + // if let Some(pbh_payload) = transaction.pbh_payload() { + // if let Err(e) = self.validate_pbh_payload(&transaction, pbh_payload) { + // return e.to_outcome(transaction); + // } + // }; validation_outcome } @@ -250,13 +251,14 @@ pub mod tests { ExtendedAccount::new(transaction.nonce(), alloy_primitives::U256::MAX), ); // Insert a world id root into the OpWorldId Account - validator.inner.client().add_account( - OP_WORLD_ID, - ExtendedAccount::new(0, alloy_primitives::U256::ZERO).extend_storage(vec![( - LATEST_ROOT_SLOT.into(), - transaction.pbh_payload.clone().unwrap().root, - )]), - ); + // TODO: This should be set to the root on the Payloads of a Bundle Tx + // validator.inner.client().add_account( + // OP_WORLD_ID, + // ExtendedAccount::new(0, alloy_primitives::U256::ZERO).extend_storage(vec![( + // LATEST_ROOT_SLOT.into(), + // transaction.pbh_payload.clone().unwrap().root, + // )]), + // ); let header = SealedHeader::default(); let body = BlockBody::default(); let block = SealedBlock::new(header, body); From 150be286cf8f4729ea8fef435540b67ce39ebdea Mon Sep 17 00:00:00 2001 From: 0xKitsune <0xkitsune@protonmail.com> Date: Fri, 13 Dec 2024 12:22:52 -0500 Subject: [PATCH 24/59] wip update payload builder initialization --- .../crates/world/node/src/node.rs | 36 +++++++++++++------ .../crates/world/payload/src/builder.rs | 2 +- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/world-chain-builder/crates/world/node/src/node.rs b/world-chain-builder/crates/world/node/src/node.rs index 0ac6f793..4f80f88c 100644 --- a/world-chain-builder/crates/world/node/src/node.rs +++ b/world-chain-builder/crates/world/node/src/node.rs @@ -177,9 +177,18 @@ impl NodeTypesWithEngine for WorldChainBuilder { /// A basic optimism payload service builder #[derive(Debug, Default, Clone)] pub struct WorldChainPayloadBuilder { - // TODO: pub? - pub inner: OpPayloadBuilder, - + /// By default the pending block equals the latest block + /// to save resources and not leak txs from the tx-pool, + /// this flag enables computing of the pending block + /// from the tx-pool instead. + /// + /// If `compute_pending_block` is not enabled, the payload builder + /// will use the payload attributes from the latest block. Note + /// that this flag is not yet functional. + pub compute_pending_block: bool, + /// The type responsible for yielding the best transactions for the payload if mempool + /// transactions are allowed. + pub best_transactions: Txs, // TODO: pub verified_blockspace_capacity: u8, } @@ -188,8 +197,9 @@ impl WorldChainPayloadBuilder { /// Create a new instance with the given `compute_pending_block` flag. pub const fn new(compute_pending_block: bool, verified_blockspace_capacity: u8) -> Self { Self { - inner: OpPayloadBuilder::new(compute_pending_block), + compute_pending_block, verified_blockspace_capacity, + best_transactions: (), } } } @@ -204,14 +214,16 @@ where self, best_transactions: T, ) -> WorldChainPayloadBuilder { - let WorldChainPayloadBuilder { - inner, + let Self { + compute_pending_block, verified_blockspace_capacity, + .. } = self; WorldChainPayloadBuilder { - inner: inner.with_transactions(best_transactions), + compute_pending_block, verified_blockspace_capacity, + best_transactions, } } @@ -235,9 +247,13 @@ where + 'static, Evm: ConfigureEvm
, { - let payload_builder = reth_optimism_payload_builder::OpPayloadBuilder::new(evm_config) - .with_transactions(self.inner.best_transactions) - .set_compute_pending_block(self.inner.compute_pending_block); + let payload_builder = world_chain_builder_payload::builder::WorldChainPayloadBuilder::new( + evm_config, + self.verified_blockspace_capacity, + ) + .with_transactions(self.best_transactions) + .set_compute_pending_block(self.compute_pending_block); + let conf = ctx.payload_builder_config(); let payload_job_config = BasicPayloadJobGeneratorConfig::default() diff --git a/world-chain-builder/crates/world/payload/src/builder.rs b/world-chain-builder/crates/world/payload/src/builder.rs index 3dd1af88..27795d7f 100644 --- a/world-chain-builder/crates/world/payload/src/builder.rs +++ b/world-chain-builder/crates/world/payload/src/builder.rs @@ -81,7 +81,7 @@ where } } -impl WorldChainPayloadBuilder { +impl WorldChainPayloadBuilder { /// Sets the rollup's compute pending block configuration option. pub const fn set_compute_pending_block(mut self, compute_pending_block: bool) -> Self { self.inner.compute_pending_block = compute_pending_block; From c2b022868d7586a495120ce44e43e54609e40d1f Mon Sep 17 00:00:00 2001 From: 0xKitsune <0xkitsune@protonmail.com> Date: Fri, 13 Dec 2024 12:32:24 -0500 Subject: [PATCH 25/59] impl PayloadBuilder for WorldChainPayloadBuilder --- .../crates/world/payload/src/builder.rs | 54 ++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/world-chain-builder/crates/world/payload/src/builder.rs b/world-chain-builder/crates/world/payload/src/builder.rs index 27795d7f..8f447707 100644 --- a/world-chain-builder/crates/world/payload/src/builder.rs +++ b/world-chain-builder/crates/world/payload/src/builder.rs @@ -53,13 +53,13 @@ use world_chain_builder_pool::tx::WorldChainPoolTransaction; use world_chain_builder_rpc::bundle::validate_conditional_options; /// World Chain payload builder -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WorldChainPayloadBuilder { pub inner: OpPayloadBuilder, pub verified_blockspace_capacity: u8, } -impl WorldChainPayloadBuilder +impl WorldChainPayloadBuilder where EvmConfig: ConfigureEvm
, { @@ -266,6 +266,56 @@ where } } +/// Implementation of the [`PayloadBuilder`] trait for [`WorldChainPayloadBuilder`]. +impl PayloadBuilder + for WorldChainPayloadBuilder +where + Client: StateProviderFactory + ChainSpecProvider, + Pool: TransactionPool>, + EvmConfig: ConfigureEvm
, + Txs: OpPayloadTransactions, +{ + type Attributes = OpPayloadBuilderAttributes; + type BuiltPayload = OpBuiltPayload; + + fn try_build( + &self, + args: BuildArguments, + ) -> Result, PayloadBuilderError> { + self.build_payload(args) + } + + fn on_missing_payload( + &self, + _args: BuildArguments, + ) -> MissingPayloadBehaviour { + // we want to await the job that's already in progress because that should be returned as + // is, there's no benefit in racing another job + MissingPayloadBehaviour::AwaitInProgress + } + + // NOTE: this should only be used for testing purposes because this doesn't have access to L1 + // system txs, hence on_missing_payload we return [MissingPayloadBehaviour::AwaitInProgress]. + fn build_empty_payload( + &self, + client: &Client, + config: PayloadConfig, + ) -> Result { + let args = BuildArguments { + client, + config, + // we use defaults here because for the empty payload we don't need to execute anything + pool: NoopTransactionPool::default(), + cached_reads: Default::default(), + cancel: Default::default(), + best_payload: None, + }; + self.build_payload(args)? + .into_payload() + .ok_or_else(|| PayloadBuilderError::MissingPayload) + } +} + impl WorldChainBuilder where Pool: TransactionPool>, From 612ccbab2b42fd7d93f683a8e234d2557b311eee Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Fri, 13 Dec 2024 10:38:48 -0700 Subject: [PATCH 26/59] feat: override --- world-chain-builder/Cargo.lock | 2 + .../crates/world/bin/src/main.rs | 9 ++- .../crates/world/node/tests/e2e.rs | 4 +- .../crates/world/payload/src/builder.rs | 2 +- .../crates/world/rpc/Cargo.toml | 3 + .../world/rpc/src/{bundle.rs => eth.rs} | 63 ++++++++++++------- .../crates/world/rpc/src/lib.rs | 30 ++++++++- 7 files changed, 83 insertions(+), 30 deletions(-) rename world-chain-builder/crates/world/rpc/src/{bundle.rs => eth.rs} (78%) diff --git a/world-chain-builder/Cargo.lock b/world-chain-builder/Cargo.lock index 4c44906a..0738b9f1 100644 --- a/world-chain-builder/Cargo.lock +++ b/world-chain-builder/Cargo.lock @@ -13840,8 +13840,10 @@ dependencies = [ "alloy-rpc-types", "jsonrpsee", "reth", + "reth-optimism-rpc", "reth-provider", "revm-primitives", + "tracing", "world-chain-builder-pool", ] diff --git a/world-chain-builder/crates/world/bin/src/main.rs b/world-chain-builder/crates/world/bin/src/main.rs index 0bb0e026..7f87ef32 100644 --- a/world-chain-builder/crates/world/bin/src/main.rs +++ b/world-chain-builder/crates/world/bin/src/main.rs @@ -1,9 +1,10 @@ use clap::Parser; use reth_optimism_cli::chainspec::OpChainSpecParser; use reth_optimism_cli::Cli; +use reth_optimism_rpc::SequencerClient; use world_chain_builder_node::args::ExtArgs; use world_chain_builder_node::node::WorldChainBuilder; -use world_chain_builder_rpc::bundle::{EthTransactionsExtServer, WorldChainEthApiExt}; +use world_chain_builder_rpc::{EthTransactionsExtServer, WorldChainEthApiExt}; #[cfg(all(feature = "jemalloc", unix))] #[global_allocator] @@ -35,7 +36,11 @@ fn main() { .extend_rpc_modules(move |ctx| { let provider = ctx.provider().clone(); let pool = ctx.pool().clone(); - let eth_api_ext = WorldChainEthApiExt::new(pool, provider); + let sequencer_client = builder_args.rollup_args.sequencer_http.map(SequencerClient::new); + let eth_api_ext = WorldChainEthApiExt::new(pool, provider, sequencer_client); + // Remove the `eth_sendRawTransaction` method from the configured modules + ctx.modules.remove_method_from_configured(&"eth_sendRawTransaction"); + // Merge the `eth_sendRawTransaction` and `eth_sendRawTransactionConditional` RPC methods ctx.modules.merge_configured(eth_api_ext.into_rpc())?; Ok(()) }) diff --git a/world-chain-builder/crates/world/node/tests/e2e.rs b/world-chain-builder/crates/world/node/tests/e2e.rs index fd19febd..dd47af19 100644 --- a/world-chain-builder/crates/world/node/tests/e2e.rs +++ b/world-chain-builder/crates/world/node/tests/e2e.rs @@ -45,7 +45,7 @@ use world_chain_builder_pool::root::{LATEST_ROOT_SLOT, OP_WORLD_ID}; use world_chain_builder_pool::tx::WorldChainPooledTransaction; use world_chain_builder_pool::validator::WorldChainTransactionValidator; use world_chain_builder_primitives::transaction::WorldChainPooledTransactionsElement; -use world_chain_builder_rpc::bundle::{EthTransactionsExtServer, WorldChainEthApiExt}; +use world_chain_builder_rpc::{EthTransactionsExtServer, WorldChainEthApiExt}; pub const DEV_CHAIN_ID: u64 = 8453; @@ -142,7 +142,7 @@ impl WorldChainBuilderTestContext { .extend_rpc_modules(move |ctx| { let provider = ctx.provider().clone(); let pool = ctx.pool().clone(); - let eth_api_ext = WorldChainEthApiExt::new(pool, provider); + let eth_api_ext = WorldChainEthApiExt::new(pool, provider, None); ctx.modules.merge_configured(eth_api_ext.into_rpc())?; Ok(()) }); diff --git a/world-chain-builder/crates/world/payload/src/builder.rs b/world-chain-builder/crates/world/payload/src/builder.rs index 3dd1af88..a1ceb821 100644 --- a/world-chain-builder/crates/world/payload/src/builder.rs +++ b/world-chain-builder/crates/world/payload/src/builder.rs @@ -50,7 +50,7 @@ use tracing::{debug, trace, warn}; use world_chain_builder_pool::noop::NoopWorldChainTransactionPool; use world_chain_builder_pool::tx::WorldChainPoolTransaction; -use world_chain_builder_rpc::bundle::validate_conditional_options; +use world_chain_builder_rpc::eth::validate_conditional_options; /// World Chain payload builder #[derive(Debug)] diff --git a/world-chain-builder/crates/world/rpc/Cargo.toml b/world-chain-builder/crates/world/rpc/Cargo.toml index 26b8c10e..6e8e6e78 100644 --- a/world-chain-builder/crates/world/rpc/Cargo.toml +++ b/world-chain-builder/crates/world/rpc/Cargo.toml @@ -17,6 +17,7 @@ reth.workspace = true reth-provider.workspace = true revm-primitives.workspace = true +reth-optimism-rpc.workspace = true alloy-consensus.workspace = true alloy-eips.workspace = true @@ -24,3 +25,5 @@ alloy-primitives.workspace = true alloy-rpc-types.workspace = true jsonrpsee.workspace = true + +tracing.workspace = true diff --git a/world-chain-builder/crates/world/rpc/src/bundle.rs b/world-chain-builder/crates/world/rpc/src/eth.rs similarity index 78% rename from world-chain-builder/crates/world/rpc/src/bundle.rs rename to world-chain-builder/crates/world/rpc/src/eth.rs index b4e7b8ce..8d9d93bc 100644 --- a/world-chain-builder/crates/world/rpc/src/bundle.rs +++ b/world-chain-builder/crates/world/rpc/src/eth.rs @@ -4,7 +4,6 @@ use alloy_primitives::{map::HashMap, StorageKey}; use alloy_rpc_types::erc4337::{AccountStorage, ConditionalOptions}; use jsonrpsee::{ core::{async_trait, RpcResult}, - proc_macros::rpc, types::{ErrorCode, ErrorObject, ErrorObjectOwned}, }; use reth::{ @@ -12,31 +11,12 @@ use reth::{ rpc::server_types::eth::utils::recover_raw_transaction, transaction_pool::{EthPooledTransaction, PoolTransaction, TransactionOrigin, TransactionPool}, }; +use reth_optimism_rpc::SequencerClient; use reth_provider::{BlockReaderIdExt, StateProviderFactory}; use revm_primitives::{map::FbBuildHasher, Address, Bytes, FixedBytes, B256}; use world_chain_builder_pool::tx::WorldChainPooledTransaction; -/// Trait interface for `eth_sendRawTransactionConditional` -#[cfg_attr(not(test), rpc(server, namespace = "eth"))] -#[cfg_attr(test, rpc(server, client, namespace = "eth"))] -#[async_trait] -pub trait EthTransactionsExt { - #[method(name = "sendRawTransactionConditional")] - async fn send_raw_transaction_conditional( - &self, - tx: Bytes, - options: ConditionalOptions, - ) -> RpcResult; -} - -/// WorldChainEthApi Extension for ERC-4337 Conditionally Included -/// -/// Bundled Transactions -#[derive(Clone, Debug)] -pub struct WorldChainEthApiExt { - pool: Pool, - client: Client, -} +use crate::{EthTransactionsExtServer, WorldChainEthApiExt}; #[async_trait] impl EthTransactionsExtServer for WorldChainEthApiExt @@ -63,6 +43,23 @@ where .await .map_err(|_| ErrorObjectOwned::from(ErrorCode::InternalError))?; + self.maybe_forward_raw_transaction(tx, hash).await?; + Ok(hash) + } + + async fn send_raw_transaction(&self, tx: Bytes) -> RpcResult { + let recovered = recover_raw_transaction(&tx)?; + let pool_transaction: WorldChainPooledTransaction = + EthPooledTransaction::from_pooled(recovered).into(); + + // submit the transaction to the pool with a `Local` origin + let hash = self + .pool() + .add_transaction(TransactionOrigin::Local, pool_transaction) + .await + .map_err(|_| ErrorObjectOwned::from(ErrorCode::InternalError))?; + + self.maybe_forward_raw_transaction(tx, hash).await?; Ok(hash) } } @@ -72,8 +69,12 @@ where Pool: TransactionPool + Clone + 'static, Client: BlockReaderIdExt + StateProviderFactory + 'static, { - pub fn new(pool: Pool, client: Client) -> Self { - Self { pool, client } + pub fn new(pool: Pool, client: Client, sequencer_client: Option) -> Self { + Self { + pool, + client, + sequencer_client, + } } pub fn provider(&self) -> &Client { @@ -83,6 +84,20 @@ where pub fn pool(&self) -> &Pool { &self.pool } + + pub fn raw_tx_forwarder(&self) -> Option<&SequencerClient> { + self.sequencer_client.as_ref() + } + + async fn maybe_forward_raw_transaction(&self, tx: Bytes, hash: B256) -> RpcResult<()> { + if let Some(client) = self.raw_tx_forwarder().as_ref() { + tracing::debug!( target: "rpc::eth", "forwarding raw transaction to"); + let _ = client.forward_raw_transaction(&tx).await.inspect_err(|err| { + tracing::debug!(target: "rpc::eth", %err, hash=?*hash, "failed to forward raw transaction"); + }); + } + Ok(()) + } } /// Validates the conditional inclusion options provided by the client. diff --git a/world-chain-builder/crates/world/rpc/src/lib.rs b/world-chain-builder/crates/world/rpc/src/lib.rs index ced4c376..a0b24f77 100644 --- a/world-chain-builder/crates/world/rpc/src/lib.rs +++ b/world-chain-builder/crates/world/rpc/src/lib.rs @@ -1 +1,29 @@ -pub mod bundle; +use alloy_primitives::{Bytes, B256}; +use alloy_rpc_types::erc4337::ConditionalOptions; +use jsonrpsee::{core::RpcResult, proc_macros::rpc}; +use reth_optimism_rpc::SequencerClient; +pub mod eth; + +/// Trait interface for EthApi Extension +#[cfg_attr(not(test), rpc(server, namespace = "eth"))] +#[cfg_attr(test, rpc(server, client, namespace = "eth"))] +#[async_trait] +pub trait EthTransactionsExt { + #[method(name = "sendRawTransactionConditional")] + async fn send_raw_transaction_conditional( + &self, + tx: Bytes, + options: ConditionalOptions, + ) -> RpcResult; + + #[method(name = "sendRawTransaction")] + async fn send_raw_transaction(&self, tx: Bytes) -> RpcResult; +} + +/// WorldChainEthApi Extension for `sendRawTransactionConditional` and `sendRawTransaction` +#[derive(Clone, Debug)] +pub struct WorldChainEthApiExt { + pool: Pool, + client: Client, + sequencer_client: Option +} From 212bfcd8ce8883bf18afde3c62ec5f07465ab501 Mon Sep 17 00:00:00 2001 From: 0xKitsune <0xkitsune@protonmail.com> Date: Fri, 13 Dec 2024 12:39:41 -0500 Subject: [PATCH 27/59] add payload builder ctx --- .../crates/world/payload/src/builder.rs | 404 +++++++++++++++++- 1 file changed, 382 insertions(+), 22 deletions(-) diff --git a/world-chain-builder/crates/world/payload/src/builder.rs b/world-chain-builder/crates/world/payload/src/builder.rs index 8f447707..fc3ac5dc 100644 --- a/world-chain-builder/crates/world/payload/src/builder.rs +++ b/world-chain-builder/crates/world/payload/src/builder.rs @@ -1,11 +1,12 @@ use alloy_consensus::EMPTY_OMMER_ROOT_HASH; +use alloy_eips::eip4895::Withdrawals; use alloy_eips::merge::BEACON_NONCE; use alloy_rpc_types_debug::ExecutionWitness; use reth::api::PayloadBuilderError; use reth::builder::components::PayloadServiceBuilder; use reth::builder::{BuilderContext, FullNodeTypes, NodeTypesWithEngine, PayloadBuilderConfig}; use reth::chainspec::EthereumHardforks; -use reth::payload::PayloadBuilderAttributes; +use reth::payload::{PayloadBuilderAttributes, PayloadId}; use reth::payload::{PayloadBuilderHandle, PayloadBuilderService}; use reth::revm::database::StateProviderDatabase; use reth::revm::db::states::bundle_state::BundleRetention; @@ -40,11 +41,12 @@ use reth_provider::{ use reth_transaction_pool::{noop::NoopTransactionPool, pool::BestPayloadTransactions}; use reth_trie::HashedPostState; use revm::Database; -use revm_primitives::calc_excess_blob_gas; +use revm_primitives::{calc_excess_blob_gas, Bytes, B256}; use revm_primitives::{ BlockEnv, CfgEnvWithHandlerCfg, EVMError, EnvWithHandlerCfg, InvalidTransaction, ResultAndState, U256, }; +use std::fmt::Display; use std::sync::Arc; use tracing::{debug, trace, warn}; @@ -316,6 +318,29 @@ where } } +/// The type that builds the payload. +/// +/// Payload building for optimism is composed of several steps. +/// The first steps are mandatory and defined by the protocol. +/// +/// 1. first all System calls are applied. +/// 2. After canyon the forced deployed `create2deployer` must be loaded +/// 3. all sequencer transactions are executed (part of the payload attributes) +/// +/// Depending on whether the node acts as a sequencer and is allowed to include additional +/// transactions (`no_tx_pool == false`): +/// 4. include additional transactions +/// +/// And finally +/// 5. build the block: compute all roots (txs, state) +#[derive(Debug)] +pub struct WorldChainBuilder { + /// The transaction pool + pool: Pool, + /// Yields the best transaction to include if transactions from the mempool are allowed. + best: Txs, +} + impl WorldChainBuilder where Pool: TransactionPool>, @@ -540,25 +565,360 @@ where } } -/// The type that builds the payload. -/// -/// Payload building for optimism is composed of several steps. -/// The first steps are mandatory and defined by the protocol. -/// -/// 1. first all System calls are applied. -/// 2. After canyon the forced deployed `create2deployer` must be loaded -/// 3. all sequencer transactions are executed (part of the payload attributes) -/// -/// Depending on whether the node acts as a sequencer and is allowed to include additional -/// transactions (`no_tx_pool == false`): -/// 4. include additional transactions -/// -/// And finally -/// 5. build the block: compute all roots (txs, state) +/// Container type that holds all necessities to build a new payload. #[derive(Debug)] -pub struct WorldChainBuilder { - /// The transaction pool - pool: Pool, - /// Yields the best transaction to include if transactions from the mempool are allowed. - best: Txs, +pub struct WorldChainPayloadBuilderCtx { + pub inner: OpPayloadBuilderCtx, +} + +impl WorldChainPayloadBuilderCtx { + /// Returns the parent block the payload will be build on. + pub fn parent(&self) -> &SealedHeader { + self.inner.parent() + } + + /// Returns the builder attributes. + pub const fn attributes(&self) -> &OpPayloadBuilderAttributes { + self.inner.attributes() + } + + /// Returns the withdrawals if shanghai is active. + pub fn withdrawals(&self) -> Option<&Withdrawals> { + self.inner.withdrawals() + } + + /// Returns the block gas limit to target. + pub fn block_gas_limit(&self) -> u64 { + self.inner.block_gas_limit() + } + + /// Returns the block number for the block. + pub fn block_number(&self) -> u64 { + self.inner.block_number() + } + + /// Returns the current base fee + pub fn base_fee(&self) -> u64 { + self.inner.base_fee() + } + + /// Returns the current blob gas price. + pub fn get_blob_gasprice(&self) -> Option { + self.inner.get_blob_gasprice() + } + + /// Returns the blob fields for the header. + /// + /// This will always return `Some(0)` after ecotone. + pub fn blob_fields(&self) -> (Option, Option) { + self.inner.blob_fields() + } + + /// Returns the extra data for the block. + /// + /// After holocene this extracts the extradata from the paylpad + pub fn extra_data(&self) -> Result { + self.inner.extra_data() + } + + /// Returns the current fee settings for transactions from the mempool + // TODO: PBH + pub fn best_transaction_attributes(&self) -> BestTransactionsAttributes { + BestTransactionsAttributes::new(self.base_fee(), self.get_blob_gasprice()) + } + + /// Returns the unique id for this payload job. + pub fn payload_id(&self) -> PayloadId { + self.inner.payload_id() + } + + /// Returns true if regolith is active for the payload. + pub fn is_regolith_active(&self) -> bool { + self.inner.is_regolith_active() + } + + /// Returns true if ecotone is active for the payload. + pub fn is_ecotone_active(&self) -> bool { + self.inner.is_ecotone_active() + } + + /// Returns true if canyon is active for the payload. + pub fn is_canyon_active(&self) -> bool { + self.inner.is_canyon_active() + } + + /// Returns true if holocene is active for the payload. + pub fn is_holocene_active(&self) -> bool { + self.inner.is_holocene_active() + } + + /// Returns true if the fees are higher than the previous payload. + /// TODO: PBH + pub fn is_better_payload(&self, total_fees: U256) -> bool { + // is_better_payload(self.best_payload.as_ref(), total_fees) + todo!() + } + + /// Commits the withdrawals from the payload attributes to the state. + pub fn commit_withdrawals(&self, db: &mut State) -> Result, ProviderError> + where + DB: Database, + { + self.inner.commit_withdrawals(db) + } + + /// Ensure that the create2deployer is force-deployed at the canyon transition. Optimism + /// blocks will always have at least a single transaction in them (the L1 info transaction), + /// so we can safely assume that this will always be triggered upon the transition and that + /// the above check for empty blocks will never be hit on OP chains. + pub fn ensure_create2_deployer(&self, db: &mut State) -> Result<(), PayloadBuilderError> + where + DB: Database, + DB::Error: Display, + { + self.inner.ensure_create2_deployer(db) + } } + +// impl WorldChainPayloadBuilderCtx +// where +// EvmConfig: ConfigureEvm
, +// { +// /// apply eip-4788 pre block contract call +// pub fn apply_pre_beacon_root_contract_call( +// &self, +// db: &mut DB, +// ) -> Result<(), PayloadBuilderError> +// where +// DB: Database + DatabaseCommit, +// DB::Error: Display, +// { +// SystemCaller::new(self.evm_config.clone(), self.chain_spec.clone()) +// .pre_block_beacon_root_contract_call( +// db, +// &self.initialized_cfg, +// &self.initialized_block_env, +// self.attributes() +// .payload_attributes +// .parent_beacon_block_root, +// ) +// .map_err(|err| { +// warn!(target: "payload_builder", +// parent_header=%self.parent().hash(), +// %err, +// "failed to apply beacon root contract call for payload" +// ); +// PayloadBuilderError::Internal(err.into()) +// })?; + +// Ok(()) +// } + +// /// Executes all sequencer transactions that are included in the payload attributes. +// pub fn execute_sequencer_transactions( +// &self, +// db: &mut State, +// ) -> Result +// where +// DB: Database, +// { +// let mut info = ExecutionInfo::with_capacity(self.attributes().transactions.len()); + +// let env = EnvWithHandlerCfg::new_with_cfg_env( +// self.initialized_cfg.clone(), +// self.initialized_block_env.clone(), +// TxEnv::default(), +// ); +// let mut evm = self.evm_config.evm_with_env(&mut *db, env); + +// for sequencer_tx in &self.attributes().transactions { +// // A sequencer's block should never contain blob transactions. +// if sequencer_tx.value().is_eip4844() { +// return Err(PayloadBuilderError::other( +// OpPayloadBuilderError::BlobTransactionRejected, +// )); +// } + +// // Convert the transaction to a [RecoveredTx]. This is +// // purely for the purposes of utilizing the `evm_config.tx_env`` function. +// // Deposit transactions do not have signatures, so if the tx is a deposit, this +// // will just pull in its `from` address. +// let sequencer_tx = sequencer_tx +// .value() +// .clone() +// .try_into_ecrecovered() +// .map_err(|_| { +// PayloadBuilderError::other(OpPayloadBuilderError::TransactionEcRecoverFailed) +// })?; + +// // Cache the depositor account prior to the state transition for the deposit nonce. +// // +// // Note that this *only* needs to be done post-regolith hardfork, as deposit nonces +// // were not introduced in Bedrock. In addition, regular transactions don't have deposit +// // nonces, so we don't need to touch the DB for those. +// let depositor = (self.is_regolith_active() && sequencer_tx.is_deposit()) +// .then(|| { +// evm.db_mut() +// .load_cache_account(sequencer_tx.signer()) +// .map(|acc| acc.account_info().unwrap_or_default()) +// }) +// .transpose() +// .map_err(|_| { +// PayloadBuilderError::other(OpPayloadBuilderError::AccountLoadFailed( +// sequencer_tx.signer(), +// )) +// })?; + +// *evm.tx_mut() = self +// .evm_config +// .tx_env(sequencer_tx.as_signed(), sequencer_tx.signer()); + +// let ResultAndState { result, state } = match evm.transact() { +// Ok(res) => res, +// Err(err) => { +// match err { +// EVMError::Transaction(err) => { +// trace!(target: "payload_builder", %err, ?sequencer_tx, "Error in sequencer transaction, skipping."); +// continue; +// } +// err => { +// // this is an error that we should treat as fatal for this attempt +// return Err(PayloadBuilderError::EvmExecutionError(err)); +// } +// } +// } +// }; + +// // commit changes +// evm.db_mut().commit(state); + +// let gas_used = result.gas_used(); + +// // add gas used by the transaction to cumulative gas used, before creating the receipt +// info.cumulative_gas_used += gas_used; + +// // Push transaction changeset and calculate header bloom filter for receipt. +// info.receipts.push(Some(Receipt { +// tx_type: sequencer_tx.tx_type(), +// success: result.is_success(), +// cumulative_gas_used: info.cumulative_gas_used, +// logs: result.into_logs().into_iter().map(Into::into).collect(), +// deposit_nonce: depositor.map(|account| account.nonce), +// // The deposit receipt version was introduced in Canyon to indicate an update to how +// // receipt hashes should be computed when set. The state transition process +// // ensures this is only set for post-Canyon deposit transactions. +// deposit_receipt_version: self.is_canyon_active().then_some(1), +// })); + +// // append sender and transaction to the respective lists +// info.executed_senders.push(sequencer_tx.signer()); +// info.executed_transactions.push(sequencer_tx.into_signed()); +// } + +// Ok(info) +// } + +// /// Executes the given best transactions and updates the execution info. +// /// +// /// Returns `Ok(Some(())` if the job was cancelled. +// pub fn execute_best_transactions( +// &self, +// info: &mut ExecutionInfo, +// db: &mut State, +// mut best_txs: impl PayloadTransactions, +// ) -> Result, PayloadBuilderError> +// where +// DB: Database, +// { +// let block_gas_limit = self.block_gas_limit(); +// let base_fee = self.base_fee(); + +// let env = EnvWithHandlerCfg::new_with_cfg_env( +// self.initialized_cfg.clone(), +// self.initialized_block_env.clone(), +// TxEnv::default(), +// ); +// let mut evm = self.evm_config.evm_with_env(&mut *db, env); + +// while let Some(tx) = best_txs.next(()) { +// // ensure we still have capacity for this transaction +// if info.cumulative_gas_used + tx.gas_limit() > block_gas_limit { +// // we can't fit this transaction into the block, so we need to mark it as +// // invalid which also removes all dependent transaction from +// // the iterator before we can continue +// best_txs.mark_invalid(tx.signer(), tx.nonce()); +// continue; +// } + +// // A sequencer's block should never contain blob or deposit transactions from the pool. +// if tx.is_eip4844() || tx.tx_type() == TxType::Deposit as u8 { +// best_txs.mark_invalid(tx.signer(), tx.nonce()); +// continue; +// } + +// // check if the job was cancelled, if so we can exit early +// if self.cancel.is_cancelled() { +// return Ok(Some(())); +// } + +// // Configure the environment for the tx. +// *evm.tx_mut() = self.evm_config.tx_env(tx.as_signed(), tx.signer()); + +// let ResultAndState { result, state } = match evm.transact() { +// Ok(res) => res, +// Err(err) => { +// match err { +// EVMError::Transaction(err) => { +// if matches!(err, InvalidTransaction::NonceTooLow { .. }) { +// // if the nonce is too low, we can skip this transaction +// trace!(target: "payload_builder", %err, ?tx, "skipping nonce too low transaction"); +// } else { +// // if the transaction is invalid, we can skip it and all of its +// // descendants +// trace!(target: "payload_builder", %err, ?tx, "skipping invalid transaction and its descendants"); +// best_txs.mark_invalid(tx.signer(), tx.nonce()); +// } + +// continue; +// } +// err => { +// // this is an error that we should treat as fatal for this attempt +// return Err(PayloadBuilderError::EvmExecutionError(err)); +// } +// } +// } +// }; + +// // commit changes +// evm.db_mut().commit(state); + +// let gas_used = result.gas_used(); + +// // add gas used by the transaction to cumulative gas used, before creating the +// // receipt +// info.cumulative_gas_used += gas_used; + +// // Push transaction changeset and calculate header bloom filter for receipt. +// info.receipts.push(Some(Receipt { +// tx_type: tx.tx_type(), +// success: result.is_success(), +// cumulative_gas_used: info.cumulative_gas_used, +// logs: result.into_logs().into_iter().map(Into::into).collect(), +// deposit_nonce: None, +// deposit_receipt_version: None, +// })); + +// // update add to total fees +// let miner_fee = tx +// .effective_tip_per_gas(base_fee) +// .expect("fee is always valid; execution succeeded"); +// info.total_fees += U256::from(miner_fee) * U256::from(gas_used); + +// // append sender and transaction to the respective lists +// info.executed_senders.push(tx.signer()); +// info.executed_transactions.push(tx.into_signed()); +// } + +// Ok(None) +// } +// } From fe17d65851e85f22891d95bee1eb822bc9d94b65 Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Fri, 13 Dec 2024 10:45:45 -0700 Subject: [PATCH 28/59] chore: fmt --- world-chain-builder/crates/world/bin/src/main.rs | 8 ++++++-- world-chain-builder/crates/world/rpc/src/lib.rs | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/world-chain-builder/crates/world/bin/src/main.rs b/world-chain-builder/crates/world/bin/src/main.rs index 7f87ef32..e774431e 100644 --- a/world-chain-builder/crates/world/bin/src/main.rs +++ b/world-chain-builder/crates/world/bin/src/main.rs @@ -36,10 +36,14 @@ fn main() { .extend_rpc_modules(move |ctx| { let provider = ctx.provider().clone(); let pool = ctx.pool().clone(); - let sequencer_client = builder_args.rollup_args.sequencer_http.map(SequencerClient::new); + let sequencer_client = builder_args + .rollup_args + .sequencer_http + .map(SequencerClient::new); let eth_api_ext = WorldChainEthApiExt::new(pool, provider, sequencer_client); // Remove the `eth_sendRawTransaction` method from the configured modules - ctx.modules.remove_method_from_configured(&"eth_sendRawTransaction"); + ctx.modules + .remove_method_from_configured(&"eth_sendRawTransaction"); // Merge the `eth_sendRawTransaction` and `eth_sendRawTransactionConditional` RPC methods ctx.modules.merge_configured(eth_api_ext.into_rpc())?; Ok(()) diff --git a/world-chain-builder/crates/world/rpc/src/lib.rs b/world-chain-builder/crates/world/rpc/src/lib.rs index a0b24f77..60666763 100644 --- a/world-chain-builder/crates/world/rpc/src/lib.rs +++ b/world-chain-builder/crates/world/rpc/src/lib.rs @@ -25,5 +25,5 @@ pub trait EthTransactionsExt { pub struct WorldChainEthApiExt { pool: Pool, client: Client, - sequencer_client: Option + sequencer_client: Option, } From f981763cdf7b0d8c8a87a697f0278e869033bb6e Mon Sep 17 00:00:00 2001 From: 0xKitsune <0xkitsune@protonmail.com> Date: Fri, 13 Dec 2024 12:56:54 -0500 Subject: [PATCH 29/59] payload attributes wip --- world-chain-builder/Cargo.lock | 1 + world-chain-builder/Cargo.toml | 1 + .../crates/world/payload/Cargo.toml | 1 + .../crates/world/payload/src/builder.rs | 396 +++++++----------- 4 files changed, 147 insertions(+), 252 deletions(-) diff --git a/world-chain-builder/Cargo.lock b/world-chain-builder/Cargo.lock index 4c44906a..ca1de20e 100644 --- a/world-chain-builder/Cargo.lock +++ b/world-chain-builder/Cargo.lock @@ -13758,6 +13758,7 @@ dependencies = [ "reth-optimism-consensus", "reth-optimism-node", "reth-optimism-payload-builder", + "reth-payload-util", "reth-primitives", "reth-provider", "reth-transaction-pool", diff --git a/world-chain-builder/Cargo.toml b/world-chain-builder/Cargo.toml index e8d3af86..9dbcc340 100644 --- a/world-chain-builder/Cargo.toml +++ b/world-chain-builder/Cargo.toml @@ -79,6 +79,7 @@ reth-optimism-consensus = { git = "https://github.com/paradigmxyz/reth", tag = " "optimism", ] } reth-optimism-chainspec = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } +reth_payload_util = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } reth-optimism-payload-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } reth-optimism-forks = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } reth-optimism-primitives = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.4" } diff --git a/world-chain-builder/crates/world/payload/Cargo.toml b/world-chain-builder/crates/world/payload/Cargo.toml index 117fd140..35706332 100644 --- a/world-chain-builder/crates/world/payload/Cargo.toml +++ b/world-chain-builder/crates/world/payload/Cargo.toml @@ -29,6 +29,7 @@ reth-provider.workspace = true reth-primitives.workspace = true reth-transaction-pool.workspace = true reth-trie.workspace = true +reth-payload-util.workspace = true # revm revm.workspace = true diff --git a/world-chain-builder/crates/world/payload/src/builder.rs b/world-chain-builder/crates/world/payload/src/builder.rs index fc3ac5dc..5324215b 100644 --- a/world-chain-builder/crates/world/payload/src/builder.rs +++ b/world-chain-builder/crates/world/payload/src/builder.rs @@ -1,4 +1,4 @@ -use alloy_consensus::EMPTY_OMMER_ROOT_HASH; +use alloy_consensus::{Transaction, EMPTY_OMMER_ROOT_HASH}; use alloy_eips::eip4895::Withdrawals; use alloy_eips::merge::BEACON_NONCE; use alloy_rpc_types_debug::ExecutionWitness; @@ -27,10 +27,11 @@ use reth_optimism_chainspec::OpChainSpec; use reth_optimism_consensus::calculate_receipt_root_no_memo_optimism; use reth_optimism_node::{OpBuiltPayload, OpPayloadBuilder, OpPayloadBuilderAttributes}; use reth_optimism_payload_builder::builder::{ - ExecutedPayload, OpBuilder, OpPayloadBuilderCtx, OpPayloadTransactions, + ExecutedPayload, ExecutionInfo, OpBuilder, OpPayloadBuilderCtx, OpPayloadTransactions, }; use reth_optimism_payload_builder::config::OpBuilderConfig; use reth_optimism_payload_builder::OpPayloadAttributes; +use reth_payload_util::PayloadTransactions; use reth_primitives::{proofs, BlockBody, BlockExt, SealedHeader, TransactionSigned}; use reth_primitives::{Block, Header, Receipt, TxType}; use reth_provider::{ @@ -41,7 +42,7 @@ use reth_provider::{ use reth_transaction_pool::{noop::NoopTransactionPool, pool::BestPayloadTransactions}; use reth_trie::HashedPostState; use revm::Database; -use revm_primitives::{calc_excess_blob_gas, Bytes, B256}; +use revm_primitives::{calc_excess_blob_gas, Bytes, TxEnv, B256}; use revm_primitives::{ BlockEnv, CfgEnvWithHandlerCfg, EVMError, EnvWithHandlerCfg, InvalidTransaction, ResultAndState, U256, @@ -350,7 +351,7 @@ where pub fn execute( self, state: &mut State, - ctx: &OpPayloadBuilderCtx, + ctx: &WorldChainPayloadBuilderCtx, ) -> Result, PayloadBuilderError> where EvmConfig: ConfigureEvm
, @@ -408,7 +409,7 @@ where pub fn build( self, mut state: State, - ctx: OpPayloadBuilderCtx, + ctx: WorldChainPayloadBuilderCtx, ) -> Result, PayloadBuilderError> where EvmConfig: ConfigureEvm
, @@ -435,7 +436,7 @@ where .generic_receipts_root_slow(block_number, |receipts| { calculate_receipt_root_no_memo_optimism( receipts, - &ctx.chain_spec, + &ctx.inner.chain_spec, ctx.attributes().timestamp(), ) }) @@ -471,7 +472,7 @@ where let header = Header { parent_hash: ctx.parent().hash(), ommers_hash: EMPTY_OMMER_ROOT_HASH, - beneficiary: ctx.initialized_block_env.coinbase, + beneficiary: ctx.inner.initialized_block_env.coinbase, state_root, transactions_root, receipts_root, @@ -521,8 +522,8 @@ where ctx.payload_id(), sealed_block, info.total_fees, - ctx.chain_spec.clone(), - ctx.config.attributes, + ctx.inner.chain_spec.clone(), + ctx.inner.config.attributes, Some(executed), ); @@ -540,7 +541,7 @@ where pub fn witness( self, state: &mut State, - ctx: &OpPayloadBuilderCtx, + ctx: &WorldChainPayloadBuilderCtx, ) -> Result where EvmConfig: ConfigureEvm
, @@ -680,245 +681,136 @@ impl WorldChainPayloadBuilderCtx { } } -// impl WorldChainPayloadBuilderCtx -// where -// EvmConfig: ConfigureEvm
, -// { -// /// apply eip-4788 pre block contract call -// pub fn apply_pre_beacon_root_contract_call( -// &self, -// db: &mut DB, -// ) -> Result<(), PayloadBuilderError> -// where -// DB: Database + DatabaseCommit, -// DB::Error: Display, -// { -// SystemCaller::new(self.evm_config.clone(), self.chain_spec.clone()) -// .pre_block_beacon_root_contract_call( -// db, -// &self.initialized_cfg, -// &self.initialized_block_env, -// self.attributes() -// .payload_attributes -// .parent_beacon_block_root, -// ) -// .map_err(|err| { -// warn!(target: "payload_builder", -// parent_header=%self.parent().hash(), -// %err, -// "failed to apply beacon root contract call for payload" -// ); -// PayloadBuilderError::Internal(err.into()) -// })?; - -// Ok(()) -// } - -// /// Executes all sequencer transactions that are included in the payload attributes. -// pub fn execute_sequencer_transactions( -// &self, -// db: &mut State, -// ) -> Result -// where -// DB: Database, -// { -// let mut info = ExecutionInfo::with_capacity(self.attributes().transactions.len()); - -// let env = EnvWithHandlerCfg::new_with_cfg_env( -// self.initialized_cfg.clone(), -// self.initialized_block_env.clone(), -// TxEnv::default(), -// ); -// let mut evm = self.evm_config.evm_with_env(&mut *db, env); - -// for sequencer_tx in &self.attributes().transactions { -// // A sequencer's block should never contain blob transactions. -// if sequencer_tx.value().is_eip4844() { -// return Err(PayloadBuilderError::other( -// OpPayloadBuilderError::BlobTransactionRejected, -// )); -// } - -// // Convert the transaction to a [RecoveredTx]. This is -// // purely for the purposes of utilizing the `evm_config.tx_env`` function. -// // Deposit transactions do not have signatures, so if the tx is a deposit, this -// // will just pull in its `from` address. -// let sequencer_tx = sequencer_tx -// .value() -// .clone() -// .try_into_ecrecovered() -// .map_err(|_| { -// PayloadBuilderError::other(OpPayloadBuilderError::TransactionEcRecoverFailed) -// })?; - -// // Cache the depositor account prior to the state transition for the deposit nonce. -// // -// // Note that this *only* needs to be done post-regolith hardfork, as deposit nonces -// // were not introduced in Bedrock. In addition, regular transactions don't have deposit -// // nonces, so we don't need to touch the DB for those. -// let depositor = (self.is_regolith_active() && sequencer_tx.is_deposit()) -// .then(|| { -// evm.db_mut() -// .load_cache_account(sequencer_tx.signer()) -// .map(|acc| acc.account_info().unwrap_or_default()) -// }) -// .transpose() -// .map_err(|_| { -// PayloadBuilderError::other(OpPayloadBuilderError::AccountLoadFailed( -// sequencer_tx.signer(), -// )) -// })?; - -// *evm.tx_mut() = self -// .evm_config -// .tx_env(sequencer_tx.as_signed(), sequencer_tx.signer()); - -// let ResultAndState { result, state } = match evm.transact() { -// Ok(res) => res, -// Err(err) => { -// match err { -// EVMError::Transaction(err) => { -// trace!(target: "payload_builder", %err, ?sequencer_tx, "Error in sequencer transaction, skipping."); -// continue; -// } -// err => { -// // this is an error that we should treat as fatal for this attempt -// return Err(PayloadBuilderError::EvmExecutionError(err)); -// } -// } -// } -// }; - -// // commit changes -// evm.db_mut().commit(state); - -// let gas_used = result.gas_used(); - -// // add gas used by the transaction to cumulative gas used, before creating the receipt -// info.cumulative_gas_used += gas_used; - -// // Push transaction changeset and calculate header bloom filter for receipt. -// info.receipts.push(Some(Receipt { -// tx_type: sequencer_tx.tx_type(), -// success: result.is_success(), -// cumulative_gas_used: info.cumulative_gas_used, -// logs: result.into_logs().into_iter().map(Into::into).collect(), -// deposit_nonce: depositor.map(|account| account.nonce), -// // The deposit receipt version was introduced in Canyon to indicate an update to how -// // receipt hashes should be computed when set. The state transition process -// // ensures this is only set for post-Canyon deposit transactions. -// deposit_receipt_version: self.is_canyon_active().then_some(1), -// })); - -// // append sender and transaction to the respective lists -// info.executed_senders.push(sequencer_tx.signer()); -// info.executed_transactions.push(sequencer_tx.into_signed()); -// } - -// Ok(info) -// } - -// /// Executes the given best transactions and updates the execution info. -// /// -// /// Returns `Ok(Some(())` if the job was cancelled. -// pub fn execute_best_transactions( -// &self, -// info: &mut ExecutionInfo, -// db: &mut State, -// mut best_txs: impl PayloadTransactions, -// ) -> Result, PayloadBuilderError> -// where -// DB: Database, -// { -// let block_gas_limit = self.block_gas_limit(); -// let base_fee = self.base_fee(); - -// let env = EnvWithHandlerCfg::new_with_cfg_env( -// self.initialized_cfg.clone(), -// self.initialized_block_env.clone(), -// TxEnv::default(), -// ); -// let mut evm = self.evm_config.evm_with_env(&mut *db, env); - -// while let Some(tx) = best_txs.next(()) { -// // ensure we still have capacity for this transaction -// if info.cumulative_gas_used + tx.gas_limit() > block_gas_limit { -// // we can't fit this transaction into the block, so we need to mark it as -// // invalid which also removes all dependent transaction from -// // the iterator before we can continue -// best_txs.mark_invalid(tx.signer(), tx.nonce()); -// continue; -// } - -// // A sequencer's block should never contain blob or deposit transactions from the pool. -// if tx.is_eip4844() || tx.tx_type() == TxType::Deposit as u8 { -// best_txs.mark_invalid(tx.signer(), tx.nonce()); -// continue; -// } - -// // check if the job was cancelled, if so we can exit early -// if self.cancel.is_cancelled() { -// return Ok(Some(())); -// } - -// // Configure the environment for the tx. -// *evm.tx_mut() = self.evm_config.tx_env(tx.as_signed(), tx.signer()); - -// let ResultAndState { result, state } = match evm.transact() { -// Ok(res) => res, -// Err(err) => { -// match err { -// EVMError::Transaction(err) => { -// if matches!(err, InvalidTransaction::NonceTooLow { .. }) { -// // if the nonce is too low, we can skip this transaction -// trace!(target: "payload_builder", %err, ?tx, "skipping nonce too low transaction"); -// } else { -// // if the transaction is invalid, we can skip it and all of its -// // descendants -// trace!(target: "payload_builder", %err, ?tx, "skipping invalid transaction and its descendants"); -// best_txs.mark_invalid(tx.signer(), tx.nonce()); -// } - -// continue; -// } -// err => { -// // this is an error that we should treat as fatal for this attempt -// return Err(PayloadBuilderError::EvmExecutionError(err)); -// } -// } -// } -// }; - -// // commit changes -// evm.db_mut().commit(state); - -// let gas_used = result.gas_used(); - -// // add gas used by the transaction to cumulative gas used, before creating the -// // receipt -// info.cumulative_gas_used += gas_used; - -// // Push transaction changeset and calculate header bloom filter for receipt. -// info.receipts.push(Some(Receipt { -// tx_type: tx.tx_type(), -// success: result.is_success(), -// cumulative_gas_used: info.cumulative_gas_used, -// logs: result.into_logs().into_iter().map(Into::into).collect(), -// deposit_nonce: None, -// deposit_receipt_version: None, -// })); - -// // update add to total fees -// let miner_fee = tx -// .effective_tip_per_gas(base_fee) -// .expect("fee is always valid; execution succeeded"); -// info.total_fees += U256::from(miner_fee) * U256::from(gas_used); - -// // append sender and transaction to the respective lists -// info.executed_senders.push(tx.signer()); -// info.executed_transactions.push(tx.into_signed()); -// } - -// Ok(None) -// } -// } +impl WorldChainPayloadBuilderCtx +where + EvmConfig: ConfigureEvm
, +{ + /// apply eip-4788 pre block contract call + pub fn apply_pre_beacon_root_contract_call( + &self, + db: &mut DB, + ) -> Result<(), PayloadBuilderError> + where + DB: Database + DatabaseCommit, + DB::Error: Display, + { + self.inner.apply_pre_beacon_root_contract_call(db) + } + + /// Executes all sequencer transactions that are included in the payload attributes. + pub fn execute_sequencer_transactions( + &self, + db: &mut State, + ) -> Result + where + DB: Database, + { + self.inner.execute_sequencer_transactions(db) + } + + /// Executes the given best transactions and updates the execution info. + /// + /// Returns `Ok(Some(())` if the job was cancelled. + + // TODO: PBH + pub fn execute_best_transactions( + &self, + info: &mut ExecutionInfo, + db: &mut State, + mut best_txs: impl PayloadTransactions, + ) -> Result, PayloadBuilderError> + where + DB: Database, + { + let block_gas_limit = self.block_gas_limit(); + let base_fee = self.base_fee(); + + let env = EnvWithHandlerCfg::new_with_cfg_env( + self.inner.initialized_cfg.clone(), + self.inner.initialized_block_env.clone(), + TxEnv::default(), + ); + let mut evm = self.inner.evm_config.evm_with_env(&mut *db, env); + + while let Some(tx) = best_txs.next(()) { + // ensure we still have capacity for this transaction + if info.cumulative_gas_used + tx.gas_limit() > block_gas_limit { + // we can't fit this transaction into the block, so we need to mark it as + // invalid which also removes all dependent transaction from + // the iterator before we can continue + best_txs.mark_invalid(tx.signer(), tx.nonce()); + continue; + } + + // A sequencer's block should never contain blob or deposit transactions from the pool. + if tx.is_eip4844() || tx.tx_type() == TxType::Deposit as u8 { + best_txs.mark_invalid(tx.signer(), tx.nonce()); + continue; + } + + // check if the job was cancelled, if so we can exit early + if self.inner.cancel.is_cancelled() { + return Ok(Some(())); + } + + // Configure the environment for the tx. + *evm.tx_mut() = self.inner.evm_config.tx_env(tx.as_signed(), tx.signer()); + + let ResultAndState { result, state } = match evm.transact() { + Ok(res) => res, + Err(err) => { + match err { + EVMError::Transaction(err) => { + if matches!(err, InvalidTransaction::NonceTooLow { .. }) { + // if the nonce is too low, we can skip this transaction + trace!(target: "payload_builder", %err, ?tx, "skipping nonce too low transaction"); + } else { + // if the transaction is invalid, we can skip it and all of its + // descendants + trace!(target: "payload_builder", %err, ?tx, "skipping invalid transaction and its descendants"); + best_txs.mark_invalid(tx.signer(), tx.nonce()); + } + + continue; + } + err => { + // this is an error that we should treat as fatal for this attempt + return Err(PayloadBuilderError::EvmExecutionError(err)); + } + } + } + }; + + // commit changes + evm.db_mut().commit(state); + + let gas_used = result.gas_used(); + + // add gas used by the transaction to cumulative gas used, before creating the + // receipt + info.cumulative_gas_used += gas_used; + + // Push transaction changeset and calculate header bloom filter for receipt. + info.receipts.push(Some(Receipt { + tx_type: tx.tx_type(), + success: result.is_success(), + cumulative_gas_used: info.cumulative_gas_used, + logs: result.into_logs().into_iter().map(Into::into).collect(), + deposit_nonce: None, + deposit_receipt_version: None, + })); + + // update add to total fees + let miner_fee = tx + .effective_tip_per_gas(base_fee) + .expect("fee is always valid; execution succeeded"); + info.total_fees += U256::from(miner_fee) * U256::from(gas_used); + + // append sender and transaction to the respective lists + info.executed_senders.push(tx.signer()); + info.executed_transactions.push(tx.into_signed()); + } + + Ok(None) + } +} From c16640d445adb70ba54434bddcbc59d6d34d1828 Mon Sep 17 00:00:00 2001 From: 0xKitsune <0xkitsune@protonmail.com> Date: Fri, 13 Dec 2024 13:00:04 -0500 Subject: [PATCH 30/59] Update builder ctx types --- .../crates/world/payload/src/builder.rs | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/world-chain-builder/crates/world/payload/src/builder.rs b/world-chain-builder/crates/world/payload/src/builder.rs index 5324215b..61162bfe 100644 --- a/world-chain-builder/crates/world/payload/src/builder.rs +++ b/world-chain-builder/crates/world/payload/src/builder.rs @@ -163,14 +163,16 @@ where best_payload, } = args; - let ctx = OpPayloadBuilderCtx { - evm_config: self.inner.evm_config.clone(), - chain_spec: client.chain_spec(), - config, - initialized_cfg, - initialized_block_env, - cancel, - best_payload, + let ctx = WorldChainPayloadBuilderCtx { + inner: OpPayloadBuilderCtx { + evm_config: self.inner.evm_config.clone(), + chain_spec: client.chain_spec(), + config, + initialized_cfg, + initialized_block_env, + cancel, + best_payload, + }, }; let builder = WorldChainBuilder { @@ -244,14 +246,16 @@ where extra_data: Default::default(), }; - let ctx = OpPayloadBuilderCtx { - evm_config: self.inner.evm_config.clone(), - chain_spec: client.chain_spec(), - config, - initialized_cfg, - initialized_block_env, - cancel: Default::default(), - best_payload: Default::default(), + let ctx = WorldChainPayloadBuilderCtx { + inner: OpPayloadBuilderCtx { + evm_config: self.inner.evm_config.clone(), + chain_spec: client.chain_spec(), + config, + initialized_cfg, + initialized_block_env, + cancel: Default::default(), + best_payload: Default::default(), + }, }; let state_provider = client.state_by_block_hash(ctx.parent().hash())?; From 0785f813c34f2a7fb769f3b63bd4a618a9ed2bbc Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Fri, 13 Dec 2024 11:11:02 -0700 Subject: [PATCH 31/59] feat: conditionally forward transactions --- world-chain-builder/Cargo.lock | 2 + .../crates/world/bin/src/main.rs | 5 +- .../crates/world/rpc/Cargo.toml | 4 +- .../crates/world/rpc/src/eth.rs | 29 ++-- .../crates/world/rpc/src/lib.rs | 5 +- .../crates/world/rpc/src/sequencer.rs | 131 ++++++++++++++++++ 6 files changed, 157 insertions(+), 19 deletions(-) create mode 100644 world-chain-builder/crates/world/rpc/src/sequencer.rs diff --git a/world-chain-builder/Cargo.lock b/world-chain-builder/Cargo.lock index 0738b9f1..65f76104 100644 --- a/world-chain-builder/Cargo.lock +++ b/world-chain-builder/Cargo.lock @@ -13839,10 +13839,12 @@ dependencies = [ "alloy-primitives", "alloy-rpc-types", "jsonrpsee", + "reqwest 0.12.9", "reth", "reth-optimism-rpc", "reth-provider", "revm-primitives", + "serde_json", "tracing", "world-chain-builder-pool", ] diff --git a/world-chain-builder/crates/world/bin/src/main.rs b/world-chain-builder/crates/world/bin/src/main.rs index e774431e..8102348d 100644 --- a/world-chain-builder/crates/world/bin/src/main.rs +++ b/world-chain-builder/crates/world/bin/src/main.rs @@ -1,10 +1,11 @@ use clap::Parser; use reth_optimism_cli::chainspec::OpChainSpecParser; use reth_optimism_cli::Cli; -use reth_optimism_rpc::SequencerClient; use world_chain_builder_node::args::ExtArgs; use world_chain_builder_node::node::WorldChainBuilder; -use world_chain_builder_rpc::{EthTransactionsExtServer, WorldChainEthApiExt}; +use world_chain_builder_rpc::{ + sequencer::SequencerClient, EthTransactionsExtServer, WorldChainEthApiExt, +}; #[cfg(all(feature = "jemalloc", unix))] #[global_allocator] diff --git a/world-chain-builder/crates/world/rpc/Cargo.toml b/world-chain-builder/crates/world/rpc/Cargo.toml index 6e8e6e78..d430fbb7 100644 --- a/world-chain-builder/crates/world/rpc/Cargo.toml +++ b/world-chain-builder/crates/world/rpc/Cargo.toml @@ -25,5 +25,7 @@ alloy-primitives.workspace = true alloy-rpc-types.workspace = true jsonrpsee.workspace = true - tracing.workspace = true +reqwest.workspace = true +serde_json.workspace = true + diff --git a/world-chain-builder/crates/world/rpc/src/eth.rs b/world-chain-builder/crates/world/rpc/src/eth.rs index 8d9d93bc..9f77c73e 100644 --- a/world-chain-builder/crates/world/rpc/src/eth.rs +++ b/world-chain-builder/crates/world/rpc/src/eth.rs @@ -11,12 +11,11 @@ use reth::{ rpc::server_types::eth::utils::recover_raw_transaction, transaction_pool::{EthPooledTransaction, PoolTransaction, TransactionOrigin, TransactionPool}, }; -use reth_optimism_rpc::SequencerClient; use reth_provider::{BlockReaderIdExt, StateProviderFactory}; use revm_primitives::{map::FbBuildHasher, Address, Bytes, FixedBytes, B256}; use world_chain_builder_pool::tx::WorldChainPooledTransaction; -use crate::{EthTransactionsExtServer, WorldChainEthApiExt}; +use crate::{sequencer::SequencerClient, EthTransactionsExtServer, WorldChainEthApiExt}; #[async_trait] impl EthTransactionsExtServer for WorldChainEthApiExt @@ -34,7 +33,7 @@ where let recovered = recover_raw_transaction(&tx)?; let mut pool_transaction: WorldChainPooledTransaction = EthPooledTransaction::from_pooled(recovered).into(); - pool_transaction.conditional_options = Some(options); + pool_transaction.conditional_options = Some(options.clone()); // submit the transaction to the pool with a `Local` origin let hash = self @@ -43,7 +42,12 @@ where .await .map_err(|_| ErrorObjectOwned::from(ErrorCode::InternalError))?; - self.maybe_forward_raw_transaction(tx, hash).await?; + if let Some(client) = self.raw_tx_forwarder().as_ref() { + tracing::debug!( target: "rpc::eth", "forwarding raw conditional transaction to"); + let _ = client.forward_raw_transaction_conditional(&tx, options).await.inspect_err(|err| { + tracing::debug!(target: "rpc::eth", %err, hash=?*hash, "failed to forward raw conditional transaction"); + }); + } Ok(hash) } @@ -59,7 +63,12 @@ where .await .map_err(|_| ErrorObjectOwned::from(ErrorCode::InternalError))?; - self.maybe_forward_raw_transaction(tx, hash).await?; + if let Some(client) = self.raw_tx_forwarder().as_ref() { + tracing::debug!( target: "rpc::eth", "forwarding raw transaction to"); + let _ = client.forward_raw_transaction(&tx).await.inspect_err(|err| { + tracing::debug!(target: "rpc::eth", %err, hash=?*hash, "failed to forward raw transaction"); + }); + } Ok(hash) } } @@ -88,16 +97,6 @@ where pub fn raw_tx_forwarder(&self) -> Option<&SequencerClient> { self.sequencer_client.as_ref() } - - async fn maybe_forward_raw_transaction(&self, tx: Bytes, hash: B256) -> RpcResult<()> { - if let Some(client) = self.raw_tx_forwarder().as_ref() { - tracing::debug!( target: "rpc::eth", "forwarding raw transaction to"); - let _ = client.forward_raw_transaction(&tx).await.inspect_err(|err| { - tracing::debug!(target: "rpc::eth", %err, hash=?*hash, "failed to forward raw transaction"); - }); - } - Ok(()) - } } /// Validates the conditional inclusion options provided by the client. diff --git a/world-chain-builder/crates/world/rpc/src/lib.rs b/world-chain-builder/crates/world/rpc/src/lib.rs index 60666763..757ed4d1 100644 --- a/world-chain-builder/crates/world/rpc/src/lib.rs +++ b/world-chain-builder/crates/world/rpc/src/lib.rs @@ -1,8 +1,11 @@ use alloy_primitives::{Bytes, B256}; use alloy_rpc_types::erc4337::ConditionalOptions; use jsonrpsee::{core::RpcResult, proc_macros::rpc}; -use reth_optimism_rpc::SequencerClient; + +use crate::sequencer::SequencerClient; + pub mod eth; +pub mod sequencer; /// Trait interface for EthApi Extension #[cfg_attr(not(test), rpc(server, namespace = "eth"))] diff --git a/world-chain-builder/crates/world/rpc/src/sequencer.rs b/world-chain-builder/crates/world/rpc/src/sequencer.rs new file mode 100644 index 00000000..7cc105b6 --- /dev/null +++ b/world-chain-builder/crates/world/rpc/src/sequencer.rs @@ -0,0 +1,131 @@ +use alloy_primitives::hex; +use alloy_rpc_types::erc4337::ConditionalOptions; +use reqwest::Client; +use reth_optimism_rpc::SequencerClientError; +use serde_json::json; +use std::sync::{ + atomic::{self, AtomicUsize}, + Arc, +}; +use tracing::warn; + +/// A client to interact with a Sequencer +#[derive(Debug, Clone)] +pub struct SequencerClient { + inner: Arc, +} + +impl SequencerClient { + /// Creates a new [`SequencerClient`]. + pub fn new(sequencer_endpoint: impl Into) -> Self { + let client = Client::builder().use_rustls_tls().build().unwrap(); + Self::with_client(sequencer_endpoint, client) + } + + /// Creates a new [`SequencerClient`]. + pub fn with_client(sequencer_endpoint: impl Into, http_client: Client) -> Self { + let inner = SequencerClientInner { + sequencer_endpoint: sequencer_endpoint.into(), + http_client, + id: AtomicUsize::new(0), + }; + Self { + inner: Arc::new(inner), + } + } + + /// Returns the network of the client + pub fn endpoint(&self) -> &str { + &self.inner.sequencer_endpoint + } + + /// Returns the client + pub fn http_client(&self) -> &Client { + &self.inner.http_client + } + + /// Returns the next id for the request + fn next_request_id(&self) -> usize { + self.inner.id.fetch_add(1, atomic::Ordering::SeqCst) + } + + /// Forwards a transaction to the sequencer endpoint. + pub async fn forward_raw_transaction(&self, tx: &[u8]) -> Result<(), SequencerClientError> { + let body = serde_json::to_string(&json!({ + "jsonrpc": "2.0", + "method": "eth_sendRawTransaction", + "params": [format!("0x{}", hex::encode(tx))], + "id": self.next_request_id() + })) + .map_err(|_| { + warn!( + target = "rpc::eth", + "Failed to serialize transaction for forwarding to sequencer" + ); + SequencerClientError::InvalidSequencerTransaction + })?; + + self.http_client() + .post(self.endpoint()) + .header(reqwest::header::CONTENT_TYPE, "application/json") + .body(body) + .send() + .await + .inspect_err(|err| { + warn!( + target = "rpc::eth", + %err, + "Failed to forward transaction to sequencer", + ); + })?; + + Ok(()) + } + + /// Forwards a transaction to the sequencer endpoint. + pub async fn forward_raw_transaction_conditional( + &self, + tx: &[u8], + options: ConditionalOptions, + ) -> Result<(), SequencerClientError> { + let body = serde_json::to_string(&json!({ + "jsonrpc": "2.0", + "method": "eth_sendRawTransactionConditional", + "params": [format!("0x{}", hex::encode(tx)), options], + "id": self.next_request_id() + })) + .map_err(|_| { + warn!( + target = "rpc::eth", + "Failed to serialize transaction for forwarding to sequencer" + ); + SequencerClientError::InvalidSequencerTransaction + })?; + + self.http_client() + .post(self.endpoint()) + .header(reqwest::header::CONTENT_TYPE, "application/json") + .body(body) + .send() + .await + .inspect_err(|err| { + warn!( + target = "rpc::eth", + %err, + "Failed to forward transaction to sequencer", + ); + })?; + + Ok(()) + } +} + +#[derive(Debug, Default)] +struct SequencerClientInner { + /// The endpoint of the sequencer + sequencer_endpoint: String, + /// The HTTP client + http_client: Client, + /// Keeps track of unique request ids + id: AtomicUsize, +} From a0a827c48b9ff8db77404c6fb0e4f105bc4c9c52 Mon Sep 17 00:00:00 2001 From: 0xKitsune <0xkitsune@protonmail.com> Date: Fri, 13 Dec 2024 13:27:06 -0500 Subject: [PATCH 32/59] pbh wip --- .../crates/world/payload/src/builder.rs | 24 ++++++++++++++++++- .../crates/world/pool/src/tx.rs | 2 -- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/world-chain-builder/crates/world/payload/src/builder.rs b/world-chain-builder/crates/world/payload/src/builder.rs index 202ce2d0..e2e455a9 100644 --- a/world-chain-builder/crates/world/payload/src/builder.rs +++ b/world-chain-builder/crates/world/payload/src/builder.rs @@ -173,6 +173,7 @@ where cancel, best_payload, }, + verified_blockspace_capacity: self.verified_blockspace_capacity, }; let builder = WorldChainBuilder { @@ -256,6 +257,7 @@ where cancel: Default::default(), best_payload: Default::default(), }, + verified_blockspace_capacity: self.verified_blockspace_capacity, }; let state_provider = client.state_by_block_hash(ctx.parent().hash())?; @@ -574,6 +576,7 @@ where #[derive(Debug)] pub struct WorldChainPayloadBuilderCtx { pub inner: OpPayloadBuilderCtx, + pub verified_blockspace_capacity: u8, } impl WorldChainPayloadBuilderCtx { @@ -721,7 +724,8 @@ where &self, info: &mut ExecutionInfo, db: &mut State, - mut best_txs: impl PayloadTransactions, + mut best_txs: impl PayloadTransactions + + WorldChainPoolTransaction, ) -> Result, PayloadBuilderError> where DB: Database, @@ -736,7 +740,25 @@ where ); let mut evm = self.inner.evm_config.evm_with_env(&mut *db, env); + let mut invalid_txs = vec![]; + let verified_gas_limit = (self.verified_blockspace_capacity as u64 * block_gas_limit) / 100; while let Some(tx) = best_txs.next(()) { + if let Some(conditional_options) = tx.transaction.conditional_options() { + if let Err(_) = validate_conditional_options(conditional_options, &client) { + best_txs.mark_invalid(tx.signer(), tx.nonce()); + invalid_txs.push(tx.hash().clone()); + continue; + } + } + + // If the transaction is verified, check if it can be added within the verified gas limit + if tx.transaction.pbh_payload().is_some() + && info.cumulative_gas_used + tx.gas_limit() > verified_gas_limit + { + best_txs.mark_invalid(tx.signer(), tx.nonce()); + continue; + } + // ensure we still have capacity for this transaction if info.cumulative_gas_used + tx.gas_limit() > block_gas_limit { // we can't fit this transaction into the block, so we need to mark it as diff --git a/world-chain-builder/crates/world/pool/src/tx.rs b/world-chain-builder/crates/world/pool/src/tx.rs index b63f05b9..758f8f60 100644 --- a/world-chain-builder/crates/world/pool/src/tx.rs +++ b/world-chain-builder/crates/world/pool/src/tx.rs @@ -18,8 +18,6 @@ use reth_primitives::{ }; use revm_primitives::{AccessList, Address, KzgSettings, TxKind, U256}; -use world_chain_builder_pbh::payload::PbhPayload; - pub trait WorldChainPoolTransaction: EthPoolTransaction { fn valid_pbh(&self) -> bool; fn conditional_options(&self) -> Option<&ConditionalOptions>; From ef9ce8ed19680e7b0204043ce38468a4fee158cf Mon Sep 17 00:00:00 2001 From: 0xKitsune <0xkitsune@protonmail.com> Date: Fri, 13 Dec 2024 13:51:47 -0500 Subject: [PATCH 33/59] wip --- .../crates/world/payload/src/builder.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/world-chain-builder/crates/world/payload/src/builder.rs b/world-chain-builder/crates/world/payload/src/builder.rs index e2e455a9..daca48e4 100644 --- a/world-chain-builder/crates/world/payload/src/builder.rs +++ b/world-chain-builder/crates/world/payload/src/builder.rs @@ -50,6 +50,7 @@ use revm_primitives::{ use std::fmt::Display; use std::sync::Arc; use tracing::{debug, trace, warn}; +use world_chain_builder_pool::tx::WorldChainPooledTransaction; use world_chain_builder_pool::noop::NoopWorldChainTransactionPool; use world_chain_builder_pool::tx::WorldChainPoolTransaction; @@ -148,7 +149,8 @@ where ) -> Result, PayloadBuilderError> where Client: StateProviderFactory + ChainSpecProvider, - Pool: TransactionPool>, + Pool: + TransactionPool>, { let (initialized_cfg, initialized_block_env) = self .cfg_and_block_env(&args.config.attributes, &args.config.parent_header) @@ -280,7 +282,7 @@ impl PayloadBuilder for WorldChainPayloadBuilder where Client: StateProviderFactory + ChainSpecProvider, - Pool: TransactionPool>, + Pool: TransactionPool>, EvmConfig: ConfigureEvm
, Txs: OpPayloadTransactions, { @@ -350,7 +352,7 @@ pub struct WorldChainBuilder { impl WorldChainBuilder where - Pool: TransactionPool>, + Pool: TransactionPool>, Txs: OpPayloadTransactions, { /// Executes the payload and returns the outcome. @@ -724,8 +726,7 @@ where &self, info: &mut ExecutionInfo, db: &mut State, - mut best_txs: impl PayloadTransactions - + WorldChainPoolTransaction, + mut best_txs: impl PayloadTransactions, ) -> Result, PayloadBuilderError> where DB: Database, From 8e372a7d238bdfa932baa273594b2d8c77ca20bb Mon Sep 17 00:00:00 2001 From: 0xKitsune <0xkitsune@protonmail.com> Date: Fri, 13 Dec 2024 13:58:38 -0500 Subject: [PATCH 34/59] wip --- world-chain-builder/crates/world/payload/src/builder.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/world-chain-builder/crates/world/payload/src/builder.rs b/world-chain-builder/crates/world/payload/src/builder.rs index daca48e4..baddc446 100644 --- a/world-chain-builder/crates/world/payload/src/builder.rs +++ b/world-chain-builder/crates/world/payload/src/builder.rs @@ -50,9 +50,9 @@ use revm_primitives::{ use std::fmt::Display; use std::sync::Arc; use tracing::{debug, trace, warn}; +use world_chain_builder_pool::noop::NoopWorldChainTransactionPool; use world_chain_builder_pool::tx::WorldChainPooledTransaction; -use world_chain_builder_pool::noop::NoopWorldChainTransactionPool; use world_chain_builder_pool::tx::WorldChainPoolTransaction; use world_chain_builder_rpc::eth::validate_conditional_options; @@ -270,7 +270,7 @@ where .build(); let builder = WorldChainBuilder { - pool: NoopTransactionPool::default(), + pool: NoopWorldChainTransactionPool::default(), best: (), }; builder.witness(&mut state, &ctx) @@ -316,7 +316,7 @@ where client, config, // we use defaults here because for the empty payload we don't need to execute anything - pool: NoopTransactionPool::default(), + pool: NoopWorldChainTransactionPool::default(), cached_reads: Default::default(), cancel: Default::default(), best_payload: None, From 6080b6667dea1a4e950324c7df7507a3cfca8f41 Mon Sep 17 00:00:00 2001 From: 0xKitsune <0xkitsune@protonmail.com> Date: Fri, 13 Dec 2024 14:04:24 -0500 Subject: [PATCH 35/59] wip --- .../crates/world/payload/src/builder.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/world-chain-builder/crates/world/payload/src/builder.rs b/world-chain-builder/crates/world/payload/src/builder.rs index baddc446..857d3a78 100644 --- a/world-chain-builder/crates/world/payload/src/builder.rs +++ b/world-chain-builder/crates/world/payload/src/builder.rs @@ -720,13 +720,11 @@ where /// Executes the given best transactions and updates the execution info. /// /// Returns `Ok(Some(())` if the job was cancelled. - - // TODO: PBH pub fn execute_best_transactions( &self, info: &mut ExecutionInfo, db: &mut State, - mut best_txs: impl PayloadTransactions, + mut best_txs: impl PayloadTransactions, ) -> Result, PayloadBuilderError> where DB: Database, @@ -744,8 +742,8 @@ where let mut invalid_txs = vec![]; let verified_gas_limit = (self.verified_blockspace_capacity as u64 * block_gas_limit) / 100; while let Some(tx) = best_txs.next(()) { - if let Some(conditional_options) = tx.transaction.conditional_options() { - if let Err(_) = validate_conditional_options(conditional_options, &client) { + if let Some(conditional_options) = tx.conditional_options { + if let Err(_) = validate_conditional_options(&conditional_options, &client) { best_txs.mark_invalid(tx.signer(), tx.nonce()); invalid_txs.push(tx.hash().clone()); continue; @@ -753,9 +751,7 @@ where } // If the transaction is verified, check if it can be added within the verified gas limit - if tx.transaction.pbh_payload().is_some() - && info.cumulative_gas_used + tx.gas_limit() > verified_gas_limit - { + if tx.valid_pbh && info.cumulative_gas_used + tx.gas_limit() > verified_gas_limit { best_txs.mark_invalid(tx.signer(), tx.nonce()); continue; } @@ -781,7 +777,10 @@ where } // Configure the environment for the tx. - *evm.tx_mut() = self.inner.evm_config.tx_env(tx.as_signed(), tx.signer()); + *evm.tx_mut() = self + .inner + .evm_config + .tx_env(tx.inner.transaction().as_signed(), tx.signer()); let ResultAndState { result, state } = match evm.transact() { Ok(res) => res, From 5177e1fe2723a8266e22bb69e3fefaa51ba69d83 Mon Sep 17 00:00:00 2001 From: 0xKitsune <0xkitsune@protonmail.com> Date: Fri, 13 Dec 2024 14:05:41 -0500 Subject: [PATCH 36/59] wip --- world-chain-builder/crates/world/payload/src/builder.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/world-chain-builder/crates/world/payload/src/builder.rs b/world-chain-builder/crates/world/payload/src/builder.rs index 857d3a78..a76eef2a 100644 --- a/world-chain-builder/crates/world/payload/src/builder.rs +++ b/world-chain-builder/crates/world/payload/src/builder.rs @@ -818,7 +818,7 @@ where // Push transaction changeset and calculate header bloom filter for receipt. info.receipts.push(Some(Receipt { - tx_type: tx.tx_type(), + tx_type: tx.inner.transaction().tx_type(), success: result.is_success(), cumulative_gas_used: info.cumulative_gas_used, logs: result.into_logs().into_iter().map(Into::into).collect(), @@ -834,7 +834,8 @@ where // append sender and transaction to the respective lists info.executed_senders.push(tx.signer()); - info.executed_transactions.push(tx.into_signed()); + info.executed_transactions + .push(tx.inner.transaction().into_signed()); } Ok(None) From 9ad0569710cca44c199b4bb2b23892a0c917e4bb Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Fri, 13 Dec 2024 15:16:28 -0700 Subject: [PATCH 37/59] fix: BestTransactions iterator --- .../crates/world/payload/src/builder.rs | 53 +++++++++++++------ 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/world-chain-builder/crates/world/payload/src/builder.rs b/world-chain-builder/crates/world/payload/src/builder.rs index a76eef2a..b3890015 100644 --- a/world-chain-builder/crates/world/payload/src/builder.rs +++ b/world-chain-builder/crates/world/payload/src/builder.rs @@ -32,14 +32,18 @@ use reth_optimism_payload_builder::builder::{ use reth_optimism_payload_builder::config::OpBuilderConfig; use reth_optimism_payload_builder::OpPayloadAttributes; use reth_payload_util::PayloadTransactions; -use reth_primitives::{proofs, BlockBody, BlockExt, SealedHeader, TransactionSigned}; +use reth_primitives::{ + proofs, BlockBody, BlockExt, InvalidTransactionError, SealedHeader, TransactionSigned, +}; use reth_primitives::{Block, Header, Receipt, TxType}; use reth_provider::{ BlockReaderIdExt, CanonStateSubscriptions, ChainSpecProvider, ExecutionOutcome, HashedPostStateProvider, ProviderError, StateProofProvider, StateProviderFactory, StateRootProvider, }; +use reth_transaction_pool::error::{InvalidPoolTransactionError, PoolTransactionError}; use reth_transaction_pool::{noop::NoopTransactionPool, pool::BestPayloadTransactions}; +use reth_transaction_pool::{BestTransactions, ValidPoolTransaction}; use reth_trie::HashedPostState; use revm::Database; use revm_primitives::{calc_excess_blob_gas, Bytes, TxEnv, B256}; @@ -380,8 +384,8 @@ where // 4. if mem pool transactions are requested we execute them if !ctx.attributes().no_tx_pool { //TODO: build pbh payload + let best_txs= pool.best_transactions_with_attributes(ctx.best_transaction_attributes()); - let best_txs = best.best_transactions(pool, ctx.best_transaction_attributes()); if ctx .execute_best_transactions::<_, Pool>(&mut info, state, best_txs)? .is_some() @@ -724,10 +728,16 @@ where &self, info: &mut ExecutionInfo, db: &mut State, - mut best_txs: impl PayloadTransactions, + mut best_txs: Box< + dyn BestTransactions< + Item = Arc::Transaction>>, + >, + >, ) -> Result, PayloadBuilderError> where DB: Database, + Pool: + TransactionPool>, { let block_gas_limit = self.block_gas_limit(); let base_fee = self.base_fee(); @@ -741,18 +751,22 @@ where let mut invalid_txs = vec![]; let verified_gas_limit = (self.verified_blockspace_capacity as u64 * block_gas_limit) / 100; - while let Some(tx) = best_txs.next(()) { - if let Some(conditional_options) = tx.conditional_options { + while let Some(tx) = best_txs.next() { + let pooled_tx = tx.transaction; + let consensus_tx = tx.to_consensus(); + if let Some(conditional_options) = pooled_tx.conditional_options() { if let Err(_) = validate_conditional_options(&conditional_options, &client) { - best_txs.mark_invalid(tx.signer(), tx.nonce()); + best_txs.mark_invalid(consensus_tx.signer(), consensus_tx.nonce()); invalid_txs.push(tx.hash().clone()); continue; } } // If the transaction is verified, check if it can be added within the verified gas limit - if tx.valid_pbh && info.cumulative_gas_used + tx.gas_limit() > verified_gas_limit { - best_txs.mark_invalid(tx.signer(), tx.nonce()); + if tx.transaction.valid_pbh() + && info.cumulative_gas_used + tx.gas_limit() > verified_gas_limit + { + best_txs.mark_invalid(&tx, InvalidPoolTransactionError::Underpriced); continue; } @@ -761,13 +775,18 @@ where // we can't fit this transaction into the block, so we need to mark it as // invalid which also removes all dependent transaction from // the iterator before we can continue - best_txs.mark_invalid(tx.signer(), tx.nonce()); + best_txs.mark_invalid(&tx, InvalidPoolTransactionError::Underpriced); // TODO: Update this error continue; } // A sequencer's block should never contain blob or deposit transactions from the pool. if tx.is_eip4844() || tx.tx_type() == TxType::Deposit as u8 { - best_txs.mark_invalid(tx.signer(), tx.nonce()); + best_txs.mark_invalid( + &tx, + InvalidPoolTransactionError::Consensus( + InvalidTransactionError::TxTypeNotSupported, + ), + ); continue; } @@ -780,21 +799,22 @@ where *evm.tx_mut() = self .inner .evm_config - .tx_env(tx.inner.transaction().as_signed(), tx.signer()); + .tx_env(&consensus_tx, consensus_tx.signer()); let ResultAndState { result, state } = match evm.transact() { Ok(res) => res, Err(err) => { match err { EVMError::Transaction(err) => { - if matches!(err, InvalidTransaction::NonceTooLow { .. }) { + if matches!(err, InvalidTransaction::NonceTooLow { tx, state }) { // if the nonce is too low, we can skip this transaction trace!(target: "payload_builder", %err, ?tx, "skipping nonce too low transaction"); } else { // if the transaction is invalid, we can skip it and all of its // descendants trace!(target: "payload_builder", %err, ?tx, "skipping invalid transaction and its descendants"); - best_txs.mark_invalid(tx.signer(), tx.nonce()); + best_txs + .mark_invalid(&tx, InvalidPoolTransactionError::Underpriced); } continue; @@ -818,7 +838,7 @@ where // Push transaction changeset and calculate header bloom filter for receipt. info.receipts.push(Some(Receipt { - tx_type: tx.inner.transaction().tx_type(), + tx_type: consensus_tx.tx_type(), success: result.is_success(), cumulative_gas_used: info.cumulative_gas_used, logs: result.into_logs().into_iter().map(Into::into).collect(), @@ -833,9 +853,8 @@ where info.total_fees += U256::from(miner_fee) * U256::from(gas_used); // append sender and transaction to the respective lists - info.executed_senders.push(tx.signer()); - info.executed_transactions - .push(tx.inner.transaction().into_signed()); + info.executed_senders.push(consensus_tx.signer()); + info.executed_transactions.push(consensus_tx.into_signed()); } Ok(None) From d76dc792af7fead68243a1a941b8549cc472556b Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Fri, 13 Dec 2024 15:27:22 -0700 Subject: [PATCH 38/59] feat(payload-builder): error handling --- world-chain-builder/Cargo.lock | 1 + .../crates/world/payload/Cargo.toml | 1 + .../crates/world/payload/src/builder.rs | 35 ++++++++++++++++--- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/world-chain-builder/Cargo.lock b/world-chain-builder/Cargo.lock index ffadf664..7e16b7e6 100644 --- a/world-chain-builder/Cargo.lock +++ b/world-chain-builder/Cargo.lock @@ -13765,6 +13765,7 @@ dependencies = [ "reth-trie", "revm", "revm-primitives", + "thiserror 1.0.69", "tracing", "world-chain-builder-pool", "world-chain-builder-rpc", diff --git a/world-chain-builder/crates/world/payload/Cargo.toml b/world-chain-builder/crates/world/payload/Cargo.toml index 35706332..2a3c060c 100644 --- a/world-chain-builder/crates/world/payload/Cargo.toml +++ b/world-chain-builder/crates/world/payload/Cargo.toml @@ -43,3 +43,4 @@ alloy-rpc-types-debug.workspace = true # misc tracing.workspace = true jsonrpsee.workspace = true +thiserror.workspace = true diff --git a/world-chain-builder/crates/world/payload/src/builder.rs b/world-chain-builder/crates/world/payload/src/builder.rs index b3890015..01e43587 100644 --- a/world-chain-builder/crates/world/payload/src/builder.rs +++ b/world-chain-builder/crates/world/payload/src/builder.rs @@ -53,9 +53,9 @@ use revm_primitives::{ }; use std::fmt::Display; use std::sync::Arc; +use thiserror::Error; use tracing::{debug, trace, warn}; use world_chain_builder_pool::noop::NoopWorldChainTransactionPool; -use world_chain_builder_pool::tx::WorldChainPooledTransaction; use world_chain_builder_pool::tx::WorldChainPoolTransaction; use world_chain_builder_rpc::eth::validate_conditional_options; @@ -67,6 +67,23 @@ pub struct WorldChainPayloadBuilder { pub verified_blockspace_capacity: u8, } +#[derive(Debug, Error)] +pub enum WorldChainPoolTransactionError { + #[error("Conditional Validation Failed: {0}")] + ConditionalValidationFailed(B256), + #[error("EVM Error: {0}")] + EVMError(#[from] InvalidTransaction), +} + +impl PoolTransactionError for WorldChainPoolTransactionError { + fn is_bad_transaction(&self) -> bool { + match self { + WorldChainPoolTransactionError::ConditionalValidationFailed(_) => true, + WorldChainPoolTransactionError::EVMError(_) => true, // TODO: Should we return false here? + } + } +} + impl WorldChainPayloadBuilder where EvmConfig: ConfigureEvm
, @@ -384,7 +401,8 @@ where // 4. if mem pool transactions are requested we execute them if !ctx.attributes().no_tx_pool { //TODO: build pbh payload - let best_txs= pool.best_transactions_with_attributes(ctx.best_transaction_attributes()); + let best_txs = + pool.best_transactions_with_attributes(ctx.best_transaction_attributes()); if ctx .execute_best_transactions::<_, Pool>(&mut info, state, best_txs)? @@ -756,7 +774,14 @@ where let consensus_tx = tx.to_consensus(); if let Some(conditional_options) = pooled_tx.conditional_options() { if let Err(_) = validate_conditional_options(&conditional_options, &client) { - best_txs.mark_invalid(consensus_tx.signer(), consensus_tx.nonce()); + best_txs.mark_invalid( + &tx, + InvalidPoolTransactionError::Other(Box::new( + WorldChainPoolTransactionError::ConditionalValidationFailed( + tx.hash().clone(), + ), + )), + ); invalid_txs.push(tx.hash().clone()); continue; } @@ -775,7 +800,7 @@ where // we can't fit this transaction into the block, so we need to mark it as // invalid which also removes all dependent transaction from // the iterator before we can continue - best_txs.mark_invalid(&tx, InvalidPoolTransactionError::Underpriced); // TODO: Update this error + best_txs.mark_invalid(&tx, InvalidPoolTransactionError::Underpriced); continue; } @@ -814,7 +839,7 @@ where // descendants trace!(target: "payload_builder", %err, ?tx, "skipping invalid transaction and its descendants"); best_txs - .mark_invalid(&tx, InvalidPoolTransactionError::Underpriced); + .mark_invalid(&tx, InvalidPoolTransactionError::Other(Box::new(err.into()))); } continue; From fb25f998d4a627f676e4ee7dd7c45e91b23c7657 Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Fri, 13 Dec 2024 16:08:02 -0700 Subject: [PATCH 39/59] fix: payload builder --- .../crates/world/node/src/node.rs | 9 +- .../crates/world/payload/src/builder.rs | 86 ++++++++++++------- 2 files changed, 61 insertions(+), 34 deletions(-) diff --git a/world-chain-builder/crates/world/node/src/node.rs b/world-chain-builder/crates/world/node/src/node.rs index 4f80f88c..5a2f7aca 100644 --- a/world-chain-builder/crates/world/node/src/node.rs +++ b/world-chain-builder/crates/world/node/src/node.rs @@ -33,7 +33,7 @@ use reth_trie_db::MerklePatriciaTrie; use world_chain_builder_db::load_world_chain_db; use world_chain_builder_pool::builder::WorldChainPoolBuilder; use world_chain_builder_pool::ordering::WorldChainOrdering; -use world_chain_builder_pool::tx::WorldChainPooledTransaction; +use world_chain_builder_pool::tx::{WorldChainPoolTransaction, WorldChainPooledTransaction}; use world_chain_builder_pool::validator::WorldChainTransactionValidator; use super::args::{ExtArgs, WorldChainBuilderArgs}; @@ -242,7 +242,7 @@ where Primitives = OpPrimitives, >, >, - Pool: TransactionPool>> + Pool: TransactionPool>> + Unpin + 'static, Evm: ConfigureEvm
, @@ -289,8 +289,9 @@ where Primitives = OpPrimitives, >, >, - Pool: - TransactionPool>> + Unpin + 'static, + Pool: TransactionPool>> + + Unpin + + 'static, Txs: OpPayloadTransactions, { async fn spawn_payload_service( diff --git a/world-chain-builder/crates/world/payload/src/builder.rs b/world-chain-builder/crates/world/payload/src/builder.rs index 01e43587..ceacf8b6 100644 --- a/world-chain-builder/crates/world/payload/src/builder.rs +++ b/world-chain-builder/crates/world/payload/src/builder.rs @@ -2,6 +2,7 @@ use alloy_consensus::{Transaction, EMPTY_OMMER_ROOT_HASH}; use alloy_eips::eip4895::Withdrawals; use alloy_eips::merge::BEACON_NONCE; use alloy_rpc_types_debug::ExecutionWitness; +use jsonrpsee::core::client; use reth::api::PayloadBuilderError; use reth::builder::components::PayloadServiceBuilder; use reth::builder::{BuilderContext, FullNodeTypes, NodeTypesWithEngine, PayloadBuilderConfig}; @@ -169,7 +170,8 @@ where args: BuildArguments, ) -> Result, PayloadBuilderError> where - Client: StateProviderFactory + ChainSpecProvider, + Client: + StateProviderFactory + ChainSpecProvider + BlockReaderIdExt, Pool: TransactionPool>, { @@ -197,6 +199,7 @@ where best_payload, }, verified_blockspace_capacity: self.verified_blockspace_capacity, + client, }; let builder = WorldChainBuilder { @@ -204,6 +207,7 @@ where best: self.inner.best_transactions.clone(), }; + let client = ctx.client(); let state_provider = client.state_by_block_hash(ctx.parent().hash())?; let state = StateProviderDatabase::new(state_provider); @@ -250,12 +254,13 @@ where /// Computes the witness for the payload. pub fn payload_witness( &self, - client: &Client, + client: Client, parent: SealedHeader, attributes: OpPayloadAttributes, ) -> Result where - Client: StateProviderFactory + ChainSpecProvider, + Client: + StateProviderFactory + ChainSpecProvider + BlockReaderIdExt, { let attributes = OpPayloadBuilderAttributes::try_new(parent.hash(), attributes, 3) .map_err(PayloadBuilderError::other)?; @@ -281,8 +286,10 @@ where best_payload: Default::default(), }, verified_blockspace_capacity: self.verified_blockspace_capacity, + client, }; + let client = ctx.client(); let state_provider = client.state_by_block_hash(ctx.parent().hash())?; let state = StateProviderDatabase::new(state_provider); let mut state = State::builder() @@ -302,7 +309,7 @@ where impl PayloadBuilder for WorldChainPayloadBuilder where - Client: StateProviderFactory + ChainSpecProvider, + Client: StateProviderFactory + ChainSpecProvider + BlockReaderIdExt, Pool: TransactionPool>, EvmConfig: ConfigureEvm
, Txs: OpPayloadTransactions, @@ -333,18 +340,20 @@ where client: &Client, config: PayloadConfig, ) -> Result { - let args = BuildArguments { - client, - config, - // we use defaults here because for the empty payload we don't need to execute anything - pool: NoopWorldChainTransactionPool::default(), - cached_reads: Default::default(), - cancel: Default::default(), - best_payload: None, - }; - self.build_payload(args)? - .into_payload() - .ok_or_else(|| PayloadBuilderError::MissingPayload) + // TODO: + // let args = BuildArguments { + // client, + // config, + // // we use defaults here because for the empty payload we don't need to execute anything + // pool: NoopWorldChainTransactionPool::default(), + // cached_reads: Default::default(), + // cancel: Default::default(), + // best_payload: None, + // }; + // self.build_payload(args)? + // .into_payload() + // .ok_or_else(|| PayloadBuilderError::MissingPayload) + todo!() } } @@ -377,14 +386,16 @@ where Txs: OpPayloadTransactions, { /// Executes the payload and returns the outcome. - pub fn execute( + pub fn execute( self, state: &mut State, - ctx: &WorldChainPayloadBuilderCtx, + ctx: &WorldChainPayloadBuilderCtx, ) -> Result, PayloadBuilderError> where EvmConfig: ConfigureEvm
, DB: Database, + Client: + StateProviderFactory + ChainSpecProvider + BlockReaderIdExt, { let Self { pool, best } = self; debug!(target: "payload_builder", id=%ctx.payload_id(), parent_header = ?ctx.parent().hash(), parent_number = ctx.parent().number, "building new payload"); @@ -436,15 +447,17 @@ where // TODO: /// Builds the payload on top of the state. - pub fn build( + pub fn build( self, mut state: State, - ctx: WorldChainPayloadBuilderCtx, + ctx: WorldChainPayloadBuilderCtx, ) -> Result, PayloadBuilderError> where EvmConfig: ConfigureEvm
, DB: Database + AsRef

, P: StateRootProvider + HashedPostStateProvider, + Client: + StateProviderFactory + ChainSpecProvider + BlockReaderIdExt, { let ExecutedPayload { info, @@ -568,15 +581,17 @@ where } /// Builds the payload and returns its [`ExecutionWitness`] based on the state after execution. - pub fn witness( + pub fn witness( self, state: &mut State, - ctx: &WorldChainPayloadBuilderCtx, + ctx: &WorldChainPayloadBuilderCtx, ) -> Result where EvmConfig: ConfigureEvm

, DB: Database + AsRef

, P: StateProofProvider, + Client: + StateProviderFactory + ChainSpecProvider + BlockReaderIdExt, { let _ = self.execute(state, ctx)?; let ExecutionWitnessRecord { @@ -598,17 +613,23 @@ where /// Container type that holds all necessities to build a new payload. #[derive(Debug)] -pub struct WorldChainPayloadBuilderCtx { +pub struct WorldChainPayloadBuilderCtx { pub inner: OpPayloadBuilderCtx, pub verified_blockspace_capacity: u8, + pub client: Client, } -impl WorldChainPayloadBuilderCtx { +impl WorldChainPayloadBuilderCtx { /// Returns the parent block the payload will be build on. pub fn parent(&self) -> &SealedHeader { self.inner.parent() } + /// Returns the state provider client. + pub fn client(&self) -> &Client { + &self.client + } + /// Returns the builder attributes. pub const fn attributes(&self) -> &OpPayloadBuilderAttributes { self.inner.attributes() @@ -712,9 +733,10 @@ impl WorldChainPayloadBuilderCtx { } } -impl WorldChainPayloadBuilderCtx +impl WorldChainPayloadBuilderCtx where EvmConfig: ConfigureEvm

, + Client: StateProviderFactory + ChainSpecProvider + BlockReaderIdExt, { /// apply eip-4788 pre block contract call pub fn apply_pre_beacon_root_contract_call( @@ -770,10 +792,10 @@ where let mut invalid_txs = vec![]; let verified_gas_limit = (self.verified_blockspace_capacity as u64 * block_gas_limit) / 100; while let Some(tx) = best_txs.next() { - let pooled_tx = tx.transaction; + let pooled_tx = &tx.transaction; let consensus_tx = tx.to_consensus(); if let Some(conditional_options) = pooled_tx.conditional_options() { - if let Err(_) = validate_conditional_options(&conditional_options, &client) { + if let Err(_) = validate_conditional_options(&conditional_options, &self.client) { best_txs.mark_invalid( &tx, InvalidPoolTransactionError::Other(Box::new( @@ -831,15 +853,19 @@ where Err(err) => { match err { EVMError::Transaction(err) => { - if matches!(err, InvalidTransaction::NonceTooLow { tx, state }) { + if matches!(err, InvalidTransaction::NonceTooLow { .. }) { // if the nonce is too low, we can skip this transaction trace!(target: "payload_builder", %err, ?tx, "skipping nonce too low transaction"); } else { // if the transaction is invalid, we can skip it and all of its // descendants trace!(target: "payload_builder", %err, ?tx, "skipping invalid transaction and its descendants"); - best_txs - .mark_invalid(&tx, InvalidPoolTransactionError::Other(Box::new(err.into()))); + best_txs.mark_invalid( + &tx, + InvalidPoolTransactionError::Other(Box::new( + WorldChainPoolTransactionError::from(err), + )), + ); } continue; From 937ec92c439cf6054425703a3f689f13b7462aa6 Mon Sep 17 00:00:00 2001 From: 0xKitsune <0xkitsune@protonmail.com> Date: Fri, 13 Dec 2024 22:41:18 -0500 Subject: [PATCH 40/59] clippy --- .../crates/assertor/src/main.rs | 3 +- .../crates/world/bin/src/main.rs | 2 +- .../crates/world/db/src/lib.rs | 1 - .../node/benches/validate_transaction.rs | 2 -- .../crates/world/node/src/node.rs | 16 +++------ .../crates/world/payload/src/builder.rs | 36 ++++++------------- .../crates/world/pool/src/root.rs | 2 +- .../crates/world/pool/src/test_utils.rs | 2 +- .../crates/world/pool/src/tx.rs | 12 +++---- .../crates/world/pool/src/validator.rs | 5 +-- 10 files changed, 28 insertions(+), 53 deletions(-) diff --git a/world-chain-builder/crates/assertor/src/main.rs b/world-chain-builder/crates/assertor/src/main.rs index c1f54c4a..dfcebac1 100644 --- a/world-chain-builder/crates/assertor/src/main.rs +++ b/world-chain-builder/crates/assertor/src/main.rs @@ -109,9 +109,10 @@ where { let start = Instant::now(); loop { - if let Ok(_) = provider + if provider .get_block_by_number(BlockNumberOrTag::Latest, false) .await + .is_ok() { break; } diff --git a/world-chain-builder/crates/world/bin/src/main.rs b/world-chain-builder/crates/world/bin/src/main.rs index 8102348d..11d07e83 100644 --- a/world-chain-builder/crates/world/bin/src/main.rs +++ b/world-chain-builder/crates/world/bin/src/main.rs @@ -44,7 +44,7 @@ fn main() { let eth_api_ext = WorldChainEthApiExt::new(pool, provider, sequencer_client); // Remove the `eth_sendRawTransaction` method from the configured modules ctx.modules - .remove_method_from_configured(&"eth_sendRawTransaction"); + .remove_method_from_configured("eth_sendRawTransaction"); // Merge the `eth_sendRawTransaction` and `eth_sendRawTransactionConditional` RPC methods ctx.modules.merge_configured(eth_api_ext.into_rpc())?; Ok(()) diff --git a/world-chain-builder/crates/world/db/src/lib.rs b/world-chain-builder/crates/world/db/src/lib.rs index 59dbbbb4..0f02c32a 100644 --- a/world-chain-builder/crates/world/db/src/lib.rs +++ b/world-chain-builder/crates/world/db/src/lib.rs @@ -11,7 +11,6 @@ use reth_db::table::{Compress, Decompress, Table}; use reth_db::transaction::DbTxMut; use reth_db::TableSet; use reth_db::{create_db, tables, DatabaseError, TableType, TableViewer}; -use reth_db_api; use revm_primitives::{FixedBytes, B256}; use semaphore::Field; use serde::{Deserialize, Serialize}; diff --git a/world-chain-builder/crates/world/node/benches/validate_transaction.rs b/world-chain-builder/crates/world/node/benches/validate_transaction.rs index 84449187..b347bcaf 100644 --- a/world-chain-builder/crates/world/node/benches/validate_transaction.rs +++ b/world-chain-builder/crates/world/node/benches/validate_transaction.rs @@ -5,10 +5,8 @@ use reth::transaction_pool::blobstore::InMemoryBlobStore; use reth::transaction_pool::{Pool, PoolTransaction as _, TransactionPool, TransactionValidator}; use reth_primitives::{BlockBody, SealedBlock, SealedHeader}; use reth_provider::test_utils::{ExtendedAccount, MockEthProvider}; -use semaphore::Field; use tokio::runtime::{Builder, Runtime}; use world_chain_builder_pool::ordering::WorldChainOrdering; -use world_chain_builder_pool::root::{LATEST_ROOT_SLOT, OP_WORLD_ID}; use world_chain_builder_pool::test_utils::{ get_non_pbh_transaction, get_pbh_transaction, world_chain_validator, }; diff --git a/world-chain-builder/crates/world/node/src/node.rs b/world-chain-builder/crates/world/node/src/node.rs index 5a2f7aca..6a9c2b19 100644 --- a/world-chain-builder/crates/world/node/src/node.rs +++ b/world-chain-builder/crates/world/node/src/node.rs @@ -4,37 +4,31 @@ use std::sync::Arc; use eyre::eyre::Result; use reth::api::{ConfigureEvm, TxTy}; use reth::builder::components::{ - ComponentsBuilder, ConsensusBuilder, ExecutorBuilder, NetworkBuilder, PayloadServiceBuilder, - PoolBuilder, + ComponentsBuilder, PayloadServiceBuilder, }; use reth::builder::{ BuilderContext, FullNodeTypes, Node, NodeAdapter, NodeComponentsBuilder, NodeTypes, NodeTypesWithEngine, PayloadBuilderConfig, }; use reth::payload::{PayloadBuilderHandle, PayloadBuilderService}; -use reth::transaction_pool::blobstore::DiskFileBlobStore; -use reth::transaction_pool::{ - Pool, PoolTransaction, TransactionPool, TransactionValidationTaskExecutor, -}; +use reth::transaction_pool::TransactionPool; use reth_basic_payload_builder::{BasicPayloadJobGenerator, BasicPayloadJobGeneratorConfig}; use reth_db::DatabaseEnv; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_node::args::RollupArgs; use reth_optimism_node::node::{ - OpAddOns, OpConsensusBuilder, OpExecutorBuilder, OpNetworkBuilder, OpPayloadBuilder, OpStorage, + OpAddOns, OpConsensusBuilder, OpExecutorBuilder, OpNetworkBuilder, OpStorage, }; use reth_optimism_node::{OpEngineTypes, OpEvmConfig}; use reth_optimism_payload_builder::builder::OpPayloadTransactions; use reth_optimism_payload_builder::config::OpDAConfig; use reth_optimism_primitives::OpPrimitives; -use reth_primitives::{Header, NodePrimitives, TransactionSigned}; +use reth_primitives::{Header, TransactionSigned}; use reth_provider::CanonStateSubscriptions; use reth_trie_db::MerklePatriciaTrie; use world_chain_builder_db::load_world_chain_db; use world_chain_builder_pool::builder::WorldChainPoolBuilder; -use world_chain_builder_pool::ordering::WorldChainOrdering; -use world_chain_builder_pool::tx::{WorldChainPoolTransaction, WorldChainPooledTransaction}; -use world_chain_builder_pool::validator::WorldChainTransactionValidator; +use world_chain_builder_pool::tx::WorldChainPoolTransaction; use super::args::{ExtArgs, WorldChainBuilderArgs}; diff --git a/world-chain-builder/crates/world/payload/src/builder.rs b/world-chain-builder/crates/world/payload/src/builder.rs index ceacf8b6..01689365 100644 --- a/world-chain-builder/crates/world/payload/src/builder.rs +++ b/world-chain-builder/crates/world/payload/src/builder.rs @@ -1,57 +1,45 @@ -use alloy_consensus::{Transaction, EMPTY_OMMER_ROOT_HASH}; +use alloy_consensus::EMPTY_OMMER_ROOT_HASH; use alloy_eips::eip4895::Withdrawals; use alloy_eips::merge::BEACON_NONCE; use alloy_rpc_types_debug::ExecutionWitness; -use jsonrpsee::core::client; use reth::api::PayloadBuilderError; -use reth::builder::components::PayloadServiceBuilder; -use reth::builder::{BuilderContext, FullNodeTypes, NodeTypesWithEngine, PayloadBuilderConfig}; -use reth::chainspec::EthereumHardforks; use reth::payload::{PayloadBuilderAttributes, PayloadId}; -use reth::payload::{PayloadBuilderHandle, PayloadBuilderService}; use reth::revm::database::StateProviderDatabase; use reth::revm::db::states::bundle_state::BundleRetention; use reth::revm::witness::ExecutionWitnessRecord; use reth::revm::DatabaseCommit; use reth::revm::State; -use reth::transaction_pool::{BestTransactionsAttributes, PoolTransaction, TransactionPool}; +use reth::transaction_pool::{BestTransactionsAttributes, TransactionPool}; use reth_basic_payload_builder::{ - commit_withdrawals, is_better_payload, BasicPayloadJobGenerator, - BasicPayloadJobGeneratorConfig, BuildArguments, BuildOutcome, BuildOutcomeKind, - MissingPayloadBehaviour, PayloadBuilder, PayloadConfig, + BuildArguments, BuildOutcome, BuildOutcomeKind, MissingPayloadBehaviour, PayloadBuilder, + PayloadConfig, }; use reth_chain_state::ExecutedBlock; -use reth_db::DatabaseEnv; -use reth_evm::system_calls::SystemCaller; use reth_evm::{ConfigureEvm, NextBlockEnvAttributes}; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_consensus::calculate_receipt_root_no_memo_optimism; use reth_optimism_node::{OpBuiltPayload, OpPayloadBuilder, OpPayloadBuilderAttributes}; use reth_optimism_payload_builder::builder::{ - ExecutedPayload, ExecutionInfo, OpBuilder, OpPayloadBuilderCtx, OpPayloadTransactions, + ExecutedPayload, ExecutionInfo, OpPayloadBuilderCtx, OpPayloadTransactions, }; use reth_optimism_payload_builder::config::OpBuilderConfig; use reth_optimism_payload_builder::OpPayloadAttributes; -use reth_payload_util::PayloadTransactions; use reth_primitives::{ proofs, BlockBody, BlockExt, InvalidTransactionError, SealedHeader, TransactionSigned, }; use reth_primitives::{Block, Header, Receipt, TxType}; use reth_provider::{ - BlockReaderIdExt, CanonStateSubscriptions, ChainSpecProvider, ExecutionOutcome, - HashedPostStateProvider, ProviderError, StateProofProvider, StateProviderFactory, - StateRootProvider, + BlockReaderIdExt, ChainSpecProvider, ExecutionOutcome, HashedPostStateProvider, ProviderError, + StateProofProvider, StateProviderFactory, StateRootProvider, }; use reth_transaction_pool::error::{InvalidPoolTransactionError, PoolTransactionError}; -use reth_transaction_pool::{noop::NoopTransactionPool, pool::BestPayloadTransactions}; use reth_transaction_pool::{BestTransactions, ValidPoolTransaction}; -use reth_trie::HashedPostState; use revm::Database; -use revm_primitives::{calc_excess_blob_gas, Bytes, TxEnv, B256}; use revm_primitives::{ BlockEnv, CfgEnvWithHandlerCfg, EVMError, EnvWithHandlerCfg, InvalidTransaction, ResultAndState, U256, }; +use revm_primitives::{Bytes, TxEnv, B256}; use std::fmt::Display; use std::sync::Arc; use thiserror::Error; @@ -795,16 +783,14 @@ where let pooled_tx = &tx.transaction; let consensus_tx = tx.to_consensus(); if let Some(conditional_options) = pooled_tx.conditional_options() { - if let Err(_) = validate_conditional_options(&conditional_options, &self.client) { + if validate_conditional_options(conditional_options, &self.client).is_err() { best_txs.mark_invalid( &tx, InvalidPoolTransactionError::Other(Box::new( - WorldChainPoolTransactionError::ConditionalValidationFailed( - tx.hash().clone(), - ), + WorldChainPoolTransactionError::ConditionalValidationFailed(*tx.hash()), )), ); - invalid_txs.push(tx.hash().clone()); + invalid_txs.push(*tx.hash()); continue; } } diff --git a/world-chain-builder/crates/world/pool/src/root.rs b/world-chain-builder/crates/world/pool/src/root.rs index e316cc9d..a41058f2 100644 --- a/world-chain-builder/crates/world/pool/src/root.rs +++ b/world-chain-builder/crates/world/pool/src/root.rs @@ -205,7 +205,7 @@ mod tests { header: SealedHeader::new(block.header.clone(), block.header.hash_slow()), body: block.body, }; - validator.on_new_block(&block.into()); + validator.on_new_block(&block); } #[test] diff --git a/world-chain-builder/crates/world/pool/src/test_utils.rs b/world-chain-builder/crates/world/pool/src/test_utils.rs index 8f7f6e11..f12b3d03 100644 --- a/world-chain-builder/crates/world/pool/src/test_utils.rs +++ b/world-chain-builder/crates/world/pool/src/test_utils.rs @@ -42,7 +42,7 @@ pub fn get_non_pbh_transaction() -> WorldChainPooledTransaction { pub fn get_pbh_transaction(nonce: u16) -> WorldChainPooledTransaction { let eth_tx = get_eth_transaction(); - let pbh_payload = valid_pbh_payload( + let _pbh_payload = valid_pbh_payload( &mut [0; 32], eth_tx.hash().as_slice(), chrono::Utc::now(), diff --git a/world-chain-builder/crates/world/pool/src/tx.rs b/world-chain-builder/crates/world/pool/src/tx.rs index 758f8f60..bc114e24 100644 --- a/world-chain-builder/crates/world/pool/src/tx.rs +++ b/world-chain-builder/crates/world/pool/src/tx.rs @@ -54,7 +54,7 @@ impl EthPoolTransaction for WorldChainPooledTransaction { let pooled = PooledTransactionsElement::try_from_blob_transaction(tx, sidecar) .ok() .map(|tx| tx.with_signer(signer)) - .map(|tx| EthPooledTransaction::from_pooled(tx)); + .map(EthPooledTransaction::from_pooled); pooled.map(|inner| Self { inner, @@ -129,9 +129,9 @@ impl TryFrom for WorldChainPooledTransaction { } } -impl Into for WorldChainPooledTransaction { - fn into(self) -> RecoveredTx { - self.inner.into() +impl From for RecoveredTx { + fn from(val: WorldChainPooledTransaction) -> Self { + val.inner.into() } } @@ -159,7 +159,7 @@ impl PoolTransaction for WorldChainPooledTransaction { /// Returns hash of the transaction. fn hash(&self) -> &TxHash { let transaction = self.inner.transaction(); - &transaction.tx_hash() + transaction.tx_hash() } /// Returns the Sender of the transaction. @@ -184,7 +184,7 @@ impl PoolTransaction for WorldChainPooledTransaction { /// For EIP-4844 blob transactions: `max_fee_per_gas * gas_limit + tx_value + /// max_blob_fee_per_gas * blob_gas_used`. fn cost(&self) -> &U256 { - &self.inner.cost() + self.inner.cost() } /// Amount of gas that should be used in executing this transaction. This is paid up-front. diff --git a/world-chain-builder/crates/world/pool/src/validator.rs b/world-chain-builder/crates/world/pool/src/validator.rs index 7da5aaae..bf862966 100644 --- a/world-chain-builder/crates/world/pool/src/validator.rs +++ b/world-chain-builder/crates/world/pool/src/validator.rs @@ -166,8 +166,6 @@ where origin: TransactionOrigin, transaction: Tx, ) -> TransactionValidationOutcome { - let validation_outcome = self.inner.validate_one(origin, transaction.clone()); - // TODO: Extend Validation logic for 4337 Architecture // if let Some(pbh_payload) = transaction.pbh_payload() { // if let Err(e) = self.validate_pbh_payload(&transaction, pbh_payload) { @@ -175,7 +173,7 @@ where // } // }; - validation_outcome + self.inner.validate_one(origin, transaction.clone()) } /// Validates all given transactions. @@ -237,7 +235,6 @@ pub mod tests { use test_case::test_case; use world_chain_builder_pbh::payload::{PbhPayload, Proof}; - use super::*; use crate::ordering::WorldChainOrdering; use crate::root::{LATEST_ROOT_SLOT, OP_WORLD_ID}; use crate::test_utils::{get_pbh_transaction, world_chain_validator}; From 994bf51ee13ed2f54a724d7f4bbb19fbb5e53c1d Mon Sep 17 00:00:00 2001 From: 0xKitsune <0xkitsune@protonmail.com> Date: Sat, 14 Dec 2024 20:11:10 -0500 Subject: [PATCH 41/59] remove invalid txs --- world-chain-builder/crates/world/payload/src/builder.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/world-chain-builder/crates/world/payload/src/builder.rs b/world-chain-builder/crates/world/payload/src/builder.rs index 01689365..86d06121 100644 --- a/world-chain-builder/crates/world/payload/src/builder.rs +++ b/world-chain-builder/crates/world/payload/src/builder.rs @@ -404,7 +404,7 @@ where pool.best_transactions_with_attributes(ctx.best_transaction_attributes()); if ctx - .execute_best_transactions::<_, Pool>(&mut info, state, best_txs)? + .execute_best_transactions::<_, Pool>(&mut info, state, &pool, best_txs)? .is_some() { return Ok(BuildOutcomeKind::Cancelled); @@ -756,6 +756,7 @@ where &self, info: &mut ExecutionInfo, db: &mut State, + pool: &Pool, mut best_txs: Box< dyn BestTransactions< Item = Arc::Transaction>>, @@ -894,6 +895,10 @@ where info.executed_transactions.push(consensus_tx.into_signed()); } + if !invalid_txs.is_empty() { + pool.remove_transactions(invalid_txs); + } + Ok(None) } } From a77adca9348a9f1a72637ec568ca86ecac263f31 Mon Sep 17 00:00:00 2001 From: Dzejkop Date: Mon, 16 Dec 2024 12:40:28 +0100 Subject: [PATCH 42/59] Enable test_utils within pool crate --- world-chain-builder/Cargo.toml | 1 + world-chain-builder/crates/world/pool/Cargo.toml | 9 +++------ world-chain-builder/crates/world/pool/src/lib.rs | 3 ++- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/world-chain-builder/Cargo.toml b/world-chain-builder/Cargo.toml index 9dbcc340..ffd2e658 100644 --- a/world-chain-builder/Cargo.toml +++ b/world-chain-builder/Cargo.toml @@ -143,3 +143,4 @@ ethers-core = { git = "https://github.com/gakonst/ethers-rs", default-features = serde_json = "1" rand = "0.8" reqwest = { version = "0.12", default-features = false } + diff --git a/world-chain-builder/crates/world/pool/Cargo.toml b/world-chain-builder/crates/world/pool/Cargo.toml index 1a84bc25..ea211d26 100644 --- a/world-chain-builder/crates/world/pool/Cargo.toml +++ b/world-chain-builder/crates/world/pool/Cargo.toml @@ -28,26 +28,23 @@ alloy-primitives.workspace = true alloy-rpc-types.workspace = true alloy-eips.workspace = true +# 3rd party tokio.workspace = true semaphore.workspace = true chrono.workspace = true eyre.workspace = true thiserror.workspace = true - tracing.workspace = true parking_lot.workspace = true - -tempfile = {workspace = true, optional = true} - +tempfile = {workspace = true} [dev-dependencies] ethers-core.workspace = true test-case.workspace = true -tempfile.workspace = true [features] default = [] -test = ["dep:tempfile"] +test = [] [lints] workspace = true diff --git a/world-chain-builder/crates/world/pool/src/lib.rs b/world-chain-builder/crates/world/pool/src/lib.rs index 006c2af0..7f06bb25 100644 --- a/world-chain-builder/crates/world/pool/src/lib.rs +++ b/world-chain-builder/crates/world/pool/src/lib.rs @@ -6,5 +6,6 @@ pub mod root; pub mod tx; pub mod validator; -#[cfg(feature = "test")] +#[cfg(any(feature = "test", test))] pub mod test_utils; + From a2af9cf6913cf8a337498c5a00726d3e1b2ab0e8 Mon Sep 17 00:00:00 2001 From: Dzejkop Date: Mon, 16 Dec 2024 13:20:03 +0100 Subject: [PATCH 43/59] Replace methods instead of merging --- world-chain-builder/crates/world/node/tests/e2e.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/world-chain-builder/crates/world/node/tests/e2e.rs b/world-chain-builder/crates/world/node/tests/e2e.rs index dd47af19..793acd16 100644 --- a/world-chain-builder/crates/world/node/tests/e2e.rs +++ b/world-chain-builder/crates/world/node/tests/e2e.rs @@ -143,7 +143,8 @@ impl WorldChainBuilderTestContext { let provider = ctx.provider().clone(); let pool = ctx.pool().clone(); let eth_api_ext = WorldChainEthApiExt::new(pool, provider, None); - ctx.modules.merge_configured(eth_api_ext.into_rpc())?; + + ctx.modules.replace_configured(eth_api_ext.into_rpc())?; Ok(()) }); From d53165e954efefe6dc1e5c8c0841ec6dc34b013d Mon Sep 17 00:00:00 2001 From: Dzejkop Date: Mon, 16 Dec 2024 13:44:36 +0100 Subject: [PATCH 44/59] simplify --- .../crates/world/pool/src/validator.rs | 48 +++++-------------- 1 file changed, 11 insertions(+), 37 deletions(-) diff --git a/world-chain-builder/crates/world/pool/src/validator.rs b/world-chain-builder/crates/world/pool/src/validator.rs index bf862966..abf1746d 100644 --- a/world-chain-builder/crates/world/pool/src/validator.rs +++ b/world-chain-builder/crates/world/pool/src/validator.rs @@ -160,36 +160,6 @@ where Err(e) => Err(TransactionValidationError::Error(e.into())), } } - - pub fn validate_one( - &self, - origin: TransactionOrigin, - transaction: Tx, - ) -> TransactionValidationOutcome { - // TODO: Extend Validation logic for 4337 Architecture - // if let Some(pbh_payload) = transaction.pbh_payload() { - // if let Err(e) = self.validate_pbh_payload(&transaction, pbh_payload) { - // return e.to_outcome(transaction); - // } - // }; - - self.inner.validate_one(origin, transaction.clone()) - } - - /// Validates all given transactions. - /// - /// Returns all outcomes for the given transactions in the same order. - /// - /// See also [`Self::validate_one`] - pub fn validate_all( - &self, - transactions: Vec<(TransactionOrigin, Tx)>, - ) -> Vec> { - transactions - .into_iter() - .map(|(origin, tx)| self.validate_one(origin, tx)) - .collect() - } } impl TransactionValidator for WorldChainTransactionValidator @@ -204,14 +174,14 @@ where origin: TransactionOrigin, transaction: Self::Transaction, ) -> TransactionValidationOutcome { - self.validate_one(origin, transaction) - } + // TODO: Extend Validation logic for 4337 Architecture + // if let Some(pbh_payload) = transaction.pbh_payload() { + // if let Err(e) = self.validate_pbh_payload(&transaction, pbh_payload) { + // return e.to_outcome(transaction); + // } + // }; - async fn validate_transactions( - &self, - transactions: Vec<(TransactionOrigin, Self::Transaction)>, - ) -> Vec> { - self.validate_all(transactions) + self.inner.validate_one(origin, transaction.clone()) } fn on_new_head_block(&self, new_tip_block: &SealedBlock) { @@ -312,7 +282,11 @@ pub mod tests { ); let res = pool.add_external_transaction(transaction.clone()).await; + + println!("res = {res:#?}"); assert!(res.is_err()); + + assert!(false); } #[tokio::test] From f4af1764ef402db900e1902920ca85b77344116f Mon Sep 17 00:00:00 2001 From: Dzejkop Date: Mon, 16 Dec 2024 13:44:38 +0100 Subject: [PATCH 45/59] fmt --- world-chain-builder/crates/world/node/src/node.rs | 4 +--- world-chain-builder/crates/world/pool/src/lib.rs | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/world-chain-builder/crates/world/node/src/node.rs b/world-chain-builder/crates/world/node/src/node.rs index 6a9c2b19..565faa83 100644 --- a/world-chain-builder/crates/world/node/src/node.rs +++ b/world-chain-builder/crates/world/node/src/node.rs @@ -3,9 +3,7 @@ use std::sync::Arc; use eyre::eyre::Result; use reth::api::{ConfigureEvm, TxTy}; -use reth::builder::components::{ - ComponentsBuilder, PayloadServiceBuilder, -}; +use reth::builder::components::{ComponentsBuilder, PayloadServiceBuilder}; use reth::builder::{ BuilderContext, FullNodeTypes, Node, NodeAdapter, NodeComponentsBuilder, NodeTypes, NodeTypesWithEngine, PayloadBuilderConfig, diff --git a/world-chain-builder/crates/world/pool/src/lib.rs b/world-chain-builder/crates/world/pool/src/lib.rs index 7f06bb25..3978e059 100644 --- a/world-chain-builder/crates/world/pool/src/lib.rs +++ b/world-chain-builder/crates/world/pool/src/lib.rs @@ -8,4 +8,3 @@ pub mod validator; #[cfg(any(feature = "test", test))] pub mod test_utils; - From 83dfca8ad6f18f6da67454b6d1f4e3433b04209c Mon Sep 17 00:00:00 2001 From: Dzejkop Date: Mon, 16 Dec 2024 15:00:44 +0100 Subject: [PATCH 46/59] Add binginds --- world-chain-builder/Cargo.lock | 37 ++++++++++++++++ world-chain-builder/Cargo.toml | 4 +- .../crates/world/pool/Cargo.toml | 4 +- .../crates/world/pool/src/bindings.rs | 43 +++++++++++++++++++ .../crates/world/pool/src/lib.rs | 1 + 5 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 world-chain-builder/crates/world/pool/src/bindings.rs diff --git a/world-chain-builder/Cargo.lock b/world-chain-builder/Cargo.lock index 7e16b7e6..0074a478 100644 --- a/world-chain-builder/Cargo.lock +++ b/world-chain-builder/Cargo.lock @@ -1921,6 +1921,31 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "bon" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f265cdb2e8501f1c952749e78babe8f1937be92c98120e5f78fc72d634682bad" +dependencies = [ + "bon-macros", + "rustversion", +] + +[[package]] +name = "bon-macros" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38aa5c627cd7706490e5b003d685f8b9d69bc343b1a00b9fdd01e75fdf6827cf" +dependencies = [ + "darling 0.20.10", + "ident_case", + "prettyplease", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.90", +] + [[package]] name = "boyer-moore-magiclen" version = "0.2.20" @@ -6703,6 +6728,16 @@ dependencies = [ "yansi", ] +[[package]] +name = "prettyplease" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +dependencies = [ + "proc-macro2", + "syn 2.0.90", +] + [[package]] name = "primeorder" version = "0.13.6" @@ -13793,6 +13828,8 @@ dependencies = [ "alloy-eips 0.7.3", "alloy-primitives", "alloy-rpc-types", + "alloy-sol-types", + "bon", "chrono", "color-eyre", "ethers-core 2.0.14 (git+https://github.com/gakonst/ethers-rs)", diff --git a/world-chain-builder/Cargo.toml b/world-chain-builder/Cargo.toml index ffd2e658..ee1f1f98 100644 --- a/world-chain-builder/Cargo.toml +++ b/world-chain-builder/Cargo.toml @@ -110,6 +110,8 @@ alloy-genesis = { version = "0.7.3", default-features = false } alloy-rpc-types-debug = "0.8.0" alloy-signer = { version = "0.7.3", default-features = false } alloy-signer-local = { version = "0.7.3", default-features = false } +alloy-sol-types = "0.8.15" + # revm revm = { version = "18.0.0", features = ["std"], default-features = false } @@ -143,4 +145,4 @@ ethers-core = { git = "https://github.com/gakonst/ethers-rs", default-features = serde_json = "1" rand = "0.8" reqwest = { version = "0.12", default-features = false } - +bon = "3.3.0" diff --git a/world-chain-builder/crates/world/pool/Cargo.toml b/world-chain-builder/crates/world/pool/Cargo.toml index ea211d26..834491d6 100644 --- a/world-chain-builder/crates/world/pool/Cargo.toml +++ b/world-chain-builder/crates/world/pool/Cargo.toml @@ -27,6 +27,7 @@ alloy-consensus.workspace = true alloy-primitives.workspace = true alloy-rpc-types.workspace = true alloy-eips.workspace = true +alloy-sol-types.workspace = true # 3rd party tokio.workspace = true @@ -36,7 +37,8 @@ eyre.workspace = true thiserror.workspace = true tracing.workspace = true parking_lot.workspace = true -tempfile = {workspace = true} +tempfile.workspace = true +bon.workspace = true [dev-dependencies] ethers-core.workspace = true diff --git a/world-chain-builder/crates/world/pool/src/bindings.rs b/world-chain-builder/crates/world/pool/src/bindings.rs new file mode 100644 index 00000000..25596f65 --- /dev/null +++ b/world-chain-builder/crates/world/pool/src/bindings.rs @@ -0,0 +1,43 @@ +use alloy_sol_types::sol; + +sol! { + #[derive(Default)] + struct PackedUserOperation { + address sender; + uint256 nonce; + bytes initCode; + bytes callData; + bytes32 accountGasLimits; + uint256 preVerificationGas; + bytes32 gasFees; + bytes paymasterAndData; + bytes signature; + } + + #[derive(Default)] + struct UserOpsPerAggregator { + PackedUserOperation[] userOps; + address aggregator; + bytes signature; + } + + contract IEntryPoint { + function handleOps( + PackedUserOperation[] calldata, + address payable + ) external; + + function handleAggregatedOps( + UserOpsPerAggregator[] calldata, + address payable + ) public; + } + + // TODO: WIP + contract PBH { + function handleAggregatedOps( + UserOpsPerAggregator[] calldata, + address payable + ) public; + } +} diff --git a/world-chain-builder/crates/world/pool/src/lib.rs b/world-chain-builder/crates/world/pool/src/lib.rs index 3978e059..8f76f5f0 100644 --- a/world-chain-builder/crates/world/pool/src/lib.rs +++ b/world-chain-builder/crates/world/pool/src/lib.rs @@ -5,6 +5,7 @@ pub mod ordering; pub mod root; pub mod tx; pub mod validator; +pub mod bindings; #[cfg(any(feature = "test", test))] pub mod test_utils; From db9adeec4fee1f3c5f9257566cbcc6e3e694ee58 Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Mon, 16 Dec 2024 12:33:50 -0700 Subject: [PATCH 47/59] wip --- world-chain-builder/Cargo.lock | 1 + world-chain-builder/Cargo.toml | 1 + .../crates/world/node/src/args.rs | 12 ++- .../crates/world/node/src/node.rs | 12 ++- .../crates/world/pool/Cargo.toml | 1 + .../crates/world/pool/src/bindings.rs | 51 +++++------ .../crates/world/pool/src/builder.rs | 17 ++++ .../crates/world/pool/src/test_utils.rs | 11 ++- .../crates/world/pool/src/tx.rs | 18 ++-- .../crates/world/pool/src/validator.rs | 85 +++++++++++++++++-- 10 files changed, 157 insertions(+), 52 deletions(-) diff --git a/world-chain-builder/Cargo.lock b/world-chain-builder/Cargo.lock index 0074a478..7b4bd8a4 100644 --- a/world-chain-builder/Cargo.lock +++ b/world-chain-builder/Cargo.lock @@ -13834,6 +13834,7 @@ dependencies = [ "color-eyre", "ethers-core 2.0.14 (git+https://github.com/gakonst/ethers-rs)", "parking_lot", + "rayon", "reth", "reth-db", "reth-eth-wire-types", diff --git a/world-chain-builder/Cargo.toml b/world-chain-builder/Cargo.toml index ee1f1f98..a78e6fdd 100644 --- a/world-chain-builder/Cargo.toml +++ b/world-chain-builder/Cargo.toml @@ -146,3 +146,4 @@ serde_json = "1" rand = "0.8" reqwest = { version = "0.12", default-features = false } bon = "3.3.0" +rayon = "1.10.0" \ No newline at end of file diff --git a/world-chain-builder/crates/world/node/src/args.rs b/world-chain-builder/crates/world/node/src/args.rs index fd02fd81..bacc16c0 100644 --- a/world-chain-builder/crates/world/node/src/args.rs +++ b/world-chain-builder/crates/world/node/src/args.rs @@ -1,6 +1,6 @@ use clap::value_parser; use reth_optimism_node::args::RollupArgs; - +use alloy_primitives::Address; /// Parameters for rollup configuration #[derive(Debug, Clone, Default, PartialEq, Eq, clap::Args)] pub struct ExtArgs { @@ -30,4 +30,14 @@ pub struct WorldChainBuilderArgs { /// This arg is a percentage of the total blockspace with the default set to 70 (ie 70%). #[arg(long = "builder.verified_blockspace_capacity", default_value = "70", value_parser = value_parser!(u8).range(0..=100))] pub verified_blockspace_capacity: u8, + + /// Sets the ERC-4337 EntryPoint Proxy contract address + /// This contract is used to verify World-Id Proofs attached to 4337 payloads. + #[arg(long = "builder.pbh_validator")] + pub pbh_validator: Address, + + /// Sets the ERC0-7766 Signature Aggregator contract address + /// This contract signifies that a given bundle should receive priority inclusion if it passes validation + #[arg(long = "builder.signature_aggregator")] + pub signature_aggregator: Address, } diff --git a/world-chain-builder/crates/world/node/src/node.rs b/world-chain-builder/crates/world/node/src/node.rs index 565faa83..086583cf 100644 --- a/world-chain-builder/crates/world/node/src/node.rs +++ b/world-chain-builder/crates/world/node/src/node.rs @@ -86,6 +86,8 @@ impl WorldChainBuilder { clear_nullifiers, num_pbh_txs, verified_blockspace_capacity, + pbh_validator, + signature_aggregator, } = args.builder_args; let RollupArgs { @@ -97,11 +99,13 @@ impl WorldChainBuilder { ComponentsBuilder::default() .node_types::() - .pool(WorldChainPoolBuilder { - num_pbh_txs, + .pool(WorldChainPoolBuilder::new( clear_nullifiers, - db: db.clone(), - }) + num_pbh_txs, + db.clone(), + pbh_validator, + signature_aggregator + )) .payload(WorldChainPayloadBuilder::new( compute_pending_block, verified_blockspace_capacity, diff --git a/world-chain-builder/crates/world/pool/Cargo.toml b/world-chain-builder/crates/world/pool/Cargo.toml index 834491d6..fe2a7d24 100644 --- a/world-chain-builder/crates/world/pool/Cargo.toml +++ b/world-chain-builder/crates/world/pool/Cargo.toml @@ -39,6 +39,7 @@ tracing.workspace = true parking_lot.workspace = true tempfile.workspace = true bon.workspace = true +rayon.workspace = true [dev-dependencies] ethers-core.workspace = true diff --git a/world-chain-builder/crates/world/pool/src/bindings.rs b/world-chain-builder/crates/world/pool/src/bindings.rs index 25596f65..9a68af97 100644 --- a/world-chain-builder/crates/world/pool/src/bindings.rs +++ b/world-chain-builder/crates/world/pool/src/bindings.rs @@ -1,42 +1,31 @@ use alloy_sol_types::sol; sol! { - #[derive(Default)] - struct PackedUserOperation { - address sender; - uint256 nonce; - bytes initCode; - bytes callData; - bytes32 accountGasLimits; - uint256 preVerificationGas; - bytes32 gasFees; - bytes paymasterAndData; - bytes signature; - } - - #[derive(Default)] - struct UserOpsPerAggregator { - PackedUserOperation[] userOps; - address aggregator; - bytes signature; - } - contract IEntryPoint { - function handleOps( - PackedUserOperation[] calldata, - address payable - ) external; + #[derive(Default)] + struct PackedUserOperation { + address sender; + uint256 nonce; + bytes initCode; + bytes callData; + bytes32 accountGasLimits; + uint256 preVerificationGas; + bytes32 gasFees; + bytes paymasterAndData; + bytes signature; + } - function handleAggregatedOps( - UserOpsPerAggregator[] calldata, - address payable - ) public; + #[derive(Default)] + struct UserOpsPerAggregator { + PackedUserOperation[] userOps; + address aggregator; + bytes signature; + } } - // TODO: WIP - contract PBH { + contract IPBHValidator { function handleAggregatedOps( - UserOpsPerAggregator[] calldata, + IEntryPoint.UserOpsPerAggregator[] calldata, address payable ) public; } diff --git a/world-chain-builder/crates/world/pool/src/builder.rs b/world-chain-builder/crates/world/pool/src/builder.rs index d66ac073..d0081907 100644 --- a/world-chain-builder/crates/world/pool/src/builder.rs +++ b/world-chain-builder/crates/world/pool/src/builder.rs @@ -10,6 +10,7 @@ use reth_optimism_node::txpool::OpTransactionValidator; use reth_optimism_primitives::OpPrimitives; use reth_provider::CanonStateSubscriptions; use tracing::{debug, info}; +use alloy_primitives::Address; use super::validator::WorldChainTransactionPool; use crate::ordering::WorldChainOrdering; @@ -25,6 +26,20 @@ pub struct WorldChainPoolBuilder { pub clear_nullifiers: bool, pub num_pbh_txs: u16, pub db: Arc, + pub pbh_validator: Address, + pub pbh_signature_aggregator: Address, +} + +impl WorldChainPoolBuilder { + pub fn new(clear_nullifiers: bool, num_pbh_txs: u16, db: Arc, pbh_validator: Address, pbh_signature_aggregator: Address) -> Self { + Self { + clear_nullifiers, + num_pbh_txs, + db, + pbh_validator, + pbh_signature_aggregator + } + } } impl PoolBuilder for WorldChainPoolBuilder @@ -59,6 +74,8 @@ where root_validator, self.db.clone(), self.num_pbh_txs, + self.pbh_validator, + self.pbh_signature_aggregator, ) }); diff --git a/world-chain-builder/crates/world/pool/src/test_utils.rs b/world-chain-builder/crates/world/pool/src/test_utils.rs index f12b3d03..907d38f4 100644 --- a/world-chain-builder/crates/world/pool/src/test_utils.rs +++ b/world-chain-builder/crates/world/pool/src/test_utils.rs @@ -1,5 +1,8 @@ +use std::sync::Arc; + use alloy_eips::eip2718::Decodable2718; use chrono::Utc; +use parking_lot::RwLock; use reth::chainspec::MAINNET; use reth::transaction_pool::blobstore::InMemoryBlobStore; use reth::transaction_pool::validate::EthTransactionValidatorBuilder; @@ -7,7 +10,7 @@ use reth::transaction_pool::{EthPooledTransaction, PoolTransaction as _}; use reth_optimism_node::txpool::OpTransactionValidator; use reth_primitives::PooledTransactionsElement; use reth_provider::test_utils::MockEthProvider; -use revm_primitives::hex; +use revm_primitives::{hex, Address}; use semaphore::identity::Identity; use semaphore::poseidon_tree::LazyPoseidonTree; use semaphore::protocol::{generate_nullifier_hash, generate_proof}; @@ -35,7 +38,7 @@ pub fn get_non_pbh_transaction() -> WorldChainPooledTransaction { let eth_tx = get_eth_transaction(); WorldChainPooledTransaction { inner: eth_tx, - valid_pbh: false, + valid_pbh: Arc::new(RwLock::new(false)), conditional_options: None, } } @@ -50,7 +53,7 @@ pub fn get_pbh_transaction(nonce: u16) -> WorldChainPooledTransaction { ); WorldChainPooledTransaction { inner: eth_tx, - valid_pbh: false, + valid_pbh: Arc::new(RwLock::new(false)), conditional_options: None, } } @@ -67,7 +70,7 @@ pub fn world_chain_validator( let path = temp_dir.path().join("db"); let db = load_world_chain_db(&path, false).unwrap(); let root_validator = WorldChainRootValidator::new(client).unwrap(); - WorldChainTransactionValidator::new(validator, root_validator, db, 30) + WorldChainTransactionValidator::new(validator, root_validator, db, 30, Address::default(), Address::default()) } pub fn valid_pbh_payload( diff --git a/world-chain-builder/crates/world/pool/src/tx.rs b/world-chain-builder/crates/world/pool/src/tx.rs index bc114e24..531dd95d 100644 --- a/world-chain-builder/crates/world/pool/src/tx.rs +++ b/world-chain-builder/crates/world/pool/src/tx.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use alloy_consensus::{BlobTransactionSidecar, BlobTransactionValidationError, Transaction}; use alloy_primitives::TxHash; use alloy_rpc_types::erc4337::ConditionalOptions; +use parking_lot::RwLock; use reth::{ core::primitives::SignedTransaction, transaction_pool::{ @@ -20,13 +21,14 @@ use revm_primitives::{AccessList, Address, KzgSettings, TxKind, U256}; pub trait WorldChainPoolTransaction: EthPoolTransaction { fn valid_pbh(&self) -> bool; + fn set_valid_pbh(&self); fn conditional_options(&self) -> Option<&ConditionalOptions>; } #[derive(Debug, Clone)] pub struct WorldChainPooledTransaction { pub inner: EthPooledTransaction, - pub valid_pbh: bool, + pub valid_pbh: Arc>, pub conditional_options: Option, } @@ -58,7 +60,7 @@ impl EthPoolTransaction for WorldChainPooledTransaction { pooled.map(|inner| Self { inner, - valid_pbh: false, + valid_pbh: Arc::new(RwLock::new(false)), conditional_options: None, }) } @@ -86,19 +88,23 @@ impl EthPoolTransaction for WorldChainPooledTransaction { impl WorldChainPoolTransaction for WorldChainPooledTransaction { fn valid_pbh(&self) -> bool { - self.valid_pbh + *self.valid_pbh.read() } fn conditional_options(&self) -> Option<&ConditionalOptions> { self.conditional_options.as_ref() } + + fn set_valid_pbh(&self) { + *self.valid_pbh.write() = true; + } } impl From for WorldChainPooledTransaction { fn from(tx: EthPooledTransaction) -> Self { Self { inner: tx, - valid_pbh: false, + valid_pbh: Arc::new(RwLock::new(false)), conditional_options: None, } } @@ -110,7 +116,7 @@ impl From for WorldChainPooledTransaction let inner = EthPooledTransaction::from(tx); Self { inner, - valid_pbh: false, + valid_pbh: Arc::new(RwLock::new(false)), conditional_options: None, } } @@ -123,7 +129,7 @@ impl TryFrom for WorldChainPooledTransaction { let inner = EthPooledTransaction::try_from(tx)?; Ok(Self { inner, - valid_pbh: false, + valid_pbh: Arc::new(RwLock::new(false)), conditional_options: None, }) } diff --git a/world-chain-builder/crates/world/pool/src/validator.rs b/world-chain-builder/crates/world/pool/src/validator.rs index abf1746d..66c4d2a1 100644 --- a/world-chain-builder/crates/world/pool/src/validator.rs +++ b/world-chain-builder/crates/world/pool/src/validator.rs @@ -1,6 +1,12 @@ //! World Chain transaction pool types use std::sync::Arc; +use crate::bindings::{IEntryPoint, IPBHValidator}; +use alloy_primitives::{Address, Bytes, U256}; +use alloy_sol_types::abi::encode_sequence; +use alloy_sol_types::{SolCall, SolValue}; +use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; +use reth::transaction_pool::validate::TransactionValidatorError; use reth::transaction_pool::{ Pool, TransactionOrigin, TransactionValidationOutcome, TransactionValidationTaskExecutor, TransactionValidator, @@ -11,6 +17,7 @@ use reth_db::{Database, DatabaseEnv, DatabaseError}; use reth_optimism_node::txpool::OpTransactionValidator; use reth_primitives::{SealedBlock, TransactionSigned}; use reth_provider::{BlockReaderIdExt, StateProviderFactory}; +use revm_primitives::hex::encode_prefixed; use semaphore::hash_to_field; use semaphore::protocol::verify_proof; use world_chain_builder_db::{EmptyValue, ValidatedPbhTransaction}; @@ -42,6 +49,8 @@ where root_validator: WorldChainRootValidator, pub(crate) pbh_db: Arc, num_pbh_txs: u16, + pbh_validator: Address, + pbh_signature_aggregator: Address, } impl WorldChainTransactionValidator @@ -55,12 +64,16 @@ where root_validator: WorldChainRootValidator, pbh_db: Arc, num_pbh_txs: u16, + pbh_validator: Address, + pbh_signature_aggregator: Address, ) -> Self { Self { inner, root_validator, pbh_db, num_pbh_txs, + pbh_validator, + pbh_signature_aggregator, } } @@ -160,6 +173,62 @@ where Err(e) => Err(TransactionValidationError::Error(e.into())), } } + + pub fn is_valid_eip4337_pbh_bundle( + &self, + tx: &Tx, + ) -> Option { + if !tx + .input() + .starts_with(&IPBHValidator::handleAggregatedOpsCall::SELECTOR) + { + return None; + } + + // TODO: Boolean args is `validate`. Can it be `false`? + let Ok(decoded) = IPBHValidator::handleAggregatedOpsCall::abi_decode(tx.input(), true) + else { + return None; + }; + + let are_aggregators_valid = decoded + ._0 + .iter() + .cloned() + .all(|per_aggregator| per_aggregator.aggregator == self.pbh_signature_aggregator); + + if are_aggregators_valid { + Some(decoded) + } else { + None + } + } + + pub fn validate_pbh_bundle(&self, transaction: &Tx) -> Result<(), TransactionValidationError> { + if let Some(calldata) = self.is_valid_eip4337_pbh_bundle(transaction) { + for user_op in calldata._0 { + user_op.userOps.par_iter().try_for_each(|op| { + // TODO: Decode the PbhPayload from the signature + let _signal = alloy_primitives::keccak256( + <(Address, U256, Bytes) as SolValue>::abi_encode_packed(&( + op.sender, + op.nonce, + op.callData.clone(), + )), + ); + + let payload = parse_signature(&op.signature); + self.validate_pbh_payload(transaction, &payload)?; + + Ok::<(), TransactionValidationError>(()) + })?; + } + + transaction.set_valid_pbh(); + } + + Ok(()) + } } impl TransactionValidator for WorldChainTransactionValidator @@ -174,12 +243,11 @@ where origin: TransactionOrigin, transaction: Self::Transaction, ) -> TransactionValidationOutcome { - // TODO: Extend Validation logic for 4337 Architecture - // if let Some(pbh_payload) = transaction.pbh_payload() { - // if let Err(e) = self.validate_pbh_payload(&transaction, pbh_payload) { - // return e.to_outcome(transaction); - // } - // }; + if transaction.to().unwrap_or_default() == self.pbh_validator { + if let Err(e) = self.validate_pbh_bundle(&transaction) { + return e.to_outcome(transaction); + } + }; self.inner.validate_one(origin, transaction.clone()) } @@ -191,6 +259,11 @@ where } } +pub fn parse_signature(_signature: &Bytes) -> PbhPayload { + // TODO: Figure out signature scheme then implement this + PbhPayload::default() +} + #[cfg(test)] pub mod tests { use chrono::{TimeZone, Utc}; From 5d9ef179598aef779604d5705b0c3b636495fe9d Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Mon, 16 Dec 2024 13:15:16 -0700 Subject: [PATCH 48/59] feat: parse PbhPayload from UO signature --- world-chain-builder/Cargo.lock | 1 + .../crates/world/node/src/args.rs | 2 +- .../crates/world/node/src/node.rs | 2 +- .../crates/world/payload/src/builder.rs | 4 +-- .../crates/world/pool/Cargo.toml | 1 + .../crates/world/pool/src/builder.rs | 12 +++++-- .../crates/world/pool/src/error.rs | 2 ++ .../crates/world/pool/src/lib.rs | 2 +- .../crates/world/pool/src/test_utils.rs | 9 +++++- .../crates/world/pool/src/validator.rs | 32 +++++++++++-------- 10 files changed, 44 insertions(+), 23 deletions(-) diff --git a/world-chain-builder/Cargo.lock b/world-chain-builder/Cargo.lock index 7b4bd8a4..d469e01c 100644 --- a/world-chain-builder/Cargo.lock +++ b/world-chain-builder/Cargo.lock @@ -13827,6 +13827,7 @@ dependencies = [ "alloy-consensus 0.7.3", "alloy-eips 0.7.3", "alloy-primitives", + "alloy-rlp", "alloy-rpc-types", "alloy-sol-types", "bon", diff --git a/world-chain-builder/crates/world/node/src/args.rs b/world-chain-builder/crates/world/node/src/args.rs index bacc16c0..c3760de5 100644 --- a/world-chain-builder/crates/world/node/src/args.rs +++ b/world-chain-builder/crates/world/node/src/args.rs @@ -1,6 +1,6 @@ +use alloy_primitives::Address; use clap::value_parser; use reth_optimism_node::args::RollupArgs; -use alloy_primitives::Address; /// Parameters for rollup configuration #[derive(Debug, Clone, Default, PartialEq, Eq, clap::Args)] pub struct ExtArgs { diff --git a/world-chain-builder/crates/world/node/src/node.rs b/world-chain-builder/crates/world/node/src/node.rs index 086583cf..45187273 100644 --- a/world-chain-builder/crates/world/node/src/node.rs +++ b/world-chain-builder/crates/world/node/src/node.rs @@ -104,7 +104,7 @@ impl WorldChainBuilder { num_pbh_txs, db.clone(), pbh_validator, - signature_aggregator + signature_aggregator, )) .payload(WorldChainPayloadBuilder::new( compute_pending_block, diff --git a/world-chain-builder/crates/world/payload/src/builder.rs b/world-chain-builder/crates/world/payload/src/builder.rs index 86d06121..5f3982c9 100644 --- a/world-chain-builder/crates/world/payload/src/builder.rs +++ b/world-chain-builder/crates/world/payload/src/builder.rs @@ -325,8 +325,8 @@ where // system txs, hence on_missing_payload we return [MissingPayloadBehaviour::AwaitInProgress]. fn build_empty_payload( &self, - client: &Client, - config: PayloadConfig, + _client: &Client, + _config: PayloadConfig, ) -> Result { // TODO: // let args = BuildArguments { diff --git a/world-chain-builder/crates/world/pool/Cargo.toml b/world-chain-builder/crates/world/pool/Cargo.toml index fe2a7d24..3451c3f8 100644 --- a/world-chain-builder/crates/world/pool/Cargo.toml +++ b/world-chain-builder/crates/world/pool/Cargo.toml @@ -28,6 +28,7 @@ alloy-primitives.workspace = true alloy-rpc-types.workspace = true alloy-eips.workspace = true alloy-sol-types.workspace = true +alloy-rlp.workspace = true # 3rd party tokio.workspace = true diff --git a/world-chain-builder/crates/world/pool/src/builder.rs b/world-chain-builder/crates/world/pool/src/builder.rs index d0081907..1e76ab2f 100644 --- a/world-chain-builder/crates/world/pool/src/builder.rs +++ b/world-chain-builder/crates/world/pool/src/builder.rs @@ -1,5 +1,6 @@ use std::sync::Arc; +use alloy_primitives::Address; use reth::builder::components::PoolBuilder; use reth::builder::{BuilderContext, FullNodeTypes, NodeTypes}; use reth::transaction_pool::blobstore::DiskFileBlobStore; @@ -10,7 +11,6 @@ use reth_optimism_node::txpool::OpTransactionValidator; use reth_optimism_primitives::OpPrimitives; use reth_provider::CanonStateSubscriptions; use tracing::{debug, info}; -use alloy_primitives::Address; use super::validator::WorldChainTransactionPool; use crate::ordering::WorldChainOrdering; @@ -31,13 +31,19 @@ pub struct WorldChainPoolBuilder { } impl WorldChainPoolBuilder { - pub fn new(clear_nullifiers: bool, num_pbh_txs: u16, db: Arc, pbh_validator: Address, pbh_signature_aggregator: Address) -> Self { + pub fn new( + clear_nullifiers: bool, + num_pbh_txs: u16, + db: Arc, + pbh_validator: Address, + pbh_signature_aggregator: Address, + ) -> Self { Self { clear_nullifiers, num_pbh_txs, db, pbh_validator, - pbh_signature_aggregator + pbh_signature_aggregator, } } } diff --git a/world-chain-builder/crates/world/pool/src/error.rs b/world-chain-builder/crates/world/pool/src/error.rs index e2456704..ae10f5b2 100644 --- a/world-chain-builder/crates/world/pool/src/error.rs +++ b/world-chain-builder/crates/world/pool/src/error.rs @@ -27,6 +27,8 @@ pub enum WorldChainTransactionPoolInvalid { DuplicateTxHash, #[error("invalid root")] InvalidRoot, + #[error(transparent)] + MalformedSignature(#[from] alloy_rlp::Error), } #[derive(Debug, thiserror::Error)] diff --git a/world-chain-builder/crates/world/pool/src/lib.rs b/world-chain-builder/crates/world/pool/src/lib.rs index 8f76f5f0..01676dab 100644 --- a/world-chain-builder/crates/world/pool/src/lib.rs +++ b/world-chain-builder/crates/world/pool/src/lib.rs @@ -1,3 +1,4 @@ +pub mod bindings; pub mod builder; pub mod error; pub mod noop; @@ -5,7 +6,6 @@ pub mod ordering; pub mod root; pub mod tx; pub mod validator; -pub mod bindings; #[cfg(any(feature = "test", test))] pub mod test_utils; diff --git a/world-chain-builder/crates/world/pool/src/test_utils.rs b/world-chain-builder/crates/world/pool/src/test_utils.rs index 907d38f4..1989a28b 100644 --- a/world-chain-builder/crates/world/pool/src/test_utils.rs +++ b/world-chain-builder/crates/world/pool/src/test_utils.rs @@ -70,7 +70,14 @@ pub fn world_chain_validator( let path = temp_dir.path().join("db"); let db = load_world_chain_db(&path, false).unwrap(); let root_validator = WorldChainRootValidator::new(client).unwrap(); - WorldChainTransactionValidator::new(validator, root_validator, db, 30, Address::default(), Address::default()) + WorldChainTransactionValidator::new( + validator, + root_validator, + db, + 30, + Address::default(), + Address::default(), + ) } pub fn valid_pbh_payload( diff --git a/world-chain-builder/crates/world/pool/src/validator.rs b/world-chain-builder/crates/world/pool/src/validator.rs index 66c4d2a1..56ca9b41 100644 --- a/world-chain-builder/crates/world/pool/src/validator.rs +++ b/world-chain-builder/crates/world/pool/src/validator.rs @@ -1,12 +1,11 @@ //! World Chain transaction pool types use std::sync::Arc; -use crate::bindings::{IEntryPoint, IPBHValidator}; +use crate::bindings::IPBHValidator; use alloy_primitives::{Address, Bytes, U256}; -use alloy_sol_types::abi::encode_sequence; +use alloy_rlp::Decodable; use alloy_sol_types::{SolCall, SolValue}; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; -use reth::transaction_pool::validate::TransactionValidatorError; use reth::transaction_pool::{ Pool, TransactionOrigin, TransactionValidationOutcome, TransactionValidationTaskExecutor, TransactionValidator, @@ -15,9 +14,8 @@ use reth_db::cursor::DbCursorRW; use reth_db::transaction::{DbTx, DbTxMut}; use reth_db::{Database, DatabaseEnv, DatabaseError}; use reth_optimism_node::txpool::OpTransactionValidator; -use reth_primitives::{SealedBlock, TransactionSigned}; +use reth_primitives::{Block, SealedBlock, TransactionSigned}; use reth_provider::{BlockReaderIdExt, StateProviderFactory}; -use revm_primitives::hex::encode_prefixed; use semaphore::hash_to_field; use semaphore::protocol::verify_proof; use world_chain_builder_db::{EmptyValue, ValidatedPbhTransaction}; @@ -141,8 +139,8 @@ where pub fn validate_pbh_payload( &self, - transaction: &Tx, payload: &PbhPayload, + signal: U256, ) -> Result<(), TransactionValidationError> { self.validate_root(payload)?; let date = chrono::Utc::now(); @@ -157,7 +155,7 @@ where let res = verify_proof( payload.root, payload.nullifier_hash, - hash_to_field(transaction.hash().as_ref()), + signal, hash_to_field(payload.external_nullifier.as_bytes()), &payload.proof.0, TREE_DEPTH, @@ -209,7 +207,7 @@ where for user_op in calldata._0 { user_op.userOps.par_iter().try_for_each(|op| { // TODO: Decode the PbhPayload from the signature - let _signal = alloy_primitives::keccak256( + let signal = alloy_primitives::keccak256( <(Address, U256, Bytes) as SolValue>::abi_encode_packed(&( op.sender, op.nonce, @@ -217,8 +215,11 @@ where )), ); - let payload = parse_signature(&op.signature); - self.validate_pbh_payload(transaction, &payload)?; + let payload = parse_signature(&op.signature) + .map_err(WorldChainTransactionPoolInvalid::from) + .map_err(TransactionValidationError::from)?; + + self.validate_pbh_payload(&payload, hash_to_field(signal.as_ref()))?; Ok::<(), TransactionValidationError>(()) })?; @@ -233,7 +234,7 @@ where impl TransactionValidator for WorldChainTransactionValidator where - Client: StateProviderFactory + BlockReaderIdExt, + Client: StateProviderFactory + BlockReaderIdExt, Tx: WorldChainPoolTransaction, { type Transaction = Tx; @@ -259,9 +260,12 @@ where } } -pub fn parse_signature(_signature: &Bytes) -> PbhPayload { - // TODO: Figure out signature scheme then implement this - PbhPayload::default() +/// Parse the [`PbhPayload`] from a `UserOperation` signature +pub fn parse_signature(signature: &Bytes) -> Result { + // First 65 bytes are the signature + let signature = signature.as_ref(); + let mut buff = &signature[65..]; + PbhPayload::decode(&mut buff) } #[cfg(test)] From f3fceeb3f7be9ac0b68690e085cdc065663bbb4c Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Mon, 16 Dec 2024 14:17:32 -0700 Subject: [PATCH 49/59] wip --- world-chain-builder/Cargo.lock | 2 + .../crates/world/pool/Cargo.toml | 8 ++- .../crates/world/pool/src/test_utils.rs | 67 +++++++++++++++++-- .../crates/world/pool/src/validator.rs | 50 +++++++------- 4 files changed, 96 insertions(+), 31 deletions(-) diff --git a/world-chain-builder/Cargo.lock b/world-chain-builder/Cargo.lock index d469e01c..b10f34a0 100644 --- a/world-chain-builder/Cargo.lock +++ b/world-chain-builder/Cargo.lock @@ -13829,6 +13829,7 @@ dependencies = [ "alloy-primitives", "alloy-rlp", "alloy-rpc-types", + "alloy-signer-local", "alloy-sol-types", "bon", "chrono", @@ -13838,6 +13839,7 @@ dependencies = [ "rayon", "reth", "reth-db", + "reth-e2e-test-utils", "reth-eth-wire-types", "reth-optimism-chainspec", "reth-optimism-node", diff --git a/world-chain-builder/crates/world/pool/Cargo.toml b/world-chain-builder/crates/world/pool/Cargo.toml index 3451c3f8..d78efaac 100644 --- a/world-chain-builder/crates/world/pool/Cargo.toml +++ b/world-chain-builder/crates/world/pool/Cargo.toml @@ -17,7 +17,7 @@ reth-optimism-node.workspace = true reth-primitives.workspace = true reth-provider.workspace = true reth-eth-wire-types.workspace = true - +reth-e2e-test-utils = { workspace = true, optional = true} reth-optimism-primitives.workspace = true reth-optimism-chainspec.workspace = true @@ -29,6 +29,7 @@ alloy-rpc-types.workspace = true alloy-eips.workspace = true alloy-sol-types.workspace = true alloy-rlp.workspace = true +alloy-signer-local = { workspace = true, optional = true } # 3rd party tokio.workspace = true @@ -48,7 +49,10 @@ test-case.workspace = true [features] default = [] -test = [] +test = [ + "dep:reth-e2e-test-utils", + "dep:alloy-signer-local", +] [lints] workspace = true diff --git a/world-chain-builder/crates/world/pool/src/test_utils.rs b/world-chain-builder/crates/world/pool/src/test_utils.rs index 1989a28b..b362b543 100644 --- a/world-chain-builder/crates/world/pool/src/test_utils.rs +++ b/world-chain-builder/crates/world/pool/src/test_utils.rs @@ -1,30 +1,41 @@ use std::sync::Arc; +use crate::bindings::IEntryPoint::{PackedUserOperation, UserOpsPerAggregator}; +use crate::bindings::IPBHValidator::{handleAggregatedOpsCall, IPBHValidatorCalls}; +use crate::root::WorldChainRootValidator; +use crate::tx::WorldChainPooledTransaction; +use crate::validator::WorldChainTransactionValidator; use alloy_eips::eip2718::Decodable2718; +use alloy_eips::eip2718::Encodable2718; +use alloy_primitives::{address, keccak256, Bytes, U256}; +use alloy_rlp::Encodable; +use alloy_rpc_types::{TransactionInput, TransactionRequest}; +use alloy_signer_local::LocalSigner; +use alloy_sol_types::{SolInterface, SolValue}; use chrono::Utc; use parking_lot::RwLock; use reth::chainspec::MAINNET; use reth::transaction_pool::blobstore::InMemoryBlobStore; use reth::transaction_pool::validate::EthTransactionValidatorBuilder; use reth::transaction_pool::{EthPooledTransaction, PoolTransaction as _}; +use reth_e2e_test_utils::transaction::TransactionTestContext; use reth_optimism_node::txpool::OpTransactionValidator; use reth_primitives::PooledTransactionsElement; use reth_provider::test_utils::MockEthProvider; -use revm_primitives::{hex, Address}; +use revm_primitives::{hex, Address, TxKind}; use semaphore::identity::Identity; use semaphore::poseidon_tree::LazyPoseidonTree; use semaphore::protocol::{generate_nullifier_hash, generate_proof}; use semaphore::{hash_to_field, Field}; use tempfile::tempdir; - -use crate::root::WorldChainRootValidator; -use crate::tx::WorldChainPooledTransaction; -use crate::validator::WorldChainTransactionValidator; use world_chain_builder_db::load_world_chain_db; use world_chain_builder_pbh::date_marker::DateMarker; use world_chain_builder_pbh::external_nullifier::{ExternalNullifier, Prefix}; use world_chain_builder_pbh::payload::{PbhPayload, Proof, TREE_DEPTH}; +pub const PBH_TEST_SIGNATURE_AGGREGATOR: Address = + address!("dEAD000000000000000042069420694206942069"); + pub fn get_eth_transaction() -> EthPooledTransaction { let raw = "0x02f914950181ad84b2d05e0085117553845b830f7df88080b9143a6040608081523462000414576200133a803803806200001e8162000419565b9283398101608082820312620004145781516001600160401b03908181116200041457826200004f9185016200043f565b92602092838201519083821162000414576200006d9183016200043f565b8186015190946001600160a01b03821692909183900362000414576060015190805193808511620003145760038054956001938488811c9816801562000409575b89891014620003f3578190601f988981116200039d575b50899089831160011462000336576000926200032a575b505060001982841b1c191690841b1781555b8751918211620003145760049788548481811c9116801562000309575b89821014620002f457878111620002a9575b5087908784116001146200023e5793839491849260009562000232575b50501b92600019911b1c19161785555b6005556007805460ff60a01b19169055600880546001600160a01b0319169190911790553015620001f3575060025469d3c21bcecceda100000092838201809211620001de57506000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9160025530835282815284832084815401905584519384523093a351610e889081620004b28239f35b601190634e487b7160e01b6000525260246000fd5b90606493519262461bcd60e51b845283015260248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152fd5b0151935038806200013a565b9190601f198416928a600052848a6000209460005b8c8983831062000291575050501062000276575b50505050811b0185556200014a565b01519060f884600019921b161c191690553880808062000267565b86860151895590970196948501948893500162000253565b89600052886000208880860160051c8201928b8710620002ea575b0160051c019085905b828110620002dd5750506200011d565b60008155018590620002cd565b92508192620002c4565b60228a634e487b7160e01b6000525260246000fd5b90607f16906200010b565b634e487b7160e01b600052604160045260246000fd5b015190503880620000dc565b90869350601f19831691856000528b6000209260005b8d8282106200038657505084116200036d575b505050811b018155620000ee565b015160001983861b60f8161c191690553880806200035f565b8385015186558a979095019493840193016200034c565b90915083600052896000208980850160051c8201928c8610620003e9575b918891869594930160051c01915b828110620003d9575050620000c5565b60008155859450889101620003c9565b92508192620003bb565b634e487b7160e01b600052602260045260246000fd5b97607f1697620000ae565b600080fd5b6040519190601f01601f191682016001600160401b038111838210176200031457604052565b919080601f84011215620004145782516001600160401b038111620003145760209062000475601f8201601f1916830162000419565b92818452828287010111620004145760005b8181106200049d57508260009394955001015290565b85810183015184820184015282016200048756fe608060408181526004918236101561001657600080fd5b600092833560e01c91826306fdde0314610a1c57508163095ea7b3146109f257816318160ddd146109d35781631b4c84d2146109ac57816323b872dd14610833578163313ce5671461081757816339509351146107c357816370a082311461078c578163715018a6146107685781638124f7ac146107495781638da5cb5b1461072057816395d89b411461061d578163a457c2d714610575578163a9059cbb146104e4578163c9567bf914610120575063dd62ed3e146100d557600080fd5b3461011c578060031936011261011c57806020926100f1610b5a565b6100f9610b75565b6001600160a01b0391821683526001865283832091168252845220549051908152f35b5080fd5b905082600319360112610338576008546001600160a01b039190821633036104975760079283549160ff8360a01c1661045557737a250d5630b4cf539739df2c5dacb4c659f2488d92836bffffffffffffffffffffffff60a01b8092161786553087526020938785528388205430156104065730895260018652848920828a52865280858a205584519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925863092a38554835163c45a015560e01b815290861685828581845afa9182156103dd57849187918b946103e7575b5086516315ab88c960e31b815292839182905afa9081156103dd576044879289928c916103c0575b508b83895196879586946364e329cb60e11b8652308c870152166024850152165af19081156103b6579086918991610389575b50169060065416176006558385541660604730895288865260c4858a20548860085416928751958694859363f305d71960e01b8552308a86015260248501528d60448501528d606485015260848401524260a48401525af1801561037f579084929161034c575b50604485600654169587541691888551978894859363095ea7b360e01b855284015260001960248401525af1908115610343575061030c575b5050805460ff60a01b1916600160a01b17905580f35b81813d831161033c575b6103208183610b8b565b8101031261033857518015150361011c5738806102f6565b8280fd5b503d610316565b513d86823e3d90fd5b6060809293503d8111610378575b6103648183610b8b565b81010312610374578290386102bd565b8580fd5b503d61035a565b83513d89823e3d90fd5b6103a99150863d88116103af575b6103a18183610b8b565b810190610e33565b38610256565b503d610397565b84513d8a823e3d90fd5b6103d79150843d86116103af576103a18183610b8b565b38610223565b85513d8b823e3d90fd5b6103ff919450823d84116103af576103a18183610b8b565b92386101fb565b845162461bcd60e51b81528085018790526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b6020606492519162461bcd60e51b8352820152601760248201527f74726164696e6720697320616c7265616479206f70656e0000000000000000006044820152fd5b608490602084519162461bcd60e51b8352820152602160248201527f4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f6044820152603760f91b6064820152fd5b9050346103385781600319360112610338576104fe610b5a565b9060243593303303610520575b602084610519878633610bc3565b5160018152f35b600594919454808302908382041483151715610562576127109004820391821161054f5750925080602061050b565b634e487b7160e01b815260118552602490fd5b634e487b7160e01b825260118652602482fd5b9050823461061a578260031936011261061a57610590610b5a565b918360243592338152600160205281812060018060a01b03861682526020522054908282106105c9576020856105198585038733610d31565b608490602086519162461bcd60e51b8352820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152fd5b80fd5b83833461011c578160031936011261011c57805191809380549160019083821c92828516948515610716575b6020958686108114610703578589529081156106df5750600114610687575b6106838787610679828c0383610b8b565b5191829182610b11565b0390f35b81529295507f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b8284106106cc57505050826106839461067992820101948680610668565b80548685018801529286019281016106ae565b60ff19168887015250505050151560051b8301019250610679826106838680610668565b634e487b7160e01b845260228352602484fd5b93607f1693610649565b50503461011c578160031936011261011c5760085490516001600160a01b039091168152602090f35b50503461011c578160031936011261011c576020906005549051908152f35b833461061a578060031936011261061a57600880546001600160a01b031916905580f35b50503461011c57602036600319011261011c5760209181906001600160a01b036107b4610b5a565b16815280845220549051908152f35b82843461061a578160031936011261061a576107dd610b5a565b338252600160209081528383206001600160a01b038316845290528282205460243581019290831061054f57602084610519858533610d31565b50503461011c578160031936011261011c576020905160128152f35b83833461011c57606036600319011261011c5761084e610b5a565b610856610b75565b6044359160018060a01b0381169485815260209560018752858220338352875285822054976000198903610893575b505050906105199291610bc3565b85891061096957811561091a5733156108cc5750948481979861051997845260018a528284203385528a52039120558594938780610885565b865162461bcd60e51b8152908101889052602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608490fd5b865162461bcd60e51b81529081018890526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b865162461bcd60e51b8152908101889052601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606490fd5b50503461011c578160031936011261011c5760209060ff60075460a01c1690519015158152f35b50503461011c578160031936011261011c576020906002549051908152f35b50503461011c578060031936011261011c57602090610519610a12610b5a565b6024359033610d31565b92915034610b0d5783600319360112610b0d57600354600181811c9186908281168015610b03575b6020958686108214610af05750848852908115610ace5750600114610a75575b6106838686610679828b0383610b8b565b929550600383527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b828410610abb575050508261068394610679928201019438610a64565b8054868501880152928601928101610a9e565b60ff191687860152505050151560051b83010192506106798261068338610a64565b634e487b7160e01b845260229052602483fd5b93607f1693610a44565b8380fd5b6020808252825181830181905290939260005b828110610b4657505060409293506000838284010152601f8019910116010190565b818101860151848201604001528501610b24565b600435906001600160a01b0382168203610b7057565b600080fd5b602435906001600160a01b0382168203610b7057565b90601f8019910116810190811067ffffffffffffffff821117610bad57604052565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03908116918215610cde5716918215610c8d57600082815280602052604081205491808310610c3957604082827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef958760209652828652038282205586815220818154019055604051908152a3565b60405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608490fd5b6001600160a01b03908116918215610de25716918215610d925760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925918360005260018252604060002085600052825280604060002055604051908152a3565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608490fd5b60405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b90816020910312610b7057516001600160a01b0381168103610b70579056fea2646970667358221220285c200b3978b10818ff576bb83f2dc4a2a7c98dfb6a36ea01170de792aa652764736f6c63430008140033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000d3fd4f95820a9aa848ce716d6c200eaefb9a2e4900000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000003543131000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035431310000000000000000000000000000000000000000000000000000000000c001a04e551c75810ffdfe6caff57da9f5a8732449f42f0f4c57f935b05250a76db3b6a046cd47e6d01914270c1ec0d9ac7fae7dfb240ec9a8b6ec7898c4d6aa174388f2"; @@ -43,6 +54,52 @@ pub fn get_non_pbh_transaction() -> WorldChainPooledTransaction { } } +pub async fn get_pbh_4337_transaction() -> WorldChainPooledTransaction { + let signal = keccak256(<(Address, U256, Bytes) as SolValue>::abi_encode_packed(&( + Address::with_last_byte(0xab), + U256::ZERO, + Bytes::default(), + ))); + let pbh_payload = valid_pbh_payload(&mut [0; 32], signal.as_ref(), chrono::Utc::now(), 0); + let aggregated_signature = vec![pbh_payload]; + let mut buff = Vec::new(); + aggregated_signature.encode(&mut buff); + + let calldata = IPBHValidatorCalls::handleAggregatedOps(handleAggregatedOpsCall { + _0: vec![UserOpsPerAggregator { + userOps: vec![PackedUserOperation::default()], + signature: buff.into(), + aggregator: PBH_TEST_SIGNATURE_AGGREGATOR, + }], + _1: alloy_sol_types::private::Address::ZERO, + }); + let tx = TransactionRequest { + nonce: Some(0), + value: Some(U256::ZERO), + to: Some(TxKind::Call(Address::ZERO)), + gas: Some(210000), + max_fee_per_gas: Some(20e10 as u128), + max_priority_fee_per_gas: Some(20e10 as u128), + chain_id: Some(1), + input: TransactionInput { + input: Some(calldata.abi_encode().into()), + ..Default::default() + }, + ..Default::default() + }; + + let envelope = TransactionTestContext::sign_tx(LocalSigner::random(), tx).await; + let raw_tx = envelope.encoded_2718(); + let mut data = raw_tx.as_ref(); + let recovered = PooledTransactionsElement::decode_2718(&mut data).unwrap(); + let eth_tx: EthPooledTransaction = recovered.try_into_ecrecovered().unwrap().into(); + WorldChainPooledTransaction { + inner: eth_tx, + valid_pbh: Arc::new(RwLock::new(false)), + conditional_options: None, + } +} + pub fn get_pbh_transaction(nonce: u16) -> WorldChainPooledTransaction { let eth_tx = get_eth_transaction(); let _pbh_payload = valid_pbh_payload( diff --git a/world-chain-builder/crates/world/pool/src/validator.rs b/world-chain-builder/crates/world/pool/src/validator.rs index 56ca9b41..5a18ad15 100644 --- a/world-chain-builder/crates/world/pool/src/validator.rs +++ b/world-chain-builder/crates/world/pool/src/validator.rs @@ -5,12 +5,13 @@ use crate::bindings::IPBHValidator; use alloy_primitives::{Address, Bytes, U256}; use alloy_rlp::Decodable; use alloy_sol_types::{SolCall, SolValue}; -use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; +use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator}; use reth::transaction_pool::{ Pool, TransactionOrigin, TransactionValidationOutcome, TransactionValidationTaskExecutor, TransactionValidator, }; use reth_db::cursor::DbCursorRW; +use reth_db::mdbx::cursor::decode; use reth_db::transaction::{DbTx, DbTxMut}; use reth_db::{Database, DatabaseEnv, DatabaseError}; use reth_optimism_node::txpool::OpTransactionValidator; @@ -204,25 +205,27 @@ where pub fn validate_pbh_bundle(&self, transaction: &Tx) -> Result<(), TransactionValidationError> { if let Some(calldata) = self.is_valid_eip4337_pbh_bundle(transaction) { - for user_op in calldata._0 { - user_op.userOps.par_iter().try_for_each(|op| { - // TODO: Decode the PbhPayload from the signature - let signal = alloy_primitives::keccak256( - <(Address, U256, Bytes) as SolValue>::abi_encode_packed(&( - op.sender, - op.nonce, - op.callData.clone(), - )), - ); - - let payload = parse_signature(&op.signature) - .map_err(WorldChainTransactionPoolInvalid::from) - .map_err(TransactionValidationError::from)?; - - self.validate_pbh_payload(&payload, hash_to_field(signal.as_ref()))?; - - Ok::<(), TransactionValidationError>(()) - })?; + for aggregated_ops in calldata._0 { + let mut buff = aggregated_ops.signature.as_ref(); + let pbh_payloads = >::decode(&mut buff) + .map_err(WorldChainTransactionPoolInvalid::from) + .map_err(TransactionValidationError::from)?; + + pbh_payloads.par_iter().zip(aggregated_ops.userOps).try_for_each( + |(payload, op)| { + let signal = alloy_primitives::keccak256( + <(Address, U256, Bytes) as SolValue>::abi_encode_packed(&( + op.sender, + op.nonce, + op.callData, + )), + ); + + self.validate_pbh_payload(&payload, hash_to_field(signal.as_ref()))?; + + Ok::<(), TransactionValidationError>(()) + }, + )?; } transaction.set_valid_pbh(); @@ -270,6 +273,9 @@ pub fn parse_signature(signature: &Bytes) -> Result Date: Mon, 16 Dec 2024 14:39:54 -0700 Subject: [PATCH 50/59] test: add 4337 bundle validation tests --- .../crates/world/pool/Cargo.toml | 2 + .../crates/world/pool/src/test_utils.rs | 30 ++++++--- .../crates/world/pool/src/validator.rs | 61 +++++++++++++++++-- 3 files changed, 78 insertions(+), 15 deletions(-) diff --git a/world-chain-builder/crates/world/pool/Cargo.toml b/world-chain-builder/crates/world/pool/Cargo.toml index d78efaac..4d5c3e8b 100644 --- a/world-chain-builder/crates/world/pool/Cargo.toml +++ b/world-chain-builder/crates/world/pool/Cargo.toml @@ -46,6 +46,8 @@ rayon.workspace = true [dev-dependencies] ethers-core.workspace = true test-case.workspace = true +alloy-signer-local.workspace = true +reth-e2e-test-utils.workspace = true [features] default = [] diff --git a/world-chain-builder/crates/world/pool/src/test_utils.rs b/world-chain-builder/crates/world/pool/src/test_utils.rs index b362b543..66d3bd66 100644 --- a/world-chain-builder/crates/world/pool/src/test_utils.rs +++ b/world-chain-builder/crates/world/pool/src/test_utils.rs @@ -36,6 +36,8 @@ use world_chain_builder_pbh::payload::{PbhPayload, Proof, TREE_DEPTH}; pub const PBH_TEST_SIGNATURE_AGGREGATOR: Address = address!("dEAD000000000000000042069420694206942069"); +pub const PBH_TEST_VALIDATOR: Address = address!("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); + pub fn get_eth_transaction() -> EthPooledTransaction { let raw = "0x02f914950181ad84b2d05e0085117553845b830f7df88080b9143a6040608081523462000414576200133a803803806200001e8162000419565b9283398101608082820312620004145781516001600160401b03908181116200041457826200004f9185016200043f565b92602092838201519083821162000414576200006d9183016200043f565b8186015190946001600160a01b03821692909183900362000414576060015190805193808511620003145760038054956001938488811c9816801562000409575b89891014620003f3578190601f988981116200039d575b50899089831160011462000336576000926200032a575b505060001982841b1c191690841b1781555b8751918211620003145760049788548481811c9116801562000309575b89821014620002f457878111620002a9575b5087908784116001146200023e5793839491849260009562000232575b50501b92600019911b1c19161785555b6005556007805460ff60a01b19169055600880546001600160a01b0319169190911790553015620001f3575060025469d3c21bcecceda100000092838201809211620001de57506000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9160025530835282815284832084815401905584519384523093a351610e889081620004b28239f35b601190634e487b7160e01b6000525260246000fd5b90606493519262461bcd60e51b845283015260248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152fd5b0151935038806200013a565b9190601f198416928a600052848a6000209460005b8c8983831062000291575050501062000276575b50505050811b0185556200014a565b01519060f884600019921b161c191690553880808062000267565b86860151895590970196948501948893500162000253565b89600052886000208880860160051c8201928b8710620002ea575b0160051c019085905b828110620002dd5750506200011d565b60008155018590620002cd565b92508192620002c4565b60228a634e487b7160e01b6000525260246000fd5b90607f16906200010b565b634e487b7160e01b600052604160045260246000fd5b015190503880620000dc565b90869350601f19831691856000528b6000209260005b8d8282106200038657505084116200036d575b505050811b018155620000ee565b015160001983861b60f8161c191690553880806200035f565b8385015186558a979095019493840193016200034c565b90915083600052896000208980850160051c8201928c8610620003e9575b918891869594930160051c01915b828110620003d9575050620000c5565b60008155859450889101620003c9565b92508192620003bb565b634e487b7160e01b600052602260045260246000fd5b97607f1697620000ae565b600080fd5b6040519190601f01601f191682016001600160401b038111838210176200031457604052565b919080601f84011215620004145782516001600160401b038111620003145760209062000475601f8201601f1916830162000419565b92818452828287010111620004145760005b8181106200049d57508260009394955001015290565b85810183015184820184015282016200048756fe608060408181526004918236101561001657600080fd5b600092833560e01c91826306fdde0314610a1c57508163095ea7b3146109f257816318160ddd146109d35781631b4c84d2146109ac57816323b872dd14610833578163313ce5671461081757816339509351146107c357816370a082311461078c578163715018a6146107685781638124f7ac146107495781638da5cb5b1461072057816395d89b411461061d578163a457c2d714610575578163a9059cbb146104e4578163c9567bf914610120575063dd62ed3e146100d557600080fd5b3461011c578060031936011261011c57806020926100f1610b5a565b6100f9610b75565b6001600160a01b0391821683526001865283832091168252845220549051908152f35b5080fd5b905082600319360112610338576008546001600160a01b039190821633036104975760079283549160ff8360a01c1661045557737a250d5630b4cf539739df2c5dacb4c659f2488d92836bffffffffffffffffffffffff60a01b8092161786553087526020938785528388205430156104065730895260018652848920828a52865280858a205584519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925863092a38554835163c45a015560e01b815290861685828581845afa9182156103dd57849187918b946103e7575b5086516315ab88c960e31b815292839182905afa9081156103dd576044879289928c916103c0575b508b83895196879586946364e329cb60e11b8652308c870152166024850152165af19081156103b6579086918991610389575b50169060065416176006558385541660604730895288865260c4858a20548860085416928751958694859363f305d71960e01b8552308a86015260248501528d60448501528d606485015260848401524260a48401525af1801561037f579084929161034c575b50604485600654169587541691888551978894859363095ea7b360e01b855284015260001960248401525af1908115610343575061030c575b5050805460ff60a01b1916600160a01b17905580f35b81813d831161033c575b6103208183610b8b565b8101031261033857518015150361011c5738806102f6565b8280fd5b503d610316565b513d86823e3d90fd5b6060809293503d8111610378575b6103648183610b8b565b81010312610374578290386102bd565b8580fd5b503d61035a565b83513d89823e3d90fd5b6103a99150863d88116103af575b6103a18183610b8b565b810190610e33565b38610256565b503d610397565b84513d8a823e3d90fd5b6103d79150843d86116103af576103a18183610b8b565b38610223565b85513d8b823e3d90fd5b6103ff919450823d84116103af576103a18183610b8b565b92386101fb565b845162461bcd60e51b81528085018790526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b6020606492519162461bcd60e51b8352820152601760248201527f74726164696e6720697320616c7265616479206f70656e0000000000000000006044820152fd5b608490602084519162461bcd60e51b8352820152602160248201527f4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f6044820152603760f91b6064820152fd5b9050346103385781600319360112610338576104fe610b5a565b9060243593303303610520575b602084610519878633610bc3565b5160018152f35b600594919454808302908382041483151715610562576127109004820391821161054f5750925080602061050b565b634e487b7160e01b815260118552602490fd5b634e487b7160e01b825260118652602482fd5b9050823461061a578260031936011261061a57610590610b5a565b918360243592338152600160205281812060018060a01b03861682526020522054908282106105c9576020856105198585038733610d31565b608490602086519162461bcd60e51b8352820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152fd5b80fd5b83833461011c578160031936011261011c57805191809380549160019083821c92828516948515610716575b6020958686108114610703578589529081156106df5750600114610687575b6106838787610679828c0383610b8b565b5191829182610b11565b0390f35b81529295507f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b8284106106cc57505050826106839461067992820101948680610668565b80548685018801529286019281016106ae565b60ff19168887015250505050151560051b8301019250610679826106838680610668565b634e487b7160e01b845260228352602484fd5b93607f1693610649565b50503461011c578160031936011261011c5760085490516001600160a01b039091168152602090f35b50503461011c578160031936011261011c576020906005549051908152f35b833461061a578060031936011261061a57600880546001600160a01b031916905580f35b50503461011c57602036600319011261011c5760209181906001600160a01b036107b4610b5a565b16815280845220549051908152f35b82843461061a578160031936011261061a576107dd610b5a565b338252600160209081528383206001600160a01b038316845290528282205460243581019290831061054f57602084610519858533610d31565b50503461011c578160031936011261011c576020905160128152f35b83833461011c57606036600319011261011c5761084e610b5a565b610856610b75565b6044359160018060a01b0381169485815260209560018752858220338352875285822054976000198903610893575b505050906105199291610bc3565b85891061096957811561091a5733156108cc5750948481979861051997845260018a528284203385528a52039120558594938780610885565b865162461bcd60e51b8152908101889052602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608490fd5b865162461bcd60e51b81529081018890526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b865162461bcd60e51b8152908101889052601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606490fd5b50503461011c578160031936011261011c5760209060ff60075460a01c1690519015158152f35b50503461011c578160031936011261011c576020906002549051908152f35b50503461011c578060031936011261011c57602090610519610a12610b5a565b6024359033610d31565b92915034610b0d5783600319360112610b0d57600354600181811c9186908281168015610b03575b6020958686108214610af05750848852908115610ace5750600114610a75575b6106838686610679828b0383610b8b565b929550600383527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b828410610abb575050508261068394610679928201019438610a64565b8054868501880152928601928101610a9e565b60ff191687860152505050151560051b83010192506106798261068338610a64565b634e487b7160e01b845260229052602483fd5b93607f1693610a44565b8380fd5b6020808252825181830181905290939260005b828110610b4657505060409293506000838284010152601f8019910116010190565b818101860151848201604001528501610b24565b600435906001600160a01b0382168203610b7057565b600080fd5b602435906001600160a01b0382168203610b7057565b90601f8019910116810190811067ffffffffffffffff821117610bad57604052565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03908116918215610cde5716918215610c8d57600082815280602052604081205491808310610c3957604082827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef958760209652828652038282205586815220818154019055604051908152a3565b60405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608490fd5b6001600160a01b03908116918215610de25716918215610d925760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925918360005260018252604060002085600052825280604060002055604051908152a3565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608490fd5b60405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b90816020910312610b7057516001600160a01b0381168103610b70579056fea2646970667358221220285c200b3978b10818ff576bb83f2dc4a2a7c98dfb6a36ea01170de792aa652764736f6c63430008140033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000d3fd4f95820a9aa848ce716d6c200eaefb9a2e4900000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000003543131000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035431310000000000000000000000000000000000000000000000000000000000c001a04e551c75810ffdfe6caff57da9f5a8732449f42f0f4c57f935b05250a76db3b6a046cd47e6d01914270c1ec0d9ac7fae7dfb240ec9a8b6ec7898c4d6aa174388f2"; @@ -54,20 +56,25 @@ pub fn get_non_pbh_transaction() -> WorldChainPooledTransaction { } } -pub async fn get_pbh_4337_transaction() -> WorldChainPooledTransaction { +pub async fn get_pbh_4337_transaction() -> (WorldChainPooledTransaction, U256) { let signal = keccak256(<(Address, U256, Bytes) as SolValue>::abi_encode_packed(&( Address::with_last_byte(0xab), U256::ZERO, Bytes::default(), ))); let pbh_payload = valid_pbh_payload(&mut [0; 32], signal.as_ref(), chrono::Utc::now(), 0); + let root = pbh_payload.root; let aggregated_signature = vec![pbh_payload]; let mut buff = Vec::new(); aggregated_signature.encode(&mut buff); let calldata = IPBHValidatorCalls::handleAggregatedOps(handleAggregatedOpsCall { _0: vec![UserOpsPerAggregator { - userOps: vec![PackedUserOperation::default()], + userOps: vec![PackedUserOperation { + sender: Address::with_last_byte(0xab), + nonce: U256::ZERO, + ..Default::default() + }], signature: buff.into(), aggregator: PBH_TEST_SIGNATURE_AGGREGATOR, }], @@ -76,7 +83,7 @@ pub async fn get_pbh_4337_transaction() -> WorldChainPooledTransaction { let tx = TransactionRequest { nonce: Some(0), value: Some(U256::ZERO), - to: Some(TxKind::Call(Address::ZERO)), + to: Some(TxKind::Call(PBH_TEST_VALIDATOR)), gas: Some(210000), max_fee_per_gas: Some(20e10 as u128), max_priority_fee_per_gas: Some(20e10 as u128), @@ -93,11 +100,14 @@ pub async fn get_pbh_4337_transaction() -> WorldChainPooledTransaction { let mut data = raw_tx.as_ref(); let recovered = PooledTransactionsElement::decode_2718(&mut data).unwrap(); let eth_tx: EthPooledTransaction = recovered.try_into_ecrecovered().unwrap().into(); - WorldChainPooledTransaction { - inner: eth_tx, - valid_pbh: Arc::new(RwLock::new(false)), - conditional_options: None, - } + ( + WorldChainPooledTransaction { + inner: eth_tx, + valid_pbh: Arc::new(RwLock::new(false)), + conditional_options: None, + }, + root, + ) } pub fn get_pbh_transaction(nonce: u16) -> WorldChainPooledTransaction { @@ -132,8 +142,8 @@ pub fn world_chain_validator( root_validator, db, 30, - Address::default(), - Address::default(), + PBH_TEST_VALIDATOR, + PBH_TEST_SIGNATURE_AGGREGATOR, ) } diff --git a/world-chain-builder/crates/world/pool/src/validator.rs b/world-chain-builder/crates/world/pool/src/validator.rs index 5a18ad15..d39e3209 100644 --- a/world-chain-builder/crates/world/pool/src/validator.rs +++ b/world-chain-builder/crates/world/pool/src/validator.rs @@ -11,7 +11,6 @@ use reth::transaction_pool::{ TransactionValidator, }; use reth_db::cursor::DbCursorRW; -use reth_db::mdbx::cursor::decode; use reth_db::transaction::{DbTx, DbTxMut}; use reth_db::{Database, DatabaseEnv, DatabaseError}; use reth_optimism_node::txpool::OpTransactionValidator; @@ -211,8 +210,10 @@ where .map_err(WorldChainTransactionPoolInvalid::from) .map_err(TransactionValidationError::from)?; - pbh_payloads.par_iter().zip(aggregated_ops.userOps).try_for_each( - |(payload, op)| { + pbh_payloads + .par_iter() + .zip(aggregated_ops.userOps) + .try_for_each(|(payload, op)| { let signal = alloy_primitives::keccak256( <(Address, U256, Bytes) as SolValue>::abi_encode_packed(&( op.sender, @@ -224,8 +225,7 @@ where self.validate_pbh_payload(&payload, hash_to_field(signal.as_ref()))?; Ok::<(), TransactionValidationError>(()) - }, - )?; + })?; } transaction.set_valid_pbh(); @@ -341,6 +341,57 @@ pub mod tests { assert!(res.is_err()); } + #[tokio::test] + async fn validate_4337_bundle() { + let validator = world_chain_validator(); + let (transaction, root) = get_pbh_4337_transaction().await; + validator.inner.client().add_account( + transaction.sender(), + ExtendedAccount::new(transaction.nonce(), alloy_primitives::U256::MAX), + ); + // Insert a world id root into the OpWorldId Account + // TODO: This should be set to the root on the Payloads of a Bundle Tx + validator.inner.client().add_account( + OP_WORLD_ID, + ExtendedAccount::new(0, alloy_primitives::U256::ZERO) + .extend_storage(vec![(LATEST_ROOT_SLOT.into(), root)]), + ); + let header = SealedHeader::default(); + let body = BlockBody::default(); + let block = SealedBlock::new(header, body); + + // Propogate the block to the root validator + validator.on_new_head_block(&block); + + let ordering = WorldChainOrdering::default(); + + let pool = Pool::new( + validator, + ordering, + InMemoryBlobStore::default(), + Default::default(), + ); + + let start = chrono::Utc::now(); + let res = pool.add_external_transaction(transaction.clone()).await; + let first_insert = chrono::Utc::now() - start; + println!("first_insert: {first_insert:?}"); + println!("res = {res:#?}"); + assert!(res.is_ok()); + let tx = pool.get(transaction.hash()); + assert!(tx.is_some()); + + let start = chrono::Utc::now(); + let res = pool.add_external_transaction(transaction.clone()).await; + + let second_insert = chrono::Utc::now() - start; + println!("second_insert: {second_insert:?}"); + + // Check here that we're properly caching the transaction + assert!(first_insert > second_insert * 10); + assert!(res.is_err()); + } + #[tokio::test] async fn invalid_external_nullifier_hash() { let validator = world_chain_validator(); From 9a12f853105e1bb3ade3164fb269432927dcee88 Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Mon, 16 Dec 2024 14:47:41 -0700 Subject: [PATCH 51/59] remove parse_signature --- world-chain-builder/crates/world/pool/src/validator.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/world-chain-builder/crates/world/pool/src/validator.rs b/world-chain-builder/crates/world/pool/src/validator.rs index d39e3209..cca6b31e 100644 --- a/world-chain-builder/crates/world/pool/src/validator.rs +++ b/world-chain-builder/crates/world/pool/src/validator.rs @@ -263,14 +263,6 @@ where } } -/// Parse the [`PbhPayload`] from a `UserOperation` signature -pub fn parse_signature(signature: &Bytes) -> Result { - // First 65 bytes are the signature - let signature = signature.as_ref(); - let mut buff = &signature[65..]; - PbhPayload::decode(&mut buff) -} - #[cfg(test)] pub mod tests { use crate::ordering::WorldChainOrdering; From d5a37f66f13f376633739642d5ec93ecf6ca6a8e Mon Sep 17 00:00:00 2001 From: 0xKitsune <0xkitsune@protonmail.com> Date: Mon, 16 Dec 2024 22:55:44 -0500 Subject: [PATCH 52/59] remove rwlock --- .../crates/world/pool/src/test_utils.rs | 6 +++--- .../crates/world/pool/src/tx.rs | 19 +++++++++---------- .../crates/world/pool/src/validator.rs | 9 ++++++--- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/world-chain-builder/crates/world/pool/src/test_utils.rs b/world-chain-builder/crates/world/pool/src/test_utils.rs index 66d3bd66..4032562b 100644 --- a/world-chain-builder/crates/world/pool/src/test_utils.rs +++ b/world-chain-builder/crates/world/pool/src/test_utils.rs @@ -51,7 +51,7 @@ pub fn get_non_pbh_transaction() -> WorldChainPooledTransaction { let eth_tx = get_eth_transaction(); WorldChainPooledTransaction { inner: eth_tx, - valid_pbh: Arc::new(RwLock::new(false)), + valid_pbh: false, conditional_options: None, } } @@ -103,7 +103,7 @@ pub async fn get_pbh_4337_transaction() -> (WorldChainPooledTransaction, U256) { ( WorldChainPooledTransaction { inner: eth_tx, - valid_pbh: Arc::new(RwLock::new(false)), + valid_pbh: false, conditional_options: None, }, root, @@ -120,7 +120,7 @@ pub fn get_pbh_transaction(nonce: u16) -> WorldChainPooledTransaction { ); WorldChainPooledTransaction { inner: eth_tx, - valid_pbh: Arc::new(RwLock::new(false)), + valid_pbh: false, conditional_options: None, } } diff --git a/world-chain-builder/crates/world/pool/src/tx.rs b/world-chain-builder/crates/world/pool/src/tx.rs index 531dd95d..3b0f840f 100644 --- a/world-chain-builder/crates/world/pool/src/tx.rs +++ b/world-chain-builder/crates/world/pool/src/tx.rs @@ -3,7 +3,6 @@ use std::sync::Arc; use alloy_consensus::{BlobTransactionSidecar, BlobTransactionValidationError, Transaction}; use alloy_primitives::TxHash; use alloy_rpc_types::erc4337::ConditionalOptions; -use parking_lot::RwLock; use reth::{ core::primitives::SignedTransaction, transaction_pool::{ @@ -21,14 +20,14 @@ use revm_primitives::{AccessList, Address, KzgSettings, TxKind, U256}; pub trait WorldChainPoolTransaction: EthPoolTransaction { fn valid_pbh(&self) -> bool; - fn set_valid_pbh(&self); + fn set_valid_pbh(&mut self); fn conditional_options(&self) -> Option<&ConditionalOptions>; } #[derive(Debug, Clone)] pub struct WorldChainPooledTransaction { pub inner: EthPooledTransaction, - pub valid_pbh: Arc>, + pub valid_pbh: bool, pub conditional_options: Option, } @@ -60,7 +59,7 @@ impl EthPoolTransaction for WorldChainPooledTransaction { pooled.map(|inner| Self { inner, - valid_pbh: Arc::new(RwLock::new(false)), + valid_pbh: false, conditional_options: None, }) } @@ -88,15 +87,15 @@ impl EthPoolTransaction for WorldChainPooledTransaction { impl WorldChainPoolTransaction for WorldChainPooledTransaction { fn valid_pbh(&self) -> bool { - *self.valid_pbh.read() + self.valid_pbh } fn conditional_options(&self) -> Option<&ConditionalOptions> { self.conditional_options.as_ref() } - fn set_valid_pbh(&self) { - *self.valid_pbh.write() = true; + fn set_valid_pbh(&mut self) { + self.valid_pbh = true; } } @@ -104,7 +103,7 @@ impl From for WorldChainPooledTransaction { fn from(tx: EthPooledTransaction) -> Self { Self { inner: tx, - valid_pbh: Arc::new(RwLock::new(false)), + valid_pbh: false, conditional_options: None, } } @@ -116,7 +115,7 @@ impl From for WorldChainPooledTransaction let inner = EthPooledTransaction::from(tx); Self { inner, - valid_pbh: Arc::new(RwLock::new(false)), + valid_pbh: false, conditional_options: None, } } @@ -129,7 +128,7 @@ impl TryFrom for WorldChainPooledTransaction { let inner = EthPooledTransaction::try_from(tx)?; Ok(Self { inner, - valid_pbh: Arc::new(RwLock::new(false)), + valid_pbh: false, conditional_options: None, }) } diff --git a/world-chain-builder/crates/world/pool/src/validator.rs b/world-chain-builder/crates/world/pool/src/validator.rs index cca6b31e..9cf650bc 100644 --- a/world-chain-builder/crates/world/pool/src/validator.rs +++ b/world-chain-builder/crates/world/pool/src/validator.rs @@ -202,7 +202,10 @@ where } } - pub fn validate_pbh_bundle(&self, transaction: &Tx) -> Result<(), TransactionValidationError> { + pub fn validate_pbh_bundle( + &self, + transaction: &mut Tx, + ) -> Result<(), TransactionValidationError> { if let Some(calldata) = self.is_valid_eip4337_pbh_bundle(transaction) { for aggregated_ops in calldata._0 { let mut buff = aggregated_ops.signature.as_ref(); @@ -245,10 +248,10 @@ where async fn validate_transaction( &self, origin: TransactionOrigin, - transaction: Self::Transaction, + mut transaction: Self::Transaction, ) -> TransactionValidationOutcome { if transaction.to().unwrap_or_default() == self.pbh_validator { - if let Err(e) = self.validate_pbh_bundle(&transaction) { + if let Err(e) = self.validate_pbh_bundle(&mut transaction) { return e.to_outcome(transaction); } }; From 305cc2d8f2f60d0cc63d4c4812e085babebc3c89 Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Mon, 16 Dec 2024 23:45:59 -0700 Subject: [PATCH 53/59] rm mdbx db --- world-chain-builder/Cargo.lock | 17 ---- world-chain-builder/Cargo.toml | 2 - .../crates/world/bin/src/main.rs | 6 +- .../crates/world/db/Cargo.toml | 16 ---- .../crates/world/db/src/lib.rs | 83 ------------------- .../crates/world/node/Cargo.toml | 1 - .../crates/world/node/src/args.rs | 4 - .../crates/world/node/src/node.rs | 25 +----- .../crates/world/node/src/test_utils.rs | 4 +- .../crates/world/node/tests/e2e.rs | 19 ++--- .../crates/world/payload/src/builder.rs | 10 +-- .../crates/world/pool/Cargo.toml | 1 - .../crates/world/pool/src/builder.rs | 8 -- .../crates/world/pool/src/test_utils.rs | 6 -- .../crates/world/pool/src/validator.rs | 52 +----------- 15 files changed, 20 insertions(+), 234 deletions(-) delete mode 100644 world-chain-builder/crates/world/db/Cargo.toml delete mode 100644 world-chain-builder/crates/world/db/src/lib.rs diff --git a/world-chain-builder/Cargo.lock b/world-chain-builder/Cargo.lock index b10f34a0..7588ebfd 100644 --- a/world-chain-builder/Cargo.lock +++ b/world-chain-builder/Cargo.lock @@ -13715,21 +13715,6 @@ dependencies = [ "world-chain-builder-rpc", ] -[[package]] -name = "world-chain-builder-db" -version = "0.1.0" -dependencies = [ - "bytes", - "color-eyre", - "reth-db", - "reth-db-api", - "reth-primitives", - "revm-primitives", - "semaphore", - "serde", - "tracing", -] - [[package]] name = "world-chain-builder-node" version = "0.1.0" @@ -13768,7 +13753,6 @@ dependencies = [ "semaphore", "serde_json", "tokio", - "world-chain-builder-db", "world-chain-builder-payload", "world-chain-builder-pbh", "world-chain-builder-pool", @@ -13853,7 +13837,6 @@ dependencies = [ "thiserror 1.0.69", "tokio", "tracing", - "world-chain-builder-db", "world-chain-builder-pbh", ] diff --git a/world-chain-builder/Cargo.toml b/world-chain-builder/Cargo.toml index a78e6fdd..6a4ba860 100644 --- a/world-chain-builder/Cargo.toml +++ b/world-chain-builder/Cargo.toml @@ -16,7 +16,6 @@ members = [ "crates/world/payload", "crates/world/rpc", "crates/world/pbh", - "crates/world/db", "crates/world/primitives", "crates/world/pool", ] @@ -26,7 +25,6 @@ members = [ [workspace.dependencies] # internal world-chain-builder-node = { path = "crates/world/node" } -world-chain-builder-db = { path = "crates/world/db" } world-chain-builder-pbh = { path = "crates/world/pbh" } world-chain-builder-payload = { path = "crates/world/payload" } world-chain-builder-primitives = { path = "crates/world/primitives" } diff --git a/world-chain-builder/crates/world/bin/src/main.rs b/world-chain-builder/crates/world/bin/src/main.rs index 11d07e83..bc9b367d 100644 --- a/world-chain-builder/crates/world/bin/src/main.rs +++ b/world-chain-builder/crates/world/bin/src/main.rs @@ -28,12 +28,8 @@ fn main() { } if let Err(err) = Cli::::parse().run(|builder, builder_args| async move { - let data_dir = builder.config().datadir(); let handle = builder - .node(WorldChainBuilder::new( - builder_args.clone(), - data_dir.data_dir(), - )?) + .node(WorldChainBuilder::new(builder_args.clone())?) .extend_rpc_modules(move |ctx| { let provider = ctx.provider().clone(); let pool = ctx.pool().clone(); diff --git a/world-chain-builder/crates/world/db/Cargo.toml b/world-chain-builder/crates/world/db/Cargo.toml deleted file mode 100644 index 233e5136..00000000 --- a/world-chain-builder/crates/world/db/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "world-chain-builder-db" -version.workspace = true -edition.workspace = true - -[dependencies] -reth-db = { workspace = true } -reth-db-api = { workspace = true } -reth-primitives = { workspace = true, features = ["optimism"] } -revm-primitives.workspace = true - -semaphore = { workspace = true } -serde = { workspace = true } -tracing = { workspace = true } -bytes = { workspace = true } -eyre = { workspace = true } diff --git a/world-chain-builder/crates/world/db/src/lib.rs b/world-chain-builder/crates/world/db/src/lib.rs deleted file mode 100644 index 0f02c32a..00000000 --- a/world-chain-builder/crates/world/db/src/lib.rs +++ /dev/null @@ -1,83 +0,0 @@ -use std::fmt; -use std::path::Path; -use std::sync::Arc; - -use bytes::BufMut; -use reth_db::cursor::DbCursorRW; -use reth_db::mdbx::tx::Tx; -use reth_db::mdbx::{DatabaseArguments, DatabaseFlags, RW}; -use reth_db::table::TableInfo; -use reth_db::table::{Compress, Decompress, Table}; -use reth_db::transaction::DbTxMut; -use reth_db::TableSet; -use reth_db::{create_db, tables, DatabaseError, TableType, TableViewer}; -use revm_primitives::{FixedBytes, B256}; -use semaphore::Field; -use serde::{Deserialize, Serialize}; -use tracing::info; - -tables! { - /// Table to store PBH validated transactions along with their nullifiers. - /// - /// When a trasnaction is validated before being inserted into the pool, - /// a mapping is created from the transaction hash to the nullifier here. - /// This is primarily used as a caching mechanism to avoid certain types of - /// DoS attacks. - table ValidatedPbhTransaction { - type Key = B256; - type Value = EmptyValue; - } -} - -#[derive(Debug, Clone, Default, Serialize, Deserialize)] -pub struct EmptyValue; - -impl Decompress for EmptyValue { - fn decompress(_: &[u8]) -> Result { - Ok(Self) - } -} - -impl Compress for EmptyValue { - type Compressed = Vec; - - fn compress_to_buf>(self, _buf: &mut B) {} -} - -/// Set the store the nullifier for a tx after it -/// has been included in the block -/// don't forget to call db_tx.commit() at the very end -pub fn set_pbh_nullifier(db_tx: &Tx, nullifier: Field) -> Result<(), DatabaseError> { - let bytes: FixedBytes<32> = nullifier.into(); - let mut cursor = db_tx.cursor_write::()?; - cursor.insert(bytes, EmptyValue)?; - Ok(()) -} - -pub fn load_world_chain_db( - data_dir: &Path, - clear_nullifiers: bool, -) -> Result, eyre::eyre::Error> { - let path = data_dir.join("world-chain"); - if clear_nullifiers { - info!(?path, "Clearing semaphore-nullifiers database"); - // delete the directory - std::fs::remove_dir_all(&path)?; - } - info!(?path, "Opening semaphore-nullifiers database"); - let db = create_db(path, DatabaseArguments::default())?; - - let tx = db - .begin_rw_txn() - .map_err(|e| DatabaseError::InitTx(e.into()))?; - - tx.create_db( - Some(ValidatedPbhTransaction::NAME), - DatabaseFlags::default(), - ) - .map_err(|e| DatabaseError::CreateTable(e.into()))?; - - tx.commit().map_err(|e| DatabaseError::Commit(e.into()))?; - - Ok(Arc::new(db)) -} diff --git a/world-chain-builder/crates/world/node/Cargo.toml b/world-chain-builder/crates/world/node/Cargo.toml index f6e41df2..edfcb235 100644 --- a/world-chain-builder/crates/world/node/Cargo.toml +++ b/world-chain-builder/crates/world/node/Cargo.toml @@ -11,7 +11,6 @@ repository.workspace = true workspace = true [dependencies] -world-chain-builder-db.workspace = true world-chain-builder-payload.workspace = true world-chain-builder-pool.workspace = true diff --git a/world-chain-builder/crates/world/node/src/args.rs b/world-chain-builder/crates/world/node/src/args.rs index c3760de5..6b149086 100644 --- a/world-chain-builder/crates/world/node/src/args.rs +++ b/world-chain-builder/crates/world/node/src/args.rs @@ -16,10 +16,6 @@ pub struct ExtArgs { #[derive(Debug, Clone, Default, PartialEq, Eq, clap::Args)] #[command(next_help_heading = "PBH Builder")] pub struct WorldChainBuilderArgs { - /// Clears existing pbh semaphore nullifiers from the database - #[arg(long = "builder.clear_nullifiers")] - pub clear_nullifiers: bool, - /// Sets the number of allowed PBH transactions per month #[arg(long = "builder.num_pbh_txs", default_value = "30")] pub num_pbh_txs: u16, diff --git a/world-chain-builder/crates/world/node/src/node.rs b/world-chain-builder/crates/world/node/src/node.rs index 45187273..cd9d7cc2 100644 --- a/world-chain-builder/crates/world/node/src/node.rs +++ b/world-chain-builder/crates/world/node/src/node.rs @@ -1,6 +1,3 @@ -use std::path::Path; -use std::sync::Arc; - use eyre::eyre::Result; use reth::api::{ConfigureEvm, TxTy}; use reth::builder::components::{ComponentsBuilder, PayloadServiceBuilder}; @@ -11,7 +8,6 @@ use reth::builder::{ use reth::payload::{PayloadBuilderHandle, PayloadBuilderService}; use reth::transaction_pool::TransactionPool; use reth_basic_payload_builder::{BasicPayloadJobGenerator, BasicPayloadJobGeneratorConfig}; -use reth_db::DatabaseEnv; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_node::args::RollupArgs; use reth_optimism_node::node::{ @@ -24,7 +20,6 @@ use reth_optimism_primitives::OpPrimitives; use reth_primitives::{Header, TransactionSigned}; use reth_provider::CanonStateSubscriptions; use reth_trie_db::MerklePatriciaTrie; -use world_chain_builder_db::load_world_chain_db; use world_chain_builder_pool::builder::WorldChainPoolBuilder; use world_chain_builder_pool::tx::WorldChainPoolTransaction; @@ -41,16 +36,12 @@ pub struct WorldChainBuilder { /// /// By default no throttling is applied. pub da_config: OpDAConfig, - /// The World Chain database - pub db: Arc, } impl WorldChainBuilder { - pub fn new(args: ExtArgs, data_dir: &Path) -> Result { - let db = load_world_chain_db(data_dir, args.builder_args.clear_nullifiers)?; + pub fn new(args: ExtArgs) -> Result { Ok(Self { args, - db, da_config: OpDAConfig::default(), }) } @@ -64,7 +55,6 @@ impl WorldChainBuilder { /// Returns the components for the given [`RollupArgs`]. pub fn components( args: ExtArgs, - db: Arc, ) -> ComponentsBuilder< Node, WorldChainPoolBuilder, @@ -83,7 +73,6 @@ impl WorldChainBuilder { >, { let WorldChainBuilderArgs { - clear_nullifiers, num_pbh_txs, verified_blockspace_capacity, pbh_validator, @@ -100,9 +89,7 @@ impl WorldChainBuilder { ComponentsBuilder::default() .node_types::() .pool(WorldChainPoolBuilder::new( - clear_nullifiers, num_pbh_txs, - db.clone(), pbh_validator, signature_aggregator, )) @@ -143,16 +130,12 @@ where OpAddOns>::Components>>; fn components_builder(&self) -> Self::ComponentsBuilder { - let Self { args, db, .. } = self; - Self::components(args.clone(), db.clone()) + let Self { args, .. } = self; + Self::components(args.clone()) } fn add_ons(&self) -> Self::AddOns { - let Self { - args, - db, - da_config, - } = self; + let Self { args, da_config } = self; Self::AddOns::builder() .with_sequencer(args.rollup_args.sequencer_http.clone()) .with_da_config(da_config.clone()) diff --git a/world-chain-builder/crates/world/node/src/test_utils.rs b/world-chain-builder/crates/world/node/src/test_utils.rs index d8b5a077..a7653db0 100644 --- a/world-chain-builder/crates/world/node/src/test_utils.rs +++ b/world-chain-builder/crates/world/node/src/test_utils.rs @@ -596,14 +596,14 @@ pub struct WorldChainNoopValidator where Client: StateProviderFactory + BlockReaderIdExt, { - inner: WorldChainTransactionValidator, + _inner: WorldChainTransactionValidator, } impl WorldChainNoopValidator { pub fn new( inner: WorldChainTransactionValidator, ) -> Self { - Self { inner } + Self { _inner: inner } } } diff --git a/world-chain-builder/crates/world/node/tests/e2e.rs b/world-chain-builder/crates/world/node/tests/e2e.rs index 793acd16..cb76e426 100644 --- a/world-chain-builder/crates/world/node/tests/e2e.rs +++ b/world-chain-builder/crates/world/node/tests/e2e.rs @@ -16,7 +16,7 @@ use reth::payload::{EthPayloadBuilderAttributes, PayloadId}; use reth::tasks::TaskManager; use reth::transaction_pool::blobstore::DiskFileBlobStore; use reth::transaction_pool::{Pool, TransactionValidationTaskExecutor}; -use reth_db::test_utils::{tempdir_path, TempDatabase}; +use reth_db::test_utils::TempDatabase; use reth_db::DatabaseEnv; use reth_e2e_test_utils::node::NodeTestContext; use reth_e2e_test_utils::transaction::TransactionTestContext; @@ -124,21 +124,16 @@ impl WorldChainBuilderTestContext { // is 0.0.0.0 by default node_config.network.addr = [127, 0, 0, 1].into(); - let path = tempdir_path(); - let builder = NodeBuilder::new(node_config.clone()) .testing_node(exec.clone()) - .node(WorldChainBuilder::new( - ExtArgs { - builder_args: WorldChainBuilderArgs { - num_pbh_txs: 30, - verified_blockspace_capacity: 70, - ..Default::default() - }, + .node(WorldChainBuilder::new(ExtArgs { + builder_args: WorldChainBuilderArgs { + num_pbh_txs: 30, + verified_blockspace_capacity: 70, ..Default::default() }, - &path, - )?) + ..Default::default() + })?) .extend_rpc_modules(move |ctx| { let provider = ctx.provider().clone(); let pool = ctx.pool().clone(); diff --git a/world-chain-builder/crates/world/payload/src/builder.rs b/world-chain-builder/crates/world/payload/src/builder.rs index 5f3982c9..274733ea 100644 --- a/world-chain-builder/crates/world/payload/src/builder.rs +++ b/world-chain-builder/crates/world/payload/src/builder.rs @@ -192,7 +192,7 @@ where let builder = WorldChainBuilder { pool, - best: self.inner.best_transactions.clone(), + _best: self.inner.best_transactions.clone(), }; let client = ctx.client(); @@ -287,7 +287,7 @@ where let builder = WorldChainBuilder { pool: NoopWorldChainTransactionPool::default(), - best: (), + _best: (), }; builder.witness(&mut state, &ctx) } @@ -365,7 +365,7 @@ pub struct WorldChainBuilder { /// The transaction pool pool: Pool, /// Yields the best transaction to include if transactions from the mempool are allowed. - best: Txs, + _best: Txs, } impl WorldChainBuilder @@ -385,7 +385,7 @@ where Client: StateProviderFactory + ChainSpecProvider + BlockReaderIdExt, { - let Self { pool, best } = self; + let Self { pool, _best } = self; debug!(target: "payload_builder", id=%ctx.payload_id(), parent_header = ?ctx.parent().hash(), parent_number = ctx.parent().number, "building new payload"); // 1. apply eip-4788 pre block contract call @@ -696,7 +696,7 @@ impl WorldChainPayloadBuilderCtx { /// Returns true if the fees are higher than the previous payload. /// TODO: PBH pub fn is_better_payload(&self, total_fees: U256) -> bool { - // is_better_payload(self.best_payload.as_ref(), total_fees) + // self.inner.is_better_payload( total_fees) todo!() } diff --git a/world-chain-builder/crates/world/pool/Cargo.toml b/world-chain-builder/crates/world/pool/Cargo.toml index 4d5c3e8b..5d41853b 100644 --- a/world-chain-builder/crates/world/pool/Cargo.toml +++ b/world-chain-builder/crates/world/pool/Cargo.toml @@ -9,7 +9,6 @@ repository.workspace = true [dependencies] world-chain-builder-pbh.workspace = true -world-chain-builder-db.workspace = true reth.workspace = true reth-db.workspace = true diff --git a/world-chain-builder/crates/world/pool/src/builder.rs b/world-chain-builder/crates/world/pool/src/builder.rs index 1e76ab2f..49fc3124 100644 --- a/world-chain-builder/crates/world/pool/src/builder.rs +++ b/world-chain-builder/crates/world/pool/src/builder.rs @@ -5,7 +5,6 @@ use reth::builder::components::PoolBuilder; use reth::builder::{BuilderContext, FullNodeTypes, NodeTypes}; use reth::transaction_pool::blobstore::DiskFileBlobStore; use reth::transaction_pool::TransactionValidationTaskExecutor; -use reth_db::DatabaseEnv; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_node::txpool::OpTransactionValidator; use reth_optimism_primitives::OpPrimitives; @@ -23,25 +22,19 @@ use crate::validator::WorldChainTransactionValidator; /// config. #[derive(Debug, Clone)] pub struct WorldChainPoolBuilder { - pub clear_nullifiers: bool, pub num_pbh_txs: u16, - pub db: Arc, pub pbh_validator: Address, pub pbh_signature_aggregator: Address, } impl WorldChainPoolBuilder { pub fn new( - clear_nullifiers: bool, num_pbh_txs: u16, - db: Arc, pbh_validator: Address, pbh_signature_aggregator: Address, ) -> Self { Self { - clear_nullifiers, num_pbh_txs, - db, pbh_validator, pbh_signature_aggregator, } @@ -78,7 +71,6 @@ where WorldChainTransactionValidator::new( op_tx_validator, root_validator, - self.db.clone(), self.num_pbh_txs, self.pbh_validator, self.pbh_signature_aggregator, diff --git a/world-chain-builder/crates/world/pool/src/test_utils.rs b/world-chain-builder/crates/world/pool/src/test_utils.rs index 66d3bd66..2afbb121 100644 --- a/world-chain-builder/crates/world/pool/src/test_utils.rs +++ b/world-chain-builder/crates/world/pool/src/test_utils.rs @@ -27,8 +27,6 @@ use semaphore::identity::Identity; use semaphore::poseidon_tree::LazyPoseidonTree; use semaphore::protocol::{generate_nullifier_hash, generate_proof}; use semaphore::{hash_to_field, Field}; -use tempfile::tempdir; -use world_chain_builder_db::load_world_chain_db; use world_chain_builder_pbh::date_marker::DateMarker; use world_chain_builder_pbh::external_nullifier::{ExternalNullifier, Prefix}; use world_chain_builder_pbh::payload::{PbhPayload, Proof, TREE_DEPTH}; @@ -133,14 +131,10 @@ pub fn world_chain_validator( .no_cancun() .build(client.clone(), InMemoryBlobStore::default()); let validator = OpTransactionValidator::new(validator).require_l1_data_gas_fee(false); - let temp_dir = tempdir().unwrap(); - let path = temp_dir.path().join("db"); - let db = load_world_chain_db(&path, false).unwrap(); let root_validator = WorldChainRootValidator::new(client).unwrap(); WorldChainTransactionValidator::new( validator, root_validator, - db, 30, PBH_TEST_VALIDATOR, PBH_TEST_SIGNATURE_AGGREGATOR, diff --git a/world-chain-builder/crates/world/pool/src/validator.rs b/world-chain-builder/crates/world/pool/src/validator.rs index cca6b31e..f5bb2bf0 100644 --- a/world-chain-builder/crates/world/pool/src/validator.rs +++ b/world-chain-builder/crates/world/pool/src/validator.rs @@ -1,6 +1,4 @@ //! World Chain transaction pool types -use std::sync::Arc; - use crate::bindings::IPBHValidator; use alloy_primitives::{Address, Bytes, U256}; use alloy_rlp::Decodable; @@ -10,15 +8,11 @@ use reth::transaction_pool::{ Pool, TransactionOrigin, TransactionValidationOutcome, TransactionValidationTaskExecutor, TransactionValidator, }; -use reth_db::cursor::DbCursorRW; -use reth_db::transaction::{DbTx, DbTxMut}; -use reth_db::{Database, DatabaseEnv, DatabaseError}; use reth_optimism_node::txpool::OpTransactionValidator; use reth_primitives::{Block, SealedBlock, TransactionSigned}; use reth_provider::{BlockReaderIdExt, StateProviderFactory}; use semaphore::hash_to_field; use semaphore::protocol::verify_proof; -use world_chain_builder_db::{EmptyValue, ValidatedPbhTransaction}; use world_chain_builder_pbh::date_marker::DateMarker; use world_chain_builder_pbh::external_nullifier::ExternalNullifier; use world_chain_builder_pbh::payload::{PbhPayload, TREE_DEPTH}; @@ -45,7 +39,6 @@ where { inner: OpTransactionValidator, root_validator: WorldChainRootValidator, - pub(crate) pbh_db: Arc, num_pbh_txs: u16, pbh_validator: Address, pbh_signature_aggregator: Address, @@ -60,7 +53,6 @@ where pub fn new( inner: OpTransactionValidator, root_validator: WorldChainRootValidator, - pbh_db: Arc, num_pbh_txs: u16, pbh_validator: Address, pbh_signature_aggregator: Address, @@ -68,7 +60,6 @@ where Self { inner, root_validator, - pbh_db, num_pbh_txs, pbh_validator, pbh_signature_aggregator, @@ -80,14 +71,6 @@ where &self.inner } - pub fn set_validated(&self, pbh_payload: &PbhPayload) -> Result<(), DatabaseError> { - let db_tx = self.pbh_db.tx_mut()?; - let mut cursor = db_tx.cursor_write::()?; - cursor.insert(pbh_payload.nullifier_hash.to_be_bytes().into(), EmptyValue)?; - db_tx.commit()?; - Ok(()) - } - /// Ensure the provided root is on chain and valid pub fn validate_root( &self, @@ -146,12 +129,6 @@ where let date = chrono::Utc::now(); self.validate_external_nullifier(date, payload)?; - // Create db transaction and insert the nullifier hash - // We do this first to prevent repeatedly validating the same transaction - let db_tx = self.pbh_db.tx_mut()?; - let mut cursor = db_tx.cursor_write::()?; - cursor.insert(payload.nullifier_hash.to_be_bytes().into(), EmptyValue)?; - let res = verify_proof( payload.root, payload.nullifier_hash, @@ -162,11 +139,7 @@ where ); match res { - Ok(true) => { - // Only commit if the proof is valid - db_tx.commit()?; - Ok(()) - } + Ok(true) => Ok(()), Ok(false) => Err(WorldChainTransactionPoolInvalid::InvalidSemaphoreProof.into()), Err(e) => Err(TransactionValidationError::Error(e.into())), } @@ -183,7 +156,6 @@ where return None; } - // TODO: Boolean args is `validate`. Can it be `false`? let Ok(decoded) = IPBHValidator::handleAggregatedOpsCall::abi_decode(tx.input(), true) else { return None; @@ -561,26 +533,4 @@ pub mod tests { let res = validator.validate_external_nullifier(date, &payload); assert!(res.is_err()); } - - #[test] - fn test_set_validated() { - let validator = world_chain_validator(); - - let proof = Proof(semaphore::protocol::Proof( - (U256::from(1u64), U256::from(2u64)), - ( - [U256::from(3u64), U256::from(4u64)], - [U256::from(5u64), U256::from(6u64)], - ), - (U256::from(7u64), U256::from(8u64)), - )); - let payload = PbhPayload { - external_nullifier: "0-012025-11".to_string(), - nullifier_hash: Field::from(10u64), - root: Field::from(12u64), - proof, - }; - - validator.set_validated(&payload).unwrap(); - } } From 2ea1fd3dad7b96639483a9b78f6873392549dd96 Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Mon, 16 Dec 2024 23:47:27 -0700 Subject: [PATCH 54/59] update comments --- world-chain-builder/crates/world/node/src/args.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/world-chain-builder/crates/world/node/src/args.rs b/world-chain-builder/crates/world/node/src/args.rs index 6b149086..7beb9dee 100644 --- a/world-chain-builder/crates/world/node/src/args.rs +++ b/world-chain-builder/crates/world/node/src/args.rs @@ -28,7 +28,7 @@ pub struct WorldChainBuilderArgs { pub verified_blockspace_capacity: u8, /// Sets the ERC-4337 EntryPoint Proxy contract address - /// This contract is used to verify World-Id Proofs attached to 4337 payloads. + /// This contract is used to validate 4337 PBH bundles #[arg(long = "builder.pbh_validator")] pub pbh_validator: Address, From f56a6c2ddd04079e8ceed58d2503ec3a1a9440c7 Mon Sep 17 00:00:00 2001 From: Dzejkop Date: Tue, 17 Dec 2024 09:22:06 +0100 Subject: [PATCH 55/59] reduce nesting --- .../crates/world/pool/src/validator.rs | 61 ++++++++++--------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/world-chain-builder/crates/world/pool/src/validator.rs b/world-chain-builder/crates/world/pool/src/validator.rs index 8de2f0de..bd89c337 100644 --- a/world-chain-builder/crates/world/pool/src/validator.rs +++ b/world-chain-builder/crates/world/pool/src/validator.rs @@ -1,5 +1,4 @@ //! World Chain transaction pool types -use crate::bindings::IPBHValidator; use alloy_primitives::{Address, Bytes, U256}; use alloy_rlp::Decodable; use alloy_sol_types::{SolCall, SolValue}; @@ -21,6 +20,7 @@ use super::error::{TransactionValidationError, WorldChainTransactionPoolInvalid} use super::ordering::WorldChainOrdering; use super::root::WorldChainRootValidator; use super::tx::{WorldChainPoolTransaction, WorldChainPooledTransaction}; +use crate::bindings::IPBHValidator; /// Type alias for World Chain transaction pool pub type WorldChainTransactionPool = Pool< @@ -178,34 +178,36 @@ where &self, transaction: &mut Tx, ) -> Result<(), TransactionValidationError> { - if let Some(calldata) = self.is_valid_eip4337_pbh_bundle(transaction) { - for aggregated_ops in calldata._0 { - let mut buff = aggregated_ops.signature.as_ref(); - let pbh_payloads = >::decode(&mut buff) - .map_err(WorldChainTransactionPoolInvalid::from) - .map_err(TransactionValidationError::from)?; - - pbh_payloads - .par_iter() - .zip(aggregated_ops.userOps) - .try_for_each(|(payload, op)| { - let signal = alloy_primitives::keccak256( - <(Address, U256, Bytes) as SolValue>::abi_encode_packed(&( - op.sender, - op.nonce, - op.callData, - )), - ); - - self.validate_pbh_payload(&payload, hash_to_field(signal.as_ref()))?; - - Ok::<(), TransactionValidationError>(()) - })?; - } + let Some(calldata) = self.is_valid_eip4337_pbh_bundle(transaction) else { + return Ok(()); + }; - transaction.set_valid_pbh(); + for aggregated_ops in calldata._0 { + let mut buff = aggregated_ops.signature.as_ref(); + let pbh_payloads = >::decode(&mut buff) + .map_err(WorldChainTransactionPoolInvalid::from) + .map_err(TransactionValidationError::from)?; + + pbh_payloads + .par_iter() + .zip(aggregated_ops.userOps) + .try_for_each(|(payload, op)| { + let signal = alloy_primitives::keccak256( + <(Address, U256, Bytes) as SolValue>::abi_encode_packed(&( + op.sender, + op.nonce, + op.callData, + )), + ); + + self.validate_pbh_payload(&payload, hash_to_field(signal.as_ref()))?; + + Ok::<(), TransactionValidationError>(()) + })?; } + transaction.set_valid_pbh(); + Ok(()) } } @@ -240,9 +242,6 @@ where #[cfg(test)] pub mod tests { - use crate::ordering::WorldChainOrdering; - use crate::root::{LATEST_ROOT_SLOT, OP_WORLD_ID}; - use crate::test_utils::{get_pbh_4337_transaction, get_pbh_transaction, world_chain_validator}; use chrono::{TimeZone, Utc}; use ethers_core::types::U256; use reth::transaction_pool::blobstore::InMemoryBlobStore; @@ -255,6 +254,10 @@ pub mod tests { use test_case::test_case; use world_chain_builder_pbh::payload::{PbhPayload, Proof}; + use crate::ordering::WorldChainOrdering; + use crate::root::{LATEST_ROOT_SLOT, OP_WORLD_ID}; + use crate::test_utils::{get_pbh_4337_transaction, get_pbh_transaction, world_chain_validator}; + #[tokio::test] async fn validate_pbh_transaction() { let validator = world_chain_validator(); From b55606ed2574baf10b0727a8c0d39a7d682e182b Mon Sep 17 00:00:00 2001 From: Dzejkop Date: Tue, 17 Dec 2024 16:27:51 +0100 Subject: [PATCH 56/59] WIP: Testing --- world-chain-builder/Cargo.lock | 2 + .../world/pbh/src/external_nullifier.rs | 38 +++- .../crates/world/pbh/src/payload.rs | 8 +- .../crates/world/pool/Cargo.toml | 5 +- .../crates/world/pool/src/eip4337.rs | 20 ++ .../crates/world/pool/src/lib.rs | 2 + .../crates/world/pool/src/payload.rs | 23 ++ .../crates/world/pool/src/test_utils.rs | 194 ++++++++++++++-- .../crates/world/pool/src/validator.rs | 213 +++++++++++++----- 9 files changed, 423 insertions(+), 82 deletions(-) create mode 100644 world-chain-builder/crates/world/pool/src/eip4337.rs create mode 100644 world-chain-builder/crates/world/pool/src/payload.rs diff --git a/world-chain-builder/Cargo.lock b/world-chain-builder/Cargo.lock index 7588ebfd..4bc86228 100644 --- a/world-chain-builder/Cargo.lock +++ b/world-chain-builder/Cargo.lock @@ -13810,12 +13810,14 @@ version = "0.1.0" dependencies = [ "alloy-consensus 0.7.3", "alloy-eips 0.7.3", + "alloy-network 0.7.3", "alloy-primitives", "alloy-rlp", "alloy-rpc-types", "alloy-signer-local", "alloy-sol-types", "bon", + "bytes", "chrono", "color-eyre", "ethers-core 2.0.14 (git+https://github.com/gakonst/ethers-rs)", diff --git a/world-chain-builder/crates/world/pbh/src/external_nullifier.rs b/world-chain-builder/crates/world/pbh/src/external_nullifier.rs index b00ab4c8..e3ad34bd 100644 --- a/world-chain-builder/crates/world/pbh/src/external_nullifier.rs +++ b/world-chain-builder/crates/world/pbh/src/external_nullifier.rs @@ -1,9 +1,27 @@ -use crate::date_marker::{DateMarker, DateMarkerParsingError}; -use semaphore::{hash_to_field, Field}; use std::str::FromStr; + +use alloy_rlp::{Decodable, Encodable, Rlp}; +use semaphore::{hash_to_field, Field}; use strum::{Display, EnumString}; use thiserror::Error; +use crate::date_marker::{DateMarker, DateMarkerParsingError}; + +#[macro_export] +macro_rules! ext_nullifier { + ($mo:expr,$yr:expr,$no:expr) => {{ + let prefix = $crate::external_nullifier::Prefix::V1; + let date_marker = $crate::date_marker::DateMarker::new($yr, $mo); + + $crate::external_nullifier::ExternalNullifier::new(prefix, date_marker, $no) + }}; +} + +#[test] +fn whatever() { + ext_nullifier!(01, 2025, 1); +} + #[derive(Display, EnumString, Debug, Clone, Copy, PartialEq, Eq)] #[strum(serialize_all = "snake_case")] pub enum Prefix { @@ -18,6 +36,10 @@ pub struct ExternalNullifier { } impl ExternalNullifier { + pub fn v1(month: u32, year: i32, nonce: u16) -> Self { + Self::new(Prefix::V1, DateMarker::new(year, month), nonce) + } + pub fn new(prefix: Prefix, date_marker: DateMarker, nonce: u16) -> Self { Self { prefix, @@ -93,6 +115,18 @@ impl FromStr for ExternalNullifier { } } +impl Decodable for ExternalNullifier { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { + todo!() + } +} + +impl Encodable for ExternalNullifier { + fn encode(&self, out: &mut dyn alloy_rlp::BufMut) { + todo!() + } +} + #[cfg(test)] mod tests { use test_case::test_case; diff --git a/world-chain-builder/crates/world/pbh/src/payload.rs b/world-chain-builder/crates/world/pbh/src/payload.rs index 0c5d504d..2405b802 100644 --- a/world-chain-builder/crates/world/pbh/src/payload.rs +++ b/world-chain-builder/crates/world/pbh/src/payload.rs @@ -3,6 +3,8 @@ use semaphore::packed_proof::PackedProof; use semaphore::Field; use serde::{Deserialize, Serialize}; +use crate::external_nullifier::ExternalNullifier; + pub const TREE_DEPTH: usize = 30; const LEN: usize = 256; @@ -46,10 +48,10 @@ impl Encodable for Proof { /// /// Contains the semaphore proof and relevent metadata /// required to to verify the pbh transaction. -#[derive(Clone, Debug, RlpEncodable, RlpDecodable, PartialEq, Eq, Default)] +#[derive(Clone, Debug, RlpEncodable, RlpDecodable, PartialEq, Eq)] pub struct PbhPayload { /// A string containing a prefix, the date marker, and the pbh nonce - pub external_nullifier: String, + pub external_nullifier: ExternalNullifier, /// A nullifier hash used to keep track of /// previously used pbh transactions pub nullifier_hash: Field, @@ -78,7 +80,7 @@ mod test { (U256::from(7u64), U256::from(8u64)), )); let pbh_payload = PbhPayload { - external_nullifier: "0-012025-11".to_string(), + external_nullifier: ExternalNullifier::v1(1, 2024, 11), nullifier_hash: Field::from(10u64), root: Field::from(12u64), proof, diff --git a/world-chain-builder/crates/world/pool/Cargo.toml b/world-chain-builder/crates/world/pool/Cargo.toml index 5d41853b..9ac98a18 100644 --- a/world-chain-builder/crates/world/pool/Cargo.toml +++ b/world-chain-builder/crates/world/pool/Cargo.toml @@ -28,7 +28,8 @@ alloy-rpc-types.workspace = true alloy-eips.workspace = true alloy-sol-types.workspace = true alloy-rlp.workspace = true -alloy-signer-local = { workspace = true, optional = true } +alloy-signer-local.workspace = true +alloy-network.workspace = true # 3rd party tokio.workspace = true @@ -41,6 +42,7 @@ parking_lot.workspace = true tempfile.workspace = true bon.workspace = true rayon.workspace = true +bytes.workspace = true [dev-dependencies] ethers-core.workspace = true @@ -52,7 +54,6 @@ reth-e2e-test-utils.workspace = true default = [] test = [ "dep:reth-e2e-test-utils", - "dep:alloy-signer-local", ] [lints] diff --git a/world-chain-builder/crates/world/pool/src/eip4337.rs b/world-chain-builder/crates/world/pool/src/eip4337.rs new file mode 100644 index 00000000..e435f542 --- /dev/null +++ b/world-chain-builder/crates/world/pool/src/eip4337.rs @@ -0,0 +1,20 @@ +use alloy_primitives::keccak256; +use alloy_sol_types::SolValue; +use semaphore::{hash_to_field, Field}; + +use crate::bindings::IEntryPoint::PackedUserOperation; + +pub fn hash_user_op(user_op: &PackedUserOperation) -> Field { + let keccak_hash = keccak256(SolValue::abi_encode_packed(&( + &user_op.sender, + &user_op.nonce, + &user_op.initCode, + &user_op.callData, + &user_op.accountGasLimits, + &user_op.preVerificationGas, + &user_op.gasFees, + &user_op.paymasterAndData, + ))); + + hash_to_field(keccak_hash.as_slice()) +} diff --git a/world-chain-builder/crates/world/pool/src/lib.rs b/world-chain-builder/crates/world/pool/src/lib.rs index 01676dab..b00b4241 100644 --- a/world-chain-builder/crates/world/pool/src/lib.rs +++ b/world-chain-builder/crates/world/pool/src/lib.rs @@ -6,6 +6,8 @@ pub mod ordering; pub mod root; pub mod tx; pub mod validator; +pub mod payload; +pub mod eip4337; #[cfg(any(feature = "test", test))] pub mod test_utils; diff --git a/world-chain-builder/crates/world/pool/src/payload.rs b/world-chain-builder/crates/world/pool/src/payload.rs new file mode 100644 index 00000000..f924d3f0 --- /dev/null +++ b/world-chain-builder/crates/world/pool/src/payload.rs @@ -0,0 +1,23 @@ +use bon::builder; + +#[builder(on(String, into))] +pub fn build_pbh_tx( + #[builder(default = "test test test test test test test test test test test junk")] + mnemonic: String, + + user_ops: Vec, +) { +} + +#[builder(on(String, into))] +pub fn build_user_op() {} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn whatever() { + // build_pbh_tx().call(); + } +} diff --git a/world-chain-builder/crates/world/pool/src/test_utils.rs b/world-chain-builder/crates/world/pool/src/test_utils.rs index 6fc942fe..d7ef630d 100644 --- a/world-chain-builder/crates/world/pool/src/test_utils.rs +++ b/world-chain-builder/crates/world/pool/src/test_utils.rs @@ -1,19 +1,15 @@ -use std::sync::Arc; - -use crate::bindings::IEntryPoint::{PackedUserOperation, UserOpsPerAggregator}; -use crate::bindings::IPBHValidator::{handleAggregatedOpsCall, IPBHValidatorCalls}; -use crate::root::WorldChainRootValidator; -use crate::tx::WorldChainPooledTransaction; -use crate::validator::WorldChainTransactionValidator; -use alloy_eips::eip2718::Decodable2718; -use alloy_eips::eip2718::Encodable2718; -use alloy_primitives::{address, keccak256, Bytes, U256}; +use alloy_consensus::{SignableTransaction, TxEip1559}; +use alloy_eips::eip2718::{Decodable2718, Encodable2718}; +use alloy_eips::eip2930::AccessList; +use alloy_network::TxSigner; +use alloy_primitives::{address, keccak256, Bytes, ChainId, U256}; use alloy_rlp::Encodable; use alloy_rpc_types::{TransactionInput, TransactionRequest}; -use alloy_signer_local::LocalSigner; +use alloy_signer_local::coins_bip39::English; +use alloy_signer_local::{LocalSigner, PrivateKeySigner}; use alloy_sol_types::{SolInterface, SolValue}; +use bon::builder; use chrono::Utc; -use parking_lot::RwLock; use reth::chainspec::MAINNET; use reth::transaction_pool::blobstore::InMemoryBlobStore; use reth::transaction_pool::validate::EthTransactionValidatorBuilder; @@ -24,13 +20,182 @@ use reth_primitives::PooledTransactionsElement; use reth_provider::test_utils::MockEthProvider; use revm_primitives::{hex, Address, TxKind}; use semaphore::identity::Identity; -use semaphore::poseidon_tree::LazyPoseidonTree; +use semaphore::poseidon_tree::{LazyPoseidonTree, PoseidonTree}; use semaphore::protocol::{generate_nullifier_hash, generate_proof}; use semaphore::{hash_to_field, Field}; use world_chain_builder_pbh::date_marker::DateMarker; use world_chain_builder_pbh::external_nullifier::{ExternalNullifier, Prefix}; use world_chain_builder_pbh::payload::{PbhPayload, Proof, TREE_DEPTH}; +use crate::bindings::IEntryPoint::{self, PackedUserOperation, UserOpsPerAggregator}; +use crate::bindings::IPBHValidator::{self, handleAggregatedOpsCall, IPBHValidatorCalls}; +use crate::root::WorldChainRootValidator; +use crate::tx::WorldChainPooledTransaction; +use crate::validator::WorldChainTransactionValidator; + +const MNEMONIC: &str = "test test test test test test test test test test test junk"; + +pub fn signer(index: u32) -> PrivateKeySigner { + let signer = alloy_signer_local::MnemonicBuilder::::default() + .phrase(MNEMONIC) + .index(index) + .expect("Failed to set index") + .build() + .expect("Failed to create signer"); + + signer +} + +pub fn account(index: u32) -> Address { + let signer = signer(index); + + signer.address() +} + +pub fn identity(index: u32) -> Identity { + let mut secret = account(index).into_word().0; + + Identity::from_secret(&mut secret as &mut _, None) +} + +// TODO: Cache with Once or lazy-static? +pub fn tree() -> LazyPoseidonTree { + let mut tree = LazyPoseidonTree::new(30, Field::ZERO); + + // Only accounts 0 through 5 are included in the tree + for acc in 0..=5 { + let identity = identity(acc); + let commitment = identity.commitment(); + + tree = tree.update_with_mutation(acc as usize, &commitment); + } + + tree.derived() +} + +pub fn tree_root() -> Field { + tree().root() +} + +pub fn tree_inclusion_proof(acc: u32) -> semaphore::poseidon_tree::Proof { + tree().proof(acc as usize) +} + +pub fn nullifier_hash(acc: u32, external_nullifier: Field) -> Field { + let identity = identity(acc); + + semaphore::protocol::generate_nullifier_hash(&identity, external_nullifier) +} + +pub fn semaphore_proof( + acc: u32, + ext_nullifier: Field, + signal: Field, +) -> semaphore::protocol::Proof { + let identity = identity(acc); + let incl_proof = tree_inclusion_proof(acc); + + semaphore::protocol::generate_proof(&identity, &incl_proof, ext_nullifier, signal) + .expect("Failed to generate semaphore proof") +} + +#[builder] +pub fn eip1559( + #[builder(default = 1)] chain_id: ChainId, + #[builder(default = 0)] nonce: u64, + #[builder(default = 150000)] gas_limit: u64, + #[builder(default = 10000000)] // 0.1 GWEI + max_fee_per_gas: u128, + #[builder(default = 0)] max_priority_fee_per_gas: u128, + #[builder(into)] to: TxKind, + #[builder(default = U256::ZERO)] value: U256, + #[builder(default)] access_list: AccessList, + #[builder(into, default)] input: Bytes, +) -> TxEip1559 { + TxEip1559 { + chain_id, + nonce, + gas_limit, + max_fee_per_gas, + max_priority_fee_per_gas, + to, + value, + access_list, + input, + } +} + +pub async fn eth_tx(acc: u32, mut tx: TxEip1559) -> EthPooledTransaction { + let signer = signer(acc); + + let signature = signer + .sign_transaction(&mut tx) + .await + .expect("Failed to sign transaction"); + + let tx_signed = tx.into_signed(signature); + let pooled = PooledTransactionsElement::Eip1559(tx_signed); + + pooled.try_into_ecrecovered().unwrap().into() +} + +#[builder] +pub fn user_op( + acc: u32, + #[builder(into, default = U256::ZERO)] nonce: U256, + #[builder(default = ExternalNullifier::v1(1, 2025, 0))] external_nullifier: ExternalNullifier, +) -> (IEntryPoint::PackedUserOperation, PbhPayload) { + let sender = account(acc); + + let user_op = PackedUserOperation { + sender, + nonce: nonce, + ..Default::default() + }; + + let signal = crate::eip4337::hash_user_op(&user_op); + + let tree = tree(); + let root = tree.root(); + let proof = semaphore_proof(acc, external_nullifier.hash(), signal); + let nullifier_hash = nullifier_hash(acc, external_nullifier.hash()); + + let proof = Proof(proof); + + let payload = PbhPayload { + external_nullifier, + nullifier_hash, + root, + proof, + }; + + (user_op, payload) +} + +pub fn pbh_bundle( + ops: Vec<(PackedUserOperation, PbhPayload)>, +) -> IPBHValidator::handleAggregatedOpsCall { + let mut user_ops = Vec::new(); + let mut proofs = Vec::new(); + + for (user_op, proof) in ops { + user_ops.push(user_op); + proofs.push(proof); + } + + let mut signature_buff = Vec::new(); + proofs.encode(&mut signature_buff); + + IPBHValidator::handleAggregatedOpsCall { + _0: vec![UserOpsPerAggregator { + userOps: user_ops, + signature: signature_buff.into(), + aggregator: PBH_TEST_SIGNATURE_AGGREGATOR, + }], + _1: Address::ZERO, + } +} + pub const PBH_TEST_SIGNATURE_AGGREGATOR: Address = address!("dEAD000000000000000042069420694206942069"); @@ -171,7 +336,8 @@ pub fn create_pbh_paylaod( let merkle_proof = tree.proof(0); let signal_hash = hash_to_field(signal); - let external_nullifier_hash = hash_to_field(external_nullifier.as_bytes()); + let external_nullifier: ExternalNullifier = external_nullifier.parse().unwrap(); + let external_nullifier_hash = external_nullifier.hash(); let nullifier_hash = generate_nullifier_hash(&id, external_nullifier_hash); let proof = diff --git a/world-chain-builder/crates/world/pool/src/validator.rs b/world-chain-builder/crates/world/pool/src/validator.rs index bd89c337..2c5009dd 100644 --- a/world-chain-builder/crates/world/pool/src/validator.rs +++ b/world-chain-builder/crates/world/pool/src/validator.rs @@ -92,12 +92,6 @@ where date: chrono::DateTime, pbh_payload: &PbhPayload, ) -> Result<(), TransactionValidationError> { - let external_nullifier: ExternalNullifier = pbh_payload - .external_nullifier - .parse() - .map_err(WorldChainTransactionPoolInvalid::InvalidExternalNullifier) - .map_err(TransactionValidationError::from)?; - // In most cases these will be the same value, but at the month boundary // we'll still accept the previous month if the transaction is at most a minute late // or the next month if the transaction is at most a minute early @@ -108,12 +102,12 @@ where ]; if valid_dates .iter() - .all(|d| external_nullifier.date_marker != *d) + .all(|d| pbh_payload.external_nullifier.date_marker != *d) { return Err(WorldChainTransactionPoolInvalid::InvalidExternalNullifierPeriod.into()); } - if external_nullifier.nonce >= self.num_pbh_txs { + if pbh_payload.external_nullifier.nonce >= self.num_pbh_txs { return Err(WorldChainTransactionPoolInvalid::InvalidExternalNullifierNonce.into()); } @@ -133,7 +127,7 @@ where payload.root, payload.nullifier_hash, signal, - hash_to_field(payload.external_nullifier.as_bytes()), + payload.external_nullifier.hash(), &payload.proof.0, TREE_DEPTH, ); @@ -242,6 +236,13 @@ where #[cfg(test)] pub mod tests { + use std::time::Instant; + + use alloy_primitives::Address; + use alloy_signer_local::coins_bip39::English; + use alloy_signer_local::PrivateKeySigner; + use alloy_sol_types::SolCall; + use bon::builder; use chrono::{TimeZone, Utc}; use ethers_core::types::U256; use reth::transaction_pool::blobstore::InMemoryBlobStore; @@ -250,31 +251,103 @@ pub mod tests { }; use reth_primitives::{BlockBody, SealedBlock, SealedHeader}; use reth_provider::test_utils::{ExtendedAccount, MockEthProvider}; + use semaphore::identity::Identity; + use semaphore::poseidon_tree::PoseidonTree; use semaphore::Field; use test_case::test_case; + use world_chain_builder_pbh::ext_nullifier; + use world_chain_builder_pbh::external_nullifier::ExternalNullifier; use world_chain_builder_pbh::payload::{PbhPayload, Proof}; + use super::WorldChainTransactionValidator; use crate::ordering::WorldChainOrdering; use crate::root::{LATEST_ROOT_SLOT, OP_WORLD_ID}; - use crate::test_utils::{get_pbh_4337_transaction, get_pbh_transaction, world_chain_validator}; + use crate::test_utils::{ + self, get_pbh_4337_transaction, get_pbh_transaction, world_chain_validator, + PBH_TEST_VALIDATOR, + }; + use crate::tx::WorldChainPooledTransaction; + + #[builder(on(String, into))] + pub fn signer( + #[builder(default = "test test test test test test test test test test test junk")] + mnemonic: String, + #[builder(default = 0)] index: u32, + ) -> PrivateKeySigner { + let signer = alloy_signer_local::MnemonicBuilder::::default() + .phrase(&mnemonic) + .index(index) + .expect("Failed to set index") + .build() + .expect("Failed to create signer"); + + signer + } + + #[builder(on(String, into))] + pub fn account( + #[builder(default = "test test test test test test test test test test test junk")] + mnemonic: String, + #[builder(default = 0)] index: u32, + ) -> Address { + let signer = signer().mnemonic(mnemonic).index(index).call(); + + signer.address() + } + + #[test_case(0, "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266")] + #[test_case(1, "0x70997970C51812dc3A010C7d01b50e0d17dc79C8")] + #[test_case(2, "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC")] + #[test_case(3, "0x90F79bf6EB2c4f870365E785982E1f101E93b906")] + #[test_case(4, "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65")] + #[test_case(5, "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc")] + #[test_case(6, "0x976EA74026E726554dB657fA54763abd0C3a0aa9")] + #[test_case(7, "0x14dC79964da2C08b23698B3D3cc7Ca32193d9955")] + #[test_case(8, "0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f")] + #[test_case(9, "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720")] + fn mnemonic_accounts(index: u32, exp_address: &str) { + let exp: Address = exp_address.parse().unwrap(); + + assert_eq!(exp, account().index(index).call()); + } + + async fn setup() -> Pool< + WorldChainTransactionValidator, + WorldChainOrdering, + InMemoryBlobStore, + > { + let start = Instant::now(); - #[tokio::test] - async fn validate_pbh_transaction() { let validator = world_chain_validator(); + + // TODO: Remove let transaction = get_pbh_transaction(0); validator.inner.client().add_account( transaction.sender(), ExtendedAccount::new(transaction.nonce(), alloy_primitives::U256::MAX), ); + + // Fund 10 test accounts + for acc in 0..10 { + let account_address = account().index(acc).call(); + + validator.inner.client().add_account( + account_address, + ExtendedAccount::new(0, alloy_primitives::U256::MAX), + ); + } + + // Prep a merkle tree with first 5 accounts + let tree = test_utils::tree(); + let root = tree.root(); + // Insert a world id root into the OpWorldId Account - // TODO: This should be set to the root on the Payloads of a Bundle Tx - // validator.inner.client().add_account( - // OP_WORLD_ID, - // ExtendedAccount::new(0, alloy_primitives::U256::ZERO).extend_storage(vec![( - // LATEST_ROOT_SLOT.into(), - // transaction.pbh_payload.clone().unwrap().root, - // )]), - // ); + validator.inner.client().add_account( + OP_WORLD_ID, + ExtendedAccount::new(0, alloy_primitives::U256::ZERO) + .extend_storage(vec![(LATEST_ROOT_SLOT.into(), root)]), + ); + let header = SealedHeader::default(); let body = BlockBody::default(); let block = SealedBlock::new(header, body); @@ -291,26 +364,68 @@ pub mod tests { Default::default(), ); - let start = chrono::Utc::now(); - let res = pool.add_external_transaction(transaction.clone()).await; - let first_insert = chrono::Utc::now() - start; - println!("first_insert: {first_insert:?}"); + println!("Building the pool took {:?}", start.elapsed()); - assert!(res.is_ok()); - let tx = pool.get(transaction.hash()); - assert!(tx.is_some()); + pool + } - let start = chrono::Utc::now(); - let res = pool.add_external_transaction(transaction.clone()).await; + #[tokio::test] + async fn validate_noop_non_pbh() { + const ACC: u32 = 0; - let second_insert = chrono::Utc::now() - start; - println!("second_insert: {second_insert:?}"); + let pool = setup().await; + + let account = test_utils::account(ACC); + let tx = test_utils::eip1559().to(account).call(); + let tx = test_utils::eth_tx(ACC, tx).await; + + pool.add_external_transaction(tx.clone().into()) + .await + .expect("Failed to add transaction"); + } + + #[tokio::test] + async fn validate_no_duplicates() { + const ACC: u32 = 0; + + let pool = setup().await; + + let account = test_utils::account(ACC); + let tx = test_utils::eip1559().to(account).call(); + let tx = test_utils::eth_tx(ACC, tx).await; + + pool.add_external_transaction(tx.clone().into()) + .await + .expect("Failed to add transaction"); + + let res = pool.add_external_transaction(tx.clone().into()).await; - // Check here that we're properly caching the transaction - assert!(first_insert > second_insert * 10); assert!(res.is_err()); } + #[tokio::test] + async fn validate_pbh_bundle() { + const BUNDLER_ACCOUNT: u32 = 9; + const USER_ACCOUNT: u32 = 0; + + let pool = setup().await; + + let user_op = test_utils::user_op().acc(USER_ACCOUNT).call(); + let bundle = test_utils::pbh_bundle(vec![user_op]); + let calldata = bundle.abi_encode(); + + let tx = test_utils::eip1559() + .to(PBH_TEST_VALIDATOR) + .input(calldata) + .call(); + + let tx = test_utils::eth_tx(BUNDLER_ACCOUNT, tx).await; + + pool.add_external_transaction(tx.clone().into()) + .await + .expect("Failed to add transaction"); + } + #[tokio::test] async fn validate_4337_bundle() { let validator = world_chain_validator(); @@ -425,7 +540,7 @@ pub mod tests { (U256::from(7u64), U256::from(8u64)), )); let payload = PbhPayload { - external_nullifier: "0-012025-11".to_string(), + external_nullifier: ExternalNullifier::v1(1, 2025, 11), nullifier_hash: Field::from(10u64), root, proof, @@ -459,7 +574,7 @@ pub mod tests { (U256::from(7u64), U256::from(8u64)), )); let payload = PbhPayload { - external_nullifier: "0-012025-11".to_string(), + external_nullifier: ExternalNullifier::v1(1, 2025, 11), nullifier_hash: Field::from(10u64), root, proof, @@ -488,7 +603,7 @@ pub mod tests { let date = chrono::Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).unwrap(); let payload = PbhPayload { - external_nullifier: external_nullifier.to_string(), + external_nullifier: external_nullifier.parse().unwrap(), nullifier_hash: Field::ZERO, root: Field::ZERO, proof: Default::default(), @@ -506,7 +621,7 @@ pub mod tests { let date: chrono::DateTime = time.parse().unwrap(); let payload = PbhPayload { - external_nullifier: external_nullifier.to_string(), + external_nullifier: external_nullifier.parse().unwrap(), nullifier_hash: Field::ZERO, root: Field::ZERO, proof: Default::default(), @@ -516,27 +631,3 @@ pub mod tests { .validate_external_nullifier(date, &payload) .unwrap(); } - - #[test_case("v0-012025-0")] - #[test_case("v1-022025-0")] - #[test_case("v1-122024-0")] - #[test_case("v1-002025-0")] - #[test_case("v1-012025-30")] - #[test_case("v1-012025")] - #[test_case("12025-0")] - #[test_case("v1-012025-0-0")] - fn validate_external_nullifier_invalid(external_nullifier: &str) { - let validator = world_chain_validator(); - let date = chrono::Utc.with_ymd_and_hms(2025, 1, 1, 12, 0, 0).unwrap(); - - let payload = PbhPayload { - external_nullifier: external_nullifier.to_string(), - nullifier_hash: Field::ZERO, - root: Field::ZERO, - proof: Default::default(), - }; - - let res = validator.validate_external_nullifier(date, &payload); - assert!(res.is_err()); - } -} From d50e8bbb150063b1bcd06a2d81969dee107d1b4b Mon Sep 17 00:00:00 2001 From: Dzejkop Date: Tue, 17 Dec 2024 16:28:17 +0100 Subject: [PATCH 57/59] Fix: deleted curly brace --- world-chain-builder/crates/world/pool/src/lib.rs | 4 ++-- world-chain-builder/crates/world/pool/src/validator.rs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/world-chain-builder/crates/world/pool/src/lib.rs b/world-chain-builder/crates/world/pool/src/lib.rs index b00b4241..6db5e685 100644 --- a/world-chain-builder/crates/world/pool/src/lib.rs +++ b/world-chain-builder/crates/world/pool/src/lib.rs @@ -1,13 +1,13 @@ pub mod bindings; pub mod builder; +pub mod eip4337; pub mod error; pub mod noop; pub mod ordering; +pub mod payload; pub mod root; pub mod tx; pub mod validator; -pub mod payload; -pub mod eip4337; #[cfg(any(feature = "test", test))] pub mod test_utils; diff --git a/world-chain-builder/crates/world/pool/src/validator.rs b/world-chain-builder/crates/world/pool/src/validator.rs index 2c5009dd..6ea279dd 100644 --- a/world-chain-builder/crates/world/pool/src/validator.rs +++ b/world-chain-builder/crates/world/pool/src/validator.rs @@ -631,3 +631,4 @@ pub mod tests { .validate_external_nullifier(date, &payload) .unwrap(); } +} From eb3743845f3960ac6c2460626f47819a3719aedb Mon Sep 17 00:00:00 2001 From: Dzejkop Date: Tue, 17 Dec 2024 17:00:16 +0100 Subject: [PATCH 58/59] Validate user ops and payload counts --- world-chain-builder/Cargo.lock | 1 + .../crates/world/pbh/Cargo.toml | 1 + .../world/pbh/src/external_nullifier.rs | 30 ++-- .../crates/world/pool/src/error.rs | 4 +- .../crates/world/pool/src/lib.rs | 1 - .../crates/world/pool/src/payload.rs | 23 --- .../crates/world/pool/src/test_utils.rs | 36 +++-- .../crates/world/pool/src/validator.rs | 146 +++++++++--------- 8 files changed, 117 insertions(+), 125 deletions(-) delete mode 100644 world-chain-builder/crates/world/pool/src/payload.rs diff --git a/world-chain-builder/Cargo.lock b/world-chain-builder/Cargo.lock index 4bc86228..c27225a8 100644 --- a/world-chain-builder/Cargo.lock +++ b/world-chain-builder/Cargo.lock @@ -13795,6 +13795,7 @@ name = "world-chain-builder-pbh" version = "0.1.0" dependencies = [ "alloy-rlp", + "bon", "chrono", "ethers-core 2.0.14 (git+https://github.com/gakonst/ethers-rs)", "semaphore", diff --git a/world-chain-builder/crates/world/pbh/Cargo.toml b/world-chain-builder/crates/world/pbh/Cargo.toml index c6df5f4f..f56bca1a 100644 --- a/world-chain-builder/crates/world/pbh/Cargo.toml +++ b/world-chain-builder/crates/world/pbh/Cargo.toml @@ -11,6 +11,7 @@ thiserror = { workspace = true } semaphore.workspace = true strum.workspace = true serde.workspace = true +bon.workspace = true [dev-dependencies] ethers-core.workspace = true diff --git a/world-chain-builder/crates/world/pbh/src/external_nullifier.rs b/world-chain-builder/crates/world/pbh/src/external_nullifier.rs index e3ad34bd..5fb53ab1 100644 --- a/world-chain-builder/crates/world/pbh/src/external_nullifier.rs +++ b/world-chain-builder/crates/world/pbh/src/external_nullifier.rs @@ -1,37 +1,25 @@ use std::str::FromStr; -use alloy_rlp::{Decodable, Encodable, Rlp}; +use alloy_rlp::{Decodable, Encodable}; +use bon::Builder; use semaphore::{hash_to_field, Field}; use strum::{Display, EnumString}; use thiserror::Error; use crate::date_marker::{DateMarker, DateMarkerParsingError}; -#[macro_export] -macro_rules! ext_nullifier { - ($mo:expr,$yr:expr,$no:expr) => {{ - let prefix = $crate::external_nullifier::Prefix::V1; - let date_marker = $crate::date_marker::DateMarker::new($yr, $mo); - - $crate::external_nullifier::ExternalNullifier::new(prefix, date_marker, $no) - }}; -} - -#[test] -fn whatever() { - ext_nullifier!(01, 2025, 1); -} - #[derive(Display, EnumString, Debug, Clone, Copy, PartialEq, Eq)] #[strum(serialize_all = "snake_case")] pub enum Prefix { V1, } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Builder, Debug, Clone, Copy, PartialEq, Eq)] pub struct ExternalNullifier { + #[builder(default = Prefix::V1)] pub prefix: Prefix, pub date_marker: DateMarker, + #[builder(default = 0)] pub nonce: u16, } @@ -117,13 +105,17 @@ impl FromStr for ExternalNullifier { impl Decodable for ExternalNullifier { fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { - todo!() + let s: String = Decodable::decode(buf)?; + + s.parse::() + .map_err(|_| alloy_rlp::Error::Custom("Failed to parse string to external nullifier")) } } impl Encodable for ExternalNullifier { fn encode(&self, out: &mut dyn alloy_rlp::BufMut) { - todo!() + let s = self.to_string(); + Encodable::encode(&s, out) } } diff --git a/world-chain-builder/crates/world/pool/src/error.rs b/world-chain-builder/crates/world/pool/src/error.rs index ae10f5b2..9dbc183e 100644 --- a/world-chain-builder/crates/world/pool/src/error.rs +++ b/world-chain-builder/crates/world/pool/src/error.rs @@ -5,7 +5,7 @@ use reth_provider::ProviderError; use world_chain_builder_pbh::external_nullifier::ExternalNullifierParsingError; -#[derive(Debug, thiserror::Error)] +#[derive(Debug, thiserror::Error, PartialEq, Eq)] pub enum WorldChainTransactionPoolInvalid { #[error("nullifier has already been seen")] NullifierAlreadyExists, @@ -29,6 +29,8 @@ pub enum WorldChainTransactionPoolInvalid { InvalidRoot, #[error(transparent)] MalformedSignature(#[from] alloy_rlp::Error), + #[error("One or more user ops are missing pbh payloads")] + MissingPbhPayload, } #[derive(Debug, thiserror::Error)] diff --git a/world-chain-builder/crates/world/pool/src/lib.rs b/world-chain-builder/crates/world/pool/src/lib.rs index 6db5e685..e2b1d650 100644 --- a/world-chain-builder/crates/world/pool/src/lib.rs +++ b/world-chain-builder/crates/world/pool/src/lib.rs @@ -4,7 +4,6 @@ pub mod eip4337; pub mod error; pub mod noop; pub mod ordering; -pub mod payload; pub mod root; pub mod tx; pub mod validator; diff --git a/world-chain-builder/crates/world/pool/src/payload.rs b/world-chain-builder/crates/world/pool/src/payload.rs deleted file mode 100644 index f924d3f0..00000000 --- a/world-chain-builder/crates/world/pool/src/payload.rs +++ /dev/null @@ -1,23 +0,0 @@ -use bon::builder; - -#[builder(on(String, into))] -pub fn build_pbh_tx( - #[builder(default = "test test test test test test test test test test test junk")] - mnemonic: String, - - user_ops: Vec, -) { -} - -#[builder(on(String, into))] -pub fn build_user_op() {} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn whatever() { - // build_pbh_tx().call(); - } -} diff --git a/world-chain-builder/crates/world/pool/src/test_utils.rs b/world-chain-builder/crates/world/pool/src/test_utils.rs index d7ef630d..3467a464 100644 --- a/world-chain-builder/crates/world/pool/src/test_utils.rs +++ b/world-chain-builder/crates/world/pool/src/test_utils.rs @@ -20,7 +20,7 @@ use reth_primitives::PooledTransactionsElement; use reth_provider::test_utils::MockEthProvider; use revm_primitives::{hex, Address, TxKind}; use semaphore::identity::Identity; -use semaphore::poseidon_tree::{LazyPoseidonTree, PoseidonTree}; +use semaphore::poseidon_tree::LazyPoseidonTree; use semaphore::protocol::{generate_nullifier_hash, generate_proof}; use semaphore::{hash_to_field, Field}; use world_chain_builder_pbh::date_marker::DateMarker; @@ -173,16 +173,9 @@ pub fn user_op( } pub fn pbh_bundle( - ops: Vec<(PackedUserOperation, PbhPayload)>, + user_ops: Vec, + proofs: Vec, ) -> IPBHValidator::handleAggregatedOpsCall { - let mut user_ops = Vec::new(); - let mut proofs = Vec::new(); - - for (user_op, proof) in ops { - user_ops.push(user_op); - proofs.push(proof); - } - let mut signature_buff = Vec::new(); proofs.encode(&mut signature_buff); @@ -350,3 +343,26 @@ pub fn create_pbh_paylaod( proof, } } + +#[cfg(test)] +mod tests { + use test_case::test_case; + + use super::*; + + #[test_case(0, "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266")] + #[test_case(1, "0x70997970C51812dc3A010C7d01b50e0d17dc79C8")] + #[test_case(2, "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC")] + #[test_case(3, "0x90F79bf6EB2c4f870365E785982E1f101E93b906")] + #[test_case(4, "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65")] + #[test_case(5, "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc")] + #[test_case(6, "0x976EA74026E726554dB657fA54763abd0C3a0aa9")] + #[test_case(7, "0x14dC79964da2C08b23698B3D3cc7Ca32193d9955")] + #[test_case(8, "0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f")] + #[test_case(9, "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720")] + fn mnemonic_accounts(index: u32, exp_address: &str) { + let exp: Address = exp_address.parse().unwrap(); + + assert_eq!(exp, account(index)); + } +} diff --git a/world-chain-builder/crates/world/pool/src/validator.rs b/world-chain-builder/crates/world/pool/src/validator.rs index 6ea279dd..98d865ea 100644 --- a/world-chain-builder/crates/world/pool/src/validator.rs +++ b/world-chain-builder/crates/world/pool/src/validator.rs @@ -1,7 +1,7 @@ //! World Chain transaction pool types -use alloy_primitives::{Address, Bytes, U256}; +use alloy_primitives::{Address, U256}; use alloy_rlp::Decodable; -use alloy_sol_types::{SolCall, SolValue}; +use alloy_sol_types::SolCall; use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator}; use reth::transaction_pool::{ Pool, TransactionOrigin, TransactionValidationOutcome, TransactionValidationTaskExecutor, @@ -10,10 +10,8 @@ use reth::transaction_pool::{ use reth_optimism_node::txpool::OpTransactionValidator; use reth_primitives::{Block, SealedBlock, TransactionSigned}; use reth_provider::{BlockReaderIdExt, StateProviderFactory}; -use semaphore::hash_to_field; use semaphore::protocol::verify_proof; use world_chain_builder_pbh::date_marker::DateMarker; -use world_chain_builder_pbh::external_nullifier::ExternalNullifier; use world_chain_builder_pbh::payload::{PbhPayload, TREE_DEPTH}; use super::error::{TransactionValidationError, WorldChainTransactionPoolInvalid}; @@ -182,19 +180,17 @@ where .map_err(WorldChainTransactionPoolInvalid::from) .map_err(TransactionValidationError::from)?; + if pbh_payloads.len() != aggregated_ops.userOps.len() { + Err(WorldChainTransactionPoolInvalid::MissingPbhPayload)?; + } + pbh_payloads .par_iter() .zip(aggregated_ops.userOps) .try_for_each(|(payload, op)| { - let signal = alloy_primitives::keccak256( - <(Address, U256, Bytes) as SolValue>::abi_encode_packed(&( - op.sender, - op.nonce, - op.callData, - )), - ); + let signal = crate::eip4337::hash_user_op(&op); - self.validate_pbh_payload(&payload, hash_to_field(signal.as_ref()))?; + self.validate_pbh_payload(&payload, signal)?; Ok::<(), TransactionValidationError>(()) })?; @@ -236,30 +232,24 @@ where #[cfg(test)] pub mod tests { - use std::time::Instant; - - use alloy_primitives::Address; - use alloy_signer_local::coins_bip39::English; - use alloy_signer_local::PrivateKeySigner; use alloy_sol_types::SolCall; - use bon::builder; use chrono::{TimeZone, Utc}; use ethers_core::types::U256; use reth::transaction_pool::blobstore::InMemoryBlobStore; + use reth::transaction_pool::error::{InvalidPoolTransactionError, PoolError, PoolErrorKind}; use reth::transaction_pool::{ Pool, PoolTransaction as _, TransactionPool, TransactionValidator, }; use reth_primitives::{BlockBody, SealedBlock, SealedHeader}; use reth_provider::test_utils::{ExtendedAccount, MockEthProvider}; - use semaphore::identity::Identity; - use semaphore::poseidon_tree::PoseidonTree; use semaphore::Field; use test_case::test_case; - use world_chain_builder_pbh::ext_nullifier; + use world_chain_builder_pbh::date_marker::DateMarker; use world_chain_builder_pbh::external_nullifier::ExternalNullifier; use world_chain_builder_pbh::payload::{PbhPayload, Proof}; use super::WorldChainTransactionValidator; + use crate::error::WorldChainTransactionPoolInvalid; use crate::ordering::WorldChainOrdering; use crate::root::{LATEST_ROOT_SLOT, OP_WORLD_ID}; use crate::test_utils::{ @@ -268,56 +258,11 @@ pub mod tests { }; use crate::tx::WorldChainPooledTransaction; - #[builder(on(String, into))] - pub fn signer( - #[builder(default = "test test test test test test test test test test test junk")] - mnemonic: String, - #[builder(default = 0)] index: u32, - ) -> PrivateKeySigner { - let signer = alloy_signer_local::MnemonicBuilder::::default() - .phrase(&mnemonic) - .index(index) - .expect("Failed to set index") - .build() - .expect("Failed to create signer"); - - signer - } - - #[builder(on(String, into))] - pub fn account( - #[builder(default = "test test test test test test test test test test test junk")] - mnemonic: String, - #[builder(default = 0)] index: u32, - ) -> Address { - let signer = signer().mnemonic(mnemonic).index(index).call(); - - signer.address() - } - - #[test_case(0, "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266")] - #[test_case(1, "0x70997970C51812dc3A010C7d01b50e0d17dc79C8")] - #[test_case(2, "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC")] - #[test_case(3, "0x90F79bf6EB2c4f870365E785982E1f101E93b906")] - #[test_case(4, "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65")] - #[test_case(5, "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc")] - #[test_case(6, "0x976EA74026E726554dB657fA54763abd0C3a0aa9")] - #[test_case(7, "0x14dC79964da2C08b23698B3D3cc7Ca32193d9955")] - #[test_case(8, "0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f")] - #[test_case(9, "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720")] - fn mnemonic_accounts(index: u32, exp_address: &str) { - let exp: Address = exp_address.parse().unwrap(); - - assert_eq!(exp, account().index(index).call()); - } - async fn setup() -> Pool< WorldChainTransactionValidator, WorldChainOrdering, InMemoryBlobStore, > { - let start = Instant::now(); - let validator = world_chain_validator(); // TODO: Remove @@ -329,7 +274,7 @@ pub mod tests { // Fund 10 test accounts for acc in 0..10 { - let account_address = account().index(acc).call(); + let account_address = test_utils::account(acc); validator.inner.client().add_account( account_address, @@ -364,11 +309,23 @@ pub mod tests { Default::default(), ); - println!("Building the pool took {:?}", start.elapsed()); - pool } + fn downcast_pool_err(err: &PoolError) -> &WorldChainTransactionPoolInvalid { + let PoolErrorKind::InvalidTransaction(InvalidPoolTransactionError::Other(other)) = + &err.kind + else { + panic!("Invalid error kind!"); + }; + + other + .source() + .expect("Missing error source") + .downcast_ref::() + .expect("Failed to downcast") + } + #[tokio::test] async fn validate_noop_non_pbh() { const ACC: u32 = 0; @@ -410,8 +367,15 @@ pub mod tests { let pool = setup().await; - let user_op = test_utils::user_op().acc(USER_ACCOUNT).call(); - let bundle = test_utils::pbh_bundle(vec![user_op]); + let (user_op, proof) = test_utils::user_op() + .acc(USER_ACCOUNT) + .external_nullifier( + ExternalNullifier::builder() + .date_marker(DateMarker::from(chrono::Utc::now())) + .build(), + ) + .call(); + let bundle = test_utils::pbh_bundle(vec![user_op], vec![proof]); let calldata = bundle.abi_encode(); let tx = test_utils::eip1559() @@ -426,6 +390,46 @@ pub mod tests { .expect("Failed to add transaction"); } + #[tokio::test] + async fn validate_pbh_missing_proof_for_user_op() { + const BUNDLER_ACCOUNT: u32 = 9; + const USER_ACCOUNT: u32 = 0; + + let pool = setup().await; + + let (user_op, _proof) = test_utils::user_op() + .acc(USER_ACCOUNT) + .external_nullifier( + ExternalNullifier::builder() + .date_marker(DateMarker::from(chrono::Utc::now())) + .build(), + ) + .call(); + + let bundle = test_utils::pbh_bundle(vec![user_op], vec![]); + + let calldata = bundle.abi_encode(); + + let tx = test_utils::eip1559() + .to(PBH_TEST_VALIDATOR) + .input(calldata) + .call(); + + let tx = test_utils::eth_tx(BUNDLER_ACCOUNT, tx).await; + + let err = pool + .add_external_transaction(tx.clone().into()) + .await + .expect_err("Validation should fail because of missing proof"); + + let world_chain_err = downcast_pool_err(&err); + + assert_eq!( + world_chain_err, + &WorldChainTransactionPoolInvalid::MissingPbhPayload + ); + } + #[tokio::test] async fn validate_4337_bundle() { let validator = world_chain_validator(); From b4ff6dbafb16cabbffca0024eec980854ce0e977 Mon Sep 17 00:00:00 2001 From: 0xOsiris Date: Tue, 17 Dec 2024 09:47:11 -0700 Subject: [PATCH 59/59] update signal hash computation --- world-chain-builder/crates/world/pool/src/eip4337.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/world-chain-builder/crates/world/pool/src/eip4337.rs b/world-chain-builder/crates/world/pool/src/eip4337.rs index e435f542..dc90731c 100644 --- a/world-chain-builder/crates/world/pool/src/eip4337.rs +++ b/world-chain-builder/crates/world/pool/src/eip4337.rs @@ -8,12 +8,7 @@ pub fn hash_user_op(user_op: &PackedUserOperation) -> Field { let keccak_hash = keccak256(SolValue::abi_encode_packed(&( &user_op.sender, &user_op.nonce, - &user_op.initCode, &user_op.callData, - &user_op.accountGasLimits, - &user_op.preVerificationGas, - &user_op.gasFees, - &user_op.paymasterAndData, ))); hash_to_field(keccak_hash.as_slice())