From bb03578eed90d2eff4d75a420cb4bee224102167 Mon Sep 17 00:00:00 2001 From: garwah <14845405+garwahl@users.noreply.github.com> Date: Mon, 4 Nov 2024 18:01:40 +1100 Subject: [PATCH 001/211] chore: Move FillTxEnv::fill_tx_env into SignedTransaction trait and implement in TransactionSigned (#12186) Co-authored-by: garwah Co-authored-by: Emilia Hane --- .../src/transaction/signed.rs | 4 + crates/primitives/src/transaction/mod.rs | 117 ++++++++++++++++++ 2 files changed, 121 insertions(+) diff --git a/crates/primitives-traits/src/transaction/signed.rs b/crates/primitives-traits/src/transaction/signed.rs index 748ef39666d..4c12437212a 100644 --- a/crates/primitives-traits/src/transaction/signed.rs +++ b/crates/primitives-traits/src/transaction/signed.rs @@ -6,6 +6,7 @@ use core::hash::Hash; use alloy_consensus::Transaction; use alloy_eips::eip2718::{Decodable2718, Encodable2718}; use alloy_primitives::{keccak256, Address, Signature, TxHash, B256}; +use revm_primitives::TxEnv; /// A signed transaction. pub trait SignedTransaction: @@ -64,4 +65,7 @@ pub trait SignedTransaction: fn recalculate_hash(&self) -> B256 { keccak256(self.encoded_2718()) } + + /// Fills [`TxEnv`] with an [`Address`] and transaction. + fn fill_tx_env(&self, tx_env: &mut TxEnv, sender: Address); } diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index 59d3b9e1297..b9a24316c40 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -64,6 +64,8 @@ use tx_type::{ }; use alloc::vec::Vec; +use reth_primitives_traits::SignedTransaction; +use revm_primitives::{AuthorizationList, TxEnv}; /// Either a transaction hash or number. pub type TxHashOrNumber = BlockHashOrNumber; @@ -1123,6 +1125,11 @@ impl TransactionSigned { &self.signature } + /// Transaction + pub const fn transaction(&self) -> &Transaction { + &self.transaction + } + /// Transaction hash. Used to identify transaction. pub const fn hash(&self) -> TxHash { self.hash @@ -1398,6 +1405,116 @@ impl alloy_consensus::Transaction for TransactionSigned { } } +impl SignedTransaction for TransactionSigned { + type Transaction = Transaction; + + fn tx_hash(&self) -> &TxHash { + Self::hash_ref(self) + } + + fn transaction(&self) -> &Self::Transaction { + Self::transaction(self) + } + + fn signature(&self) -> &Signature { + Self::signature(self) + } + + fn recover_signer(&self) -> Option
{ + Self::recover_signer(self) + } + + fn recover_signer_unchecked(&self) -> Option
{ + Self::recover_signer_unchecked(self) + } + + fn from_transaction_and_signature( + transaction: Self::Transaction, + signature: Signature, + ) -> Self { + Self::from_transaction_and_signature(transaction, signature) + } + + fn fill_tx_env(&self, tx_env: &mut TxEnv, sender: Address) { + tx_env.caller = sender; + match self.as_ref() { + Transaction::Legacy(tx) => { + tx_env.gas_limit = tx.gas_limit; + tx_env.gas_price = U256::from(tx.gas_price); + tx_env.gas_priority_fee = None; + tx_env.transact_to = tx.to; + tx_env.value = tx.value; + tx_env.data = tx.input.clone(); + tx_env.chain_id = tx.chain_id; + tx_env.nonce = Some(tx.nonce); + tx_env.access_list.clear(); + tx_env.blob_hashes.clear(); + tx_env.max_fee_per_blob_gas.take(); + tx_env.authorization_list = None; + } + Transaction::Eip2930(tx) => { + tx_env.gas_limit = tx.gas_limit; + tx_env.gas_price = U256::from(tx.gas_price); + tx_env.gas_priority_fee = None; + tx_env.transact_to = tx.to; + tx_env.value = tx.value; + tx_env.data = tx.input.clone(); + tx_env.chain_id = Some(tx.chain_id); + tx_env.nonce = Some(tx.nonce); + tx_env.access_list.clone_from(&tx.access_list.0); + tx_env.blob_hashes.clear(); + tx_env.max_fee_per_blob_gas.take(); + tx_env.authorization_list = None; + } + Transaction::Eip1559(tx) => { + tx_env.gas_limit = tx.gas_limit; + tx_env.gas_price = U256::from(tx.max_fee_per_gas); + tx_env.gas_priority_fee = Some(U256::from(tx.max_priority_fee_per_gas)); + tx_env.transact_to = tx.to; + tx_env.value = tx.value; + tx_env.data = tx.input.clone(); + tx_env.chain_id = Some(tx.chain_id); + tx_env.nonce = Some(tx.nonce); + tx_env.access_list.clone_from(&tx.access_list.0); + tx_env.blob_hashes.clear(); + tx_env.max_fee_per_blob_gas.take(); + tx_env.authorization_list = None; + } + Transaction::Eip4844(tx) => { + tx_env.gas_limit = tx.gas_limit; + tx_env.gas_price = U256::from(tx.max_fee_per_gas); + tx_env.gas_priority_fee = Some(U256::from(tx.max_priority_fee_per_gas)); + tx_env.transact_to = TxKind::Call(tx.to); + tx_env.value = tx.value; + tx_env.data = tx.input.clone(); + tx_env.chain_id = Some(tx.chain_id); + tx_env.nonce = Some(tx.nonce); + tx_env.access_list.clone_from(&tx.access_list.0); + tx_env.blob_hashes.clone_from(&tx.blob_versioned_hashes); + tx_env.max_fee_per_blob_gas = Some(U256::from(tx.max_fee_per_blob_gas)); + tx_env.authorization_list = None; + } + Transaction::Eip7702(tx) => { + tx_env.gas_limit = tx.gas_limit; + tx_env.gas_price = U256::from(tx.max_fee_per_gas); + tx_env.gas_priority_fee = Some(U256::from(tx.max_priority_fee_per_gas)); + tx_env.transact_to = tx.to.into(); + tx_env.value = tx.value; + tx_env.data = tx.input.clone(); + tx_env.chain_id = Some(tx.chain_id); + tx_env.nonce = Some(tx.nonce); + tx_env.access_list.clone_from(&tx.access_list.0); + tx_env.blob_hashes.clear(); + tx_env.max_fee_per_blob_gas.take(); + tx_env.authorization_list = + Some(AuthorizationList::Signed(tx.authorization_list.clone())); + } + #[cfg(feature = "optimism")] + Transaction::Deposit(_) => {} + } + } +} + impl From for TransactionSigned { fn from(recovered: TransactionSignedEcRecovered) -> Self { recovered.signed_transaction From 98140416032dd0e964c28fe87675e453baa815d2 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Mon, 4 Nov 2024 09:18:13 +0100 Subject: [PATCH 002/211] primitives: rm useless `OP_` constants (#12298) --- crates/primitives-traits/src/constants/mod.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/crates/primitives-traits/src/constants/mod.rs b/crates/primitives-traits/src/constants/mod.rs index f3dd28e1929..94eaf95c269 100644 --- a/crates/primitives-traits/src/constants/mod.rs +++ b/crates/primitives-traits/src/constants/mod.rs @@ -1,6 +1,6 @@ //! Ethereum protocol-related constants -use alloy_primitives::{address, b256, Address, B256}; +use alloy_primitives::{b256, B256}; /// Gas units, for example [`GIGAGAS`]. pub mod gas_units; @@ -16,12 +16,6 @@ pub const MINIMUM_GAS_LIMIT: u64 = 5000; pub const HOLESKY_GENESIS_HASH: B256 = b256!("b5f7f912443c940f21fd611f12828d75b534364ed9e95ca4e307729a4661bde4"); -/// From address from Optimism system txs: `0xdeaddeaddeaddeaddeaddeaddeaddeaddead0001` -pub const OP_SYSTEM_TX_FROM_ADDR: Address = address!("deaddeaddeaddeaddeaddeaddeaddeaddead0001"); - -/// To address from Optimism system txs: `0x4200000000000000000000000000000000000015` -pub const OP_SYSTEM_TX_TO_ADDR: Address = address!("4200000000000000000000000000000000000015"); - /// The number of blocks to unwind during a reorg that already became a part of canonical chain. /// /// In reality, the node can end up in this particular situation very rarely. It would happen only From 56b76871edd9680290242dd0f7d66d7a8b8b6cba Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Mon, 4 Nov 2024 09:21:17 +0100 Subject: [PATCH 003/211] primitives: rm alloy `Withdrawal` reexport (#12296) --- crates/consensus/common/src/validation.rs | 3 ++- crates/evm/src/state_change.rs | 3 ++- crates/primitives-traits/src/lib.rs | 2 +- crates/primitives-traits/src/withdrawal.rs | 5 +---- crates/primitives/src/lib.rs | 2 +- crates/primitives/src/proofs.rs | 6 ++---- .../storage/provider/src/providers/blockchain_provider.rs | 4 ++-- crates/storage/provider/src/providers/consistent.rs | 6 ++++-- crates/storage/provider/src/providers/database/mod.rs | 5 ++--- crates/storage/provider/src/providers/database/provider.rs | 4 ++-- crates/storage/provider/src/providers/mod.rs | 5 ++--- .../storage/provider/src/providers/static_file/manager.rs | 5 ++--- crates/storage/provider/src/test_utils/blocks.rs | 3 ++- crates/storage/provider/src/test_utils/mock.rs | 4 ++-- crates/storage/provider/src/test_utils/noop.rs | 4 ++-- crates/storage/storage-api/src/withdrawals.rs | 4 ++-- examples/custom-beacon-withdrawals/src/main.rs | 4 ++-- testing/testing-utils/Cargo.toml | 1 + testing/testing-utils/src/generators.rs | 3 ++- 19 files changed, 36 insertions(+), 37 deletions(-) diff --git a/crates/consensus/common/src/validation.rs b/crates/consensus/common/src/validation.rs index c6539cdcf71..a6e5d21587f 100644 --- a/crates/consensus/common/src/validation.rs +++ b/crates/consensus/common/src/validation.rs @@ -275,6 +275,7 @@ pub fn validate_against_parent_4844( mod tests { use super::*; use alloy_consensus::{TxEip4844, EMPTY_OMMER_ROOT_HASH, EMPTY_ROOT_HASH}; + use alloy_eips::eip4895::Withdrawal; use alloy_primitives::{ hex_literal::hex, Address, BlockHash, BlockNumber, Bytes, Parity, Sealable, U256, }; @@ -283,7 +284,7 @@ mod tests { use reth_chainspec::ChainSpecBuilder; use reth_primitives::{ proofs, Account, BlockBody, BlockHashOrNumber, Signature, Transaction, TransactionSigned, - Withdrawal, Withdrawals, + Withdrawals, }; use reth_storage_api::{ errors::provider::ProviderResult, AccountReader, HeaderProvider, WithdrawalsProvider, diff --git a/crates/evm/src/state_change.rs b/crates/evm/src/state_change.rs index 2a3d93f94d9..2d91ac30eeb 100644 --- a/crates/evm/src/state_change.rs +++ b/crates/evm/src/state_change.rs @@ -1,9 +1,10 @@ //! State changes that are not related to transactions. +use alloy_eips::eip4895::Withdrawal; use alloy_primitives::{map::HashMap, Address, U256}; use reth_chainspec::EthereumHardforks; use reth_consensus_common::calc; -use reth_primitives::{Block, Withdrawal, Withdrawals}; +use reth_primitives::{Block, Withdrawals}; /// Collect all balance changes at the end of the block. /// diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index 9f41bbd47fb..90a6935ae10 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -34,7 +34,7 @@ pub mod block; pub use block::{body::BlockBody, Block}; mod withdrawal; -pub use withdrawal::{Withdrawal, Withdrawals}; +pub use withdrawal::Withdrawals; mod error; pub use error::{GotExpected, GotExpectedBoxed}; diff --git a/crates/primitives-traits/src/withdrawal.rs b/crates/primitives-traits/src/withdrawal.rs index 995e60292c6..8f072afa578 100644 --- a/crates/primitives-traits/src/withdrawal.rs +++ b/crates/primitives-traits/src/withdrawal.rs @@ -1,13 +1,10 @@ //! [EIP-4895](https://eips.ethereum.org/EIPS/eip-4895) Withdrawal types. use alloc::vec::Vec; +use alloy_eips::eip4895::Withdrawal; use alloy_rlp::{RlpDecodableWrapper, RlpEncodableWrapper}; use derive_more::{AsRef, Deref, DerefMut, From, IntoIterator}; use reth_codecs::{add_arbitrary_tests, Compact}; - -/// Re-export from `alloy_eips`. -#[doc(inline)] -pub use alloy_eips::eip4895::Withdrawal; use serde::{Deserialize, Serialize}; /// Represents a collection of Withdrawals. diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 4e3f1d3bd24..9bb27e658ca 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -45,7 +45,7 @@ pub use receipt::{ }; pub use reth_primitives_traits::{ logs_bloom, Account, Bytecode, GotExpected, GotExpectedBoxed, Header, HeaderError, Log, - LogData, SealedHeader, StorageEntry, Withdrawal, Withdrawals, + LogData, SealedHeader, StorageEntry, Withdrawals, }; pub use static_file::StaticFileSegment; diff --git a/crates/primitives/src/proofs.rs b/crates/primitives/src/proofs.rs index 1697246702a..000244d2c54 100644 --- a/crates/primitives/src/proofs.rs +++ b/crates/primitives/src/proofs.rs @@ -1,11 +1,9 @@ //! Helper function for calculating Merkle proofs and hashes. -use crate::{ - Header, Receipt, ReceiptWithBloom, ReceiptWithBloomRef, TransactionSigned, Withdrawal, -}; +use crate::{Header, Receipt, ReceiptWithBloom, ReceiptWithBloomRef, TransactionSigned}; use alloc::vec::Vec; use alloy_consensus::EMPTY_OMMER_ROOT_HASH; -use alloy_eips::eip2718::Encodable2718; +use alloy_eips::{eip2718::Encodable2718, eip4895::Withdrawal}; use alloy_primitives::{keccak256, B256}; use reth_trie_common::root::{ordered_trie_root, ordered_trie_root_with_encoder}; diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index 64a8a204a32..85f759310ba 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -9,7 +9,7 @@ use crate::{ StageCheckpointReader, StateProviderBox, StateProviderFactory, StateReader, StaticFileProviderFactory, TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; -use alloy_eips::{BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag}; +use alloy_eips::{eip4895::Withdrawal, BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag}; use alloy_primitives::{Address, BlockHash, BlockNumber, Sealable, TxHash, TxNumber, B256, U256}; use alloy_rpc_types_engine::ForkchoiceState; use reth_chain_state::{ @@ -25,7 +25,7 @@ use reth_node_types::NodeTypesWithDB; use reth_primitives::{ Account, Block, BlockWithSenders, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, StorageEntry, TransactionMeta, TransactionSigned, TransactionSignedNoHash, - Withdrawal, Withdrawals, + Withdrawals, }; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; diff --git a/crates/storage/provider/src/providers/consistent.rs b/crates/storage/provider/src/providers/consistent.rs index e6ca1a91932..0784bdb6346 100644 --- a/crates/storage/provider/src/providers/consistent.rs +++ b/crates/storage/provider/src/providers/consistent.rs @@ -6,7 +6,9 @@ use crate::{ StageCheckpointReader, StateReader, StaticFileProviderFactory, TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; -use alloy_eips::{BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, HashOrNumber}; +use alloy_eips::{ + eip4895::Withdrawal, BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, HashOrNumber, +}; use alloy_primitives::{Address, BlockHash, BlockNumber, Sealable, TxHash, TxNumber, B256, U256}; use reth_chain_state::{BlockState, CanonicalInMemoryState, MemoryOverlayStateProviderRef}; use reth_chainspec::{ChainInfo, EthereumHardforks}; @@ -17,7 +19,7 @@ use reth_execution_types::{BundleStateInit, ExecutionOutcome, RevertsInit}; use reth_primitives::{ Account, Block, BlockWithSenders, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, StorageEntry, TransactionMeta, TransactionSigned, TransactionSignedNoHash, - Withdrawal, Withdrawals, + Withdrawals, }; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; diff --git a/crates/storage/provider/src/providers/database/mod.rs b/crates/storage/provider/src/providers/database/mod.rs index 04a30ce90aa..bd0466ff973 100644 --- a/crates/storage/provider/src/providers/database/mod.rs +++ b/crates/storage/provider/src/providers/database/mod.rs @@ -7,7 +7,7 @@ use crate::{ PruneCheckpointReader, StageCheckpointReader, StateProviderBox, StaticFileProviderFactory, TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; -use alloy_eips::BlockHashOrNumber; +use alloy_eips::{eip4895::Withdrawal, BlockHashOrNumber}; use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256}; use core::fmt; use reth_chainspec::{ChainInfo, EthereumHardforks}; @@ -18,8 +18,7 @@ use reth_evm::ConfigureEvmEnv; use reth_node_types::NodeTypesWithDB; use reth_primitives::{ Block, BlockWithSenders, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, - StaticFileSegment, TransactionMeta, TransactionSigned, TransactionSignedNoHash, Withdrawal, - Withdrawals, + StaticFileSegment, TransactionMeta, TransactionSigned, TransactionSignedNoHash, Withdrawals, }; use reth_prune_types::{PruneCheckpoint, PruneModes, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index 2af22cec0b5..d47532e712d 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -15,7 +15,7 @@ use crate::{ StaticFileProviderFactory, StatsReader, StorageReader, StorageTrieWriter, TransactionVariant, TransactionsProvider, TransactionsProviderExt, TrieWriter, WithdrawalsProvider, }; -use alloy_eips::BlockHashOrNumber; +use alloy_eips::{eip4895::Withdrawal, BlockHashOrNumber}; use alloy_primitives::{keccak256, Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256}; use itertools::{izip, Itertools}; use rayon::slice::ParallelSliceMut; @@ -43,7 +43,7 @@ use reth_primitives::{ Account, Block, BlockBody, BlockWithSenders, Bytecode, GotExpected, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, StaticFileSegment, StorageEntry, TransactionMeta, TransactionSigned, TransactionSignedEcRecovered, TransactionSignedNoHash, - Withdrawal, Withdrawals, + Withdrawals, }; use reth_prune_types::{PruneCheckpoint, PruneModes, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; diff --git a/crates/storage/provider/src/providers/mod.rs b/crates/storage/provider/src/providers/mod.rs index 3b24617fd95..5e95c6ce0db 100644 --- a/crates/storage/provider/src/providers/mod.rs +++ b/crates/storage/provider/src/providers/mod.rs @@ -7,7 +7,7 @@ use crate::{ StageCheckpointReader, StateProviderBox, StateProviderFactory, StaticFileProviderFactory, TransactionVariant, TransactionsProvider, TreeViewer, WithdrawalsProvider, }; -use alloy_eips::{BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag}; +use alloy_eips::{eip4895::Withdrawal, BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag}; use alloy_primitives::{Address, BlockHash, BlockNumber, Sealable, TxHash, TxNumber, B256, U256}; use reth_blockchain_tree_api::{ error::{CanonicalError, InsertBlockError}, @@ -21,8 +21,7 @@ use reth_evm::ConfigureEvmEnv; use reth_node_types::NodeTypesWithDB; use reth_primitives::{ Account, Block, BlockWithSenders, Header, Receipt, SealedBlock, SealedBlockWithSenders, - SealedHeader, TransactionMeta, TransactionSigned, TransactionSignedNoHash, Withdrawal, - Withdrawals, + SealedHeader, TransactionMeta, TransactionSigned, TransactionSignedNoHash, Withdrawals, }; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; diff --git a/crates/storage/provider/src/providers/static_file/manager.rs b/crates/storage/provider/src/providers/static_file/manager.rs index e81dc01f722..70c1e38f6ac 100644 --- a/crates/storage/provider/src/providers/static_file/manager.rs +++ b/crates/storage/provider/src/providers/static_file/manager.rs @@ -7,7 +7,7 @@ use crate::{ ReceiptProvider, StageCheckpointReader, StatsReader, TransactionVariant, TransactionsProvider, TransactionsProviderExt, WithdrawalsProvider, }; -use alloy_eips::BlockHashOrNumber; +use alloy_eips::{eip4895::Withdrawal, BlockHashOrNumber}; use alloy_primitives::{keccak256, Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256}; use dashmap::DashMap; use notify::{RecommendedWatcher, RecursiveMode, Watcher}; @@ -31,8 +31,7 @@ use reth_primitives::{ DEFAULT_BLOCKS_PER_STATIC_FILE, }, Block, BlockWithSenders, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, - StaticFileSegment, TransactionMeta, TransactionSigned, TransactionSignedNoHash, Withdrawal, - Withdrawals, + StaticFileSegment, TransactionMeta, TransactionSigned, TransactionSignedNoHash, Withdrawals, }; use reth_stages_types::{PipelineTarget, StageId}; use reth_storage_api::DBProvider; diff --git a/crates/storage/provider/src/test_utils/blocks.rs b/crates/storage/provider/src/test_utils/blocks.rs index cacb71b351d..d524f47cc75 100644 --- a/crates/storage/provider/src/test_utils/blocks.rs +++ b/crates/storage/provider/src/test_utils/blocks.rs @@ -6,12 +6,13 @@ use alloy_primitives::{ TxKind, B256, U256, }; +use alloy_eips::eip4895::Withdrawal; use reth_db::tables; use reth_db_api::{database::Database, models::StoredBlockBodyIndices}; use reth_node_types::NodeTypes; use reth_primitives::{ Account, BlockBody, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, - Signature, Transaction, TransactionSigned, TxType, Withdrawal, Withdrawals, + Signature, Transaction, TransactionSigned, TxType, Withdrawals, }; use reth_trie::root::{state_root_unhashed, storage_root_unhashed}; use revm::{db::BundleState, primitives::AccountInfo}; diff --git a/crates/storage/provider/src/test_utils/mock.rs b/crates/storage/provider/src/test_utils/mock.rs index 07fa505b2b4..2e7cd6a06de 100644 --- a/crates/storage/provider/src/test_utils/mock.rs +++ b/crates/storage/provider/src/test_utils/mock.rs @@ -6,7 +6,7 @@ use crate::{ StateRootProvider, TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; use alloy_consensus::constants::EMPTY_ROOT_HASH; -use alloy_eips::{BlockHashOrNumber, BlockId, BlockNumberOrTag}; +use alloy_eips::{eip4895::Withdrawal, BlockHashOrNumber, BlockId, BlockNumberOrTag}; use alloy_primitives::{ keccak256, map::{HashMap, HashSet}, @@ -23,7 +23,7 @@ use reth_node_types::NodeTypes; use reth_primitives::{ Account, Block, BlockWithSenders, Bytecode, GotExpected, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, TransactionMeta, TransactionSigned, - TransactionSignedNoHash, Withdrawal, Withdrawals, + TransactionSignedNoHash, Withdrawals, }; use reth_stages_types::{StageCheckpoint, StageId}; use reth_storage_api::{ diff --git a/crates/storage/provider/src/test_utils/noop.rs b/crates/storage/provider/src/test_utils/noop.rs index e0943764772..8e6dc7425cf 100644 --- a/crates/storage/provider/src/test_utils/noop.rs +++ b/crates/storage/provider/src/test_utils/noop.rs @@ -4,7 +4,7 @@ use std::{ sync::Arc, }; -use alloy_eips::{BlockHashOrNumber, BlockId, BlockNumberOrTag}; +use alloy_eips::{eip4895::Withdrawal, BlockHashOrNumber, BlockId, BlockNumberOrTag}; use alloy_primitives::{ map::{HashMap, HashSet}, Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, TxHash, TxNumber, B256, U256, @@ -20,7 +20,7 @@ use reth_evm::ConfigureEvmEnv; use reth_primitives::{ Account, Block, BlockWithSenders, Bytecode, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, TransactionMeta, TransactionSigned, - TransactionSignedNoHash, Withdrawal, Withdrawals, + TransactionSignedNoHash, Withdrawals, }; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; diff --git a/crates/storage/storage-api/src/withdrawals.rs b/crates/storage/storage-api/src/withdrawals.rs index 2de69b34eb6..ba422a3b33b 100644 --- a/crates/storage/storage-api/src/withdrawals.rs +++ b/crates/storage/storage-api/src/withdrawals.rs @@ -1,5 +1,5 @@ -use alloy_eips::BlockHashOrNumber; -use reth_primitives::{Withdrawal, Withdrawals}; +use alloy_eips::{eip4895::Withdrawal, BlockHashOrNumber}; +use reth_primitives::Withdrawals; use reth_storage_errors::provider::ProviderResult; /// Client trait for fetching [Withdrawal] related data. diff --git a/examples/custom-beacon-withdrawals/src/main.rs b/examples/custom-beacon-withdrawals/src/main.rs index 09dad2f7007..43e5f7428f6 100644 --- a/examples/custom-beacon-withdrawals/src/main.rs +++ b/examples/custom-beacon-withdrawals/src/main.rs @@ -3,7 +3,7 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] -use alloy_eips::eip7685::Requests; +use alloy_eips::{eip4895::Withdrawal, eip7685::Requests}; use alloy_sol_macro::sol; use alloy_sol_types::SolCall; #[cfg(feature = "optimism")] @@ -30,7 +30,7 @@ use reth_primitives::{ revm_primitives::{ address, Address, BlockEnv, Bytes, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, U256, }, - BlockWithSenders, Receipt, Withdrawal, + BlockWithSenders, Receipt, }; use std::{fmt::Display, sync::Arc}; diff --git a/testing/testing-utils/Cargo.toml b/testing/testing-utils/Cargo.toml index 98bfeabdfb1..3e0f58a7bd0 100644 --- a/testing/testing-utils/Cargo.toml +++ b/testing/testing-utils/Cargo.toml @@ -17,6 +17,7 @@ reth-primitives = { workspace = true, features = ["secp256k1"] } alloy-genesis.workspace = true alloy-primitives.workspace = true alloy-consensus.workspace = true +alloy-eips.workspace = true rand.workspace = true secp256k1 = { workspace = true, features = ["rand"] } diff --git a/testing/testing-utils/src/generators.rs b/testing/testing-utils/src/generators.rs index 571727cb2fd..84225ea72cd 100644 --- a/testing/testing-utils/src/generators.rs +++ b/testing/testing-utils/src/generators.rs @@ -1,6 +1,7 @@ //! Generators for different data structures like block headers, block bodies and ranges of those. use alloy_consensus::{Transaction as _, TxLegacy}; +use alloy_eips::eip4895::Withdrawal; use alloy_primitives::{Address, BlockNumber, Bytes, Parity, Sealable, TxKind, B256, U256}; pub use rand::Rng; use rand::{ @@ -8,7 +9,7 @@ use rand::{ }; use reth_primitives::{ proofs, sign_message, Account, BlockBody, Header, Log, Receipt, SealedBlock, SealedHeader, - StorageEntry, Transaction, TransactionSigned, Withdrawal, Withdrawals, + StorageEntry, Transaction, TransactionSigned, Withdrawals, }; use secp256k1::{Keypair, Secp256k1}; use std::{ From 566f2b4950d9e86c83dd527cde8d99b3a35f6a49 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Mon, 4 Nov 2024 11:15:56 +0100 Subject: [PATCH 004/211] primitives: rm alloy `BlockHashOrNumber` reexport (#12302) --- bin/reth/src/commands/debug_cmd/execution.rs | 2 +- bin/reth/src/commands/debug_cmd/in_memory_merkle.rs | 2 +- bin/reth/src/commands/debug_cmd/merkle.rs | 2 +- crates/consensus/auto-seal/src/client.rs | 3 ++- crates/consensus/auto-seal/src/lib.rs | 6 +++--- crates/consensus/common/src/validation.rs | 5 ++--- crates/engine/local/Cargo.toml | 6 +++--- crates/evm/src/provider.rs | 2 +- crates/net/eth-wire-types/src/blocks.rs | 3 ++- crates/node/core/src/node_config.rs | 3 ++- crates/node/core/src/utils.rs | 3 ++- crates/primitives/src/block.rs | 4 +--- crates/primitives/src/lib.rs | 4 ++-- crates/primitives/src/transaction/mod.rs | 2 +- crates/rpc/rpc-engine-api/src/engine_api.rs | 4 ++-- crates/rpc/rpc-eth-types/src/cache/mod.rs | 5 ++--- .../storage/provider/src/providers/blockchain_provider.rs | 4 ++-- 17 files changed, 30 insertions(+), 30 deletions(-) diff --git a/bin/reth/src/commands/debug_cmd/execution.rs b/bin/reth/src/commands/debug_cmd/execution.rs index 215afacb583..cc584c89287 100644 --- a/bin/reth/src/commands/debug_cmd/execution.rs +++ b/bin/reth/src/commands/debug_cmd/execution.rs @@ -1,6 +1,7 @@ //! Command for debugging execution. use crate::{args::NetworkArgs, utils::get_single_header}; +use alloy_eips::BlockHashOrNumber; use alloy_primitives::{BlockNumber, B256}; use clap::Parser; use futures::{stream::select as stream_select, StreamExt}; @@ -23,7 +24,6 @@ use reth_network_api::NetworkInfo; use reth_network_p2p::{headers::client::HeadersClient, BlockClient}; use reth_node_api::{NodeTypesWithDB, NodeTypesWithDBAdapter, NodeTypesWithEngine}; use reth_node_ethereum::EthExecutorProvider; -use reth_primitives::BlockHashOrNumber; use reth_provider::{ BlockExecutionWriter, ChainSpecProvider, ProviderFactory, StageCheckpointReader, }; diff --git a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs index 51851c0b0ad..2c56da9b4cf 100644 --- a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs +++ b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs @@ -4,6 +4,7 @@ use crate::{ args::NetworkArgs, utils::{get_single_body, get_single_header}, }; +use alloy_eips::BlockHashOrNumber; use backon::{ConstantBuilder, Retryable}; use clap::Parser; use reth_chainspec::ChainSpec; @@ -19,7 +20,6 @@ use reth_network::{BlockDownloaderProvider, NetworkHandle}; use reth_network_api::NetworkInfo; use reth_node_api::{NodeTypesWithDB, NodeTypesWithEngine}; use reth_node_ethereum::EthExecutorProvider; -use reth_primitives::BlockHashOrNumber; use reth_provider::{ writer::UnifiedStorageWriter, AccountExtReader, ChainSpecProvider, HashingWriter, HeaderProvider, LatestStateProviderRef, OriginalValuesKnown, ProviderFactory, diff --git a/bin/reth/src/commands/debug_cmd/merkle.rs b/bin/reth/src/commands/debug_cmd/merkle.rs index 8e02a52eaf0..3c6e38512c9 100644 --- a/bin/reth/src/commands/debug_cmd/merkle.rs +++ b/bin/reth/src/commands/debug_cmd/merkle.rs @@ -1,5 +1,6 @@ //! Command for debugging merkle trie calculation. use crate::{args::NetworkArgs, utils::get_single_header}; +use alloy_eips::BlockHashOrNumber; use backon::{ConstantBuilder, Retryable}; use clap::Parser; use reth_beacon_consensus::EthBeaconConsensus; @@ -18,7 +19,6 @@ use reth_network_api::NetworkInfo; use reth_network_p2p::full_block::FullBlockClient; use reth_node_api::{NodeTypesWithDB, NodeTypesWithEngine}; use reth_node_ethereum::EthExecutorProvider; -use reth_primitives::BlockHashOrNumber; use reth_provider::{ writer::UnifiedStorageWriter, BlockNumReader, BlockWriter, ChainSpecProvider, DatabaseProviderFactory, HeaderProvider, LatestStateProviderRef, OriginalValuesKnown, diff --git a/crates/consensus/auto-seal/src/client.rs b/crates/consensus/auto-seal/src/client.rs index f9b80f10bb5..0083192d7df 100644 --- a/crates/consensus/auto-seal/src/client.rs +++ b/crates/consensus/auto-seal/src/client.rs @@ -1,6 +1,7 @@ //! This includes download client implementations for auto sealing miners. use crate::Storage; +use alloy_eips::BlockHashOrNumber; use alloy_primitives::B256; use reth_network_p2p::{ bodies::client::{BodiesClient, BodiesFut}, @@ -9,7 +10,7 @@ use reth_network_p2p::{ priority::Priority, }; use reth_network_peers::{PeerId, WithPeerId}; -use reth_primitives::{BlockBody, BlockHashOrNumber, Header}; +use reth_primitives::{BlockBody, Header}; use std::fmt::Debug; use tracing::{trace, warn}; diff --git a/crates/consensus/auto-seal/src/lib.rs b/crates/consensus/auto-seal/src/lib.rs index 16299e19ba4..ad7e66acc0e 100644 --- a/crates/consensus/auto-seal/src/lib.rs +++ b/crates/consensus/auto-seal/src/lib.rs @@ -15,7 +15,7 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -use alloy_eips::eip7685::Requests; +use alloy_eips::{eip1898::BlockHashOrNumber, eip7685::Requests}; use alloy_primitives::{BlockHash, BlockNumber, Bloom, B256, U256}; use reth_beacon_consensus::BeaconEngineMessage; use reth_chainspec::{EthChainSpec, EthereumHardforks}; @@ -26,8 +26,8 @@ use reth_execution_errors::{ }; use reth_execution_types::ExecutionOutcome; use reth_primitives::{ - proofs, Block, BlockBody, BlockHashOrNumber, BlockWithSenders, Header, SealedBlock, - SealedHeader, TransactionSigned, Withdrawals, + proofs, Block, BlockBody, BlockWithSenders, Header, SealedBlock, SealedHeader, + TransactionSigned, Withdrawals, }; use reth_provider::{BlockReaderIdExt, StateProviderFactory, StateRootProvider}; use reth_revm::database::StateProviderDatabase; diff --git a/crates/consensus/common/src/validation.rs b/crates/consensus/common/src/validation.rs index a6e5d21587f..092330595ff 100644 --- a/crates/consensus/common/src/validation.rs +++ b/crates/consensus/common/src/validation.rs @@ -275,7 +275,7 @@ pub fn validate_against_parent_4844( mod tests { use super::*; use alloy_consensus::{TxEip4844, EMPTY_OMMER_ROOT_HASH, EMPTY_ROOT_HASH}; - use alloy_eips::eip4895::Withdrawal; + use alloy_eips::{eip4895::Withdrawal, BlockHashOrNumber}; use alloy_primitives::{ hex_literal::hex, Address, BlockHash, BlockNumber, Bytes, Parity, Sealable, U256, }; @@ -283,8 +283,7 @@ mod tests { use rand::Rng; use reth_chainspec::ChainSpecBuilder; use reth_primitives::{ - proofs, Account, BlockBody, BlockHashOrNumber, Signature, Transaction, TransactionSigned, - Withdrawals, + proofs, Account, BlockBody, Signature, Transaction, TransactionSigned, Withdrawals, }; use reth_storage_api::{ errors::provider::ProviderResult, AccountReader, HeaderProvider, WithdrawalsProvider, diff --git a/crates/engine/local/Cargo.toml b/crates/engine/local/Cargo.toml index d9dc6325339..2ab448e3bbf 100644 --- a/crates/engine/local/Cargo.toml +++ b/crates/engine/local/Cargo.toml @@ -47,7 +47,7 @@ workspace = true [features] optimism = [ - "op-alloy-rpc-types-engine", - "reth-beacon-consensus/optimism", - "reth-provider/optimism" + "op-alloy-rpc-types-engine", + "reth-beacon-consensus/optimism", + "reth-provider/optimism", ] diff --git a/crates/evm/src/provider.rs b/crates/evm/src/provider.rs index 8db828ec4a0..84c38db0dc5 100644 --- a/crates/evm/src/provider.rs +++ b/crates/evm/src/provider.rs @@ -1,7 +1,7 @@ //! Provider trait for populating the EVM environment. use crate::ConfigureEvmEnv; -use alloy_eips::eip1898::BlockHashOrNumber; +use alloy_eips::BlockHashOrNumber; use reth_primitives::Header; use reth_storage_errors::provider::ProviderResult; use revm::primitives::{BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, SpecId}; diff --git a/crates/net/eth-wire-types/src/blocks.rs b/crates/net/eth-wire-types/src/blocks.rs index 878b4573f2b..5ae84319005 100644 --- a/crates/net/eth-wire-types/src/blocks.rs +++ b/crates/net/eth-wire-types/src/blocks.rs @@ -113,9 +113,10 @@ mod tests { HeadersDirection, }; use alloy_consensus::TxLegacy; + use alloy_eips::BlockHashOrNumber; use alloy_primitives::{hex, Parity, TxKind, U256}; use alloy_rlp::{Decodable, Encodable}; - use reth_primitives::{BlockHashOrNumber, Header, Signature, Transaction, TransactionSigned}; + use reth_primitives::{Header, Signature, Transaction, TransactionSigned}; use std::str::FromStr; use super::BlockBody; diff --git a/crates/node/core/src/node_config.rs b/crates/node/core/src/node_config.rs index 80fb5152e7b..3848772c415 100644 --- a/crates/node/core/src/node_config.rs +++ b/crates/node/core/src/node_config.rs @@ -15,8 +15,9 @@ use reth_network_p2p::headers::client::HeadersClient; use serde::{de::DeserializeOwned, Serialize}; use std::{fs, path::Path}; +use alloy_eips::BlockHashOrNumber; use alloy_primitives::{BlockNumber, B256}; -use reth_primitives::{BlockHashOrNumber, Head, SealedHeader}; +use reth_primitives::{Head, SealedHeader}; use reth_stages_types::StageId; use reth_storage_api::{ BlockHashReader, DatabaseProviderFactory, HeaderProvider, StageCheckpointReader, diff --git a/crates/node/core/src/utils.rs b/crates/node/core/src/utils.rs index a64d1211455..a04d4e324e1 100644 --- a/crates/node/core/src/utils.rs +++ b/crates/node/core/src/utils.rs @@ -1,6 +1,7 @@ //! Utility functions for node startup and shutdown, for example path parsing and retrieving single //! blocks from the network. +use alloy_eips::BlockHashOrNumber; use alloy_primitives::Sealable; use alloy_rpc_types_engine::{JwtError, JwtSecret}; use eyre::Result; @@ -11,7 +12,7 @@ use reth_network_p2p::{ headers::client::{HeadersClient, HeadersDirection, HeadersRequest}, priority::Priority, }; -use reth_primitives::{BlockHashOrNumber, SealedBlock, SealedHeader}; +use reth_primitives::{SealedBlock, SealedHeader}; use std::{ env::VarError, path::{Path, PathBuf}, diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index 7e5e76f1b06..153f67b03d9 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -2,9 +2,7 @@ use crate::{ GotExpected, Header, SealedHeader, TransactionSigned, TransactionSignedEcRecovered, Withdrawals, }; use alloc::vec::Vec; -pub use alloy_eips::eip1898::{ - BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, ForkBlock, RpcBlockHash, -}; +pub use alloy_eips::eip1898::{BlockId, BlockNumHash, BlockNumberOrTag, ForkBlock, RpcBlockHash}; use alloy_eips::eip2718::Encodable2718; use alloy_primitives::{Address, Bytes, Sealable, B256}; use alloy_rlp::{Decodable, Encodable, RlpDecodable, RlpEncodable}; diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 9bb27e658ca..3b8589f8f1d 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -34,8 +34,8 @@ pub mod transaction; #[cfg(any(test, feature = "arbitrary"))] pub use block::{generate_valid_header, valid_header_strategy}; pub use block::{ - Block, BlockBody, BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, BlockWithSenders, - ForkBlock, RpcBlockHash, SealedBlock, SealedBlockWithSenders, + Block, BlockBody, BlockId, BlockNumHash, BlockNumberOrTag, BlockWithSenders, ForkBlock, + RpcBlockHash, SealedBlock, SealedBlockWithSenders, }; #[cfg(feature = "reth-codec")] pub use compression::*; diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index b9a24316c40..f7d36be0ab8 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -1,12 +1,12 @@ //! Transaction types. -use crate::BlockHashOrNumber; #[cfg(any(test, feature = "reth-codec"))] use alloy_consensus::constants::{EIP4844_TX_TYPE_ID, EIP7702_TX_TYPE_ID}; use alloy_consensus::{ SignableTransaction, Transaction as _, TxEip1559, TxEip2930, TxEip4844, TxEip7702, TxLegacy, }; use alloy_eips::{ + eip1898::BlockHashOrNumber, eip2718::{Decodable2718, Eip2718Error, Eip2718Result, Encodable2718}, eip2930::AccessList, eip7702::SignedAuthorization, diff --git a/crates/rpc/rpc-engine-api/src/engine_api.rs b/crates/rpc/rpc-engine-api/src/engine_api.rs index 383da2d21ff..20eeb390ac1 100644 --- a/crates/rpc/rpc-engine-api/src/engine_api.rs +++ b/crates/rpc/rpc-engine-api/src/engine_api.rs @@ -1,7 +1,7 @@ use crate::{ capabilities::EngineCapabilities, metrics::EngineApiMetrics, EngineApiError, EngineApiResult, }; -use alloy_eips::{eip4844::BlobAndProofV1, eip7685::Requests}; +use alloy_eips::{eip1898::BlockHashOrNumber, eip4844::BlobAndProofV1, eip7685::Requests}; use alloy_primitives::{BlockHash, BlockNumber, B256, U64}; use alloy_rpc_types_engine::{ CancunPayloadFields, ClientVersionV1, ExecutionPayload, ExecutionPayloadBodiesV1, @@ -19,7 +19,7 @@ use reth_payload_primitives::{ validate_payload_timestamp, EngineApiMessageVersion, PayloadBuilderAttributes, PayloadOrAttributes, }; -use reth_primitives::{Block, BlockHashOrNumber, EthereumHardfork}; +use reth_primitives::{Block, EthereumHardfork}; use reth_rpc_api::EngineApiServer; use reth_rpc_types_compat::engine::payload::{ convert_payload_input_v2_to_payload, convert_to_payload_body_v1, diff --git a/crates/rpc/rpc-eth-types/src/cache/mod.rs b/crates/rpc/rpc-eth-types/src/cache/mod.rs index cbf05f2764e..b6b0364c477 100644 --- a/crates/rpc/rpc-eth-types/src/cache/mod.rs +++ b/crates/rpc/rpc-eth-types/src/cache/mod.rs @@ -1,14 +1,13 @@ //! Async caching support for eth RPC +use alloy_eips::BlockHashOrNumber; use alloy_primitives::B256; use futures::{future::Either, Stream, StreamExt}; use reth_chain_state::CanonStateNotification; use reth_errors::{ProviderError, ProviderResult}; use reth_evm::{provider::EvmEnvProvider, ConfigureEvm}; use reth_execution_types::Chain; -use reth_primitives::{ - BlockHashOrNumber, Header, Receipt, SealedBlockWithSenders, TransactionSigned, -}; +use reth_primitives::{Header, Receipt, SealedBlockWithSenders, TransactionSigned}; use reth_storage_api::{BlockReader, StateProviderFactory, TransactionVariant}; use reth_tasks::{TaskSpawner, TokioTaskExecutor}; use revm::primitives::{BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, SpecId}; diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index 85f759310ba..669a3555931 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -1444,7 +1444,7 @@ mod tests { assert_eq!( provider .withdrawals_by_block( - reth_primitives::BlockHashOrNumber::Number(15), + alloy_eips::BlockHashOrNumber::Number(15), shainghai_timestamp ) .expect("could not call withdrawals by block"), @@ -1456,7 +1456,7 @@ mod tests { assert_eq!( provider .withdrawals_by_block( - reth_primitives::BlockHashOrNumber::Number(block.number), + alloy_eips::BlockHashOrNumber::Number(block.number), shainghai_timestamp )? .unwrap(), From 0475af8bdb605ef8deadeb3452a59f9d71373d49 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Mon, 4 Nov 2024 12:47:18 +0100 Subject: [PATCH 005/211] primitives: rm alloy `BlockId` reexport (#12303) --- Cargo.lock | 4 +++- crates/primitives/src/block.rs | 4 ++-- crates/primitives/src/lib.rs | 4 ++-- crates/rpc/rpc-api/src/debug.rs | 3 ++- crates/rpc/rpc-api/src/otterscan.rs | 2 +- crates/rpc/rpc-api/src/reth.rs | 2 +- crates/rpc/rpc-api/src/trace.rs | 2 +- crates/rpc/rpc-builder/Cargo.toml | 1 + crates/rpc/rpc-builder/tests/it/http.rs | 3 ++- crates/rpc/rpc-eth-api/src/core.rs | 4 ++-- crates/rpc/rpc-eth-api/src/helpers/block.rs | 3 ++- crates/rpc/rpc-eth-api/src/helpers/state.rs | 3 ++- crates/rpc/rpc-eth-api/src/helpers/transaction.rs | 6 ++---- crates/rpc/rpc-eth-types/src/error.rs | 3 ++- crates/rpc/rpc-eth-types/src/pending_block.rs | 3 ++- crates/rpc/rpc-server-types/Cargo.toml | 3 +-- crates/rpc/rpc-server-types/src/result.rs | 2 +- crates/rpc/rpc-testing-util/Cargo.toml | 3 ++- crates/rpc/rpc-testing-util/src/debug.rs | 3 ++- crates/rpc/rpc-testing-util/src/trace.rs | 2 +- crates/rpc/rpc/src/debug.rs | 4 ++-- crates/rpc/rpc/src/engine.rs | 3 ++- crates/rpc/rpc/src/otterscan.rs | 3 ++- crates/rpc/rpc/src/reth.rs | 2 +- crates/rpc/rpc/src/trace.rs | 3 ++- 25 files changed, 43 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0b3318c4ae0..9b5a5350c16 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8706,6 +8706,7 @@ dependencies = [ name = "reth-rpc-api-testing-util" version = "1.1.0" dependencies = [ + "alloy-eips", "alloy-primitives", "alloy-rpc-types", "alloy-rpc-types-eth", @@ -8725,6 +8726,7 @@ dependencies = [ name = "reth-rpc-builder" version = "1.1.0" dependencies = [ + "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", "alloy-rpc-types-eth", @@ -8910,13 +8912,13 @@ dependencies = [ name = "reth-rpc-server-types" version = "1.1.0" dependencies = [ + "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", "jsonrpsee-core", "jsonrpsee-types", "reth-errors", "reth-network-api", - "reth-primitives", "serde", "strum", ] diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index 153f67b03d9..2b651652df5 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -2,7 +2,7 @@ use crate::{ GotExpected, Header, SealedHeader, TransactionSigned, TransactionSignedEcRecovered, Withdrawals, }; use alloc::vec::Vec; -pub use alloy_eips::eip1898::{BlockId, BlockNumHash, BlockNumberOrTag, ForkBlock, RpcBlockHash}; +pub use alloy_eips::eip1898::{BlockNumHash, BlockNumberOrTag, ForkBlock, RpcBlockHash}; use alloy_eips::eip2718::Encodable2718; use alloy_primitives::{Address, Bytes, Sealable, B256}; use alloy_rlp::{Decodable, Encodable, RlpDecodable, RlpEncodable}; @@ -905,7 +905,7 @@ pub(super) mod serde_bincode_compat { #[cfg(test)] mod tests { use super::{BlockNumberOrTag::*, *}; - use alloy_eips::eip1898::HexStringMissingPrefixError; + use alloy_eips::{eip1898::HexStringMissingPrefixError, BlockId}; use alloy_primitives::hex_literal::hex; use alloy_rlp::{Decodable, Encodable}; use std::str::FromStr; diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 3b8589f8f1d..679b24abd84 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -34,8 +34,8 @@ pub mod transaction; #[cfg(any(test, feature = "arbitrary"))] pub use block::{generate_valid_header, valid_header_strategy}; pub use block::{ - Block, BlockBody, BlockId, BlockNumHash, BlockNumberOrTag, BlockWithSenders, ForkBlock, - RpcBlockHash, SealedBlock, SealedBlockWithSenders, + Block, BlockBody, BlockNumHash, BlockNumberOrTag, BlockWithSenders, ForkBlock, RpcBlockHash, + SealedBlock, SealedBlockWithSenders, }; #[cfg(feature = "reth-codec")] pub use compression::*; diff --git a/crates/rpc/rpc-api/src/debug.rs b/crates/rpc/rpc-api/src/debug.rs index 3e03210f1ff..162699c6ebc 100644 --- a/crates/rpc/rpc-api/src/debug.rs +++ b/crates/rpc/rpc-api/src/debug.rs @@ -1,3 +1,4 @@ +use alloy_eips::BlockId; use alloy_primitives::{Address, Bytes, B256}; use alloy_rpc_types::{Block, Bundle, StateContext}; use alloy_rpc_types_debug::ExecutionWitness; @@ -6,7 +7,7 @@ use alloy_rpc_types_trace::geth::{ BlockTraceResult, GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace, TraceResult, }; use jsonrpsee::{core::RpcResult, proc_macros::rpc}; -use reth_primitives::{BlockId, BlockNumberOrTag}; +use reth_primitives::BlockNumberOrTag; /// Debug rpc interface. #[cfg_attr(not(feature = "client"), rpc(server, namespace = "debug"))] diff --git a/crates/rpc/rpc-api/src/otterscan.rs b/crates/rpc/rpc-api/src/otterscan.rs index ee805b482c3..d3e61c03104 100644 --- a/crates/rpc/rpc-api/src/otterscan.rs +++ b/crates/rpc/rpc-api/src/otterscan.rs @@ -1,3 +1,4 @@ +use alloy_eips::BlockId; use alloy_json_rpc::RpcObject; use alloy_primitives::{Address, Bytes, TxHash, B256}; use alloy_rpc_types::Header; @@ -6,7 +7,6 @@ use alloy_rpc_types_trace::otterscan::{ TransactionsWithReceipts, }; use jsonrpsee::{core::RpcResult, proc_macros::rpc}; -use reth_primitives::BlockId; /// Otterscan rpc interface. #[cfg_attr(not(feature = "client"), rpc(server, namespace = "ots"))] diff --git a/crates/rpc/rpc-api/src/reth.rs b/crates/rpc/rpc-api/src/reth.rs index 98c31b78f9a..0589ffc00ce 100644 --- a/crates/rpc/rpc-api/src/reth.rs +++ b/crates/rpc/rpc-api/src/reth.rs @@ -1,6 +1,6 @@ +use alloy_eips::BlockId; use alloy_primitives::{Address, U256}; use jsonrpsee::{core::RpcResult, proc_macros::rpc}; -use reth_primitives::BlockId; use std::collections::HashMap; /// Reth API namespace for reth-specific methods diff --git a/crates/rpc/rpc-api/src/trace.rs b/crates/rpc/rpc-api/src/trace.rs index 58dda422ab8..45059284a2d 100644 --- a/crates/rpc/rpc-api/src/trace.rs +++ b/crates/rpc/rpc-api/src/trace.rs @@ -1,3 +1,4 @@ +use alloy_eips::BlockId; use alloy_primitives::{map::HashSet, Bytes, B256}; use alloy_rpc_types::{state::StateOverride, BlockOverrides, Index}; use alloy_rpc_types_eth::transaction::TransactionRequest; @@ -7,7 +8,6 @@ use alloy_rpc_types_trace::{ parity::*, }; use jsonrpsee::{core::RpcResult, proc_macros::rpc}; -use reth_primitives::BlockId; /// Ethereum trace API #[cfg_attr(not(feature = "client"), rpc(server, namespace = "trace"))] diff --git a/crates/rpc/rpc-builder/Cargo.toml b/crates/rpc/rpc-builder/Cargo.toml index 2d10dabf8af..b6ae86c7408 100644 --- a/crates/rpc/rpc-builder/Cargo.toml +++ b/crates/rpc/rpc-builder/Cargo.toml @@ -68,6 +68,7 @@ alloy-primitives.workspace = true alloy-rpc-types-eth.workspace = true alloy-rpc-types-trace.workspace = true alloy-rpc-types-engine.workspace = true +alloy-eips.workspace = true tokio = { workspace = true, features = ["rt", "rt-multi-thread"] } serde_json.workspace = true diff --git a/crates/rpc/rpc-builder/tests/it/http.rs b/crates/rpc/rpc-builder/tests/it/http.rs index ed9ef56d62b..5c33a5d34df 100644 --- a/crates/rpc/rpc-builder/tests/it/http.rs +++ b/crates/rpc/rpc-builder/tests/it/http.rs @@ -2,6 +2,7 @@ //! Standalone http tests use crate::utils::{launch_http, launch_http_ws, launch_ws}; +use alloy_eips::BlockId; use alloy_primitives::{hex_literal::hex, Address, Bytes, TxHash, B256, B64, U256, U64}; use alloy_rpc_types_eth::{ transaction::TransactionRequest, Block, FeeHistory, Filter, Index, Log, @@ -18,7 +19,7 @@ use jsonrpsee::{ types::error::ErrorCode, }; use reth_network_peers::NodeRecord; -use reth_primitives::{BlockId, BlockNumberOrTag, Receipt}; +use reth_primitives::{BlockNumberOrTag, Receipt}; use reth_rpc_api::{ clients::{AdminApiClient, EthApiClient}, DebugApiClient, EthFilterApiClient, NetApiClient, OtterscanClient, TraceApiClient, diff --git a/crates/rpc/rpc-eth-api/src/core.rs b/crates/rpc/rpc-eth-api/src/core.rs index 66bc5a44d2d..185297c2255 100644 --- a/crates/rpc/rpc-eth-api/src/core.rs +++ b/crates/rpc/rpc-eth-api/src/core.rs @@ -1,7 +1,7 @@ //! Implementation of the [`jsonrpsee`] generated [`EthApiServer`] trait. Handles RPC requests for //! the `eth_` namespace. use alloy_dyn_abi::TypedData; -use alloy_eips::eip2930::AccessListResult; +use alloy_eips::{eip2930::AccessListResult, BlockId}; use alloy_json_rpc::RpcObject; use alloy_primitives::{Address, Bytes, B256, B64, U256, U64}; use alloy_rpc_types::{ @@ -13,7 +13,7 @@ use alloy_rpc_types::{ }; use alloy_rpc_types_eth::transaction::TransactionRequest; use jsonrpsee::{core::RpcResult, proc_macros::rpc}; -use reth_primitives::{BlockId, BlockNumberOrTag}; +use reth_primitives::BlockNumberOrTag; use reth_rpc_server_types::{result::internal_rpc_err, ToRpcResult}; use tracing::trace; diff --git a/crates/rpc/rpc-eth-api/src/helpers/block.rs b/crates/rpc/rpc-eth-api/src/helpers/block.rs index fa397db35e0..bb8fd08ed87 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/block.rs @@ -2,9 +2,10 @@ use std::sync::Arc; +use alloy_eips::BlockId; use alloy_rpc_types::{Header, Index}; use futures::Future; -use reth_primitives::{BlockId, Receipt, SealedBlock, SealedBlockWithSenders}; +use reth_primitives::{Receipt, SealedBlock, SealedBlockWithSenders}; use reth_provider::{BlockIdReader, BlockReader, BlockReaderIdExt, HeaderProvider}; use reth_rpc_types_compat::block::{from_block, uncle_block_from_header}; diff --git a/crates/rpc/rpc-eth-api/src/helpers/state.rs b/crates/rpc/rpc-eth-api/src/helpers/state.rs index 97c94b94932..d980b9114b1 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/state.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/state.rs @@ -2,13 +2,14 @@ //! RPC methods. use alloy_consensus::constants::KECCAK_EMPTY; +use alloy_eips::BlockId; use alloy_primitives::{Address, Bytes, B256, U256}; use alloy_rpc_types::{serde_helpers::JsonStorageKey, Account, EIP1186AccountProofResponse}; use futures::Future; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_errors::RethError; use reth_evm::ConfigureEvmEnv; -use reth_primitives::{BlockId, Header}; +use reth_primitives::Header; use reth_provider::{ BlockIdReader, BlockNumReader, ChainSpecProvider, StateProvider, StateProviderBox, StateProviderFactory, diff --git a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs index 3c526cbb025..ab94e3dd107 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs @@ -3,15 +3,13 @@ use alloy_consensus::Transaction; use alloy_dyn_abi::TypedData; -use alloy_eips::eip2718::Encodable2718; +use alloy_eips::{eip2718::Encodable2718, BlockId}; use alloy_network::TransactionBuilder; use alloy_primitives::{Address, Bytes, TxHash, B256}; use alloy_rpc_types::{BlockNumberOrTag, TransactionInfo}; use alloy_rpc_types_eth::transaction::TransactionRequest; use futures::Future; -use reth_primitives::{ - BlockId, Receipt, SealedBlockWithSenders, TransactionMeta, TransactionSigned, -}; +use reth_primitives::{Receipt, SealedBlockWithSenders, TransactionMeta, TransactionSigned}; use reth_provider::{BlockNumReader, BlockReaderIdExt, ReceiptProvider, TransactionsProvider}; use reth_rpc_eth_types::{ utils::{binary_search, recover_raw_transaction}, diff --git a/crates/rpc/rpc-eth-types/src/error.rs b/crates/rpc/rpc-eth-types/src/error.rs index b38b3122708..9241e9e0b6b 100644 --- a/crates/rpc/rpc-eth-types/src/error.rs +++ b/crates/rpc/rpc-eth-types/src/error.rs @@ -2,11 +2,12 @@ use std::time::Duration; +use alloy_eips::BlockId; use alloy_primitives::{Address, Bytes, U256}; use alloy_rpc_types::{error::EthRpcErrorCode, request::TransactionInputError, BlockError}; use alloy_sol_types::decode_revert_reason; use reth_errors::RethError; -use reth_primitives::{revm_primitives::InvalidHeader, BlockId}; +use reth_primitives::revm_primitives::InvalidHeader; use reth_rpc_server_types::result::{ block_id_to_str, internal_rpc_err, invalid_params_rpc_err, rpc_err, rpc_error_with_code, }; diff --git a/crates/rpc/rpc-eth-types/src/pending_block.rs b/crates/rpc/rpc-eth-types/src/pending_block.rs index 949e205dcf8..d3e7c4158ac 100644 --- a/crates/rpc/rpc-eth-types/src/pending_block.rs +++ b/crates/rpc/rpc-eth-types/src/pending_block.rs @@ -4,9 +4,10 @@ use std::time::Instant; +use alloy_eips::BlockId; use alloy_primitives::B256; use derive_more::Constructor; -use reth_primitives::{BlockId, BlockNumberOrTag, Receipt, SealedBlockWithSenders, SealedHeader}; +use reth_primitives::{BlockNumberOrTag, Receipt, SealedBlockWithSenders, SealedHeader}; use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg}; /// Configured [`BlockEnv`] and [`CfgEnvWithHandlerCfg`] for a pending block. diff --git a/crates/rpc/rpc-server-types/Cargo.toml b/crates/rpc/rpc-server-types/Cargo.toml index 08ecd394774..275d8ea561b 100644 --- a/crates/rpc/rpc-server-types/Cargo.toml +++ b/crates/rpc/rpc-server-types/Cargo.toml @@ -14,11 +14,11 @@ workspace = true [dependencies] reth-errors.workspace = true reth-network-api.workspace = true -reth-primitives.workspace = true # ethereum alloy-primitives.workspace = true alloy-rpc-types-engine.workspace = true +alloy-eips.workspace = true # rpc jsonrpsee-core.workspace = true @@ -27,4 +27,3 @@ jsonrpsee-types.workspace = true # misc strum = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"] } - diff --git a/crates/rpc/rpc-server-types/src/result.rs b/crates/rpc/rpc-server-types/src/result.rs index 10ce1650ad1..5d1b702e9fc 100644 --- a/crates/rpc/rpc-server-types/src/result.rs +++ b/crates/rpc/rpc-server-types/src/result.rs @@ -2,10 +2,10 @@ use std::fmt; +use alloy_eips::BlockId; use alloy_rpc_types_engine::PayloadError; use jsonrpsee_core::RpcResult; use reth_errors::ConsensusError; -use reth_primitives::BlockId; /// Helper trait to easily convert various `Result` types into [`RpcResult`] pub trait ToRpcResult: Sized { diff --git a/crates/rpc/rpc-testing-util/Cargo.toml b/crates/rpc/rpc-testing-util/Cargo.toml index 4977c3a2c40..e5c57502e2b 100644 --- a/crates/rpc/rpc-testing-util/Cargo.toml +++ b/crates/rpc/rpc-testing-util/Cargo.toml @@ -21,6 +21,7 @@ alloy-primitives.workspace = true alloy-rpc-types-eth.workspace = true alloy-rpc-types.workspace = true alloy-rpc-types-trace.workspace = true +alloy-eips.workspace = true # async futures.workspace = true @@ -36,4 +37,4 @@ similar-asserts.workspace = true tokio = { workspace = true, features = ["rt-multi-thread", "macros", "rt"] } reth-rpc-eth-api.workspace = true jsonrpsee-http-client.workspace = true -alloy-rpc-types-trace.workspace = true \ No newline at end of file +alloy-rpc-types-trace.workspace = true diff --git a/crates/rpc/rpc-testing-util/src/debug.rs b/crates/rpc/rpc-testing-util/src/debug.rs index 97fe008fa97..d4c7dce860b 100644 --- a/crates/rpc/rpc-testing-util/src/debug.rs +++ b/crates/rpc/rpc-testing-util/src/debug.rs @@ -6,6 +6,7 @@ use std::{ task::{Context, Poll}, }; +use alloy_eips::BlockId; use alloy_primitives::{TxHash, B256}; use alloy_rpc_types::{Block, Transaction}; use alloy_rpc_types_eth::transaction::TransactionRequest; @@ -15,7 +16,7 @@ use alloy_rpc_types_trace::{ }; use futures::{Stream, StreamExt}; use jsonrpsee::core::client::Error as RpcError; -use reth_primitives::{BlockId, Receipt}; +use reth_primitives::Receipt; use reth_rpc_api::{clients::DebugApiClient, EthApiClient}; const NOOP_TRACER: &str = include_str!("../assets/noop-tracer.js"); diff --git a/crates/rpc/rpc-testing-util/src/trace.rs b/crates/rpc/rpc-testing-util/src/trace.rs index 0fefef7c997..efb1f3674e0 100644 --- a/crates/rpc/rpc-testing-util/src/trace.rs +++ b/crates/rpc/rpc-testing-util/src/trace.rs @@ -1,5 +1,6 @@ //! Helpers for testing trace calls. +use alloy_eips::BlockId; use alloy_primitives::{map::HashSet, Bytes, TxHash, B256}; use alloy_rpc_types::Index; use alloy_rpc_types_eth::transaction::TransactionRequest; @@ -10,7 +11,6 @@ use alloy_rpc_types_trace::{ }; use futures::{Stream, StreamExt}; use jsonrpsee::core::client::Error as RpcError; -use reth_primitives::BlockId; use reth_rpc_api::clients::TraceApiClient; use std::{ pin::Pin, diff --git a/crates/rpc/rpc/src/debug.rs b/crates/rpc/rpc/src/debug.rs index e2746a53cd0..6a73af69d92 100644 --- a/crates/rpc/rpc/src/debug.rs +++ b/crates/rpc/rpc/src/debug.rs @@ -1,4 +1,4 @@ -use alloy_eips::eip2718::Encodable2718; +use alloy_eips::{eip2718::Encodable2718, BlockId}; use alloy_primitives::{Address, Bytes, B256, U256}; use alloy_rlp::{Decodable, Encodable}; use alloy_rpc_types::{ @@ -19,7 +19,7 @@ use reth_evm::{ system_calls::SystemCaller, ConfigureEvmEnv, }; -use reth_primitives::{Block, BlockId, BlockNumberOrTag, TransactionSignedEcRecovered}; +use reth_primitives::{Block, BlockNumberOrTag, TransactionSignedEcRecovered}; use reth_provider::{ BlockReaderIdExt, ChainSpecProvider, HeaderProvider, StateProofProvider, StateProviderFactory, TransactionVariant, diff --git a/crates/rpc/rpc/src/engine.rs b/crates/rpc/rpc/src/engine.rs index 928e2050a5c..0ff90d39998 100644 --- a/crates/rpc/rpc/src/engine.rs +++ b/crates/rpc/rpc/src/engine.rs @@ -1,3 +1,4 @@ +use alloy_eips::BlockId; use alloy_primitives::{Address, Bytes, B256, U256, U64}; use alloy_rpc_types::{ state::StateOverride, BlockOverrides, EIP1186AccountProofResponse, Filter, Log, SyncStatus, @@ -5,7 +6,7 @@ use alloy_rpc_types::{ use alloy_rpc_types_eth::transaction::TransactionRequest; use alloy_serde::JsonStorageKey; use jsonrpsee::core::RpcResult as Result; -use reth_primitives::{BlockId, BlockNumberOrTag}; +use reth_primitives::BlockNumberOrTag; use reth_rpc_api::{EngineEthApiServer, EthApiServer, EthFilterApiServer}; /// Re-export for convenience pub use reth_rpc_engine_api::EngineApi; diff --git a/crates/rpc/rpc/src/otterscan.rs b/crates/rpc/rpc/src/otterscan.rs index a772dd501d4..da33bf5d3d0 100644 --- a/crates/rpc/rpc/src/otterscan.rs +++ b/crates/rpc/rpc/src/otterscan.rs @@ -1,4 +1,5 @@ use alloy_consensus::Transaction; +use alloy_eips::BlockId; use alloy_network::{ReceiptResponse, TransactionResponse}; use alloy_primitives::{Address, Bytes, TxHash, B256, U256}; use alloy_rpc_types::{BlockTransactions, Header, TransactionReceipt}; @@ -11,7 +12,7 @@ use alloy_rpc_types_trace::{ }; use async_trait::async_trait; use jsonrpsee::{core::RpcResult, types::ErrorObjectOwned}; -use reth_primitives::{BlockId, BlockNumberOrTag}; +use reth_primitives::BlockNumberOrTag; use reth_rpc_api::{EthApiServer, OtterscanServer}; use reth_rpc_eth_api::{ helpers::{EthTransactions, TraceExt}, diff --git a/crates/rpc/rpc/src/reth.rs b/crates/rpc/rpc/src/reth.rs index 6d5897df131..c33f97f5301 100644 --- a/crates/rpc/rpc/src/reth.rs +++ b/crates/rpc/rpc/src/reth.rs @@ -1,10 +1,10 @@ use std::{collections::HashMap, future::Future, sync::Arc}; +use alloy_eips::BlockId; use alloy_primitives::{Address, U256}; use async_trait::async_trait; use jsonrpsee::core::RpcResult; use reth_errors::RethResult; -use reth_primitives::BlockId; use reth_provider::{BlockReaderIdExt, ChangeSetReader, StateProviderFactory}; use reth_rpc_api::RethApiServer; use reth_rpc_eth_types::{EthApiError, EthResult}; diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 2883818afd9..38c73b0f516 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -1,3 +1,4 @@ +use alloy_eips::BlockId; use alloy_primitives::{map::HashSet, Bytes, B256, U256}; use alloy_rpc_types::{ state::{EvmOverrides, StateOverride}, @@ -17,7 +18,7 @@ use reth_consensus_common::calc::{ base_block_reward, base_block_reward_pre_merge, block_reward, ommer_reward, }; use reth_evm::ConfigureEvmEnv; -use reth_primitives::{BlockId, Header}; +use reth_primitives::Header; use reth_provider::{BlockReader, ChainSpecProvider, EvmEnvProvider, StateProviderFactory}; use reth_revm::database::StateProviderDatabase; use reth_rpc_api::TraceApiServer; From 3fe22343f1b96ef97c4199741e0b44b6567799b4 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Mon, 4 Nov 2024 13:48:32 +0100 Subject: [PATCH 006/211] feat(engine): add StateRootTask skeleton (#12305) --- Cargo.lock | 2 + crates/engine/tree/Cargo.toml | 3 ++ crates/engine/tree/src/tree/mod.rs | 2 + crates/engine/tree/src/tree/root.rs | 60 +++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+) create mode 100644 crates/engine/tree/src/tree/root.rs diff --git a/Cargo.lock b/Cargo.lock index 9b5a5350c16..a885081cd36 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7218,8 +7218,10 @@ dependencies = [ "reth-tracing", "reth-trie", "reth-trie-parallel", + "revm-primitives", "thiserror", "tokio", + "tokio-stream", "tracing", ] diff --git a/crates/engine/tree/Cargo.toml b/crates/engine/tree/Cargo.toml index dee0bcaf7ce..293883c036e 100644 --- a/crates/engine/tree/Cargo.toml +++ b/crates/engine/tree/Cargo.toml @@ -39,9 +39,12 @@ alloy-primitives.workspace = true alloy-eips.workspace = true alloy-rpc-types-engine.workspace = true +revm-primitives.workspace = true + # common futures.workspace = true tokio = { workspace = true, features = ["macros", "sync"] } +tokio-stream.workspace = true thiserror.workspace = true # metrics diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index bc070d87345..c3e922d11c9 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -75,6 +75,8 @@ pub use invalid_block_hook::{InvalidBlockHooks, NoopInvalidBlockHook}; pub use persistence_state::PersistenceState; pub use reth_engine_primitives::InvalidBlockHook; +mod root; + /// Keeps track of the state of the tree. /// /// ## Invariants diff --git a/crates/engine/tree/src/tree/root.rs b/crates/engine/tree/src/tree/root.rs new file mode 100644 index 00000000000..48b2eccdf14 --- /dev/null +++ b/crates/engine/tree/src/tree/root.rs @@ -0,0 +1,60 @@ +//! State root task related functionality. + +use reth_provider::providers::ConsistentDbView; +use reth_trie::{updates::TrieUpdates, TrieInput}; +use reth_trie_parallel::parallel_root::ParallelStateRootError; +use revm_primitives::{EvmState, B256}; +use std::{ + future::Future, + pin::Pin, + sync::Arc, + task::{Context, Poll}, +}; +use tokio_stream::wrappers::UnboundedReceiverStream; + +/// Standalone task that receives a transaction state stream and updates relevant +/// data structures to calculate state root. +/// +/// It is responsile of initializing a blinded sparse trie and subscribe to +/// transaction state stream. As it receives transaction execution results, it +/// fetches the proofs for relevant accounts from the database and reveal them +/// to the tree. +/// Then it updates relevant leaves according to the result of the transaction. +#[allow(dead_code)] +pub(crate) struct StateRootTask { + /// View over the state in the database. + consistent_view: ConsistentDbView, + /// Incoming state updates. + state_stream: UnboundedReceiverStream, + /// Latest trie input. + input: Arc, +} + +#[allow(dead_code)] +impl StateRootTask { + /// Creates a new `StateRootTask`. + pub(crate) const fn new( + consistent_view: ConsistentDbView, + input: Arc, + state_stream: UnboundedReceiverStream, + ) -> Self { + Self { consistent_view, state_stream, input } + } + + /// Handles state updates. + pub(crate) fn on_state_update(&self, _update: EvmState) { + // TODO: calculate hashed state update and dispatch proof gathering for it. + } +} + +impl Future for StateRootTask { + type Output = Result<(B256, TrieUpdates), ParallelStateRootError>; + + fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll { + // TODO: + // * poll incoming state updates stream + // * keep track of proof calculation + // * keep track of intermediate root computation + Poll::Pending + } +} From d5f01036016263fbad6a3af9dc3707b2701adc1d Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Mon, 4 Nov 2024 15:54:58 +0100 Subject: [PATCH 007/211] primitives: rm alloy `BlockNumHash` reexport (#12304) --- Cargo.lock | 2 ++ crates/blockchain-tree-api/Cargo.toml | 1 + crates/blockchain-tree-api/src/lib.rs | 3 ++- crates/consensus/beacon/src/engine/mod.rs | 4 ++-- crates/exex/exex/src/event.rs | 2 +- crates/exex/exex/src/manager.rs | 3 ++- crates/exex/test-utils/Cargo.toml | 3 +++ crates/exex/test-utils/src/lib.rs | 3 ++- crates/primitives/src/block.rs | 2 +- crates/primitives/src/lib.rs | 4 ++-- crates/rpc/rpc-eth-types/src/logs_utils.rs | 3 ++- crates/storage/provider/src/test_utils/mock.rs | 6 +++--- crates/storage/provider/src/test_utils/noop.rs | 6 +++--- crates/storage/storage-api/src/block_id.rs | 6 +++--- 14 files changed, 29 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a885081cd36..9d40ebfb2c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6550,6 +6550,7 @@ dependencies = [ name = "reth-blockchain-tree-api" version = "1.1.0" dependencies = [ + "alloy-eips", "alloy-primitives", "reth-consensus", "reth-execution-errors", @@ -7557,6 +7558,7 @@ dependencies = [ name = "reth-exex-test-utils" version = "1.1.0" dependencies = [ + "alloy-eips", "eyre", "futures-util", "rand 0.8.5", diff --git a/crates/blockchain-tree-api/Cargo.toml b/crates/blockchain-tree-api/Cargo.toml index 552b7276717..b1c01f85938 100644 --- a/crates/blockchain-tree-api/Cargo.toml +++ b/crates/blockchain-tree-api/Cargo.toml @@ -18,6 +18,7 @@ reth-storage-errors.workspace = true # alloy alloy-primitives.workspace = true +alloy-eips.workspace = true # misc thiserror.workspace = true diff --git a/crates/blockchain-tree-api/src/lib.rs b/crates/blockchain-tree-api/src/lib.rs index 0a1bf6164e0..7e1d0d714c1 100644 --- a/crates/blockchain-tree-api/src/lib.rs +++ b/crates/blockchain-tree-api/src/lib.rs @@ -9,8 +9,9 @@ use self::error::CanonicalError; use crate::error::InsertBlockError; +use alloy_eips::BlockNumHash; use alloy_primitives::{BlockHash, BlockNumber}; -use reth_primitives::{BlockNumHash, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader}; +use reth_primitives::{Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader}; use reth_storage_errors::provider::{ProviderError, ProviderResult}; use std::collections::BTreeMap; diff --git a/crates/consensus/beacon/src/engine/mod.rs b/crates/consensus/beacon/src/engine/mod.rs index a00f507dbd9..65904196e1c 100644 --- a/crates/consensus/beacon/src/engine/mod.rs +++ b/crates/consensus/beacon/src/engine/mod.rs @@ -1,4 +1,4 @@ -use alloy_eips::merge::EPOCH_SLOTS; +use alloy_eips::{merge::EPOCH_SLOTS, BlockNumHash}; use alloy_primitives::{BlockNumber, B256}; use alloy_rpc_types_engine::{ ExecutionPayload, ExecutionPayloadSidecar, ForkchoiceState, PayloadStatus, PayloadStatusEnum, @@ -20,7 +20,7 @@ use reth_node_types::NodeTypesWithEngine; use reth_payload_builder::PayloadBuilderHandle; use reth_payload_primitives::{PayloadAttributes, PayloadBuilder, PayloadBuilderAttributes}; use reth_payload_validator::ExecutionPayloadValidator; -use reth_primitives::{BlockNumHash, Head, Header, SealedBlock, SealedHeader}; +use reth_primitives::{Head, Header, SealedBlock, SealedHeader}; use reth_provider::{ providers::ProviderNodeTypes, BlockIdReader, BlockReader, BlockSource, CanonChainTracker, ChainSpecProvider, ProviderError, StageCheckpointReader, diff --git a/crates/exex/exex/src/event.rs b/crates/exex/exex/src/event.rs index 1215ea2a502..bbd79addc9e 100644 --- a/crates/exex/exex/src/event.rs +++ b/crates/exex/exex/src/event.rs @@ -1,4 +1,4 @@ -use reth_primitives::BlockNumHash; +use alloy_eips::BlockNumHash; /// Events emitted by an `ExEx`. #[derive(Debug, Clone, Copy, PartialEq, Eq)] diff --git a/crates/exex/exex/src/manager.rs b/crates/exex/exex/src/manager.rs index 8c1518f3090..a17de660862 100644 --- a/crates/exex/exex/src/manager.rs +++ b/crates/exex/exex/src/manager.rs @@ -1,13 +1,14 @@ use crate::{ wal::Wal, ExExEvent, ExExNotification, ExExNotifications, FinishedExExHeight, WalHandle, }; +use alloy_eips::BlockNumHash; use futures::StreamExt; use itertools::Itertools; use metrics::Gauge; use reth_chain_state::ForkChoiceStream; use reth_chainspec::Head; use reth_metrics::{metrics::Counter, Metrics}; -use reth_primitives::{BlockNumHash, SealedHeader}; +use reth_primitives::SealedHeader; use reth_provider::HeaderProvider; use reth_tracing::tracing::debug; use std::{ diff --git a/crates/exex/test-utils/Cargo.toml b/crates/exex/test-utils/Cargo.toml index cd0e0831b49..6e5af981b31 100644 --- a/crates/exex/test-utils/Cargo.toml +++ b/crates/exex/test-utils/Cargo.toml @@ -33,6 +33,9 @@ reth-tasks.workspace = true reth-transaction-pool = { workspace = true, features = ["test-utils"] } reth-trie-db.workspace = true +## alloy +alloy-eips.workspace = true + ## async futures-util.workspace = true tokio.workspace = true diff --git a/crates/exex/test-utils/src/lib.rs b/crates/exex/test-utils/src/lib.rs index 06aa8c81c7c..5c3468a3c1c 100644 --- a/crates/exex/test-utils/src/lib.rs +++ b/crates/exex/test-utils/src/lib.rs @@ -15,6 +15,7 @@ use std::{ task::Poll, }; +use alloy_eips::BlockNumHash; use futures_util::FutureExt; use reth_blockchain_tree::noop::NoopBlockchainTree; use reth_chainspec::{ChainSpec, MAINNET}; @@ -44,7 +45,7 @@ use reth_node_ethereum::{ EthEngineTypes, EthEvmConfig, }; use reth_payload_builder::noop::NoopPayloadBuilderService; -use reth_primitives::{BlockNumHash, Head, SealedBlockWithSenders}; +use reth_primitives::{Head, SealedBlockWithSenders}; use reth_provider::{ providers::{BlockchainProvider, StaticFileProvider}, BlockReader, ProviderFactory, diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index 2b651652df5..b9f43df5d7c 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -2,7 +2,7 @@ use crate::{ GotExpected, Header, SealedHeader, TransactionSigned, TransactionSignedEcRecovered, Withdrawals, }; use alloc::vec::Vec; -pub use alloy_eips::eip1898::{BlockNumHash, BlockNumberOrTag, ForkBlock, RpcBlockHash}; +pub use alloy_eips::eip1898::{BlockNumberOrTag, ForkBlock, RpcBlockHash}; use alloy_eips::eip2718::Encodable2718; use alloy_primitives::{Address, Bytes, Sealable, B256}; use alloy_rlp::{Decodable, Encodable, RlpDecodable, RlpEncodable}; diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 679b24abd84..4f56b1ac4e6 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -34,8 +34,8 @@ pub mod transaction; #[cfg(any(test, feature = "arbitrary"))] pub use block::{generate_valid_header, valid_header_strategy}; pub use block::{ - Block, BlockBody, BlockNumHash, BlockNumberOrTag, BlockWithSenders, ForkBlock, RpcBlockHash, - SealedBlock, SealedBlockWithSenders, + Block, BlockBody, BlockNumberOrTag, BlockWithSenders, ForkBlock, RpcBlockHash, SealedBlock, + SealedBlockWithSenders, }; #[cfg(feature = "reth-codec")] pub use compression::*; diff --git a/crates/rpc/rpc-eth-types/src/logs_utils.rs b/crates/rpc/rpc-eth-types/src/logs_utils.rs index 205e2bba37b..aa132675c93 100644 --- a/crates/rpc/rpc-eth-types/src/logs_utils.rs +++ b/crates/rpc/rpc-eth-types/src/logs_utils.rs @@ -2,11 +2,12 @@ //! //! Log parsing for building filter. +use alloy_eips::BlockNumHash; use alloy_primitives::TxHash; use alloy_rpc_types::{FilteredParams, Log}; use reth_chainspec::ChainInfo; use reth_errors::ProviderError; -use reth_primitives::{BlockNumHash, Receipt, SealedBlockWithSenders}; +use reth_primitives::{Receipt, SealedBlockWithSenders}; use reth_storage_api::BlockReader; use std::sync::Arc; diff --git a/crates/storage/provider/src/test_utils/mock.rs b/crates/storage/provider/src/test_utils/mock.rs index 2e7cd6a06de..b5593b9040d 100644 --- a/crates/storage/provider/src/test_utils/mock.rs +++ b/crates/storage/provider/src/test_utils/mock.rs @@ -463,15 +463,15 @@ impl BlockNumReader for MockEthProvider { } impl BlockIdReader for MockEthProvider { - 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) } } diff --git a/crates/storage/provider/src/test_utils/noop.rs b/crates/storage/provider/src/test_utils/noop.rs index 8e6dc7425cf..65c08306239 100644 --- a/crates/storage/provider/src/test_utils/noop.rs +++ b/crates/storage/provider/src/test_utils/noop.rs @@ -175,15 +175,15 @@ impl BlockReaderIdExt for NoopProvider { } impl BlockIdReader for NoopProvider { - 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) } } diff --git a/crates/storage/storage-api/src/block_id.rs b/crates/storage/storage-api/src/block_id.rs index 55cd6ab1c76..00856d348a5 100644 --- a/crates/storage/storage-api/src/block_id.rs +++ b/crates/storage/storage-api/src/block_id.rs @@ -99,13 +99,13 @@ pub trait BlockIdReader: BlockNumReader + Send + Sync { } /// Get the current pending block number and hash. - fn pending_block_num_hash(&self) -> ProviderResult>; + fn pending_block_num_hash(&self) -> ProviderResult>; /// Get the current safe block number and hash. - fn safe_block_num_hash(&self) -> ProviderResult>; + fn safe_block_num_hash(&self) -> ProviderResult>; /// Get the current finalized block number and hash. - fn finalized_block_num_hash(&self) -> ProviderResult>; + fn finalized_block_num_hash(&self) -> ProviderResult>; /// Get the safe block number. fn safe_block_number(&self) -> ProviderResult> { From 967cbc4e974ee2084f3342a0fbc37dd549861d05 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Tue, 5 Nov 2024 05:15:15 +0100 Subject: [PATCH 008/211] primitives: rm alloy `Signature` reexport (#12313) --- crates/blockchain-tree/src/blockchain_tree.rs | 6 +++--- crates/consensus/common/src/validation.rs | 4 ++-- crates/net/eth-wire-types/src/blocks.rs | 4 ++-- crates/net/eth-wire-types/src/transactions.rs | 4 ++-- crates/net/network/tests/it/big_pooled_txs_req.rs | 4 ++-- crates/net/network/tests/it/requests.rs | 4 ++-- crates/net/network/tests/it/txgossip.rs | 4 ++-- crates/optimism/evm/src/execute.rs | 4 ++-- crates/optimism/node/src/txpool.rs | 3 +-- crates/primitives/src/alloy_compat.rs | 4 ++-- crates/primitives/src/lib.rs | 2 +- crates/primitives/src/transaction/mod.rs | 12 ++++++------ crates/primitives/src/transaction/pooled.rs | 4 ++-- crates/primitives/src/transaction/sidecar.rs | 4 ++-- crates/primitives/src/transaction/signature.rs | 13 ++++--------- crates/primitives/src/transaction/util.rs | 3 +-- crates/rpc/rpc-eth-api/src/helpers/signer.rs | 4 ++-- crates/rpc/rpc-eth-types/src/simulate.rs | 5 ++--- .../rpc-types-compat/src/transaction/signature.rs | 10 +++++----- crates/rpc/rpc/src/eth/helpers/signer.rs | 4 ++-- crates/storage/provider/src/test_utils/blocks.rs | 3 ++- crates/transaction-pool/src/test_utils/mock.rs | 4 ++-- crates/transaction-pool/src/traits.rs | 3 ++- testing/testing-utils/src/generators.rs | 4 ++-- 24 files changed, 55 insertions(+), 61 deletions(-) diff --git a/crates/blockchain-tree/src/blockchain_tree.rs b/crates/blockchain-tree/src/blockchain_tree.rs index 4468d82052c..1674081fe70 100644 --- a/crates/blockchain-tree/src/blockchain_tree.rs +++ b/crates/blockchain-tree/src/blockchain_tree.rs @@ -1377,7 +1377,7 @@ mod tests { use alloy_consensus::{TxEip1559, EMPTY_ROOT_HASH}; use alloy_eips::eip1559::INITIAL_BASE_FEE; use alloy_genesis::{Genesis, GenesisAccount}; - use alloy_primitives::{keccak256, Address, Sealable, B256}; + use alloy_primitives::{keccak256, Address, Sealable, Signature, B256}; use assert_matches::assert_matches; use linked_hash_set::LinkedHashSet; use reth_chainspec::{ChainSpecBuilder, MAINNET, MIN_TRANSACTION_GAS}; @@ -1389,8 +1389,8 @@ mod tests { use reth_primitives::{ proofs::{calculate_receipt_root, calculate_transaction_root}, revm_primitives::AccountInfo, - Account, BlockBody, Header, Signature, Transaction, TransactionSigned, - TransactionSignedEcRecovered, Withdrawals, + Account, BlockBody, Header, Transaction, TransactionSigned, TransactionSignedEcRecovered, + Withdrawals, }; use reth_provider::{ test_utils::{ diff --git a/crates/consensus/common/src/validation.rs b/crates/consensus/common/src/validation.rs index 092330595ff..d4dea07dcda 100644 --- a/crates/consensus/common/src/validation.rs +++ b/crates/consensus/common/src/validation.rs @@ -277,13 +277,13 @@ mod tests { use alloy_consensus::{TxEip4844, EMPTY_OMMER_ROOT_HASH, EMPTY_ROOT_HASH}; use alloy_eips::{eip4895::Withdrawal, BlockHashOrNumber}; use alloy_primitives::{ - hex_literal::hex, Address, BlockHash, BlockNumber, Bytes, Parity, Sealable, U256, + hex_literal::hex, Address, BlockHash, BlockNumber, Bytes, Parity, Sealable, Signature, U256, }; use mockall::mock; use rand::Rng; use reth_chainspec::ChainSpecBuilder; use reth_primitives::{ - proofs, Account, BlockBody, Signature, Transaction, TransactionSigned, Withdrawals, + proofs, Account, BlockBody, Transaction, TransactionSigned, Withdrawals, }; use reth_storage_api::{ errors::provider::ProviderResult, AccountReader, HeaderProvider, WithdrawalsProvider, diff --git a/crates/net/eth-wire-types/src/blocks.rs b/crates/net/eth-wire-types/src/blocks.rs index 5ae84319005..ce23dfe707f 100644 --- a/crates/net/eth-wire-types/src/blocks.rs +++ b/crates/net/eth-wire-types/src/blocks.rs @@ -114,9 +114,9 @@ mod tests { }; use alloy_consensus::TxLegacy; use alloy_eips::BlockHashOrNumber; - use alloy_primitives::{hex, Parity, TxKind, U256}; + use alloy_primitives::{hex, Parity, Signature, TxKind, U256}; use alloy_rlp::{Decodable, Encodable}; - use reth_primitives::{Header, Signature, Transaction, TransactionSigned}; + use reth_primitives::{Header, Transaction, TransactionSigned}; use std::str::FromStr; use super::BlockBody; diff --git a/crates/net/eth-wire-types/src/transactions.rs b/crates/net/eth-wire-types/src/transactions.rs index ab65aa178ee..7c66f657a1d 100644 --- a/crates/net/eth-wire-types/src/transactions.rs +++ b/crates/net/eth-wire-types/src/transactions.rs @@ -78,10 +78,10 @@ impl FromIterator for PooledTransactions { mod tests { use crate::{message::RequestPair, GetPooledTransactions, PooledTransactions}; use alloy_consensus::{TxEip1559, TxLegacy}; - use alloy_primitives::{hex, Parity, TxKind, U256}; + use alloy_primitives::{hex, Parity, Signature, TxKind, U256}; use alloy_rlp::{Decodable, Encodable}; use reth_chainspec::MIN_TRANSACTION_GAS; - use reth_primitives::{PooledTransactionsElement, Signature, Transaction, TransactionSigned}; + use reth_primitives::{PooledTransactionsElement, Transaction, TransactionSigned}; use std::str::FromStr; #[test] diff --git a/crates/net/network/tests/it/big_pooled_txs_req.rs b/crates/net/network/tests/it/big_pooled_txs_req.rs index 3a645da6c9f..29b62708eee 100644 --- a/crates/net/network/tests/it/big_pooled_txs_req.rs +++ b/crates/net/network/tests/it/big_pooled_txs_req.rs @@ -1,4 +1,4 @@ -use alloy_primitives::B256; +use alloy_primitives::{Signature, B256}; use reth_eth_wire::{GetPooledTransactions, PooledTransactions}; use reth_network::{ test_utils::{NetworkEventStream, Testnet}, @@ -6,7 +6,7 @@ use reth_network::{ }; use reth_network_api::{NetworkInfo, Peers}; use reth_network_p2p::sync::{NetworkSyncUpdater, SyncState}; -use reth_primitives::{Signature, TransactionSigned}; +use reth_primitives::TransactionSigned; use reth_provider::test_utils::MockEthProvider; use reth_transaction_pool::{ test_utils::{testing_pool, MockTransaction}, diff --git a/crates/net/network/tests/it/requests.rs b/crates/net/network/tests/it/requests.rs index 61241f02d2d..8c00302f7b4 100644 --- a/crates/net/network/tests/it/requests.rs +++ b/crates/net/network/tests/it/requests.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use alloy_consensus::TxEip2930; -use alloy_primitives::{Bytes, Parity, TxKind, U256}; +use alloy_primitives::{Bytes, Parity, Signature, TxKind, U256}; use rand::Rng; use reth_eth_wire::HeadersDirection; use reth_network::{ @@ -16,7 +16,7 @@ use reth_network_p2p::{ bodies::client::BodiesClient, headers::client::{HeadersClient, HeadersRequest}, }; -use reth_primitives::{Block, Header, Signature, Transaction, TransactionSigned}; +use reth_primitives::{Block, Header, Transaction, TransactionSigned}; use reth_provider::test_utils::MockEthProvider; /// Returns a new [`TransactionSigned`] with some random parameters diff --git a/crates/net/network/tests/it/txgossip.rs b/crates/net/network/tests/it/txgossip.rs index 70ac67bb5bf..f08a2b2eb96 100644 --- a/crates/net/network/tests/it/txgossip.rs +++ b/crates/net/network/tests/it/txgossip.rs @@ -3,12 +3,12 @@ use std::sync::Arc; use alloy_consensus::TxLegacy; -use alloy_primitives::U256; +use alloy_primitives::{Signature, U256}; use futures::StreamExt; use rand::thread_rng; use reth_network::{test_utils::Testnet, NetworkEvent, NetworkEventListenerProvider}; use reth_network_api::PeersInfo; -use reth_primitives::{Signature, TransactionSigned}; +use reth_primitives::TransactionSigned; use reth_provider::test_utils::{ExtendedAccount, MockEthProvider}; use reth_transaction_pool::{test_utils::TransactionGenerator, PoolTransaction, TransactionPool}; diff --git a/crates/optimism/evm/src/execute.rs b/crates/optimism/evm/src/execute.rs index 91cdb1bd2c5..d64f4bd5ea5 100644 --- a/crates/optimism/evm/src/execute.rs +++ b/crates/optimism/evm/src/execute.rs @@ -297,12 +297,12 @@ mod tests { use super::*; use crate::OpChainSpec; use alloy_consensus::TxEip1559; - use alloy_primitives::{b256, Address, StorageKey, StorageValue}; + use alloy_primitives::{b256, Address, Signature, StorageKey, StorageValue}; use op_alloy_consensus::TxDeposit; use reth_chainspec::MIN_TRANSACTION_GAS; use reth_evm::execute::{BasicBlockExecutorProvider, BatchExecutor, BlockExecutorProvider}; use reth_optimism_chainspec::OpChainSpecBuilder; - use reth_primitives::{Account, Block, BlockBody, Signature, Transaction, TransactionSigned}; + use reth_primitives::{Account, Block, BlockBody, Transaction, TransactionSigned}; use reth_revm::{ database::StateProviderDatabase, test_utils::StateProviderTest, L1_BLOCK_CONTRACT, }; diff --git a/crates/optimism/node/src/txpool.rs b/crates/optimism/node/src/txpool.rs index 09aa76fefb8..011654909eb 100644 --- a/crates/optimism/node/src/txpool.rs +++ b/crates/optimism/node/src/txpool.rs @@ -231,9 +231,8 @@ pub struct OpL1BlockInfo { mod tests { use crate::txpool::OpTransactionValidator; use alloy_eips::eip2718::Encodable2718; - use alloy_primitives::{TxKind, U256}; + use alloy_primitives::{Signature, TxKind, U256}; use op_alloy_consensus::TxDeposit; - use reth::primitives::Signature; use reth_chainspec::MAINNET; use reth_primitives::{Transaction, TransactionSigned, TransactionSignedEcRecovered}; use reth_provider::test_utils::MockEthProvider; diff --git a/crates/primitives/src/alloy_compat.rs b/crates/primitives/src/alloy_compat.rs index 917baef6661..d86bd04c7b9 100644 --- a/crates/primitives/src/alloy_compat.rs +++ b/crates/primitives/src/alloy_compat.rs @@ -1,14 +1,14 @@ //! Common conversions from alloy types. use crate::{ - transaction::extract_chain_id, Block, BlockBody, Signature, Transaction, TransactionSigned, + transaction::extract_chain_id, Block, BlockBody, Transaction, TransactionSigned, TransactionSignedEcRecovered, TransactionSignedNoHash, TxType, }; use alloc::{string::ToString, vec::Vec}; use alloy_consensus::{ constants::EMPTY_TRANSACTIONS, Transaction as _, TxEip1559, TxEip2930, TxEip4844, TxLegacy, }; -use alloy_primitives::{Parity, TxKind}; +use alloy_primitives::{Parity, Signature, TxKind}; use alloy_rlp::Error as RlpError; use alloy_serde::WithOtherFields; use op_alloy_rpc_types as _; diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 4f56b1ac4e6..be592e1c167 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -59,7 +59,7 @@ pub use transaction::BlobTransactionValidationError; pub use transaction::{ util::secp256k1::{public_key_to_address, recover_signer_unchecked, sign_message}, - InvalidTransactionError, Signature, Transaction, TransactionMeta, TransactionSigned, + InvalidTransactionError, Transaction, TransactionMeta, TransactionSigned, TransactionSignedEcRecovered, TransactionSignedNoHash, TxHashOrNumber, TxType, }; diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index f7d36be0ab8..adbd8f0d09c 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -11,7 +11,7 @@ use alloy_eips::{ eip2930::AccessList, eip7702::SignedAuthorization, }; -use alloy_primitives::{keccak256, Address, Bytes, ChainId, TxHash, TxKind, B256, U256}; +use alloy_primitives::{keccak256, Address, Bytes, ChainId, Signature, TxHash, TxKind, B256, U256}; use alloy_rlp::{Decodable, Encodable, Error as RlpError, Header}; use core::mem; use derive_more::{AsRef, Deref}; @@ -36,9 +36,7 @@ pub use sidecar::BlobTransactionValidationError; pub use sidecar::{BlobTransaction, BlobTransactionSidecar}; pub use compat::FillTxEnv; -pub use signature::{ - extract_chain_id, legacy_parity, recover_signer, recover_signer_unchecked, Signature, -}; +pub use signature::{extract_chain_id, legacy_parity, recover_signer, recover_signer_unchecked}; pub use tx_type::TxType; pub use variant::TransactionSignedVariant; @@ -2016,12 +2014,14 @@ pub mod serde_bincode_compat { #[cfg(test)] mod tests { use crate::{ - transaction::{signature::Signature, TxEip1559, TxKind, TxLegacy}, + transaction::{TxEip1559, TxKind, TxLegacy}, Transaction, TransactionSigned, TransactionSignedEcRecovered, TransactionSignedNoHash, }; use alloy_consensus::Transaction as _; use alloy_eips::eip2718::{Decodable2718, Encodable2718}; - use alloy_primitives::{address, b256, bytes, hex, Address, Bytes, Parity, B256, U256}; + use alloy_primitives::{ + address, b256, bytes, hex, Address, Bytes, Parity, Signature, B256, U256, + }; use alloy_rlp::{Decodable, Encodable, Error as RlpError}; use reth_chainspec::MIN_TRANSACTION_GAS; use reth_codecs::Compact; diff --git a/crates/primitives/src/transaction/pooled.rs b/crates/primitives/src/transaction/pooled.rs index 000ff41fe52..11da5d8385f 100644 --- a/crates/primitives/src/transaction/pooled.rs +++ b/crates/primitives/src/transaction/pooled.rs @@ -7,7 +7,7 @@ use super::{ TxEip7702, }; use crate::{ - BlobTransaction, BlobTransactionSidecar, Signature, Transaction, TransactionSigned, + BlobTransaction, BlobTransactionSidecar, Transaction, TransactionSigned, TransactionSignedEcRecovered, }; use alloy_consensus::{ @@ -16,7 +16,7 @@ use alloy_consensus::{ SignableTransaction, TxEip4844WithSidecar, }; use alloy_eips::eip2718::{Decodable2718, Eip2718Result, Encodable2718}; -use alloy_primitives::{Address, TxHash, B256}; +use alloy_primitives::{Address, Signature, TxHash, B256}; use alloy_rlp::{Decodable, Encodable, Error as RlpError, Header}; use bytes::Buf; use derive_more::{AsRef, Deref}; diff --git a/crates/primitives/src/transaction/sidecar.rs b/crates/primitives/src/transaction/sidecar.rs index 1e6560e152b..aa473ef8a3f 100644 --- a/crates/primitives/src/transaction/sidecar.rs +++ b/crates/primitives/src/transaction/sidecar.rs @@ -1,8 +1,8 @@ #![cfg_attr(docsrs, doc(cfg(feature = "c-kzg")))] -use crate::{Signature, Transaction, TransactionSigned}; +use crate::{Transaction, TransactionSigned}; use alloy_consensus::{constants::EIP4844_TX_TYPE_ID, TxEip4844WithSidecar}; -use alloy_primitives::TxHash; +use alloy_primitives::{Signature, TxHash}; use alloy_rlp::Header; use serde::{Deserialize, Serialize}; diff --git a/crates/primitives/src/transaction/signature.rs b/crates/primitives/src/transaction/signature.rs index 5bfdab8e68e..b73206e6e77 100644 --- a/crates/primitives/src/transaction/signature.rs +++ b/crates/primitives/src/transaction/signature.rs @@ -1,9 +1,7 @@ use crate::transaction::util::secp256k1; -use alloy_primitives::{Address, Parity, B256, U256}; +use alloy_primitives::{Address, Parity, Signature, B256, U256}; use alloy_rlp::{Decodable, Error as RlpError}; -pub use alloy_primitives::Signature; - /// The order of the secp256k1 curve, divided by two. Signatures that should be checked according /// to EIP-2 should have an S value less than or equal to this. /// @@ -111,14 +109,11 @@ pub const fn extract_chain_id(v: u64) -> alloy_rlp::Result<(bool, Option)> #[cfg(test)] mod tests { - use crate::{ - transaction::signature::{ - legacy_parity, recover_signer, recover_signer_unchecked, SECP256K1N_HALF, - }, - Signature, + use crate::transaction::signature::{ + legacy_parity, recover_signer, recover_signer_unchecked, SECP256K1N_HALF, }; use alloy_eips::eip2718::Decodable2718; - use alloy_primitives::{hex, Address, Parity, B256, U256}; + use alloy_primitives::{hex, Address, Parity, Signature, B256, U256}; use std::str::FromStr; #[test] diff --git a/crates/primitives/src/transaction/util.rs b/crates/primitives/src/transaction/util.rs index 7569400e94b..ff2c2e0dab5 100644 --- a/crates/primitives/src/transaction/util.rs +++ b/crates/primitives/src/transaction/util.rs @@ -1,5 +1,4 @@ -use crate::Signature; -use alloy_primitives::Address; +use alloy_primitives::{Address, Signature}; #[cfg(feature = "secp256k1")] pub(crate) mod secp256k1 { diff --git a/crates/rpc/rpc-eth-api/src/helpers/signer.rs b/crates/rpc/rpc-eth-api/src/helpers/signer.rs index ab11e62d543..36e9277400f 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/signer.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/signer.rs @@ -1,10 +1,10 @@ //! An abstraction over ethereum signers. use alloy_dyn_abi::TypedData; -use alloy_primitives::Address; +use alloy_primitives::{Address, Signature}; use alloy_rpc_types_eth::TransactionRequest; use dyn_clone::DynClone; -use reth_primitives::{Signature, TransactionSigned}; +use reth_primitives::TransactionSigned; use reth_rpc_eth_types::SignError; use std::result; diff --git a/crates/rpc/rpc-eth-types/src/simulate.rs b/crates/rpc/rpc-eth-types/src/simulate.rs index 62f0e24b1c6..20952413c13 100644 --- a/crates/rpc/rpc-eth-types/src/simulate.rs +++ b/crates/rpc/rpc-eth-types/src/simulate.rs @@ -1,7 +1,7 @@ //! Utilities for serving `eth_simulateV1` use alloy_consensus::{Transaction as _, TxEip4844Variant, TxType, TypedTransaction}; -use alloy_primitives::Parity; +use alloy_primitives::{Parity, Signature}; use alloy_rpc_types::{ simulate::{SimCallResult, SimulateError, SimulatedBlock}, Block, BlockTransactionsKind, @@ -10,8 +10,7 @@ use alloy_rpc_types_eth::transaction::TransactionRequest; use jsonrpsee_types::ErrorObject; use reth_primitives::{ proofs::{calculate_receipt_root, calculate_transaction_root}, - BlockBody, BlockWithSenders, Receipt, Signature, Transaction, TransactionSigned, - TransactionSignedNoHash, + BlockBody, BlockWithSenders, Receipt, Transaction, TransactionSigned, TransactionSignedNoHash, }; use reth_revm::database::StateProviderDatabase; use reth_rpc_server_types::result::rpc_err; diff --git a/crates/rpc/rpc-types-compat/src/transaction/signature.rs b/crates/rpc/rpc-types-compat/src/transaction/signature.rs index 536f6ac5e5c..77ae365b2da 100644 --- a/crates/rpc/rpc-types-compat/src/transaction/signature.rs +++ b/crates/rpc/rpc-types-compat/src/transaction/signature.rs @@ -1,9 +1,9 @@ -use alloy_primitives::U256; +use alloy_primitives::{Signature as PrimitiveSignature, U256}; use alloy_rpc_types::{Parity, Signature}; -use reth_primitives::{transaction::legacy_parity, Signature as PrimitiveSignature, TxType}; +use reth_primitives::{transaction::legacy_parity, TxType}; /// Creates a new rpc signature from a legacy [primitive -/// signature](reth_primitives::Signature), using the give chain id to compute the signature's +/// signature](alloy_primitives::Signature), using the give chain id to compute the signature's /// recovery id. /// /// If the chain id is `Some`, the recovery id is computed according to [EIP-155](https://eips.ethereum.org/EIPS/eip-155). @@ -20,7 +20,7 @@ pub fn from_legacy_primitive_signature( } /// Creates a new rpc signature from a non-legacy [primitive -/// signature](reth_primitives::Signature). This sets the `v` value to `0` or `1` depending on +/// signature](alloy_primitives::Signature). This sets the `v` value to `0` or `1` depending on /// the signature's `odd_y_parity`. pub fn from_typed_primitive_signature(signature: PrimitiveSignature) -> Signature { Signature { @@ -32,7 +32,7 @@ pub fn from_typed_primitive_signature(signature: PrimitiveSignature) -> Signatur } /// Creates a new rpc signature from a legacy [primitive -/// signature](reth_primitives::Signature). +/// signature](alloy_primitives::Signature). /// /// The tx type is used to determine whether or not to use the `chain_id` to compute the /// signature's recovery id. diff --git a/crates/rpc/rpc/src/eth/helpers/signer.rs b/crates/rpc/rpc/src/eth/helpers/signer.rs index e59be0ac283..c6c60312730 100644 --- a/crates/rpc/rpc/src/eth/helpers/signer.rs +++ b/crates/rpc/rpc/src/eth/helpers/signer.rs @@ -6,11 +6,11 @@ use crate::EthApi; use alloy_dyn_abi::TypedData; use alloy_eips::eip2718::Decodable2718; use alloy_network::{eip2718::Encodable2718, EthereumWallet, TransactionBuilder}; -use alloy_primitives::{eip191_hash_message, Address, B256}; +use alloy_primitives::{eip191_hash_message, Address, Signature, B256}; use alloy_rpc_types_eth::TransactionRequest; use alloy_signer::SignerSync; use alloy_signer_local::PrivateKeySigner; -use reth_primitives::{Signature, TransactionSigned}; +use reth_primitives::TransactionSigned; use reth_rpc_eth_api::helpers::{signer::Result, AddDevSigners, EthSigner}; use reth_rpc_eth_types::SignError; diff --git a/crates/storage/provider/src/test_utils/blocks.rs b/crates/storage/provider/src/test_utils/blocks.rs index d524f47cc75..19f885e27a8 100644 --- a/crates/storage/provider/src/test_utils/blocks.rs +++ b/crates/storage/provider/src/test_utils/blocks.rs @@ -7,12 +7,13 @@ use alloy_primitives::{ }; use alloy_eips::eip4895::Withdrawal; +use alloy_primitives::Signature; use reth_db::tables; use reth_db_api::{database::Database, models::StoredBlockBodyIndices}; use reth_node_types::NodeTypes; use reth_primitives::{ Account, BlockBody, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, - Signature, Transaction, TransactionSigned, TxType, Withdrawals, + Transaction, TransactionSigned, TxType, Withdrawals, }; use reth_trie::root::{state_root_unhashed, storage_root_unhashed}; use revm::{db::BundleState, primitives::AccountInfo}; diff --git a/crates/transaction-pool/src/test_utils/mock.rs b/crates/transaction-pool/src/test_utils/mock.rs index a3cddaf0a71..c6143ff16c8 100644 --- a/crates/transaction-pool/src/test_utils/mock.rs +++ b/crates/transaction-pool/src/test_utils/mock.rs @@ -12,7 +12,7 @@ use alloy_consensus::{ TxEip1559, TxEip2930, TxEip4844, TxLegacy, }; use alloy_eips::{eip1559::MIN_PROTOCOL_BASE_FEE, eip2930::AccessList, eip4844::DATA_GAS_PER_BLOB}; -use alloy_primitives::{Address, Bytes, ChainId, TxHash, TxKind, B256, U256}; +use alloy_primitives::{Address, Bytes, ChainId, Signature, TxHash, TxKind, B256, U256}; use paste::paste; use rand::{ distributions::{Uniform, WeightedIndex}, @@ -20,7 +20,7 @@ use rand::{ }; use reth_primitives::{ transaction::TryFromRecoveredTransactionError, BlobTransactionSidecar, - BlobTransactionValidationError, PooledTransactionsElementEcRecovered, Signature, Transaction, + BlobTransactionValidationError, PooledTransactionsElementEcRecovered, Transaction, TransactionSigned, TransactionSignedEcRecovered, TxType, }; diff --git a/crates/transaction-pool/src/traits.rs b/crates/transaction-pool/src/traits.rs index 2667143b7c8..709b43e7132 100644 --- a/crates/transaction-pool/src/traits.rs +++ b/crates/transaction-pool/src/traits.rs @@ -1498,7 +1498,8 @@ mod tests { use super::*; use alloy_consensus::{TxEip1559, TxEip2930, TxEip4844, TxEip7702, TxLegacy}; use alloy_eips::eip4844::DATA_GAS_PER_BLOB; - use reth_primitives::{Signature, TransactionSigned}; + use alloy_primitives::Signature; + use reth_primitives::TransactionSigned; #[test] fn test_pool_size_invariants() { diff --git a/testing/testing-utils/src/generators.rs b/testing/testing-utils/src/generators.rs index 84225ea72cd..83fcf4484a0 100644 --- a/testing/testing-utils/src/generators.rs +++ b/testing/testing-utils/src/generators.rs @@ -464,8 +464,8 @@ mod tests { use super::*; use alloy_consensus::TxEip1559; use alloy_eips::eip2930::AccessList; - use alloy_primitives::{hex, Parity}; - use reth_primitives::{public_key_to_address, Signature}; + use alloy_primitives::{hex, Parity, Signature}; + use reth_primitives::public_key_to_address; use std::str::FromStr; #[test] From e3173407e103fd036ab6240d599668292cf1190a Mon Sep 17 00:00:00 2001 From: Steven <112043913+stevencartavia@users.noreply.github.com> Date: Tue, 5 Nov 2024 04:07:58 -0600 Subject: [PATCH 009/211] renamed OptimismEngineValidator to OpEngineValidator (#12312) --- crates/optimism/node/src/engine.rs | 26 +++++++++++++------------- crates/optimism/node/src/node.rs | 14 +++++++------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/crates/optimism/node/src/engine.rs b/crates/optimism/node/src/engine.rs index d956f0cd5cd..eb356e86e1d 100644 --- a/crates/optimism/node/src/engine.rs +++ b/crates/optimism/node/src/engine.rs @@ -58,11 +58,11 @@ impl PayloadTypes for OpPayloadTypes { /// Validator for Optimism engine API. #[derive(Debug, Clone)] -pub struct OptimismEngineValidator { +pub struct OpEngineValidator { chain_spec: Arc, } -impl OptimismEngineValidator { +impl OpEngineValidator { /// Instantiates a new validator. pub const fn new(chain_spec: Arc) -> Self { Self { chain_spec } @@ -111,7 +111,7 @@ pub fn validate_withdrawals_presence( Ok(()) } -impl EngineValidator for OptimismEngineValidator +impl EngineValidator for OpEngineValidator where Types: EngineTypes, { @@ -220,10 +220,10 @@ mod test { #[test] fn test_well_formed_attributes_pre_holocene() { - let validator = OptimismEngineValidator::new(get_chainspec(false)); + let validator = OpEngineValidator::new(get_chainspec(false)); let attributes = get_attributes(None, 1799999999); - let result = >::ensure_well_formed_attributes( &validator, EngineApiMessageVersion::V3, &attributes @@ -233,10 +233,10 @@ mod test { #[test] fn test_well_formed_attributes_holocene_no_eip1559_params() { - let validator = OptimismEngineValidator::new(get_chainspec(true)); + let validator = OpEngineValidator::new(get_chainspec(true)); let attributes = get_attributes(None, 1800000000); - let result = >::ensure_well_formed_attributes( &validator, EngineApiMessageVersion::V3, &attributes @@ -246,10 +246,10 @@ mod test { #[test] fn test_well_formed_attributes_holocene_eip1559_params_zero_denominator() { - let validator = OptimismEngineValidator::new(get_chainspec(true)); + let validator = OpEngineValidator::new(get_chainspec(true)); let attributes = get_attributes(Some(b64!("0000000000000008")), 1800000000); - let result = >::ensure_well_formed_attributes( &validator, EngineApiMessageVersion::V3, &attributes @@ -259,10 +259,10 @@ mod test { #[test] fn test_well_formed_attributes_holocene_valid() { - let validator = OptimismEngineValidator::new(get_chainspec(true)); + let validator = OpEngineValidator::new(get_chainspec(true)); let attributes = get_attributes(Some(b64!("0000000800000008")), 1800000000); - let result = >::ensure_well_formed_attributes( &validator, EngineApiMessageVersion::V3, &attributes @@ -272,10 +272,10 @@ mod test { #[test] fn test_well_formed_attributes_holocene_valid_all_zero() { - let validator = OptimismEngineValidator::new(get_chainspec(true)); + let validator = OpEngineValidator::new(get_chainspec(true)); let attributes = get_attributes(Some(b64!("0000000000000000")), 1800000000); - let result = >::ensure_well_formed_attributes( &validator, EngineApiMessageVersion::V3, &attributes diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index 7e6f1d0981c..14088e636f1 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -34,7 +34,7 @@ use reth_trie_db::MerklePatriciaTrie; use crate::{ args::RollupArgs, - engine::OptimismEngineValidator, + engine::OpEngineValidator, txpool::{OpTransactionPool, OpTransactionValidator}, OpEngineTypes, }; @@ -150,7 +150,7 @@ impl OptimismAddOns { impl NodeAddOns for OptimismAddOns where N: FullNodeComponents>, - OptimismEngineValidator: EngineValidator<::Engine>, + OpEngineValidator: EngineValidator<::Engine>, { type Handle = RpcHandle>; @@ -165,7 +165,7 @@ where impl RethRpcAddOns for OptimismAddOns where N: FullNodeComponents>, - OptimismEngineValidator: EngineValidator<::Engine>, + OpEngineValidator: EngineValidator<::Engine>, { type EthApi = OpEthApi; @@ -456,7 +456,7 @@ where } } -/// Builder for [`OptimismEngineValidator`]. +/// Builder for [`OpEngineValidator`]. #[derive(Debug, Default, Clone)] #[non_exhaustive] pub struct OptimismEngineValidatorBuilder; @@ -465,11 +465,11 @@ impl EngineValidatorBuilder for OptimismEngineValidatorBuilde where Types: NodeTypesWithEngine, Node: FullNodeComponents, - OptimismEngineValidator: EngineValidator, + OpEngineValidator: EngineValidator, { - type Validator = OptimismEngineValidator; + type Validator = OpEngineValidator; async fn build(self, ctx: &AddOnsContext<'_, Node>) -> eyre::Result { - Ok(OptimismEngineValidator::new(ctx.config.chain.clone())) + Ok(OpEngineValidator::new(ctx.config.chain.clone())) } } From 4222cbe6826715a5b7b70e8505984ffb613b7078 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 5 Nov 2024 12:11:04 +0100 Subject: [PATCH 010/211] chore: switch op to new engine (#12329) --- crates/optimism/bin/src/main.rs | 11 +++++++---- crates/optimism/node/src/args.rs | 14 +++++++++++--- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/crates/optimism/bin/src/main.rs b/crates/optimism/bin/src/main.rs index c6d3e32b7cf..6c440f43491 100644 --- a/crates/optimism/bin/src/main.rs +++ b/crates/optimism/bin/src/main.rs @@ -23,10 +23,13 @@ fn main() { if let Err(err) = Cli::::parse().run(|builder, rollup_args| async move { - let enable_engine2 = rollup_args.experimental; + if rollup_args.experimental { + tracing::warn!(target: "reth::cli", "Experimental engine is default now, and the --engine.experimental flag is deprecated. To enable the legacy functionality, use --engine.legacy."); + } + let use_legacy_engine = rollup_args.legacy; let sequencer_http_arg = rollup_args.sequencer_http.clone(); - match enable_engine2 { - true => { + match use_legacy_engine { + false => { let engine_tree_config = TreeConfig::default() .with_persistence_threshold(rollup_args.persistence_threshold) .with_memory_block_buffer_target(rollup_args.memory_block_buffer_target); @@ -46,7 +49,7 @@ fn main() { handle.node_exit_future.await } - false => { + true => { let handle = builder.node(OptimismNode::new(rollup_args.clone())).launch().await?; diff --git a/crates/optimism/node/src/args.rs b/crates/optimism/node/src/args.rs index 54be83dc510..b84e98d28b1 100644 --- a/crates/optimism/node/src/args.rs +++ b/crates/optimism/node/src/args.rs @@ -38,16 +38,23 @@ pub struct RollupArgs { #[arg(long = "rollup.discovery.v4", default_value = "false")] pub discovery_v4: bool, - /// Enable the engine2 experimental features on op-reth binary + /// Enable the experimental engine features on reth binary + /// + /// DEPRECATED: experimental engine is default now, use --engine.legacy to enable the legacy + /// functionality #[arg(long = "engine.experimental", default_value = "false")] pub experimental: bool, + /// Enable the legacy engine on reth binary + #[arg(long = "engine.legacy", default_value = "false")] + pub legacy: bool, + /// Configure persistence threshold for engine experimental. - #[arg(long = "engine.persistence-threshold", requires = "experimental", default_value_t = DEFAULT_PERSISTENCE_THRESHOLD)] + #[arg(long = "engine.persistence-threshold", conflicts_with = "legacy", default_value_t = DEFAULT_PERSISTENCE_THRESHOLD)] pub persistence_threshold: u64, /// Configure the target number of blocks to keep in memory. - #[arg(long = "engine.memory-block-buffer-target", requires = "experimental", default_value_t = DEFAULT_MEMORY_BLOCK_BUFFER_TARGET)] + #[arg(long = "engine.memory-block-buffer-target", conflicts_with = "legacy", default_value_t = DEFAULT_MEMORY_BLOCK_BUFFER_TARGET)] pub memory_block_buffer_target: u64, } @@ -60,6 +67,7 @@ impl Default for RollupArgs { compute_pending_block: false, discovery_v4: false, experimental: false, + legacy: false, persistence_threshold: DEFAULT_PERSISTENCE_THRESHOLD, memory_block_buffer_target: DEFAULT_MEMORY_BLOCK_BUFFER_TARGET, } From 556995fc5d8df8f6614a3cd2a7fc152cac3d3efe Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 5 Nov 2024 12:23:20 +0100 Subject: [PATCH 011/211] chore: limit initial status size (#12324) --- crates/net/eth-wire/src/ethstream.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/net/eth-wire/src/ethstream.rs b/crates/net/eth-wire/src/ethstream.rs index 74f3fab2be6..8ae599b6792 100644 --- a/crates/net/eth-wire/src/ethstream.rs +++ b/crates/net/eth-wire/src/ethstream.rs @@ -21,6 +21,9 @@ use tracing::{debug, trace}; // https://github.com/ethereum/go-ethereum/blob/30602163d5d8321fbc68afdcbbaf2362b2641bde/eth/protocols/eth/protocol.go#L50 pub const MAX_MESSAGE_SIZE: usize = 10 * 1024 * 1024; +/// [`MAX_STATUS_SIZE`] is the maximum cap on the size of the initial status message +pub(crate) const MAX_STATUS_SIZE: usize = 500 * 1024; + /// An un-authenticated [`EthStream`]. This is consumed and returns a [`EthStream`] after the /// `Status` handshake is completed. #[pin_project] @@ -97,7 +100,7 @@ where } }?; - if their_msg.len() > MAX_MESSAGE_SIZE { + if their_msg.len() > MAX_STATUS_SIZE { self.inner.disconnect(DisconnectReason::ProtocolBreach).await?; return Err(EthStreamError::MessageTooBig(their_msg.len())) } From 441ddbf0858e809556cbb6e85cde860df592c8b2 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Tue, 5 Nov 2024 12:37:56 +0100 Subject: [PATCH 012/211] primitives: rm more alloy block reexports (#12308) --- Cargo.lock | 3 ++- crates/optimism/node/src/txpool.rs | 2 +- crates/optimism/rpc/src/eth/pending_block.rs | 5 ++--- crates/payload/basic/src/lib.rs | 6 ++---- crates/primitives/src/block.rs | 8 +++++--- crates/primitives/src/lib.rs | 5 +---- crates/rpc/rpc-api/Cargo.toml | 1 - crates/rpc/rpc-api/src/debug.rs | 3 +-- crates/rpc/rpc-builder/tests/it/http.rs | 4 ++-- crates/rpc/rpc-eth-api/src/core.rs | 3 +-- crates/rpc/rpc-eth-api/src/helpers/state.rs | 6 +++--- crates/rpc/rpc-eth-types/src/gas_oracle.rs | 2 +- crates/rpc/rpc-eth-types/src/pending_block.rs | 4 ++-- crates/rpc/rpc-testing-util/src/trace.rs | 2 +- crates/rpc/rpc/src/debug.rs | 4 ++-- crates/rpc/rpc/src/engine.rs | 3 +-- crates/rpc/rpc/src/eth/core.rs | 5 +++-- crates/rpc/rpc/src/otterscan.rs | 3 +-- crates/transaction-pool/src/maintain.rs | 3 ++- examples/custom-inspector/Cargo.toml | 1 + examples/custom-inspector/src/main.rs | 2 +- examples/custom-payload-builder/Cargo.toml | 1 + examples/custom-payload-builder/src/generator.rs | 3 ++- 23 files changed, 38 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9d40ebfb2c7..7c0c4f318b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2890,6 +2890,7 @@ dependencies = [ name = "example-custom-inspector" version = "0.0.0" dependencies = [ + "alloy-eips", "alloy-primitives", "alloy-rpc-types", "clap", @@ -2913,6 +2914,7 @@ dependencies = [ name = "example-custom-payload-builder" version = "0.0.0" dependencies = [ + "alloy-eips", "alloy-primitives", "eyre", "futures-util", @@ -8700,7 +8702,6 @@ dependencies = [ "jsonrpsee", "reth-engine-primitives", "reth-network-peers", - "reth-primitives", "reth-rpc-eth-api", "serde", "serde_with", diff --git a/crates/optimism/node/src/txpool.rs b/crates/optimism/node/src/txpool.rs index 011654909eb..b1255a987e9 100644 --- a/crates/optimism/node/src/txpool.rs +++ b/crates/optimism/node/src/txpool.rs @@ -74,7 +74,7 @@ where pub fn new(inner: EthTransactionValidator) -> Self { let this = Self::with_block_info(inner, OpL1BlockInfo::default()); if let Ok(Some(block)) = - this.inner.client().block_by_number_or_tag(reth_primitives::BlockNumberOrTag::Latest) + this.inner.client().block_by_number_or_tag(alloy_eips::BlockNumberOrTag::Latest) { // genesis block has no txs, so we can't extract L1 info, we set the block info to empty // so that we will accept txs into the pool before the first block diff --git a/crates/optimism/rpc/src/eth/pending_block.rs b/crates/optimism/rpc/src/eth/pending_block.rs index 3b3b7845cc1..c90b3f7b794 100644 --- a/crates/optimism/rpc/src/eth/pending_block.rs +++ b/crates/optimism/rpc/src/eth/pending_block.rs @@ -1,12 +1,11 @@ //! Loads OP pending block for a RPC response. +use alloy_eips::BlockNumberOrTag; use alloy_primitives::{BlockNumber, B256}; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_evm::ConfigureEvm; use reth_optimism_consensus::calculate_receipt_root_no_memo_optimism; -use reth_primitives::{ - revm_primitives::BlockEnv, BlockNumberOrTag, Header, Receipt, SealedBlockWithSenders, -}; +use reth_primitives::{revm_primitives::BlockEnv, Header, Receipt, SealedBlockWithSenders}; use reth_provider::{ BlockReader, BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, ExecutionOutcome, ReceiptProvider, StateProviderFactory, diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index 7b1de980ce9..d6dcdf114b0 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -10,7 +10,7 @@ use crate::metrics::PayloadBuilderMetrics; use alloy_consensus::constants::EMPTY_WITHDRAWALS; -use alloy_eips::merge::SLOT_DURATION; +use alloy_eips::{merge::SLOT_DURATION, BlockNumberOrTag}; use alloy_primitives::{Bytes, B256, U256}; use futures_core::ready; use futures_util::FutureExt; @@ -20,9 +20,7 @@ use reth_payload_builder::{KeepPayloadJobAlive, PayloadId, PayloadJob, PayloadJo use reth_payload_primitives::{ BuiltPayload, PayloadBuilderAttributes, PayloadBuilderError, PayloadKind, }; -use reth_primitives::{ - constants::RETH_CLIENT_VERSION, proofs, BlockNumberOrTag, SealedHeader, Withdrawals, -}; +use reth_primitives::{constants::RETH_CLIENT_VERSION, proofs, SealedHeader, Withdrawals}; use reth_provider::{ BlockReaderIdExt, BlockSource, CanonStateNotification, ProviderError, StateProviderFactory, }; diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index b9f43df5d7c..5f32728489c 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -2,7 +2,6 @@ use crate::{ GotExpected, Header, SealedHeader, TransactionSigned, TransactionSignedEcRecovered, Withdrawals, }; use alloc::vec::Vec; -pub use alloy_eips::eip1898::{BlockNumberOrTag, ForkBlock, RpcBlockHash}; use alloy_eips::eip2718::Encodable2718; use alloy_primitives::{Address, Bytes, Sealable, B256}; use alloy_rlp::{Decodable, Encodable, RlpDecodable, RlpEncodable}; @@ -904,8 +903,11 @@ pub(super) mod serde_bincode_compat { #[cfg(test)] mod tests { - use super::{BlockNumberOrTag::*, *}; - use alloy_eips::{eip1898::HexStringMissingPrefixError, BlockId}; + use super::*; + use alloy_eips::{ + eip1898::HexStringMissingPrefixError, BlockId, BlockNumberOrTag, BlockNumberOrTag::*, + RpcBlockHash, + }; use alloy_primitives::hex_literal::hex; use alloy_rlp::{Decodable, Encodable}; use std::str::FromStr; diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index be592e1c167..9b121a56fa4 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -33,10 +33,7 @@ pub use reth_static_file_types as static_file; pub mod transaction; #[cfg(any(test, feature = "arbitrary"))] pub use block::{generate_valid_header, valid_header_strategy}; -pub use block::{ - Block, BlockBody, BlockNumberOrTag, BlockWithSenders, ForkBlock, RpcBlockHash, SealedBlock, - SealedBlockWithSenders, -}; +pub use block::{Block, BlockBody, BlockWithSenders, SealedBlock, SealedBlockWithSenders}; #[cfg(feature = "reth-codec")] pub use compression::*; pub use constants::HOLESKY_GENESIS_HASH; diff --git a/crates/rpc/rpc-api/Cargo.toml b/crates/rpc/rpc-api/Cargo.toml index 60146e8b2c2..75c06a2554c 100644 --- a/crates/rpc/rpc-api/Cargo.toml +++ b/crates/rpc/rpc-api/Cargo.toml @@ -13,7 +13,6 @@ workspace = true [dependencies] # reth -reth-primitives.workspace = true reth-rpc-eth-api.workspace = true reth-engine-primitives.workspace = true reth-network-peers.workspace = true diff --git a/crates/rpc/rpc-api/src/debug.rs b/crates/rpc/rpc-api/src/debug.rs index 162699c6ebc..d1837787d54 100644 --- a/crates/rpc/rpc-api/src/debug.rs +++ b/crates/rpc/rpc-api/src/debug.rs @@ -1,4 +1,4 @@ -use alloy_eips::BlockId; +use alloy_eips::{BlockId, BlockNumberOrTag}; use alloy_primitives::{Address, Bytes, B256}; use alloy_rpc_types::{Block, Bundle, StateContext}; use alloy_rpc_types_debug::ExecutionWitness; @@ -7,7 +7,6 @@ use alloy_rpc_types_trace::geth::{ BlockTraceResult, GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace, TraceResult, }; use jsonrpsee::{core::RpcResult, proc_macros::rpc}; -use reth_primitives::BlockNumberOrTag; /// Debug rpc interface. #[cfg_attr(not(feature = "client"), rpc(server, namespace = "debug"))] diff --git a/crates/rpc/rpc-builder/tests/it/http.rs b/crates/rpc/rpc-builder/tests/it/http.rs index 5c33a5d34df..b5faa71cc5e 100644 --- a/crates/rpc/rpc-builder/tests/it/http.rs +++ b/crates/rpc/rpc-builder/tests/it/http.rs @@ -2,7 +2,7 @@ //! Standalone http tests use crate::utils::{launch_http, launch_http_ws, launch_ws}; -use alloy_eips::BlockId; +use alloy_eips::{BlockId, BlockNumberOrTag}; use alloy_primitives::{hex_literal::hex, Address, Bytes, TxHash, B256, B64, U256, U64}; use alloy_rpc_types_eth::{ transaction::TransactionRequest, Block, FeeHistory, Filter, Index, Log, @@ -19,7 +19,7 @@ use jsonrpsee::{ types::error::ErrorCode, }; use reth_network_peers::NodeRecord; -use reth_primitives::{BlockNumberOrTag, Receipt}; +use reth_primitives::Receipt; use reth_rpc_api::{ clients::{AdminApiClient, EthApiClient}, DebugApiClient, EthFilterApiClient, NetApiClient, OtterscanClient, TraceApiClient, diff --git a/crates/rpc/rpc-eth-api/src/core.rs b/crates/rpc/rpc-eth-api/src/core.rs index 185297c2255..a89364a15db 100644 --- a/crates/rpc/rpc-eth-api/src/core.rs +++ b/crates/rpc/rpc-eth-api/src/core.rs @@ -1,7 +1,7 @@ //! Implementation of the [`jsonrpsee`] generated [`EthApiServer`] trait. Handles RPC requests for //! the `eth_` namespace. use alloy_dyn_abi::TypedData; -use alloy_eips::{eip2930::AccessListResult, BlockId}; +use alloy_eips::{eip2930::AccessListResult, BlockId, BlockNumberOrTag}; use alloy_json_rpc::RpcObject; use alloy_primitives::{Address, Bytes, B256, B64, U256, U64}; use alloy_rpc_types::{ @@ -13,7 +13,6 @@ use alloy_rpc_types::{ }; use alloy_rpc_types_eth::transaction::TransactionRequest; use jsonrpsee::{core::RpcResult, proc_macros::rpc}; -use reth_primitives::BlockNumberOrTag; use reth_rpc_server_types::{result::internal_rpc_err, ToRpcResult}; use tracing::trace; diff --git a/crates/rpc/rpc-eth-api/src/helpers/state.rs b/crates/rpc/rpc-eth-api/src/helpers/state.rs index d980b9114b1..702572064c5 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/state.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/state.rs @@ -30,7 +30,7 @@ pub trait EthState: LoadState + SpawnBlocking { /// Returns the number of transactions sent from an address at the given block identifier. /// - /// If this is [`BlockNumberOrTag::Pending`](reth_primitives::BlockNumberOrTag) then this will + /// If this is [`BlockNumberOrTag::Pending`](alloy_eips::BlockNumberOrTag) then this will /// look up the highest transaction in pool and return the next nonce (highest + 1). fn transaction_count( &self, @@ -184,7 +184,7 @@ pub trait LoadState: /// Returns the state at the given [`BlockId`] enum. /// - /// Note: if not [`BlockNumberOrTag::Pending`](reth_primitives::BlockNumberOrTag) then this + /// Note: if not [`BlockNumberOrTag::Pending`](alloy_eips::BlockNumberOrTag) then this /// will only return canonical state. See also fn state_at_block_id(&self, at: BlockId) -> Result { self.provider().state_by_block_id(at).map_err(Self::Error::from_eth_err) @@ -302,7 +302,7 @@ pub trait LoadState: /// Returns the number of transactions sent from an address at the given block identifier. /// - /// If this is [`BlockNumberOrTag::Pending`](reth_primitives::BlockNumberOrTag) then this will + /// If this is [`BlockNumberOrTag::Pending`](alloy_eips::BlockNumberOrTag) then this will /// look up the highest transaction in pool and return the next nonce (highest + 1). fn transaction_count( &self, diff --git a/crates/rpc/rpc-eth-types/src/gas_oracle.rs b/crates/rpc/rpc-eth-types/src/gas_oracle.rs index 065ac1acc20..9da373376bd 100644 --- a/crates/rpc/rpc-eth-types/src/gas_oracle.rs +++ b/crates/rpc/rpc-eth-types/src/gas_oracle.rs @@ -2,11 +2,11 @@ //! previous blocks. use alloy_consensus::constants::GWEI_TO_WEI; +use alloy_eips::BlockNumberOrTag; use alloy_primitives::{B256, U256}; use alloy_rpc_types::BlockId; use derive_more::{Deref, DerefMut, From, Into}; use itertools::Itertools; -use reth_primitives::BlockNumberOrTag; use reth_rpc_server_types::constants; use reth_storage_api::BlockReaderIdExt; use schnellru::{ByLength, LruMap}; diff --git a/crates/rpc/rpc-eth-types/src/pending_block.rs b/crates/rpc/rpc-eth-types/src/pending_block.rs index d3e7c4158ac..d8f413650a3 100644 --- a/crates/rpc/rpc-eth-types/src/pending_block.rs +++ b/crates/rpc/rpc-eth-types/src/pending_block.rs @@ -4,10 +4,10 @@ use std::time::Instant; -use alloy_eips::BlockId; +use alloy_eips::{BlockId, BlockNumberOrTag}; use alloy_primitives::B256; use derive_more::Constructor; -use reth_primitives::{BlockNumberOrTag, Receipt, SealedBlockWithSenders, SealedHeader}; +use reth_primitives::{Receipt, SealedBlockWithSenders, SealedHeader}; use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg}; /// Configured [`BlockEnv`] and [`CfgEnvWithHandlerCfg`] for a pending block. diff --git a/crates/rpc/rpc-testing-util/src/trace.rs b/crates/rpc/rpc-testing-util/src/trace.rs index efb1f3674e0..097d582df45 100644 --- a/crates/rpc/rpc-testing-util/src/trace.rs +++ b/crates/rpc/rpc-testing-util/src/trace.rs @@ -514,9 +514,9 @@ where #[cfg(test)] mod tests { use super::*; + use alloy_eips::BlockNumberOrTag; use alloy_rpc_types_trace::filter::TraceFilterMode; use jsonrpsee::http_client::HttpClientBuilder; - use reth_primitives::BlockNumberOrTag; const fn assert_is_stream(_: &St) {} diff --git a/crates/rpc/rpc/src/debug.rs b/crates/rpc/rpc/src/debug.rs index 6a73af69d92..7e4c8fb8230 100644 --- a/crates/rpc/rpc/src/debug.rs +++ b/crates/rpc/rpc/src/debug.rs @@ -1,4 +1,4 @@ -use alloy_eips::{eip2718::Encodable2718, BlockId}; +use alloy_eips::{eip2718::Encodable2718, BlockId, BlockNumberOrTag}; use alloy_primitives::{Address, Bytes, B256, U256}; use alloy_rlp::{Decodable, Encodable}; use alloy_rpc_types::{ @@ -19,7 +19,7 @@ use reth_evm::{ system_calls::SystemCaller, ConfigureEvmEnv, }; -use reth_primitives::{Block, BlockNumberOrTag, TransactionSignedEcRecovered}; +use reth_primitives::{Block, TransactionSignedEcRecovered}; use reth_provider::{ BlockReaderIdExt, ChainSpecProvider, HeaderProvider, StateProofProvider, StateProviderFactory, TransactionVariant, diff --git a/crates/rpc/rpc/src/engine.rs b/crates/rpc/rpc/src/engine.rs index 0ff90d39998..ac4de7c74e1 100644 --- a/crates/rpc/rpc/src/engine.rs +++ b/crates/rpc/rpc/src/engine.rs @@ -1,4 +1,4 @@ -use alloy_eips::BlockId; +use alloy_eips::{BlockId, BlockNumberOrTag}; use alloy_primitives::{Address, Bytes, B256, U256, U64}; use alloy_rpc_types::{ state::StateOverride, BlockOverrides, EIP1186AccountProofResponse, Filter, Log, SyncStatus, @@ -6,7 +6,6 @@ use alloy_rpc_types::{ use alloy_rpc_types_eth::transaction::TransactionRequest; use alloy_serde::JsonStorageKey; use jsonrpsee::core::RpcResult as Result; -use reth_primitives::BlockNumberOrTag; use reth_rpc_api::{EngineEthApiServer, EthApiServer, EthFilterApiServer}; /// Re-export for convenience pub use reth_rpc_engine_api::EngineApi; diff --git a/crates/rpc/rpc/src/eth/core.rs b/crates/rpc/rpc/src/eth/core.rs index 98ac9e9f409..c491ca21dfb 100644 --- a/crates/rpc/rpc/src/eth/core.rs +++ b/crates/rpc/rpc/src/eth/core.rs @@ -3,10 +3,10 @@ use std::sync::Arc; +use alloy_eips::BlockNumberOrTag; use alloy_network::Ethereum; use alloy_primitives::U256; use derive_more::Deref; -use reth_primitives::BlockNumberOrTag; use reth_provider::{BlockReaderIdExt, CanonStateSubscriptions, ChainSpecProvider}; use reth_rpc_eth_api::{ helpers::{EthSigner, SpawnBlocking}, @@ -400,13 +400,14 @@ impl EthApiInner Date: Tue, 5 Nov 2024 13:00:16 +0100 Subject: [PATCH 013/211] chore: 1.1.1 (#12334) --- Cargo.lock | 238 ++++++++++++++++++++++++++--------------------------- Cargo.toml | 2 +- 2 files changed, 120 insertions(+), 120 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7c0c4f318b0..d3fcd59e79f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2605,7 +2605,7 @@ dependencies = [ [[package]] name = "ef-tests" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -5368,7 +5368,7 @@ dependencies = [ [[package]] name = "op-reth" -version = "1.1.0" +version = "1.1.1" dependencies = [ "clap", "reth-cli-util", @@ -6296,7 +6296,7 @@ dependencies = [ [[package]] name = "reth" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6368,7 +6368,7 @@ dependencies = [ [[package]] name = "reth-auto-seal-consensus" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-primitives", @@ -6399,7 +6399,7 @@ dependencies = [ [[package]] name = "reth-basic-payload-builder" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6425,7 +6425,7 @@ dependencies = [ [[package]] name = "reth-beacon-consensus" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-genesis", @@ -6477,7 +6477,7 @@ dependencies = [ [[package]] name = "reth-bench" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-json-rpc", @@ -6512,7 +6512,7 @@ dependencies = [ [[package]] name = "reth-blockchain-tree" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6550,7 +6550,7 @@ dependencies = [ [[package]] name = "reth-blockchain-tree-api" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-primitives", @@ -6563,7 +6563,7 @@ dependencies = [ [[package]] name = "reth-chain-state" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6592,7 +6592,7 @@ dependencies = [ [[package]] name = "reth-chainspec" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-chains", "alloy-consensus", @@ -6613,7 +6613,7 @@ dependencies = [ [[package]] name = "reth-cli" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-genesis", "clap", @@ -6626,7 +6626,7 @@ dependencies = [ [[package]] name = "reth-cli-commands" -version = "1.1.0" +version = "1.1.1" dependencies = [ "ahash", "alloy-eips", @@ -6692,7 +6692,7 @@ dependencies = [ [[package]] name = "reth-cli-runner" -version = "1.1.0" +version = "1.1.1" dependencies = [ "reth-tasks", "tokio", @@ -6701,7 +6701,7 @@ dependencies = [ [[package]] name = "reth-cli-util" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-primitives", @@ -6719,7 +6719,7 @@ dependencies = [ [[package]] name = "reth-codecs" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6741,7 +6741,7 @@ dependencies = [ [[package]] name = "reth-codecs-derive" -version = "1.1.0" +version = "1.1.1" dependencies = [ "convert_case", "proc-macro2", @@ -6752,7 +6752,7 @@ dependencies = [ [[package]] name = "reth-config" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "eyre", @@ -6768,7 +6768,7 @@ dependencies = [ [[package]] name = "reth-consensus" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-primitives", @@ -6779,7 +6779,7 @@ dependencies = [ [[package]] name = "reth-consensus-common" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6795,7 +6795,7 @@ dependencies = [ [[package]] name = "reth-consensus-debug-client" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6818,7 +6818,7 @@ dependencies = [ [[package]] name = "reth-db" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "arbitrary", @@ -6858,7 +6858,7 @@ dependencies = [ [[package]] name = "reth-db-api" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-genesis", "alloy-primitives", @@ -6885,7 +6885,7 @@ dependencies = [ [[package]] name = "reth-db-common" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-genesis", @@ -6914,7 +6914,7 @@ dependencies = [ [[package]] name = "reth-db-models" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "arbitrary", @@ -6930,7 +6930,7 @@ dependencies = [ [[package]] name = "reth-discv4" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -6957,7 +6957,7 @@ dependencies = [ [[package]] name = "reth-discv5" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -6981,7 +6981,7 @@ dependencies = [ [[package]] name = "reth-dns-discovery" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-chains", "alloy-primitives", @@ -7009,7 +7009,7 @@ dependencies = [ [[package]] name = "reth-downloaders" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-primitives", @@ -7046,7 +7046,7 @@ dependencies = [ [[package]] name = "reth-e2e-test-utils" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7082,7 +7082,7 @@ dependencies = [ [[package]] name = "reth-ecies" -version = "1.1.0" +version = "1.1.1" dependencies = [ "aes", "alloy-primitives", @@ -7112,7 +7112,7 @@ dependencies = [ [[package]] name = "reth-engine-local" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "alloy-rpc-types-engine", @@ -7142,7 +7142,7 @@ dependencies = [ [[package]] name = "reth-engine-primitives" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "reth-execution-types", @@ -7154,7 +7154,7 @@ dependencies = [ [[package]] name = "reth-engine-service" -version = "1.1.0" +version = "1.1.1" dependencies = [ "futures", "pin-project", @@ -7182,7 +7182,7 @@ dependencies = [ [[package]] name = "reth-engine-tree" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-primitives", @@ -7230,7 +7230,7 @@ dependencies = [ [[package]] name = "reth-engine-util" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7262,7 +7262,7 @@ dependencies = [ [[package]] name = "reth-errors" -version = "1.1.0" +version = "1.1.1" dependencies = [ "reth-blockchain-tree-api", "reth-consensus", @@ -7274,7 +7274,7 @@ dependencies = [ [[package]] name = "reth-eth-wire" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-primitives", @@ -7309,7 +7309,7 @@ dependencies = [ [[package]] name = "reth-eth-wire-types" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-chains", "alloy-consensus", @@ -7332,7 +7332,7 @@ dependencies = [ [[package]] name = "reth-ethereum-cli" -version = "1.1.0" +version = "1.1.1" dependencies = [ "clap", "eyre", @@ -7343,7 +7343,7 @@ dependencies = [ [[package]] name = "reth-ethereum-consensus" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7357,7 +7357,7 @@ dependencies = [ [[package]] name = "reth-ethereum-engine-primitives" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-primitives", @@ -7376,7 +7376,7 @@ dependencies = [ [[package]] name = "reth-ethereum-forks" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-chains", "alloy-consensus", @@ -7396,7 +7396,7 @@ dependencies = [ [[package]] name = "reth-ethereum-payload-builder" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7422,7 +7422,7 @@ dependencies = [ [[package]] name = "reth-etl" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "rayon", @@ -7432,7 +7432,7 @@ dependencies = [ [[package]] name = "reth-evm" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7459,7 +7459,7 @@ dependencies = [ [[package]] name = "reth-evm-ethereum" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7482,7 +7482,7 @@ dependencies = [ [[package]] name = "reth-execution-errors" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-primitives", @@ -7497,7 +7497,7 @@ dependencies = [ [[package]] name = "reth-execution-types" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-primitives", @@ -7514,7 +7514,7 @@ dependencies = [ [[package]] name = "reth-exex" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7558,7 +7558,7 @@ dependencies = [ [[package]] name = "reth-exex-test-utils" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "eyre", @@ -7591,7 +7591,7 @@ dependencies = [ [[package]] name = "reth-exex-types" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-primitives", @@ -7607,7 +7607,7 @@ dependencies = [ [[package]] name = "reth-fs-util" -version = "1.1.0" +version = "1.1.1" dependencies = [ "serde", "serde_json", @@ -7616,7 +7616,7 @@ dependencies = [ [[package]] name = "reth-invalid-block-hooks" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -7640,7 +7640,7 @@ dependencies = [ [[package]] name = "reth-ipc" -version = "1.1.0" +version = "1.1.1" dependencies = [ "async-trait", "bytes", @@ -7662,7 +7662,7 @@ dependencies = [ [[package]] name = "reth-libmdbx" -version = "1.1.0" +version = "1.1.1" dependencies = [ "bitflags 2.6.0", "byteorder", @@ -7683,7 +7683,7 @@ dependencies = [ [[package]] name = "reth-mdbx-sys" -version = "1.1.0" +version = "1.1.1" dependencies = [ "bindgen", "cc", @@ -7691,7 +7691,7 @@ dependencies = [ [[package]] name = "reth-metrics" -version = "1.1.0" +version = "1.1.1" dependencies = [ "futures", "metrics", @@ -7702,14 +7702,14 @@ dependencies = [ [[package]] name = "reth-net-banlist" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", ] [[package]] name = "reth-net-nat" -version = "1.1.0" +version = "1.1.1" dependencies = [ "futures-util", "if-addrs", @@ -7723,7 +7723,7 @@ dependencies = [ [[package]] name = "reth-network" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7783,7 +7783,7 @@ dependencies = [ [[package]] name = "reth-network-api" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "alloy-rpc-types-admin", @@ -7805,7 +7805,7 @@ dependencies = [ [[package]] name = "reth-network-p2p" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-primitives", @@ -7825,7 +7825,7 @@ dependencies = [ [[package]] name = "reth-network-peers" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -7841,7 +7841,7 @@ dependencies = [ [[package]] name = "reth-network-types" -version = "1.1.0" +version = "1.1.1" dependencies = [ "humantime-serde", "reth-ethereum-forks", @@ -7854,7 +7854,7 @@ dependencies = [ [[package]] name = "reth-nippy-jar" -version = "1.1.0" +version = "1.1.1" dependencies = [ "anyhow", "bincode", @@ -7872,7 +7872,7 @@ dependencies = [ [[package]] name = "reth-node-api" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-rpc-types-engine", "eyre", @@ -7893,7 +7893,7 @@ dependencies = [ [[package]] name = "reth-node-builder" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "alloy-rpc-types", @@ -7958,7 +7958,7 @@ dependencies = [ [[package]] name = "reth-node-core" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8007,7 +8007,7 @@ dependencies = [ [[package]] name = "reth-node-ethereum" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-contract", @@ -8053,7 +8053,7 @@ dependencies = [ [[package]] name = "reth-node-events" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8076,7 +8076,7 @@ dependencies = [ [[package]] name = "reth-node-metrics" -version = "1.1.0" +version = "1.1.1" dependencies = [ "eyre", "http", @@ -8101,7 +8101,7 @@ dependencies = [ [[package]] name = "reth-node-types" -version = "1.1.0" +version = "1.1.1" dependencies = [ "reth-chainspec", "reth-db-api", @@ -8113,7 +8113,7 @@ dependencies = [ [[package]] name = "reth-optimism-chainspec" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-chains", "alloy-consensus", @@ -8133,7 +8133,7 @@ dependencies = [ [[package]] name = "reth-optimism-cli" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -8179,7 +8179,7 @@ dependencies = [ [[package]] name = "reth-optimism-consensus" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -8195,7 +8195,7 @@ dependencies = [ [[package]] name = "reth-optimism-evm" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8222,7 +8222,7 @@ dependencies = [ [[package]] name = "reth-optimism-forks" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-chains", "alloy-primitives", @@ -8233,7 +8233,7 @@ dependencies = [ [[package]] name = "reth-optimism-node" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-genesis", @@ -8278,7 +8278,7 @@ dependencies = [ [[package]] name = "reth-optimism-payload-builder" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8312,7 +8312,7 @@ dependencies = [ [[package]] name = "reth-optimism-primitives" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -8321,7 +8321,7 @@ dependencies = [ [[package]] name = "reth-optimism-rpc" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8361,7 +8361,7 @@ dependencies = [ [[package]] name = "reth-optimism-storage" -version = "1.1.0" +version = "1.1.1" dependencies = [ "reth-codecs", "reth-db-api", @@ -8372,7 +8372,7 @@ dependencies = [ [[package]] name = "reth-payload-builder" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "alloy-rpc-types", @@ -8393,7 +8393,7 @@ dependencies = [ [[package]] name = "reth-payload-primitives" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-primitives", @@ -8415,7 +8415,7 @@ dependencies = [ [[package]] name = "reth-payload-validator" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-rpc-types", "reth-chainspec", @@ -8425,7 +8425,7 @@ dependencies = [ [[package]] name = "reth-primitives" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8469,7 +8469,7 @@ dependencies = [ [[package]] name = "reth-primitives-traits" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8497,7 +8497,7 @@ dependencies = [ [[package]] name = "reth-provider" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8546,7 +8546,7 @@ dependencies = [ [[package]] name = "reth-prune" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "assert_matches", @@ -8575,7 +8575,7 @@ dependencies = [ [[package]] name = "reth-prune-types" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "arbitrary", @@ -8595,7 +8595,7 @@ dependencies = [ [[package]] name = "reth-revm" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8612,7 +8612,7 @@ dependencies = [ [[package]] name = "reth-rpc" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-dyn-abi", @@ -8683,7 +8683,7 @@ dependencies = [ [[package]] name = "reth-rpc-api" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-json-rpc", @@ -8709,7 +8709,7 @@ dependencies = [ [[package]] name = "reth-rpc-api-testing-util" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-primitives", @@ -8729,7 +8729,7 @@ dependencies = [ [[package]] name = "reth-rpc-builder" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-primitives", @@ -8779,7 +8779,7 @@ dependencies = [ [[package]] name = "reth-rpc-engine-api" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-primitives", @@ -8815,7 +8815,7 @@ dependencies = [ [[package]] name = "reth-rpc-eth-api" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-dyn-abi", @@ -8857,7 +8857,7 @@ dependencies = [ [[package]] name = "reth-rpc-eth-types" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8900,7 +8900,7 @@ dependencies = [ [[package]] name = "reth-rpc-layer" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-rpc-types-engine", "http", @@ -8915,7 +8915,7 @@ dependencies = [ [[package]] name = "reth-rpc-server-types" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-primitives", @@ -8930,7 +8930,7 @@ dependencies = [ [[package]] name = "reth-rpc-types-compat" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8947,7 +8947,7 @@ dependencies = [ [[package]] name = "reth-stages" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -8996,7 +8996,7 @@ dependencies = [ [[package]] name = "reth-stages-api" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "aquamarine", @@ -9024,7 +9024,7 @@ dependencies = [ [[package]] name = "reth-stages-types" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "arbitrary", @@ -9041,7 +9041,7 @@ dependencies = [ [[package]] name = "reth-static-file" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "assert_matches", @@ -9063,7 +9063,7 @@ dependencies = [ [[package]] name = "reth-static-file-types" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "clap", @@ -9074,7 +9074,7 @@ dependencies = [ [[package]] name = "reth-storage-api" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -9093,7 +9093,7 @@ dependencies = [ [[package]] name = "reth-storage-errors" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-eips", "alloy-primitives", @@ -9105,7 +9105,7 @@ dependencies = [ [[package]] name = "reth-tasks" -version = "1.1.0" +version = "1.1.1" dependencies = [ "auto_impl", "dyn-clone", @@ -9122,7 +9122,7 @@ dependencies = [ [[package]] name = "reth-testing-utils" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -9135,7 +9135,7 @@ dependencies = [ [[package]] name = "reth-tokio-util" -version = "1.1.0" +version = "1.1.1" dependencies = [ "tokio", "tokio-stream", @@ -9144,7 +9144,7 @@ dependencies = [ [[package]] name = "reth-tracing" -version = "1.1.0" +version = "1.1.1" dependencies = [ "clap", "eyre", @@ -9158,7 +9158,7 @@ dependencies = [ [[package]] name = "reth-transaction-pool" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -9203,7 +9203,7 @@ dependencies = [ [[package]] name = "reth-trie" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -9232,7 +9232,7 @@ dependencies = [ [[package]] name = "reth-trie-common" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-genesis", @@ -9256,7 +9256,7 @@ dependencies = [ [[package]] name = "reth-trie-db" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -9285,7 +9285,7 @@ dependencies = [ [[package]] name = "reth-trie-parallel" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -9311,7 +9311,7 @@ dependencies = [ [[package]] name = "reth-trie-sparse" -version = "1.1.0" +version = "1.1.1" dependencies = [ "alloy-primitives", "alloy-rlp", diff --git a/Cargo.toml b/Cargo.toml index 8c5cf7b0cd5..10d39b11b99 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace.package] -version = "1.1.0" +version = "1.1.1" edition = "2021" rust-version = "1.82" license = "MIT OR Apache-2.0" From 15c230bac20e2b1b3532c8b0d470e815fbc0cc22 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Tue, 5 Nov 2024 13:17:28 +0100 Subject: [PATCH 014/211] primitives: rm alloy `BlobTransactionValidationError` reexport (#12311) --- crates/primitives/src/lib.rs | 3 --- crates/primitives/src/transaction/mod.rs | 2 -- crates/primitives/src/transaction/sidecar.rs | 5 +---- crates/transaction-pool/src/error.rs | 3 ++- crates/transaction-pool/src/test_utils/mock.rs | 12 ++++++++---- crates/transaction-pool/src/traits.rs | 10 +++++++--- 6 files changed, 18 insertions(+), 17 deletions(-) diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 9b121a56fa4..09610bf7458 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -51,9 +51,6 @@ pub use transaction::{ PooledTransactionsElementEcRecovered, }; -#[cfg(feature = "c-kzg")] -pub use transaction::BlobTransactionValidationError; - pub use transaction::{ util::secp256k1::{public_key_to_address, recover_signer_unchecked, sign_message}, InvalidTransactionError, Transaction, TransactionMeta, TransactionSigned, diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index adbd8f0d09c..aa6aaa2d83e 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -31,8 +31,6 @@ pub use error::{ }; pub use meta::TransactionMeta; pub use pooled::{PooledTransactionsElement, PooledTransactionsElementEcRecovered}; -#[cfg(feature = "c-kzg")] -pub use sidecar::BlobTransactionValidationError; pub use sidecar::{BlobTransaction, BlobTransactionSidecar}; pub use compat::FillTxEnv; diff --git a/crates/primitives/src/transaction/sidecar.rs b/crates/primitives/src/transaction/sidecar.rs index aa473ef8a3f..e7ff7a9b508 100644 --- a/crates/primitives/src/transaction/sidecar.rs +++ b/crates/primitives/src/transaction/sidecar.rs @@ -9,9 +9,6 @@ use serde::{Deserialize, Serialize}; #[doc(inline)] pub use alloy_eips::eip4844::BlobTransactionSidecar; -#[cfg(feature = "c-kzg")] -pub use alloy_eips::eip4844::BlobTransactionValidationError; - /// A response to `GetPooledTransactions` that includes blob data, their commitments, and their /// corresponding proofs. /// @@ -58,7 +55,7 @@ impl BlobTransaction { pub fn validate( &self, proof_settings: &c_kzg::KzgSettings, - ) -> Result<(), BlobTransactionValidationError> { + ) -> Result<(), alloy_eips::eip4844::BlobTransactionValidationError> { self.transaction.validate_blob(proof_settings) } diff --git a/crates/transaction-pool/src/error.rs b/crates/transaction-pool/src/error.rs index a4766a89d5c..f71bf018807 100644 --- a/crates/transaction-pool/src/error.rs +++ b/crates/transaction-pool/src/error.rs @@ -1,7 +1,8 @@ //! Transaction pool errors +use alloy_eips::eip4844::BlobTransactionValidationError; use alloy_primitives::{Address, TxHash, U256}; -use reth_primitives::{BlobTransactionValidationError, InvalidTransactionError}; +use reth_primitives::InvalidTransactionError; /// Transaction pool result type. pub type PoolResult = Result; diff --git a/crates/transaction-pool/src/test_utils/mock.rs b/crates/transaction-pool/src/test_utils/mock.rs index c6143ff16c8..a272e8d00ed 100644 --- a/crates/transaction-pool/src/test_utils/mock.rs +++ b/crates/transaction-pool/src/test_utils/mock.rs @@ -11,7 +11,11 @@ use alloy_consensus::{ constants::{EIP1559_TX_TYPE_ID, EIP2930_TX_TYPE_ID, EIP4844_TX_TYPE_ID, LEGACY_TX_TYPE_ID}, TxEip1559, TxEip2930, TxEip4844, TxLegacy, }; -use alloy_eips::{eip1559::MIN_PROTOCOL_BASE_FEE, eip2930::AccessList, eip4844::DATA_GAS_PER_BLOB}; +use alloy_eips::{ + eip1559::MIN_PROTOCOL_BASE_FEE, + eip2930::AccessList, + eip4844::{BlobTransactionValidationError, DATA_GAS_PER_BLOB}, +}; use alloy_primitives::{Address, Bytes, ChainId, Signature, TxHash, TxKind, B256, U256}; use paste::paste; use rand::{ @@ -20,8 +24,8 @@ use rand::{ }; use reth_primitives::{ transaction::TryFromRecoveredTransactionError, BlobTransactionSidecar, - BlobTransactionValidationError, PooledTransactionsElementEcRecovered, Transaction, - TransactionSigned, TransactionSignedEcRecovered, TxType, + PooledTransactionsElementEcRecovered, Transaction, TransactionSigned, + TransactionSignedEcRecovered, TxType, }; use std::{ops::Range, sync::Arc, time::Instant, vec::IntoIter}; @@ -761,7 +765,7 @@ impl EthPoolTransaction for MockTransaction { &self, _blob: &BlobTransactionSidecar, _settings: &reth_primitives::kzg::KzgSettings, - ) -> Result<(), reth_primitives::BlobTransactionValidationError> { + ) -> Result<(), alloy_eips::eip4844::BlobTransactionValidationError> { match &self { Self::Eip4844 { .. } => Ok(()), _ => Err(BlobTransactionValidationError::NotBlobTransaction(self.tx_type())), diff --git a/crates/transaction-pool/src/traits.rs b/crates/transaction-pool/src/traits.rs index 709b43e7132..512e3e31f12 100644 --- a/crates/transaction-pool/src/traits.rs +++ b/crates/transaction-pool/src/traits.rs @@ -11,15 +11,19 @@ use alloy_consensus::{ constants::{EIP1559_TX_TYPE_ID, EIP4844_TX_TYPE_ID, EIP7702_TX_TYPE_ID}, Transaction as _, }; -use alloy_eips::{eip2718::Encodable2718, eip2930::AccessList, eip4844::BlobAndProofV1}; +use alloy_eips::{ + eip2718::Encodable2718, + eip2930::AccessList, + eip4844::{BlobAndProofV1, BlobTransactionValidationError}, +}; use alloy_primitives::{Address, TxHash, TxKind, B256, U256}; use futures_util::{ready, Stream}; use reth_eth_wire_types::HandleMempoolData; use reth_execution_types::ChangedAccount; use reth_primitives::{ kzg::KzgSettings, transaction::TryFromRecoveredTransactionError, BlobTransactionSidecar, - BlobTransactionValidationError, PooledTransactionsElement, - PooledTransactionsElementEcRecovered, SealedBlock, Transaction, TransactionSignedEcRecovered, + PooledTransactionsElement, PooledTransactionsElementEcRecovered, SealedBlock, Transaction, + TransactionSignedEcRecovered, }; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; From 5af551782c9084bcd61d15529b167b90bcc86c9c Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 5 Nov 2024 15:04:52 +0100 Subject: [PATCH 015/211] feat: restructure op builder (#12229) --- crates/optimism/payload/src/builder.rs | 888 ++++++++++++++++--------- crates/payload/basic/src/lib.rs | 31 + crates/transaction-pool/src/traits.rs | 5 + 3 files changed, 613 insertions(+), 311 deletions(-) diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index 0cf45835a23..35e1d905a46 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -1,13 +1,15 @@ //! Optimism payload builder implementation. -use std::sync::Arc; + +use std::{fmt::Display, sync::Arc}; use alloy_consensus::EMPTY_OMMER_ROOT_HASH; use alloy_eips::merge::BEACON_NONCE; -use alloy_primitives::{B64, U256}; +use alloy_primitives::{Address, Bytes, B64, U256}; +use alloy_rpc_types_engine::PayloadId; use reth_basic_payload_builder::*; use reth_chain_state::ExecutedBlock; use reth_chainspec::ChainSpecProvider; -use reth_evm::{system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, NextBlockEnvAttributes}; +use reth_evm::{system_calls::SystemCaller, ConfigureEvm, NextBlockEnvAttributes}; use reth_execution_types::ExecutionOutcome; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_consensus::calculate_receipt_root_no_memo_optimism; @@ -16,18 +18,19 @@ use reth_payload_primitives::{PayloadBuilderAttributes, PayloadBuilderError}; use reth_primitives::{ proofs, revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg}, - Block, BlockBody, Header, Receipt, TxType, + Block, BlockBody, Header, Receipt, SealedHeader, TransactionSigned, TxType, }; -use reth_provider::StateProviderFactory; +use reth_provider::{ProviderError, StateProviderFactory, StateRootProvider}; use reth_revm::database::StateProviderDatabase; use reth_transaction_pool::{ - noop::NoopTransactionPool, BestTransactionsAttributes, TransactionPool, + noop::NoopTransactionPool, BestTransactions, BestTransactionsAttributes, BestTransactionsFor, + TransactionPool, }; use reth_trie::HashedPostState; use revm::{ db::{states::bundle_state::BundleRetention, State}, primitives::{EVMError, EnvWithHandlerCfg, InvalidTransaction, ResultAndState}, - DatabaseCommit, + Database, DatabaseCommit, }; use tracing::{debug, trace, warn}; @@ -71,7 +74,7 @@ impl OpPayloadBuilder { } impl OpPayloadBuilder where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvm
, { /// Returns the configured [`CfgEnvWithHandlerCfg`] and [`BlockEnv`] for the targeted payload /// (that has the `parent` as its parent). @@ -87,6 +90,62 @@ where }; self.evm_config.next_cfg_and_block_env(parent, next_attributes) } + + /// 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, &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.evm_config.clone(), + chain_spec: client.chain_spec(), + config, + initialized_cfg, + initialized_block_env, + cancel, + best_payload, + }; + + let builder = OpBuilder { + pool, + // TODO(mattsse): make this configurable in the `OpPayloadBuilder` directly via an + // additional generic + best: best_txs::, + }; + + 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)) + } } /// Implementation of the [`PayloadBuilder`] trait for [`OpPayloadBuilder`]. @@ -103,10 +162,7 @@ where &self, args: BuildArguments, ) -> Result, PayloadBuilderError> { - let (cfg_env, block_env) = self - .cfg_and_block_env(&args.config, &args.config.parent_header) - .map_err(PayloadBuilderError::other)?; - optimism_payload(&self.evm_config, args, cfg_env, block_env, self.compute_pending_block) + self.build_payload(args) } fn on_missing_payload( @@ -134,198 +190,534 @@ where cancel: Default::default(), best_payload: None, }; - let (cfg_env, block_env) = self - .cfg_and_block_env(&args.config, &args.config.parent_header) - .map_err(PayloadBuilderError::other)?; - optimism_payload(&self.evm_config, args, cfg_env, block_env, false)? - .into_payload() - .ok_or_else(|| PayloadBuilderError::MissingPayload) + self.build_payload(args)?.into_payload().ok_or_else(|| PayloadBuilderError::MissingPayload) } } -/// Constructs an Optimism 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. +/// 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) /// -/// 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. -#[inline] -pub(crate) fn optimism_payload( - evm_config: &EvmConfig, - args: BuildArguments, - initialized_cfg: CfgEnvWithHandlerCfg, - initialized_block_env: BlockEnv, - _compute_pending_block: bool, -) -> Result, PayloadBuilderError> +/// 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 OpBuilder { + /// The transaction pool + pool: Pool, + /// Yields the best transaction to include if transactions from the mempool are allowed. + // TODO(mattsse): convert this to a trait + best: Best, +} + +impl OpBuilder where - EvmConfig: ConfigureEvm
, - Client: StateProviderFactory + ChainSpecProvider, Pool: TransactionPool, + Best: FnOnce(Pool, BestTransactionsAttributes) -> BestTransactionsFor, { - let BuildArguments { client, pool, mut cached_reads, config, cancel, best_payload } = args; + /// Builds the payload on top of the state. + pub fn build( + self, + mut db: State, + ctx: OpPayloadBuilderCtx, + ) -> Result, PayloadBuilderError> + where + EvmConfig: ConfigureEvm
, + DB: Database + AsRef

, + P: StateRootProvider, + { + 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(&mut db)?; + + // 2. ensure create2deployer is force deployed + ctx.ensure_create2_deployer(&mut db)?; + + // 3. execute sequencer transactions + let mut info = ctx.execute_sequencer_transactions(&mut db)?; + + // 4. if mem pool transactions are requested we execute them + if !ctx.attributes().no_tx_pool { + let best_txs = best(pool, ctx.best_transaction_attributes()); + if let Some(cancelled) = + ctx.execute_best_transactions::<_, Pool>(&mut info, &mut db, best_txs)? + { + return Ok(cancelled) + } - let chain_spec = client.chain_spec(); - let state_provider = client.state_by_block_hash(config.parent_header.hash())?; - let state = StateProviderDatabase::new(state_provider); - let mut db = - State::builder().with_database(cached_reads.as_db_mut(state)).with_bundle_update().build(); - let PayloadConfig { parent_header, attributes, mut extra_data } = config; + // 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 }) + } + } - debug!(target: "payload_builder", id=%attributes.payload_attributes.payload_id(), parent_header = ?parent_header.hash(), parent_number = parent_header.number, "building new payload"); + let WithdrawalsOutcome { withdrawals_root, withdrawals } = + ctx.commit_withdrawals(&mut db)?; - 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::(); + // merge all transitions into bundle state, this would apply the withdrawal balance changes + // and 4788 contract call + db.merge_transitions(BundleRetention::Reverts); - let mut executed_txs = Vec::with_capacity(attributes.transactions.len()); - let mut executed_senders = Vec::with_capacity(attributes.transactions.len()); + let block_number = ctx.block_number(); + let execution_outcome = ExecutionOutcome::new( + db.take_bundle(), + vec![info.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, + &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 hashed_state = HashedPostState::from_bundle_state(&execution_outcome.state().state); + let (state_root, trie_output) = { + db.database.as_ref().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" + ); + }, + )? + }; - let mut best_txs = pool.best_transactions_with_attributes(BestTransactionsAttributes::new( - base_fee, - initialized_block_env.get_blob_gasprice().map(|gasprice| gasprice as u64), - )); + // 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, + }; - let mut total_fees = U256::ZERO; + // seal the block + let block = Block { + header, + body: BlockBody { + transactions: info.executed_transactions, + ommers: vec![], + withdrawals, + }, + }; - let block_number = initialized_block_env.number.to::(); + let sealed_block = block.seal_slow(); + debug!(target: "payload_builder", ?sealed_block, "sealed built block"); - let is_regolith = - chain_spec.is_regolith_active_at_timestamp(attributes.payload_attributes.timestamp); + // create the executed block data + let executed = ExecutedBlock { + block: Arc::new(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), + }; - // apply eip-4788 pre block contract call - let mut system_caller = SystemCaller::new(evm_config.clone(), chain_spec.clone()); + let no_tx_pool = ctx.attributes().no_tx_pool; - system_caller - .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_header=%parent_header.hash(), - %err, - "failed to apply beacon root contract call for 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) + 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 }) } + } +} + +fn best_txs( + pool: Pool, + attr: BestTransactionsAttributes, +) -> BestTransactionsFor { + pool.best_transactions_with_attributes(attr) +} - // A sequencer's block should never contain blob transactions. - if sequencer_tx.value().is_eip4844() { - return Err(PayloadBuilderError::other( - OptimismPayloadBuilderError::BlobTransactionRejected, - )) +/// This acts as the container for executed transactions and its byproducts (receipts, gas used) +#[derive(Default, Debug)] +pub struct ExecutionInfo { + /// All executed transactions (unrecovered). + pub executed_transactions: Vec, + /// The recovered senders for the executed transactions. + pub executed_senders: Vec

, + /// The transaction receipts + pub receipts: Vec>, + /// All gas used so far + pub cumulative_gas_used: u64, + /// Tracks fees from executed mempool transactions + pub total_fees: U256, +} + +impl ExecutionInfo { + /// Create a new instance with allocated slots. + pub fn with_capacity(capacity: usize) -> Self { + Self { + executed_transactions: Vec::with_capacity(capacity), + executed_senders: Vec::with_capacity(capacity), + receipts: Vec::with_capacity(capacity), + cumulative_gas_used: 0, + total_fees: U256::ZERO, } + } +} - // 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(), - )) +/// Container type that holds all necessities to build a new payload. +#[derive(Debug)] +pub struct OpPayloadBuilderCtx { + /// The type that knows how to perform system calls and configure the evm. + pub evm_config: EvmConfig, + /// The chainspec + pub chain_spec: Arc, + /// How to build the payload. + pub config: PayloadConfig, + /// Evm Settings + pub initialized_cfg: CfgEnvWithHandlerCfg, + /// Block config + pub initialized_block_env: BlockEnv, + /// Marker to check whether the job has been cancelled. + pub cancel: Cancelled, + /// The currently best payload. + pub best_payload: Option, +} + +impl OpPayloadBuilderCtx { + /// Returns the parent block the payload will be build on. + pub fn parent(&self) -> &SealedHeader { + &self.config.parent_header + } + + /// Returns the builder attributes. + pub const fn attributes(&self) -> &OpPayloadBuilderAttributes { + &self.config.attributes + } + + /// Returns the block gas limit to target. + pub fn block_gas_limit(&self) -> u64 { + self.attributes() + .gas_limit + .unwrap_or_else(|| self.initialized_block_env.gas_limit.saturating_to()) + } + + /// Returns the block number for the block. + pub fn block_number(&self) -> u64 { + self.initialized_block_env.number.to() + } + + /// Returns the current base fee + pub fn base_fee(&self) -> u64 { + self.initialized_block_env.basefee.to() + } + + /// Returns the current blob gas price. + pub fn get_blob_gasprice(&self) -> Option { + self.initialized_block_env.get_blob_gasprice().map(|gasprice| gasprice as u64) + } + + /// Returns the blob fields for the header. + /// + /// This will always return `Some(0)` after ecotone. + pub fn blob_fields(&self) -> (Option, Option) { + // 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. + if self.is_ecotone_active() { + (Some(0), Some(0)) + } else { + (None, None) + } + } + + /// Returns the extra data for the block. + /// + /// After holocene this extracts the extradata from the paylpad + pub fn extra_data(&self) -> Result { + if self.is_holocene_active() { + self.attributes() + .get_holocene_extra_data( + self.chain_spec.base_fee_params_at_timestamp( + self.attributes().payload_attributes.timestamp, + ), + ) + .map_err(PayloadBuilderError::other) + } else { + Ok(self.config.extra_data.clone()) + } + } + + /// Returns the current fee settings for transactions from the mempool + 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.attributes().payload_id() + } + + /// Returns true if regolith is active for the payload. + pub fn is_regolith_active(&self) -> bool { + self.chain_spec.is_regolith_active_at_timestamp(self.attributes().timestamp()) + } + + /// Returns true if ecotone is active for the payload. + pub fn is_ecotone_active(&self) -> bool { + self.chain_spec.is_ecotone_active_at_timestamp(self.attributes().timestamp()) + } + + /// Returns true if canyon is active for the payload. + pub fn is_canyon_active(&self) -> bool { + self.chain_spec.is_canyon_active_at_timestamp(self.attributes().timestamp()) + } + + /// Returns true if holocene is active for the payload. + pub fn is_holocene_active(&self) -> bool { + self.chain_spec.is_holocene_active_at_timestamp(self.attributes().timestamp()) + } + + /// Returns true if the fees are higher than the previous payload. + pub fn is_better_payload(&self, total_fees: U256) -> bool { + is_better_payload(self.best_payload.as_ref(), total_fees) + } + + /// Commits the withdrawals from the payload attributes to the state. + pub fn commit_withdrawals( + &self, + db: &mut State, + ) -> Result + where + DB: Database, + { + commit_withdrawals( + db, + &self.chain_spec, + self.attributes().payload_attributes.timestamp, + self.attributes().payload_attributes.withdrawals.clone(), + ) + } + + /// 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, + { + reth_optimism_evm::ensure_create2_deployer( + self.chain_spec.clone(), + self.attributes().payload_attributes.timestamp, + db, + ) + .map_err(|err| { + warn!(target: "payload_builder", %err, "missing create2 deployer, skipping block."); + PayloadBuilderError::other(OptimismPayloadBuilderError::ForceCreate2DeployerFail) + }) + } +} + +impl OpPayloadBuilderCtx +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()) })?; - 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()), - ); + Ok(()) + } - let mut evm = evm_config.evm_with_env(&mut db, env); + /// 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()); + + 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( + OptimismPayloadBuilderError::BlobTransactionRejected, + )) + } - 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)) + // 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 = (self.is_regolith_active() && 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( + self.initialized_cfg.clone(), + self.initialized_block_env.clone(), + self.evm_config.tx_env(sequencer_tx.as_signed(), sequencer_tx.signer()), + ); + + let mut evm = self.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_canyon_active_at_timestamp(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()); + // 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 + 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) } - if !attributes.no_tx_pool { + /// Executes the given best transactions and updates the execution info + pub fn execute_best_transactions( + &self, + info: &mut ExecutionInfo, + db: &mut State, + mut best_txs: BestTransactionsFor, + ) -> Result>, PayloadBuilderError> + where + DB: Database, + Pool: TransactionPool, + { + let block_gas_limit = self.block_gas_limit(); + let base_fee = self.base_fee(); while let Some(pool_tx) = best_txs.next() { // ensure we still have capacity for this transaction - if cumulative_gas_used + pool_tx.gas_limit() > block_gas_limit { + if info.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 @@ -340,20 +732,20 @@ where } // check if the job was cancelled, if so we can exit early - if cancel.is_cancelled() { - return Ok(BuildOutcome::Cancelled) + if self.cancel.is_cancelled() { + return Ok(Some(BuildOutcomeKind::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()), + self.initialized_cfg.clone(), + self.initialized_block_env.clone(), + self.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 mut evm = self.evm_config.evm_with_env(&mut *db, env); let ResultAndState { result, state } = match evm.transact() { Ok(res) => res, @@ -388,13 +780,13 @@ where // add gas used by the transaction to cumulative gas used, before creating the // receipt - cumulative_gas_used += gas_used; + info.cumulative_gas_used += gas_used; // Push transaction changeset and calculate header bloom filter for receipt. - receipts.push(Some(Receipt { + info.receipts.push(Some(Receipt { tx_type: tx.tx_type(), success: result.is_success(), - cumulative_gas_used, + cumulative_gas_used: info.cumulative_gas_used, logs: result.into_logs().into_iter().map(Into::into).collect(), deposit_nonce: None, deposit_receipt_version: None, @@ -404,140 +796,14 @@ where 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); + info.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()); + info.executed_senders.push(tx.signer()); + info.executed_transactions.push(tx.into_signed()); } - } - - // check if we have a better block, but only if we included transactions from the pool - if !attributes.no_tx_pool && !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.payload_attributes.withdrawals.clone(), - )?; - - // 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.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) = { - db.database.inner().state_root_with_updates(hashed_state.clone()).inspect_err(|err| { - warn!(target: "payload_builder", - parent_header=%parent_header.hash(), - %err, - "failed to calculate state root for payload" - ); - })? - }; - - // create the block header - let transactions_root = proofs::calculate_transaction_root(&executed_txs); - - // 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) = - if chain_spec.is_ecotone_active_at_timestamp(attributes.payload_attributes.timestamp) { - (Some(0), Some(0)) - } else { - (None, None) - }; - - let is_holocene = - chain_spec.is_holocene_active_at_timestamp(attributes.payload_attributes.timestamp); - - if is_holocene { - extra_data = attributes - .get_holocene_extra_data( - chain_spec.base_fee_params_at_timestamp(attributes.payload_attributes.timestamp), - ) - .map_err(PayloadBuilderError::other)?; - } - let header = Header { - parent_hash: parent_header.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_header.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 no_tx_pool = attributes.no_tx_pool; - - let payload = OpBuiltPayload::new( - attributes.payload_attributes.id, - sealed_block, - total_fees, - chain_spec, - 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(BuildOutcome::Freeze(payload)) - } else { - Ok(BuildOutcome::Better { payload, cached_reads }) + Ok(None) } } diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index d6dcdf114b0..e57cc668d27 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -790,6 +790,37 @@ impl BuildOutcome { } } +/// The possible outcomes of a payload building attempt without reused [`CachedReads`] +#[derive(Debug)] +pub enum BuildOutcomeKind { + /// Successfully built a better block. + Better { + /// The new payload that was built. + payload: Payload, + }, + /// Aborted payload building because resulted in worse block wrt. fees. + Aborted { + /// The total fees associated with the attempted payload. + fees: U256, + }, + /// Build job was cancelled + Cancelled, + /// The payload is final and no further building should occur + Freeze(Payload), +} + +impl BuildOutcomeKind { + /// Attaches the [`CachedReads`] to the outcome. + pub fn with_cached_reads(self, cached_reads: CachedReads) -> BuildOutcome { + match self { + Self::Better { payload } => BuildOutcome::Better { payload, cached_reads }, + Self::Aborted { fees } => BuildOutcome::Aborted { fees, cached_reads }, + Self::Cancelled => BuildOutcome::Cancelled, + Self::Freeze(payload) => BuildOutcome::Freeze(payload), + } + } +} + /// A collection of arguments used for building payloads. /// /// This struct encapsulates the essential components and configuration required for the payload diff --git a/crates/transaction-pool/src/traits.rs b/crates/transaction-pool/src/traits.rs index 512e3e31f12..b62b7ff2316 100644 --- a/crates/transaction-pool/src/traits.rs +++ b/crates/transaction-pool/src/traits.rs @@ -739,6 +739,11 @@ impl fmt::Display for CanonicalStateUpdate<'_> { } } +/// Alias to restrict the [`BestTransactions`] items to the pool's transaction type. +pub type BestTransactionsFor = Box< + dyn BestTransactions::Transaction>>>, +>; + /// An `Iterator` that only returns transactions that are ready to be executed. /// /// This makes no assumptions about the order of the transactions, but expects that _all_ From 0e83203658a58570028284c5cf32c3858974c0f8 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Tue, 5 Nov 2024 15:40:10 +0100 Subject: [PATCH 016/211] primitives: rm alloy `BlobTransactionSidecar` reexport (#12310) --- bin/reth/src/commands/debug_cmd/build_block.rs | 7 +++---- crates/optimism/payload/src/payload.rs | 9 +++++---- crates/primitives/benches/validate_blob_tx.rs | 5 +++-- crates/primitives/src/lib.rs | 3 +-- crates/primitives/src/transaction/mod.rs | 2 +- crates/primitives/src/transaction/pooled.rs | 9 ++++----- crates/primitives/src/transaction/sidecar.rs | 4 +--- crates/transaction-pool/src/blobstore/disk.rs | 3 +-- crates/transaction-pool/src/blobstore/mem.rs | 6 ++---- crates/transaction-pool/src/blobstore/mod.rs | 3 +-- crates/transaction-pool/src/blobstore/noop.rs | 4 ++-- crates/transaction-pool/src/lib.rs | 4 ++-- crates/transaction-pool/src/noop.rs | 6 ++++-- crates/transaction-pool/src/pool/mod.rs | 4 ++-- crates/transaction-pool/src/test_utils/mock.rs | 7 +++---- crates/transaction-pool/src/traits.rs | 7 +++---- crates/transaction-pool/src/validate/mod.rs | 3 ++- 17 files changed, 40 insertions(+), 46 deletions(-) diff --git a/bin/reth/src/commands/debug_cmd/build_block.rs b/bin/reth/src/commands/debug_cmd/build_block.rs index 0559d473f62..30af4c61c53 100644 --- a/bin/reth/src/commands/debug_cmd/build_block.rs +++ b/bin/reth/src/commands/debug_cmd/build_block.rs @@ -1,6 +1,6 @@ //! Command for debugging block building. use alloy_consensus::TxEip4844; -use alloy_eips::eip2718::Encodable2718; +use alloy_eips::{eip2718::Encodable2718, eip4844::BlobTransactionSidecar}; use alloy_primitives::{Address, Bytes, B256, U256}; use alloy_rlp::Decodable; use alloy_rpc_types::engine::{BlobsBundleV1, PayloadAttributes}; @@ -27,9 +27,8 @@ use reth_node_api::{ }; use reth_node_ethereum::{EthEvmConfig, EthExecutorProvider}; use reth_primitives::{ - revm_primitives::KzgSettings, BlobTransaction, BlobTransactionSidecar, - PooledTransactionsElement, SealedBlock, SealedBlockWithSenders, SealedHeader, Transaction, - TransactionSigned, + revm_primitives::KzgSettings, BlobTransaction, PooledTransactionsElement, SealedBlock, + SealedBlockWithSenders, SealedHeader, Transaction, TransactionSigned, }; use reth_provider::{ providers::BlockchainProvider, BlockHashReader, BlockReader, BlockWriter, ChainSpecProvider, diff --git a/crates/optimism/payload/src/payload.rs b/crates/optimism/payload/src/payload.rs index 3a7d87acc4c..5acac70e914 100644 --- a/crates/optimism/payload/src/payload.rs +++ b/crates/optimism/payload/src/payload.rs @@ -3,7 +3,10 @@ //! Optimism builder support use crate::{builder::decode_eip_1559_params, error::EIP1559ParamError}; -use alloy_eips::{eip1559::BaseFeeParams, eip2718::Decodable2718, eip7685::Requests}; +use alloy_eips::{ + eip1559::BaseFeeParams, eip2718::Decodable2718, eip4844::BlobTransactionSidecar, + eip7685::Requests, +}; use alloy_primitives::{keccak256, Address, Bytes, B256, B64, U256}; use alloy_rlp::Encodable; use alloy_rpc_types_engine::{ExecutionPayloadEnvelopeV2, ExecutionPayloadV1, PayloadId}; @@ -15,9 +18,7 @@ use reth_chainspec::EthereumHardforks; use reth_optimism_chainspec::OpChainSpec; use reth_payload_builder::EthPayloadBuilderAttributes; use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes}; -use reth_primitives::{ - transaction::WithEncoded, BlobTransactionSidecar, SealedBlock, TransactionSigned, Withdrawals, -}; +use reth_primitives::{transaction::WithEncoded, SealedBlock, TransactionSigned, Withdrawals}; use reth_rpc_types_compat::engine::payload::{ block_to_payload_v1, block_to_payload_v3, convert_block_to_payload_field_v2, }; diff --git a/crates/primitives/benches/validate_blob_tx.rs b/crates/primitives/benches/validate_blob_tx.rs index 50498a9420f..453381366e1 100644 --- a/crates/primitives/benches/validate_blob_tx.rs +++ b/crates/primitives/benches/validate_blob_tx.rs @@ -1,7 +1,9 @@ #![allow(missing_docs)] use alloy_consensus::TxEip4844; -use alloy_eips::eip4844::{env_settings::EnvKzgSettings, MAX_BLOBS_PER_BLOCK}; +use alloy_eips::eip4844::{ + env_settings::EnvKzgSettings, BlobTransactionSidecar, MAX_BLOBS_PER_BLOCK, +}; use alloy_primitives::hex; use criterion::{ criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, Criterion, @@ -12,7 +14,6 @@ use proptest::{ test_runner::{RngAlgorithm, TestRng, TestRunner}, }; use proptest_arbitrary_interop::arb; -use reth_primitives::BlobTransactionSidecar; // constant seed to use for the rng const SEED: [u8; 32] = hex!("1337133713371337133713371337133713371337133713371337133713371337"); diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 09610bf7458..c16c4d3f42f 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -47,8 +47,7 @@ pub use reth_primitives_traits::{ pub use static_file::StaticFileSegment; pub use transaction::{ - BlobTransaction, BlobTransactionSidecar, PooledTransactionsElement, - PooledTransactionsElementEcRecovered, + BlobTransaction, PooledTransactionsElement, PooledTransactionsElementEcRecovered, }; pub use transaction::{ diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index aa6aaa2d83e..194ddf9c0ce 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -31,7 +31,7 @@ pub use error::{ }; pub use meta::TransactionMeta; pub use pooled::{PooledTransactionsElement, PooledTransactionsElementEcRecovered}; -pub use sidecar::{BlobTransaction, BlobTransactionSidecar}; +pub use sidecar::BlobTransaction; pub use compat::FillTxEnv; pub use signature::{extract_chain_id, legacy_parity, recover_signer, recover_signer_unchecked}; diff --git a/crates/primitives/src/transaction/pooled.rs b/crates/primitives/src/transaction/pooled.rs index 11da5d8385f..2d62bb3e685 100644 --- a/crates/primitives/src/transaction/pooled.rs +++ b/crates/primitives/src/transaction/pooled.rs @@ -6,10 +6,9 @@ use super::{ signature::{recover_signer, with_eip155_parity}, TxEip7702, }; -use crate::{ - BlobTransaction, BlobTransactionSidecar, Transaction, TransactionSigned, - TransactionSignedEcRecovered, -}; +use crate::{BlobTransaction, Transaction, TransactionSigned, TransactionSignedEcRecovered}; +use alloy_eips::eip4844::BlobTransactionSidecar; + use alloy_consensus::{ constants::EIP4844_TX_TYPE_ID, transaction::{TxEip1559, TxEip2930, TxEip4844, TxLegacy}, @@ -546,7 +545,7 @@ impl<'a> arbitrary::Arbitrary<'a> for PooledTransactionsElement { match Self::try_from(tx_signed) { Ok(Self::BlobTransaction(mut tx)) => { // Successfully converted to a BlobTransaction, now generate a sidecar. - tx.transaction.sidecar = crate::BlobTransactionSidecar::arbitrary(u)?; + tx.transaction.sidecar = alloy_eips::eip4844::BlobTransactionSidecar::arbitrary(u)?; Ok(Self::BlobTransaction(tx)) } Ok(tx) => Ok(tx), // Successfully converted, but not a BlobTransaction. diff --git a/crates/primitives/src/transaction/sidecar.rs b/crates/primitives/src/transaction/sidecar.rs index e7ff7a9b508..5bd647d5393 100644 --- a/crates/primitives/src/transaction/sidecar.rs +++ b/crates/primitives/src/transaction/sidecar.rs @@ -2,13 +2,11 @@ use crate::{Transaction, TransactionSigned}; use alloy_consensus::{constants::EIP4844_TX_TYPE_ID, TxEip4844WithSidecar}; +use alloy_eips::eip4844::BlobTransactionSidecar; use alloy_primitives::{Signature, TxHash}; use alloy_rlp::Header; use serde::{Deserialize, Serialize}; -#[doc(inline)] -pub use alloy_eips::eip4844::BlobTransactionSidecar; - /// A response to `GetPooledTransactions` that includes blob data, their commitments, and their /// corresponding proofs. /// diff --git a/crates/transaction-pool/src/blobstore/disk.rs b/crates/transaction-pool/src/blobstore/disk.rs index 987264853db..9d02276db85 100644 --- a/crates/transaction-pool/src/blobstore/disk.rs +++ b/crates/transaction-pool/src/blobstore/disk.rs @@ -1,10 +1,9 @@ //! A simple diskstore for blobs use crate::blobstore::{BlobStore, BlobStoreCleanupStat, BlobStoreError, BlobStoreSize}; -use alloy_eips::eip4844::BlobAndProofV1; +use alloy_eips::eip4844::{BlobAndProofV1, BlobTransactionSidecar}; use alloy_primitives::{TxHash, B256}; use parking_lot::{Mutex, RwLock}; -use reth_primitives::BlobTransactionSidecar; use schnellru::{ByLength, LruMap}; use std::{collections::HashSet, fmt, fs, io, path::PathBuf, sync::Arc}; use tracing::{debug, trace}; diff --git a/crates/transaction-pool/src/blobstore/mem.rs b/crates/transaction-pool/src/blobstore/mem.rs index cea1837bdcd..0ab9c0d7af0 100644 --- a/crates/transaction-pool/src/blobstore/mem.rs +++ b/crates/transaction-pool/src/blobstore/mem.rs @@ -1,7 +1,5 @@ -use crate::blobstore::{ - BlobStore, BlobStoreCleanupStat, BlobStoreError, BlobStoreSize, BlobTransactionSidecar, -}; -use alloy_eips::eip4844::BlobAndProofV1; +use crate::blobstore::{BlobStore, BlobStoreCleanupStat, BlobStoreError, BlobStoreSize}; +use alloy_eips::eip4844::{BlobAndProofV1, BlobTransactionSidecar}; use alloy_primitives::B256; use parking_lot::RwLock; use std::{collections::HashMap, sync::Arc}; diff --git a/crates/transaction-pool/src/blobstore/mod.rs b/crates/transaction-pool/src/blobstore/mod.rs index f8d37bfcc0f..f1612bcd022 100644 --- a/crates/transaction-pool/src/blobstore/mod.rs +++ b/crates/transaction-pool/src/blobstore/mod.rs @@ -1,11 +1,10 @@ //! Storage for blob data of EIP4844 transactions. -use alloy_eips::eip4844::BlobAndProofV1; +use alloy_eips::eip4844::{BlobAndProofV1, BlobTransactionSidecar}; use alloy_primitives::B256; pub use disk::{DiskFileBlobStore, DiskFileBlobStoreConfig, OpenDiskFileBlobStore}; pub use mem::InMemoryBlobStore; pub use noop::NoopBlobStore; -use reth_primitives::BlobTransactionSidecar; use std::{ fmt, sync::{ diff --git a/crates/transaction-pool/src/blobstore/noop.rs b/crates/transaction-pool/src/blobstore/noop.rs index 0f293573556..943a6eeda95 100644 --- a/crates/transaction-pool/src/blobstore/noop.rs +++ b/crates/transaction-pool/src/blobstore/noop.rs @@ -1,5 +1,5 @@ -use crate::blobstore::{BlobStore, BlobStoreCleanupStat, BlobStoreError, BlobTransactionSidecar}; -use alloy_eips::eip4844::BlobAndProofV1; +use crate::blobstore::{BlobStore, BlobStoreCleanupStat, BlobStoreError}; +use alloy_eips::eip4844::{BlobAndProofV1, BlobTransactionSidecar}; use alloy_primitives::B256; use std::sync::Arc; diff --git a/crates/transaction-pool/src/lib.rs b/crates/transaction-pool/src/lib.rs index 02037599432..669cb69b0e8 100644 --- a/crates/transaction-pool/src/lib.rs +++ b/crates/transaction-pool/src/lib.rs @@ -151,12 +151,12 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] use crate::{identifier::TransactionId, pool::PoolInner}; -use alloy_eips::eip4844::BlobAndProofV1; +use alloy_eips::eip4844::{BlobAndProofV1, BlobTransactionSidecar}; use alloy_primitives::{Address, TxHash, B256, U256}; use aquamarine as _; use reth_eth_wire_types::HandleMempoolData; use reth_execution_types::ChangedAccount; -use reth_primitives::{BlobTransactionSidecar, PooledTransactionsElement}; +use reth_primitives::PooledTransactionsElement; use reth_storage_api::StateProviderFactory; use std::{collections::HashSet, sync::Arc}; use tokio::sync::mpsc::Receiver; diff --git a/crates/transaction-pool/src/noop.rs b/crates/transaction-pool/src/noop.rs index 47a26ee29a3..cf2270978ab 100644 --- a/crates/transaction-pool/src/noop.rs +++ b/crates/transaction-pool/src/noop.rs @@ -16,10 +16,12 @@ use crate::{ PooledTransactionsElement, PropagatedTransactions, TransactionEvents, TransactionOrigin, TransactionPool, TransactionValidationOutcome, TransactionValidator, ValidPoolTransaction, }; -use alloy_eips::{eip1559::ETHEREUM_BLOCK_GAS_LIMIT, eip4844::BlobAndProofV1}; +use alloy_eips::{ + eip1559::ETHEREUM_BLOCK_GAS_LIMIT, + eip4844::{BlobAndProofV1, BlobTransactionSidecar}, +}; use alloy_primitives::{Address, TxHash, B256, U256}; use reth_eth_wire_types::HandleMempoolData; -use reth_primitives::BlobTransactionSidecar; use std::{collections::HashSet, marker::PhantomData, sync::Arc}; use tokio::sync::{mpsc, mpsc::Receiver}; diff --git a/crates/transaction-pool/src/pool/mod.rs b/crates/transaction-pool/src/pool/mod.rs index 77446a52375..0841c0d3d28 100644 --- a/crates/transaction-pool/src/pool/mod.rs +++ b/crates/transaction-pool/src/pool/mod.rs @@ -86,9 +86,9 @@ use parking_lot::{Mutex, RwLock, RwLockReadGuard}; use reth_eth_wire_types::HandleMempoolData; use reth_execution_types::ChangedAccount; +use alloy_eips::eip4844::BlobTransactionSidecar; use reth_primitives::{ - BlobTransaction, BlobTransactionSidecar, PooledTransactionsElement, TransactionSigned, - TransactionSignedEcRecovered, + BlobTransaction, PooledTransactionsElement, TransactionSigned, TransactionSignedEcRecovered, }; use std::{ collections::{HashMap, HashSet}, diff --git a/crates/transaction-pool/src/test_utils/mock.rs b/crates/transaction-pool/src/test_utils/mock.rs index a272e8d00ed..c97632c7dcd 100644 --- a/crates/transaction-pool/src/test_utils/mock.rs +++ b/crates/transaction-pool/src/test_utils/mock.rs @@ -14,7 +14,7 @@ use alloy_consensus::{ use alloy_eips::{ eip1559::MIN_PROTOCOL_BASE_FEE, eip2930::AccessList, - eip4844::{BlobTransactionValidationError, DATA_GAS_PER_BLOB}, + eip4844::{BlobTransactionSidecar, BlobTransactionValidationError, DATA_GAS_PER_BLOB}, }; use alloy_primitives::{Address, Bytes, ChainId, Signature, TxHash, TxKind, B256, U256}; use paste::paste; @@ -23,9 +23,8 @@ use rand::{ prelude::Distribution, }; use reth_primitives::{ - transaction::TryFromRecoveredTransactionError, BlobTransactionSidecar, - PooledTransactionsElementEcRecovered, Transaction, TransactionSigned, - TransactionSignedEcRecovered, TxType, + transaction::TryFromRecoveredTransactionError, PooledTransactionsElementEcRecovered, + Transaction, TransactionSigned, TransactionSignedEcRecovered, TxType, }; use std::{ops::Range, sync::Arc, time::Instant, vec::IntoIter}; diff --git a/crates/transaction-pool/src/traits.rs b/crates/transaction-pool/src/traits.rs index b62b7ff2316..6be25cb2ecc 100644 --- a/crates/transaction-pool/src/traits.rs +++ b/crates/transaction-pool/src/traits.rs @@ -14,16 +14,15 @@ use alloy_consensus::{ use alloy_eips::{ eip2718::Encodable2718, eip2930::AccessList, - eip4844::{BlobAndProofV1, BlobTransactionValidationError}, + eip4844::{BlobAndProofV1, BlobTransactionSidecar, BlobTransactionValidationError}, }; use alloy_primitives::{Address, TxHash, TxKind, B256, U256}; use futures_util::{ready, Stream}; use reth_eth_wire_types::HandleMempoolData; use reth_execution_types::ChangedAccount; use reth_primitives::{ - kzg::KzgSettings, transaction::TryFromRecoveredTransactionError, BlobTransactionSidecar, - PooledTransactionsElement, PooledTransactionsElementEcRecovered, SealedBlock, Transaction, - TransactionSignedEcRecovered, + kzg::KzgSettings, transaction::TryFromRecoveredTransactionError, PooledTransactionsElement, + PooledTransactionsElementEcRecovered, SealedBlock, Transaction, TransactionSignedEcRecovered, }; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; diff --git a/crates/transaction-pool/src/validate/mod.rs b/crates/transaction-pool/src/validate/mod.rs index 4a82a1a148f..6a3b0b96e97 100644 --- a/crates/transaction-pool/src/validate/mod.rs +++ b/crates/transaction-pool/src/validate/mod.rs @@ -6,9 +6,10 @@ use crate::{ traits::{PoolTransaction, TransactionOrigin}, PriceBumpConfig, }; +use alloy_eips::eip4844::BlobTransactionSidecar; use alloy_primitives::{Address, TxHash, B256, U256}; use futures_util::future::Either; -use reth_primitives::{BlobTransactionSidecar, SealedBlock, TransactionSignedEcRecovered}; +use reth_primitives::{SealedBlock, TransactionSignedEcRecovered}; use std::{fmt, future::Future, time::Instant}; mod constants; From 39a667bbfeeb1d6d0d8860814030df5abff680c4 Mon Sep 17 00:00:00 2001 From: greg <82421016+greged93@users.noreply.github.com> Date: Tue, 5 Nov 2024 15:58:16 +0100 Subject: [PATCH 017/211] feat: graceful incoming connection closing (#12282) Co-authored-by: Matthias Seitz --- crates/net/network/src/session/mod.rs | 46 +++++++++++++++++++++++++++ crates/net/network/src/swarm.rs | 11 +++++-- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/crates/net/network/src/session/mod.rs b/crates/net/network/src/session/mod.rs index 712f076b47d..30b1cda9da9 100644 --- a/crates/net/network/src/session/mod.rs +++ b/crates/net/network/src/session/mod.rs @@ -110,6 +110,8 @@ pub struct SessionManager { active_session_rx: ReceiverStream, /// Additional `RLPx` sub-protocols to be used by the session manager. extra_protocols: RlpxSubProtocols, + /// Tracks the ongoing graceful disconnections attempts for incoming connections. + disconnections_counter: DisconnectionsCounter, /// Metrics for the session manager. metrics: SessionManagerMetrics, } @@ -151,6 +153,7 @@ impl SessionManager { active_session_tx: MeteredPollSender::new(active_session_tx, "network_active_session"), active_session_rx: ReceiverStream::new(active_session_rx), extra_protocols, + disconnections_counter: Default::default(), metrics: Default::default(), } } @@ -376,6 +379,35 @@ impl SessionManager { Some(session) } + /// Try to gracefully disconnect an incoming connection by initiating a ECIES connection and + /// sending a disconnect. If [`SessionManager`] is at capacity for ongoing disconnections, will + /// simply drop the incoming connection. + pub(crate) fn try_disconnect_incoming_connection( + &self, + stream: TcpStream, + reason: DisconnectReason, + ) { + if !self.disconnections_counter.has_capacity() { + // drop the connection if we don't have capacity for gracefully disconnecting + return + } + + let guard = self.disconnections_counter.clone(); + let secret_key = self.secret_key; + + self.spawn(async move { + trace!( + target: "net::session", + "gracefully disconnecting incoming connection" + ); + if let Ok(stream) = get_ecies_stream(stream, secret_key, Direction::Incoming).await { + let mut unauth = UnauthedP2PStream::new(stream); + let _ = unauth.send_disconnect(reason).await; + drop(guard); + } + }); + } + /// This polls all the session handles and returns [`SessionEvent`]. /// /// Active sessions are prioritized. @@ -615,6 +647,20 @@ impl SessionManager { } } +/// A counter for ongoing graceful disconnections attempts. +#[derive(Default, Debug, Clone)] +struct DisconnectionsCounter(Arc<()>); + +impl DisconnectionsCounter { + const MAX_CONCURRENT_GRACEFUL_DISCONNECTIONS: usize = 15; + + /// Returns true if the [`DisconnectionsCounter`] still has capacity + /// for an additional graceful disconnection. + fn has_capacity(&self) -> bool { + Arc::strong_count(&self.0) <= Self::MAX_CONCURRENT_GRACEFUL_DISCONNECTIONS + } +} + /// Events produced by the [`SessionManager`] #[derive(Debug)] pub enum SessionEvent { diff --git a/crates/net/network/src/swarm.rs b/crates/net/network/src/swarm.rs index 0be7ae1c1bb..c1fe9f9e231 100644 --- a/crates/net/network/src/swarm.rs +++ b/crates/net/network/src/swarm.rs @@ -8,7 +8,8 @@ use std::{ use futures::Stream; use reth_eth_wire::{ - capability::CapabilityMessage, errors::EthStreamError, Capabilities, EthVersion, Status, + capability::CapabilityMessage, errors::EthStreamError, Capabilities, DisconnectReason, + EthVersion, Status, }; use reth_network_api::PeerRequestSender; use reth_network_peers::PeerId; @@ -32,7 +33,7 @@ use crate::{ /// [`SessionManager`]. Outgoing connections are either initiated on demand or triggered by the /// [`NetworkState`] and also delegated to the [`NetworkState`]. /// -/// Following diagram gives displays the dataflow contained in the [`Swarm`] +/// Following diagram displays the dataflow contained in the [`Swarm`] /// /// The [`ConnectionListener`] yields incoming [`TcpStream`]s from peers that are spawned as session /// tasks. After a successful `RLPx` authentication, the task is ready to accept ETH requests or @@ -70,7 +71,7 @@ impl Swarm { Self { incoming, sessions, state } } - /// Adds an additional protocol handler to the `RLPx` sub-protocol list. + /// Adds a protocol handler to the `RLPx` sub-protocol list. pub(crate) fn add_rlpx_sub_protocol(&mut self, protocol: impl IntoRlpxSubProtocol) { self.sessions_mut().add_rlpx_sub_protocol(protocol); } @@ -201,6 +202,10 @@ impl Swarm { } InboundConnectionError::ExceedsCapacity => { trace!(target: "net", ?remote_addr, "No capacity for incoming connection"); + self.sessions.try_disconnect_incoming_connection( + stream, + DisconnectReason::TooManyPeers, + ); } } return None From ab037756e5f9afec363e50bdb2eadcfc5ecd761d Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 5 Nov 2024 16:17:42 +0100 Subject: [PATCH 018/211] feat: make it configurable how txs are yielded (#12337) --- crates/optimism/node/src/node.rs | 27 +++++++++-- crates/optimism/payload/src/builder.rs | 67 ++++++++++++++++++-------- 2 files changed, 70 insertions(+), 24 deletions(-) diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index 14088e636f1..ae146a60885 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -21,6 +21,7 @@ use reth_node_builder::{ use reth_optimism_chainspec::OpChainSpec; use reth_optimism_consensus::OpBeaconConsensus; use reth_optimism_evm::{OpEvmConfig, OpExecutionStrategyFactory}; +use reth_optimism_payload_builder::builder::OpPayloadTransactions; use reth_optimism_rpc::OpEthApi; use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService}; use reth_primitives::{Block, Header}; @@ -286,7 +287,7 @@ where /// A basic optimism payload service builder #[derive(Debug, Default, Clone)] -pub struct OpPayloadBuilder { +pub struct 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 @@ -296,12 +297,30 @@ pub struct OpPayloadBuilder { /// 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, } impl OpPayloadBuilder { /// Create a new instance with the given `compute_pending_block` flag. pub const fn new(compute_pending_block: bool) -> Self { - Self { compute_pending_block } + Self { compute_pending_block, best_transactions: () } + } +} + +impl OpPayloadBuilder +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, + ) -> OpPayloadBuilder { + let Self { compute_pending_block, .. } = self; + OpPayloadBuilder { compute_pending_block, best_transactions } } /// A helper method to initialize [`PayloadBuilderService`] with the given EVM config. @@ -319,6 +338,7 @@ impl OpPayloadBuilder { Evm: ConfigureEvm
, { let payload_builder = reth_optimism_payload_builder::OpPayloadBuilder::new(evm_config) + .with_transactions(self.best_transactions) .set_compute_pending_block(self.compute_pending_block); let conf = ctx.payload_builder_config(); @@ -345,11 +365,12 @@ impl OpPayloadBuilder { } } -impl PayloadServiceBuilder for OpPayloadBuilder +impl PayloadServiceBuilder for OpPayloadBuilder where Node: FullNodeTypes>, Pool: TransactionPool + Unpin + 'static, + Txs: OpPayloadTransactions, { async fn spawn_payload_service( self, diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index 35e1d905a46..f0c6c04ce73 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -42,26 +42,41 @@ use op_alloy_consensus::DepositTransaction; /// Optimism's payload builder #[derive(Debug, Clone, PartialEq, Eq)] -pub struct OpPayloadBuilder { +pub struct OpPayloadBuilder { /// The rollup's compute pending block configuration option. // TODO(clabby): Implement this feature. pub compute_pending_block: bool, /// The type responsible for creating the evm. pub evm_config: EvmConfig, + /// The type responsible for yielding the best transactions for the payload if mempool + /// transactions are allowed. + pub best_transactions: Txs, } impl OpPayloadBuilder { /// `OpPayloadBuilder` constructor. pub const fn new(evm_config: EvmConfig) -> Self { - Self { compute_pending_block: true, evm_config } + Self { compute_pending_block: true, evm_config, best_transactions: () } } +} +impl OpPayloadBuilder { /// Sets the rollup's compute pending block configuration option. pub const fn set_compute_pending_block(mut self, compute_pending_block: bool) -> Self { self.compute_pending_block = compute_pending_block; self } + /// Configures the type responsible for yielding the transactions that should be included in the + /// payload. + pub fn with_transactions( + self, + best_transactions: T, + ) -> OpPayloadBuilder { + let Self { compute_pending_block, evm_config, .. } = self; + OpPayloadBuilder { compute_pending_block, evm_config, best_transactions } + } + /// Enables the rollup's compute pending block configuration option. pub const fn compute_pending_block(self) -> Self { self.set_compute_pending_block(true) @@ -72,9 +87,10 @@ impl OpPayloadBuilder { self.compute_pending_block } } -impl OpPayloadBuilder +impl OpPayloadBuilder where EvmConfig: ConfigureEvm
, + Txs: OpPayloadTransactions, { /// Returns the configured [`CfgEnvWithHandlerCfg`] and [`BlockEnv`] for the targeted payload /// (that has the `parent` as its parent). @@ -123,12 +139,7 @@ where best_payload, }; - let builder = OpBuilder { - pool, - // TODO(mattsse): make this configurable in the `OpPayloadBuilder` directly via an - // additional generic - best: best_txs::, - }; + let builder = OpBuilder { pool, best: self.best_transactions.clone() }; let state_provider = client.state_by_block_hash(ctx.parent().hash())?; let state = StateProviderDatabase::new(state_provider); @@ -149,11 +160,12 @@ where } /// Implementation of the [`PayloadBuilder`] trait for [`OpPayloadBuilder`]. -impl PayloadBuilder for OpPayloadBuilder +impl PayloadBuilder for OpPayloadBuilder where Client: StateProviderFactory + ChainSpecProvider, Pool: TransactionPool, EvmConfig: ConfigureEvm
, + Txs: OpPayloadTransactions, { type Attributes = OpPayloadBuilderAttributes; type BuiltPayload = OpBuiltPayload; @@ -210,18 +222,17 @@ where /// And finally /// 5. build the block: compute all roots (txs, state) #[derive(Debug)] -pub struct OpBuilder { +pub struct OpBuilder { /// The transaction pool pool: Pool, /// Yields the best transaction to include if transactions from the mempool are allowed. - // TODO(mattsse): convert this to a trait - best: Best, + best: Txs, } -impl OpBuilder +impl OpBuilder where Pool: TransactionPool, - Best: FnOnce(Pool, BestTransactionsAttributes) -> BestTransactionsFor, + Txs: OpPayloadTransactions, { /// Builds the payload on top of the state. pub fn build( @@ -248,7 +259,7 @@ where // 4. if mem pool transactions are requested we execute them if !ctx.attributes().no_tx_pool { - let best_txs = best(pool, ctx.best_transaction_attributes()); + let best_txs = best.best_transactions(pool, ctx.best_transaction_attributes()); if let Some(cancelled) = ctx.execute_best_transactions::<_, Pool>(&mut info, &mut db, best_txs)? { @@ -379,11 +390,25 @@ where } } -fn best_txs( - pool: Pool, - attr: BestTransactionsAttributes, -) -> BestTransactionsFor { - pool.best_transactions_with_attributes(attr) +/// A type that returns a the [`BestTransactions`] that should be included in the pool. +pub trait OpPayloadTransactions: Clone + Send + Sync + Unpin + 'static { + /// Returns an iterator that yields the transaction in the order they should get included in the + /// new payload. + fn best_transactions( + &self, + pool: Pool, + attr: BestTransactionsAttributes, + ) -> BestTransactionsFor; +} + +impl OpPayloadTransactions for () { + fn best_transactions( + &self, + pool: Pool, + attr: BestTransactionsAttributes, + ) -> BestTransactionsFor { + pool.best_transactions_with_attributes(attr) + } } /// This acts as the container for executed transactions and its byproducts (receipts, gas used) From 6ddb3eac97c63ed489ade8a92ad334690647708d Mon Sep 17 00:00:00 2001 From: Skanda Bhat Date: Tue, 5 Nov 2024 17:28:18 +0000 Subject: [PATCH 019/211] feat: mev_simBundle (#12218) Co-authored-by: Arsenii Kulikov --- crates/rpc/rpc/src/eth/sim_bundle.rs | 476 ++++++++++++++++++++++++++- 1 file changed, 465 insertions(+), 11 deletions(-) diff --git a/crates/rpc/rpc/src/eth/sim_bundle.rs b/crates/rpc/rpc/src/eth/sim_bundle.rs index 46dbb45d962..67fd5181759 100644 --- a/crates/rpc/rpc/src/eth/sim_bundle.rs +++ b/crates/rpc/rpc/src/eth/sim_bundle.rs @@ -1,15 +1,71 @@ //! `Eth` Sim bundle implementation and helpers. -use std::sync::Arc; - -use alloy_rpc_types_mev::{SendBundleRequest, SimBundleOverrides, SimBundleResponse}; +use alloy_eips::BlockNumberOrTag; +use alloy_primitives::U256; +use alloy_rpc_types::BlockId; +use alloy_rpc_types_mev::{ + BundleItem, Inclusion, Privacy, RefundConfig, SendBundleRequest, SimBundleLogs, + SimBundleOverrides, SimBundleResponse, Validity, +}; use jsonrpsee::core::RpcResult; +use reth_chainspec::EthChainSpec; +use reth_evm::{ConfigureEvm, ConfigureEvmEnv}; +use reth_primitives::{ + revm_primitives::db::{DatabaseCommit, DatabaseRef}, + TransactionSigned, +}; +use reth_provider::{ChainSpecProvider, HeaderProvider}; +use reth_revm::database::StateProviderDatabase; use reth_rpc_api::MevSimApiServer; -use reth_rpc_eth_api::helpers::{Call, EthTransactions, LoadPendingBlock}; -use reth_rpc_eth_types::EthApiError; +use reth_rpc_eth_api::{ + helpers::{Call, EthTransactions, LoadPendingBlock}, + FromEthApiError, RpcNodeCore, +}; +use reth_rpc_eth_types::{utils::recover_raw_transaction, EthApiError}; use reth_tasks::pool::BlockingTaskGuard; +use revm::{ + db::CacheDB, + primitives::{Address, EnvWithHandlerCfg, ResultAndState, SpecId, TxEnv}, +}; +use std::{sync::Arc, time::Duration}; use tracing::info; +/// Maximum bundle depth +const MAX_NESTED_BUNDLE_DEPTH: usize = 5; + +/// Maximum body size +const MAX_BUNDLE_BODY_SIZE: usize = 50; + +/// Default simulation timeout +const DEFAULT_SIM_TIMEOUT: Duration = Duration::from_secs(5); + +/// Maximum simulation timeout +const MAX_SIM_TIMEOUT: Duration = Duration::from_secs(30); + +/// Maximum payout cost +const SBUNDLE_PAYOUT_MAX_COST: u64 = 30_000; + +/// A flattened representation of a bundle item containing transaction and associated metadata. +#[derive(Clone, Debug)] +pub struct FlattenedBundleItem { + /// The signed transaction + pub tx: TransactionSigned, + /// The address that signed the transaction + pub signer: Address, + /// Whether the transaction is allowed to revert + pub can_revert: bool, + /// Item-level inclusion constraints + pub inclusion: Inclusion, + /// Optional validity constraints for the bundle item + pub validity: Option, + /// Optional privacy settings for the bundle item + pub privacy: Option, + /// Optional refund percent for the bundle item + pub refund_percent: Option, + /// Optional refund configs for the bundle item + pub refund_configs: Option>, +} + /// `Eth` sim bundle implementation. pub struct EthSimBundle { /// All nested fields bundled together. @@ -21,20 +77,370 @@ impl EthSimBundle { pub fn new(eth_api: Eth, blocking_task_guard: BlockingTaskGuard) -> Self { Self { inner: Arc::new(EthSimBundleInner { eth_api, blocking_task_guard }) } } + + /// Access the underlying `Eth` API. + pub fn eth_api(&self) -> &Eth { + &self.inner.eth_api + } } impl EthSimBundle where Eth: EthTransactions + LoadPendingBlock + Call + 'static, { - /// Simulates a bundle of transactions. - pub async fn sim_bundle( + /// Flattens a potentially nested bundle into a list of individual transactions in a + /// `FlattenedBundleItem` with their associated metadata. This handles recursive bundle + /// processing up to `MAX_NESTED_BUNDLE_DEPTH` and `MAX_BUNDLE_BODY_SIZE`, preserving + /// inclusion, validity and privacy settings from parent bundles. + fn parse_and_flatten_bundle( + &self, + request: &SendBundleRequest, + ) -> Result, EthApiError> { + let mut items = Vec::new(); + + // Stack for processing bundles + let mut stack = Vec::new(); + + // Start with initial bundle, index 0, and depth 1 + stack.push((request, 0, 1)); + + while let Some((current_bundle, mut idx, depth)) = stack.pop() { + // Check max depth + if depth > MAX_NESTED_BUNDLE_DEPTH { + return Err(EthApiError::InvalidParams(EthSimBundleError::MaxDepth.to_string())); + } + + // Determine inclusion, validity, and privacy + let inclusion = ¤t_bundle.inclusion; + let validity = ¤t_bundle.validity; + let privacy = ¤t_bundle.privacy; + + // Validate inclusion parameters + let block_number = inclusion.block_number(); + let max_block_number = inclusion.max_block_number().unwrap_or(block_number); + + if max_block_number < block_number || block_number == 0 { + return Err(EthApiError::InvalidParams( + EthSimBundleError::InvalidInclusion.to_string(), + )); + } + + // Validate bundle body size + if current_bundle.bundle_body.len() > MAX_BUNDLE_BODY_SIZE { + return Err(EthApiError::InvalidParams( + EthSimBundleError::BundleTooLarge.to_string(), + )); + } + + // Validate validity and refund config + if let Some(validity) = ¤t_bundle.validity { + // Validate refund entries + if let Some(refunds) = &validity.refund { + let mut total_percent = 0; + for refund in refunds { + if refund.body_idx as usize >= current_bundle.bundle_body.len() { + return Err(EthApiError::InvalidParams( + EthSimBundleError::InvalidValidity.to_string(), + )); + } + if 100 - total_percent < refund.percent { + return Err(EthApiError::InvalidParams( + EthSimBundleError::InvalidValidity.to_string(), + )); + } + total_percent += refund.percent; + } + } + + // Validate refund configs + if let Some(refund_configs) = &validity.refund_config { + let mut total_percent = 0; + for refund_config in refund_configs { + if 100 - total_percent < refund_config.percent { + return Err(EthApiError::InvalidParams( + EthSimBundleError::InvalidValidity.to_string(), + )); + } + total_percent += refund_config.percent; + } + } + } + + let body = ¤t_bundle.bundle_body; + + // Process items in the current bundle + while idx < body.len() { + match &body[idx] { + BundleItem::Tx { tx, can_revert } => { + let recovered_tx = + recover_raw_transaction(tx.clone()).map_err(EthApiError::from)?; + let (tx, signer) = recovered_tx.into_components(); + let tx = tx.into_transaction(); + + let refund_percent = + validity.as_ref().and_then(|v| v.refund.as_ref()).and_then(|refunds| { + refunds.iter().find_map(|refund| { + (refund.body_idx as usize == idx).then_some(refund.percent) + }) + }); + let refund_configs = + validity.as_ref().and_then(|v| v.refund_config.clone()); + + // Create FlattenedBundleItem with current inclusion, validity, and privacy + let flattened_item = FlattenedBundleItem { + tx, + signer, + can_revert: *can_revert, + inclusion: inclusion.clone(), + validity: validity.clone(), + privacy: privacy.clone(), + refund_percent, + refund_configs, + }; + + // Add to items + items.push(flattened_item); + + idx += 1; + } + BundleItem::Bundle { bundle } => { + // Push the current bundle and next index onto the stack to resume later + stack.push((current_bundle, idx + 1, depth)); + + // process the nested bundle next + stack.push((bundle, 0, depth + 1)); + break; + } + BundleItem::Hash { hash: _ } => { + // Hash-only items are not allowed + return Err(EthApiError::InvalidParams( + EthSimBundleError::InvalidBundle.to_string(), + )); + } + } + } + } + + Ok(items) + } + + async fn sim_bundle( &self, request: SendBundleRequest, overrides: SimBundleOverrides, - ) -> RpcResult { - info!("mev_simBundle called, request: {:?}, overrides: {:?}", request, overrides); - Err(EthApiError::Unsupported("mev_simBundle is not supported").into()) + logs: bool, + ) -> Result { + let SimBundleOverrides { + parent_block, + block_number, + coinbase, + timestamp, + gas_limit, + base_fee, + .. + } = overrides; + + // Parse and validate bundle + // Also, flatten the bundle here so that its easier to process + let flattened_bundle = self.parse_and_flatten_bundle(&request)?; + + let block_id = parent_block.unwrap_or(BlockId::Number(BlockNumberOrTag::Pending)); + let (cfg, mut block_env, current_block) = self.eth_api().evm_env_at(block_id).await?; + + let parent_header = RpcNodeCore::provider(&self.inner.eth_api) + .header_by_number(block_env.number.saturating_to::()) + .map_err(EthApiError::from_eth_err)? // Explicitly map the error + .ok_or_else(|| { + EthApiError::HeaderNotFound((block_env.number.saturating_to::()).into()) + })?; + + // apply overrides + if let Some(block_number) = block_number { + block_env.number = U256::from(block_number); + } + + if let Some(coinbase) = coinbase { + block_env.coinbase = coinbase; + } + + if let Some(timestamp) = timestamp { + block_env.timestamp = U256::from(timestamp); + } + + if let Some(gas_limit) = gas_limit { + block_env.gas_limit = U256::from(gas_limit); + } + + if let Some(base_fee) = base_fee { + block_env.basefee = U256::from(base_fee); + } else if cfg.handler_cfg.spec_id.is_enabled_in(SpecId::LONDON) { + if let Some(base_fee) = parent_header.next_block_base_fee( + RpcNodeCore::provider(&self.inner.eth_api) + .chain_spec() + .base_fee_params_at_block(block_env.number.saturating_to::()), + ) { + block_env.basefee = U256::from(base_fee); + } + } + + let eth_api = self.inner.eth_api.clone(); + + let sim_response = self + .inner + .eth_api + .spawn_with_state_at_block(current_block, move |state| { + // Setup environment + let current_block_number = current_block.as_u64().unwrap(); + let coinbase = block_env.coinbase; + let basefee = block_env.basefee; + let env = EnvWithHandlerCfg::new_with_cfg_env(cfg, block_env, TxEnv::default()); + let db = CacheDB::new(StateProviderDatabase::new(state)); + + let initial_coinbase_balance = DatabaseRef::basic_ref(&db, coinbase) + .map_err(EthApiError::from_eth_err)? + .map(|acc| acc.balance) + .unwrap_or_default(); + + let mut coinbase_balance_before_tx = initial_coinbase_balance; + let mut total_gas_used = 0; + let mut total_profit = U256::ZERO; + let mut refundable_value = U256::ZERO; + let mut body_logs: Vec = Vec::new(); + + let mut evm = RpcNodeCore::evm_config(ð_api).evm_with_env(db, env); + + for item in &flattened_bundle { + // Check inclusion constraints + let block_number = item.inclusion.block_number(); + let max_block_number = + item.inclusion.max_block_number().unwrap_or(block_number); + + if current_block_number < block_number || + current_block_number > max_block_number + { + return Err(EthApiError::InvalidParams( + EthSimBundleError::InvalidInclusion.to_string(), + ) + .into()); + } + RpcNodeCore::evm_config(ð_api).fill_tx_env( + evm.tx_mut(), + &item.tx, + item.signer, + ); + + let ResultAndState { result, state } = + evm.transact().map_err(EthApiError::from_eth_err)?; + + if !result.is_success() && !item.can_revert { + return Err(EthApiError::InvalidParams( + EthSimBundleError::BundleTransactionFailed.to_string(), + ) + .into()); + } + + let gas_used = result.gas_used(); + total_gas_used += gas_used; + + // coinbase is always present in the result state + let coinbase_balance_after_tx = + state.get(&coinbase).map(|acc| acc.info.balance).unwrap_or_default(); + + let coinbase_diff = + coinbase_balance_after_tx.saturating_sub(coinbase_balance_before_tx); + total_profit += coinbase_diff; + + // Add to refundable value if this tx does not have a refund percent + if item.refund_percent.is_none() { + refundable_value += coinbase_diff; + } + + // Update coinbase balance before next tx + coinbase_balance_before_tx = coinbase_balance_after_tx; + + // Collect logs if requested + // TODO: since we are looping over iteratively, we are not collecting bundle + // logs. We should collect bundle logs when we are processing the bundle items. + if logs { + let tx_logs = result.logs().to_vec(); + let sim_bundle_logs = + SimBundleLogs { tx_logs: Some(tx_logs), bundle_logs: None }; + body_logs.push(sim_bundle_logs); + } + + // Apply state changes + evm.context.evm.db.commit(state); + } + + // After processing all transactions, process refunds + for item in &flattened_bundle { + if let Some(refund_percent) = item.refund_percent { + // Get refund configurations + let refund_configs = item.refund_configs.clone().unwrap_or_else(|| { + vec![RefundConfig { address: item.signer, percent: 100 }] + }); + + // Calculate payout transaction fee + let payout_tx_fee = basefee * + U256::from(SBUNDLE_PAYOUT_MAX_COST) * + U256::from(refund_configs.len() as u64); + + // Add gas used for payout transactions + total_gas_used += SBUNDLE_PAYOUT_MAX_COST * refund_configs.len() as u64; + + // Calculate allocated refundable value (payout value) + let payout_value = + refundable_value * U256::from(refund_percent) / U256::from(100); + + if payout_tx_fee > payout_value { + return Err(EthApiError::InvalidParams( + EthSimBundleError::NegativeProfit.to_string(), + ) + .into()); + } + + // Subtract payout value from total profit + total_profit = total_profit.checked_sub(payout_value).ok_or( + EthApiError::InvalidParams( + EthSimBundleError::NegativeProfit.to_string(), + ), + )?; + + // Adjust refundable value + refundable_value = refundable_value.checked_sub(payout_value).ok_or( + EthApiError::InvalidParams( + EthSimBundleError::NegativeProfit.to_string(), + ), + )?; + } + } + + // Calculate mev gas price + let mev_gas_price = if total_gas_used != 0 { + total_profit / U256::from(total_gas_used) + } else { + U256::ZERO + }; + + Ok(SimBundleResponse { + success: true, + state_block: current_block_number, + error: None, + logs: Some(body_logs), + gas_used: total_gas_used, + mev_gas_price, + profit: total_profit, + refundable_value, + exec_error: None, + revert: None, + }) + }) + .await + .map_err(|_| { + EthApiError::InvalidParams(EthSimBundleError::BundleTimeout.to_string()) + })?; + + Ok(sim_response) } } @@ -48,7 +454,23 @@ where request: SendBundleRequest, overrides: SimBundleOverrides, ) -> RpcResult { - Self::sim_bundle(self, request, overrides).await + info!("mev_simBundle called, request: {:?}, overrides: {:?}", request, overrides); + + let override_timeout = overrides.timeout; + + let timeout = override_timeout + .map(Duration::from_secs) + .filter(|&custom_duration| custom_duration <= MAX_SIM_TIMEOUT) + .unwrap_or(DEFAULT_SIM_TIMEOUT); + + let bundle_res = + tokio::time::timeout(timeout, Self::sim_bundle(self, request, overrides, true)) + .await + .map_err(|_| { + EthApiError::InvalidParams(EthSimBundleError::BundleTimeout.to_string()) + })?; + + bundle_res.map_err(Into::into) } } @@ -74,3 +496,35 @@ impl Clone for EthSimBundle { Self { inner: Arc::clone(&self.inner) } } } + +/// [`EthSimBundle`] specific errors. +#[derive(Debug, thiserror::Error)] +pub enum EthSimBundleError { + /// Thrown when max depth is reached + #[error("max depth reached")] + MaxDepth, + /// Thrown when a bundle is unmatched + #[error("unmatched bundle")] + UnmatchedBundle, + /// Thrown when a bundle is too large + #[error("bundle too large")] + BundleTooLarge, + /// Thrown when validity is invalid + #[error("invalid validity")] + InvalidValidity, + /// Thrown when inclusion is invalid + #[error("invalid inclusion")] + InvalidInclusion, + /// Thrown when a bundle is invalid + #[error("invalid bundle")] + InvalidBundle, + /// Thrown when a bundle simulation times out + #[error("bundle simulation timed out")] + BundleTimeout, + /// Thrown when a transaction is reverted in a bundle + #[error("bundle transaction failed")] + BundleTransactionFailed, + /// Thrown when a bundle simulation returns negative profit + #[error("bundle simulation returned negative profit")] + NegativeProfit, +} From 3f02e18dc589f34a52da2fbe20c0b5a351442220 Mon Sep 17 00:00:00 2001 From: tedison <76473430+edisontim@users.noreply.github.com> Date: Wed, 6 Nov 2024 02:30:08 -0500 Subject: [PATCH 020/211] fix: add dev feature in error message to generate test vectors (#12084) --- crates/storage/db/benches/utils.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/storage/db/benches/utils.rs b/crates/storage/db/benches/utils.rs index 9700ef94b24..d4ae96e0006 100644 --- a/crates/storage/db/benches/utils.rs +++ b/crates/storage/db/benches/utils.rs @@ -32,7 +32,7 @@ where env!("CARGO_MANIFEST_DIR"), T::NAME )) - .expect("Test vectors not found. They can be generated from the workspace by calling `cargo run --bin reth -- test-vectors tables`."), + .expect("Test vectors not found. They can be generated from the workspace by calling `cargo run --bin reth --features dev -- test-vectors tables`."), )) .unwrap(); From 0c7700f2c7f87df7fb9c568005b2b977fd72bccb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Narzis?= <78718413+lean-apple@users.noreply.github.com> Date: Wed, 6 Nov 2024 14:58:45 +0700 Subject: [PATCH 021/211] feat(payload) : optimize new payload job by fetching only header hash instead of block (#12343) --- crates/payload/basic/src/lib.rs | 39 ++++++++++++-------------- crates/payload/primitives/src/error.rs | 3 ++ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index e57cc668d27..9c90f7f83e0 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -10,7 +10,7 @@ use crate::metrics::PayloadBuilderMetrics; use alloy_consensus::constants::EMPTY_WITHDRAWALS; -use alloy_eips::{merge::SLOT_DURATION, BlockNumberOrTag}; +use alloy_eips::merge::SLOT_DURATION; use alloy_primitives::{Bytes, B256, U256}; use futures_core::ready; use futures_util::FutureExt; @@ -22,7 +22,7 @@ use reth_payload_primitives::{ }; use reth_primitives::{constants::RETH_CLIENT_VERSION, proofs, SealedHeader, Withdrawals}; use reth_provider::{ - BlockReaderIdExt, BlockSource, CanonStateNotification, ProviderError, StateProviderFactory, + BlockReaderIdExt, CanonStateNotification, ProviderError, StateProviderFactory, }; use reth_revm::cached::CachedReads; use reth_tasks::TaskSpawner; @@ -144,33 +144,30 @@ where &self, attributes: ::PayloadAttributes, ) -> Result { - let parent_block = if attributes.parent().is_zero() { - // use latest block if parent is zero: genesis block + let parent_header = if attributes.parent().is_zero() { + // Use latest header for genesis block case self.client - .block_by_number_or_tag(BlockNumberOrTag::Latest)? - .ok_or_else(|| PayloadBuilderError::MissingParentBlock(attributes.parent()))? - .seal_slow() + .latest_header() + .map_err(PayloadBuilderError::from)? + .ok_or_else(|| PayloadBuilderError::MissingParentHeader(B256::ZERO))? } else { - let block = self - .client - .find_block_by_hash(attributes.parent(), BlockSource::Any)? - .ok_or_else(|| PayloadBuilderError::MissingParentBlock(attributes.parent()))?; - - // we already know the hash, so we can seal it - block.seal(attributes.parent()) + // Fetch specific header by hash + self.client + .sealed_header_by_hash(attributes.parent()) + .map_err(PayloadBuilderError::from)? + .ok_or_else(|| PayloadBuilderError::MissingParentHeader(attributes.parent()))? }; - let hash = parent_block.hash(); - let parent_header = parent_block.header(); - let header = SealedHeader::new(parent_header.clone(), hash); - - let config = - PayloadConfig::new(Arc::new(header), self.config.extradata.clone(), attributes); + let config = PayloadConfig::new( + Arc::new(parent_header.clone()), + self.config.extradata.clone(), + attributes, + ); let until = self.job_deadline(config.attributes.timestamp()); let deadline = Box::pin(tokio::time::sleep_until(until)); - let cached_reads = self.maybe_pre_cached(hash); + let cached_reads = self.maybe_pre_cached(parent_header.hash()); let mut job = BasicPayloadJob { config, diff --git a/crates/payload/primitives/src/error.rs b/crates/payload/primitives/src/error.rs index 00df9e8d290..16446255c35 100644 --- a/crates/payload/primitives/src/error.rs +++ b/crates/payload/primitives/src/error.rs @@ -9,6 +9,9 @@ use tokio::sync::oneshot; /// Possible error variants during payload building. #[derive(Debug, thiserror::Error)] pub enum PayloadBuilderError { + /// Thrown when the parent header cannot be found + #[error("missing parent header: {0}")] + MissingParentHeader(B256), /// Thrown when the parent block is missing. #[error("missing parent block {0}")] MissingParentBlock(B256), From e34a88d2ccd7ff0a12394f4806989cc5db05976b Mon Sep 17 00:00:00 2001 From: Steven <112043913+stevencartavia@users.noreply.github.com> Date: Wed, 6 Nov 2024 02:30:15 -0600 Subject: [PATCH 022/211] renamed OptimismNode to OpNode (#12338) --- crates/node/builder/src/builder/mod.rs | 2 +- crates/optimism/bin/src/main.rs | 8 ++++---- crates/optimism/cli/src/lib.rs | 20 +++++++++----------- crates/optimism/node/src/lib.rs | 2 +- crates/optimism/node/src/node.rs | 10 +++++----- crates/optimism/node/tests/e2e/utils.rs | 4 ++-- crates/optimism/node/tests/it/builder.rs | 6 +++--- 7 files changed, 25 insertions(+), 27 deletions(-) diff --git a/crates/node/builder/src/builder/mod.rs b/crates/node/builder/src/builder/mod.rs index 82d8d96f6f5..2e00b08f8a5 100644 --- a/crates/node/builder/src/builder/mod.rs +++ b/crates/node/builder/src/builder/mod.rs @@ -79,7 +79,7 @@ pub type RethFullAdapter = FullNodeTypesAdapter< /// configured components and can interact with the node. /// /// There are convenience functions for networks that come with a preset of types and components via -/// the [Node] trait, see `reth_node_ethereum::EthereumNode` or `reth_optimism_node::OptimismNode`. +/// the [`Node`] trait, see `reth_node_ethereum::EthereumNode` or `reth_optimism_node::OpNode`. /// /// The [`NodeBuilder::node`] function configures the node's types and components in one step. /// diff --git a/crates/optimism/bin/src/main.rs b/crates/optimism/bin/src/main.rs index 6c440f43491..840da3bcf0b 100644 --- a/crates/optimism/bin/src/main.rs +++ b/crates/optimism/bin/src/main.rs @@ -5,7 +5,7 @@ use clap::Parser; use reth_node_builder::{engine_tree_config::TreeConfig, EngineNodeLauncher}; use reth_optimism_cli::{chainspec::OpChainSpecParser, Cli}; -use reth_optimism_node::{args::RollupArgs, node::OptimismAddOns, OptimismNode}; +use reth_optimism_node::{args::RollupArgs, node::OptimismAddOns, OpNode}; use reth_provider::providers::BlockchainProvider2; use tracing as _; @@ -34,8 +34,8 @@ fn main() { .with_persistence_threshold(rollup_args.persistence_threshold) .with_memory_block_buffer_target(rollup_args.memory_block_buffer_target); let handle = builder - .with_types_and_provider::>() - .with_components(OptimismNode::components(rollup_args)) + .with_types_and_provider::>() + .with_components(OpNode::components(rollup_args)) .with_add_ons(OptimismAddOns::new(sequencer_http_arg)) .launch_with_fn(|builder| { let launcher = EngineNodeLauncher::new( @@ -51,7 +51,7 @@ fn main() { } true => { let handle = - builder.node(OptimismNode::new(rollup_args.clone())).launch().await?; + builder.node(OpNode::new(rollup_args.clone())).launch().await?; handle.node_exit_future.await } diff --git a/crates/optimism/cli/src/lib.rs b/crates/optimism/cli/src/lib.rs index 43d12616484..b3c7c86d1d1 100644 --- a/crates/optimism/cli/src/lib.rs +++ b/crates/optimism/cli/src/lib.rs @@ -47,7 +47,7 @@ use reth_node_core::{ version::{LONG_VERSION, SHORT_VERSION}, }; use reth_optimism_evm::OpExecutorProvider; -use reth_optimism_node::OptimismNode; +use reth_optimism_node::OpNode; use reth_tracing::FileWorkerGuard; use tracing::info; @@ -145,30 +145,28 @@ where runner.run_command_until_exit(|ctx| command.execute(ctx, launcher)) } Commands::Init(command) => { - runner.run_blocking_until_ctrl_c(command.execute::()) + runner.run_blocking_until_ctrl_c(command.execute::()) } Commands::InitState(command) => { - runner.run_blocking_until_ctrl_c(command.execute::()) + runner.run_blocking_until_ctrl_c(command.execute::()) } Commands::ImportOp(command) => { - runner.run_blocking_until_ctrl_c(command.execute::()) + runner.run_blocking_until_ctrl_c(command.execute::()) } Commands::ImportReceiptsOp(command) => { - runner.run_blocking_until_ctrl_c(command.execute::()) + runner.run_blocking_until_ctrl_c(command.execute::()) } Commands::DumpGenesis(command) => runner.run_blocking_until_ctrl_c(command.execute()), - Commands::Db(command) => { - runner.run_blocking_until_ctrl_c(command.execute::()) - } + Commands::Db(command) => runner.run_blocking_until_ctrl_c(command.execute::()), Commands::Stage(command) => runner.run_command_until_exit(|ctx| { - command.execute::(ctx, OpExecutorProvider::optimism) + command.execute::(ctx, OpExecutorProvider::optimism) }), Commands::P2P(command) => runner.run_until_ctrl_c(command.execute()), Commands::Config(command) => runner.run_until_ctrl_c(command.execute()), Commands::Recover(command) => { - runner.run_command_until_exit(|ctx| command.execute::(ctx)) + runner.run_command_until_exit(|ctx| command.execute::(ctx)) } - Commands::Prune(command) => runner.run_until_ctrl_c(command.execute::()), + Commands::Prune(command) => runner.run_until_ctrl_c(command.execute::()), #[cfg(feature = "dev")] Commands::TestVectors(command) => runner.run_until_ctrl_c(command.execute()), } diff --git a/crates/optimism/node/src/lib.rs b/crates/optimism/node/src/lib.rs index f2870d0b839..6419611067e 100644 --- a/crates/optimism/node/src/lib.rs +++ b/crates/optimism/node/src/lib.rs @@ -18,7 +18,7 @@ pub mod engine; pub use engine::OpEngineTypes; pub mod node; -pub use node::OptimismNode; +pub use node::OpNode; pub mod txpool; diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index ae146a60885..2e1f71a5175 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -51,12 +51,12 @@ impl NodePrimitives for OpPrimitives { /// Type configuration for a regular Optimism node. #[derive(Debug, Default, Clone)] #[non_exhaustive] -pub struct OptimismNode { +pub struct OpNode { /// Additional Optimism args pub args: RollupArgs, } -impl OptimismNode { +impl OpNode { /// Creates a new instance of the Optimism node type. pub const fn new(args: RollupArgs) -> Self { Self { args } @@ -92,7 +92,7 @@ impl OptimismNode { } } -impl Node for OptimismNode +impl Node for OpNode where N: FullNodeTypes>, { @@ -119,13 +119,13 @@ where } } -impl NodeTypes for OptimismNode { +impl NodeTypes for OpNode { type Primitives = OpPrimitives; type ChainSpec = OpChainSpec; type StateCommitment = MerklePatriciaTrie; } -impl NodeTypesWithEngine for OptimismNode { +impl NodeTypesWithEngine for OpNode { type Engine = OpEngineTypes; } diff --git a/crates/optimism/node/tests/e2e/utils.rs b/crates/optimism/node/tests/e2e/utils.rs index 16eb974914d..a8afab87ec2 100644 --- a/crates/optimism/node/tests/e2e/utils.rs +++ b/crates/optimism/node/tests/e2e/utils.rs @@ -6,14 +6,14 @@ use reth_e2e_test_utils::{ }; use reth_optimism_chainspec::OpChainSpecBuilder; use reth_optimism_node::{ - node::OptimismAddOns, OpBuiltPayload, OpPayloadBuilderAttributes, OptimismNode, + node::OptimismAddOns, OpBuiltPayload, OpNode as OtherOpNode, OpPayloadBuilderAttributes, }; use reth_payload_builder::EthPayloadBuilderAttributes; use std::sync::Arc; use tokio::sync::Mutex; /// Optimism Node Helper type -pub(crate) type OpNode = NodeHelperType>>; +pub(crate) type OpNode = NodeHelperType>>; pub(crate) async fn setup(num_nodes: usize) -> eyre::Result<(Vec, TaskManager, Wallet)> { let genesis: Genesis = serde_json::from_str(include_str!("../assets/genesis.json")).unwrap(); diff --git a/crates/optimism/node/tests/it/builder.rs b/crates/optimism/node/tests/it/builder.rs index f1dde4c2c0a..3bd2da75557 100644 --- a/crates/optimism/node/tests/it/builder.rs +++ b/crates/optimism/node/tests/it/builder.rs @@ -4,7 +4,7 @@ use reth_db::test_utils::create_test_rw_db; use reth_node_api::FullNodeComponents; use reth_node_builder::{NodeBuilder, NodeConfig}; use reth_optimism_chainspec::BASE_MAINNET; -use reth_optimism_node::{node::OptimismAddOns, OptimismNode}; +use reth_optimism_node::{node::OptimismAddOns, OpNode}; #[test] fn test_basic_setup() { @@ -13,8 +13,8 @@ fn test_basic_setup() { let db = create_test_rw_db(); let _builder = NodeBuilder::new(config) .with_database(db) - .with_types::() - .with_components(OptimismNode::components(Default::default())) + .with_types::() + .with_components(OpNode::components(Default::default())) .with_add_ons(OptimismAddOns::new(None)) .on_component_initialized(move |ctx| { let _provider = ctx.provider(); From 1a091a76432021e2a51187debb50cb5ecba10f3f Mon Sep 17 00:00:00 2001 From: Eniko Nagy <4188977+eenagy@users.noreply.github.com> Date: Wed, 6 Nov 2024 15:44:12 +0700 Subject: [PATCH 023/211] fix: allow SOURCE_DATE_EPOCH to be overridable (#12342) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ac4ad103858..b1908d7b109 100644 --- a/Makefile +++ b/Makefile @@ -62,7 +62,7 @@ install-op: ## Build and install the op-reth binary under `~/.cargo/bin`. build: ## Build the reth binary into `target` directory. cargo build --bin reth --features "$(FEATURES)" --profile "$(PROFILE)" -SOURCE_DATE_EPOCH := $(shell git log -1 --pretty=%ct) +SOURCE_DATE_EPOCH ?= $(shell git log -1 --pretty=%ct) .PHONY: reproducible reproducible: ## Build the reth binary into `target` directory with reproducible builds. Only works for x86_64-unknown-linux-gnu currently SOURCE_DATE_EPOCH=$(SOURCE_DATE_EPOCH) \ From f1ac9b87b8cc3bd1c59a9a463f3c3693c3d3f048 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Wed, 6 Nov 2024 10:45:00 +0100 Subject: [PATCH 024/211] refactor(rpc): simplifications with `DatabaseRef` calls (#12294) --- crates/rpc/rpc-eth-types/src/revm_utils.rs | 2 +- crates/rpc/rpc/src/eth/bundle.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/rpc/rpc-eth-types/src/revm_utils.rs b/crates/rpc/rpc-eth-types/src/revm_utils.rs index 7dc20c52421..ee3c6e7d9a7 100644 --- a/crates/rpc/rpc-eth-types/src/revm_utils.rs +++ b/crates/rpc/rpc-eth-types/src/revm_utils.rs @@ -265,7 +265,7 @@ where { // we need to fetch the account via the `DatabaseRef` to not update the state of the account, // which is modified via `Database::basic_ref` - let mut account_info = DatabaseRef::basic_ref(db, account)?.unwrap_or_default(); + let mut account_info = db.basic_ref(account)?.unwrap_or_default(); if let Some(nonce) = account_override.nonce { account_info.nonce = nonce; diff --git a/crates/rpc/rpc/src/eth/bundle.rs b/crates/rpc/rpc/src/eth/bundle.rs index ec1a43c7548..4d72efd1f8c 100644 --- a/crates/rpc/rpc/src/eth/bundle.rs +++ b/crates/rpc/rpc/src/eth/bundle.rs @@ -156,7 +156,8 @@ where let env = EnvWithHandlerCfg::new_with_cfg_env(cfg, block_env, TxEnv::default()); let db = CacheDB::new(StateProviderDatabase::new(state)); - let initial_coinbase = DatabaseRef::basic_ref(&db, coinbase) + let initial_coinbase = db + .basic_ref(coinbase) .map_err(Eth::Error::from_eth_err)? .map(|acc| acc.balance) .unwrap_or_default(); From 8ec3af65b4f1fea82c8429c68c3fbaf337941ddd Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Wed, 6 Nov 2024 10:45:22 +0100 Subject: [PATCH 025/211] test(tokio-util): add unit tests for `RateLimit` (#12297) --- crates/tokio-util/src/ratelimit.rs | 117 ++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-) diff --git a/crates/tokio-util/src/ratelimit.rs b/crates/tokio-util/src/ratelimit.rs index 16e403f10aa..33a9c5273d8 100644 --- a/crates/tokio-util/src/ratelimit.rs +++ b/crates/tokio-util/src/ratelimit.rs @@ -8,7 +8,7 @@ use std::{ }; use tokio::time::Sleep; -/// Given a [Rate] this type enforces a rate limit. +/// Given a [`Rate`] this type enforces a rate limit. #[derive(Debug)] pub struct RateLimit { rate: Rate, @@ -122,6 +122,7 @@ impl Rate { #[cfg(test)] mod tests { use super::*; + use tokio::time; #[tokio::test] async fn test_rate_limit() { @@ -157,4 +158,118 @@ mod tests { }) .await; } + + #[tokio::test] + async fn test_rate_limit_initialization() { + let rate = Rate::new(5, Duration::from_secs(1)); + let limit = RateLimit::new(rate); + + // Verify the limit is correctly set + assert_eq!(limit.limit(), 5); + } + + #[tokio::test] + async fn test_rate_limit_allows_within_limit() { + let mut limit = RateLimit::new(Rate::new(3, Duration::from_millis(1))); + + // Check that the rate limiter is ready initially + for _ in 0..3 { + poll_fn(|cx| { + // Should be ready within the limit + assert!(limit.poll_ready(cx).is_ready()); + Poll::Ready(()) + }) + .await; + // Signal that a request has been made + limit.tick(); + } + + // After 3 requests, it should be pending (rate limit hit) + poll_fn(|cx| { + // Exceeded limit, should now be limited + assert!(limit.poll_ready(cx).is_pending()); + Poll::Ready(()) + }) + .await; + } + + #[tokio::test] + async fn test_rate_limit_enforces_wait_after_limit() { + let mut limit = RateLimit::new(Rate::new(2, Duration::from_millis(500))); + + // Consume the limit + for _ in 0..2 { + poll_fn(|cx| { + assert!(limit.poll_ready(cx).is_ready()); + Poll::Ready(()) + }) + .await; + limit.tick(); + } + + // Should now be limited (pending) + poll_fn(|cx| { + assert!(limit.poll_ready(cx).is_pending()); + Poll::Ready(()) + }) + .await; + + // Wait until the rate period elapses + time::sleep(limit.rate.duration()).await; + + // Now it should be ready again after the wait + poll_fn(|cx| { + assert!(limit.poll_ready(cx).is_ready()); + Poll::Ready(()) + }) + .await; + } + + #[tokio::test] + async fn test_wait_method_awaits_readiness() { + let mut limit = RateLimit::new(Rate::new(1, Duration::from_millis(500))); + + poll_fn(|cx| { + assert!(limit.poll_ready(cx).is_ready()); + Poll::Ready(()) + }) + .await; + + limit.tick(); + + // The limit should now be exceeded + poll_fn(|cx| { + assert!(limit.poll_ready(cx).is_pending()); + Poll::Ready(()) + }) + .await; + + // The `wait` method should block until the rate period elapses + limit.wait().await; + + // After `wait`, it should now be ready + poll_fn(|cx| { + assert!(limit.poll_ready(cx).is_ready()); + Poll::Ready(()) + }) + .await; + } + + #[tokio::test] + #[should_panic(expected = "RateLimit limited; poll_ready must be called first")] + async fn test_tick_panics_when_limited() { + let mut limit = RateLimit::new(Rate::new(1, Duration::from_secs(1))); + + poll_fn(|cx| { + assert!(limit.poll_ready(cx).is_ready()); + Poll::Ready(()) + }) + .await; + + // Consume the limit + limit.tick(); + + // Attempting to tick again without poll_ready being ready should panic + limit.tick(); + } } From 4bac1530d7f403ae3bca58f736aba9a1911bab4c Mon Sep 17 00:00:00 2001 From: tedison <76473430+edisontim@users.noreply.github.com> Date: Wed, 6 Nov 2024 05:19:15 -0500 Subject: [PATCH 026/211] feat: add gas averages over time into grafana (#12237) --- etc/grafana/dashboards/overview.json | 96 ++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/etc/grafana/dashboards/overview.json b/etc/grafana/dashboards/overview.json index 25cc280fe03..a19d3be8cf6 100644 --- a/etc/grafana/dashboards/overview.json +++ b/etc/grafana/dashboards/overview.json @@ -3017,6 +3017,102 @@ "legendFormat": "Gas/s", "range": true, "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "avg_over_time(reth_sync_execution_gas_per_second{instance=~\"$instance\"}[1m])", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "legendFormat": "Avg Gas/s (1m)", + "range": true, + "refId": "B", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "avg_over_time(reth_sync_execution_gas_per_second{instance=~\"$instance\"}[5m])", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "legendFormat": "Avg Gas/s (5m)", + "range": true, + "refId": "C", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "avg_over_time(reth_sync_execution_gas_per_second{instance=~\"$instance\"}[10m])", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "legendFormat": "Avg Gas/s (10m)", + "range": true, + "refId": "D", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "avg_over_time(reth_sync_execution_gas_per_second{instance=~\"$instance\"}[30m])", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "legendFormat": "Avg Gas/s (30m)", + "range": true, + "refId": "E", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "avg_over_time(reth_sync_execution_gas_per_second{instance=~\"$instance\"}[1h])", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "legendFormat": "Avg Gas/s (1h)", + "range": true, + "refId": "F", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "avg_over_time(reth_sync_execution_gas_per_second{instance=~\"$instance\"}[24h])", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "legendFormat": "Avg Gas/s (24h)", + "range": true, + "refId": "G", + "useBackend": false } ], "title": "Execution throughput", From 4048117bcff47cd720e2bf16a01e031711017040 Mon Sep 17 00:00:00 2001 From: Steven <112043913+stevencartavia@users.noreply.github.com> Date: Wed, 6 Nov 2024 04:20:33 -0600 Subject: [PATCH 027/211] Track time diff between `new_payload` and FCU (#12245) Co-authored-by: Matthias Seitz --- Cargo.lock | 1 + crates/rpc/rpc-engine-api/Cargo.toml | 1 + crates/rpc/rpc-engine-api/src/engine_api.rs | 39 ++++++++++++++++++--- crates/rpc/rpc-engine-api/src/metrics.rs | 2 ++ 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d3fcd59e79f..0f6a62647a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8790,6 +8790,7 @@ dependencies = [ "jsonrpsee-core", "jsonrpsee-types", "metrics", + "parking_lot", "reth-beacon-consensus", "reth-chainspec", "reth-engine-primitives", diff --git a/crates/rpc/rpc-engine-api/Cargo.toml b/crates/rpc/rpc-engine-api/Cargo.toml index 00503f2c1dd..62d1eea3225 100644 --- a/crates/rpc/rpc-engine-api/Cargo.toml +++ b/crates/rpc/rpc-engine-api/Cargo.toml @@ -45,6 +45,7 @@ jsonrpsee-types.workspace = true serde.workspace = true thiserror.workspace = true tracing.workspace = true +parking_lot.workspace = true [dev-dependencies] reth-ethereum-engine-primitives.workspace = true diff --git a/crates/rpc/rpc-engine-api/src/engine_api.rs b/crates/rpc/rpc-engine-api/src/engine_api.rs index 20eeb390ac1..a017c50678f 100644 --- a/crates/rpc/rpc-engine-api/src/engine_api.rs +++ b/crates/rpc/rpc-engine-api/src/engine_api.rs @@ -10,6 +10,7 @@ use alloy_rpc_types_engine::{ }; use async_trait::async_trait; use jsonrpsee_core::RpcResult; +use parking_lot::Mutex; use reth_beacon_consensus::BeaconConsensusEngineHandle; use reth_chainspec::{EthereumHardforks, Hardforks}; use reth_engine_primitives::{EngineTypes, EngineValidator}; @@ -67,6 +68,8 @@ struct EngineApiInner>, } impl @@ -102,6 +105,7 @@ where capabilities, tx_pool, validator, + latest_new_payload_response: Mutex::new(None), }); Self { inner } } @@ -140,11 +144,13 @@ where self.inner .validator .validate_version_specific_fields(EngineApiMessageVersion::V1, payload_or_attrs)?; + Ok(self .inner .beacon_consensus .new_payload(payload, ExecutionPayloadSidecar::none()) - .await?) + .await + .inspect(|_| self.inner.on_new_payload_response())?) } /// See also @@ -164,7 +170,8 @@ where .inner .beacon_consensus .new_payload(payload, ExecutionPayloadSidecar::none()) - .await?) + .await + .inspect(|_| self.inner.on_new_payload_response())?) } /// See also @@ -194,7 +201,8 @@ where parent_beacon_block_root, }), ) - .await?) + .await + .inspect(|_| self.inner.on_new_payload_response())?) } /// See also @@ -225,7 +233,8 @@ where execution_requests, ), ) - .await?) + .await + .inspect(|_| self.inner.on_new_payload_response())?) } /// Sends a message to the beacon consensus engine to update the fork choice _without_ @@ -598,6 +607,8 @@ where state: ForkchoiceState, payload_attrs: Option, ) -> EngineApiResult { + self.inner.record_elapsed_time_on_fcu(); + if let Some(ref attrs) = payload_attrs { let attr_validation_res = self.inner.validator.ensure_well_formed_attributes(version, attrs); @@ -631,6 +642,26 @@ where } } +impl + EngineApiInner +where + EngineT: EngineTypes, +{ + /// Tracks the elapsed time between the new payload response and the received forkchoice update + /// request. + fn record_elapsed_time_on_fcu(&self) { + if let Some(start_time) = self.latest_new_payload_response.lock().take() { + let elapsed_time = start_time.elapsed(); + self.metrics.latency.new_payload_forkchoice_updated_time_diff.record(elapsed_time); + } + } + + /// Updates the timestamp for the latest new payload response. + fn on_new_payload_response(&self) { + self.latest_new_payload_response.lock().replace(Instant::now()); + } +} + #[async_trait] impl EngineApiServer for EngineApi diff --git a/crates/rpc/rpc-engine-api/src/metrics.rs b/crates/rpc/rpc-engine-api/src/metrics.rs index 8d0106f9dd9..9325ce26778 100644 --- a/crates/rpc/rpc-engine-api/src/metrics.rs +++ b/crates/rpc/rpc-engine-api/src/metrics.rs @@ -34,6 +34,8 @@ pub(crate) struct EngineApiLatencyMetrics { pub(crate) fork_choice_updated_v2: Histogram, /// Latency for `engine_forkchoiceUpdatedV3` pub(crate) fork_choice_updated_v3: Histogram, + /// Time diff between `engine_newPayloadV*` and the next FCU + pub(crate) new_payload_forkchoice_updated_time_diff: Histogram, /// Latency for `engine_getPayloadV1` pub(crate) get_payload_v1: Histogram, /// Latency for `engine_getPayloadV2` From 098fa7f6119b332eb64b3fa2e2b4bd9414dbf5c9 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Wed, 6 Nov 2024 12:38:29 +0100 Subject: [PATCH 028/211] feat(engine): use execute_with_state_hook in ExecutorMetrics (#12316) --- Cargo.lock | 12 ++ crates/engine/tree/src/tree/mod.rs | 10 +- crates/evm/Cargo.toml | 1 + crates/evm/src/metrics.rs | 243 ++++++++++++++++++++++++++--- 4 files changed, 239 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f6a62647a7..f70611f7a5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4863,7 +4863,9 @@ dependencies = [ "crossbeam-epoch", "crossbeam-utils", "hashbrown 0.15.0", + "indexmap 2.6.0", "metrics", + "ordered-float", "quanta", "sketches-ddsketch", ] @@ -5404,6 +5406,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "ordered-float" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d501f1a72f71d3c063a6bbc8f7271fa73aa09fe5d6283b6571e2ed176a2537" +dependencies = [ + "num-traits", +] + [[package]] name = "overload" version = "0.1.1" @@ -7440,6 +7451,7 @@ dependencies = [ "auto_impl", "futures-util", "metrics", + "metrics-util", "parking_lot", "reth-chainspec", "reth-consensus", diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index c3e922d11c9..36108e63bf8 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -44,6 +44,7 @@ use reth_revm::database::StateProviderDatabase; use reth_stages_api::ControlFlow; use reth_trie::{updates::TrieUpdates, HashedPostState, TrieInput}; use reth_trie_parallel::parallel_root::{ParallelStateRoot, ParallelStateRootError}; +use revm_primitives::ResultAndState; use std::{ cmp::Ordering, collections::{btree_map, hash_map, BTreeMap, VecDeque}, @@ -2187,7 +2188,14 @@ where let block = block.unseal(); let exec_time = Instant::now(); - let output = self.metrics.executor.execute_metered(executor, (&block, U256::MAX).into())?; + // TODO: create StateRootTask with the receiving end of a channel and + // pass the sending end of the channel to the state hook. + let noop_state_hook = |_result_and_state: &ResultAndState| {}; + let output = self.metrics.executor.execute_metered( + executor, + (&block, U256::MAX).into(), + Box::new(noop_state_hook), + )?; trace!(target: "engine::tree", elapsed=?exec_time.elapsed(), ?block_number, "Executed block"); if let Err(err) = self.consensus.validate_block_post_execution( diff --git a/crates/evm/Cargo.toml b/crates/evm/Cargo.toml index a4ce3c3893b..c895110209b 100644 --- a/crates/evm/Cargo.toml +++ b/crates/evm/Cargo.toml @@ -40,6 +40,7 @@ parking_lot = { workspace = true, optional = true } parking_lot.workspace = true reth-ethereum-forks.workspace = true alloy-consensus.workspace = true +metrics-util = { workspace = true, features = ["debugging"] } [features] default = ["std"] diff --git a/crates/evm/src/metrics.rs b/crates/evm/src/metrics.rs index fbb2b858b15..3464bb96f4c 100644 --- a/crates/evm/src/metrics.rs +++ b/crates/evm/src/metrics.rs @@ -2,14 +2,41 @@ //! //! Block processing related to syncing should take care to update the metrics by using either //! [`ExecutorMetrics::execute_metered`] or [`ExecutorMetrics::metered_one`]. -use std::time::Instant; - +use crate::{execute::Executor, system_calls::OnStateHook}; use metrics::{Counter, Gauge, Histogram}; use reth_execution_types::{BlockExecutionInput, BlockExecutionOutput}; use reth_metrics::Metrics; use reth_primitives::BlockWithSenders; +use revm_primitives::ResultAndState; +use std::time::Instant; + +/// Wrapper struct that combines metrics and state hook +struct MeteredStateHook { + metrics: ExecutorMetrics, + inner_hook: Box, +} + +impl OnStateHook for MeteredStateHook { + fn on_state(&mut self, result_and_state: &ResultAndState) { + // Update the metrics for the number of accounts, storage slots and bytecodes loaded + let accounts = result_and_state.state.keys().len(); + let storage_slots = + result_and_state.state.values().map(|account| account.storage.len()).sum::(); + let bytecodes = result_and_state + .state + .values() + .filter(|account| !account.info.is_empty_code_hash()) + .collect::>() + .len(); + + self.metrics.accounts_loaded_histogram.record(accounts as f64); + self.metrics.storage_slots_loaded_histogram.record(storage_slots as f64); + self.metrics.bytecodes_loaded_histogram.record(bytecodes as f64); -use crate::execute::Executor; + // Call the original state hook + self.inner_hook.on_state(result_and_state); + } +} /// Executor metrics. // TODO(onbjerg): add sload/sstore @@ -65,10 +92,13 @@ impl ExecutorMetrics { /// /// Compared to [`Self::metered_one`], this method additionally updates metrics for the number /// of accounts, storage slots and bytecodes loaded and updated. + /// Execute the given block using the provided [`Executor`] and update metrics for the + /// execution. pub fn execute_metered<'a, E, DB, O, Error>( &self, executor: E, input: BlockExecutionInput<'a, BlockWithSenders>, + state_hook: Box, ) -> Result, Error> where E: Executor< @@ -78,29 +108,16 @@ impl ExecutorMetrics { Error = Error, >, { - let output = self.metered(input.block, || { - executor.execute_with_state_closure(input, |state: &revm::db::State| { - // Update the metrics for the number of accounts, storage slots and bytecodes - // loaded - let accounts = state.cache.accounts.len(); - let storage_slots = state - .cache - .accounts - .values() - .filter_map(|account| { - account.account.as_ref().map(|account| account.storage.len()) - }) - .sum::(); - let bytecodes = state.cache.contracts.len(); - - // Record all state present in the cache state as loaded even though some might have - // been newly created. - // TODO: Consider spitting these into loaded and newly created. - self.accounts_loaded_histogram.record(accounts as f64); - self.storage_slots_loaded_histogram.record(storage_slots as f64); - self.bytecodes_loaded_histogram.record(bytecodes as f64); - }) - })?; + // clone here is cheap, all the metrics are Option>. additionally + // they are gloally registered so that the data recorded in the hook will + // be accessible. + let wrapper = MeteredStateHook { metrics: self.clone(), inner_hook: state_hook }; + + // Store reference to block for metered + let block = input.block; + + // Use metered to execute and track timing/gas metrics + let output = self.metered(block, || executor.execute_with_state_hook(input, wrapper))?; // Update the metrics for the number of accounts, storage slots and bytecodes updated let accounts = output.state.state.len(); @@ -123,3 +140,177 @@ impl ExecutorMetrics { self.metered(input.block, || f(input)) } } + +#[cfg(test)] +mod tests { + use super::*; + use alloy_eips::eip7685::Requests; + use metrics_util::debugging::{DebugValue, DebuggingRecorder, Snapshotter}; + use revm::db::BundleState; + use revm_primitives::{ + Account, AccountInfo, AccountStatus, Bytes, EvmState, EvmStorage, EvmStorageSlot, + ExecutionResult, Output, SuccessReason, B256, U256, + }; + use std::sync::mpsc; + + /// A mock executor that simulates state changes + struct MockExecutor { + result_and_state: ResultAndState, + } + + impl Executor<()> for MockExecutor { + type Input<'a> + = BlockExecutionInput<'a, BlockWithSenders> + where + Self: 'a; + type Output = BlockExecutionOutput<()>; + type Error = std::convert::Infallible; + + fn execute(self, _input: Self::Input<'_>) -> Result { + Ok(BlockExecutionOutput { + state: BundleState::default(), + receipts: vec![], + requests: Requests::default(), + gas_used: 0, + }) + } + fn execute_with_state_closure( + self, + _input: Self::Input<'_>, + _state: F, + ) -> Result + where + F: FnMut(&revm::State<()>), + { + Ok(BlockExecutionOutput { + state: BundleState::default(), + receipts: vec![], + requests: Requests::default(), + gas_used: 0, + }) + } + fn execute_with_state_hook( + self, + _input: Self::Input<'_>, + mut hook: F, + ) -> Result + where + F: OnStateHook + 'static, + { + // Call hook with our mock state + hook.on_state(&self.result_and_state); + + Ok(BlockExecutionOutput { + state: BundleState::default(), + receipts: vec![], + requests: Requests::default(), + gas_used: 0, + }) + } + } + + struct ChannelStateHook { + output: i32, + sender: mpsc::Sender, + } + + impl OnStateHook for ChannelStateHook { + fn on_state(&mut self, _result_and_state: &ResultAndState) { + let _ = self.sender.send(self.output); + } + } + + fn setup_test_recorder() -> Snapshotter { + let recorder = DebuggingRecorder::new(); + let snapshotter = recorder.snapshotter(); + recorder.install().unwrap(); + snapshotter + } + + #[test] + fn test_executor_metrics_hook_metrics_recorded() { + let snapshotter = setup_test_recorder(); + let metrics = ExecutorMetrics::default(); + + let input = BlockExecutionInput { + block: &BlockWithSenders::default(), + total_difficulty: Default::default(), + }; + + let (tx, _rx) = mpsc::channel(); + let expected_output = 42; + let state_hook = Box::new(ChannelStateHook { sender: tx, output: expected_output }); + + let result_and_state = ResultAndState { + result: ExecutionResult::Success { + reason: SuccessReason::Stop, + gas_used: 100, + output: Output::Call(Bytes::default()), + logs: vec![], + gas_refunded: 0, + }, + state: { + let mut state = EvmState::default(); + let storage = + EvmStorage::from_iter([(U256::from(1), EvmStorageSlot::new(U256::from(2)))]); + state.insert( + Default::default(), + Account { + info: AccountInfo { + balance: U256::from(100), + nonce: 10, + code_hash: B256::random(), + code: Default::default(), + }, + storage, + status: AccountStatus::Loaded, + }, + ); + state + }, + }; + let executor = MockExecutor { result_and_state }; + let _result = metrics.execute_metered(executor, input, state_hook).unwrap(); + + let snapshot = snapshotter.snapshot().into_vec(); + + for metric in snapshot { + let metric_name = metric.0.key().name(); + if metric_name == "sync.execution.accounts_loaded_histogram" || + metric_name == "sync.execution.storage_slots_loaded_histogram" || + metric_name == "sync.execution.bytecodes_loaded_histogram" + { + if let DebugValue::Histogram(vs) = metric.3 { + assert!( + vs.iter().any(|v| v.into_inner() > 0.0), + "metric {metric_name} not recorded" + ); + } + } + } + } + + #[test] + fn test_executor_metrics_hook_called() { + let metrics = ExecutorMetrics::default(); + + let input = BlockExecutionInput { + block: &BlockWithSenders::default(), + total_difficulty: Default::default(), + }; + + let (tx, rx) = mpsc::channel(); + let expected_output = 42; + let state_hook = Box::new(ChannelStateHook { sender: tx, output: expected_output }); + + let result_and_state = ResultAndState { + result: ExecutionResult::Revert { gas_used: 0, output: Default::default() }, + state: EvmState::default(), + }; + let executor = MockExecutor { result_and_state }; + let _result = metrics.execute_metered(executor, input, state_hook).unwrap(); + + let actual_output = rx.try_recv().unwrap(); + assert_eq!(actual_output, expected_output); + } +} From d8edf9c80ec2a339486c8b678642c90a59756a12 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Wed, 6 Nov 2024 14:20:51 +0100 Subject: [PATCH 029/211] chore(sdk): define `FullBlock` trait (#12326) --- crates/primitives-traits/src/block/mod.rs | 9 +++++---- crates/primitives-traits/src/lib.rs | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/crates/primitives-traits/src/block/mod.rs b/crates/primitives-traits/src/block/mod.rs index 395cf61df14..519987606ee 100644 --- a/crates/primitives-traits/src/block/mod.rs +++ b/crates/primitives-traits/src/block/mod.rs @@ -6,13 +6,14 @@ use alloc::{fmt, vec::Vec}; use alloy_consensus::BlockHeader; use alloy_primitives::{Address, Sealable, B256}; +use reth_codecs::Compact; use crate::BlockBody; -/// Helper trait, unifies behaviour required of a block header. -pub trait Header: BlockHeader + Sealable {} +/// Helper trait that unifies all behaviour required by block to support full node operations. +pub trait FullBlock: Block + Compact {} -impl Header for T where T: BlockHeader + Sealable {} +impl FullBlock for T where T: Block + Compact {} /// Abstraction of block data type. // todo: make sealable super-trait, depends on @@ -30,7 +31,7 @@ pub trait Block: + Into<(Self::Header, Self::Body)> { /// Header part of the block. - type Header: Header; + type Header: BlockHeader + Sealable; /// The block's body contains the transactions in the block. type Body: BlockBody; diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index 90a6935ae10..02f1664d799 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -31,7 +31,7 @@ mod integer_list; pub use integer_list::{IntegerList, IntegerListError}; pub mod block; -pub use block::{body::BlockBody, Block}; +pub use block::{body::BlockBody, Block, FullBlock}; mod withdrawal; pub use withdrawal::Withdrawals; From 660ca389e76da84aa20eec6255ebdf5d5993339c Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Wed, 6 Nov 2024 14:21:17 +0100 Subject: [PATCH 030/211] chore(sdk): define `FullSignedTx` trait (#12327) --- crates/primitives-traits/src/lib.rs | 5 ++++- crates/primitives-traits/src/transaction/signed.rs | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index 02f1664d799..3316e713541 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -25,7 +25,10 @@ pub mod receipt; pub use receipt::Receipt; pub mod transaction; -pub use transaction::{signed::SignedTransaction, FullTransaction, Transaction}; +pub use transaction::{ + signed::{FullSignedTx, SignedTransaction}, + FullTransaction, Transaction, +}; mod integer_list; pub use integer_list::{IntegerList, IntegerListError}; diff --git a/crates/primitives-traits/src/transaction/signed.rs b/crates/primitives-traits/src/transaction/signed.rs index 4c12437212a..555cc3851f8 100644 --- a/crates/primitives-traits/src/transaction/signed.rs +++ b/crates/primitives-traits/src/transaction/signed.rs @@ -2,12 +2,18 @@ use alloc::fmt; use core::hash::Hash; +use reth_codecs::Compact; use alloy_consensus::Transaction; use alloy_eips::eip2718::{Decodable2718, Encodable2718}; use alloy_primitives::{keccak256, Address, Signature, TxHash, B256}; use revm_primitives::TxEnv; +/// Helper trait that unifies all behaviour required by block to support full node operations. +pub trait FullSignedTx: SignedTransaction + Compact {} + +impl FullSignedTx for T where T: SignedTransaction + Compact {} + /// A signed transaction. pub trait SignedTransaction: fmt::Debug From b5f8c72095d65dc13a986b785ecd1f627a94a582 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 6 Nov 2024 15:27:06 +0100 Subject: [PATCH 031/211] chore: misc trait bounds (#12347) --- crates/payload/basic/src/lib.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index 9c90f7f83e0..867125d808b 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -14,16 +14,14 @@ use alloy_eips::merge::SLOT_DURATION; use alloy_primitives::{Bytes, B256, U256}; use futures_core::ready; use futures_util::FutureExt; -use reth_chainspec::{ChainSpec, EthereumHardforks}; +use reth_chainspec::EthereumHardforks; use reth_evm::state_change::post_block_withdrawals_balance_increments; use reth_payload_builder::{KeepPayloadJobAlive, PayloadId, PayloadJob, PayloadJobGenerator}; use reth_payload_primitives::{ BuiltPayload, PayloadBuilderAttributes, PayloadBuilderError, PayloadKind, }; use reth_primitives::{constants::RETH_CLIENT_VERSION, proofs, SealedHeader, Withdrawals}; -use reth_provider::{ - BlockReaderIdExt, CanonStateNotification, ProviderError, StateProviderFactory, -}; +use reth_provider::{BlockReaderIdExt, CanonStateNotification, StateProviderFactory}; use reth_revm::cached::CachedReads; use reth_tasks::TaskSpawner; use reth_transaction_pool::TransactionPool; @@ -991,12 +989,16 @@ impl WithdrawalsOutcome { /// Returns the withdrawals root. /// /// Returns `None` values pre shanghai -pub fn commit_withdrawals>( +pub fn commit_withdrawals( db: &mut State, chain_spec: &ChainSpec, timestamp: u64, withdrawals: Withdrawals, -) -> Result { +) -> Result +where + DB: Database, + ChainSpec: EthereumHardforks, +{ if !chain_spec.is_shanghai_active_at_timestamp(timestamp) { return Ok(WithdrawalsOutcome::pre_shanghai()) } @@ -1023,7 +1025,7 @@ pub fn commit_withdrawals>( /// /// This compares the total fees of the blocks, higher is better. #[inline(always)] -pub fn is_better_payload(best_payload: Option, new_fees: U256) -> bool { +pub fn is_better_payload(best_payload: Option<&T>, new_fees: U256) -> bool { if let Some(best_payload) = best_payload { new_fees > best_payload.fees() } else { From 12b0637485725ab72f9b2fafccc707249d9d2d11 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Wed, 6 Nov 2024 15:35:47 +0100 Subject: [PATCH 032/211] refactor(trie): small refactor in `HashedPostState::from_reverts` (#12319) Co-authored-by: Matthias Seitz --- crates/trie/db/src/state.rs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/crates/trie/db/src/state.rs b/crates/trie/db/src/state.rs index 4d46183dfda..0d2171604d5 100644 --- a/crates/trie/db/src/state.rs +++ b/crates/trie/db/src/state.rs @@ -7,16 +7,12 @@ use reth_db_api::{ transaction::DbTx, }; use reth_execution_errors::StateRootError; -use reth_primitives::Account; use reth_storage_errors::db::DatabaseError; use reth_trie::{ hashed_cursor::HashedPostStateCursorFactory, trie_cursor::InMemoryTrieCursorFactory, updates::TrieUpdates, HashedPostState, HashedStorage, StateRoot, StateRootProgress, TrieInput, }; -use std::{ - collections::{hash_map, HashMap}, - ops::RangeInclusive, -}; +use std::{collections::HashMap, ops::RangeInclusive}; use tracing::debug; /// Extends [`StateRoot`] with operations specific for working with a database transaction. @@ -222,13 +218,11 @@ impl<'a, TX: DbTx> DatabaseStateRoot<'a, TX> impl DatabaseHashedPostState for HashedPostState { fn from_reverts(tx: &TX, from: BlockNumber) -> Result { // Iterate over account changesets and record value before first occurring account change. - let mut accounts = HashMap::>::default(); + let mut accounts = HashMap::new(); let mut account_changesets_cursor = tx.cursor_read::()?; for entry in account_changesets_cursor.walk_range(from..)? { let (_, AccountBeforeTx { address, info }) = entry?; - if let hash_map::Entry::Vacant(entry) = accounts.entry(address) { - entry.insert(info); - } + accounts.entry(address).or_insert(info); } // Iterate over storage changesets and record value before first occurring storage change. @@ -239,9 +233,7 @@ impl DatabaseHashedPostState for HashedPostState { { let (BlockNumberAddress((_, address)), storage) = entry?; let account_storage = storages.entry(address).or_default(); - if let hash_map::Entry::Vacant(entry) = account_storage.entry(storage.key) { - entry.insert(storage.value); - } + account_storage.entry(storage.key).or_insert(storage.value); } let hashed_accounts = From 38fdc93a126ab2233266a355d5cb0dd048f1fe66 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Wed, 6 Nov 2024 18:50:25 +0400 Subject: [PATCH 033/211] feat: bump alloy (#12215) Co-authored-by: Matthias Seitz --- Cargo.lock | 216 ++++++------ Cargo.toml | 78 ++--- bin/reth-bench/src/bench/context.rs | 7 +- bin/reth-bench/src/bench/new_payload_fcu.rs | 9 +- bin/reth-bench/src/bench/new_payload_only.rs | 5 +- crates/blockchain-tree/src/blockchain_tree.rs | 2 +- crates/consensus/common/src/validation.rs | 5 +- crates/consensus/debug-client/src/client.rs | 18 +- .../debug-client/src/providers/rpc.rs | 6 +- crates/ethereum/node/tests/e2e/p2p.rs | 3 +- crates/ethereum/node/tests/e2e/rpc.rs | 7 +- crates/net/eth-wire-types/src/blocks.rs | 10 +- crates/net/eth-wire-types/src/transactions.rs | 30 +- .../network/tests/it/big_pooled_txs_req.rs | 2 +- crates/net/network/tests/it/requests.rs | 4 +- crates/net/network/tests/it/txgossip.rs | 2 +- crates/optimism/chainspec/src/lib.rs | 8 +- crates/optimism/evm/src/execute.rs | 4 +- crates/optimism/node/src/txpool.rs | 2 +- crates/optimism/rpc/src/eth/transaction.rs | 63 ++-- crates/primitives-traits/src/header/sealed.rs | 7 + .../src/transaction/signed.rs | 2 +- crates/primitives/Cargo.toml | 2 + crates/primitives/src/alloy_compat.rs | 331 ++++++------------ crates/primitives/src/transaction/mod.rs | 154 +++----- crates/primitives/src/transaction/pooled.rs | 58 +-- crates/primitives/src/transaction/sidecar.rs | 108 +----- .../primitives/src/transaction/signature.rs | 94 ++--- crates/primitives/src/transaction/util.rs | 24 +- crates/rpc/rpc-eth-api/src/helpers/block.rs | 6 +- crates/rpc/rpc-eth-api/src/helpers/call.rs | 30 +- crates/rpc/rpc-eth-api/src/helpers/signer.rs | 2 +- crates/rpc/rpc-eth-api/src/helpers/state.rs | 4 +- crates/rpc/rpc-eth-api/src/types.rs | 5 +- crates/rpc/rpc-eth-types/src/simulate.rs | 9 +- crates/rpc/rpc-types-compat/src/block.rs | 95 +---- crates/rpc/rpc-types-compat/src/proof.rs | 6 +- .../rpc-types-compat/src/transaction/mod.rs | 46 +-- crates/rpc/rpc/src/eth/helpers/signer.rs | 8 +- crates/rpc/rpc/src/eth/helpers/types.rs | 97 ++--- crates/rpc/rpc/src/eth/pubsub.rs | 2 +- crates/rpc/rpc/src/otterscan.rs | 8 +- .../codecs/src/alloy/authorization_list.rs | 3 +- crates/storage/codecs/src/alloy/signature.rs | 6 +- .../provider/src/providers/consistent.rs | 4 +- .../src/providers/database/provider.rs | 2 +- .../src/providers/static_file/manager.rs | 2 +- .../storage/provider/src/test_utils/blocks.rs | 8 +- crates/storage/provider/src/writer/mod.rs | 10 +- .../transaction-pool/src/test_utils/mock.rs | 4 +- crates/transaction-pool/src/traits.rs | 2 +- testing/testing-utils/src/generators.rs | 16 +- 52 files changed, 589 insertions(+), 1047 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f70611f7a5c..fba1e61e037 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -112,9 +112,9 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ed961a48297c732a5d97ee321aa8bb5009ecadbcb077d8bec90cb54e651629" +checksum = "7109d565c7157ee2c10beea7911a71130aa6c3cb6dfeaf66905a98f69b96a754" dependencies = [ "alloy-eips", "alloy-primitives", @@ -124,15 +124,16 @@ dependencies = [ "auto_impl", "c-kzg", "derive_more 1.0.0", + "rand 0.8.5", "serde", "serde_with", ] [[package]] name = "alloy-contract" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460ab80ce4bda1c80bcf96fe7460520476f2c7b734581c6567fac2708e2a60ef" +checksum = "08f16c29a39afa238e35ee4ba06ca2e1c3a4764c2096e94c66730688a0471be7" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", @@ -150,9 +151,9 @@ dependencies = [ [[package]] name = "alloy-dyn-abi" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5228b189b18b85761340dc9eaac0141148a8503657b36f9bc3a869413d987ca" +checksum = "85132f2698b520fab3f54beed55a44389f7006a7b557a0261e1e69439dcc1572" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -181,9 +182,9 @@ dependencies = [ [[package]] name = "alloy-eip7702" -version = "0.3.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ffc577390ce50234e02d841214b3dc0bea6aaaae8e04bbf3cb82e9a45da9eb" +checksum = "69fb9fd842fdf10a524bbf2c4de6942ad869c1c8c3d128a1b09e67ed5f7cedbd" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -197,9 +198,9 @@ dependencies = [ [[package]] name = "alloy-eips" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b69e06cf9c37be824b9d26d6d101114fdde6af0c87de2828b414c05c4b3daa71" +checksum = "711de3f04cf728259ff149f725df12a8595b6b10baefafb0a0447201c72d76de" dependencies = [ "alloy-eip2930", "alloy-eip7702", @@ -218,9 +219,9 @@ dependencies = [ [[package]] name = "alloy-genesis" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde15e14944a88bd6a57d325e9a49b75558746fe16aaccc79713ae50a6a9574c" +checksum = "76b8fa6253466bd6f4b5ba3d725d350f7a05de494dd1b8d01537eafe934667e9" dependencies = [ "alloy-primitives", "alloy-serde", @@ -229,9 +230,9 @@ dependencies = [ [[package]] name = "alloy-json-abi" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31a0f0d51db8a1a30a4d98a9f90e090a94c8f44cb4d9eafc7e03aa6d00aae984" +checksum = "ded610181f3dad5810f6ff12d1a99994cf9b42d2fcb7709029352398a5da5ae6" dependencies = [ "alloy-primitives", "alloy-sol-type-parser", @@ -241,9 +242,9 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af5979e0d5a7bf9c7eb79749121e8256e59021af611322aee56e77e20776b4b3" +checksum = "b9278d6d554510136d9e0e4e51de4f5a9a4baffc8975f29e9acd01e12b2e045c" dependencies = [ "alloy-primitives", "alloy-sol-types", @@ -255,9 +256,9 @@ dependencies = [ [[package]] name = "alloy-network" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "204237129086ce5dc17a58025e93739b01b45313841f98fa339eb1d780511e57" +checksum = "85d356983dea86089b05674d5ef88a7168a5c34a523ef62e2e3c8a9847ce0822" dependencies = [ "alloy-consensus", "alloy-eips", @@ -271,14 +272,16 @@ dependencies = [ "async-trait", "auto_impl", "futures-utils-wasm", + "serde", + "serde_json", "thiserror", ] [[package]] name = "alloy-network-primitives" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514f70ee2a953db21631cd817b13a1571474ec77ddc03d47616d5e8203489fde" +checksum = "18fbc9778e7989877465888383a7533c7318a9200d7229336bcc2b0277df36ba" dependencies = [ "alloy-consensus", "alloy-eips", @@ -289,9 +292,9 @@ dependencies = [ [[package]] name = "alloy-node-bindings" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27444ea67d360508753022807cdd0b49a95c878924c9c5f8f32668b7d7768245" +checksum = "6fe5fd811738d37c56318378802b7bc3cc44e4d12b532641374309a10a04c515" dependencies = [ "alloy-genesis", "alloy-primitives", @@ -306,9 +309,9 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8edae627382349b56cd6a7a2106f4fd69b243a9233e560c55c2e03cabb7e1d3c" +checksum = "fd58d377699e6cfeab52c4a9d28bdc4ef37e2bd235ff2db525071fe37a2e9af5" dependencies = [ "alloy-rlp", "arbitrary", @@ -338,9 +341,9 @@ dependencies = [ [[package]] name = "alloy-provider" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4814d141ede360bb6cd1b4b064f1aab9de391e7c4d0d4d50ac89ea4bc1e25fbd" +checksum = "fe3189c8cf3c3e9185862ac0d0b2a9d6bf00e4395746c7ec36307a4db0d5d486" dependencies = [ "alloy-chains", "alloy-consensus", @@ -379,9 +382,9 @@ dependencies = [ [[package]] name = "alloy-pubsub" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ba46eb69ddf7a9925b81f15229cb74658e6eebe5dd30a5b74e2cd040380573" +checksum = "51358f866bcb93b8440c08086557e415c455cdc8d63754fa339611a3e215b038" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -420,9 +423,9 @@ dependencies = [ [[package]] name = "alloy-rpc-client" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc2bd1e7403463a5f2c61e955bcc9d3072b63aa177442b0f9aa6a6d22a941e3" +checksum = "d847913cea3fcd64fb1fe1247fafe15aab4060a2d24e535bbffcaa4670de9a79" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -445,9 +448,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eea9bf1abdd506f985a53533f5ac01296bcd6102c5e139bbc5d40bc468d2c916" +checksum = "37ef8fd215cf81ddb0565815e1592a87377fa1e259db8ca4e683e6659fdf5c08" dependencies = [ "alloy-primitives", "alloy-rpc-types-engine", @@ -458,9 +461,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-admin" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea02c25541fb19eaac4278aa5c41d2d7e0245898887e54a74bfc0f3103e99415" +checksum = "647f703e27edad1f9c97455a6434378ea70b4ca9ae95f5e1559acf354c69bc14" dependencies = [ "alloy-genesis", "alloy-primitives", @@ -470,20 +473,21 @@ dependencies = [ [[package]] name = "alloy-rpc-types-anvil" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2382fc63fb0cf3e02818d547b80cb66cc49a31f8803d0c328402b2008bc13650" +checksum = "6805b1626b084c231b2ec70c05090d45ce914d22e47f6cd4e8426f43098bbdf1" dependencies = [ "alloy-primitives", + "alloy-rpc-types-eth", "alloy-serde", "serde", ] [[package]] name = "alloy-rpc-types-beacon" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45357a642081c8ce235c0ad990c4e9279f5f18a723545076b38cfcc05cc25234" +checksum = "7ed50d4f427bcb5bc561b3e6f45238158db6592deabcfbecb03c7ca9dadafe98" dependencies = [ "alloy-eips", "alloy-primitives", @@ -495,9 +499,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-debug" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5afe3ab1038f90faf56304aa0adf1e6a8c9844615d8f83967f932f3a70390b1" +checksum = "e00a212581221f03d18c4239a1b985d695205a9518468a0b11ef64a143dd0724" dependencies = [ "alloy-primitives", "serde", @@ -505,9 +509,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-engine" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "886d22d41992287a235af2f3af4299b5ced2bcafb81eb835572ad35747476946" +checksum = "7312fb85ef76428f8e20f50d1505494be9d081ffdb5cbf6a25c153c7b530994c" dependencies = [ "alloy-consensus", "alloy-eips", @@ -526,9 +530,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b034779a4850b4b03f5be5ea674a1cf7d746b2da762b34d1860ab45e48ca27" +checksum = "eba7afa617e7942ba5df88ca063a99e9f51e67df2de816fd52513e64926145a3" dependencies = [ "alloy-consensus", "alloy-eips", @@ -547,9 +551,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-mev" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3246948dfa5f5060a9abe04233d741ea656ef076b12958f3242416ce9f375058" +checksum = "8b479e525a57388821d05c99732b3f6195128d8b74c9372329287f5e0d47d0aa" dependencies = [ "alloy-eips", "alloy-primitives", @@ -560,9 +564,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-trace" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e5fb6c5c401321f802f69dcdb95b932f30f8158f6798793f914baac5995628e" +checksum = "563105a7fb420d44bd30bfe043f5bba8b6fe78432d8da99f4148aa7226d90d69" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -574,9 +578,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-txpool" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ad066b49c3b1b5f64cdd2399177a19926a6a15db2dbf11e2098de621f9e7480" +checksum = "f0da9410a730ced6e30cd349e6d9f39bc9e37ca1bb58a39691e276d7a4061631" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -586,9 +590,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "028e72eaa9703e4882344983cfe7636ce06d8cce104a78ea62fd19b46659efc4" +checksum = "5c9f13d8c9180dcced875f91f1876e428941cec151fc501637f68ad30d088d89" dependencies = [ "alloy-primitives", "arbitrary", @@ -598,9 +602,9 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "592c185d7100258c041afac51877660c7bf6213447999787197db4842f0e938e" +checksum = "796f951bcd6a00f9fb53265676eed9fab6feb37d1eb912b70fc2654be5e5a560" dependencies = [ "alloy-primitives", "async-trait", @@ -612,9 +616,9 @@ dependencies = [ [[package]] name = "alloy-signer-local" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6614f02fc1d5b079b2a4a5320018317b506fd0a6d67c1fd5542a71201724986c" +checksum = "56e2a3fb629bbe89cfba73699a4be64d6dc3bd73691f2e43f2a35448294ffbf9" dependencies = [ "alloy-consensus", "alloy-network", @@ -630,9 +634,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841eabaa4710f719fddbc24c95d386eae313f07e6da4babc25830ee37945be0c" +checksum = "8a1b42ac8f45e2f49f4bcdd72cbfde0bb148f5481d403774ffa546e48b83efc1" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", @@ -644,9 +648,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-expander" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6672337f19d837b9f7073c45853aeb528ed9f7dd6a4154ce683e9e5cb7794014" +checksum = "06318f1778e57f36333e850aa71bd1bb5e560c10279e236622faae0470c50412" dependencies = [ "alloy-sol-macro-input", "const-hex", @@ -662,9 +666,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-input" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dff37dd20bfb118b777c96eda83b2067f4226d2644c5cfa00187b3bc01770ba" +checksum = "eaebb9b0ad61a41345a22c9279975c0cdd231b97947b10d7aad1cf0a7181e4a5" dependencies = [ "const-hex", "dunce", @@ -677,9 +681,9 @@ dependencies = [ [[package]] name = "alloy-sol-type-parser" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b853d42292dbb159671a3edae3b2750277ff130f32b726fe07dc2b17aa6f2b5" +checksum = "12c71028bfbfec210e24106a542aad3def7caf1a70e2c05710e92a98481980d3" dependencies = [ "serde", "winnow", @@ -687,9 +691,9 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa828bb1b9a6dc52208fbb18084fb9ce2c30facc2bfda6a5d922349b4990354f" +checksum = "374d7fb042d68ddfe79ccb23359de3007f6d4d53c13f703b64fb0db422132111" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -700,9 +704,9 @@ dependencies = [ [[package]] name = "alloy-transport" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be77579633ebbc1266ae6fd7694f75c408beb1aeb6865d0b18f22893c265a061" +checksum = "4d315ab988e06f6b12038a3d7811957da28a8b378ff0d084b0819ebae1746ead" dependencies = [ "alloy-json-rpc", "base64 0.22.1", @@ -720,9 +724,9 @@ dependencies = [ [[package]] name = "alloy-transport-http" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fd1a5d0827939847983b46f2f79510361f901dc82f8e3c38ac7397af142c6e" +checksum = "166449a8d8867be0978d6fa85aa56b89a27988b09e57bfd1f3b9962a9c8d5bae" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -735,9 +739,9 @@ dependencies = [ [[package]] name = "alloy-transport-ipc" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8073d1186bfeeb8fbdd1292b6f1a0731f3aed8e21e1463905abfae0b96a887a6" +checksum = "716b21dce8e7ea29a5d459ed4b6d29a13a71d2b766fd84ac15e68623662b5d87" dependencies = [ "alloy-json-rpc", "alloy-pubsub", @@ -754,9 +758,9 @@ dependencies = [ [[package]] name = "alloy-transport-ws" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61f27837bb4a1d6c83a28231c94493e814882f0e9058648a97e908a5f3fc9fcf" +checksum = "b577974182a4e6d9b1a1ecd5a7fd48da9d239a1e214e2368d37b3179e86cd8c3" dependencies = [ "alloy-pubsub", "alloy-transport", @@ -5270,9 +5274,9 @@ checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "op-alloy-consensus" -version = "0.5.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26c3b35b7b3e36d15e0563eebffe13c1d9ca16b7aaffcb6a64354633547e16b" +checksum = "ae4582945fa96ae0ed78babcac6e41f025460e30ed0c9781aaeedf878fc2b527" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5288,9 +5292,9 @@ dependencies = [ [[package]] name = "op-alloy-genesis" -version = "0.5.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccacc2efed3d60d98ea581bddb885df1c6c62a592e55de049cfefd94116112cd" +checksum = "d1ece4a037c56536d8b517d045cef9cc07364c578709c184d33817108309c31e" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5302,23 +5306,24 @@ dependencies = [ [[package]] name = "op-alloy-network" -version = "0.5.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ff6fc0f94702ea0f4d8466bffdc990067ae6df9213465df9b7957f74f1e5461" +checksum = "05e9b64d15a7bf27a06c16eb286349aa2d4e3173260a8ab1fe73bd2c13c89769" dependencies = [ "alloy-consensus", "alloy-network", "alloy-primitives", "alloy-rpc-types-eth", + "alloy-signer", "op-alloy-consensus", "op-alloy-rpc-types", ] [[package]] name = "op-alloy-protocol" -version = "0.5.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5f8e6ec6b91c6aaeb20860b455a52fd8e300acfe5d534e96e9073a24f853e74" +checksum = "aa989d1ea8deced466b0edd7a447264b1f934fd740ab895d32b8544dcce3b151" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5336,9 +5341,9 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types" -version = "0.5.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94bae9bf91b620e1e2c2291562e5998bc1247bd8ada011773e1997b31a95de99" +checksum = "ca6e53039829ff0b3482d8dd02cb2de45d5c7b889023c7e4588a43ea7451664a" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5347,6 +5352,7 @@ dependencies = [ "alloy-rpc-types-eth", "alloy-serde", "arbitrary", + "derive_more 1.0.0", "op-alloy-consensus", "serde", "serde_json", @@ -5354,10 +5360,11 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types-engine" -version = "0.5.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b52ee59c86537cff83e8c7f2a6aa287a94f3608bb40c06d442aafd0c2e807a4" +checksum = "283b19e1e7fef1ca9078df39f45a48609cacf856b7b441ed6cf19301ed162cca" dependencies = [ + "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", "alloy-serde", @@ -8442,6 +8449,7 @@ dependencies = [ "alloy-consensus", "alloy-eips", "alloy-genesis", + "alloy-network", "alloy-primitives", "alloy-rlp", "alloy-rpc-types", @@ -9344,9 +9352,9 @@ dependencies = [ [[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", @@ -9359,9 +9367,9 @@ dependencies = [ [[package]] name = "revm-inspectors" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e29c662f7887f3b659d4b0fd234673419a8fcbeaa1ecc29bf7034c0a75cc8ea" +checksum = "747291a18ad6726a08dd73f8b6a6b3a844db582ecae2063ccf0a04880c44f482" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -9378,9 +9386,9 @@ 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", "serde", @@ -9388,9 +9396,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", @@ -9408,9 +9416,9 @@ 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", @@ -10388,9 +10396,9 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16320d4a2021ba1a32470b3759676114a918885e9800e68ad60f2c67969fba62" +checksum = "edf42e81491fb8871b74df3d222c64ae8cbc1269ea509fa768a3ed3e1b0ac8cb" dependencies = [ "paste", "proc-macro2", @@ -10522,18 +10530,18 @@ checksum = "a38c90d48152c236a3ab59271da4f4ae63d678c5d7ad6b7714d7cb9760be5e4b" [[package]] name = "thiserror" -version = "1.0.66" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d171f59dbaa811dbbb1aee1e73db92ec2b122911a48e1390dfe327a821ddede" +checksum = "3b3c6efbfc763e64eb85c11c25320f0737cb7364c4b6336db90aa9ebe27a0bbd" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.66" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b08be0f17bd307950653ce45db00cd31200d82b624b36e181337d9c7d92765b5" +checksum = "b607164372e89797d78b8e23a6d67d5d1038c1c65efd52e1389ef8b77caba2a6" dependencies = [ "proc-macro2", "quote", @@ -11437,9 +11445,9 @@ dependencies = [ [[package]] name = "wasmtimer" -version = "0.2.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7ed9d8b15c7fb594d72bfb4b5a276f3d2029333cd93a932f376f5937f6f80ee" +checksum = "bb4f099acbc1043cc752b91615b24b02d7f6fcd975bd781fed9f50b3c3e15bf7" dependencies = [ "futures", "js-sys", diff --git a/Cargo.toml b/Cargo.toml index 10d39b11b99..b8734afe664 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -418,60 +418,60 @@ reth-trie-db = { path = "crates/trie/db" } reth-trie-parallel = { path = "crates/trie/parallel" } # 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.11.0" +revm-primitives = { version = "14.0.0", features = [ "std", ], default-features = false } # eth alloy-chains = "0.1.32" -alloy-dyn-abi = "0.8.0" -alloy-primitives = { version = "0.8.9", default-features = false } +alloy-dyn-abi = "0.8.11" +alloy-primitives = { version = "0.8.11", default-features = false } alloy-rlp = "0.3.4" -alloy-sol-types = "0.8.0" +alloy-sol-types = "0.8.11" alloy-trie = { version = "0.7", default-features = false } -alloy-consensus = { version = "0.5.4", default-features = false } -alloy-contract = { version = "0.5.4", default-features = false } -alloy-eips = { version = "0.5.4", default-features = false } -alloy-genesis = { version = "0.5.4", default-features = false } -alloy-json-rpc = { version = "0.5.4", default-features = false } -alloy-network = { version = "0.5.4", default-features = false } -alloy-network-primitives = { version = "0.5.4", default-features = false } -alloy-node-bindings = { version = "0.5.4", default-features = false } -alloy-provider = { version = "0.5.4", features = [ +alloy-consensus = { version = "0.6.0", default-features = false } +alloy-contract = { version = "0.6.0", default-features = false } +alloy-eips = { version = "0.6.0", default-features = false } +alloy-genesis = { version = "0.6.0", default-features = false } +alloy-json-rpc = { version = "0.6.0", default-features = false } +alloy-network = { version = "0.6.0", default-features = false } +alloy-network-primitives = { version = "0.6.0", default-features = false } +alloy-node-bindings = { version = "0.6.0", default-features = false } +alloy-provider = { version = "0.6.0", features = [ "reqwest", ], default-features = false } -alloy-pubsub = { version = "0.5.4", default-features = false } -alloy-rpc-client = { version = "0.5.4", default-features = false } -alloy-rpc-types = { version = "0.5.4", features = [ +alloy-pubsub = { version = "0.6.0", default-features = false } +alloy-rpc-client = { version = "0.6.0", default-features = false } +alloy-rpc-types = { version = "0.6.0", features = [ "eth", ], default-features = false } -alloy-rpc-types-admin = { version = "0.5.4", default-features = false } -alloy-rpc-types-anvil = { version = "0.5.4", default-features = false } -alloy-rpc-types-beacon = { version = "0.5.4", default-features = false } -alloy-rpc-types-debug = { version = "0.5.4", default-features = false } -alloy-rpc-types-engine = { version = "0.5.4", default-features = false } -alloy-rpc-types-eth = { version = "0.5.4", default-features = false } -alloy-rpc-types-mev = { version = "0.5.4", default-features = false } -alloy-rpc-types-trace = { version = "0.5.4", default-features = false } -alloy-rpc-types-txpool = { version = "0.5.4", default-features = false } -alloy-serde = { version = "0.5.4", default-features = false } -alloy-signer = { version = "0.5.4", default-features = false } -alloy-signer-local = { version = "0.5.4", default-features = false } -alloy-transport = { version = "0.5.4" } -alloy-transport-http = { version = "0.5.4", features = [ +alloy-rpc-types-admin = { version = "0.6.0", default-features = false } +alloy-rpc-types-anvil = { version = "0.6.0", default-features = false } +alloy-rpc-types-beacon = { version = "0.6.0", default-features = false } +alloy-rpc-types-debug = { version = "0.6.0", default-features = false } +alloy-rpc-types-engine = { version = "0.6.0", default-features = false } +alloy-rpc-types-eth = { version = "0.6.0", default-features = false } +alloy-rpc-types-mev = { version = "0.6.0", default-features = false } +alloy-rpc-types-trace = { version = "0.6.0", default-features = false } +alloy-rpc-types-txpool = { version = "0.6.0", default-features = false } +alloy-serde = { version = "0.6.0", default-features = false } +alloy-signer = { version = "0.6.0", default-features = false } +alloy-signer-local = { version = "0.6.0", default-features = false } +alloy-transport = { version = "0.6.0" } +alloy-transport-http = { version = "0.6.0", features = [ "reqwest-rustls-tls", ], default-features = false } -alloy-transport-ipc = { version = "0.5.4", default-features = false } -alloy-transport-ws = { version = "0.5.4", default-features = false } +alloy-transport-ipc = { version = "0.6.0", default-features = false } +alloy-transport-ws = { version = "0.6.0", default-features = false } # op -op-alloy-rpc-types = "0.5" -op-alloy-rpc-types-engine = "0.5" -op-alloy-network = "0.5" -op-alloy-consensus = "0.5" +op-alloy-rpc-types = "0.6" +op-alloy-rpc-types-engine = "0.6" +op-alloy-network = "0.6" +op-alloy-consensus = "0.6" # misc aquamarine = "0.6" @@ -633,4 +633,4 @@ tracy-client = "0.17.3" #op-alloy-rpc-types = { git = "https://github.com/alloy-rs/op-alloy", rev = "6a042e7681b1" } #op-alloy-rpc-types-engine = { git = "https://github.com/alloy-rs/op-alloy", rev = "6a042e7681b1" } #op-alloy-network = { git = "https://github.com/alloy-rs/op-alloy", rev = "6a042e7681b1" } -#op-alloy-consensus = { git = "https://github.com/alloy-rs/op-alloy", rev = "6a042e7681b1" } \ No newline at end of file +#op-alloy-consensus = { git = "https://github.com/alloy-rs/op-alloy", rev = "6a042e7681b1" } diff --git a/bin/reth-bench/src/bench/context.rs b/bin/reth-bench/src/bench/context.rs index 5f8936934c6..59533bc6e97 100644 --- a/bin/reth-bench/src/bench/context.rs +++ b/bin/reth-bench/src/bench/context.rs @@ -74,14 +74,17 @@ impl BenchContext { let first_block = match benchmark_mode { BenchMode::Continuous => { // fetch Latest block - block_provider.get_block_by_number(BlockNumberOrTag::Latest, true).await?.unwrap() + block_provider + .get_block_by_number(BlockNumberOrTag::Latest, true.into()) + .await? + .unwrap() } BenchMode::Range(ref mut range) => { match range.next() { Some(block_number) => { // fetch first block in range block_provider - .get_block_by_number(block_number.into(), true) + .get_block_by_number(block_number.into(), true.into()) .await? .unwrap() } diff --git a/bin/reth-bench/src/bench/new_payload_fcu.rs b/bin/reth-bench/src/bench/new_payload_fcu.rs index ca5359fb8c2..dd2f863e2c9 100644 --- a/bin/reth-bench/src/bench/new_payload_fcu.rs +++ b/bin/reth-bench/src/bench/new_payload_fcu.rs @@ -43,16 +43,17 @@ impl Command { let (sender, mut receiver) = tokio::sync::mpsc::channel(1000); tokio::task::spawn(async move { while benchmark_mode.contains(next_block) { - let block_res = block_provider.get_block_by_number(next_block.into(), true).await; + let block_res = + block_provider.get_block_by_number(next_block.into(), true.into()).await; let block = block_res.unwrap().unwrap(); let block_hash = block.header.hash; - let block = Block::try_from(block.inner).unwrap().seal(block_hash); + let block = Block::try_from(block).unwrap().seal(block_hash); let head_block_hash = block.hash(); let safe_block_hash = block_provider - .get_block_by_number(block.number.saturating_sub(32).into(), false); + .get_block_by_number(block.number.saturating_sub(32).into(), false.into()); let finalized_block_hash = block_provider - .get_block_by_number(block.number.saturating_sub(64).into(), false); + .get_block_by_number(block.number.saturating_sub(64).into(), false.into()); let (safe, finalized) = tokio::join!(safe_block_hash, finalized_block_hash,); diff --git a/bin/reth-bench/src/bench/new_payload_only.rs b/bin/reth-bench/src/bench/new_payload_only.rs index 85342d1af76..68b2f76527d 100644 --- a/bin/reth-bench/src/bench/new_payload_only.rs +++ b/bin/reth-bench/src/bench/new_payload_only.rs @@ -43,10 +43,11 @@ impl Command { let (sender, mut receiver) = tokio::sync::mpsc::channel(1000); tokio::task::spawn(async move { while benchmark_mode.contains(next_block) { - let block_res = block_provider.get_block_by_number(next_block.into(), true).await; + let block_res = + block_provider.get_block_by_number(next_block.into(), true.into()).await; let block = block_res.unwrap().unwrap(); let block_hash = block.header.hash; - let block = Block::try_from(block.inner).unwrap().seal(block_hash); + let block = Block::try_from(block).unwrap().seal(block_hash); next_block += 1; sender.send(block).await.unwrap(); diff --git a/crates/blockchain-tree/src/blockchain_tree.rs b/crates/blockchain-tree/src/blockchain_tree.rs index 1674081fe70..65e55d7d9f8 100644 --- a/crates/blockchain-tree/src/blockchain_tree.rs +++ b/crates/blockchain-tree/src/blockchain_tree.rs @@ -1377,7 +1377,7 @@ mod tests { use alloy_consensus::{TxEip1559, EMPTY_ROOT_HASH}; use alloy_eips::eip1559::INITIAL_BASE_FEE; use alloy_genesis::{Genesis, GenesisAccount}; - use alloy_primitives::{keccak256, Address, Sealable, Signature, B256}; + use alloy_primitives::{keccak256, Address, PrimitiveSignature as Signature, Sealable, B256}; use assert_matches::assert_matches; use linked_hash_set::LinkedHashSet; use reth_chainspec::{ChainSpecBuilder, MAINNET, MIN_TRANSACTION_GAS}; diff --git a/crates/consensus/common/src/validation.rs b/crates/consensus/common/src/validation.rs index d4dea07dcda..46a9e4d1572 100644 --- a/crates/consensus/common/src/validation.rs +++ b/crates/consensus/common/src/validation.rs @@ -277,7 +277,8 @@ mod tests { use alloy_consensus::{TxEip4844, EMPTY_OMMER_ROOT_HASH, EMPTY_ROOT_HASH}; use alloy_eips::{eip4895::Withdrawal, BlockHashOrNumber}; use alloy_primitives::{ - hex_literal::hex, Address, BlockHash, BlockNumber, Bytes, Parity, Sealable, Signature, U256, + hex_literal::hex, Address, BlockHash, BlockNumber, Bytes, PrimitiveSignature as Signature, + Sealable, U256, }; use mockall::mock; use rand::Rng; @@ -403,7 +404,7 @@ mod tests { blob_versioned_hashes: std::iter::repeat_with(|| rng.gen()).take(num_blobs).collect(), }); - let signature = Signature::new(U256::default(), U256::default(), Parity::Parity(true)); + let signature = Signature::new(U256::default(), U256::default(), true); TransactionSigned::from_transaction_and_signature(request, signature) } diff --git a/crates/consensus/debug-client/src/client.rs b/crates/consensus/debug-client/src/client.rs index a6a59a6a380..b6993a41b90 100644 --- a/crates/consensus/debug-client/src/client.rs +++ b/crates/consensus/debug-client/src/client.rs @@ -1,4 +1,4 @@ -use alloy_consensus::TxEnvelope; +use alloy_consensus::Transaction; use alloy_eips::eip2718::Encodable2718; use alloy_primitives::B256; use alloy_rpc_types::{Block, BlockTransactions}; @@ -184,18 +184,19 @@ pub fn block_to_execution_payload_v3(block: Block) -> ExecutionNewPayload { // https://github.com/ethereum/execution-apis/blob/main/src/engine/cancun.md#specification let versioned_hashes = transactions .iter() - .flat_map(|tx| tx.blob_versioned_hashes.clone().unwrap_or_default()) + .flat_map(|tx| tx.blob_versioned_hashes().unwrap_or_default()) + .copied() .collect(); let payload: ExecutionPayloadV3 = ExecutionPayloadV3 { payload_inner: ExecutionPayloadV2 { payload_inner: ExecutionPayloadV1 { parent_hash: block.header.parent_hash, - fee_recipient: block.header.miner, + fee_recipient: block.header.beneficiary, state_root: block.header.state_root, receipts_root: block.header.receipts_root, logs_bloom: block.header.logs_bloom, - prev_randao: block.header.mix_hash.unwrap(), + prev_randao: block.header.mix_hash, block_number: block.header.number, gas_limit: block.header.gas_limit, gas_used: block.header.gas_used, @@ -205,15 +206,10 @@ pub fn block_to_execution_payload_v3(block: Block) -> ExecutionNewPayload { block_hash: block.header.hash, transactions: transactions .into_iter() - .map(|tx| { - let envelope: TxEnvelope = tx.try_into().unwrap(); - let mut buffer: Vec = vec![]; - envelope.encode_2718(&mut buffer); - buffer.into() - }) + .map(|tx| tx.inner.encoded_2718().into()) .collect(), }, - withdrawals: block.withdrawals.clone().unwrap_or_default(), + withdrawals: block.withdrawals.clone().unwrap_or_default().into_inner(), }, blob_gas_used: block.header.blob_gas_used.unwrap(), excess_blob_gas: block.header.excess_blob_gas.unwrap(), diff --git a/crates/consensus/debug-client/src/providers/rpc.rs b/crates/consensus/debug-client/src/providers/rpc.rs index a8cd15c105a..5312bd55b3f 100644 --- a/crates/consensus/debug-client/src/providers/rpc.rs +++ b/crates/consensus/debug-client/src/providers/rpc.rs @@ -30,9 +30,9 @@ impl BlockProvider for RpcBlockProvider { .expect("failed to subscribe on new blocks") .into_stream(); - while let Some(block) = stream.next().await { + while let Some(header) = stream.next().await { let full_block = ws_provider - .get_block_by_hash(block.header.hash, BlockTransactionsKind::Full) + .get_block_by_hash(header.hash, BlockTransactionsKind::Full) .await .expect("failed to get block") .expect("block not found"); @@ -49,7 +49,7 @@ impl BlockProvider for RpcBlockProvider { .await .expect("failed to create WS provider"); let block: Block = ws_provider - .get_block_by_number(BlockNumberOrTag::Number(block_number), true) + .get_block_by_number(BlockNumberOrTag::Number(block_number), true.into()) .await? .ok_or_else(|| eyre::eyre!("block not found by number {}", block_number))?; Ok(block) diff --git a/crates/ethereum/node/tests/e2e/p2p.rs b/crates/ethereum/node/tests/e2e/p2p.rs index 180b88bbd5a..5b2a6654fbb 100644 --- a/crates/ethereum/node/tests/e2e/p2p.rs +++ b/crates/ethereum/node/tests/e2e/p2p.rs @@ -157,7 +157,8 @@ async fn e2e_test_send_transactions() -> eyre::Result<()> { assert_eq!(second_provider.get_block_number().await?, 0); - let head = provider.get_block_by_number(Default::default(), false).await?.unwrap().header.hash; + let head = + provider.get_block_by_number(Default::default(), false.into()).await?.unwrap().header.hash; second_node.engine_api.update_forkchoice(head, head).await?; let start = std::time::Instant::now(); diff --git a/crates/ethereum/node/tests/e2e/rpc.rs b/crates/ethereum/node/tests/e2e/rpc.rs index 1f7ac32e048..94ae997eed6 100644 --- a/crates/ethereum/node/tests/e2e/rpc.rs +++ b/crates/ethereum/node/tests/e2e/rpc.rs @@ -69,7 +69,7 @@ async fn test_fee_history() -> eyre::Result<()> { let receipt = builder.get_receipt().await?; assert!(receipt.status()); - let block = provider.get_block_by_number(1.into(), false).await?.unwrap(); + let block = provider.get_block_by_number(1.into(), false.into()).await?.unwrap(); assert_eq!(block.header.gas_used as u128, receipt.gas_used,); assert_eq!(block.header.base_fee_per_gas.unwrap(), expected_first_base_fee as u64); @@ -89,7 +89,7 @@ async fn test_fee_history() -> eyre::Result<()> { let fee_history = provider.get_fee_history(block_count, latest_block.into(), &[]).await?; let mut prev_header = provider - .get_block_by_number((latest_block + 1 - block_count).into(), false) + .get_block_by_number((latest_block + 1 - block_count).into(), false.into()) .await? .unwrap() .header; @@ -101,7 +101,8 @@ async fn test_fee_history() -> eyre::Result<()> { chain_spec.base_fee_params_at_block(block), ); - let header = provider.get_block_by_number(block.into(), false).await?.unwrap().header; + let header = + provider.get_block_by_number(block.into(), false.into()).await?.unwrap().header; assert_eq!(header.base_fee_per_gas.unwrap(), expected_base_fee as u64); assert_eq!( diff --git a/crates/net/eth-wire-types/src/blocks.rs b/crates/net/eth-wire-types/src/blocks.rs index ce23dfe707f..c24fc45022f 100644 --- a/crates/net/eth-wire-types/src/blocks.rs +++ b/crates/net/eth-wire-types/src/blocks.rs @@ -114,7 +114,7 @@ mod tests { }; use alloy_consensus::TxLegacy; use alloy_eips::BlockHashOrNumber; - use alloy_primitives::{hex, Parity, Signature, TxKind, U256}; + use alloy_primitives::{hex, PrimitiveSignature as Signature, TxKind, U256}; use alloy_rlp::{Decodable, Encodable}; use reth_primitives::{Header, Transaction, TransactionSigned}; use std::str::FromStr; @@ -373,7 +373,7 @@ mod tests { }), Signature::new( U256::from_str("0x64b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12").unwrap(), U256::from_str("0x64b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10").unwrap(), - Parity::Parity(false), + false, ), ), TransactionSigned::from_transaction_and_signature(Transaction::Legacy(TxLegacy { @@ -387,7 +387,7 @@ mod tests { }), Signature::new( U256::from_str("0x52f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb").unwrap(), U256::from_str("0x52f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb").unwrap(), - Parity::Parity(false), + false, ), ), ], @@ -446,7 +446,7 @@ mod tests { Signature::new( U256::from_str("0x64b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12").unwrap(), U256::from_str("0x64b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10").unwrap(), - Parity::Eip155(37), + false, ), ), TransactionSigned::from_transaction_and_signature( @@ -462,7 +462,7 @@ mod tests { Signature::new( U256::from_str("0x52f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb").unwrap(), U256::from_str("0x52f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb").unwrap(), - Parity::Eip155(37), + false, ), ), ], diff --git a/crates/net/eth-wire-types/src/transactions.rs b/crates/net/eth-wire-types/src/transactions.rs index 7c66f657a1d..97d18001f13 100644 --- a/crates/net/eth-wire-types/src/transactions.rs +++ b/crates/net/eth-wire-types/src/transactions.rs @@ -78,7 +78,7 @@ impl FromIterator for PooledTransactions { mod tests { use crate::{message::RequestPair, GetPooledTransactions, PooledTransactions}; use alloy_consensus::{TxEip1559, TxLegacy}; - use alloy_primitives::{hex, Parity, Signature, TxKind, U256}; + use alloy_primitives::{hex, PrimitiveSignature as Signature, TxKind, U256}; use alloy_rlp::{Decodable, Encodable}; use reth_chainspec::MIN_TRANSACTION_GAS; use reth_primitives::{PooledTransactionsElement, Transaction, TransactionSigned}; @@ -142,7 +142,7 @@ mod tests { "0x64b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10", ) .unwrap(), - Parity::Parity(false), + false, ), ), TransactionSigned::from_transaction_and_signature( @@ -164,7 +164,7 @@ mod tests { "0x52f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb", ) .unwrap(), - Parity::Parity(false), + false, ), ), ]; @@ -208,7 +208,7 @@ mod tests { "0x64b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10", ) .unwrap(), - Parity::Eip155(37), + false, ), ), TransactionSigned::from_transaction_and_signature( @@ -230,7 +230,7 @@ mod tests { "0x52f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb", ) .unwrap(), - Parity::Eip155(37), + false, ), ), ]; @@ -275,7 +275,7 @@ mod tests { "0x612638fb29427ca33b9a3be2a0a561beecfe0269655be160d35e72d366a6a860", ) .unwrap(), - Parity::Eip155(44), + true, ), ), TransactionSigned::from_transaction_and_signature( @@ -299,7 +299,7 @@ mod tests { "0x016b83f4f980694ed2eee4d10667242b1f40dc406901b34125b008d334d47469", ) .unwrap(), - Parity::Parity(true), + true, ), ), TransactionSigned::from_transaction_and_signature( @@ -321,7 +321,7 @@ mod tests { "0x3ca3ae86580e94550d7c071e3a02eadb5a77830947c9225165cf9100901bee88", ) .unwrap(), - Parity::Eip155(43), + false, ), ), TransactionSigned::from_transaction_and_signature( @@ -343,7 +343,7 @@ mod tests { "0x5406ad177223213df262cb66ccbb2f46bfdccfdfbbb5ffdda9e2c02d977631da", ) .unwrap(), - Parity::Eip155(43), + false, ), ), TransactionSigned::from_transaction_and_signature( @@ -365,7 +365,7 @@ mod tests { "0x3a456401896b1b6055311536bf00a718568c744d8c1f9df59879e8350220ca18", ) .unwrap(), - Parity::Eip155(43), + false, ), ), ]; @@ -414,7 +414,7 @@ mod tests { "0x612638fb29427ca33b9a3be2a0a561beecfe0269655be160d35e72d366a6a860", ) .unwrap(), - Parity::Parity(true), + true, ), ), TransactionSigned::from_transaction_and_signature( @@ -438,7 +438,7 @@ mod tests { "0x016b83f4f980694ed2eee4d10667242b1f40dc406901b34125b008d334d47469", ) .unwrap(), - Parity::Parity(true), + true, ), ), TransactionSigned::from_transaction_and_signature( @@ -460,7 +460,7 @@ mod tests { "0x3ca3ae86580e94550d7c071e3a02eadb5a77830947c9225165cf9100901bee88", ) .unwrap(), - Parity::Parity(false), + false, ), ), TransactionSigned::from_transaction_and_signature( @@ -482,7 +482,7 @@ mod tests { "0x5406ad177223213df262cb66ccbb2f46bfdccfdfbbb5ffdda9e2c02d977631da", ) .unwrap(), - Parity::Parity(false), + false, ), ), TransactionSigned::from_transaction_and_signature( @@ -504,7 +504,7 @@ mod tests { "0x3a456401896b1b6055311536bf00a718568c744d8c1f9df59879e8350220ca18", ) .unwrap(), - Parity::Parity(false), + false, ), ), ]; diff --git a/crates/net/network/tests/it/big_pooled_txs_req.rs b/crates/net/network/tests/it/big_pooled_txs_req.rs index 29b62708eee..4d65e3f63ba 100644 --- a/crates/net/network/tests/it/big_pooled_txs_req.rs +++ b/crates/net/network/tests/it/big_pooled_txs_req.rs @@ -1,4 +1,4 @@ -use alloy_primitives::{Signature, B256}; +use alloy_primitives::{PrimitiveSignature as Signature, B256}; use reth_eth_wire::{GetPooledTransactions, PooledTransactions}; use reth_network::{ test_utils::{NetworkEventStream, Testnet}, diff --git a/crates/net/network/tests/it/requests.rs b/crates/net/network/tests/it/requests.rs index 8c00302f7b4..58e46e3fb09 100644 --- a/crates/net/network/tests/it/requests.rs +++ b/crates/net/network/tests/it/requests.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use alloy_consensus::TxEip2930; -use alloy_primitives::{Bytes, Parity, Signature, TxKind, U256}; +use alloy_primitives::{Bytes, PrimitiveSignature as Signature, TxKind, U256}; use rand::Rng; use reth_eth_wire::HeadersDirection; use reth_network::{ @@ -31,7 +31,7 @@ pub fn rng_transaction(rng: &mut impl rand::RngCore) -> TransactionSigned { input: Bytes::from(vec![1, 2]), access_list: Default::default(), }); - let signature = Signature::new(U256::default(), U256::default(), Parity::Parity(true)); + let signature = Signature::new(U256::default(), U256::default(), true); TransactionSigned::from_transaction_and_signature(request, signature) } diff --git a/crates/net/network/tests/it/txgossip.rs b/crates/net/network/tests/it/txgossip.rs index f08a2b2eb96..2e2ee4a031a 100644 --- a/crates/net/network/tests/it/txgossip.rs +++ b/crates/net/network/tests/it/txgossip.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use alloy_consensus::TxLegacy; -use alloy_primitives::{Signature, U256}; +use alloy_primitives::{PrimitiveSignature as Signature, U256}; use futures::StreamExt; use rand::thread_rng; use reth_network::{test_utils::Testnet, NetworkEvent, NetworkEventListenerProvider}; diff --git a/crates/optimism/chainspec/src/lib.rs b/crates/optimism/chainspec/src/lib.rs index 3248625d604..a60a9a22abc 100644 --- a/crates/optimism/chainspec/src/lib.rs +++ b/crates/optimism/chainspec/src/lib.rs @@ -20,7 +20,7 @@ mod op_sepolia; use alloc::{boxed::Box, vec, vec::Vec}; use alloy_chains::Chain; use alloy_genesis::Genesis; -use alloy_primitives::{Bytes, Parity, Signature, B256, U256}; +use alloy_primitives::{Bytes, B256, U256}; pub use base::BASE_MAINNET; pub use base_sepolia::BASE_SEPOLIA; use derive_more::{Constructor, Deref, Display, From, Into}; @@ -256,12 +256,6 @@ pub fn decode_holocene_1559_params(extra_data: Bytes) -> Result<(u32, u32), Deco Ok((u32::from_be_bytes(denominator), u32::from_be_bytes(elasticity))) } -/// Returns the signature for the optimism deposit transactions, which don't include a -/// signature. -pub fn optimism_deposit_tx_signature() -> Signature { - Signature::new(U256::ZERO, U256::ZERO, Parity::Parity(false)) -} - impl EthChainSpec for OpChainSpec { fn chain(&self) -> alloy_chains::Chain { self.inner.chain() diff --git a/crates/optimism/evm/src/execute.rs b/crates/optimism/evm/src/execute.rs index d64f4bd5ea5..3702f13a47d 100644 --- a/crates/optimism/evm/src/execute.rs +++ b/crates/optimism/evm/src/execute.rs @@ -297,7 +297,9 @@ mod tests { use super::*; use crate::OpChainSpec; use alloy_consensus::TxEip1559; - use alloy_primitives::{b256, Address, Signature, StorageKey, StorageValue}; + use alloy_primitives::{ + b256, Address, PrimitiveSignature as Signature, StorageKey, StorageValue, + }; use op_alloy_consensus::TxDeposit; use reth_chainspec::MIN_TRANSACTION_GAS; use reth_evm::execute::{BasicBlockExecutorProvider, BatchExecutor, BlockExecutorProvider}; diff --git a/crates/optimism/node/src/txpool.rs b/crates/optimism/node/src/txpool.rs index b1255a987e9..0edfeec7322 100644 --- a/crates/optimism/node/src/txpool.rs +++ b/crates/optimism/node/src/txpool.rs @@ -231,7 +231,7 @@ pub struct OpL1BlockInfo { mod tests { use crate::txpool::OpTransactionValidator; use alloy_eips::eip2718::Encodable2718; - use alloy_primitives::{Signature, TxKind, U256}; + use alloy_primitives::{PrimitiveSignature as Signature, TxKind, U256}; use op_alloy_consensus::TxDeposit; use reth_chainspec::MAINNET; use reth_primitives::{Transaction, TransactionSigned, TransactionSignedEcRecovered}; diff --git a/crates/optimism/rpc/src/eth/transaction.rs b/crates/optimism/rpc/src/eth/transaction.rs index 6b5954391d9..b019ce0e97f 100644 --- a/crates/optimism/rpc/src/eth/transaction.rs +++ b/crates/optimism/rpc/src/eth/transaction.rs @@ -1,14 +1,13 @@ //! Loads and formats OP transaction RPC response. -use alloy_consensus::Transaction as _; +use alloy_consensus::Signed; use alloy_primitives::{Bytes, B256}; use alloy_rpc_types::TransactionInfo; -use op_alloy_consensus::DepositTransaction; +use op_alloy_consensus::OpTxEnvelope; use op_alloy_rpc_types::Transaction; use reth_node_api::FullNodeComponents; -use reth_primitives::TransactionSignedEcRecovered; +use reth_primitives::{TransactionSigned, TransactionSignedEcRecovered}; use reth_provider::{BlockReaderIdExt, ReceiptProvider, TransactionsProvider}; -use reth_rpc::eth::EthTxBuilder; use reth_rpc_eth_api::{ helpers::{EthSigner, EthTransactions, LoadTransaction, SpawnBlocking}, FromEthApiError, FullEthApiTypes, RpcNodeCore, TransactionCompat, @@ -83,14 +82,25 @@ where tx: TransactionSignedEcRecovered, tx_info: TransactionInfo, ) -> Self::Transaction { - let signed_tx = tx.clone().into_signed(); - let hash = tx.hash; - - let mut inner = EthTxBuilder.fill(tx, tx_info); - - if signed_tx.is_deposit() { - inner.gas_price = Some(signed_tx.max_fee_per_gas()) - } + let from = tx.signer(); + let TransactionSigned { transaction, signature, hash } = tx.into_signed(); + + let inner = match transaction { + reth_primitives::Transaction::Legacy(tx) => { + Signed::new_unchecked(tx, signature, hash).into() + } + reth_primitives::Transaction::Eip2930(tx) => { + Signed::new_unchecked(tx, signature, hash).into() + } + reth_primitives::Transaction::Eip1559(tx) => { + Signed::new_unchecked(tx, signature, hash).into() + } + reth_primitives::Transaction::Eip4844(_) => unreachable!(), + reth_primitives::Transaction::Eip7702(tx) => { + Signed::new_unchecked(tx, signature, hash).into() + } + reth_primitives::Transaction::Deposit(tx) => OpTxEnvelope::Deposit(tx), + }; let deposit_receipt_version = self .inner @@ -100,22 +110,29 @@ where .flatten() .and_then(|receipt| receipt.deposit_receipt_version); + let TransactionInfo { block_hash, block_number, index: transaction_index, .. } = tx_info; + Transaction { - inner, - source_hash: signed_tx.source_hash(), - mint: signed_tx.mint(), - // only include is_system_tx if true: - is_system_tx: (signed_tx.is_deposit() && signed_tx.is_system_transaction()) - .then_some(true), + inner: alloy_rpc_types::Transaction { + inner, + block_hash, + block_number, + transaction_index, + from, + }, deposit_receipt_version, } } fn otterscan_api_truncate_input(tx: &mut Self::Transaction) { - tx.inner.input = tx.inner.input.slice(..4); - } - - fn tx_type(tx: &Self::Transaction) -> u8 { - tx.inner.transaction_type.unwrap_or_default() + let input = match &mut tx.inner.inner { + OpTxEnvelope::Eip1559(tx) => &mut tx.tx_mut().input, + OpTxEnvelope::Eip2930(tx) => &mut tx.tx_mut().input, + OpTxEnvelope::Legacy(tx) => &mut tx.tx_mut().input, + OpTxEnvelope::Eip7702(tx) => &mut tx.tx_mut().input, + OpTxEnvelope::Deposit(tx) => &mut tx.input, + _ => return, + }; + *input = input.slice(..4); } } diff --git a/crates/primitives-traits/src/header/sealed.rs b/crates/primitives-traits/src/header/sealed.rs index 7119a37e742..7552ece31f1 100644 --- a/crates/primitives-traits/src/header/sealed.rs +++ b/crates/primitives-traits/src/header/sealed.rs @@ -1,4 +1,5 @@ use super::Header; +use alloy_consensus::Sealed; use alloy_eips::BlockNumHash; use alloy_primitives::{keccak256, BlockHash, Sealable}; #[cfg(any(test, feature = "test-utils"))] @@ -132,6 +133,12 @@ impl SealedHeader { } } +impl From> for Sealed { + fn from(value: SealedHeader) -> Self { + Self::new_unchecked(value.header, value.hash) + } +} + #[cfg(any(test, feature = "arbitrary"))] impl<'a> arbitrary::Arbitrary<'a> for SealedHeader { fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { diff --git a/crates/primitives-traits/src/transaction/signed.rs b/crates/primitives-traits/src/transaction/signed.rs index 555cc3851f8..c40403865df 100644 --- a/crates/primitives-traits/src/transaction/signed.rs +++ b/crates/primitives-traits/src/transaction/signed.rs @@ -6,7 +6,7 @@ use reth_codecs::Compact; use alloy_consensus::Transaction; use alloy_eips::eip2718::{Decodable2718, Encodable2718}; -use alloy_primitives::{keccak256, Address, Signature, TxHash, B256}; +use alloy_primitives::{keccak256, Address, PrimitiveSignature as Signature, TxHash, B256}; use revm_primitives::TxEnv; /// Helper trait that unifies all behaviour required by block to support full node operations. diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index 5e761f41fe2..04d96aa369a 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -22,6 +22,7 @@ reth-codecs = { workspace = true, optional = true } # ethereum alloy-consensus.workspace = true +alloy-network = { workspace = true, optional = true } alloy-primitives = { workspace = true, features = ["rand", "rlp"] } alloy-rlp = { workspace = true, features = ["arrayvec"] } alloy-rpc-types = { workspace = true, optional = true } @@ -138,6 +139,7 @@ alloy-compat = [ "dep:alloy-rpc-types", "dep:alloy-serde", "dep:op-alloy-rpc-types", + "dep:alloy-network", ] test-utils = [ "reth-primitives-traits/test-utils", diff --git a/crates/primitives/src/alloy_compat.rs b/crates/primitives/src/alloy_compat.rs index d86bd04c7b9..462b27f9c73 100644 --- a/crates/primitives/src/alloy_compat.rs +++ b/crates/primitives/src/alloy_compat.rs @@ -1,26 +1,20 @@ //! Common conversions from alloy types. -use crate::{ - transaction::extract_chain_id, Block, BlockBody, Transaction, TransactionSigned, - TransactionSignedEcRecovered, TransactionSignedNoHash, TxType, -}; +use crate::{Block, BlockBody, Transaction, TransactionSigned}; use alloc::{string::ToString, vec::Vec}; -use alloy_consensus::{ - constants::EMPTY_TRANSACTIONS, Transaction as _, TxEip1559, TxEip2930, TxEip4844, TxLegacy, -}; -use alloy_primitives::{Parity, Signature, TxKind}; -use alloy_rlp::Error as RlpError; +use alloy_consensus::{constants::EMPTY_TRANSACTIONS, Header, TxEnvelope}; +use alloy_network::{AnyHeader, AnyRpcBlock, AnyRpcTransaction, AnyTxEnvelope}; use alloy_serde::WithOtherFields; use op_alloy_rpc_types as _; -impl TryFrom>> for Block { +impl TryFrom for Block { type Error = alloy_rpc_types::ConversionError; - fn try_from( - block: alloy_rpc_types::Block>, - ) -> Result { + fn try_from(block: AnyRpcBlock) -> Result { use alloy_rpc_types::ConversionError; + let block = block.inner; + let transactions = { let transactions: Result, ConversionError> = match block .transactions @@ -35,241 +29,134 @@ impl TryFrom> for Transaction { +impl TryFrom for TransactionSigned { type Error = alloy_rpc_types::ConversionError; - fn try_from(tx: WithOtherFields) -> Result { - use alloy_eips::eip2718::Eip2718Error; + fn try_from(tx: AnyRpcTransaction) -> Result { use alloy_rpc_types::ConversionError; - #[cfg(feature = "optimism")] - let WithOtherFields { inner: tx, other } = tx; - #[cfg(not(feature = "optimism"))] let WithOtherFields { inner: tx, other: _ } = tx; - match tx.transaction_type.map(TryInto::try_into).transpose().map_err(|_| { - ConversionError::Eip2718Error(Eip2718Error::UnexpectedType( - tx.transaction_type.unwrap(), - )) - })? { - None | Some(TxType::Legacy) => { - // legacy - if tx.max_fee_per_gas.is_some() || tx.max_priority_fee_per_gas.is_some() { - return Err(ConversionError::Eip2718Error( - RlpError::Custom("EIP-1559 fields are present in a legacy transaction") - .into(), - )) - } - - // extract the chain id if possible - let chain_id = match tx.chain_id { - Some(chain_id) => Some(chain_id), - None => { - if let Some(signature) = tx.signature { - // TODO: make this error conversion better. This is needed because - // sometimes rpc providers return legacy transactions without a chain id - // explicitly in the response, however those transactions may also have - // a chain id in the signature from eip155 - extract_chain_id(signature.v.to()) - .map_err(|err| ConversionError::Eip2718Error(err.into()))? - .1 - } else { - return Err(ConversionError::MissingChainId) - } - } - }; - - Ok(Self::Legacy(TxLegacy { - chain_id, - nonce: tx.nonce, - gas_price: tx.gas_price.ok_or(ConversionError::MissingGasPrice)?, - gas_limit: tx.gas, - to: tx.to.map_or(TxKind::Create, TxKind::Call), - value: tx.value, - input: tx.input, - })) + let (transaction, signature, hash) = match tx.inner { + AnyTxEnvelope::Ethereum(TxEnvelope::Legacy(tx)) => { + let (tx, signature, hash) = tx.into_parts(); + (Transaction::Legacy(tx), signature, hash) } - Some(TxType::Eip2930) => { - // eip2930 - Ok(Self::Eip2930(TxEip2930 { - chain_id: tx.chain_id.ok_or(ConversionError::MissingChainId)?, - nonce: tx.nonce, - gas_limit: tx.gas, - to: tx.to.map_or(TxKind::Create, TxKind::Call), - value: tx.value, - input: tx.input, - access_list: tx.access_list.ok_or(ConversionError::MissingAccessList)?, - gas_price: tx.gas_price.ok_or(ConversionError::MissingGasPrice)?, - })) + AnyTxEnvelope::Ethereum(TxEnvelope::Eip2930(tx)) => { + let (tx, signature, hash) = tx.into_parts(); + (Transaction::Eip2930(tx), signature, hash) } - Some(TxType::Eip1559) => { - // EIP-1559 - Ok(Self::Eip1559(TxEip1559 { - chain_id: tx.chain_id.ok_or(ConversionError::MissingChainId)?, - nonce: tx.nonce, - max_priority_fee_per_gas: tx - .max_priority_fee_per_gas - .ok_or(ConversionError::MissingMaxPriorityFeePerGas)?, - max_fee_per_gas: tx - .max_fee_per_gas - .ok_or(ConversionError::MissingMaxFeePerGas)?, - gas_limit: tx.gas, - to: tx.to.map_or(TxKind::Create, TxKind::Call), - value: tx.value, - access_list: tx.access_list.ok_or(ConversionError::MissingAccessList)?, - input: tx.input, - })) + AnyTxEnvelope::Ethereum(TxEnvelope::Eip1559(tx)) => { + let (tx, signature, hash) = tx.into_parts(); + (Transaction::Eip1559(tx), signature, hash) } - Some(TxType::Eip4844) => { - // EIP-4844 - Ok(Self::Eip4844(TxEip4844 { - chain_id: tx.chain_id.ok_or(ConversionError::MissingChainId)?, - nonce: tx.nonce, - max_priority_fee_per_gas: tx - .max_priority_fee_per_gas - .ok_or(ConversionError::MissingMaxPriorityFeePerGas)?, - max_fee_per_gas: tx - .max_fee_per_gas - .ok_or(ConversionError::MissingMaxFeePerGas)?, - gas_limit: tx.gas, - to: tx.to.unwrap_or_default(), - value: tx.value, - access_list: tx.access_list.ok_or(ConversionError::MissingAccessList)?, - input: tx.input, - blob_versioned_hashes: tx - .blob_versioned_hashes - .ok_or(ConversionError::MissingBlobVersionedHashes)?, - max_fee_per_blob_gas: tx - .max_fee_per_blob_gas - .ok_or(ConversionError::MissingMaxFeePerBlobGas)?, - })) + AnyTxEnvelope::Ethereum(TxEnvelope::Eip4844(tx)) => { + let (tx, signature, hash) = tx.into_parts(); + (Transaction::Eip4844(tx.into()), signature, hash) } - Some(TxType::Eip7702) => { - // this is currently unsupported as it is not present in alloy due to missing rpc - // specs - Err(ConversionError::Custom("Unimplemented".to_string())) - /* - // EIP-7702 - Ok(Transaction::Eip7702(TxEip7702 { - chain_id: tx.chain_id.ok_or(ConversionError::MissingChainId)?, - nonce: tx.nonce, - max_priority_fee_per_gas: tx - .max_priority_fee_per_gas - .ok_or(ConversionError::MissingMaxPriorityFeePerGas)?, - max_fee_per_gas: tx - .max_fee_per_gas - .ok_or(ConversionError::MissingMaxFeePerGas)?, - gas_limit: tx - .gas - .try_into() - .map_err(|_| ConversionError::Eip2718Error(RlpError::Overflow.into()))?, - to: tx.to.map_or(TxKind::Create, TxKind::Call), - value: tx.value, - access_list: tx.access_list.ok_or(ConversionError::MissingAccessList)?, - authorization_list: tx - .authorization_list - .ok_or(ConversionError::MissingAuthorizationList)?, - input: tx.input, - }))*/ + AnyTxEnvelope::Ethereum(TxEnvelope::Eip7702(tx)) => { + let (tx, signature, hash) = tx.into_parts(); + (Transaction::Eip7702(tx), signature, hash) } #[cfg(feature = "optimism")] - Some(TxType::Deposit) => { - let fields = other - .deserialize_into::() - .map_err(|e| ConversionError::Custom(e.to_string()))?; - Ok(Self::Deposit(op_alloy_consensus::TxDeposit { - source_hash: fields - .source_hash - .ok_or_else(|| ConversionError::Custom("MissingSourceHash".to_string()))?, - from: tx.from, - to: TxKind::from(tx.to), - mint: fields.mint.filter(|n| *n != 0), - value: tx.value, - gas_limit: tx.gas, - is_system_transaction: fields.is_system_tx.unwrap_or(false), - input: tx.input, - })) - } - } - } -} + AnyTxEnvelope::Unknown(alloy_network::UnknownTxEnvelope { hash, inner }) => { + use alloy_consensus::Transaction as _; -impl TryFrom> for TransactionSigned { - type Error = alloy_rpc_types::ConversionError; - - fn try_from(tx: WithOtherFields) -> Result { - use alloy_rpc_types::ConversionError; - - let signature = tx.signature.ok_or(ConversionError::MissingSignature)?; - let transaction: Transaction = tx.try_into()?; - let y_parity = if let Some(y_parity) = signature.y_parity { - y_parity.0 - } else { - match transaction.tx_type() { - // If the transaction type is Legacy, adjust the v component of the - // signature according to the Ethereum specification - TxType::Legacy => { - extract_chain_id(signature.v.to()) - .map_err(|_| ConversionError::InvalidSignature)? - .0 + if inner.ty() == crate::TxType::Deposit { + let fields: op_alloy_rpc_types::OpTransactionFields = inner + .fields + .clone() + .deserialize_into::() + .map_err(|e| ConversionError::Custom(e.to_string()))?; + ( + Transaction::Deposit(op_alloy_consensus::TxDeposit { + source_hash: fields.source_hash.ok_or_else(|| { + ConversionError::Custom("MissingSourceHash".to_string()) + })?, + from: tx.from, + to: revm_primitives::TxKind::from(inner.to()), + mint: fields.mint.filter(|n| *n != 0), + value: inner.value(), + gas_limit: inner.gas_limit(), + is_system_transaction: fields.is_system_tx.unwrap_or(false), + input: inner.input().clone(), + }), + op_alloy_consensus::TxDeposit::signature(), + hash, + ) + } else { + return Err(ConversionError::Custom("unknown transaction type".to_string())) } - _ => !signature.v.is_zero(), } + _ => return Err(ConversionError::Custom("unknown transaction type".to_string())), }; - let mut parity = Parity::Parity(y_parity); - - if matches!(transaction.tx_type(), TxType::Legacy) { - if let Some(chain_id) = transaction.chain_id() { - parity = parity.with_chain_id(chain_id) - } - } - - Ok(Self::from_transaction_and_signature( - transaction, - Signature::new(signature.r, signature.s, parity), - )) - } -} - -impl TryFrom> for TransactionSignedEcRecovered { - type Error = alloy_rpc_types::ConversionError; - - fn try_from(tx: WithOtherFields) -> Result { - use alloy_rpc_types::ConversionError; - - let transaction: TransactionSigned = tx.try_into()?; - - transaction.try_into_ecrecovered().map_err(|_| ConversionError::InvalidSignature) - } -} - -impl TryFrom> for TransactionSignedNoHash { - type Error = alloy_rpc_types::ConversionError; - - fn try_from(tx: WithOtherFields) -> Result { - Ok(Self { - signature: tx.signature.ok_or(Self::Error::MissingSignature)?.try_into()?, - transaction: tx.try_into()?, - }) + Ok(Self { transaction, signature, hash }) } } @@ -278,7 +165,7 @@ impl TryFrom> for TransactionSigne mod tests { use super::*; use alloy_primitives::{address, Address, B256, U256}; - use alloy_rpc_types::Transaction as AlloyTransaction; + use revm_primitives::TxKind; #[test] fn optimism_deposit_tx_conversion_no_mint() { @@ -302,10 +189,11 @@ mod tests { "v": "0x0", "value": "0x0" }"#; - let alloy_tx: WithOtherFields = + let alloy_tx: WithOtherFields> = serde_json::from_str(input).expect("failed to deserialize"); - let reth_tx: Transaction = alloy_tx.try_into().expect("failed to convert"); + let TransactionSigned { transaction: reth_tx, .. } = + alloy_tx.try_into().expect("failed to convert"); if let Transaction::Deposit(deposit_tx) = reth_tx { assert_eq!( deposit_tx.source_hash, @@ -352,10 +240,11 @@ mod tests { "v": "0x0", "value": "0x239c2e16a5ca590000" }"#; - let alloy_tx: WithOtherFields = + let alloy_tx: WithOtherFields> = serde_json::from_str(input).expect("failed to deserialize"); - let reth_tx: Transaction = alloy_tx.try_into().expect("failed to convert"); + let TransactionSigned { transaction: reth_tx, .. } = + alloy_tx.try_into().expect("failed to convert"); if let Transaction::Deposit(deposit_tx) = reth_tx { assert_eq!( diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index 194ddf9c0ce..208474fc6c4 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -3,7 +3,8 @@ #[cfg(any(test, feature = "reth-codec"))] use alloy_consensus::constants::{EIP4844_TX_TYPE_ID, EIP7702_TX_TYPE_ID}; use alloy_consensus::{ - SignableTransaction, Transaction as _, TxEip1559, TxEip2930, TxEip4844, TxEip7702, TxLegacy, + transaction::RlpEcdsaTx, SignableTransaction, Transaction as _, TxEip1559, TxEip2930, + TxEip4844, TxEip7702, TxLegacy, }; use alloy_eips::{ eip1898::BlockHashOrNumber, @@ -11,7 +12,9 @@ use alloy_eips::{ eip2930::AccessList, eip7702::SignedAuthorization, }; -use alloy_primitives::{keccak256, Address, Bytes, ChainId, Signature, TxHash, TxKind, B256, U256}; +use alloy_primitives::{ + keccak256, Address, Bytes, ChainId, PrimitiveSignature as Signature, TxHash, TxKind, B256, U256, +}; use alloy_rlp::{Decodable, Encodable, Error as RlpError, Header}; use core::mem; use derive_more::{AsRef, Deref}; @@ -22,7 +25,7 @@ use once_cell::sync::Lazy as LazyLock; use op_alloy_consensus::DepositTransaction; use rayon::prelude::{IntoParallelIterator, ParallelIterator}; use serde::{Deserialize, Serialize}; -use signature::{decode_with_eip155_chain_id, with_eip155_parity}; +use signature::decode_with_eip155_chain_id; #[cfg(feature = "std")] use std::sync::LazyLock; @@ -34,7 +37,7 @@ pub use pooled::{PooledTransactionsElement, PooledTransactionsElementEcRecovered pub use sidecar::BlobTransaction; pub use compat::FillTxEnv; -pub use signature::{extract_chain_id, legacy_parity, recover_signer, recover_signer_unchecked}; +pub use signature::{recover_signer, recover_signer_unchecked}; pub use tx_type::TxType; pub use variant::TransactionSignedVariant; @@ -383,38 +386,37 @@ impl Transaction { /// This encodes the transaction _without_ the signature, and is only suitable for creating a /// hash intended for signing. - pub fn encode_without_signature(&self, out: &mut dyn bytes::BufMut) { - Encodable::encode(self, out); + pub fn encode_for_signing(&self, out: &mut dyn bytes::BufMut) { + match self { + Self::Legacy(tx) => tx.encode_for_signing(out), + Self::Eip2930(tx) => tx.encode_for_signing(out), + Self::Eip1559(tx) => tx.encode_for_signing(out), + Self::Eip4844(tx) => tx.encode_for_signing(out), + Self::Eip7702(tx) => tx.encode_for_signing(out), + #[cfg(feature = "optimism")] + Self::Deposit(_) => {} + } } - /// Inner encoding function that is used for both rlp [`Encodable`] trait and for calculating - /// hash that for eip2718 does not require rlp header - pub fn encode_with_signature( - &self, - signature: &Signature, - out: &mut dyn bytes::BufMut, - with_header: bool, - ) { + /// Produces EIP-2718 encoding of the transaction + pub fn eip2718_encode(&self, signature: &Signature, out: &mut dyn bytes::BufMut) { match self { Self::Legacy(legacy_tx) => { // do nothing w/ with_header - legacy_tx.encode_with_signature_fields( - &with_eip155_parity(signature, legacy_tx.chain_id), - out, - ) + legacy_tx.eip2718_encode(signature, out); } Self::Eip2930(access_list_tx) => { - access_list_tx.encode_with_signature(signature, out, with_header) + access_list_tx.eip2718_encode(signature, out); } Self::Eip1559(dynamic_fee_tx) => { - dynamic_fee_tx.encode_with_signature(signature, out, with_header) + dynamic_fee_tx.eip2718_encode(signature, out); } - Self::Eip4844(blob_tx) => blob_tx.encode_with_signature(signature, out, with_header), + Self::Eip4844(blob_tx) => blob_tx.eip2718_encode(signature, out), Self::Eip7702(set_code_tx) => { - set_code_tx.encode_with_signature(signature, out, with_header) + set_code_tx.eip2718_encode(signature, out); } #[cfg(feature = "optimism")] - Self::Deposit(deposit_tx) => deposit_tx.encode_inner(out, with_header), + Self::Deposit(deposit_tx) => deposit_tx.eip2718_encode(out), } } @@ -649,46 +651,6 @@ impl Default for Transaction { } } -impl Encodable for Transaction { - /// This encodes the transaction _without_ the signature, and is only suitable for creating a - /// hash intended for signing. - fn encode(&self, out: &mut dyn bytes::BufMut) { - match self { - Self::Legacy(legacy_tx) => { - legacy_tx.encode_for_signing(out); - } - Self::Eip2930(access_list_tx) => { - access_list_tx.encode_for_signing(out); - } - Self::Eip1559(dynamic_fee_tx) => { - dynamic_fee_tx.encode_for_signing(out); - } - Self::Eip4844(blob_tx) => { - blob_tx.encode_for_signing(out); - } - Self::Eip7702(set_code_tx) => { - set_code_tx.encode_for_signing(out); - } - #[cfg(feature = "optimism")] - Self::Deposit(deposit_tx) => { - deposit_tx.encode_inner(out, true); - } - } - } - - fn length(&self) -> usize { - match self { - Self::Legacy(legacy_tx) => legacy_tx.payload_len_for_signature(), - Self::Eip2930(access_list_tx) => access_list_tx.payload_len_for_signature(), - Self::Eip1559(dynamic_fee_tx) => dynamic_fee_tx.payload_len_for_signature(), - Self::Eip4844(blob_tx) => blob_tx.payload_len_for_signature(), - Self::Eip7702(set_code_tx) => set_code_tx.payload_len_for_signature(), - #[cfg(feature = "optimism")] - Self::Deposit(deposit_tx) => deposit_tx.encoded_len(true), - } - } -} - impl alloy_consensus::Transaction for Transaction { fn chain_id(&self) -> Option { match self { @@ -891,7 +853,7 @@ impl TransactionSignedNoHash { pub fn hash(&self) -> B256 { // pre-allocate buffer for the transaction let mut buf = Vec::with_capacity(128 + self.transaction.input().len()); - self.transaction.encode_with_signature(&self.signature, &mut buf, false); + self.transaction.eip2718_encode(&self.signature, &mut buf); keccak256(&buf) } @@ -925,7 +887,7 @@ impl TransactionSignedNoHash { /// This makes it possible to import pre bedrock transactions via the sender recovery stage. pub fn encode_and_recover_unchecked(&self, buffer: &mut Vec) -> Option
{ buffer.clear(); - self.transaction.encode_without_signature(buffer); + self.transaction.encode_for_signing(buffer); // Optimism's Deposit transaction does not have a signature. Directly return the // `from` address. @@ -1034,7 +996,7 @@ impl reth_codecs::Compact for TransactionSignedNoHash { let bitflags = buf.get_u8() as usize; let sig_bit = bitflags & 1; - let (mut signature, buf) = Signature::from_compact(buf, sig_bit); + let (signature, buf) = Signature::from_compact(buf, sig_bit); let zstd_bit = bitflags >> 3; let (transaction, buf) = if zstd_bit != 0 { @@ -1063,10 +1025,6 @@ impl reth_codecs::Compact for TransactionSignedNoHash { Transaction::from_compact(buf, transaction_type) }; - if matches!(transaction, Transaction::Legacy(_)) { - signature = signature.with_parity(legacy_parity(&signature, transaction.chain_id())) - } - (Self { signature, transaction }, buf) } } @@ -1581,28 +1539,24 @@ impl Encodable2718 for TransactionSigned { fn encode_2718_len(&self) -> usize { match &self.transaction { - Transaction::Legacy(legacy_tx) => legacy_tx.encoded_len_with_signature( - &with_eip155_parity(&self.signature, legacy_tx.chain_id), - ), + Transaction::Legacy(legacy_tx) => legacy_tx.eip2718_encoded_length(&self.signature), Transaction::Eip2930(access_list_tx) => { - access_list_tx.encoded_len_with_signature(&self.signature, false) + access_list_tx.eip2718_encoded_length(&self.signature) } Transaction::Eip1559(dynamic_fee_tx) => { - dynamic_fee_tx.encoded_len_with_signature(&self.signature, false) - } - Transaction::Eip4844(blob_tx) => { - blob_tx.encoded_len_with_signature(&self.signature, false) + dynamic_fee_tx.eip2718_encoded_length(&self.signature) } + Transaction::Eip4844(blob_tx) => blob_tx.eip2718_encoded_length(&self.signature), Transaction::Eip7702(set_code_tx) => { - set_code_tx.encoded_len_with_signature(&self.signature, false) + set_code_tx.eip2718_encoded_length(&self.signature) } #[cfg(feature = "optimism")] - Transaction::Deposit(deposit_tx) => deposit_tx.encoded_len(false), + Transaction::Deposit(deposit_tx) => deposit_tx.eip2718_encoded_length(), } } fn encode_2718(&self, out: &mut dyn alloy_rlp::BufMut) { - self.transaction.encode_with_signature(&self.signature, out, false) + self.transaction.eip2718_encode(&self.signature, out) } } @@ -1611,24 +1565,24 @@ impl Decodable2718 for TransactionSigned { match ty.try_into().map_err(|_| Eip2718Error::UnexpectedType(ty))? { TxType::Legacy => Err(Eip2718Error::UnexpectedType(0)), TxType::Eip2930 => { - let (tx, signature, hash) = TxEip2930::decode_signed_fields(buf)?.into_parts(); + let (tx, signature, hash) = TxEip2930::rlp_decode_signed(buf)?.into_parts(); Ok(Self { transaction: Transaction::Eip2930(tx), signature, hash }) } TxType::Eip1559 => { - let (tx, signature, hash) = TxEip1559::decode_signed_fields(buf)?.into_parts(); + let (tx, signature, hash) = TxEip1559::rlp_decode_signed(buf)?.into_parts(); Ok(Self { transaction: Transaction::Eip1559(tx), signature, hash }) } TxType::Eip7702 => { - let (tx, signature, hash) = TxEip7702::decode_signed_fields(buf)?.into_parts(); + let (tx, signature, hash) = TxEip7702::rlp_decode_signed(buf)?.into_parts(); Ok(Self { transaction: Transaction::Eip7702(tx), signature, hash }) } TxType::Eip4844 => { - let (tx, signature, hash) = TxEip4844::decode_signed_fields(buf)?.into_parts(); + let (tx, signature, hash) = TxEip4844::rlp_decode_signed(buf)?.into_parts(); Ok(Self { transaction: Transaction::Eip4844(tx), signature, hash }) } #[cfg(feature = "optimism")] TxType::Deposit => Ok(Self::from_transaction_and_signature( - Transaction::Deposit(TxDeposit::decode(buf)?), + Transaction::Deposit(TxDeposit::rlp_decode(buf)?), TxDeposit::signature(), )), } @@ -1647,22 +1601,12 @@ impl<'a> arbitrary::Arbitrary<'a> for TransactionSigned { let secp = secp256k1::Secp256k1::new(); let key_pair = secp256k1::Keypair::new(&secp, &mut rand::thread_rng()); - let mut signature = crate::sign_message( + let signature = crate::sign_message( B256::from_slice(&key_pair.secret_bytes()[..]), transaction.signature_hash(), ) .unwrap(); - signature = if matches!(transaction, Transaction::Legacy(_)) { - if let Some(chain_id) = transaction.chain_id() { - signature.with_chain_id(chain_id) - } else { - signature.with_parity(alloy_primitives::Parity::NonEip155(bool::arbitrary(u)?)) - } - } else { - signature.with_parity_bool() - }; - #[cfg(feature = "optimism")] // Both `Some(0)` and `None` values are encoded as empty string byte. This introduces // ambiguity in roundtrip tests. Patch the mint value of deposit transaction here, so that @@ -1810,7 +1754,7 @@ pub mod serde_bincode_compat { transaction::serde_bincode_compat::{TxEip1559, TxEip2930, TxEip7702, TxLegacy}, TxEip4844, }; - use alloy_primitives::{Signature, TxHash}; + use alloy_primitives::{PrimitiveSignature as Signature, TxHash}; #[cfg(feature = "optimism")] use op_alloy_consensus::serde_bincode_compat::TxDeposit; use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -2018,7 +1962,7 @@ mod tests { use alloy_consensus::Transaction as _; use alloy_eips::eip2718::{Decodable2718, Encodable2718}; use alloy_primitives::{ - address, b256, bytes, hex, Address, Bytes, Parity, Signature, B256, U256, + address, b256, bytes, hex, Address, Bytes, PrimitiveSignature as Signature, B256, U256, }; use alloy_rlp::{Decodable, Encodable, Error as RlpError}; use reth_chainspec::MIN_TRANSACTION_GAS; @@ -2127,7 +2071,7 @@ mod tests { .unwrap(), U256::from_str("0x3a456401896b1b6055311536bf00a718568c744d8c1f9df59879e8350220ca18") .unwrap(), - Parity::Eip155(43), + false, ); let hash = b256!("a517b206d2223278f860ea017d3626cacad4f52ff51030dc9a96b432f17f8d34"); test_decode_and_encode(&bytes, transaction, signature, Some(hash)); @@ -2147,7 +2091,7 @@ mod tests { .unwrap(), U256::from_str("0x5406ad177223213df262cb66ccbb2f46bfdccfdfbbb5ffdda9e2c02d977631da") .unwrap(), - Parity::Eip155(43), + false, ); test_decode_and_encode(&bytes, transaction, signature, None); @@ -2166,7 +2110,7 @@ mod tests { .unwrap(), U256::from_str("0x3ca3ae86580e94550d7c071e3a02eadb5a77830947c9225165cf9100901bee88") .unwrap(), - Parity::Eip155(43), + false, ); test_decode_and_encode(&bytes, transaction, signature, None); @@ -2187,7 +2131,7 @@ mod tests { .unwrap(), U256::from_str("0x016b83f4f980694ed2eee4d10667242b1f40dc406901b34125b008d334d47469") .unwrap(), - Parity::Parity(true), + true, ); test_decode_and_encode(&bytes, transaction, signature, None); @@ -2206,7 +2150,7 @@ mod tests { .unwrap(), U256::from_str("0x612638fb29427ca33b9a3be2a0a561beecfe0269655be160d35e72d366a6a860") .unwrap(), - Parity::Eip155(44), + true, ); test_decode_and_encode(&bytes, transaction, signature, None); } @@ -2370,7 +2314,7 @@ mod tests { .unwrap(), U256::from_str("0x3a456401896b1b6055311536bf00a718568c744d8c1f9df59879e8350220ca18") .unwrap(), - Parity::Eip155(43), + false, ); let inputs: Vec> = vec![ diff --git a/crates/primitives/src/transaction/pooled.rs b/crates/primitives/src/transaction/pooled.rs index 2d62bb3e685..0d48dd5a443 100644 --- a/crates/primitives/src/transaction/pooled.rs +++ b/crates/primitives/src/transaction/pooled.rs @@ -1,21 +1,17 @@ //! Defines the types for blob transactions, legacy, and other EIP-2718 transactions included in a //! response to `GetPooledTransactions`. -use super::{ - error::TransactionConversionError, - signature::{recover_signer, with_eip155_parity}, - TxEip7702, -}; +use super::{error::TransactionConversionError, signature::recover_signer, TxEip7702}; use crate::{BlobTransaction, Transaction, TransactionSigned, TransactionSignedEcRecovered}; use alloy_eips::eip4844::BlobTransactionSidecar; use alloy_consensus::{ constants::EIP4844_TX_TYPE_ID, - transaction::{TxEip1559, TxEip2930, TxEip4844, TxLegacy}, + transaction::{RlpEcdsaTx, TxEip1559, TxEip2930, TxEip4844, TxLegacy}, SignableTransaction, TxEip4844WithSidecar, }; use alloy_eips::eip2718::{Decodable2718, Eip2718Result, Encodable2718}; -use alloy_primitives::{Address, Signature, TxHash, B256}; +use alloy_primitives::{Address, PrimitiveSignature as Signature, TxHash, B256}; use alloy_rlp::{Decodable, Encodable, Error as RlpError, Header}; use bytes::Buf; use derive_more::{AsRef, Deref}; @@ -402,59 +398,39 @@ impl Encodable2718 for PooledTransactionsElement { fn encode_2718_len(&self) -> usize { match self { Self::Legacy { transaction, signature, .. } => { - // method computes the payload len with a RLP header - transaction.encoded_len_with_signature(&with_eip155_parity( - signature, - transaction.chain_id, - )) + transaction.eip2718_encoded_length(signature) } Self::Eip2930 { transaction, signature, .. } => { - // method computes the payload len without a RLP header - transaction.encoded_len_with_signature(signature, false) + transaction.eip2718_encoded_length(signature) } Self::Eip1559 { transaction, signature, .. } => { - // method computes the payload len without a RLP header - transaction.encoded_len_with_signature(signature, false) + transaction.eip2718_encoded_length(signature) } Self::Eip7702 { transaction, signature, .. } => { - // method computes the payload len without a RLP header - transaction.encoded_len_with_signature(signature, false) + transaction.eip2718_encoded_length(signature) } - Self::BlobTransaction(blob_tx) => { - // the encoding does not use a header, so we set `with_header` to false - blob_tx.payload_len_with_type(false) + Self::BlobTransaction(BlobTransaction { transaction, signature, .. }) => { + transaction.eip2718_encoded_length(signature) } } } fn encode_2718(&self, out: &mut dyn alloy_rlp::BufMut) { - // The encoding of `tx-data` depends on the transaction type. Refer to these docs for more - // information on the exact format: - // - Legacy: TxLegacy::encode_with_signature - // - EIP-2930: TxEip2930::encode_with_signature - // - EIP-1559: TxEip1559::encode_with_signature - // - EIP-4844: BlobTransaction::encode_with_type_inner - // - EIP-7702: TxEip7702::encode_with_signature match self { - Self::Legacy { transaction, signature, .. } => transaction - .encode_with_signature_fields( - &with_eip155_parity(signature, transaction.chain_id), - out, - ), + Self::Legacy { transaction, signature, .. } => { + transaction.eip2718_encode(signature, out) + } Self::Eip2930 { transaction, signature, .. } => { - transaction.encode_with_signature(signature, out, false) + transaction.eip2718_encode(signature, out) } Self::Eip1559 { transaction, signature, .. } => { - transaction.encode_with_signature(signature, out, false) + transaction.eip2718_encode(signature, out) } Self::Eip7702 { transaction, signature, .. } => { - transaction.encode_with_signature(signature, out, false) + transaction.eip2718_encode(signature, out) } - Self::BlobTransaction(blob_tx) => { - // The inner encoding is used with `with_header` set to true, making the final - // encoding: - // `tx_type || rlp([transaction_payload_body, blobs, commitments, proofs]))` - blob_tx.encode_with_type_inner(out, false); + Self::BlobTransaction(BlobTransaction { transaction, signature, .. }) => { + transaction.eip2718_encode(signature, out) } } } diff --git a/crates/primitives/src/transaction/sidecar.rs b/crates/primitives/src/transaction/sidecar.rs index 5bd647d5393..48a02f4e740 100644 --- a/crates/primitives/src/transaction/sidecar.rs +++ b/crates/primitives/src/transaction/sidecar.rs @@ -1,10 +1,9 @@ #![cfg_attr(docsrs, doc(cfg(feature = "c-kzg")))] use crate::{Transaction, TransactionSigned}; -use alloy_consensus::{constants::EIP4844_TX_TYPE_ID, TxEip4844WithSidecar}; +use alloy_consensus::{transaction::RlpEcdsaTx, TxEip4844WithSidecar}; use alloy_eips::eip4844::BlobTransactionSidecar; -use alloy_primitives::{Signature, TxHash}; -use alloy_rlp::Header; +use alloy_primitives::{PrimitiveSignature as Signature, TxHash}; use serde::{Deserialize, Serialize}; /// A response to `GetPooledTransactions` that includes blob data, their commitments, and their @@ -69,107 +68,6 @@ impl BlobTransaction { (transaction, self.transaction.sidecar) } - /// Encodes the [`BlobTransaction`] fields as RLP, with a tx type. If `with_header` is `false`, - /// the following will be encoded: - /// `tx_type (0x03) || rlp([transaction_payload_body, blobs, commitments, proofs])` - /// - /// If `with_header` is `true`, the following will be encoded: - /// `rlp(tx_type (0x03) || rlp([transaction_payload_body, blobs, commitments, proofs]))` - /// - /// NOTE: The header will be a byte string header, not a list header. - pub(crate) fn encode_with_type_inner(&self, out: &mut dyn bytes::BufMut, with_header: bool) { - // Calculate the length of: - // `tx_type || rlp([transaction_payload_body, blobs, commitments, proofs])` - // - // to construct and encode the string header - if with_header { - Header { - list: false, - // add one for the tx type - payload_length: 1 + self.payload_len(), - } - .encode(out); - } - - out.put_u8(EIP4844_TX_TYPE_ID); - - // Now we encode the inner blob transaction: - self.encode_inner(out); - } - - /// Encodes the [`BlobTransaction`] fields as RLP, with the following format: - /// `rlp([transaction_payload_body, blobs, commitments, proofs])` - /// - /// where `transaction_payload_body` is a list: - /// `[chain_id, nonce, max_priority_fee_per_gas, ..., y_parity, r, s]` - /// - /// Note: this should be used only when implementing other RLP encoding methods, and does not - /// represent the full RLP encoding of the blob transaction. - pub(crate) fn encode_inner(&self, out: &mut dyn bytes::BufMut) { - self.transaction.encode_with_signature_fields(&self.signature, out); - } - - /// Outputs the length of the RLP encoding of the blob transaction, including the tx type byte, - /// optionally including the length of a wrapping string header. If `with_header` is `false`, - /// the length of the following will be calculated: - /// `tx_type (0x03) || rlp([transaction_payload_body, blobs, commitments, proofs])` - /// - /// If `with_header` is `true`, the length of the following will be calculated: - /// `rlp(tx_type (0x03) || rlp([transaction_payload_body, blobs, commitments, proofs]))` - pub(crate) fn payload_len_with_type(&self, with_header: bool) -> usize { - if with_header { - // Construct a header and use that to calculate the total length - let wrapped_header = Header { - list: false, - // add one for the tx type byte - payload_length: 1 + self.payload_len(), - }; - - // The total length is now the length of the header plus the length of the payload - // (which includes the tx type byte) - wrapped_header.length() + wrapped_header.payload_length - } else { - // Just add the length of the tx type to the payload length - 1 + self.payload_len() - } - } - - /// Outputs the length of the RLP encoding of the blob transaction with the following format: - /// `rlp([transaction_payload_body, blobs, commitments, proofs])` - /// - /// where `transaction_payload_body` is a list: - /// `[chain_id, nonce, max_priority_fee_per_gas, ..., y_parity, r, s]` - /// - /// Note: this should be used only when implementing other RLP encoding length methods, and - /// does not represent the full RLP encoding of the blob transaction. - pub(crate) fn payload_len(&self) -> usize { - // The `transaction_payload_body` length is the length of the fields, plus the length of - // its list header. - let tx_header = Header { - list: true, - payload_length: self.transaction.tx.fields_len() + self.signature.rlp_vrs_len(), - }; - - let tx_length = tx_header.length() + tx_header.payload_length; - - // The payload length is the length of the `tranascation_payload_body` list, plus the - // length of the blobs, commitments, and proofs. - let payload_length = tx_length + self.transaction.sidecar.rlp_encoded_fields_length(); - - // We use the calculated payload len to construct the first list header, which encompasses - // everything in the tx - the length of the second, inner list header is part of - // payload_length - let blob_tx_header = Header { list: true, payload_length }; - - // The final length is the length of: - // * the outer blob tx header + - // * the inner tx header + - // * the inner tx fields + - // * the signature fields + - // * the sidecar fields - blob_tx_header.length() + blob_tx_header.payload_length - } - /// Decodes a [`BlobTransaction`] from RLP. This expects the encoding to be: /// `rlp([transaction_payload_body, blobs, commitments, proofs])` /// @@ -180,7 +78,7 @@ impl BlobTransaction { /// represent the full RLP decoding of the `PooledTransactionsElement` type. pub(crate) fn decode_inner(data: &mut &[u8]) -> alloy_rlp::Result { let (transaction, signature, hash) = - TxEip4844WithSidecar::decode_signed_fields(data)?.into_parts(); + TxEip4844WithSidecar::rlp_decode_signed(data)?.into_parts(); Ok(Self { transaction, hash, signature }) } diff --git a/crates/primitives/src/transaction/signature.rs b/crates/primitives/src/transaction/signature.rs index b73206e6e77..ef4fab0fccb 100644 --- a/crates/primitives/src/transaction/signature.rs +++ b/crates/primitives/src/transaction/signature.rs @@ -1,6 +1,7 @@ use crate::transaction::util::secp256k1; -use alloy_primitives::{Address, Parity, Signature, B256, U256}; -use alloy_rlp::{Decodable, Error as RlpError}; +use alloy_consensus::transaction::from_eip155_value; +use alloy_primitives::{Address, PrimitiveSignature as Signature, B256, U256}; +use alloy_rlp::Decodable; /// The order of the secp256k1 curve, divided by two. Signatures that should be checked according /// to EIP-2 should have an S value less than or equal to this. @@ -14,25 +15,23 @@ const SECP256K1N_HALF: U256 = U256::from_be_bytes([ pub(crate) fn decode_with_eip155_chain_id( buf: &mut &[u8], ) -> alloy_rlp::Result<(Signature, Option)> { - let v: Parity = Decodable::decode(buf)?; + let v: u64 = Decodable::decode(buf)?; let r: U256 = Decodable::decode(buf)?; let s: U256 = Decodable::decode(buf)?; - #[cfg(not(feature = "optimism"))] - if matches!(v, Parity::Parity(_)) { - return Err(alloy_rlp::Error::Custom("invalid parity for legacy transaction")); - } - - #[cfg(feature = "optimism")] - // pre bedrock system transactions were sent from the zero address as legacy - // transactions with an empty signature - // - // NOTE: this is very hacky and only relevant for op-mainnet pre bedrock - if matches!(v, Parity::Parity(false)) && r.is_zero() && s.is_zero() { - return Ok((Signature::new(r, s, Parity::Parity(false)), None)) - } + let Some((parity, chain_id)) = from_eip155_value(v) else { + // pre bedrock system transactions were sent from the zero address as legacy + // transactions with an empty signature + // + // NOTE: this is very hacky and only relevant for op-mainnet pre bedrock + #[cfg(feature = "optimism")] + if v == 0 && r.is_zero() && s.is_zero() { + return Ok((Signature::new(r, s, false), None)) + } + return Err(alloy_rlp::Error::Custom("invalid parity for legacy transaction")) + }; - Ok((Signature::new(r, s, v), v.chain_id())) + Ok((Signature::new(r, s, parity), chain_id)) } /// Recover signer from message hash, _without ensuring that the signature has a low `s` @@ -46,7 +45,7 @@ pub fn recover_signer_unchecked(signature: &Signature, hash: B256) -> Option()); sig[32..64].copy_from_slice(&signature.s().to_be_bytes::<32>()); - sig[64] = signature.v().y_parity_byte(); + sig[64] = signature.v() as u8; // NOTE: we are removing error from underlying crypto library as it will restrain primitive // errors and we care only if recovery is passing or not. @@ -66,68 +65,15 @@ pub fn recover_signer(signature: &Signature, hash: B256) -> Option
{ recover_signer_unchecked(signature, hash) } -/// Returns [Parity] value based on `chain_id` for legacy transaction signature. -#[allow(clippy::missing_const_for_fn)] -pub fn legacy_parity(signature: &Signature, chain_id: Option) -> Parity { - if let Some(chain_id) = chain_id { - Parity::Parity(signature.v().y_parity()).with_chain_id(chain_id) - } else { - #[cfg(feature = "optimism")] - // pre bedrock system transactions were sent from the zero address as legacy - // transactions with an empty signature - // - // NOTE: this is very hacky and only relevant for op-mainnet pre bedrock - if *signature == op_alloy_consensus::TxDeposit::signature() { - return Parity::Parity(false) - } - Parity::NonEip155(signature.v().y_parity()) - } -} - -/// Returns a signature with the given chain ID applied to the `v` value. -pub(crate) fn with_eip155_parity(signature: &Signature, chain_id: Option) -> Signature { - Signature::new(signature.r(), signature.s(), legacy_parity(signature, chain_id)) -} - -/// Outputs (`odd_y_parity`, `chain_id`) from the `v` value. -/// This doesn't check validity of the `v` value for optimism. -#[inline] -pub const fn extract_chain_id(v: u64) -> alloy_rlp::Result<(bool, Option)> { - if v < 35 { - // non-EIP-155 legacy scheme, v = 27 for even y-parity, v = 28 for odd y-parity - if v != 27 && v != 28 { - return Err(RlpError::Custom("invalid Ethereum signature (V is not 27 or 28)")) - } - Ok((v == 28, None)) - } else { - // EIP-155: v = {0, 1} + CHAIN_ID * 2 + 35 - let odd_y_parity = ((v - 35) % 2) != 0; - let chain_id = (v - 35) >> 1; - Ok((odd_y_parity, Some(chain_id))) - } -} - #[cfg(test)] mod tests { use crate::transaction::signature::{ - legacy_parity, recover_signer, recover_signer_unchecked, SECP256K1N_HALF, + recover_signer, recover_signer_unchecked, SECP256K1N_HALF, }; use alloy_eips::eip2718::Decodable2718; - use alloy_primitives::{hex, Address, Parity, Signature, B256, U256}; + use alloy_primitives::{hex, Address, PrimitiveSignature as Signature, B256, U256}; use std::str::FromStr; - #[test] - fn test_legacy_parity() { - // Select 1 as an arbitrary nonzero value for R and S, as v() always returns 0 for (0, 0). - let signature = Signature::new(U256::from(1), U256::from(1), Parity::Parity(false)); - assert_eq!(Parity::NonEip155(false), legacy_parity(&signature, None)); - assert_eq!(Parity::Eip155(37), legacy_parity(&signature, Some(1))); - - let signature = Signature::new(U256::from(1), U256::from(1), Parity::Parity(true)); - assert_eq!(Parity::NonEip155(true), legacy_parity(&signature, None)); - assert_eq!(Parity::Eip155(38), legacy_parity(&signature, Some(1))); - } - #[test] fn test_recover_signer() { let signature = Signature::new( @@ -139,7 +85,7 @@ mod tests { "46948507304638947509940763649030358759909902576025900602547168820602576006531", ) .unwrap(), - Parity::Parity(false), + false, ); let hash = B256::from_str("daf5a779ae972f972197303d7b574746c7ef83eadac0f2791ad23db92e4c8e53") diff --git a/crates/primitives/src/transaction/util.rs b/crates/primitives/src/transaction/util.rs index ff2c2e0dab5..7964cc1c5f0 100644 --- a/crates/primitives/src/transaction/util.rs +++ b/crates/primitives/src/transaction/util.rs @@ -1,4 +1,4 @@ -use alloy_primitives::{Address, Signature}; +use alloy_primitives::{Address, PrimitiveSignature as Signature}; #[cfg(feature = "secp256k1")] pub(crate) mod secp256k1 { @@ -18,7 +18,7 @@ mod impl_secp256k1 { ecdsa::{RecoverableSignature, RecoveryId}, Message, PublicKey, SecretKey, SECP256K1, }; - use alloy_primitives::{keccak256, Parity, B256, U256}; + use alloy_primitives::{keccak256, B256, U256}; /// Recovers the address of the sender using secp256k1 pubkey recovery. /// @@ -44,7 +44,7 @@ mod impl_secp256k1 { let signature = Signature::new( U256::try_from_be_slice(&data[..32]).expect("The slice has at most 32 bytes"), U256::try_from_be_slice(&data[32..64]).expect("The slice has at most 32 bytes"), - Parity::Parity(rec_id.to_i32() != 0), + rec_id.to_i32() != 0, ); Ok(signature) } @@ -62,7 +62,7 @@ mod impl_secp256k1 { #[cfg_attr(feature = "secp256k1", allow(unused, unreachable_pub))] mod impl_k256 { use super::*; - use alloy_primitives::{keccak256, Parity, B256, U256}; + use alloy_primitives::{keccak256, B256}; pub(crate) use k256::ecdsa::Error; use k256::ecdsa::{RecoveryId, SigningKey, VerifyingKey}; @@ -92,15 +92,7 @@ mod impl_k256 { /// Returns the corresponding signature. pub fn sign_message(secret: B256, message: B256) -> Result { let sec = SigningKey::from_slice(secret.as_ref())?; - let (sig, rec_id) = sec.sign_prehash_recoverable(&message.0)?; - let (r, s) = sig.split_bytes(); - - let signature = Signature::new( - U256::try_from_be_slice(&r).expect("The slice has at most 32 bytes"), - U256::try_from_be_slice(&s).expect("The slice has at most 32 bytes"), - Parity::Parity(rec_id.is_y_odd()), - ); - Ok(signature) + sec.sign_prehash_recoverable(&message.0).map(Into::into) } /// Converts a public key into an ethereum address by hashing the encoded public key with @@ -131,7 +123,7 @@ mod tests { let mut sig: [u8; 65] = [0; 65]; sig[0..32].copy_from_slice(&signature.r().to_be_bytes::<32>()); sig[32..64].copy_from_slice(&signature.s().to_be_bytes::<32>()); - sig[64] = signature.v().y_parity_byte(); + sig[64] = signature.v() as u8; assert_eq!(recover_signer_unchecked(&sig, &hash), Ok(signer)); } @@ -189,14 +181,14 @@ mod tests { sig[0..32].copy_from_slice(&secp256k1_signature.r().to_be_bytes::<32>()); sig[32..64].copy_from_slice(&secp256k1_signature.s().to_be_bytes::<32>()); - sig[64] = secp256k1_signature.v().y_parity_byte(); + sig[64] = secp256k1_signature.v() as u8; let secp256k1_recovered = impl_secp256k1::recover_signer_unchecked(&sig, &hash).expect("secp256k1 recover"); assert_eq!(secp256k1_recovered, secp256k1_signer); sig[0..32].copy_from_slice(&k256_signature.r().to_be_bytes::<32>()); sig[32..64].copy_from_slice(&k256_signature.s().to_be_bytes::<32>()); - sig[64] = k256_signature.v().y_parity_byte(); + sig[64] = k256_signature.v() as u8; let k256_recovered = impl_k256::recover_signer_unchecked(&sig, &hash).expect("k256 recover"); assert_eq!(k256_recovered, k256_signer); diff --git a/crates/rpc/rpc-eth-api/src/helpers/block.rs b/crates/rpc/rpc-eth-api/src/helpers/block.rs index bb8fd08ed87..a9794af004a 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/block.rs @@ -3,11 +3,11 @@ use std::sync::Arc; use alloy_eips::BlockId; -use alloy_rpc_types::{Header, Index}; +use alloy_rpc_types::{Block, Header, Index}; use futures::Future; use reth_primitives::{Receipt, SealedBlock, SealedBlockWithSenders}; use reth_provider::{BlockIdReader, BlockReader, BlockReaderIdExt, HeaderProvider}; -use reth_rpc_types_compat::block::{from_block, uncle_block_from_header}; +use reth_rpc_types_compat::block::from_block; use crate::{node::RpcNodeCoreExt, FromEthApiError, FullEthApiTypes, RpcBlock, RpcReceipt}; @@ -189,7 +189,7 @@ pub trait EthBlocks: LoadBlock { } .unwrap_or_default(); - Ok(uncles.into_iter().nth(index.into()).map(uncle_block_from_header)) + Ok(uncles.into_iter().nth(index.into()).map(Block::uncle_from_header)) } } } diff --git a/crates/rpc/rpc-eth-api/src/helpers/call.rs b/crates/rpc/rpc-eth-api/src/helpers/call.rs index b90577c1486..10148fbe78b 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/call.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/call.rs @@ -5,6 +5,7 @@ use crate::{ AsEthApiError, FromEthApiError, FromEvmError, FullEthApiTypes, IntoEthApiError, RpcBlock, RpcNodeCore, }; +use alloy_consensus::BlockHeader; use alloy_eips::{eip1559::calc_next_block_base_fee, eip2930::AccessListResult}; use alloy_primitives::{Address, Bytes, TxKind, B256, U256}; use alloy_rpc_types::{ @@ -125,9 +126,9 @@ pub trait EthCall: Call + LoadPendingBlock { let base_fee = if let Some(latest) = blocks.last() { let header = &latest.inner.header; calc_next_block_base_fee( - header.gas_used, - header.gas_limit, - header.base_fee_per_gas.unwrap_or_default(), + header.gas_used(), + header.gas_limit(), + header.base_fee_per_gas().unwrap_or_default(), base_fee_params, ) } else { @@ -192,19 +193,20 @@ pub trait EthCall: Call + LoadPendingBlock { results.push((env.tx.caller, res.result)); } - let block = simulate::build_block( - results, - transactions, - &block_env, - parent_hash, - total_difficulty, - return_full_transactions, - &db, - this.tx_resp_builder(), - )?; + let block: SimulatedBlock> = + simulate::build_block( + results, + transactions, + &block_env, + parent_hash, + total_difficulty, + return_full_transactions, + &db, + this.tx_resp_builder(), + )?; parent_hash = block.inner.header.hash; - gas_used += block.inner.header.gas_used; + gas_used += block.inner.header.gas_used(); blocks.push(block); } diff --git a/crates/rpc/rpc-eth-api/src/helpers/signer.rs b/crates/rpc/rpc-eth-api/src/helpers/signer.rs index 36e9277400f..dc8beab38a0 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/signer.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/signer.rs @@ -1,7 +1,7 @@ //! An abstraction over ethereum signers. use alloy_dyn_abi::TypedData; -use alloy_primitives::{Address, Signature}; +use alloy_primitives::{Address, PrimitiveSignature as Signature}; use alloy_rpc_types_eth::TransactionRequest; use dyn_clone::DynClone; use reth_primitives::TransactionSigned; diff --git a/crates/rpc/rpc-eth-api/src/helpers/state.rs b/crates/rpc/rpc-eth-api/src/helpers/state.rs index 702572064c5..f3796b4b9bb 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/state.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/state.rs @@ -74,7 +74,7 @@ pub trait EthState: LoadState + SpawnBlocking { self.spawn_blocking_io(move |this| { Ok(B256::new( this.state_at_block_id_or_latest(block_id)? - .storage(address, index.0) + .storage(address, index.as_b256()) .map_err(Self::Error::from_eth_err)? .unwrap_or_default() .to_be_bytes(), @@ -118,7 +118,7 @@ pub trait EthState: LoadState + SpawnBlocking { self.spawn_blocking_io(move |this| { let state = this.state_at_block_id(block_id)?; - let storage_keys = keys.iter().map(|key| key.0).collect::>(); + let storage_keys = keys.iter().map(|key| key.as_b256()).collect::>(); let proof = state .proof(Default::default(), address, &storage_keys) .map_err(Self::Error::from_eth_err)?; diff --git a/crates/rpc/rpc-eth-api/src/types.rs b/crates/rpc/rpc-eth-api/src/types.rs index 1d176dd1e86..620f4523d21 100644 --- a/crates/rpc/rpc-eth-api/src/types.rs +++ b/crates/rpc/rpc-eth-api/src/types.rs @@ -1,6 +1,9 @@ //! Trait for specifying `eth` network dependent API types. -use std::{error::Error, fmt}; +use std::{ + error::Error, + fmt::{self}, +}; use alloy_network::Network; use alloy_rpc_types::Block; diff --git a/crates/rpc/rpc-eth-types/src/simulate.rs b/crates/rpc/rpc-eth-types/src/simulate.rs index 20952413c13..d881b854a79 100644 --- a/crates/rpc/rpc-eth-types/src/simulate.rs +++ b/crates/rpc/rpc-eth-types/src/simulate.rs @@ -1,7 +1,7 @@ //! Utilities for serving `eth_simulateV1` use alloy_consensus::{Transaction as _, TxEip4844Variant, TxType, TypedTransaction}; -use alloy_primitives::{Parity, Signature}; +use alloy_primitives::PrimitiveSignature as Signature; use alloy_rpc_types::{ simulate::{SimCallResult, SimulateError, SimulatedBlock}, Block, BlockTransactionsKind, @@ -133,8 +133,7 @@ where }; // Create an empty signature for the transaction. - let signature = - Signature::new(Default::default(), Default::default(), Parity::Parity(false)); + let signature = Signature::new(Default::default(), Default::default(), false); let tx = match tx { TypedTransaction::Legacy(tx) => { @@ -170,7 +169,7 @@ where } /// Handles outputs of the calls execution and builds a [`SimulatedBlock`]. -#[expect(clippy::too_many_arguments)] +#[expect(clippy::complexity)] pub fn build_block( results: Vec<(Address, ExecutionResult)>, transactions: Vec, @@ -306,6 +305,6 @@ pub fn build_block( let txs_kind = if full_transactions { BlockTransactionsKind::Full } else { BlockTransactionsKind::Hashes }; - let block = from_block(block, total_difficulty, txs_kind, None, tx_resp_builder)?; + let block = from_block::(block, total_difficulty, txs_kind, None, tx_resp_builder)?; Ok(SimulatedBlock { inner: block, calls }) } diff --git a/crates/rpc/rpc-types-compat/src/block.rs b/crates/rpc/rpc-types-compat/src/block.rs index a954e05e4f6..3b297ba0bc3 100644 --- a/crates/rpc/rpc-types-compat/src/block.rs +++ b/crates/rpc/rpc-types-compat/src/block.rs @@ -1,13 +1,12 @@ //! Compatibility functions for rpc `Block` type. +use alloy_consensus::Sealed; use alloy_primitives::{B256, U256}; use alloy_rlp::Encodable; use alloy_rpc_types::{ Block, BlockError, BlockTransactions, BlockTransactionsKind, Header, TransactionInfo, }; -use reth_primitives::{ - Block as PrimitiveBlock, BlockWithSenders, Header as PrimitiveHeader, SealedHeader, Withdrawals, -}; +use reth_primitives::{Block as PrimitiveBlock, BlockWithSenders, Withdrawals}; use crate::{transaction::from_recovered_with_block_context, TransactionCompat}; @@ -100,64 +99,6 @@ pub fn from_block_full( )) } -/// Converts from a [`reth_primitives::SealedHeader`] to a [`alloy-rpc-types::Header`] -/// -/// # Note -/// -/// This does not set the `totalDifficulty` field. -pub fn from_primitive_with_hash(primitive_header: reth_primitives::SealedHeader) -> Header { - let (header, hash) = primitive_header.split(); - let PrimitiveHeader { - parent_hash, - ommers_hash, - beneficiary, - state_root, - transactions_root, - receipts_root, - logs_bloom, - difficulty, - number, - gas_limit, - gas_used, - timestamp, - mix_hash, - nonce, - base_fee_per_gas, - extra_data, - withdrawals_root, - blob_gas_used, - excess_blob_gas, - parent_beacon_block_root, - requests_hash, - } = header; - - Header { - hash, - parent_hash, - uncles_hash: ommers_hash, - miner: beneficiary, - state_root, - transactions_root, - receipts_root, - withdrawals_root, - number, - gas_used, - gas_limit, - extra_data, - logs_bloom, - timestamp, - difficulty, - mix_hash: Some(mix_hash), - nonce: Some(nonce), - base_fee_per_gas, - blob_gas_used, - excess_blob_gas, - parent_beacon_block_root, - total_difficulty: None, - requests_hash, - } -} - #[inline] fn from_block_with_transactions( block_length: usize, @@ -166,31 +107,19 @@ fn from_block_with_transactions( total_difficulty: U256, transactions: BlockTransactions, ) -> Block { - let uncles = block.body.ommers.into_iter().map(|h| h.hash_slow()).collect(); - let mut header = from_primitive_with_hash(SealedHeader::new(block.header, block_hash)); - header.total_difficulty = Some(total_difficulty); - - let withdrawals = header + let withdrawals = block + .header .withdrawals_root .is_some() - .then(|| block.body.withdrawals.map(Withdrawals::into_inner)) + .then(|| block.body.withdrawals.map(Withdrawals::into_inner).map(Into::into)) .flatten(); - Block { header, uncles, transactions, size: Some(U256::from(block_length)), withdrawals } -} + let uncles = block.body.ommers.into_iter().map(|h| h.hash_slow()).collect(); + let header = Header::from_consensus( + Sealed::new_unchecked(block.header, block_hash), + Some(total_difficulty), + Some(U256::from(block_length)), + ); -/// Build an RPC block response representing -/// an Uncle from its header. -pub fn uncle_block_from_header(header: PrimitiveHeader) -> Block { - let hash = header.hash_slow(); - let uncle_block = PrimitiveBlock { header, ..Default::default() }; - let size = Some(U256::from(uncle_block.length())); - let rpc_header = from_primitive_with_hash(SealedHeader::new(uncle_block.header, hash)); - Block { - uncles: vec![], - header: rpc_header, - transactions: BlockTransactions::Uncle, - withdrawals: None, - size, - } + Block { header, uncles, transactions, withdrawals } } diff --git a/crates/rpc/rpc-types-compat/src/proof.rs b/crates/rpc/rpc-types-compat/src/proof.rs index 19bc76f3d7b..7bdf629e96a 100644 --- a/crates/rpc/rpc-types-compat/src/proof.rs +++ b/crates/rpc/rpc-types-compat/src/proof.rs @@ -6,7 +6,11 @@ use reth_trie_common::{AccountProof, StorageProof}; /// Creates a new rpc storage proof from a primitive storage proof type. pub fn from_primitive_storage_proof(proof: StorageProof) -> EIP1186StorageProof { - EIP1186StorageProof { key: JsonStorageKey(proof.key), value: proof.value, proof: proof.proof } + EIP1186StorageProof { + key: JsonStorageKey::Hash(proof.key), + value: proof.value, + proof: proof.proof, + } } /// Creates a new rpc account proof from a primitive account proof type. diff --git a/crates/rpc/rpc-types-compat/src/transaction/mod.rs b/crates/rpc/rpc-types-compat/src/transaction/mod.rs index 16742144f25..27f0b0288d5 100644 --- a/crates/rpc/rpc-types-compat/src/transaction/mod.rs +++ b/crates/rpc/rpc-types-compat/src/transaction/mod.rs @@ -1,7 +1,4 @@ //! Compatibility functions for rpc `Transaction` type. -mod signature; - -pub use signature::*; use std::fmt; @@ -10,7 +7,7 @@ use alloy_rpc_types::{ request::{TransactionInput, TransactionRequest}, TransactionInfo, }; -use reth_primitives::{TransactionSigned, TransactionSignedEcRecovered, TxType}; +use reth_primitives::TransactionSignedEcRecovered; use serde::{Deserialize, Serialize}; /// Create a new rpc transaction result for a mined transaction, using the given block hash, @@ -44,36 +41,8 @@ pub trait TransactionCompat: Send + Sync + Unpin + Clone + fmt::Debug { + Sync + Unpin + Clone - + Default + fmt::Debug; - /// - /// Formats gas price and max fee per gas for RPC transaction response w.r.t. network specific - /// transaction type. - fn gas_price(signed_tx: &TransactionSigned, base_fee: Option) -> GasPrice { - #[allow(unreachable_patterns)] - match signed_tx.tx_type() { - TxType::Legacy | TxType::Eip2930 => { - GasPrice { gas_price: Some(signed_tx.max_fee_per_gas()), max_fee_per_gas: None } - } - TxType::Eip1559 | TxType::Eip4844 | TxType::Eip7702 => { - // the gas price field for EIP1559 is set to `min(tip, gasFeeCap - baseFee) + - // baseFee` - let gas_price = base_fee - .and_then(|base_fee| { - signed_tx.effective_tip_per_gas(base_fee).map(|tip| tip + base_fee as u128) - }) - .unwrap_or_else(|| signed_tx.max_fee_per_gas()); - - GasPrice { - gas_price: Some(gas_price), - max_fee_per_gas: Some(signed_tx.max_fee_per_gas()), - } - } - _ => GasPrice::default(), - } - } - /// Create a new rpc transaction result for a _pending_ signed transaction, setting block /// environment related fields to `None`. fn fill(&self, tx: TransactionSignedEcRecovered, tx_inf: TransactionInfo) -> Self::Transaction; @@ -82,19 +51,6 @@ pub trait TransactionCompat: Send + Sync + Unpin + Clone + fmt::Debug { // todo: remove in favour of using constructor on `TransactionResponse` or similar // . fn otterscan_api_truncate_input(tx: &mut Self::Transaction); - - /// Returns the transaction type. - // todo: remove when alloy TransactionResponse trait it updated. - fn tx_type(tx: &Self::Transaction) -> u8; -} - -/// Gas price and max fee per gas for a transaction. Helper type to format transaction RPC response. -#[derive(Debug, Default)] -pub struct GasPrice { - /// Gas price for transaction. - pub gas_price: Option, - /// Max fee per gas for transaction. - pub max_fee_per_gas: Option, } /// Convert [`TransactionSignedEcRecovered`] to [`TransactionRequest`] diff --git a/crates/rpc/rpc/src/eth/helpers/signer.rs b/crates/rpc/rpc/src/eth/helpers/signer.rs index c6c60312730..e7e9c64447b 100644 --- a/crates/rpc/rpc/src/eth/helpers/signer.rs +++ b/crates/rpc/rpc/src/eth/helpers/signer.rs @@ -6,7 +6,7 @@ use crate::EthApi; use alloy_dyn_abi::TypedData; use alloy_eips::eip2718::Decodable2718; use alloy_network::{eip2718::Encodable2718, EthereumWallet, TransactionBuilder}; -use alloy_primitives::{eip191_hash_message, Address, Signature, B256}; +use alloy_primitives::{eip191_hash_message, Address, PrimitiveSignature as Signature, B256}; use alloy_rpc_types_eth::TransactionRequest; use alloy_signer::SignerSync; use alloy_signer_local::PrivateKeySigner; @@ -109,7 +109,7 @@ impl EthSigner for DevSigner { #[cfg(test)] mod tests { - use alloy_primitives::{Bytes, Parity, U256}; + use alloy_primitives::{Bytes, U256}; use alloy_rpc_types_eth::TransactionInput; use revm_primitives::TxKind; @@ -205,7 +205,7 @@ mod tests { 16, ) .unwrap(), - Parity::Parity(false), + false, ); assert_eq!(sig, expected) } @@ -227,7 +227,7 @@ mod tests { 16, ) .unwrap(), - Parity::Parity(true), + true, ); assert_eq!(sig, expected) } diff --git a/crates/rpc/rpc/src/eth/helpers/types.rs b/crates/rpc/rpc/src/eth/helpers/types.rs index 0998c057e29..b86e32f046f 100644 --- a/crates/rpc/rpc/src/eth/helpers/types.rs +++ b/crates/rpc/rpc/src/eth/helpers/types.rs @@ -1,14 +1,10 @@ //! L1 `eth` API types. -use alloy_consensus::Transaction as _; +use alloy_consensus::{Signed, TxEip4844Variant, TxEnvelope}; use alloy_network::{Ethereum, Network}; -use alloy_primitives::{Address, TxKind}; use alloy_rpc_types::{Transaction, TransactionInfo}; -use reth_primitives::TransactionSignedEcRecovered; -use reth_rpc_types_compat::{ - transaction::{from_primitive_signature, GasPrice}, - TransactionCompat, -}; +use reth_primitives::{TransactionSigned, TransactionSignedEcRecovered}; +use reth_rpc_types_compat::TransactionCompat; /// Builds RPC transaction response for l1. #[derive(Debug, Clone, Copy)] @@ -25,65 +21,46 @@ where tx: TransactionSignedEcRecovered, tx_info: TransactionInfo, ) -> Self::Transaction { - let signer = tx.signer(); - let signed_tx = tx.into_signed(); + let from = tx.signer(); + let TransactionSigned { transaction, signature, hash } = tx.into_signed(); - let to: Option
= match signed_tx.kind() { - TxKind::Create => None, - TxKind::Call(to) => Some(Address(*to)), + let inner = match transaction { + reth_primitives::Transaction::Legacy(tx) => { + Signed::new_unchecked(tx, signature, hash).into() + } + reth_primitives::Transaction::Eip2930(tx) => { + Signed::new_unchecked(tx, signature, hash).into() + } + reth_primitives::Transaction::Eip1559(tx) => { + Signed::new_unchecked(tx, signature, hash).into() + } + reth_primitives::Transaction::Eip4844(tx) => { + Signed::new_unchecked(tx, signature, hash).into() + } + reth_primitives::Transaction::Eip7702(tx) => { + Signed::new_unchecked(tx, signature, hash).into() + } + #[allow(unreachable_patterns)] + _ => unreachable!(), }; - let TransactionInfo { - base_fee, block_hash, block_number, index: transaction_index, .. - } = tx_info; + let TransactionInfo { block_hash, block_number, index: transaction_index, .. } = tx_info; - let GasPrice { gas_price, max_fee_per_gas } = - Self::gas_price(&signed_tx, base_fee.map(|fee| fee as u64)); - - let input = signed_tx.input().to_vec().into(); - let chain_id = signed_tx.chain_id(); - let blob_versioned_hashes = signed_tx.blob_versioned_hashes().map(|hs| hs.to_vec()); - let access_list = signed_tx.access_list().cloned(); - let authorization_list = signed_tx.authorization_list().map(|l| l.to_vec()); - - let signature = from_primitive_signature( - *signed_tx.signature(), - signed_tx.tx_type(), - signed_tx.chain_id(), - ); - - Transaction { - hash: signed_tx.hash(), - nonce: signed_tx.nonce(), - from: signer, - to, - value: signed_tx.value(), - gas_price, - max_fee_per_gas, - max_priority_fee_per_gas: signed_tx.max_priority_fee_per_gas(), - signature: Some(signature), - gas: signed_tx.gas_limit(), - input, - chain_id, - access_list, - transaction_type: Some(signed_tx.tx_type() as u8), - // These fields are set to None because they are not stored as part of the - // transaction - block_hash, - block_number, - transaction_index, - // EIP-4844 fields - max_fee_per_blob_gas: signed_tx.max_fee_per_blob_gas(), - blob_versioned_hashes, - authorization_list, - } + Transaction { inner, block_hash, block_number, transaction_index, from } } fn otterscan_api_truncate_input(tx: &mut Self::Transaction) { - tx.input = tx.input.slice(..4); - } - - fn tx_type(tx: &Self::Transaction) -> u8 { - tx.transaction_type.unwrap_or(0) + let input = match &mut tx.inner { + TxEnvelope::Eip1559(tx) => &mut tx.tx_mut().input, + TxEnvelope::Eip2930(tx) => &mut tx.tx_mut().input, + TxEnvelope::Legacy(tx) => &mut tx.tx_mut().input, + TxEnvelope::Eip4844(tx) => match tx.tx_mut() { + TxEip4844Variant::TxEip4844(tx) => &mut tx.input, + TxEip4844Variant::TxEip4844WithSidecar(tx) => &mut tx.tx.input, + }, + TxEnvelope::Eip7702(tx) => &mut tx.tx_mut().input, + _ => return, + }; + *input = input.slice(..4); } } diff --git a/crates/rpc/rpc/src/eth/pubsub.rs b/crates/rpc/rpc/src/eth/pubsub.rs index 663ec0b99d6..922694cdba6 100644 --- a/crates/rpc/rpc/src/eth/pubsub.rs +++ b/crates/rpc/rpc/src/eth/pubsub.rs @@ -329,7 +329,7 @@ where self.chain_events.canonical_state_stream().flat_map(|new_chain| { let headers = new_chain.committed().headers().collect::>(); futures::stream::iter( - headers.into_iter().map(reth_rpc_types_compat::block::from_primitive_with_hash), + headers.into_iter().map(|h| Header::from_consensus(h.into(), None, None)), ) }) } diff --git a/crates/rpc/rpc/src/otterscan.rs b/crates/rpc/rpc/src/otterscan.rs index 54ddaaaad50..0585ef76459 100644 --- a/crates/rpc/rpc/src/otterscan.rs +++ b/crates/rpc/rpc/src/otterscan.rs @@ -165,7 +165,7 @@ where } /// Handler for `ots_getBlockDetails` - async fn get_block_details(&self, block_number: u64) -> RpcResult { + async fn get_block_details(&self, block_number: u64) -> RpcResult> { let block_id = block_number.into(); let block = self.eth.block_by_number(block_id, true); let block_id = block_id.into(); @@ -178,7 +178,7 @@ where } /// Handler for `getBlockDetailsByHash` - async fn get_block_details_by_hash(&self, block_hash: B256) -> RpcResult { + async fn get_block_details_by_hash(&self, block_hash: B256) -> RpcResult> { let block = self.eth.block_by_hash(block_hash, true); let block_id = block_hash.into(); let receipts = self.eth.block_receipts(block_id); @@ -195,7 +195,7 @@ where block_number: u64, page_number: usize, page_size: usize, - ) -> RpcResult>> { + ) -> RpcResult, Header>> { let block_id = block_number.into(); // retrieve full block and its receipts let block = self.eth.block_by_number(block_id, true); @@ -239,7 +239,7 @@ where let timestamp = Some(block.header.timestamp); let receipts = receipts .drain(page_start..page_end) - .zip(transactions.iter().map(Eth::TransactionCompat::tx_type)) + .zip(transactions.iter().map(Transaction::ty)) .map(|(receipt, tx_ty)| { let inner = OtsReceipt { status: receipt.status(), diff --git a/crates/storage/codecs/src/alloy/authorization_list.rs b/crates/storage/codecs/src/alloy/authorization_list.rs index e17c0fb32a1..15285f36047 100644 --- a/crates/storage/codecs/src/alloy/authorization_list.rs +++ b/crates/storage/codecs/src/alloy/authorization_list.rs @@ -85,12 +85,11 @@ mod tests { nonce: 1, } .into_signed( - alloy_primitives::Signature::from_rs_and_parity( + alloy_primitives::PrimitiveSignature::new( b256!("1fd474b1f9404c0c5df43b7620119ffbc3a1c3f942c73b6e14e9f55255ed9b1d").into(), b256!("29aca24813279a901ec13b5f7bb53385fa1fc627b946592221417ff74a49600d").into(), false, ) - .unwrap(), ); let mut compacted_authorization = Vec::::new(); let len = authorization.to_compact(&mut compacted_authorization); diff --git a/crates/storage/codecs/src/alloy/signature.rs b/crates/storage/codecs/src/alloy/signature.rs index 0cc4774d0f8..b8fd19cf35a 100644 --- a/crates/storage/codecs/src/alloy/signature.rs +++ b/crates/storage/codecs/src/alloy/signature.rs @@ -1,7 +1,7 @@ //! Compact implementation for [`Signature`] use crate::Compact; -use alloy_primitives::{Parity, Signature, U256}; +use alloy_primitives::{PrimitiveSignature as Signature, U256}; impl Compact for Signature { fn to_compact(&self, buf: &mut B) -> usize @@ -10,7 +10,7 @@ impl Compact for Signature { { buf.put_slice(&self.r().as_le_bytes()); buf.put_slice(&self.s().as_le_bytes()); - self.v().y_parity() as usize + self.v() as usize } fn from_compact(mut buf: &[u8], identifier: usize) -> (Self, &[u8]) { @@ -19,6 +19,6 @@ impl Compact for Signature { let r = U256::from_le_slice(&buf[0..32]); let s = U256::from_le_slice(&buf[32..64]); buf.advance(64); - (Self::new(r, s, Parity::Parity(identifier != 0)), buf) + (Self::new(r, s, identifier != 0), buf) } } diff --git a/crates/storage/provider/src/providers/consistent.rs b/crates/storage/provider/src/providers/consistent.rs index 0784bdb6346..786a2f2b108 100644 --- a/crates/storage/provider/src/providers/consistent.rs +++ b/crates/storage/provider/src/providers/consistent.rs @@ -1388,7 +1388,7 @@ impl StorageChangeSetReader for ConsistentProvider { .bundle .reverts .clone() - .into_plain_state_reverts() + .to_plain_state_reverts() .storage .into_iter() .flatten() @@ -1441,7 +1441,7 @@ impl ChangeSetReader for ConsistentProvider { .bundle .reverts .clone() - .into_plain_state_reverts() + .to_plain_state_reverts() .accounts .into_iter() .flatten() diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index d47532e712d..266f98aae37 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -1704,7 +1704,7 @@ impl> TransactionsProviderE rlp_buf: &mut Vec, ) -> Result<(B256, TxNumber), Box> { let (tx_id, tx) = entry.map_err(|e| Box::new(e.into()))?; - tx.transaction.encode_with_signature(&tx.signature, rlp_buf, false); + tx.transaction.eip2718_encode(&tx.signature, rlp_buf); Ok((keccak256(rlp_buf), tx_id)) } diff --git a/crates/storage/provider/src/providers/static_file/manager.rs b/crates/storage/provider/src/providers/static_file/manager.rs index 70c1e38f6ac..9ccaf051463 100644 --- a/crates/storage/provider/src/providers/static_file/manager.rs +++ b/crates/storage/provider/src/providers/static_file/manager.rs @@ -1671,6 +1671,6 @@ fn calculate_hash( rlp_buf: &mut Vec, ) -> Result<(B256, TxNumber), Box> { let (tx_id, tx) = entry; - tx.transaction.encode_with_signature(&tx.signature, rlp_buf, false); + tx.transaction.eip2718_encode(&tx.signature, rlp_buf); Ok((keccak256(rlp_buf), tx_id)) } diff --git a/crates/storage/provider/src/test_utils/blocks.rs b/crates/storage/provider/src/test_utils/blocks.rs index 19f885e27a8..8439aef1609 100644 --- a/crates/storage/provider/src/test_utils/blocks.rs +++ b/crates/storage/provider/src/test_utils/blocks.rs @@ -2,12 +2,12 @@ use crate::{DatabaseProviderRW, ExecutionOutcome}; use alloy_consensus::{TxLegacy, EMPTY_OMMER_ROOT_HASH}; use alloy_primitives::{ - b256, hex_literal::hex, map::HashMap, Address, BlockNumber, Bytes, Log, Parity, Sealable, - TxKind, B256, U256, + b256, hex_literal::hex, map::HashMap, Address, BlockNumber, Bytes, Log, Sealable, TxKind, B256, + U256, }; use alloy_eips::eip4895::Withdrawal; -use alloy_primitives::Signature; +use alloy_primitives::PrimitiveSignature as Signature; use reth_db::tables; use reth_db_api::{database::Database, models::StoredBlockBodyIndices}; use reth_node_types::NodeTypes; @@ -99,7 +99,7 @@ pub(crate) static TEST_BLOCK: LazyLock = LazyLock::new(|| SealedBlo "29056683545955299640297374067888344259176096769870751649153779895496107008675", ) .unwrap(), - Parity::NonEip155(false), + false, ), transaction: Transaction::Legacy(TxLegacy { gas_price: 10, diff --git a/crates/storage/provider/src/writer/mod.rs b/crates/storage/provider/src/writer/mod.rs index 5b16b2da4e5..37092a5dd51 100644 --- a/crates/storage/provider/src/writer/mod.rs +++ b/crates/storage/provider/src/writer/mod.rs @@ -523,7 +523,7 @@ where is_value_known: OriginalValuesKnown, ) -> ProviderResult<()> { let (plain_state, reverts) = - execution_outcome.bundle.into_plain_state_and_reverts(is_value_known); + execution_outcome.bundle.to_plain_state_and_reverts(is_value_known); self.database().write_state_reverts(reverts, execution_outcome.first_block)?; @@ -664,8 +664,8 @@ mod tests { let mut revm_bundle_state = state.take_bundle(); // Write plain state and reverts separately. - let reverts = revm_bundle_state.take_all_reverts().into_plain_state_reverts(); - let plain_state = revm_bundle_state.into_plain_state(OriginalValuesKnown::Yes); + let reverts = revm_bundle_state.take_all_reverts().to_plain_state_reverts(); + let plain_state = revm_bundle_state.to_plain_state(OriginalValuesKnown::Yes); assert!(plain_state.storage.is_empty()); assert!(plain_state.contracts.is_empty()); provider.write_state_changes(plain_state).expect("Could not write plain state to DB"); @@ -722,8 +722,8 @@ mod tests { let mut revm_bundle_state = state.take_bundle(); // Write plain state and reverts separately. - let reverts = revm_bundle_state.take_all_reverts().into_plain_state_reverts(); - let plain_state = revm_bundle_state.into_plain_state(OriginalValuesKnown::Yes); + let reverts = revm_bundle_state.take_all_reverts().to_plain_state_reverts(); + let plain_state = revm_bundle_state.to_plain_state(OriginalValuesKnown::Yes); // Account B selfdestructed so flag for it should be present. assert_eq!( plain_state.storage, diff --git a/crates/transaction-pool/src/test_utils/mock.rs b/crates/transaction-pool/src/test_utils/mock.rs index c97632c7dcd..92f74665279 100644 --- a/crates/transaction-pool/src/test_utils/mock.rs +++ b/crates/transaction-pool/src/test_utils/mock.rs @@ -16,7 +16,9 @@ use alloy_eips::{ eip2930::AccessList, eip4844::{BlobTransactionSidecar, BlobTransactionValidationError, DATA_GAS_PER_BLOB}, }; -use alloy_primitives::{Address, Bytes, ChainId, Signature, TxHash, TxKind, B256, U256}; +use alloy_primitives::{ + Address, Bytes, ChainId, PrimitiveSignature as Signature, TxHash, TxKind, B256, U256, +}; use paste::paste; use rand::{ distributions::{Uniform, WeightedIndex}, diff --git a/crates/transaction-pool/src/traits.rs b/crates/transaction-pool/src/traits.rs index 6be25cb2ecc..aa99e7af615 100644 --- a/crates/transaction-pool/src/traits.rs +++ b/crates/transaction-pool/src/traits.rs @@ -1506,7 +1506,7 @@ mod tests { use super::*; use alloy_consensus::{TxEip1559, TxEip2930, TxEip4844, TxEip7702, TxLegacy}; use alloy_eips::eip4844::DATA_GAS_PER_BLOB; - use alloy_primitives::Signature; + use alloy_primitives::PrimitiveSignature as Signature; use reth_primitives::TransactionSigned; #[test] diff --git a/testing/testing-utils/src/generators.rs b/testing/testing-utils/src/generators.rs index 83fcf4484a0..57c9acedfea 100644 --- a/testing/testing-utils/src/generators.rs +++ b/testing/testing-utils/src/generators.rs @@ -2,7 +2,7 @@ use alloy_consensus::{Transaction as _, TxLegacy}; use alloy_eips::eip4895::Withdrawal; -use alloy_primitives::{Address, BlockNumber, Bytes, Parity, Sealable, TxKind, B256, U256}; +use alloy_primitives::{Address, BlockNumber, Bytes, Sealable, TxKind, B256, U256}; pub use rand::Rng; use rand::{ distributions::uniform::SampleRange, rngs::StdRng, seq::SliceRandom, thread_rng, SeedableRng, @@ -148,17 +148,9 @@ pub fn sign_tx_with_random_key_pair(rng: &mut R, tx: Transaction) -> Tra /// Signs the [Transaction] with the given key pair. pub fn sign_tx_with_key_pair(key_pair: Keypair, tx: Transaction) -> TransactionSigned { - let mut signature = + let signature = sign_message(B256::from_slice(&key_pair.secret_bytes()[..]), tx.signature_hash()).unwrap(); - if matches!(tx, Transaction::Legacy(_)) { - signature = if let Some(chain_id) = tx.chain_id() { - signature.with_chain_id(chain_id) - } else { - signature.with_parity(Parity::NonEip155(signature.v().y_parity())) - } - } - TransactionSigned::from_transaction_and_signature(tx, signature) } @@ -464,7 +456,7 @@ mod tests { use super::*; use alloy_consensus::TxEip1559; use alloy_eips::eip2930::AccessList; - use alloy_primitives::{hex, Parity, Signature}; + use alloy_primitives::{hex, PrimitiveSignature as Signature}; use reth_primitives::public_key_to_address; use std::str::FromStr; @@ -538,7 +530,7 @@ mod tests { "46948507304638947509940763649030358759909902576025900602547168820602576006531", ) .unwrap(), - Parity::Parity(false), + false, ); assert_eq!(expected, signature); } From c2e8e2f4f95d2b82b491ed9f1b8676f5f944d855 Mon Sep 17 00:00:00 2001 From: Jun Song <87601811+syjn99@users.noreply.github.com> Date: Thu, 7 Nov 2024 01:53:45 +0900 Subject: [PATCH 034/211] Add `queued_outgoing_messages` panel for grafana (#12306) --- etc/grafana/dashboards/reth-mempool.json | 104 ++++++++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/etc/grafana/dashboards/reth-mempool.json b/etc/grafana/dashboards/reth-mempool.json index ebb693184a5..bba5dbd0e22 100644 --- a/etc/grafana/dashboards/reth-mempool.json +++ b/etc/grafana/dashboards/reth-mempool.json @@ -1493,6 +1493,108 @@ "title": "Incoming Gossip and Requests", "type": "timeseries" }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Measures the message send rate (MPS) for queued outgoing messages. Outgoing messages are added to the queue before being sent to other peers, and this metric helps track the rate of message dispatch.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "mps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 29 + }, + "id": 219, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "rate(reth_network_queued_outgoing_messages{instance=\"$instance\"}[$__rate_interval])", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Queued Messages per Second", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Queued Outgoing Messages", + "type": "timeseries" + }, { "datasource": { "type": "prometheus", @@ -2931,7 +3033,7 @@ "gridPos": { "h": 8, "w": 12, - "x": 12, + "x": 0, "y": 69 }, "id": 214, From dc0a6007e3cd4bb75a6d6e6152cc097a2fcc8f91 Mon Sep 17 00:00:00 2001 From: Hai | RISE <150876604+hai-rise@users.noreply.github.com> Date: Thu, 7 Nov 2024 01:24:18 +0700 Subject: [PATCH 035/211] fix(pool-args): `saturating_mul` max sizes to avoid overflow (#12350) --- crates/node/core/src/args/txpool.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/node/core/src/args/txpool.rs b/crates/node/core/src/args/txpool.rs index 538315101ad..2e691aaa963 100644 --- a/crates/node/core/src/args/txpool.rs +++ b/crates/node/core/src/args/txpool.rs @@ -125,19 +125,19 @@ impl RethTransactionPoolConfig for TxPoolArgs { }, pending_limit: SubPoolLimit { max_txs: self.pending_max_count, - max_size: self.pending_max_size * 1024 * 1024, + max_size: self.pending_max_size.saturating_mul(1024 * 1024), }, basefee_limit: SubPoolLimit { max_txs: self.basefee_max_count, - max_size: self.basefee_max_size * 1024 * 1024, + max_size: self.basefee_max_size.saturating_mul(1024 * 1024), }, queued_limit: SubPoolLimit { max_txs: self.queued_max_count, - max_size: self.queued_max_size * 1024 * 1024, + max_size: self.queued_max_size.saturating_mul(1024 * 1024), }, blob_limit: SubPoolLimit { max_txs: self.queued_max_count, - max_size: self.queued_max_size * 1024 * 1024, + max_size: self.queued_max_size.saturating_mul(1024 * 1024), }, max_account_slots: self.max_account_slots, price_bumps: PriceBumpConfig { From e084bed089667d5da471db8638c31aaeef52966a Mon Sep 17 00:00:00 2001 From: Steven <112043913+stevencartavia@users.noreply.github.com> Date: Wed, 6 Nov 2024 13:22:00 -0600 Subject: [PATCH 036/211] renamed OptimismAddOns to OpAddOns (#12348) --- crates/optimism/bin/src/main.rs | 4 ++-- crates/optimism/node/src/node.rs | 17 ++++++++--------- crates/optimism/node/tests/e2e/utils.rs | 4 ++-- crates/optimism/node/tests/it/builder.rs | 4 ++-- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/crates/optimism/bin/src/main.rs b/crates/optimism/bin/src/main.rs index 840da3bcf0b..6494298ba39 100644 --- a/crates/optimism/bin/src/main.rs +++ b/crates/optimism/bin/src/main.rs @@ -5,7 +5,7 @@ use clap::Parser; use reth_node_builder::{engine_tree_config::TreeConfig, EngineNodeLauncher}; use reth_optimism_cli::{chainspec::OpChainSpecParser, Cli}; -use reth_optimism_node::{args::RollupArgs, node::OptimismAddOns, OpNode}; +use reth_optimism_node::{args::RollupArgs, node::OpAddOns, OpNode}; use reth_provider::providers::BlockchainProvider2; use tracing as _; @@ -36,7 +36,7 @@ fn main() { let handle = builder .with_types_and_provider::>() .with_components(OpNode::components(rollup_args)) - .with_add_ons(OptimismAddOns::new(sequencer_http_arg)) + .with_add_ons(OpAddOns::new(sequencer_http_arg)) .launch_with_fn(|builder| { let launcher = EngineNodeLauncher::new( builder.task_executor().clone(), diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index 2e1f71a5175..0eb024fe231 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -105,9 +105,8 @@ where OpConsensusBuilder, >; - type AddOns = OptimismAddOns< - NodeAdapter>::Components>, - >; + type AddOns = + OpAddOns>::Components>>; fn components_builder(&self) -> Self::ComponentsBuilder { let Self { args } = self; @@ -115,7 +114,7 @@ where } fn add_ons(&self) -> Self::AddOns { - OptimismAddOns::new(self.args.sequencer_http.clone()) + OpAddOns::new(self.args.sequencer_http.clone()) } } @@ -131,24 +130,24 @@ impl NodeTypesWithEngine for OpNode { /// Add-ons w.r.t. optimism. #[derive(Debug)] -pub struct OptimismAddOns( +pub struct OpAddOns( pub RpcAddOns, OptimismEngineValidatorBuilder>, ); -impl Default for OptimismAddOns { +impl Default for OpAddOns { fn default() -> Self { Self::new(None) } } -impl OptimismAddOns { +impl OpAddOns { /// Create a new instance with the given `sequencer_http` URL. pub fn new(sequencer_http: Option) -> Self { Self(RpcAddOns::new(move |ctx| OpEthApi::new(ctx, sequencer_http), Default::default())) } } -impl NodeAddOns for OptimismAddOns +impl NodeAddOns for OpAddOns where N: FullNodeComponents>, OpEngineValidator: EngineValidator<::Engine>, @@ -163,7 +162,7 @@ where } } -impl RethRpcAddOns for OptimismAddOns +impl RethRpcAddOns for OpAddOns where N: FullNodeComponents>, OpEngineValidator: EngineValidator<::Engine>, diff --git a/crates/optimism/node/tests/e2e/utils.rs b/crates/optimism/node/tests/e2e/utils.rs index a8afab87ec2..c3b6acddc5a 100644 --- a/crates/optimism/node/tests/e2e/utils.rs +++ b/crates/optimism/node/tests/e2e/utils.rs @@ -6,14 +6,14 @@ use reth_e2e_test_utils::{ }; use reth_optimism_chainspec::OpChainSpecBuilder; use reth_optimism_node::{ - node::OptimismAddOns, OpBuiltPayload, OpNode as OtherOpNode, OpPayloadBuilderAttributes, + node::OpAddOns, OpBuiltPayload, OpNode as OtherOpNode, OpPayloadBuilderAttributes, }; use reth_payload_builder::EthPayloadBuilderAttributes; use std::sync::Arc; use tokio::sync::Mutex; /// Optimism Node Helper type -pub(crate) type OpNode = NodeHelperType>>; +pub(crate) type OpNode = NodeHelperType>>; pub(crate) async fn setup(num_nodes: usize) -> eyre::Result<(Vec, TaskManager, Wallet)> { let genesis: Genesis = serde_json::from_str(include_str!("../assets/genesis.json")).unwrap(); diff --git a/crates/optimism/node/tests/it/builder.rs b/crates/optimism/node/tests/it/builder.rs index 3bd2da75557..67cac17d398 100644 --- a/crates/optimism/node/tests/it/builder.rs +++ b/crates/optimism/node/tests/it/builder.rs @@ -4,7 +4,7 @@ use reth_db::test_utils::create_test_rw_db; use reth_node_api::FullNodeComponents; use reth_node_builder::{NodeBuilder, NodeConfig}; use reth_optimism_chainspec::BASE_MAINNET; -use reth_optimism_node::{node::OptimismAddOns, OpNode}; +use reth_optimism_node::{node::OpAddOns, OpNode}; #[test] fn test_basic_setup() { @@ -15,7 +15,7 @@ fn test_basic_setup() { .with_database(db) .with_types::() .with_components(OpNode::components(Default::default())) - .with_add_ons(OptimismAddOns::new(None)) + .with_add_ons(OpAddOns::new(None)) .on_component_initialized(move |ctx| { let _provider = ctx.provider(); Ok(()) From 2c5ba732b7fe6b653c973157bf88106be22b8c5f Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Wed, 6 Nov 2024 20:27:33 +0100 Subject: [PATCH 037/211] feat(engine): integrate executor with StateRootTask (#12335) Co-authored-by: Roman Krasiuk --- Cargo.lock | 1 + crates/engine/tree/Cargo.toml | 1 + crates/engine/tree/src/tree/mod.rs | 15 ++++-- crates/engine/tree/src/tree/root.rs | 84 +++++++++++++++++++++++++---- 4 files changed, 86 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fba1e61e037..dcd29b36a93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7209,6 +7209,7 @@ dependencies = [ "assert_matches", "futures", "metrics", + "pin-project", "reth-beacon-consensus", "reth-blockchain-tree", "reth-blockchain-tree-api", diff --git a/crates/engine/tree/Cargo.toml b/crates/engine/tree/Cargo.toml index 293883c036e..2ce18aa0e7d 100644 --- a/crates/engine/tree/Cargo.toml +++ b/crates/engine/tree/Cargo.toml @@ -43,6 +43,7 @@ revm-primitives.workspace = true # common futures.workspace = true +pin-project.workspace = true tokio = { workspace = true, features = ["macros", "sync"] } tokio-stream.workspace = true thiserror.workspace = true diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index 36108e63bf8..11dd95e5583 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -57,9 +57,8 @@ use std::{ time::Instant, }; use tokio::sync::{ - mpsc::{UnboundedReceiver, UnboundedSender}, - oneshot, - oneshot::error::TryRecvError, + mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender}, + oneshot::{self, error::TryRecvError}, }; use tracing::*; @@ -612,7 +611,7 @@ where remove_above_state: VecDeque::new(), }; - let (tx, outgoing) = tokio::sync::mpsc::unbounded_channel(); + let (tx, outgoing) = unbounded_channel(); let state = EngineApiTreeState::new( config.block_buffer_limit(), config.max_invalid_header_cache_length(), @@ -2188,6 +2187,7 @@ where let block = block.unseal(); let exec_time = Instant::now(); + // TODO: create StateRootTask with the receiving end of a channel and // pass the sending end of the channel to the state hook. let noop_state_hook = |_result_and_state: &ResultAndState| {}; @@ -2198,6 +2198,7 @@ where )?; trace!(target: "engine::tree", elapsed=?exec_time.elapsed(), ?block_number, "Executed block"); + if let Err(err) = self.consensus.validate_block_post_execution( &block, PostExecutionInput::new(&output.receipts, &output.requests), @@ -2218,6 +2219,8 @@ where let root_time = Instant::now(); let mut state_root_result = None; + // TODO: switch to calculate state root using `StateRootTask`. + // We attempt to compute state root in parallel if we are currently not persisting anything // to database. This is safe, because the database state cannot change until we // finish parallel computation. It is important that nothing is being persisted as @@ -2305,6 +2308,9 @@ where parent_hash: B256, hashed_state: &HashedPostState, ) -> Result<(B256, TrieUpdates), ParallelStateRootError> { + // TODO: when we switch to calculate state root using `StateRootTask` this + // method can be still useful to calculate the required `TrieInput` to + // create the task. let consistent_view = ConsistentDbView::new_with_latest_tip(self.provider.clone())?; let mut input = TrieInput::default(); @@ -2607,7 +2613,6 @@ mod tests { str::FromStr, sync::mpsc::{channel, Sender}, }; - use tokio::sync::mpsc::unbounded_channel; /// This is a test channel that allows you to `release` any value that is in the channel. /// diff --git a/crates/engine/tree/src/tree/root.rs b/crates/engine/tree/src/tree/root.rs index 48b2eccdf14..dc039d418eb 100644 --- a/crates/engine/tree/src/tree/root.rs +++ b/crates/engine/tree/src/tree/root.rs @@ -1,5 +1,7 @@ //! State root task related functionality. +use futures::Stream; +use pin_project::pin_project; use reth_provider::providers::ConsistentDbView; use reth_trie::{updates::TrieUpdates, TrieInput}; use reth_trie_parallel::parallel_root::ParallelStateRootError; @@ -7,31 +9,55 @@ use revm_primitives::{EvmState, B256}; use std::{ future::Future, pin::Pin, - sync::Arc, + sync::{mpsc, Arc}, task::{Context, Poll}, }; use tokio_stream::wrappers::UnboundedReceiverStream; +use tracing::debug; + +/// Result of the state root calculation +pub(crate) type StateRootResult = Result<(B256, TrieUpdates), ParallelStateRootError>; + +/// Handle to a spawned state root task. +#[derive(Debug)] +#[allow(dead_code)] +pub(crate) struct StateRootHandle { + /// Channel for receiving the final result. + rx: mpsc::Receiver, +} + +#[allow(dead_code)] +impl StateRootHandle { + /// Waits for the state root calculation to complete. + pub(crate) fn wait_for_result(self) -> StateRootResult { + self.rx.recv().expect("state root task was dropped without sending result") + } +} /// Standalone task that receives a transaction state stream and updates relevant /// data structures to calculate state root. /// -/// It is responsile of initializing a blinded sparse trie and subscribe to +/// It is responsible of initializing a blinded sparse trie and subscribe to /// transaction state stream. As it receives transaction execution results, it /// fetches the proofs for relevant accounts from the database and reveal them /// to the tree. /// Then it updates relevant leaves according to the result of the transaction. -#[allow(dead_code)] +#[pin_project] pub(crate) struct StateRootTask { /// View over the state in the database. consistent_view: ConsistentDbView, /// Incoming state updates. + #[pin] state_stream: UnboundedReceiverStream, /// Latest trie input. input: Arc, } #[allow(dead_code)] -impl StateRootTask { +impl StateRootTask +where + Factory: Send + 'static, +{ /// Creates a new `StateRootTask`. pub(crate) const fn new( consistent_view: ConsistentDbView, @@ -41,20 +67,58 @@ impl StateRootTask { Self { consistent_view, state_stream, input } } + /// Spawns the state root task and returns a handle to await its result. + pub(crate) fn spawn(self) -> StateRootHandle { + let (tx, rx) = mpsc::channel(); + + // Spawn the task that will process state updates and calculate the root + tokio::spawn(async move { + debug!(target: "engine::tree", "Starting state root task"); + let result = self.await; + let _ = tx.send(result); + }); + + StateRootHandle { rx } + } + /// Handles state updates. - pub(crate) fn on_state_update(&self, _update: EvmState) { + fn on_state_update( + _view: &ConsistentDbView, + _input: &Arc, + _state: EvmState, + ) { // TODO: calculate hashed state update and dispatch proof gathering for it. } } -impl Future for StateRootTask { - type Output = Result<(B256, TrieUpdates), ParallelStateRootError>; +impl Future for StateRootTask +where + Factory: Send + 'static, +{ + type Output = StateRootResult; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let mut this = self.project(); + + // Process all items until the stream is closed + loop { + match this.state_stream.as_mut().poll_next(cx) { + Poll::Ready(Some(state)) => { + Self::on_state_update(this.consistent_view, this.input, state); + } + Poll::Ready(None) => { + // stream closed, return final result + return Poll::Ready(Ok((B256::default(), TrieUpdates::default()))); + } + Poll::Pending => { + return Poll::Pending; + } + } + } - fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll { // TODO: - // * poll incoming state updates stream // * keep track of proof calculation // * keep track of intermediate root computation - Poll::Pending + // * return final state root result } } From fe2b02828d62aa430a180e6b7407ffaee11de538 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 6 Nov 2024 21:30:49 +0100 Subject: [PATCH 038/211] feat: use 1559 functions directly (#12356) --- Cargo.lock | 25 ++++++++++---------- Cargo.toml | 8 +++---- crates/optimism/chainspec/src/lib.rs | 6 ++--- crates/optimism/node/src/engine.rs | 16 ++++++------- crates/optimism/payload/src/builder.rs | 11 +-------- crates/optimism/payload/src/error.rs | 14 ----------- crates/optimism/payload/src/payload.rs | 32 ++++---------------------- crates/optimism/rpc/src/eth/receipt.rs | 2 +- 8 files changed, 33 insertions(+), 81 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dcd29b36a93..cdc31489b34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5274,9 +5274,9 @@ checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "op-alloy-consensus" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae4582945fa96ae0ed78babcac6e41f025460e30ed0c9781aaeedf878fc2b527" +checksum = "dabf6e7d7d63b2c6ed746b24d334e16388c6c3921bc50172440c72aa923c6b4a" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5292,9 +5292,9 @@ dependencies = [ [[package]] name = "op-alloy-genesis" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1ece4a037c56536d8b517d045cef9cc07364c578709c184d33817108309c31e" +checksum = "f901aa077832e22820c644d63d2e5e48601eed0f06e40f2a26d1b2a89bd17dec" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5306,9 +5306,9 @@ dependencies = [ [[package]] name = "op-alloy-network" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e9b64d15a7bf27a06c16eb286349aa2d4e3173260a8ab1fe73bd2c13c89769" +checksum = "8b2e7db7997b12c1f364a3bd54b35338357f44c8e2e533a81ebf625104d80110" dependencies = [ "alloy-consensus", "alloy-network", @@ -5321,9 +5321,9 @@ dependencies = [ [[package]] name = "op-alloy-protocol" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa989d1ea8deced466b0edd7a447264b1f934fd740ab895d32b8544dcce3b151" +checksum = "b9226c7618f45f1d1e1f1112230818d5cfa719da9f5ca05fa28eaeb44d024181" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5341,9 +5341,9 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6e53039829ff0b3482d8dd02cb2de45d5c7b889023c7e4588a43ea7451664a" +checksum = "d60079165fe9a4be99b04865d8746c6c9c7b505be2fdce8982f677ca18c3cc10" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5360,9 +5360,9 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types-engine" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "283b19e1e7fef1ca9078df39f45a48609cacf856b7b441ed6cf19301ed162cca" +checksum = "59a5b505325e343b299b1c574b2b8542f6ac3101e0d92a1c909b2d7dd74665f1" dependencies = [ "alloy-eips", "alloy-primitives", @@ -5370,6 +5370,7 @@ dependencies = [ "alloy-serde", "derive_more 1.0.0", "ethereum_ssz", + "op-alloy-consensus", "op-alloy-protocol", "serde", "snap", diff --git a/Cargo.toml b/Cargo.toml index b8734afe664..8ff8c1eb7fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -468,10 +468,10 @@ alloy-transport-ipc = { version = "0.6.0", default-features = false } alloy-transport-ws = { version = "0.6.0", default-features = false } # op -op-alloy-rpc-types = "0.6" -op-alloy-rpc-types-engine = "0.6" -op-alloy-network = "0.6" -op-alloy-consensus = "0.6" +op-alloy-rpc-types = "0.6.2" +op-alloy-rpc-types-engine = "0.6.2" +op-alloy-network = "0.6.2" +op-alloy-consensus = "0.6.2" # misc aquamarine = "0.6" diff --git a/crates/optimism/chainspec/src/lib.rs b/crates/optimism/chainspec/src/lib.rs index a60a9a22abc..aa59e9ab3f8 100644 --- a/crates/optimism/chainspec/src/lib.rs +++ b/crates/optimism/chainspec/src/lib.rs @@ -436,14 +436,14 @@ impl From for OpChainSpec { #[derive(Default, Debug)] struct OpGenesisInfo { - optimism_chain_info: op_alloy_rpc_types::genesis::OpChainInfo, + optimism_chain_info: op_alloy_rpc_types::OpChainInfo, base_fee_params: BaseFeeParamsKind, } impl OpGenesisInfo { fn extract_from(genesis: &Genesis) -> Self { let mut info = Self { - optimism_chain_info: op_alloy_rpc_types::genesis::OpChainInfo::extract_from( + optimism_chain_info: op_alloy_rpc_types::OpChainInfo::extract_from( &genesis.config.extra_fields, ) .unwrap_or_default(), @@ -852,7 +852,7 @@ mod tests { #[test] fn parse_genesis_optimism_with_variable_base_fee_params() { - use op_alloy_rpc_types::genesis::OpBaseFeeInfo; + use op_alloy_rpc_types::OpBaseFeeInfo; let geth_genesis = r#" { diff --git a/crates/optimism/node/src/engine.rs b/crates/optimism/node/src/engine.rs index eb356e86e1d..e337a23551e 100644 --- a/crates/optimism/node/src/engine.rs +++ b/crates/optimism/node/src/engine.rs @@ -15,9 +15,7 @@ use reth_node_api::{ }; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_forks::{OptimismHardfork, OptimismHardforks}; -use reth_optimism_payload_builder::{ - builder::decode_eip_1559_params, OpBuiltPayload, OpPayloadBuilderAttributes, -}; +use reth_optimism_payload_builder::{OpBuiltPayload, OpPayloadBuilderAttributes}; /// The types used in the optimism beacon consensus engine. #[derive(Debug, Default, Clone, serde::Deserialize, serde::Serialize)] @@ -151,12 +149,12 @@ where if self.chain_spec.is_holocene_active_at_timestamp(attributes.payload_attributes.timestamp) { - let Some(eip_1559_params) = attributes.eip_1559_params else { - return Err(EngineObjectValidationError::InvalidParams( - "MissingEip1559ParamsInPayloadAttributes".to_string().into(), - )) - }; - let (elasticity, denominator) = decode_eip_1559_params(eip_1559_params); + let (elasticity, denominator) = + attributes.decode_eip_1559_params().ok_or_else(|| { + EngineObjectValidationError::InvalidParams( + "MissingEip1559ParamsInPayloadAttributes".to_string().into(), + ) + })?; if elasticity != 0 && denominator == 0 { return Err(EngineObjectValidationError::InvalidParams( "Eip1559ParamsDenominatorZero".to_string().into(), diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index f0c6c04ce73..76c48c09bbb 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -4,7 +4,7 @@ use std::{fmt::Display, sync::Arc}; use alloy_consensus::EMPTY_OMMER_ROOT_HASH; use alloy_eips::merge::BEACON_NONCE; -use alloy_primitives::{Address, Bytes, B64, U256}; +use alloy_primitives::{Address, Bytes, U256}; use alloy_rpc_types_engine::PayloadId; use reth_basic_payload_builder::*; use reth_chain_state::ExecutedBlock; @@ -831,12 +831,3 @@ where Ok(None) } } - -/// Extracts the Holocene 1599 parameters from the encoded form: -/// -pub fn decode_eip_1559_params(eip_1559_params: B64) -> (u32, u32) { - let denominator: [u8; 4] = eip_1559_params.0[..4].try_into().expect("sufficient length"); - let elasticity: [u8; 4] = eip_1559_params.0[4..8].try_into().expect("sufficient length"); - - (u32::from_be_bytes(elasticity), u32::from_be_bytes(denominator)) -} diff --git a/crates/optimism/payload/src/error.rs b/crates/optimism/payload/src/error.rs index ce5f584a1ce..2016fdc6dd9 100644 --- a/crates/optimism/payload/src/error.rs +++ b/crates/optimism/payload/src/error.rs @@ -21,17 +21,3 @@ pub enum OptimismPayloadBuilderError { #[error("blob transaction included in sequencer block")] BlobTransactionRejected, } - -/// Error type for EIP-1559 parameters -#[derive(Debug, thiserror::Error)] -pub enum EIP1559ParamError { - /// No EIP-1559 parameters provided - #[error("No EIP-1559 parameters provided")] - NoEIP1559Params, - /// Denominator overflow - #[error("Denominator overflow")] - DenominatorOverflow, - /// Elasticity overflow - #[error("Elasticity overflow")] - ElasticityOverflow, -} diff --git a/crates/optimism/payload/src/payload.rs b/crates/optimism/payload/src/payload.rs index 5acac70e914..f3576407909 100644 --- a/crates/optimism/payload/src/payload.rs +++ b/crates/optimism/payload/src/payload.rs @@ -1,8 +1,5 @@ //! Payload related types -//! Optimism builder support - -use crate::{builder::decode_eip_1559_params, error::EIP1559ParamError}; use alloy_eips::{ eip1559::BaseFeeParams, eip2718::Decodable2718, eip4844::BlobTransactionSidecar, eip7685::Requests, @@ -10,6 +7,7 @@ use alloy_eips::{ use alloy_primitives::{keccak256, Address, Bytes, B256, B64, U256}; use alloy_rlp::Encodable; use alloy_rpc_types_engine::{ExecutionPayloadEnvelopeV2, ExecutionPayloadV1, PayloadId}; +use op_alloy_consensus::eip1559::{decode_holocene_extra_data, EIP1559ParamError}; /// Re-export for use in downstream arguments. pub use op_alloy_rpc_types_engine::OpPayloadAttributes; use op_alloy_rpc_types_engine::{OpExecutionPayloadEnvelopeV3, OpExecutionPayloadEnvelopeV4}; @@ -46,31 +44,9 @@ impl OpPayloadBuilderAttributes { &self, default_base_fee_params: BaseFeeParams, ) -> Result { - let eip_1559_params = self.eip_1559_params.ok_or(EIP1559ParamError::NoEIP1559Params)?; - - let mut extra_data = [0u8; 9]; - // If eip 1559 params aren't set, use the canyon base fee param constants - // otherwise use them - if eip_1559_params.is_zero() { - // Try casting max_change_denominator to u32 - let max_change_denominator: u32 = (default_base_fee_params.max_change_denominator) - .try_into() - .map_err(|_| EIP1559ParamError::DenominatorOverflow)?; - - // Try casting elasticity_multiplier to u32 - let elasticity_multiplier: u32 = (default_base_fee_params.elasticity_multiplier) - .try_into() - .map_err(|_| EIP1559ParamError::ElasticityOverflow)?; - - // Copy the values safely - extra_data[1..5].copy_from_slice(&max_change_denominator.to_be_bytes()); - extra_data[5..9].copy_from_slice(&elasticity_multiplier.to_be_bytes()); - } else { - let (elasticity, denominator) = decode_eip_1559_params(eip_1559_params); - extra_data[1..5].copy_from_slice(&denominator.to_be_bytes()); - extra_data[5..9].copy_from_slice(&elasticity.to_be_bytes()); - } - Ok(Bytes::copy_from_slice(&extra_data)) + self.eip_1559_params + .map(|params| decode_holocene_extra_data(params, default_base_fee_params)) + .ok_or(EIP1559ParamError::NoEIP1559Params)? } } diff --git a/crates/optimism/rpc/src/eth/receipt.rs b/crates/optimism/rpc/src/eth/receipt.rs index f8e6b7fc21e..3563d4ae45d 100644 --- a/crates/optimism/rpc/src/eth/receipt.rs +++ b/crates/optimism/rpc/src/eth/receipt.rs @@ -5,7 +5,7 @@ use alloy_rpc_types::{Log, TransactionReceipt}; use op_alloy_consensus::{ DepositTransaction, OpDepositReceipt, OpDepositReceiptWithBloom, OpReceiptEnvelope, }; -use op_alloy_rpc_types::{receipt::L1BlockInfo, OpTransactionReceipt, OpTransactionReceiptFields}; +use op_alloy_rpc_types::{L1BlockInfo, OpTransactionReceipt, OpTransactionReceiptFields}; use reth_node_api::{FullNodeComponents, NodeTypes}; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_evm::RethL1BlockInfo; From 302ed291e4b8b56198e4e2d85113e9ff78cc9dd3 Mon Sep 17 00:00:00 2001 From: Hai | RISE <150876604+hai-rise@users.noreply.github.com> Date: Thu, 7 Nov 2024 03:33:49 +0700 Subject: [PATCH 039/211] perf(`EthBuiltPayload`): `Arc` `SealedBlock` (#12351) --- .../ethereum/engine-primitives/src/payload.rs | 19 +++++++++++-------- crates/ethereum/payload/src/lib.rs | 4 ++-- crates/payload/builder/src/lib.rs | 5 +++-- crates/payload/builder/src/test_utils.rs | 3 ++- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/crates/ethereum/engine-primitives/src/payload.rs b/crates/ethereum/engine-primitives/src/payload.rs index ed377d003dd..21c544f16ba 100644 --- a/crates/ethereum/engine-primitives/src/payload.rs +++ b/crates/ethereum/engine-primitives/src/payload.rs @@ -13,7 +13,7 @@ use reth_primitives::{SealedBlock, Withdrawals}; use reth_rpc_types_compat::engine::payload::{ block_to_payload_v1, block_to_payload_v3, convert_block_to_payload_field_v2, }; -use std::convert::Infallible; +use std::{convert::Infallible, sync::Arc}; /// Contains the built payload. /// @@ -25,7 +25,7 @@ pub struct EthBuiltPayload { /// Identifier of the payload pub(crate) id: PayloadId, /// The built block - pub(crate) block: SealedBlock, + pub(crate) block: Arc, /// Block execution data for the payload, if any. pub(crate) executed_block: Option, /// The fees of the block @@ -45,7 +45,7 @@ impl EthBuiltPayload { /// Caution: This does not set any [`BlobTransactionSidecar`]. pub const fn new( id: PayloadId, - block: SealedBlock, + block: Arc, fees: U256, executed_block: Option, requests: Option, @@ -59,7 +59,7 @@ impl EthBuiltPayload { } /// Returns the built block(sealed) - pub const fn block(&self) -> &SealedBlock { + pub fn block(&self) -> &SealedBlock { &self.block } @@ -127,7 +127,7 @@ impl BuiltPayload for &EthBuiltPayload { // V1 engine_getPayloadV1 response impl From for ExecutionPayloadV1 { fn from(value: EthBuiltPayload) -> Self { - block_to_payload_v1(value.block) + block_to_payload_v1(Arc::unwrap_or_clone(value.block)) } } @@ -136,7 +136,10 @@ impl From for ExecutionPayloadEnvelopeV2 { fn from(value: EthBuiltPayload) -> Self { let EthBuiltPayload { block, fees, .. } = value; - Self { block_value: fees, execution_payload: convert_block_to_payload_field_v2(block) } + Self { + block_value: fees, + execution_payload: convert_block_to_payload_field_v2(Arc::unwrap_or_clone(block)), + } } } @@ -145,7 +148,7 @@ impl From for ExecutionPayloadEnvelopeV3 { let EthBuiltPayload { block, fees, sidecars, .. } = value; Self { - execution_payload: block_to_payload_v3(block), + execution_payload: block_to_payload_v3(Arc::unwrap_or_clone(block)), block_value: fees, // From the engine API spec: // @@ -166,7 +169,7 @@ impl From for ExecutionPayloadEnvelopeV4 { let EthBuiltPayload { block, fees, sidecars, requests, .. } = value; Self { - execution_payload: block_to_payload_v3(block), + execution_payload: block_to_payload_v3(Arc::unwrap_or_clone(block)), block_value: fees, // From the engine API spec: // diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index ed33292ef98..403f35d8eff 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -439,12 +439,12 @@ where body: BlockBody { transactions: executed_txs, ommers: vec![], withdrawals }, }; - let sealed_block = block.seal_slow(); + let sealed_block = Arc::new(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()), + block: sealed_block.clone(), senders: Arc::new(executed_senders), execution_output: Arc::new(execution_outcome), hashed_state: Arc::new(hashed_state), diff --git a/crates/payload/builder/src/lib.rs b/crates/payload/builder/src/lib.rs index 2c46a4a9e16..57a040a4bb4 100644 --- a/crates/payload/builder/src/lib.rs +++ b/crates/payload/builder/src/lib.rs @@ -26,6 +26,7 @@ //! ``` //! use std::future::Future; //! use std::pin::Pin; +//! use std::sync::Arc; //! use std::task::{Context, Poll}; //! use alloy_primitives::U256; //! use reth_payload_builder::{EthBuiltPayload, PayloadBuilderError, KeepPayloadJobAlive, EthPayloadBuilderAttributes, PayloadJob, PayloadJobGenerator, PayloadKind}; @@ -56,7 +57,7 @@ //! //! fn best_payload(&self) -> Result { //! // NOTE: some fields are omitted here for brevity -//! let payload = Block { +//! let block = Block { //! header: Header { //! parent_hash: self.attributes.parent, //! timestamp: self.attributes.timestamp, @@ -65,7 +66,7 @@ //! }, //! ..Default::default() //! }; -//! let payload = EthBuiltPayload::new(self.attributes.id, payload.seal_slow(), U256::ZERO, None, None); +//! let payload = EthBuiltPayload::new(self.attributes.id, Arc::new(block.seal_slow()), U256::ZERO, None, None); //! Ok(payload) //! } //! diff --git a/crates/payload/builder/src/test_utils.rs b/crates/payload/builder/src/test_utils.rs index 676e60d912f..746853b74f0 100644 --- a/crates/payload/builder/src/test_utils.rs +++ b/crates/payload/builder/src/test_utils.rs @@ -13,6 +13,7 @@ use reth_provider::CanonStateNotification; use std::{ future::Future, pin::Pin, + sync::Arc, task::{Context, Poll}, }; @@ -86,7 +87,7 @@ impl PayloadJob for TestPayloadJob { fn best_payload(&self) -> Result { Ok(EthBuiltPayload::new( self.attr.payload_id(), - Block::default().seal_slow(), + Arc::new(Block::default().seal_slow()), U256::ZERO, Some(ExecutedBlock::default()), Some(Default::default()), From 2d945292acee7a65460e24de81756b8a34ce0e80 Mon Sep 17 00:00:00 2001 From: Steven <112043913+stevencartavia@users.noreply.github.com> Date: Wed, 6 Nov 2024 15:22:34 -0600 Subject: [PATCH 040/211] renamed OptimismEngineValidatorBuilder to OpEngineValidatorBuilder (#12359) --- crates/optimism/node/src/node.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index 0eb024fe231..541c9bcd483 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -130,9 +130,7 @@ impl NodeTypesWithEngine for OpNode { /// Add-ons w.r.t. optimism. #[derive(Debug)] -pub struct OpAddOns( - pub RpcAddOns, OptimismEngineValidatorBuilder>, -); +pub struct OpAddOns(pub RpcAddOns, OpEngineValidatorBuilder>); impl Default for OpAddOns { fn default() -> Self { @@ -479,9 +477,9 @@ where /// Builder for [`OpEngineValidator`]. #[derive(Debug, Default, Clone)] #[non_exhaustive] -pub struct OptimismEngineValidatorBuilder; +pub struct OpEngineValidatorBuilder; -impl EngineValidatorBuilder for OptimismEngineValidatorBuilder +impl EngineValidatorBuilder for OpEngineValidatorBuilder where Types: NodeTypesWithEngine, Node: FullNodeComponents, From 8e8a1a827d240166d93d00423deae677059b49c4 Mon Sep 17 00:00:00 2001 From: Steven <112043913+stevencartavia@users.noreply.github.com> Date: Thu, 7 Nov 2024 02:56:16 -0600 Subject: [PATCH 041/211] renamed OptimismPayloadBuilderError to OpPayloadBuilderError (#12364) --- crates/optimism/payload/src/builder.rs | 12 +++++------- crates/optimism/payload/src/error.rs | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index 76c48c09bbb..f7fdf157ce3 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -35,7 +35,7 @@ use revm::{ use tracing::{debug, trace, warn}; use crate::{ - error::OptimismPayloadBuilderError, + error::OpPayloadBuilderError, payload::{OpBuiltPayload, OpPayloadBuilderAttributes}, }; use op_alloy_consensus::DepositTransaction; @@ -589,7 +589,7 @@ impl OpPayloadBuilderCtx { ) .map_err(|err| { warn!(target: "payload_builder", %err, "missing create2 deployer, skipping block."); - PayloadBuilderError::other(OptimismPayloadBuilderError::ForceCreate2DeployerFail) + PayloadBuilderError::other(OpPayloadBuilderError::ForceCreate2DeployerFail) }) } } @@ -640,7 +640,7 @@ where // A sequencer's block should never contain blob transactions. if sequencer_tx.value().is_eip4844() { return Err(PayloadBuilderError::other( - OptimismPayloadBuilderError::BlobTransactionRejected, + OpPayloadBuilderError::BlobTransactionRejected, )) } @@ -650,9 +650,7 @@ where // will just pull in its `from` address. let sequencer_tx = sequencer_tx.value().clone().try_into_ecrecovered().map_err(|_| { - PayloadBuilderError::other( - OptimismPayloadBuilderError::TransactionEcRecoverFailed, - ) + PayloadBuilderError::other(OpPayloadBuilderError::TransactionEcRecoverFailed) })?; // Cache the depositor account prior to the state transition for the deposit nonce. @@ -667,7 +665,7 @@ where }) .transpose() .map_err(|_| { - PayloadBuilderError::other(OptimismPayloadBuilderError::AccountLoadFailed( + PayloadBuilderError::other(OpPayloadBuilderError::AccountLoadFailed( sequencer_tx.signer(), )) })?; diff --git a/crates/optimism/payload/src/error.rs b/crates/optimism/payload/src/error.rs index 2016fdc6dd9..8a254e9835c 100644 --- a/crates/optimism/payload/src/error.rs +++ b/crates/optimism/payload/src/error.rs @@ -2,7 +2,7 @@ /// Optimism specific payload building errors. #[derive(Debug, thiserror::Error)] -pub enum OptimismPayloadBuilderError { +pub enum OpPayloadBuilderError { /// Thrown when a transaction fails to convert to a /// [`reth_primitives::TransactionSignedEcRecovered`]. #[error("failed to convert deposit transaction to TransactionSignedEcRecovered")] From 29a9e9779757e569186937ba573aae2f737c0817 Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Thu, 7 Nov 2024 19:00:48 +0900 Subject: [PATCH 042/211] feat: add `PrimitiveSignature` to `test-vectors compact` tests (#12366) --- crates/cli/commands/src/test_vectors/compact.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/cli/commands/src/test_vectors/compact.rs b/crates/cli/commands/src/test_vectors/compact.rs index 8def25fa39b..c2995170057 100644 --- a/crates/cli/commands/src/test_vectors/compact.rs +++ b/crates/cli/commands/src/test_vectors/compact.rs @@ -1,4 +1,4 @@ -use alloy_primitives::{hex, private::getrandom::getrandom, TxKind}; +use alloy_primitives::{hex, private::getrandom::getrandom, PrimitiveSignature, TxKind}; use arbitrary::Arbitrary; use eyre::{Context, Result}; use proptest::{ @@ -126,7 +126,7 @@ compact_types!( ], // These types require an extra identifier which is usually stored elsewhere (eg. parent type). identifier: [ - // Signature todo we for v we only store parity(true || false), while v can take more values + PrimitiveSignature, Transaction, TxType, TxKind From d31e1d601d2f97bdb6b7c7f39829456e6865fe43 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Thu, 7 Nov 2024 10:59:17 +0100 Subject: [PATCH 043/211] chore(sdk): Add `NodePrimitives::Receipt` (#12357) --- crates/ethereum/node/src/node.rs | 3 ++- crates/node/types/src/lib.rs | 3 +++ crates/optimism/node/src/node.rs | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/crates/ethereum/node/src/node.rs b/crates/ethereum/node/src/node.rs index 1942f8a9e56..17a952a58d3 100644 --- a/crates/ethereum/node/src/node.rs +++ b/crates/ethereum/node/src/node.rs @@ -26,7 +26,7 @@ use reth_node_builder::{ BuilderContext, Node, NodeAdapter, NodeComponentsBuilder, PayloadBuilderConfig, PayloadTypes, }; use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService}; -use reth_primitives::{Block, Header}; +use reth_primitives::{Block, Header, Receipt}; use reth_provider::CanonStateSubscriptions; use reth_rpc::EthApi; use reth_tracing::tracing::{debug, info}; @@ -44,6 +44,7 @@ pub struct EthPrimitives; impl NodePrimitives for EthPrimitives { type Block = Block; + type Receipt = Receipt; } /// Type configuration for a regular Ethereum node. diff --git a/crates/node/types/src/lib.rs b/crates/node/types/src/lib.rs index 38e194bd4fb..6c3ed9ca46e 100644 --- a/crates/node/types/src/lib.rs +++ b/crates/node/types/src/lib.rs @@ -24,10 +24,13 @@ use reth_trie_db::StateCommitment; pub trait NodePrimitives { /// Block primitive. type Block; + /// A receipt. + type Receipt; } impl NodePrimitives for () { type Block = reth_primitives::Block; + type Receipt = (); } /// The type that configures the essential types of an Ethereum-like node. diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index 541c9bcd483..e39fdfc27a8 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -24,7 +24,7 @@ use reth_optimism_evm::{OpEvmConfig, OpExecutionStrategyFactory}; use reth_optimism_payload_builder::builder::OpPayloadTransactions; use reth_optimism_rpc::OpEthApi; use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService}; -use reth_primitives::{Block, Header}; +use reth_primitives::{Block, Header, Receipt}; use reth_provider::CanonStateSubscriptions; use reth_tracing::tracing::{debug, info}; use reth_transaction_pool::{ @@ -46,6 +46,7 @@ pub struct OpPrimitives; impl NodePrimitives for OpPrimitives { type Block = Block; + type Receipt = Receipt; } /// Type configuration for a regular Optimism node. From 037dffeb15b96dc1b9f2851d96973fc15d0e08f8 Mon Sep 17 00:00:00 2001 From: Hai | RISE <150876604+hai-rise@users.noreply.github.com> Date: Thu, 7 Nov 2024 17:51:05 +0700 Subject: [PATCH 044/211] perf(`OpBuiltPayload`): `Arc` `SealedBlock` (#12361) --- crates/optimism/payload/src/builder.rs | 4 ++-- crates/optimism/payload/src/payload.rs | 17 ++++++++++------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index f7fdf157ce3..8c1b8faa56c 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -356,12 +356,12 @@ where }, }; - let sealed_block = block.seal_slow(); + let sealed_block = Arc::new(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()), + block: sealed_block.clone(), senders: Arc::new(info.executed_senders), execution_output: Arc::new(execution_outcome), hashed_state: Arc::new(hashed_state), diff --git a/crates/optimism/payload/src/payload.rs b/crates/optimism/payload/src/payload.rs index f3576407909..37224716c75 100644 --- a/crates/optimism/payload/src/payload.rs +++ b/crates/optimism/payload/src/payload.rs @@ -135,7 +135,7 @@ pub struct OpBuiltPayload { /// Identifier of the payload pub(crate) id: PayloadId, /// The built block - pub(crate) block: SealedBlock, + pub(crate) block: Arc, /// Block execution data for the payload, if any. pub(crate) executed_block: Option, /// The fees of the block @@ -155,7 +155,7 @@ impl OpBuiltPayload { /// Initializes the payload with the given initial block. pub const fn new( id: PayloadId, - block: SealedBlock, + block: Arc, fees: U256, chain_spec: Arc, attributes: OpPayloadBuilderAttributes, @@ -170,7 +170,7 @@ impl OpBuiltPayload { } /// Returns the built block(sealed) - pub const fn block(&self) -> &SealedBlock { + pub fn block(&self) -> &SealedBlock { &self.block } @@ -224,7 +224,7 @@ impl BuiltPayload for &OpBuiltPayload { // V1 engine_getPayloadV1 response impl From for ExecutionPayloadV1 { fn from(value: OpBuiltPayload) -> Self { - block_to_payload_v1(value.block) + block_to_payload_v1(Arc::unwrap_or_clone(value.block)) } } @@ -233,7 +233,10 @@ impl From for ExecutionPayloadEnvelopeV2 { fn from(value: OpBuiltPayload) -> Self { let OpBuiltPayload { block, fees, .. } = value; - Self { block_value: fees, execution_payload: convert_block_to_payload_field_v2(block) } + Self { + block_value: fees, + execution_payload: convert_block_to_payload_field_v2(Arc::unwrap_or_clone(block)), + } } } @@ -248,7 +251,7 @@ impl From for OpExecutionPayloadEnvelopeV3 { B256::ZERO }; Self { - execution_payload: block_to_payload_v3(block), + execution_payload: block_to_payload_v3(Arc::unwrap_or_clone(block)), block_value: fees, // From the engine API spec: // @@ -275,7 +278,7 @@ impl From for OpExecutionPayloadEnvelopeV4 { B256::ZERO }; Self { - execution_payload: block_to_payload_v3(block), + execution_payload: block_to_payload_v3(Arc::unwrap_or_clone(block)), block_value: fees, // From the engine API spec: // From 6d05788de2c23b98245d62ea64eeff0063da5e44 Mon Sep 17 00:00:00 2001 From: Hai | RISE <150876604+hai-rise@users.noreply.github.com> Date: Thu, 7 Nov 2024 17:52:25 +0700 Subject: [PATCH 045/211] perf(`default_ethereum_payload`): reuse `Evm` between txs (#12365) --- crates/ethereum/payload/src/lib.rs | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index 403f35d8eff..87ceb4200b1 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -41,7 +41,7 @@ use revm::{ primitives::{EVMError, EnvWithHandlerCfg, InvalidTransaction, ResultAndState}, DatabaseCommit, }; -use revm_primitives::calc_excess_blob_gas; +use revm_primitives::{calc_excess_blob_gas, TxEnv}; use std::sync::Arc; use tracing::{debug, trace, warn}; @@ -212,6 +212,13 @@ where PayloadBuilderError::Internal(err.into()) })?; + let env = EnvWithHandlerCfg::new_with_cfg_env( + initialized_cfg.clone(), + initialized_block_env.clone(), + TxEnv::default(), + ); + let mut evm = evm_config.evm_with_env(&mut db, env); + let mut receipts = Vec::new(); while let Some(pool_tx) = best_txs.next() { // ensure we still have capacity for this transaction @@ -246,14 +253,8 @@ where } } - 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); + // Configure the environment for the tx. + *evm.tx_mut() = evm_config.tx_env(tx.as_signed(), tx.signer()); let ResultAndState { result, state } = match evm.transact() { Ok(res) => res, @@ -279,10 +280,9 @@ where } } }; - // drop evm so db is released. - drop(evm); + // commit changes - db.commit(state); + evm.db_mut().commit(state); // add to the total blob gas used if the transaction successfully executed if let Some(blob_tx) = tx.transaction.as_eip4844() { @@ -321,6 +321,9 @@ where executed_txs.push(tx.into_signed()); } + // Release db + drop(evm); + // check if we have a better block if !is_better_payload(best_payload.as_ref(), total_fees) { // can skip building the block From 581cef330358e3ffbeaadd433bc8c0499f824380 Mon Sep 17 00:00:00 2001 From: Delweng Date: Thu, 7 Nov 2024 18:53:11 +0800 Subject: [PATCH 046/211] feat(rpc/admin): return deposit_contract_address for the admin_NodeInfo RPC (#12362) Signed-off-by: jsvisa --- crates/rpc/rpc/src/admin.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/rpc/rpc/src/admin.rs b/crates/rpc/rpc/src/admin.rs index 311719a04ed..0358aa3a8d4 100644 --- a/crates/rpc/rpc/src/admin.rs +++ b/crates/rpc/rpc/src/admin.rs @@ -115,6 +115,7 @@ where .get_final_paris_total_difficulty() .is_some(), terminal_total_difficulty: self.chain_spec.fork(EthereumHardfork::Paris).ttd(), + deposit_contract_address: self.chain_spec.deposit_contract().map(|dc| dc.address), ..self.chain_spec.genesis().config.clone() }; From f0a1f919ff4275adacb377af079fe221e8ddf330 Mon Sep 17 00:00:00 2001 From: Steven <112043913+stevencartavia@users.noreply.github.com> Date: Thu, 7 Nov 2024 04:58:59 -0600 Subject: [PATCH 047/211] New panel for new_payload_forkchoice_updated_time_diff metric (#12363) --- etc/grafana/dashboards/overview.json | 74 ++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/etc/grafana/dashboards/overview.json b/etc/grafana/dashboards/overview.json index a19d3be8cf6..39ccdffe34f 100644 --- a/etc/grafana/dashboards/overview.json +++ b/etc/grafana/dashboards/overview.json @@ -5162,6 +5162,80 @@ "title": "Pipeline runs", "type": "timeseries" }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Latency histogram for the engine_newPayload to Forkchoice Update", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "mode": "none" + } + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 188 + }, + "id": 213, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "reth_engine_rpc_new_payload_forkchoice_updated_time_diff{instance=~\"$instance\"}", + "legendFormat": "new_payload_forkchoice_updated", + "range": true, + "refId": "A" + } + ], + "title": "Engine API newPayload Forkchoice Update Latency", + "type": "timeseries" + }, { "datasource": { "type": "prometheus", From 581a2f1d477afe9a525ba2279b0af78410bf87bf Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Thu, 7 Nov 2024 15:05:55 +0400 Subject: [PATCH 048/211] refactor(rpc): unify system caller invocations (#12360) --- crates/rpc/rpc-eth-api/src/helpers/trace.rs | 66 ++++++---- crates/rpc/rpc/src/debug.rs | 131 ++++++-------------- 2 files changed, 75 insertions(+), 122 deletions(-) diff --git a/crates/rpc/rpc-eth-api/src/helpers/trace.rs b/crates/rpc/rpc-eth-api/src/helpers/trace.rs index fa70b2df2ef..29bde519960 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/trace.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/trace.rs @@ -1,6 +1,6 @@ //! Loads a pending block from database. Helper trait for `eth_` call and trace RPC methods. -use std::sync::Arc; +use std::{fmt::Display, sync::Arc}; use crate::{FromEvmError, RpcNodeCore}; use alloy_primitives::B256; @@ -16,7 +16,9 @@ use reth_rpc_eth_types::{ }; use revm::{db::CacheDB, Database, DatabaseCommit, GetInspector, Inspector}; use revm_inspectors::tracing::{TracingInspector, TracingInspectorConfig}; -use revm_primitives::{EnvWithHandlerCfg, EvmState, ExecutionResult, ResultAndState}; +use revm_primitives::{ + BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, EvmState, ExecutionResult, ResultAndState, +}; use super::{Call, LoadBlock, LoadPendingBlock, LoadState, LoadTransaction}; @@ -187,26 +189,13 @@ pub trait Trace: LoadState> { // we need to get the state of the parent block because we're essentially replaying the // block the transaction is included in let parent_block = block.parent_hash; - let parent_beacon_block_root = block.parent_beacon_block_root; let this = self.clone(); self.spawn_with_state_at_block(parent_block.into(), move |state| { let mut db = CacheDB::new(StateProviderDatabase::new(state)); let block_txs = block.transactions_with_sender(); - // apply relevant system calls - SystemCaller::new(this.evm_config().clone(), this.provider().chain_spec()) - .pre_block_beacon_root_contract_call( - &mut db, - &cfg, - &block_env, - parent_beacon_block_root, - ) - .map_err(|_| { - EthApiError::EvmCustom( - "failed to apply 4788 beacon root system call".to_string(), - ) - })?; + this.apply_pre_execution_changes(&block, &mut db, &cfg, &block_env)?; // replay all transactions prior to the targeted transaction this.replay_transactions_until( @@ -333,17 +322,7 @@ pub trait Trace: LoadState> { let mut db = CacheDB::new(StateProviderDatabase::new(StateProviderTraitObjWrapper(&state))); - // apply relevant system calls - SystemCaller::new(this.evm_config().clone(), this.provider().chain_spec()) - .pre_block_beacon_root_contract_call( - &mut db, - &cfg, - &block_env, - block.header().parent_beacon_block_root, - ) - .map_err(|_| { - EthApiError::EvmCustom("failed to apply 4788 system call".to_string()) - })?; + this.apply_pre_execution_changes(&block, &mut db, &cfg, &block_env)?; // prepare transactions, we do everything upfront to reduce time spent with open // state @@ -470,4 +449,37 @@ pub trait Trace: LoadState> { { self.trace_block_until_with_inspector(block_id, block, None, insp_setup, f) } + + /// Applies chain-specific state transitions required before executing a block. + /// + /// Note: This should only be called when tracing an entire block vs individual transactions. + /// When tracing transaction on top of an already committed block state, those transitions are + /// already applied. + fn apply_pre_execution_changes + DatabaseCommit>( + &self, + block: &SealedBlockWithSenders, + db: &mut DB, + cfg: &CfgEnvWithHandlerCfg, + block_env: &BlockEnv, + ) -> Result<(), Self::Error> { + let mut system_caller = + SystemCaller::new(self.evm_config().clone(), self.provider().chain_spec()); + // apply relevant system calls + system_caller + .pre_block_beacon_root_contract_call( + db, + cfg, + block_env, + block.header.parent_beacon_block_root, + ) + .map_err(|_| EthApiError::EvmCustom("failed to apply 4788 system call".to_string()))?; + + system_caller + .pre_block_blockhashes_contract_call(db, cfg, block_env, block.header.parent_hash) + .map_err(|_| { + EthApiError::EvmCustom("failed to apply blockhashes system call".to_string()) + })?; + + Ok(()) + } } diff --git a/crates/rpc/rpc/src/debug.rs b/crates/rpc/rpc/src/debug.rs index 7e4c8fb8230..5b7e161691c 100644 --- a/crates/rpc/rpc/src/debug.rs +++ b/crates/rpc/rpc/src/debug.rs @@ -16,10 +16,9 @@ use jsonrpsee::core::RpcResult; use reth_chainspec::EthereumHardforks; use reth_evm::{ execute::{BlockExecutorProvider, Executor}, - system_calls::SystemCaller, ConfigureEvmEnv, }; -use reth_primitives::{Block, TransactionSignedEcRecovered}; +use reth_primitives::{Block, SealedBlockWithSenders}; use reth_provider::{ BlockReaderIdExt, ChainSpecProvider, HeaderProvider, StateProofProvider, StateProviderFactory, TransactionVariant, @@ -93,54 +92,30 @@ where /// Trace the entire block asynchronously async fn trace_block( &self, - at: BlockId, - transactions: Vec, + block: Arc, cfg: CfgEnvWithHandlerCfg, block_env: BlockEnv, opts: GethDebugTracingOptions, - parent_beacon_block_root: Option, ) -> Result, Eth::Error> { - if transactions.is_empty() { - // nothing to trace - return Ok(Vec::new()) - } - // replay all transactions of the block let this = self.clone(); self.eth_api() - .spawn_with_state_at_block(at, move |state| { - let block_hash = at.as_block_hash(); - let mut results = Vec::with_capacity(transactions.len()); + .spawn_with_state_at_block(block.parent_hash.into(), move |state| { + let mut results = Vec::with_capacity(block.body.transactions.len()); let mut db = CacheDB::new(StateProviderDatabase::new(state)); - // apply relevant system calls - SystemCaller::new( - this.eth_api().evm_config().clone(), - this.eth_api().provider().chain_spec(), - ) - .pre_block_beacon_root_contract_call( - &mut db, - &cfg, - &block_env, - parent_beacon_block_root, - ) - .map_err(|_| { - EthApiError::EvmCustom( - "failed to apply 4788 beacon root system call".to_string(), - ) - })?; + this.eth_api().apply_pre_execution_changes(&block, &mut db, &cfg, &block_env)?; - let mut transactions = transactions.into_iter().enumerate().peekable(); + let mut transactions = block.transactions_with_sender().enumerate().peekable(); let mut inspector = None; - while let Some((index, tx)) = transactions.next() { + while let Some((index, (signer, tx))) = transactions.next() { let tx_hash = tx.hash; let env = EnvWithHandlerCfg { env: Env::boxed( cfg.cfg_env.clone(), block_env.clone(), - RpcNodeCore::evm_config(this.eth_api()) - .tx_env(tx.as_signed(), tx.signer()), + RpcNodeCore::evm_config(this.eth_api()).tx_env(tx, *signer), ), handler_cfg: cfg.handler_cfg, }; @@ -149,7 +124,7 @@ where env, &mut db, Some(TransactionContext { - block_hash, + block_hash: Some(block.hash()), tx_hash: Some(tx_hash), tx_index: Some(index), }), @@ -186,45 +161,38 @@ where .map_err(Eth::Error::from_eth_err)?; let (cfg, block_env) = self.eth_api().evm_env_for_raw_block(&block.header).await?; - // we trace on top the block's parent block - let parent = block.parent_hash; - - // we need the beacon block root for a system call - let parent_beacon_block_root = block.parent_beacon_block_root; // Depending on EIP-2 we need to recover the transactions differently - let transactions = - if self.inner.provider.chain_spec().is_homestead_active_at_block(block.number) { - block - .body - .transactions - .into_iter() - .map(|tx| { - tx.into_ecrecovered() - .ok_or(EthApiError::InvalidTransactionSignature) - .map_err(Eth::Error::from_eth_err) - }) - .collect::, Eth::Error>>()? - } else { - block - .body - .transactions - .into_iter() - .map(|tx| { - tx.into_ecrecovered_unchecked() - .ok_or(EthApiError::InvalidTransactionSignature) - .map_err(Eth::Error::from_eth_err) - }) - .collect::, Eth::Error>>()? - }; + let senders = if self.inner.provider.chain_spec().is_homestead_active_at_block(block.number) + { + block + .body + .transactions + .iter() + .map(|tx| { + tx.recover_signer() + .ok_or(EthApiError::InvalidTransactionSignature) + .map_err(Eth::Error::from_eth_err) + }) + .collect::, Eth::Error>>()? + } else { + block + .body + .transactions + .iter() + .map(|tx| { + tx.recover_signer_unchecked() + .ok_or(EthApiError::InvalidTransactionSignature) + .map_err(Eth::Error::from_eth_err) + }) + .collect::, Eth::Error>>()? + }; self.trace_block( - parent.into(), - transactions, + Arc::new(block.with_senders_unchecked(senders).seal_slow()), cfg, block_env, opts, - parent_beacon_block_root, ) .await } @@ -248,19 +216,8 @@ where )?; let block = block.ok_or(EthApiError::HeaderNotFound(block_id))?; - // we need to get the state of the parent block because we're replaying this block on top of - // its parent block's state - let state_at = block.parent_hash; - self.trace_block( - state_at.into(), - (*block).clone().into_transactions_ecrecovered().collect(), - cfg, - block_env, - opts, - block.parent_beacon_block_root, - ) - .await + self.trace_block(block, cfg, block_env, opts).await } /// Trace the transaction according to the provided options. @@ -281,7 +238,6 @@ where // block the transaction is included in let state_at: BlockId = block.parent_hash.into(); let block_hash = block.hash(); - let parent_beacon_block_root = block.parent_beacon_block_root; let this = self.clone(); self.eth_api() @@ -293,22 +249,7 @@ where let mut db = CacheDB::new(StateProviderDatabase::new(state)); - // apply relevant system calls - SystemCaller::new( - this.eth_api().evm_config().clone(), - this.eth_api().provider().chain_spec(), - ) - .pre_block_beacon_root_contract_call( - &mut db, - &cfg, - &block_env, - parent_beacon_block_root, - ) - .map_err(|_| { - EthApiError::EvmCustom( - "failed to apply 4788 beacon root system call".to_string(), - ) - })?; + this.eth_api().apply_pre_execution_changes(&block, &mut db, &cfg, &block_env)?; // replay all transactions prior to the targeted transaction let index = this.eth_api().replay_transactions_until( From eab1a725771dc16e0facccdc4046c91783c66d57 Mon Sep 17 00:00:00 2001 From: Hai | RISE <150876604+hai-rise@users.noreply.github.com> Date: Thu, 7 Nov 2024 19:05:28 +0700 Subject: [PATCH 049/211] perf(`OpPayloadBuilderCtx`): reuse `Evm` between txs (#12369) --- crates/optimism/payload/src/builder.rs | 46 ++++++++++++++------------ 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index 8c1b8faa56c..dc6084f4881 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -29,7 +29,7 @@ use reth_transaction_pool::{ use reth_trie::HashedPostState; use revm::{ db::{states::bundle_state::BundleRetention, State}, - primitives::{EVMError, EnvWithHandlerCfg, InvalidTransaction, ResultAndState}, + primitives::{EVMError, EnvWithHandlerCfg, InvalidTransaction, ResultAndState, TxEnv}, Database, DatabaseCommit, }; use tracing::{debug, trace, warn}; @@ -636,6 +636,13 @@ where { 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() { @@ -660,7 +667,8 @@ where // nonces, so we don't need to touch the DB for those. let depositor = (self.is_regolith_active() && sequencer_tx.is_deposit()) .then(|| { - db.load_cache_account(sequencer_tx.signer()) + evm.db_mut() + .load_cache_account(sequencer_tx.signer()) .map(|acc| acc.account_info().unwrap_or_default()) }) .transpose() @@ -670,13 +678,7 @@ where )) })?; - let env = EnvWithHandlerCfg::new_with_cfg_env( - self.initialized_cfg.clone(), - self.initialized_block_env.clone(), - self.evm_config.tx_env(sequencer_tx.as_signed(), sequencer_tx.signer()), - ); - - let mut evm = self.evm_config.evm_with_env(&mut *db, env); + *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, @@ -694,10 +696,8 @@ where } }; - // to release the db reference drop evm. - drop(evm); // commit changes - db.commit(state); + evm.db_mut().commit(state); let gas_used = result.gas_used(); @@ -738,6 +738,14 @@ where { 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(pool_tx) = best_txs.next() { // ensure we still have capacity for this transaction if info.cumulative_gas_used + pool_tx.gas_limit() > block_gas_limit { @@ -761,14 +769,9 @@ where // convert tx to a signed transaction let tx = pool_tx.to_recovered_transaction(); - let env = EnvWithHandlerCfg::new_with_cfg_env( - self.initialized_cfg.clone(), - self.initialized_block_env.clone(), - self.evm_config.tx_env(tx.as_signed(), tx.signer()), - ); - // Configure the environment for the block. - let mut evm = self.evm_config.evm_with_env(&mut *db, env); + // 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, @@ -794,10 +797,9 @@ where } } }; - // drop evm so db is released. - drop(evm); + // commit changes - db.commit(state); + evm.db_mut().commit(state); let gas_used = result.gas_used(); From cf72b6f38d03a6f8bae5360329a9ceb3d8474fb5 Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Thu, 7 Nov 2024 21:06:53 +0900 Subject: [PATCH 050/211] chore: move helper methods from `DatabaseProvider` to `DBProvider` as defaults (#12367) --- crates/blockchain-tree/src/blockchain_tree.rs | 4 +- crates/blockchain-tree/src/chain.rs | 3 +- crates/cli/commands/src/db/checksum.rs | 2 +- crates/storage/db-common/src/db_tool/mod.rs | 2 +- .../provider/src/providers/database/mod.rs | 3 +- .../src/providers/database/provider.rs | 166 +++--------------- .../storage/provider/src/test_utils/blocks.rs | 2 +- .../storage-api/src/database_provider.rs | 119 ++++++++++++- 8 files changed, 153 insertions(+), 148 deletions(-) diff --git a/crates/blockchain-tree/src/blockchain_tree.rs b/crates/blockchain-tree/src/blockchain_tree.rs index 65e55d7d9f8..64705e5ccb5 100644 --- a/crates/blockchain-tree/src/blockchain_tree.rs +++ b/crates/blockchain-tree/src/blockchain_tree.rs @@ -23,8 +23,8 @@ use reth_primitives::{ use reth_provider::{ providers::ProviderNodeTypes, BlockExecutionWriter, BlockNumReader, BlockWriter, CanonStateNotification, CanonStateNotificationSender, CanonStateNotifications, - ChainSpecProvider, ChainSplit, ChainSplitTarget, DisplayBlocksChain, HeaderProvider, - ProviderError, StaticFileProviderFactory, + ChainSpecProvider, ChainSplit, ChainSplitTarget, DBProvider, DisplayBlocksChain, + HeaderProvider, ProviderError, StaticFileProviderFactory, }; use reth_stages_api::{MetricEvent, MetricEventsSender}; use reth_storage_errors::provider::{ProviderResult, RootMismatch}; diff --git a/crates/blockchain-tree/src/chain.rs b/crates/blockchain-tree/src/chain.rs index 393e525d5ae..09ba5c3f851 100644 --- a/crates/blockchain-tree/src/chain.rs +++ b/crates/blockchain-tree/src/chain.rs @@ -18,7 +18,8 @@ use reth_execution_types::{Chain, ExecutionOutcome}; use reth_primitives::{GotExpected, SealedBlockWithSenders, SealedHeader}; use reth_provider::{ providers::{BundleStateProvider, ConsistentDbView, ProviderNodeTypes}, - FullExecutionDataProvider, ProviderError, StateRootProvider, TryIntoHistoricalStateProvider, + DBProvider, FullExecutionDataProvider, ProviderError, StateRootProvider, + TryIntoHistoricalStateProvider, }; use reth_revm::database::StateProviderDatabase; use reth_trie::{updates::TrieUpdates, HashedPostState, TrieInput}; diff --git a/crates/cli/commands/src/db/checksum.rs b/crates/cli/commands/src/db/checksum.rs index 60ec09c9606..9aa48e0e865 100644 --- a/crates/cli/commands/src/db/checksum.rs +++ b/crates/cli/commands/src/db/checksum.rs @@ -6,7 +6,7 @@ use reth_db::{DatabaseEnv, RawKey, RawTable, RawValue, TableViewer, Tables}; use reth_db_api::{cursor::DbCursorRO, table::Table, transaction::DbTx}; use reth_db_common::DbTool; use reth_node_builder::{NodeTypesWithDB, NodeTypesWithDBAdapter, NodeTypesWithEngine}; -use reth_provider::providers::ProviderNodeTypes; +use reth_provider::{providers::ProviderNodeTypes, DBProvider}; use std::{ hash::{BuildHasher, Hasher}, sync::Arc, diff --git a/crates/storage/db-common/src/db_tool/mod.rs b/crates/storage/db-common/src/db_tool/mod.rs index 67a5dd62762..3420f2089fd 100644 --- a/crates/storage/db-common/src/db_tool/mod.rs +++ b/crates/storage/db-common/src/db_tool/mod.rs @@ -12,7 +12,7 @@ use reth_db_api::{ }; use reth_fs_util as fs; use reth_node_types::NodeTypesWithDB; -use reth_provider::{providers::ProviderNodeTypes, ChainSpecProvider, ProviderFactory}; +use reth_provider::{providers::ProviderNodeTypes, ChainSpecProvider, DBProvider, ProviderFactory}; use std::{path::Path, rc::Rc, sync::Arc}; use tracing::info; diff --git a/crates/storage/provider/src/providers/database/mod.rs b/crates/storage/provider/src/providers/database/mod.rs index bd0466ff973..38918f52c23 100644 --- a/crates/storage/provider/src/providers/database/mod.rs +++ b/crates/storage/provider/src/providers/database/mod.rs @@ -621,7 +621,8 @@ mod tests { use crate::{ providers::{StaticFileProvider, StaticFileWriter}, test_utils::{blocks::TEST_BLOCK, create_test_provider_factory, MockNodeTypesWithDB}, - BlockHashReader, BlockNumReader, BlockWriter, HeaderSyncGapProvider, TransactionsProvider, + BlockHashReader, BlockNumReader, BlockWriter, DBProvider, HeaderSyncGapProvider, + TransactionsProvider, }; use alloy_primitives::{TxNumber, B256, U256}; use assert_matches::assert_matches; diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index 266f98aae37..c76f77572ab 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -24,7 +24,6 @@ use reth_db::{ cursor::DbDupCursorRW, tables, BlockNumberList, PlainAccountState, PlainStorageState, }; use reth_db_api::{ - common::KeyValue, cursor::{DbCursorRO, DbCursorRW, DbDupCursorRO}, database::Database, models::{ @@ -63,7 +62,7 @@ use std::{ cmp::Ordering, collections::{hash_map, BTreeMap, BTreeSet, HashMap, HashSet}, fmt::Debug, - ops::{Bound, Deref, DerefMut, Range, RangeBounds, RangeInclusive}, + ops::{Deref, DerefMut, Range, RangeBounds, RangeInclusive}, sync::{mpsc, Arc}, time::{Duration, Instant}, }; @@ -145,7 +144,7 @@ impl DatabaseProvider { } } -impl DatabaseProvider { +impl DatabaseProvider { /// State provider for latest block pub fn latest<'a>(&'a self) -> ProviderResult> { trace!(target: "providers::db", "Returning latest state provider"); @@ -364,7 +363,7 @@ where Ok(Vec::new()) } -impl DatabaseProvider { +impl DatabaseProvider { /// Creates a provider with an inner read-only transaction. pub const fn new( tx: TX, @@ -395,75 +394,6 @@ impl DatabaseProvider { &self.chain_spec } - /// Disables long-lived read transaction safety guarantees for leaks prevention and - /// observability improvements. - /// - /// CAUTION: In most of the cases, you want the safety guarantees for long read transactions - /// enabled. Use this only if you're sure that no write transaction is open in parallel, meaning - /// that Reth as a node is offline and not progressing. - pub fn disable_long_read_transaction_safety(mut self) -> Self { - self.tx.disable_long_read_transaction_safety(); - self - } - - /// Return full table as Vec - pub fn table(&self) -> Result>, DatabaseError> - where - T::Key: Default + Ord, - { - self.tx - .cursor_read::()? - .walk(Some(T::Key::default()))? - .collect::, DatabaseError>>() - } - - /// Return a list of entries from the table, based on the given range. - #[inline] - pub fn get( - &self, - range: impl RangeBounds, - ) -> Result>, DatabaseError> { - self.tx.cursor_read::()?.walk_range(range)?.collect::, _>>() - } - - /// Iterates over read only values in the given table and collects them into a vector. - /// - /// Early-returns if the range is empty, without opening a cursor transaction. - fn cursor_read_collect>( - &self, - range: impl RangeBounds, - ) -> ProviderResult> { - let capacity = match range_size_hint(&range) { - Some(0) | None => return Ok(Vec::new()), - Some(capacity) => capacity, - }; - let mut cursor = self.tx.cursor_read::()?; - self.cursor_collect_with_capacity(&mut cursor, range, capacity) - } - - /// Iterates over read only values in the given table and collects them into a vector. - fn cursor_collect>( - &self, - cursor: &mut impl DbCursorRO, - range: impl RangeBounds, - ) -> ProviderResult> { - let capacity = range_size_hint(&range).unwrap_or(0); - self.cursor_collect_with_capacity(cursor, range, capacity) - } - - fn cursor_collect_with_capacity>( - &self, - cursor: &mut impl DbCursorRO, - range: impl RangeBounds, - capacity: usize, - ) -> ProviderResult> { - let mut items = Vec::with_capacity(capacity); - for entry in cursor.walk_range(range)? { - items.push(entry?.1); - } - Ok(items) - } - fn transactions_by_tx_range_with_cursor( &self, range: impl RangeBounds, @@ -852,44 +782,12 @@ impl DatabaseProvider { } } -impl DatabaseProvider { +impl DatabaseProvider { /// Commit database transaction. pub fn commit(self) -> ProviderResult { Ok(self.tx.commit()?) } - /// Remove list of entries from the table. Returns the number of entries removed. - #[inline] - pub fn remove( - &self, - range: impl RangeBounds, - ) -> Result { - let mut entries = 0; - let mut cursor_write = self.tx.cursor_write::()?; - let mut walker = cursor_write.walk_range(range)?; - while walker.next().transpose()?.is_some() { - walker.delete_current()?; - entries += 1; - } - Ok(entries) - } - - /// Return a list of entries from the table, and remove them, based on the given range. - #[inline] - pub fn take( - &self, - range: impl RangeBounds, - ) -> Result>, DatabaseError> { - let mut cursor_write = self.tx.cursor_write::()?; - let mut walker = cursor_write.walk_range(range)?; - let mut items = Vec::new(); - while let Some(i) = walker.next().transpose()? { - walker.delete_current()?; - items.push(i) - } - Ok(items) - } - /// Remove requested block transactions, without returning them. /// /// This will remove block data for the given range from the following tables: @@ -1299,7 +1197,7 @@ impl ChangeSetReader for DatabaseProvider { } } -impl HeaderSyncGapProvider for DatabaseProvider { +impl HeaderSyncGapProvider for DatabaseProvider { fn sync_gap( &self, tip: watch::Receiver, @@ -1343,7 +1241,7 @@ impl HeaderSyncGapProvider for DatabaseProvider { } } -impl> HeaderProvider +impl> HeaderProvider for DatabaseProvider { fn header(&self, block_hash: &BlockHash) -> ProviderResult> { @@ -1443,7 +1341,7 @@ impl> HeaderProvider } } -impl BlockHashReader for DatabaseProvider { +impl BlockHashReader for DatabaseProvider { fn block_hash(&self, number: u64) -> ProviderResult> { self.static_file_provider.get_with_static_file_or_database( StaticFileSegment::Headers, @@ -1470,7 +1368,7 @@ impl BlockHashReader for DatabaseProvider { } } -impl BlockNumReader for DatabaseProvider { +impl BlockNumReader for DatabaseProvider { fn chain_info(&self) -> ProviderResult { let best_number = self.best_block_number()?; let best_hash = self.block_hash(best_number)?.unwrap_or_default(); @@ -1501,7 +1399,9 @@ impl BlockNumReader for DatabaseProvider { } } -impl> BlockReader for DatabaseProvider { +impl> BlockReader + for DatabaseProvider +{ fn find_block_by_hash(&self, hash: B256, source: BlockSource) -> ProviderResult> { if source.is_canonical() { self.block(hash.into()) @@ -1676,7 +1576,7 @@ impl> BlockReader for Datab } } -impl> TransactionsProviderExt +impl> TransactionsProviderExt for DatabaseProvider { /// Recovers transaction hashes by walking through `Transactions` table and @@ -1746,7 +1646,7 @@ impl> TransactionsProviderE } // Calculates the hash of the given transaction -impl> TransactionsProvider +impl> TransactionsProvider for DatabaseProvider { fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult> { @@ -1906,7 +1806,7 @@ impl> TransactionsProvider } } -impl> ReceiptProvider +impl> ReceiptProvider for DatabaseProvider { fn receipt(&self, id: TxNumber) -> ProviderResult> { @@ -1954,7 +1854,7 @@ impl> ReceiptProvider } } -impl> WithdrawalsProvider +impl> WithdrawalsProvider for DatabaseProvider { fn withdrawals_by_block( @@ -1984,7 +1884,7 @@ impl> WithdrawalsProvider } } -impl> EvmEnvProvider +impl> EvmEnvProvider for DatabaseProvider { fn fill_env_at( @@ -2110,7 +2010,7 @@ impl StageCheckpointWriter for DatabaseProvider StorageReader for DatabaseProvider { +impl StorageReader for DatabaseProvider { fn plain_state_storages( &self, addresses_with_keys: impl IntoIterator)>, @@ -2173,7 +2073,7 @@ impl StorageReader for DatabaseProvider { } } -impl StateChangeWriter for DatabaseProvider { +impl StateChangeWriter for DatabaseProvider { fn write_state_reverts( &self, reverts: PlainStateReverts, @@ -2550,7 +2450,7 @@ impl StateChangeWriter for DatabaseProvider TrieWriter for DatabaseProvider { +impl TrieWriter for DatabaseProvider { /// Writes trie updates. Returns the number of entries modified. fn write_trie_updates(&self, trie_updates: &TrieUpdates) -> ProviderResult { if trie_updates.is_empty() { @@ -2600,7 +2500,7 @@ impl TrieWriter for DatabaseProvider { } } -impl StorageTrieWriter for DatabaseProvider { +impl StorageTrieWriter for DatabaseProvider { /// Writes storage trie updates from the given storage trie map. First sorts the storage trie /// updates by the hashed address, writing in sorted order. fn write_storage_trie_updates( @@ -2637,7 +2537,7 @@ impl StorageTrieWriter for DatabaseProvider HashingWriter for DatabaseProvider { +impl HashingWriter for DatabaseProvider { fn unwind_account_hashing<'a>( &self, changesets: impl Iterator, @@ -2862,7 +2762,7 @@ impl HashingWriter for DatabaseProvider } } -impl HistoryWriter for DatabaseProvider { +impl HistoryWriter for DatabaseProvider { fn unwind_account_history_indices<'a>( &self, changesets: impl Iterator, @@ -2996,7 +2896,7 @@ impl HistoryWriter for DatabaseProvider } } -impl StateReader for DatabaseProvider { +impl StateReader for DatabaseProvider { fn get_state(&self, block: BlockNumber) -> ProviderResult> { self.get_state(block..=block) } @@ -3417,7 +3317,7 @@ impl + } } -impl PruneCheckpointReader for DatabaseProvider { +impl PruneCheckpointReader for DatabaseProvider { fn get_prune_checkpoint( &self, segment: PruneSegment, @@ -3444,7 +3344,7 @@ impl PruneCheckpointWriter for DatabaseProvider StatsReader for DatabaseProvider { +impl StatsReader for DatabaseProvider { fn count_entries(&self) -> ProviderResult { let db_entries = self.tx.entries::()?; let static_file_entries = match self.static_file_provider.count_entries::() { @@ -3457,7 +3357,7 @@ impl StatsReader for DatabaseProvider { } } -impl ChainStateBlockReader for DatabaseProvider { +impl ChainStateBlockReader for DatabaseProvider { fn last_finalized_block_number(&self) -> ProviderResult> { let mut finalized_blocks = self .tx @@ -3592,17 +3492,3 @@ fn recover_block_senders( Ok(()) } - -fn range_size_hint(range: &impl RangeBounds) -> Option { - let start = match range.start_bound().cloned() { - Bound::Included(start) => start, - Bound::Excluded(start) => start.checked_add(1)?, - Bound::Unbounded => 0, - }; - let end = match range.end_bound().cloned() { - Bound::Included(end) => end.saturating_add(1), - Bound::Excluded(end) => end, - Bound::Unbounded => return None, - }; - end.checked_sub(start).map(|x| x as _) -} diff --git a/crates/storage/provider/src/test_utils/blocks.rs b/crates/storage/provider/src/test_utils/blocks.rs index 8439aef1609..2c9c108139c 100644 --- a/crates/storage/provider/src/test_utils/blocks.rs +++ b/crates/storage/provider/src/test_utils/blocks.rs @@ -1,5 +1,5 @@ //! Dummy blocks and data for tests -use crate::{DatabaseProviderRW, ExecutionOutcome}; +use crate::{DBProvider, DatabaseProviderRW, ExecutionOutcome}; use alloy_consensus::{TxLegacy, EMPTY_OMMER_ROOT_HASH}; use alloy_primitives::{ b256, hex_literal::hex, map::HashMap, Address, BlockNumber, Bytes, Log, Sealable, TxKind, B256, diff --git a/crates/storage/storage-api/src/database_provider.rs b/crates/storage/storage-api/src/database_provider.rs index 6a463ed01e9..20aebce88fe 100644 --- a/crates/storage/storage-api/src/database_provider.rs +++ b/crates/storage/storage-api/src/database_provider.rs @@ -1,6 +1,14 @@ -use reth_db_api::{database::Database, transaction::DbTx}; +use reth_db_api::{ + common::KeyValue, + cursor::DbCursorRO, + database::Database, + table::Table, + transaction::{DbTx, DbTxMut}, + DatabaseError, +}; use reth_prune_types::PruneModes; use reth_storage_errors::provider::ProviderResult; +use std::ops::{Bound, RangeBounds}; /// Database provider. pub trait DBProvider: Send + Sync + Sized + 'static { @@ -34,6 +42,101 @@ pub trait DBProvider: Send + Sync + Sized + 'static { /// Returns a reference to prune modes. fn prune_modes_ref(&self) -> &PruneModes; + + /// Return full table as Vec + fn table(&self) -> Result>, DatabaseError> + where + T::Key: Default + Ord, + { + self.tx_ref() + .cursor_read::()? + .walk(Some(T::Key::default()))? + .collect::, DatabaseError>>() + } + + /// Return a list of entries from the table, based on the given range. + #[inline] + fn get( + &self, + range: impl RangeBounds, + ) -> Result>, DatabaseError> { + self.tx_ref().cursor_read::()?.walk_range(range)?.collect::, _>>() + } + + /// Iterates over read only values in the given table and collects them into a vector. + /// + /// Early-returns if the range is empty, without opening a cursor transaction. + fn cursor_read_collect>( + &self, + range: impl RangeBounds, + ) -> ProviderResult> { + let capacity = match range_size_hint(&range) { + Some(0) | None => return Ok(Vec::new()), + Some(capacity) => capacity, + }; + let mut cursor = self.tx_ref().cursor_read::()?; + self.cursor_collect_with_capacity(&mut cursor, range, capacity) + } + + /// Iterates over read only values in the given table and collects them into a vector. + fn cursor_collect>( + &self, + cursor: &mut impl DbCursorRO, + range: impl RangeBounds, + ) -> ProviderResult> { + let capacity = range_size_hint(&range).unwrap_or(0); + self.cursor_collect_with_capacity(cursor, range, capacity) + } + + /// Iterates over read only values in the given table and collects them into a vector with + /// capacity. + fn cursor_collect_with_capacity>( + &self, + cursor: &mut impl DbCursorRO, + range: impl RangeBounds, + capacity: usize, + ) -> ProviderResult> { + let mut items = Vec::with_capacity(capacity); + for entry in cursor.walk_range(range)? { + items.push(entry?.1); + } + Ok(items) + } + + /// Remove list of entries from the table. Returns the number of entries removed. + #[inline] + fn remove(&self, range: impl RangeBounds) -> Result + where + Self::Tx: DbTxMut, + { + let mut entries = 0; + let mut cursor_write = self.tx_ref().cursor_write::()?; + let mut walker = cursor_write.walk_range(range)?; + while walker.next().transpose()?.is_some() { + walker.delete_current()?; + entries += 1; + } + Ok(entries) + } + + /// Return a list of entries from the table, and remove them, based on the given range. + #[inline] + fn take( + &self, + range: impl RangeBounds, + ) -> Result>, DatabaseError> + where + Self::Tx: DbTxMut, + { + let mut cursor_write = self.tx_ref().cursor_write::()?; + let mut walker = cursor_write.walk_range(range)?; + let mut items = Vec::new(); + while let Some(i) = walker.next().transpose()? { + walker.delete_current()?; + items.push(i) + } + Ok(items) + } } /// Database provider factory. @@ -54,3 +157,17 @@ pub trait DatabaseProviderFactory: Send + Sync { /// Create new read-write database provider. fn database_provider_rw(&self) -> ProviderResult; } + +fn range_size_hint(range: &impl RangeBounds) -> Option { + let start = match range.start_bound().cloned() { + Bound::Included(start) => start, + Bound::Excluded(start) => start.checked_add(1)?, + Bound::Unbounded => 0, + }; + let end = match range.end_bound().cloned() { + Bound::Included(end) => end.saturating_add(1), + Bound::Excluded(end) => end, + Bound::Unbounded => return None, + }; + end.checked_sub(start).map(|x| x as _) +} From 473e172ac4cd9bc160708c6fb1bacf44a2eab355 Mon Sep 17 00:00:00 2001 From: wheval Date: Thu, 7 Nov 2024 13:37:40 +0100 Subject: [PATCH 051/211] chore: change "Reporting a Vulnerability" to "Report a Vulnerability" (#12372) --- SECURITY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SECURITY.md b/SECURITY.md index bea27ad1140..7521d62e959 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,5 +1,5 @@ # Security Policy -## Reporting a Vulnerability +## Report a Vulnerability Contact [security@ithaca.xyz](mailto:security@ithaca.xyz). From 764371d246f2e06133a183ee79167b25c18991e4 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Thu, 7 Nov 2024 15:34:24 +0100 Subject: [PATCH 052/211] test(eth-engine): add unit tests for `payload_id` method (#12295) --- .../ethereum/engine-primitives/src/payload.rs | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/crates/ethereum/engine-primitives/src/payload.rs b/crates/ethereum/engine-primitives/src/payload.rs index 21c544f16ba..3fe4e76e63f 100644 --- a/crates/ethereum/engine-primitives/src/payload.rs +++ b/crates/ethereum/engine-primitives/src/payload.rs @@ -304,10 +304,109 @@ pub(crate) fn payload_id(parent: &B256, attributes: &PayloadAttributes) -> Paylo #[cfg(test)] mod tests { use super::*; + use alloy_eips::eip4895::Withdrawal; + use alloy_primitives::B64; + use std::str::FromStr; #[test] fn attributes_serde() { let attributes = r#"{"timestamp":"0x1235","prevRandao":"0xf343b00e02dc34ec0124241f74f32191be28fb370bb48060f5fa4df99bda774c","suggestedFeeRecipient":"0x0000000000000000000000000000000000000000","withdrawals":null,"parentBeaconBlockRoot":null}"#; let _attributes: PayloadAttributes = serde_json::from_str(attributes).unwrap(); } + + #[test] + fn test_payload_id_basic() { + // Create a parent block and payload attributes + let parent = + B256::from_str("0x3b8fb240d288781d4aac94d3fd16809ee413bc99294a085798a589dae51ddd4a") + .unwrap(); + let attributes = PayloadAttributes { + timestamp: 0x5, + prev_randao: B256::from_str( + "0x0000000000000000000000000000000000000000000000000000000000000000", + ) + .unwrap(), + suggested_fee_recipient: Address::from_str( + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + ) + .unwrap(), + withdrawals: None, + parent_beacon_block_root: None, + }; + + // Verify that the generated payload ID matches the expected value + assert_eq!( + payload_id(&parent, &attributes), + PayloadId(B64::from_str("0xa247243752eb10b4").unwrap()) + ); + } + + #[test] + fn test_payload_id_with_withdrawals() { + // Set up the parent and attributes with withdrawals + let parent = + B256::from_str("0x9876543210abcdef9876543210abcdef9876543210abcdef9876543210abcdef") + .unwrap(); + let attributes = PayloadAttributes { + timestamp: 1622553200, + prev_randao: B256::from_slice(&[1; 32]), + suggested_fee_recipient: Address::from_str( + "0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b", + ) + .unwrap(), + withdrawals: Some(vec![ + Withdrawal { + index: 1, + validator_index: 123, + address: Address::from([0xAA; 20]), + amount: 10, + }, + Withdrawal { + index: 2, + validator_index: 456, + address: Address::from([0xBB; 20]), + amount: 20, + }, + ]), + parent_beacon_block_root: None, + }; + + // Verify that the generated payload ID matches the expected value + assert_eq!( + payload_id(&parent, &attributes), + PayloadId(B64::from_str("0xedddc2f84ba59865").unwrap()) + ); + } + + #[test] + fn test_payload_id_with_parent_beacon_block_root() { + // Set up the parent and attributes with a parent beacon block root + let parent = + B256::from_str("0x9876543210abcdef9876543210abcdef9876543210abcdef9876543210abcdef") + .unwrap(); + let attributes = PayloadAttributes { + timestamp: 1622553200, + prev_randao: B256::from_str( + "0x123456789abcdef123456789abcdef123456789abcdef123456789abcdef1234", + ) + .unwrap(), + suggested_fee_recipient: Address::from_str( + "0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b", + ) + .unwrap(), + withdrawals: None, + parent_beacon_block_root: Some( + B256::from_str( + "0x2222222222222222222222222222222222222222222222222222222222222222", + ) + .unwrap(), + ), + }; + + // Verify that the generated payload ID matches the expected value + assert_eq!( + payload_id(&parent, &attributes), + PayloadId(B64::from_str("0x0fc49cd532094cce").unwrap()) + ); + } } From 9596b1c08b2c37469843dd90dfad8717c60e9582 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 7 Nov 2024 15:53:26 +0100 Subject: [PATCH 053/211] chore: rm reth-provider dep (#12376) --- Cargo.lock | 1 - crates/payload/builder/Cargo.toml | 6 +----- crates/payload/builder/src/service.rs | 2 +- crates/payload/builder/src/test_utils.rs | 3 +-- crates/payload/builder/src/traits.rs | 2 +- 5 files changed, 4 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cdc31489b34..7ce5daf705f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8405,7 +8405,6 @@ dependencies = [ "reth-metrics", "reth-payload-primitives", "reth-primitives", - "reth-provider", "revm", "tokio", "tokio-stream", diff --git a/crates/payload/builder/Cargo.toml b/crates/payload/builder/Cargo.toml index 08399b6f9c6..7a536cdbcfa 100644 --- a/crates/payload/builder/Cargo.toml +++ b/crates/payload/builder/Cargo.toml @@ -14,10 +14,9 @@ workspace = true [dependencies] # reth reth-primitives = { workspace = true, optional = true } -reth-provider.workspace = true +reth-chain-state.workspace = true reth-payload-primitives.workspace = true reth-ethereum-engine-primitives.workspace = true -reth-chain-state = { workspace = true, optional = true } # alloy alloy-primitives = { workspace = true, optional = true } @@ -38,16 +37,13 @@ tracing.workspace = true [dev-dependencies] reth-primitives.workspace = true -reth-chain-state.workspace = true alloy-primitives.workspace = true revm.workspace = true [features] test-utils = [ "alloy-primitives", - "reth-chain-state", "reth-chain-state/test-utils", "reth-primitives/test-utils", - "reth-provider/test-utils", "revm/test-utils" ] diff --git a/crates/payload/builder/src/service.rs b/crates/payload/builder/src/service.rs index 853c69e90d8..43beaf82c38 100644 --- a/crates/payload/builder/src/service.rs +++ b/crates/payload/builder/src/service.rs @@ -9,11 +9,11 @@ use crate::{ }; use alloy_rpc_types::engine::PayloadId; use futures_util::{future::FutureExt, Stream, StreamExt}; +use reth_chain_state::CanonStateNotification; use reth_payload_primitives::{ BuiltPayload, Events, PayloadBuilder, PayloadBuilderAttributes, PayloadBuilderError, PayloadEvents, PayloadKind, PayloadTypes, }; -use reth_provider::CanonStateNotification; use std::{ fmt, future::Future, diff --git a/crates/payload/builder/src/test_utils.rs b/crates/payload/builder/src/test_utils.rs index 746853b74f0..780df5c8463 100644 --- a/crates/payload/builder/src/test_utils.rs +++ b/crates/payload/builder/src/test_utils.rs @@ -6,10 +6,9 @@ use crate::{ }; use alloy_primitives::U256; -use reth_chain_state::ExecutedBlock; +use reth_chain_state::{CanonStateNotification, ExecutedBlock}; use reth_payload_primitives::{PayloadBuilderError, PayloadKind, PayloadTypes}; use reth_primitives::Block; -use reth_provider::CanonStateNotification; use std::{ future::Future, pin::Pin, diff --git a/crates/payload/builder/src/traits.rs b/crates/payload/builder/src/traits.rs index 62dadeb45d7..ba8486b6907 100644 --- a/crates/payload/builder/src/traits.rs +++ b/crates/payload/builder/src/traits.rs @@ -1,9 +1,9 @@ //! Trait abstractions used by the payload crate. +use reth_chain_state::CanonStateNotification; use reth_payload_primitives::{ BuiltPayload, PayloadBuilderAttributes, PayloadBuilderError, PayloadKind, }; -use reth_provider::CanonStateNotification; use std::future::Future; /// A type that can build a payload. From 37e1f77047b6790f19de500e32e5908a1ca73ac3 Mon Sep 17 00:00:00 2001 From: greg <82421016+greged93@users.noreply.github.com> Date: Thu, 7 Nov 2024 15:58:09 +0100 Subject: [PATCH 054/211] chore: remove unused deconstruction (#12377) Signed-off-by: Gregory Edison --- crates/stages/stages/src/stages/execution.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/stages/stages/src/stages/execution.rs b/crates/stages/stages/src/stages/execution.rs index 47cd9d0445a..88d5f830378 100644 --- a/crates/stages/stages/src/stages/execution.rs +++ b/crates/stages/stages/src/stages/execution.rs @@ -8,7 +8,7 @@ use reth_evm::{ execute::{BatchExecutor, BlockExecutorProvider}, metrics::ExecutorMetrics, }; -use reth_execution_types::{Chain, ExecutionOutcome}; +use reth_execution_types::Chain; use reth_exex::{ExExManagerHandle, ExExNotification, ExExNotificationSource}; use reth_primitives::{Header, SealedHeader, StaticFileSegment}; use reth_primitives_traits::format_gas_throughput; @@ -325,8 +325,7 @@ where // prepare execution output for writing let time = Instant::now(); - let ExecutionOutcome { bundle, receipts, requests, first_block } = executor.finalize(); - let state = ExecutionOutcome::new(bundle, receipts, first_block, requests); + let state = executor.finalize(); let write_preparation_duration = time.elapsed(); // log the gas per second for the range we just executed From 190a1d8bb4df777cf19a90ce072e9c4435a6bcfb Mon Sep 17 00:00:00 2001 From: Alexey Shekhirin Date: Fri, 8 Nov 2024 00:21:53 +0900 Subject: [PATCH 055/211] feat(trie): reveal storage slots and calculate storage root in sparse trie (#12145) --- crates/trie/sparse/src/state.rs | 129 ++++++++++++++++++++++++-------- 1 file changed, 96 insertions(+), 33 deletions(-) diff --git a/crates/trie/sparse/src/state.rs b/crates/trie/sparse/src/state.rs index cfb17ef36ff..126e05e8582 100644 --- a/crates/trie/sparse/src/state.rs +++ b/crates/trie/sparse/src/state.rs @@ -1,3 +1,5 @@ +use std::iter::Peekable; + use crate::{SparseStateTrieError, SparseStateTrieResult, SparseTrie}; use alloy_primitives::{ map::{HashMap, HashSet}, @@ -12,10 +14,8 @@ pub struct SparseStateTrie { /// Sparse account trie. pub(crate) state: SparseTrie, /// Sparse storage tries. - #[allow(dead_code)] pub(crate) storages: HashMap, /// Collection of revealed account and storage keys. - #[allow(dead_code)] pub(crate) revealed: HashMap>, } @@ -35,7 +35,7 @@ impl SparseStateTrie { self.revealed.get(account).map_or(false, |slots| slots.contains(slot)) } - /// Reveal unknown trie paths from provided leaf path and its proof. + /// Reveal unknown trie paths from provided leaf path and its proof for the account. /// NOTE: This method does not extensively validate the proof. pub fn reveal_account( &mut self, @@ -44,22 +44,12 @@ impl SparseStateTrie { ) -> SparseStateTrieResult<()> { let mut proof = proof.into_iter().peekable(); - // reveal root and initialize the trie if not already - let Some((path, node)) = proof.next() else { return Ok(()) }; - if !path.is_empty() { - return Err(SparseStateTrieError::InvalidRootNode { path, node }) - } - - // Decode root node and perform sanity check. - let root_node = TrieNode::decode(&mut &node[..])?; - if matches!(root_node, TrieNode::EmptyRoot) && proof.peek().is_some() { - return Err(SparseStateTrieError::InvalidRootNode { path, node }) - } + let Some(root_node) = self.validate_proof(&mut proof)? else { return Ok(()) }; // Reveal root node if it wasn't already. let trie = self.state.reveal_root(root_node)?; - // add the remaining proof nodes + // Reveal the remaining proof nodes. for (path, bytes) in proof { let node = TrieNode::decode(&mut &bytes[..])?; trie.reveal_node(path, node)?; @@ -71,6 +61,55 @@ impl SparseStateTrie { Ok(()) } + /// Reveal unknown trie paths from provided leaf path and its proof for the storage slot. + /// NOTE: This method does not extensively validate the proof. + pub fn reveal_storage_slot( + &mut self, + account: B256, + slot: B256, + proof: impl IntoIterator, + ) -> SparseStateTrieResult<()> { + let mut proof = proof.into_iter().peekable(); + + let Some(root_node) = self.validate_proof(&mut proof)? else { return Ok(()) }; + + // Reveal root node if it wasn't already. + let trie = self.storages.entry(account).or_default().reveal_root(root_node)?; + + // Reveal the remaining proof nodes. + for (path, bytes) in proof { + let node = TrieNode::decode(&mut &bytes[..])?; + trie.reveal_node(path, node)?; + } + + // Mark leaf path as revealed. + self.revealed.entry(account).or_default().insert(slot); + + Ok(()) + } + + /// Validates the root node of the proof and returns it if it exists and is valid. + fn validate_proof>( + &self, + proof: &mut Peekable, + ) -> SparseStateTrieResult> { + let mut proof = proof.into_iter().peekable(); + + // Validate root node. + let Some((path, node)) = proof.next() else { return Ok(None) }; + if !path.is_empty() { + return Err(SparseStateTrieError::InvalidRootNode { path, node }) + } + + // Decode root node and perform sanity check. + let root_node = TrieNode::decode(&mut &node[..])?; + if matches!(root_node, TrieNode::EmptyRoot) && proof.peek().is_some() { + return Err(SparseStateTrieError::InvalidRootNode { path, node }) + } + + Ok(Some(root_node)) + } + /// Update the leaf node. pub fn update_leaf(&mut self, path: Nibbles, value: Vec) -> SparseStateTrieResult<()> { self.state.update_leaf(path, value)?; @@ -81,6 +120,11 @@ impl SparseStateTrie { pub fn root(&mut self) -> Option { self.state.root() } + + /// Returns storage sparse trie root if the trie has been revealed. + pub fn storage_root(&mut self, account: B256) -> Option { + self.storages.get_mut(&account).and_then(|trie| trie.root()) + } } #[cfg(test)] @@ -93,7 +137,30 @@ mod tests { use reth_trie_common::proof::ProofRetainer; #[test] - fn sparse_trie_reveal_empty() { + fn validate_proof_first_node_not_root() { + let sparse = SparseStateTrie::default(); + let proof = [(Nibbles::from_nibbles([0x1]), Bytes::from([EMPTY_STRING_CODE]))]; + assert_matches!( + sparse.validate_proof(&mut proof.into_iter().peekable()), + Err(SparseStateTrieError::InvalidRootNode { .. }) + ); + } + + #[test] + fn validate_proof_invalid_proof_with_empty_root() { + let sparse = SparseStateTrie::default(); + let proof = [ + (Nibbles::default(), Bytes::from([EMPTY_STRING_CODE])), + (Nibbles::from_nibbles([0x1]), Bytes::new()), + ]; + assert_matches!( + sparse.validate_proof(&mut proof.into_iter().peekable()), + Err(SparseStateTrieError::InvalidRootNode { .. }) + ); + } + + #[test] + fn reveal_account_empty() { let retainer = ProofRetainer::from_iter([Nibbles::default()]); let mut hash_builder = HashBuilder::default().with_proof_retainer(retainer); hash_builder.root(); @@ -107,25 +174,21 @@ mod tests { } #[test] - fn reveal_first_node_not_root() { - let mut sparse = SparseStateTrie::default(); - let proof = [(Nibbles::from_nibbles([0x1]), Bytes::from([EMPTY_STRING_CODE]))]; - assert_matches!( - sparse.reveal_account(Default::default(), proof), - Err(SparseStateTrieError::InvalidRootNode { .. }) - ); - } + fn reveal_storage_slot_empty() { + let retainer = ProofRetainer::from_iter([Nibbles::default()]); + let mut hash_builder = HashBuilder::default().with_proof_retainer(retainer); + hash_builder.root(); + let proofs = hash_builder.take_proof_nodes(); + assert_eq!(proofs.len(), 1); - #[test] - fn reveal_invalid_proof_with_empty_root() { let mut sparse = SparseStateTrie::default(); - let proof = [ - (Nibbles::default(), Bytes::from([EMPTY_STRING_CODE])), - (Nibbles::from_nibbles([0x1]), Bytes::new()), - ]; - assert_matches!( - sparse.reveal_account(Default::default(), proof), - Err(SparseStateTrieError::InvalidRootNode { .. }) + assert!(sparse.storages.is_empty()); + sparse + .reveal_storage_slot(Default::default(), Default::default(), proofs.into_inner()) + .unwrap(); + assert_eq!( + sparse.storages, + HashMap::from_iter([(Default::default(), SparseTrie::revealed_empty())]) ); } } From cf095a7536d9a21a1c16cfb9dac2654a1889f1e8 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 7 Nov 2024 16:42:37 +0100 Subject: [PATCH 056/211] chore: reorder super (#12380) --- crates/consensus/auto-seal/src/lib.rs | 3 +-- crates/etl/src/lib.rs | 3 +-- crates/net/discv5/src/config.rs | 6 ++---- crates/net/discv5/src/filter.rs | 6 ++---- crates/net/network/src/config.rs | 3 +-- crates/net/network/src/transactions/fetcher.rs | 9 +++------ crates/net/network/src/transactions/validation.rs | 1 - crates/net/peers/src/node_record.rs | 3 +-- crates/rpc/ipc/src/client/mod.rs | 3 +-- crates/transaction-pool/src/pool/txpool.rs | 5 ++--- crates/trie/trie/src/state.rs | 3 +-- 11 files changed, 15 insertions(+), 30 deletions(-) diff --git a/crates/consensus/auto-seal/src/lib.rs b/crates/consensus/auto-seal/src/lib.rs index ad7e66acc0e..a2f9fa4fa03 100644 --- a/crates/consensus/auto-seal/src/lib.rs +++ b/crates/consensus/auto-seal/src/lib.rs @@ -438,11 +438,10 @@ impl StorageInner { #[cfg(test)] mod tests { + use super::*; use reth_chainspec::{ChainHardforks, ChainSpec, EthereumHardfork, ForkCondition}; use reth_primitives::Transaction; - use super::*; - #[test] fn test_block_hash() { let mut storage = StorageInner::default(); diff --git a/crates/etl/src/lib.rs b/crates/etl/src/lib.rs index d30f432f9c1..46d41d704d0 100644 --- a/crates/etl/src/lib.rs +++ b/crates/etl/src/lib.rs @@ -281,9 +281,8 @@ impl EtlFile { #[cfg(test)] mod tests { - use alloy_primitives::{TxHash, TxNumber}; - use super::*; + use alloy_primitives::{TxHash, TxNumber}; #[test] fn etl_hashes() { diff --git a/crates/net/discv5/src/config.rs b/crates/net/discv5/src/config.rs index 203ef76134b..4a534afbef5 100644 --- a/crates/net/discv5/src/config.rs +++ b/crates/net/discv5/src/config.rs @@ -477,11 +477,9 @@ impl BootNode { #[cfg(test)] mod test { - use std::net::SocketAddrV4; - - use alloy_primitives::hex; - use super::*; + use alloy_primitives::hex; + use std::net::SocketAddrV4; const MULTI_ADDRESSES: &str = "/ip4/184.72.129.189/udp/30301/p2p/16Uiu2HAmSG2hdLwyQHQmG4bcJBgD64xnW63WMTLcrNq6KoZREfGb,/ip4/3.231.11.52/udp/30301/p2p/16Uiu2HAmMy4V8bi3XP7KDfSLQcLACSvTLroRRwEsTyFUKo8NCkkp,/ip4/54.198.153.150/udp/30301/p2p/16Uiu2HAmSVsb7MbRf1jg3Dvd6a3n5YNqKQwn1fqHCFgnbqCsFZKe,/ip4/3.220.145.177/udp/30301/p2p/16Uiu2HAm74pBDGdQ84XCZK27GRQbGFFwQ7RsSqsPwcGmCR3Cwn3B,/ip4/3.231.138.188/udp/30301/p2p/16Uiu2HAmMnTiJwgFtSVGV14ZNpwAvS1LUoF4pWWeNtURuV6C3zYB"; const BOOT_NODES_OP_MAINNET_AND_BASE_MAINNET: &[&str] = &[ diff --git a/crates/net/discv5/src/filter.rs b/crates/net/discv5/src/filter.rs index 325544de6c1..a83345a9a5e 100644 --- a/crates/net/discv5/src/filter.rs +++ b/crates/net/discv5/src/filter.rs @@ -89,13 +89,11 @@ impl MustNotIncludeKeys { #[cfg(test)] mod tests { + use super::*; + use crate::NetworkStackId; use alloy_rlp::Bytes; use discv5::enr::{CombinedKey, Enr}; - use crate::NetworkStackId; - - use super::*; - #[test] fn must_not_include_key_filter() { // rig test diff --git a/crates/net/network/src/config.rs b/crates/net/network/src/config.rs index 72627f5b657..96aef249d9f 100644 --- a/crates/net/network/src/config.rs +++ b/crates/net/network/src/config.rs @@ -631,14 +631,13 @@ impl NetworkMode { #[cfg(test)] mod tests { - use std::sync::Arc; - use super::*; use rand::thread_rng; use reth_chainspec::{Chain, MAINNET}; use reth_dns_discovery::tree::LinkEntry; use reth_primitives::ForkHash; use reth_provider::test_utils::NoopProvider; + use std::sync::Arc; fn builder() -> NetworkConfigBuilder { let secret_key = SecretKey::new(&mut thread_rng()); diff --git a/crates/net/network/src/transactions/fetcher.rs b/crates/net/network/src/transactions/fetcher.rs index 3e856951552..00a9158233b 100644 --- a/crates/net/network/src/transactions/fetcher.rs +++ b/crates/net/network/src/transactions/fetcher.rs @@ -1343,16 +1343,13 @@ struct TxFetcherSearchDurations { #[cfg(test)] mod test { - use std::{collections::HashSet, str::FromStr}; - + use super::*; + use crate::transactions::tests::{default_cache, new_mock_session}; use alloy_primitives::{hex, B256}; use alloy_rlp::Decodable; use derive_more::IntoIterator; use reth_primitives::TransactionSigned; - - use crate::transactions::tests::{default_cache, new_mock_session}; - - use super::*; + use std::{collections::HashSet, str::FromStr}; #[derive(IntoIterator)] struct TestValidAnnouncementData(Vec<(TxHash, Option<(u8, usize)>)>); diff --git a/crates/net/network/src/transactions/validation.rs b/crates/net/network/src/transactions/validation.rs index 4038f23e85c..7bfe07761a2 100644 --- a/crates/net/network/src/transactions/validation.rs +++ b/crates/net/network/src/transactions/validation.rs @@ -336,7 +336,6 @@ impl FilterAnnouncement for EthMessageFilter { #[cfg(test)] mod test { use super::*; - use alloy_primitives::B256; use reth_eth_wire::{NewPooledTransactionHashes66, NewPooledTransactionHashes68}; use std::{collections::HashMap, str::FromStr}; diff --git a/crates/net/peers/src/node_record.rs b/crates/net/peers/src/node_record.rs index d6836d88193..ed48e242c1d 100644 --- a/crates/net/peers/src/node_record.rs +++ b/crates/net/peers/src/node_record.rs @@ -231,12 +231,11 @@ impl TryFrom<&Enr> for NodeRecord { #[cfg(test)] mod tests { + use super::*; use alloy_rlp::Decodable; use rand::{thread_rng, Rng, RngCore}; use std::net::Ipv6Addr; - use super::*; - #[test] fn test_mapped_ipv6() { let mut rng = thread_rng(); diff --git a/crates/rpc/ipc/src/client/mod.rs b/crates/rpc/ipc/src/client/mod.rs index 8f2fe0255c7..48f58e77a4a 100644 --- a/crates/rpc/ipc/src/client/mod.rs +++ b/crates/rpc/ipc/src/client/mod.rs @@ -136,10 +136,9 @@ pub enum IpcError { #[cfg(test)] mod tests { - use interprocess::local_socket::ListenerOptions; - use super::*; use crate::server::dummy_name; + use interprocess::local_socket::ListenerOptions; #[tokio::test] async fn test_connect() { diff --git a/crates/transaction-pool/src/pool/txpool.rs b/crates/transaction-pool/src/pool/txpool.rs index 8679a4318be..1258f4a270a 100644 --- a/crates/transaction-pool/src/pool/txpool.rs +++ b/crates/transaction-pool/src/pool/txpool.rs @@ -1936,15 +1936,14 @@ impl SenderInfo { #[cfg(test)] mod tests { - use alloy_primitives::address; - use reth_primitives::TxType; - use super::*; use crate::{ test_utils::{MockOrdering, MockTransaction, MockTransactionFactory, MockTransactionSet}, traits::TransactionOrigin, SubPoolLimit, }; + use alloy_primitives::address; + use reth_primitives::TxType; #[test] fn test_insert_blob() { diff --git a/crates/trie/trie/src/state.rs b/crates/trie/trie/src/state.rs index 2af48dfff79..eca126744e9 100644 --- a/crates/trie/trie/src/state.rs +++ b/crates/trie/trie/src/state.rs @@ -347,6 +347,7 @@ impl HashedStorageSorted { #[cfg(test)] mod tests { + use super::*; use alloy_primitives::Bytes; use revm::{ db::{ @@ -356,8 +357,6 @@ mod tests { primitives::{AccountInfo, Bytecode}, }; - use super::*; - #[test] fn hashed_state_wiped_extension() { let hashed_address = B256::default(); From b1642f966f8932baf40d52947e56c0e0825fe994 Mon Sep 17 00:00:00 2001 From: Kunal Arora <55632507+aroralanuk@users.noreply.github.com> Date: Thu, 7 Nov 2024 21:03:31 +0530 Subject: [PATCH 057/211] feat(payload): add support for stack of payload builders (#11004) Co-authored-by: Matthias Seitz --- crates/payload/basic/src/lib.rs | 18 ++ crates/payload/basic/src/stack.rs | 270 ++++++++++++++++++++++++++++++ 2 files changed, 288 insertions(+) create mode 100644 crates/payload/basic/src/stack.rs diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index 867125d808b..0fc63a5a149 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -42,6 +42,9 @@ use tokio::{ use tracing::{debug, trace, warn}; mod metrics; +mod stack; + +pub use stack::PayloadBuilderStack; /// The [`PayloadJobGenerator`] that creates [`BasicPayloadJob`]s. #[derive(Debug)] @@ -783,6 +786,21 @@ impl BuildOutcome { pub const fn is_cancelled(&self) -> bool { matches!(self, Self::Cancelled) } + + /// Applies a fn on the current payload. + pub(crate) fn map_payload(self, f: F) -> BuildOutcome

+ where + F: FnOnce(Payload) -> P, + { + match self { + Self::Better { payload, cached_reads } => { + BuildOutcome::Better { payload: f(payload), cached_reads } + } + Self::Aborted { fees, cached_reads } => BuildOutcome::Aborted { fees, cached_reads }, + Self::Cancelled => BuildOutcome::Cancelled, + Self::Freeze(payload) => BuildOutcome::Freeze(f(payload)), + } + } } /// The possible outcomes of a payload building attempt without reused [`CachedReads`] diff --git a/crates/payload/basic/src/stack.rs b/crates/payload/basic/src/stack.rs new file mode 100644 index 00000000000..722399ab278 --- /dev/null +++ b/crates/payload/basic/src/stack.rs @@ -0,0 +1,270 @@ +use crate::{ + BuildArguments, BuildOutcome, PayloadBuilder, PayloadBuilderAttributes, PayloadBuilderError, + PayloadConfig, +}; + +use alloy_primitives::{Address, B256, U256}; +use reth_payload_builder::PayloadId; +use reth_payload_primitives::BuiltPayload; +use reth_primitives::{SealedBlock, Withdrawals}; + +use alloy_eips::eip7685::Requests; +use std::{error::Error, fmt}; + +/// hand rolled Either enum to handle two builder types +#[derive(Debug, Clone)] +pub enum Either { + /// left variant + Left(L), + /// right variant + Right(R), +} + +impl fmt::Display for Either +where + L: fmt::Display, + R: fmt::Display, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Left(l) => write!(f, "Left: {}", l), + Self::Right(r) => write!(f, "Right: {}", r), + } + } +} + +impl Error for Either +where + L: Error + 'static, + R: Error + 'static, +{ + fn source(&self) -> Option<&(dyn Error + 'static)> { + match self { + Self::Left(l) => Some(l), + Self::Right(r) => Some(r), + } + } +} + +impl PayloadBuilderAttributes for Either +where + L: PayloadBuilderAttributes, + R: PayloadBuilderAttributes, + L::Error: Error + 'static, + R::Error: Error + 'static, +{ + type RpcPayloadAttributes = Either; + type Error = Either; + + fn try_new( + parent: B256, + rpc_payload_attributes: Self::RpcPayloadAttributes, + version: u8, + ) -> Result { + match rpc_payload_attributes { + Either::Left(attr) => { + L::try_new(parent, attr, version).map(Either::Left).map_err(Either::Left) + } + Either::Right(attr) => { + R::try_new(parent, attr, version).map(Either::Right).map_err(Either::Right) + } + } + } + + fn payload_id(&self) -> PayloadId { + match self { + Self::Left(l) => l.payload_id(), + Self::Right(r) => r.payload_id(), + } + } + + fn parent(&self) -> B256 { + match self { + Self::Left(l) => l.parent(), + Self::Right(r) => r.parent(), + } + } + + fn timestamp(&self) -> u64 { + match self { + Self::Left(l) => l.timestamp(), + Self::Right(r) => r.timestamp(), + } + } + + fn parent_beacon_block_root(&self) -> Option { + match self { + Self::Left(l) => l.parent_beacon_block_root(), + Self::Right(r) => r.parent_beacon_block_root(), + } + } + + fn suggested_fee_recipient(&self) -> Address { + match self { + Self::Left(l) => l.suggested_fee_recipient(), + Self::Right(r) => r.suggested_fee_recipient(), + } + } + + fn prev_randao(&self) -> B256 { + match self { + Self::Left(l) => l.prev_randao(), + Self::Right(r) => r.prev_randao(), + } + } + + fn withdrawals(&self) -> &Withdrawals { + match self { + Self::Left(l) => l.withdrawals(), + Self::Right(r) => r.withdrawals(), + } + } +} + +/// this structure enables the chaining of multiple `PayloadBuilder` implementations, +/// creating a hierarchical fallback system. It's designed to be nestable, allowing +/// for complex builder arrangements like `Stack, C>` with different +#[derive(Debug)] +pub struct PayloadBuilderStack { + left: L, + right: R, +} + +impl PayloadBuilderStack { + /// Creates a new `PayloadBuilderStack` with the given left and right builders. + pub const fn new(left: L, right: R) -> Self { + Self { left, right } + } +} + +impl Clone for PayloadBuilderStack +where + L: Clone, + R: Clone, +{ + fn clone(&self) -> Self { + Self::new(self.left.clone(), self.right.clone()) + } +} + +impl BuiltPayload for Either +where + L: BuiltPayload, + R: BuiltPayload, +{ + fn block(&self) -> &SealedBlock { + match self { + Self::Left(l) => l.block(), + Self::Right(r) => r.block(), + } + } + + fn fees(&self) -> U256 { + match self { + Self::Left(l) => l.fees(), + Self::Right(r) => r.fees(), + } + } + + fn requests(&self) -> Option { + match self { + Self::Left(l) => l.requests(), + Self::Right(r) => r.requests(), + } + } +} + +impl PayloadBuilder for PayloadBuilderStack +where + L: PayloadBuilder + Unpin + 'static, + R: PayloadBuilder + Unpin + 'static, + Client: Clone, + Pool: Clone, + L::Attributes: Unpin + Clone, + R::Attributes: Unpin + Clone, + L::BuiltPayload: Unpin + Clone, + R::BuiltPayload: Unpin + Clone, + <>::Attributes as PayloadBuilderAttributes>::Error: 'static, + <>::Attributes as PayloadBuilderAttributes>::Error: 'static, +{ + type Attributes = Either; + type BuiltPayload = Either; + + fn try_build( + &self, + args: BuildArguments, + ) -> Result, PayloadBuilderError> { + match args.config.attributes { + Either::Left(ref left_attr) => { + let left_args: BuildArguments = + BuildArguments { + client: args.client.clone(), + pool: args.pool.clone(), + cached_reads: args.cached_reads.clone(), + config: PayloadConfig { + parent_header: args.config.parent_header.clone(), + extra_data: args.config.extra_data.clone(), + attributes: left_attr.clone(), + }, + cancel: args.cancel.clone(), + best_payload: args.best_payload.clone().and_then(|payload| { + if let Either::Left(p) = payload { + Some(p) + } else { + None + } + }), + }; + + self.left.try_build(left_args).map(|out| out.map_payload(Either::Left)) + } + Either::Right(ref right_attr) => { + let right_args = BuildArguments { + client: args.client.clone(), + pool: args.pool.clone(), + cached_reads: args.cached_reads.clone(), + config: PayloadConfig { + parent_header: args.config.parent_header.clone(), + extra_data: args.config.extra_data.clone(), + attributes: right_attr.clone(), + }, + cancel: args.cancel.clone(), + best_payload: args.best_payload.clone().and_then(|payload| { + if let Either::Right(p) = payload { + Some(p) + } else { + None + } + }), + }; + + self.right.try_build(right_args).map(|out| out.map_payload(Either::Right)) + } + } + } + + fn build_empty_payload( + &self, + client: &Client, + config: PayloadConfig, + ) -> Result { + match config.attributes { + Either::Left(left_attr) => { + let left_config = PayloadConfig { + attributes: left_attr, + parent_header: config.parent_header.clone(), + extra_data: config.extra_data.clone(), + }; + self.left.build_empty_payload(client, left_config).map(Either::Left) + } + Either::Right(right_attr) => { + let right_config = PayloadConfig { + parent_header: config.parent_header.clone(), + extra_data: config.extra_data.clone(), + attributes: right_attr, + }; + self.right.build_empty_payload(client, right_config).map(Either::Right) + } + } + } +} From e911fe9ff03528aef9498a94c4ba7467fdeeb6b6 Mon Sep 17 00:00:00 2001 From: Steven <112043913+stevencartavia@users.noreply.github.com> Date: Thu, 7 Nov 2024 10:30:54 -0600 Subject: [PATCH 058/211] renamed OptimismBlockExecutionError to OpBlockExecutionError (#12383) --- crates/optimism/evm/src/error.rs | 8 +++---- crates/optimism/evm/src/execute.rs | 8 +++---- crates/optimism/evm/src/l1.rs | 36 +++++++++++++++--------------- crates/optimism/evm/src/lib.rs | 2 +- crates/optimism/rpc/src/error.rs | 4 ++-- 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/crates/optimism/evm/src/error.rs b/crates/optimism/evm/src/error.rs index 71f8709e1ad..db042950674 100644 --- a/crates/optimism/evm/src/error.rs +++ b/crates/optimism/evm/src/error.rs @@ -5,7 +5,7 @@ use reth_evm::execute::BlockExecutionError; /// Optimism Block Executor Errors #[derive(Debug, Clone, PartialEq, Eq, derive_more::Display)] -pub enum OptimismBlockExecutionError { +pub enum OpBlockExecutionError { /// Error when trying to parse L1 block info #[display("could not get L1 block info from L2 block: {message}")] L1BlockInfoError { @@ -23,10 +23,10 @@ pub enum OptimismBlockExecutionError { AccountLoadFailed(alloy_primitives::Address), } -impl core::error::Error for OptimismBlockExecutionError {} +impl core::error::Error for OpBlockExecutionError {} -impl From for BlockExecutionError { - fn from(err: OptimismBlockExecutionError) -> Self { +impl From for BlockExecutionError { + fn from(err: OpBlockExecutionError) -> Self { Self::other(err) } } diff --git a/crates/optimism/evm/src/execute.rs b/crates/optimism/evm/src/execute.rs index 3702f13a47d..8d701cda423 100644 --- a/crates/optimism/evm/src/execute.rs +++ b/crates/optimism/evm/src/execute.rs @@ -1,6 +1,6 @@ //! Optimism block execution strategy. -use crate::{l1::ensure_create2_deployer, OpEvmConfig, OptimismBlockExecutionError}; +use crate::{l1::ensure_create2_deployer, OpBlockExecutionError, OpEvmConfig}; use alloc::{boxed::Box, sync::Arc, vec::Vec}; use alloy_consensus::Transaction as _; use alloy_eips::eip7685::Requests; @@ -144,7 +144,7 @@ where // 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. ensure_create2_deployer(self.chain_spec.clone(), block.timestamp, evm.db_mut()) - .map_err(|_| OptimismBlockExecutionError::ForceCreate2DeployerFail)?; + .map_err(|_| OpBlockExecutionError::ForceCreate2DeployerFail)?; Ok(()) } @@ -178,7 +178,7 @@ where // An optimism block should never contain blob transactions. if matches!(transaction.tx_type(), TxType::Eip4844) { - return Err(OptimismBlockExecutionError::BlobTransactionRejected.into()) + return Err(OpBlockExecutionError::BlobTransactionRejected.into()) } // Cache the depositor account prior to the state transition for the deposit nonce. @@ -193,7 +193,7 @@ where .map(|acc| acc.account_info().unwrap_or_default()) }) .transpose() - .map_err(|_| OptimismBlockExecutionError::AccountLoadFailed(*sender))?; + .map_err(|_| OpBlockExecutionError::AccountLoadFailed(*sender))?; self.evm_config.fill_tx_env(evm.tx_mut(), transaction, *sender); diff --git a/crates/optimism/evm/src/l1.rs b/crates/optimism/evm/src/l1.rs index e0668ab0204..cdd33510c92 100644 --- a/crates/optimism/evm/src/l1.rs +++ b/crates/optimism/evm/src/l1.rs @@ -1,6 +1,6 @@ //! Optimism-specific implementation and utilities for the executor -use crate::OptimismBlockExecutionError; +use crate::OpBlockExecutionError; use alloc::{string::ToString, sync::Arc}; use alloy_primitives::{address, b256, hex, Address, Bytes, B256, U256}; use reth_chainspec::ChainSpec; @@ -31,17 +31,17 @@ const L1_BLOCK_ECOTONE_SELECTOR: [u8; 4] = hex!("440a5e20"); /// transaction in the L2 block. /// /// Returns an error if the L1 info transaction is not found, if the block is empty. -pub fn extract_l1_info(body: &BlockBody) -> Result { +pub fn extract_l1_info(body: &BlockBody) -> Result { let l1_info_tx_data = body .transactions .first() - .ok_or_else(|| OptimismBlockExecutionError::L1BlockInfoError { + .ok_or_else(|| OpBlockExecutionError::L1BlockInfoError { message: "could not find l1 block info tx in the L2 block".to_string(), }) .map(|tx| tx.input())?; if l1_info_tx_data.len() < 4 { - return Err(OptimismBlockExecutionError::L1BlockInfoError { + return Err(OpBlockExecutionError::L1BlockInfoError { message: "invalid l1 block info transaction calldata in the L2 block".to_string(), }) } @@ -52,7 +52,7 @@ pub fn extract_l1_info(body: &BlockBody) -> Result Result { +pub fn parse_l1_info(input: &[u8]) -> Result { // If the first 4 bytes of the calldata are the L1BlockInfoEcotone selector, then we parse the // calldata as an Ecotone hardfork L1BlockInfo transaction. Otherwise, we parse it as a // Bedrock hardfork L1BlockInfo transaction. @@ -64,7 +64,7 @@ pub fn parse_l1_info(input: &[u8]) -> Result Result { +pub fn parse_l1_info_tx_bedrock(data: &[u8]) -> Result { // The setL1BlockValues tx calldata must be exactly 260 bytes long, considering that // we already removed the first 4 bytes (the function selector). Detailed breakdown: // 32 bytes for the block number @@ -76,23 +76,23 @@ pub fn parse_l1_info_tx_bedrock(data: &[u8]) -> Result Result -pub fn parse_l1_info_tx_ecotone(data: &[u8]) -> Result { +pub fn parse_l1_info_tx_ecotone(data: &[u8]) -> Result { if data.len() != 160 { - return Err(OptimismBlockExecutionError::L1BlockInfoError { + return Err(OpBlockExecutionError::L1BlockInfoError { message: "unexpected l1 block info tx calldata length found".to_string(), }) } @@ -142,22 +142,22 @@ pub fn parse_l1_info_tx_ecotone(data: &[u8]) -> Result Date: Thu, 7 Nov 2024 17:56:35 +0100 Subject: [PATCH 059/211] chore: improve deps for payload prims (#12374) --- .config/zepter.yaml | 1 + Cargo.lock | 2 +- crates/consensus/beacon/Cargo.toml | 2 +- crates/optimism/payload/Cargo.toml | 2 +- crates/payload/primitives/Cargo.toml | 7 +++++-- crates/payload/primitives/src/payload.rs | 5 +++-- crates/payload/primitives/src/traits.rs | 11 ++++------- 7 files changed, 16 insertions(+), 14 deletions(-) diff --git a/.config/zepter.yaml b/.config/zepter.yaml index 8c6425f4ff0..f5d320b4af9 100644 --- a/.config/zepter.yaml +++ b/.config/zepter.yaml @@ -16,6 +16,7 @@ workflows: # Do not try to add a new section into `[features]` of `A` only because `B` expose that feature. There are edge-cases where this is still needed, but we can add them manually. "--left-side-feature-missing=ignore", # Ignore the case that `A` it outside of the workspace. Otherwise it will report errors in external dependencies that we have no influence on. + "--left-side-outside-workspace=ignore", # Auxillary flags: "--offline", diff --git a/Cargo.lock b/Cargo.lock index 7ce5daf705f..34a6fe0f98a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8417,7 +8417,7 @@ version = "1.1.1" dependencies = [ "alloy-eips", "alloy-primitives", - "alloy-rpc-types", + "alloy-rpc-types-engine", "async-trait", "op-alloy-rpc-types-engine", "pin-project", diff --git a/crates/consensus/beacon/Cargo.toml b/crates/consensus/beacon/Cargo.toml index 1abc09b2a44..d3aa5124668 100644 --- a/crates/consensus/beacon/Cargo.toml +++ b/crates/consensus/beacon/Cargo.toml @@ -32,7 +32,7 @@ reth-chainspec = { workspace = true, optional = true } # ethereum alloy-primitives.workspace = true -alloy-rpc-types-engine.workspace = true +alloy-rpc-types-engine = { workspace = true, features = ["std"] } alloy-eips.workspace = true # async diff --git a/crates/optimism/payload/Cargo.toml b/crates/optimism/payload/Cargo.toml index 4b8e64f2dba..839355b2158 100644 --- a/crates/optimism/payload/Cargo.toml +++ b/crates/optimism/payload/Cargo.toml @@ -22,7 +22,7 @@ reth-rpc-types-compat.workspace = true reth-evm.workspace = true reth-execution-types.workspace = true reth-payload-builder.workspace = true -reth-payload-primitives.workspace = true +reth-payload-primitives = { workspace = true, features = ["op"] } reth-basic-payload-builder.workspace = true reth-trie.workspace = true reth-chain-state.workspace = true diff --git a/crates/payload/primitives/Cargo.toml b/crates/payload/primitives/Cargo.toml index ad8ce63a7e9..951108e7da3 100644 --- a/crates/payload/primitives/Cargo.toml +++ b/crates/payload/primitives/Cargo.toml @@ -22,8 +22,8 @@ reth-chain-state.workspace = true # alloy alloy-eips.workspace = true alloy-primitives.workspace = true -alloy-rpc-types = { workspace = true, features = ["engine"] } -op-alloy-rpc-types-engine.workspace = true +alloy-rpc-types-engine = { workspace = true, features = ["serde"] } +op-alloy-rpc-types-engine = { workspace = true, optional = true } # async async-trait.workspace = true @@ -35,3 +35,6 @@ pin-project.workspace = true serde.workspace = true thiserror.workspace = true tracing.workspace = true + +[features] +op = ["dep:op-alloy-rpc-types-engine"] \ No newline at end of file diff --git a/crates/payload/primitives/src/payload.rs b/crates/payload/primitives/src/payload.rs index fc685559e08..bcf48cea834 100644 --- a/crates/payload/primitives/src/payload.rs +++ b/crates/payload/primitives/src/payload.rs @@ -1,6 +1,7 @@ use crate::{MessageValidationKind, PayloadAttributes}; +use alloy_eips::eip4895::Withdrawal; use alloy_primitives::B256; -use alloy_rpc_types::engine::ExecutionPayload; +use alloy_rpc_types_engine::ExecutionPayload; /// Either an [`ExecutionPayload`] or a types that implements the [`PayloadAttributes`] trait. /// @@ -39,7 +40,7 @@ where Attributes: PayloadAttributes, { /// Return the withdrawals for the payload or attributes. - pub fn withdrawals(&self) -> Option<&Vec> { + pub fn withdrawals(&self) -> Option<&Vec> { match self { Self::ExecutionPayload { payload, .. } => payload.withdrawals(), Self::PayloadAttributes(attributes) => attributes.withdrawals(), diff --git a/crates/payload/primitives/src/traits.rs b/crates/payload/primitives/src/traits.rs index a78dc8c1322..7ae558b9945 100644 --- a/crates/payload/primitives/src/traits.rs +++ b/crates/payload/primitives/src/traits.rs @@ -1,11 +1,7 @@ use crate::{PayloadEvents, PayloadKind, PayloadTypes}; -use alloy_eips::eip7685::Requests; +use alloy_eips::{eip4895::Withdrawal, eip7685::Requests}; use alloy_primitives::{Address, B256, U256}; -use alloy_rpc_types::{ - engine::{PayloadAttributes as EthPayloadAttributes, PayloadId}, - Withdrawal, -}; -use op_alloy_rpc_types_engine::OpPayloadAttributes; +use alloy_rpc_types_engine::{PayloadAttributes as EthPayloadAttributes, PayloadId}; use reth_chain_state::ExecutedBlock; use reth_primitives::{SealedBlock, Withdrawals}; use tokio::sync::oneshot; @@ -146,7 +142,8 @@ impl PayloadAttributes for EthPayloadAttributes { } } -impl PayloadAttributes for OpPayloadAttributes { +#[cfg(feature = "op")] +impl PayloadAttributes for op_alloy_rpc_types_engine::OpPayloadAttributes { fn timestamp(&self) -> u64 { self.payload_attributes.timestamp } From 29da7d744a52f9d77d27cc78705dc30e265f20bf Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Thu, 7 Nov 2024 23:31:17 +0400 Subject: [PATCH 060/211] fix: `eth_getProof` response (#12370) --- crates/rpc/rpc-eth-api/src/helpers/state.rs | 2 +- crates/rpc/rpc-types-compat/src/proof.rs | 25 ++++++++++++++------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/crates/rpc/rpc-eth-api/src/helpers/state.rs b/crates/rpc/rpc-eth-api/src/helpers/state.rs index f3796b4b9bb..6a34967058b 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/state.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/state.rs @@ -122,7 +122,7 @@ pub trait EthState: LoadState + SpawnBlocking { let proof = state .proof(Default::default(), address, &storage_keys) .map_err(Self::Error::from_eth_err)?; - Ok(from_primitive_account_proof(proof)) + Ok(from_primitive_account_proof(proof, keys)) }) .await }) diff --git a/crates/rpc/rpc-types-compat/src/proof.rs b/crates/rpc/rpc-types-compat/src/proof.rs index 7bdf629e96a..34128801f8d 100644 --- a/crates/rpc/rpc-types-compat/src/proof.rs +++ b/crates/rpc/rpc-types-compat/src/proof.rs @@ -5,16 +5,18 @@ use alloy_rpc_types_eth::{EIP1186AccountProofResponse, EIP1186StorageProof}; use reth_trie_common::{AccountProof, StorageProof}; /// Creates a new rpc storage proof from a primitive storage proof type. -pub fn from_primitive_storage_proof(proof: StorageProof) -> EIP1186StorageProof { - EIP1186StorageProof { - key: JsonStorageKey::Hash(proof.key), - value: proof.value, - proof: proof.proof, - } +pub fn from_primitive_storage_proof( + proof: StorageProof, + slot: JsonStorageKey, +) -> EIP1186StorageProof { + EIP1186StorageProof { key: slot, value: proof.value, proof: proof.proof } } /// Creates a new rpc account proof from a primitive account proof type. -pub fn from_primitive_account_proof(proof: AccountProof) -> EIP1186AccountProofResponse { +pub fn from_primitive_account_proof( + proof: AccountProof, + slots: Vec, +) -> EIP1186AccountProofResponse { let info = proof.info.unwrap_or_default(); EIP1186AccountProofResponse { address: proof.address, @@ -23,6 +25,13 @@ pub fn from_primitive_account_proof(proof: AccountProof) -> EIP1186AccountProofR nonce: info.nonce, storage_hash: proof.storage_root, account_proof: proof.proof, - storage_proof: proof.storage_proofs.into_iter().map(from_primitive_storage_proof).collect(), + storage_proof: proof + .storage_proofs + .into_iter() + .filter_map(|proof| { + let input_slot = slots.iter().find(|s| s.as_b256() == proof.key)?; + Some(from_primitive_storage_proof(proof, *input_slot)) + }) + .collect(), } } From d19032fca1a49e0d826cc1f1dd8475e25493ecb5 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Fri, 8 Nov 2024 01:29:49 +0400 Subject: [PATCH 061/211] chore: remove auto-seal consensus (#12385) --- .github/assets/check_wasm.sh | 1 - Cargo.lock | 34 -- Cargo.toml | 2 - crates/consensus/auto-seal/Cargo.toml | 57 -- crates/consensus/auto-seal/src/client.rs | 132 ----- crates/consensus/auto-seal/src/lib.rs | 690 ----------------------- crates/consensus/auto-seal/src/mode.rs | 166 ------ crates/consensus/auto-seal/src/task.rs | 221 -------- crates/ethereum/node/Cargo.toml | 1 - crates/ethereum/node/src/node.rs | 7 +- crates/ethereum/node/tests/e2e/dev.rs | 12 - crates/node/builder/Cargo.toml | 1 - crates/node/builder/src/launch/common.rs | 11 +- crates/node/builder/src/launch/engine.rs | 9 +- crates/node/builder/src/launch/mod.rs | 46 +- crates/optimism/node/Cargo.toml | 2 - crates/optimism/node/src/node.rs | 6 +- docs/repo/layout.md | 1 - 18 files changed, 11 insertions(+), 1388 deletions(-) delete mode 100644 crates/consensus/auto-seal/Cargo.toml delete mode 100644 crates/consensus/auto-seal/src/client.rs delete mode 100644 crates/consensus/auto-seal/src/lib.rs delete mode 100644 crates/consensus/auto-seal/src/mode.rs delete mode 100644 crates/consensus/auto-seal/src/task.rs diff --git a/.github/assets/check_wasm.sh b/.github/assets/check_wasm.sh index 3b2f2d6b7e6..c34f82d2e31 100755 --- a/.github/assets/check_wasm.sh +++ b/.github/assets/check_wasm.sh @@ -11,7 +11,6 @@ exclude_crates=( # The following are not working yet, but known to be fixable reth-exex-types # https://github.com/paradigmxyz/reth/issues/9946 # The following require investigation if they can be fixed - reth-auto-seal-consensus reth-basic-payload-builder reth-beacon-consensus reth-bench diff --git a/Cargo.lock b/Cargo.lock index 34a6fe0f98a..60bf29c2a07 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6385,37 +6385,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "reth-auto-seal-consensus" -version = "1.1.1" -dependencies = [ - "alloy-eips", - "alloy-primitives", - "alloy-rpc-types-engine", - "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", - "tokio", - "tokio-stream", - "tracing", -] - [[package]] name = "reth-basic-payload-builder" version = "1.1.1" @@ -7924,7 +7893,6 @@ dependencies = [ "futures", "jsonrpsee", "rayon", - "reth-auto-seal-consensus", "reth-beacon-consensus", "reth-blockchain-tree", "reth-chain-state", @@ -8043,7 +8011,6 @@ dependencies = [ "futures", "rand 0.8.5", "reth", - "reth-auto-seal-consensus", "reth-basic-payload-builder", "reth-beacon-consensus", "reth-chainspec", @@ -8266,7 +8233,6 @@ dependencies = [ "op-alloy-rpc-types-engine", "parking_lot", "reth", - "reth-auto-seal-consensus", "reth-basic-payload-builder", "reth-beacon-consensus", "reth-chainspec", diff --git a/Cargo.toml b/Cargo.toml index 8ff8c1eb7fe..dc783f071a7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,6 @@ members = [ "crates/cli/runner/", "crates/cli/util/", "crates/config/", - "crates/consensus/auto-seal/", "crates/consensus/beacon/", "crates/consensus/common/", "crates/consensus/consensus/", @@ -299,7 +298,6 @@ overflow-checks = true # reth op-reth = { path = "crates/optimism/bin" } reth = { path = "bin/reth" } -reth-auto-seal-consensus = { path = "crates/consensus/auto-seal" } reth-basic-payload-builder = { path = "crates/payload/basic" } reth-beacon-consensus = { path = "crates/consensus/beacon" } reth-bench = { path = "bin/reth-bench" } diff --git a/crates/consensus/auto-seal/Cargo.toml b/crates/consensus/auto-seal/Cargo.toml deleted file mode 100644 index f2bfb43bcce..00000000000 --- a/crates/consensus/auto-seal/Cargo.toml +++ /dev/null @@ -1,57 +0,0 @@ -[package] -name = "reth-auto-seal-consensus" -version.workspace = true -edition.workspace = true -rust-version.workspace = true -license.workspace = true -homepage.workspace = true -repository.workspace = true -description = "A consensus impl for local testing purposes" - -[lints] -workspace = true - -[dependencies] -# reth -reth-chainspec.workspace = true -reth-beacon-consensus.workspace = true -reth-primitives.workspace = true -reth-execution-errors.workspace = true -reth-execution-types.workspace = true -reth-network-p2p.workspace = true -reth-provider.workspace = true -reth-stages-api.workspace = true -reth-revm.workspace = true -reth-transaction-pool.workspace = true -reth-evm.workspace = true -reth-engine-primitives.workspace = true -reth-consensus.workspace = true -reth-network-peers.workspace = true -reth-tokio-util.workspace = true -reth-trie.workspace = true - -# ethereum -alloy-eips.workspace = true -alloy-primitives.workspace = true -revm-primitives.workspace = true -alloy-rpc-types-engine.workspace = true - -# optimism -reth-optimism-consensus = { workspace = true, optional = true } - -# async -futures-util.workspace = true -tokio = { workspace = true, features = ["sync", "time"] } -tokio-stream.workspace = true -tracing.workspace = true - -[features] -optimism = [ - "reth-provider/optimism", - "reth-optimism-consensus", - "reth-beacon-consensus/optimism", - "reth-execution-types/optimism", - "reth-optimism-consensus?/optimism", - "reth-primitives/optimism", - "revm-primitives/optimism" -] diff --git a/crates/consensus/auto-seal/src/client.rs b/crates/consensus/auto-seal/src/client.rs deleted file mode 100644 index 0083192d7df..00000000000 --- a/crates/consensus/auto-seal/src/client.rs +++ /dev/null @@ -1,132 +0,0 @@ -//! This includes download client implementations for auto sealing miners. - -use crate::Storage; -use alloy_eips::BlockHashOrNumber; -use alloy_primitives::B256; -use reth_network_p2p::{ - bodies::client::{BodiesClient, BodiesFut}, - download::DownloadClient, - headers::client::{HeadersClient, HeadersDirection, HeadersFut, HeadersRequest}, - priority::Priority, -}; -use reth_network_peers::{PeerId, WithPeerId}; -use reth_primitives::{BlockBody, Header}; -use std::fmt::Debug; -use tracing::{trace, warn}; - -/// A download client that polls the miner for transactions and assembles blocks to be returned in -/// the download process. -/// -/// When polled, the miner will assemble blocks when miners produce ready transactions and store the -/// blocks in memory. -#[derive(Debug, Clone)] -pub struct AutoSealClient { - storage: Storage, -} - -impl AutoSealClient { - pub(crate) const fn new(storage: Storage) -> Self { - Self { storage } - } - - async fn fetch_headers(&self, request: HeadersRequest) -> Vec

{ - trace!(target: "consensus::auto", ?request, "received headers request"); - - let storage = self.storage.read().await; - let HeadersRequest { start, limit, direction } = request; - let mut headers = Vec::new(); - - let mut block: BlockHashOrNumber = match start { - BlockHashOrNumber::Hash(start) => start.into(), - BlockHashOrNumber::Number(num) => { - if let Some(hash) = storage.block_hash(num) { - hash.into() - } else { - warn!(target: "consensus::auto", num, "no matching block found"); - return headers - } - } - }; - - for _ in 0..limit { - // fetch from storage - if let Some(header) = storage.header_by_hash_or_number(block) { - match direction { - HeadersDirection::Falling => block = header.parent_hash.into(), - HeadersDirection::Rising => { - let next = header.number + 1; - block = next.into() - } - } - headers.push(header); - } else { - break - } - } - - trace!(target: "consensus::auto", ?headers, "returning headers"); - - headers - } - - async fn fetch_bodies(&self, hashes: Vec) -> Vec { - trace!(target: "consensus::auto", ?hashes, "received bodies request"); - let storage = self.storage.read().await; - let mut bodies = Vec::new(); - for hash in hashes { - if let Some(body) = storage.bodies.get(&hash).cloned() { - bodies.push(body); - } else { - break - } - } - - trace!(target: "consensus::auto", ?bodies, "returning bodies"); - - bodies - } -} - -impl HeadersClient for AutoSealClient { - type Output = HeadersFut; - - fn get_headers_with_priority( - &self, - request: HeadersRequest, - _priority: Priority, - ) -> Self::Output { - let this = self.clone(); - Box::pin(async move { - let headers = this.fetch_headers(request).await; - Ok(WithPeerId::new(PeerId::random(), headers)) - }) - } -} - -impl BodiesClient for AutoSealClient { - type Output = BodiesFut; - - fn get_block_bodies_with_priority( - &self, - hashes: Vec, - _priority: Priority, - ) -> Self::Output { - let this = self.clone(); - Box::pin(async move { - let bodies = this.fetch_bodies(hashes).await; - Ok(WithPeerId::new(PeerId::random(), bodies)) - }) - } -} - -impl DownloadClient for AutoSealClient { - fn report_bad_message(&self, _peer_id: PeerId) { - warn!("Reported a bad message on a miner, we should never produce bad blocks"); - // noop - } - - fn num_connected_peers(&self) -> usize { - // no such thing as connected peers when we are mining ourselves - 1 - } -} diff --git a/crates/consensus/auto-seal/src/lib.rs b/crates/consensus/auto-seal/src/lib.rs deleted file mode 100644 index a2f9fa4fa03..00000000000 --- a/crates/consensus/auto-seal/src/lib.rs +++ /dev/null @@ -1,690 +0,0 @@ -//! A [Consensus] implementation for local testing purposes -//! that automatically seals blocks. -//! -//! The Mining task polls a [`MiningMode`], and will return a list of transactions that are ready to -//! be mined. -//! -//! These downloaders poll the miner, assemble the block, and return transactions that are ready to -//! be mined. - -#![doc( - html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", - html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" -)] -#![cfg_attr(not(test), warn(unused_crate_dependencies))] -#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] - -use alloy_eips::{eip1898::BlockHashOrNumber, eip7685::Requests}; -use alloy_primitives::{BlockHash, BlockNumber, Bloom, B256, U256}; -use reth_beacon_consensus::BeaconEngineMessage; -use reth_chainspec::{EthChainSpec, EthereumHardforks}; -use reth_consensus::{Consensus, ConsensusError, PostExecutionInput}; -use reth_engine_primitives::EngineTypes; -use reth_execution_errors::{ - BlockExecutionError, BlockValidationError, InternalBlockExecutionError, -}; -use reth_execution_types::ExecutionOutcome; -use reth_primitives::{ - proofs, Block, BlockBody, BlockWithSenders, Header, SealedBlock, SealedHeader, - TransactionSigned, Withdrawals, -}; -use reth_provider::{BlockReaderIdExt, StateProviderFactory, StateRootProvider}; -use reth_revm::database::StateProviderDatabase; -use reth_transaction_pool::TransactionPool; -use reth_trie::HashedPostState; -use revm_primitives::calc_excess_blob_gas; -use std::{ - collections::HashMap, - fmt::Debug, - sync::Arc, - time::{SystemTime, UNIX_EPOCH}, -}; -use tokio::sync::{mpsc::UnboundedSender, RwLock, RwLockReadGuard, RwLockWriteGuard}; -use tracing::trace; - -mod client; -mod mode; -mod task; - -pub use crate::client::AutoSealClient; -pub use mode::{FixedBlockTimeMiner, MiningMode, ReadyTransactionMiner}; -use reth_evm::execute::{BlockExecutorProvider, Executor}; -pub use task::MiningTask; - -/// A consensus implementation intended for local development and testing purposes. -#[derive(Debug, Clone)] -#[allow(dead_code)] -pub struct AutoSealConsensus { - /// Configuration - chain_spec: Arc, -} - -impl AutoSealConsensus { - /// Create a new instance of [`AutoSealConsensus`] - pub const fn new(chain_spec: Arc) -> Self { - Self { chain_spec } - } -} - -impl Consensus for AutoSealConsensus { - fn validate_header(&self, _header: &SealedHeader) -> Result<(), ConsensusError> { - Ok(()) - } - - fn validate_header_against_parent( - &self, - _header: &SealedHeader, - _parent: &SealedHeader, - ) -> Result<(), ConsensusError> { - Ok(()) - } - - fn validate_header_with_total_difficulty( - &self, - _header: &Header, - _total_difficulty: U256, - ) -> Result<(), ConsensusError> { - Ok(()) - } - - fn validate_block_pre_execution(&self, _block: &SealedBlock) -> Result<(), ConsensusError> { - Ok(()) - } - - fn validate_block_post_execution( - &self, - _block: &BlockWithSenders, - _input: PostExecutionInput<'_>, - ) -> Result<(), ConsensusError> { - Ok(()) - } -} - -/// Builder type for configuring the setup -#[derive(Debug)] -pub struct AutoSealBuilder { - client: Client, - consensus: AutoSealConsensus, - pool: Pool, - mode: MiningMode, - storage: Storage, - to_engine: UnboundedSender>, - evm_config: EvmConfig, -} - -// === impl AutoSealBuilder === - -impl - AutoSealBuilder -where - Client: BlockReaderIdExt, - Pool: TransactionPool, - Engine: EngineTypes, - ChainSpec: EthChainSpec, -{ - /// Creates a new builder instance to configure all parts. - pub fn new( - chain_spec: Arc, - client: Client, - pool: Pool, - to_engine: UnboundedSender>, - mode: MiningMode, - evm_config: EvmConfig, - ) -> Self { - let latest_header = client.latest_header().ok().flatten().unwrap_or_else(|| { - SealedHeader::new(chain_spec.genesis_header().clone(), chain_spec.genesis_hash()) - }); - - Self { - storage: Storage::new(latest_header), - client, - consensus: AutoSealConsensus::new(chain_spec), - pool, - mode, - to_engine, - evm_config, - } - } - - /// Sets the [`MiningMode`] it operates in, default is [`MiningMode::Auto`] - pub fn mode(mut self, mode: MiningMode) -> Self { - self.mode = mode; - self - } - - /// Consumes the type and returns all components - #[track_caller] - pub fn build( - self, - ) -> ( - AutoSealConsensus, - AutoSealClient, - MiningTask, - ) { - let Self { client, consensus, pool, mode, storage, to_engine, evm_config } = self; - let auto_client = AutoSealClient::new(storage.clone()); - let task = MiningTask::new( - Arc::clone(&consensus.chain_spec), - mode, - to_engine, - storage, - client, - pool, - evm_config, - ); - (consensus, auto_client, task) - } -} - -/// In memory storage -#[derive(Debug, Clone, Default)] -pub(crate) struct Storage { - inner: Arc>, -} - -// == impl Storage === - -impl Storage { - /// Initializes the [Storage] with the given best block. This should be initialized with the - /// highest block in the chain, if there is a chain already stored on-disk. - fn new(best_block: SealedHeader) -> Self { - let (header, best_hash) = best_block.split(); - let mut storage = StorageInner { - best_hash, - total_difficulty: header.difficulty, - best_block: header.number, - ..Default::default() - }; - storage.headers.insert(header.number, header); - storage.bodies.insert(best_hash, BlockBody::default()); - Self { inner: Arc::new(RwLock::new(storage)) } - } - - /// Returns the write lock of the storage - pub(crate) async fn write(&self) -> RwLockWriteGuard<'_, StorageInner> { - self.inner.write().await - } - - /// Returns the read lock of the storage - pub(crate) async fn read(&self) -> RwLockReadGuard<'_, StorageInner> { - self.inner.read().await - } -} - -/// In-memory storage for the chain the auto seal engine is building. -#[derive(Default, Debug)] -pub(crate) struct StorageInner { - /// Headers buffered for download. - pub(crate) headers: HashMap, - /// A mapping between block hash and number. - pub(crate) hash_to_number: HashMap, - /// Bodies buffered for download. - pub(crate) bodies: HashMap, - /// Tracks best block - pub(crate) best_block: u64, - /// Tracks hash of best block - pub(crate) best_hash: B256, - /// The total difficulty of the chain until this block - pub(crate) total_difficulty: U256, -} - -// === impl StorageInner === - -impl StorageInner { - /// Returns the block hash for the given block number if it exists. - pub(crate) fn block_hash(&self, num: u64) -> Option { - self.hash_to_number.iter().find_map(|(k, v)| num.eq(v).then_some(*k)) - } - - /// Returns the matching header if it exists. - pub(crate) fn header_by_hash_or_number( - &self, - hash_or_num: BlockHashOrNumber, - ) -> Option
{ - let num = match hash_or_num { - BlockHashOrNumber::Hash(hash) => self.hash_to_number.get(&hash).copied()?, - BlockHashOrNumber::Number(num) => num, - }; - self.headers.get(&num).cloned() - } - - /// Inserts a new header+body pair - pub(crate) fn insert_new_block(&mut self, mut header: Header, body: BlockBody) { - header.number = self.best_block + 1; - header.parent_hash = self.best_hash; - - self.best_hash = header.hash_slow(); - self.best_block = header.number; - self.total_difficulty += header.difficulty; - - trace!(target: "consensus::auto", num=self.best_block, hash=?self.best_hash, "inserting new block"); - self.headers.insert(header.number, header); - self.bodies.insert(self.best_hash, body); - self.hash_to_number.insert(self.best_hash, self.best_block); - } - - /// Fills in pre-execution header fields based on the current best block and given - /// transactions. - pub(crate) fn build_header_template( - &self, - timestamp: u64, - transactions: &[TransactionSigned], - ommers: &[Header], - withdrawals: Option<&Withdrawals>, - requests: Option<&Requests>, - chain_spec: &ChainSpec, - ) -> Header - where - ChainSpec: EthChainSpec + EthereumHardforks, - { - // check previous block for base fee - let base_fee_per_gas = self.headers.get(&self.best_block).and_then(|parent| { - parent.next_block_base_fee(chain_spec.base_fee_params_at_timestamp(timestamp)) - }); - - let blob_gas_used = chain_spec.is_cancun_active_at_timestamp(timestamp).then(|| { - transactions - .iter() - .filter_map(|tx| tx.transaction.as_eip4844()) - .map(|blob_tx| blob_tx.blob_gas()) - .sum::() - }); - - let mut header = Header { - parent_hash: self.best_hash, - ommers_hash: proofs::calculate_ommers_root(ommers), - transactions_root: proofs::calculate_transaction_root(transactions), - withdrawals_root: withdrawals.map(|w| proofs::calculate_withdrawals_root(w)), - difficulty: U256::from(2), - number: self.best_block + 1, - gas_limit: chain_spec.max_gas_limit(), - timestamp, - base_fee_per_gas, - blob_gas_used, - requests_hash: requests.map(|r| r.requests_hash()), - ..Default::default() - }; - - if chain_spec.is_cancun_active_at_timestamp(timestamp) { - let parent = self.headers.get(&self.best_block); - header.parent_beacon_block_root = - parent.and_then(|parent| parent.parent_beacon_block_root); - header.blob_gas_used = Some(0); - - let (parent_excess_blob_gas, parent_blob_gas_used) = match parent { - Some(parent) if chain_spec.is_cancun_active_at_timestamp(parent.timestamp) => ( - parent.excess_blob_gas.unwrap_or_default(), - parent.blob_gas_used.unwrap_or_default(), - ), - _ => (0, 0), - }; - header.excess_blob_gas = - Some(calc_excess_blob_gas(parent_excess_blob_gas, parent_blob_gas_used)) - } - - header - } - - /// Builds and executes a new block with the given transactions, on the provided executor. - /// - /// This returns the header of the executed block, as well as the poststate from execution. - #[allow(clippy::too_many_arguments)] - pub(crate) fn build_and_execute( - &mut self, - transactions: Vec, - ommers: Vec
, - provider: &Provider, - chain_spec: Arc, - executor: &Executor, - ) -> Result<(SealedHeader, ExecutionOutcome), BlockExecutionError> - where - Executor: BlockExecutorProvider, - Provider: StateProviderFactory, - ChainSpec: EthChainSpec + EthereumHardforks, - { - let timestamp = SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_secs(); - - // if shanghai is active, include empty withdrawals - let withdrawals = - chain_spec.is_shanghai_active_at_timestamp(timestamp).then_some(Withdrawals::default()); - // if prague is active, include empty requests - let requests = - chain_spec.is_prague_active_at_timestamp(timestamp).then_some(Requests::default()); - - let header = self.build_header_template( - timestamp, - &transactions, - &ommers, - withdrawals.as_ref(), - requests.as_ref(), - &chain_spec, - ); - - let block = Block { - header, - body: BlockBody { - transactions, - ommers: ommers.clone(), - withdrawals: withdrawals.clone(), - }, - } - .with_recovered_senders() - .ok_or(BlockExecutionError::Validation(BlockValidationError::SenderRecoveryError))?; - - trace!(target: "consensus::auto", transactions=?&block.body, "executing transactions"); - - let mut db = StateProviderDatabase::new( - provider.latest().map_err(InternalBlockExecutionError::LatestBlock)?, - ); - - // execute the block - let block_execution_output = - executor.executor(&mut db).execute((&block, U256::ZERO).into())?; - let gas_used = block_execution_output.gas_used; - let execution_outcome = ExecutionOutcome::from((block_execution_output, block.number)); - let hashed_state = HashedPostState::from_bundle_state(&execution_outcome.state().state); - - // todo(onbjerg): we should not pass requests around as this is building a block, which - // means we need to extract the requests from the execution output and compute the requests - // root here - - let Block { mut header, body, .. } = block.block; - let body = BlockBody { transactions: body.transactions, ommers, withdrawals }; - - trace!(target: "consensus::auto", ?execution_outcome, ?header, ?body, "executed block, calculating state root and completing header"); - - // now we need to update certain header fields with the results of the execution - header.state_root = db.state_root(hashed_state)?; - header.gas_used = gas_used; - - let receipts = execution_outcome.receipts_by_block(header.number); - - // update logs bloom - let receipts_with_bloom = - receipts.iter().map(|r| r.as_ref().unwrap().bloom_slow()).collect::>(); - header.logs_bloom = receipts_with_bloom.iter().fold(Bloom::ZERO, |bloom, r| bloom | *r); - - // update receipts root - header.receipts_root = { - #[cfg(feature = "optimism")] - let receipts_root = execution_outcome - .generic_receipts_root_slow(header.number, |receipts| { - reth_optimism_consensus::calculate_receipt_root_no_memo_optimism( - receipts, - &chain_spec, - header.timestamp, - ) - }) - .expect("Receipts is present"); - - #[cfg(not(feature = "optimism"))] - let receipts_root = - execution_outcome.receipts_root_slow(header.number).expect("Receipts is present"); - - receipts_root - }; - trace!(target: "consensus::auto", root=?header.state_root, ?body, "calculated root"); - - // finally insert into storage - self.insert_new_block(header.clone(), body); - - // set new header with hash that should have been updated by insert_new_block - let new_header = SealedHeader::new(header, self.best_hash); - - Ok((new_header, execution_outcome)) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use reth_chainspec::{ChainHardforks, ChainSpec, EthereumHardfork, ForkCondition}; - use reth_primitives::Transaction; - - #[test] - fn test_block_hash() { - let mut storage = StorageInner::default(); - - // Define two block hashes and their corresponding block numbers. - let block_hash_1: BlockHash = B256::random(); - let block_number_1: BlockNumber = 1; - let block_hash_2: BlockHash = B256::random(); - let block_number_2: BlockNumber = 2; - - // Insert the block number and hash pairs into the `hash_to_number` map. - storage.hash_to_number.insert(block_hash_1, block_number_1); - storage.hash_to_number.insert(block_hash_2, block_number_2); - - // Verify that `block_hash` returns the correct block hash for the given block number. - assert_eq!(storage.block_hash(block_number_1), Some(block_hash_1)); - assert_eq!(storage.block_hash(block_number_2), Some(block_hash_2)); - - // Test that `block_hash` returns `None` for a non-existent block number. - let block_number_3: BlockNumber = 3; - assert_eq!(storage.block_hash(block_number_3), None); - } - - #[test] - fn test_header_by_hash_or_number() { - let mut storage = StorageInner::default(); - - // Define block numbers, headers, and hashes. - let block_number_1: u64 = 1; - let block_number_2: u64 = 2; - let header_1 = Header { number: block_number_1, ..Default::default() }; - let header_2 = Header { number: block_number_2, ..Default::default() }; - let block_hash_1: BlockHash = B256::random(); - let block_hash_2: BlockHash = B256::random(); - - // Insert headers and hash-to-number mappings. - storage.headers.insert(block_number_1, header_1.clone()); - storage.headers.insert(block_number_2, header_2.clone()); - storage.hash_to_number.insert(block_hash_1, block_number_1); - storage.hash_to_number.insert(block_hash_2, block_number_2); - - // Test header retrieval by block number. - assert_eq!( - storage.header_by_hash_or_number(BlockHashOrNumber::Number(block_number_1)), - Some(header_1.clone()) - ); - assert_eq!( - storage.header_by_hash_or_number(BlockHashOrNumber::Number(block_number_2)), - Some(header_2.clone()) - ); - - // Test header retrieval by block hash. - assert_eq!( - storage.header_by_hash_or_number(BlockHashOrNumber::Hash(block_hash_1)), - Some(header_1) - ); - assert_eq!( - storage.header_by_hash_or_number(BlockHashOrNumber::Hash(block_hash_2)), - Some(header_2) - ); - - // Test non-existent block number and hash. - assert_eq!(storage.header_by_hash_or_number(BlockHashOrNumber::Number(999)), None); - let non_existent_hash: BlockHash = B256::random(); - assert_eq!( - storage.header_by_hash_or_number(BlockHashOrNumber::Hash(non_existent_hash)), - None - ); - } - - #[test] - fn test_insert_new_block() { - let mut storage = StorageInner::default(); - - // Define headers and block bodies. - let header_1 = Header { difficulty: U256::from(100), ..Default::default() }; - let body_1 = BlockBody::default(); - let header_2 = Header { difficulty: U256::from(200), ..Default::default() }; - let body_2 = BlockBody::default(); - - // Insert the first block. - storage.insert_new_block(header_1.clone(), body_1.clone()); - let best_block_1 = storage.best_block; - let best_hash_1 = storage.best_hash; - - // Verify the block was inserted correctly. - assert_eq!( - storage.headers.get(&best_block_1), - Some(&Header { number: 1, ..header_1.clone() }) - ); - assert_eq!(storage.bodies.get(&best_hash_1), Some(&body_1)); - assert_eq!(storage.hash_to_number.get(&best_hash_1), Some(&best_block_1)); - - // Insert the second block. - storage.insert_new_block(header_2.clone(), body_2.clone()); - let best_block_2 = storage.best_block; - let best_hash_2 = storage.best_hash; - - // Verify the second block was inserted correctly. - assert_eq!( - storage.headers.get(&best_block_2), - Some(&Header { - number: 2, - parent_hash: Header { number: 1, ..header_1 }.hash_slow(), - ..header_2 - }) - ); - assert_eq!(storage.bodies.get(&best_hash_2), Some(&body_2)); - assert_eq!(storage.hash_to_number.get(&best_hash_2), Some(&best_block_2)); - - // Check that the total difficulty was updated. - assert_eq!(storage.total_difficulty, header_1.difficulty + header_2.difficulty); - } - - #[test] - fn test_build_basic_header_template() { - let mut storage = StorageInner::default(); - let chain_spec = ChainSpec::default(); - - let best_block_number = 1; - let best_block_hash = B256::random(); - let timestamp = 1_600_000_000; - - // Set up best block information - storage.best_block = best_block_number; - storage.best_hash = best_block_hash; - - // Build header template - let header = storage.build_header_template( - timestamp, - &[], // no transactions - &[], // no ommers - None, // no withdrawals - None, // no requests - &chain_spec, - ); - - // Verify basic fields - assert_eq!(header.parent_hash, best_block_hash); - assert_eq!(header.number, best_block_number + 1); - assert_eq!(header.timestamp, timestamp); - assert_eq!(header.gas_limit, chain_spec.max_gas_limit); - } - - #[test] - fn test_ommers_and_transactions_roots() { - let storage = StorageInner::default(); - let chain_spec = ChainSpec::default(); - let timestamp = 1_600_000_000; - - // Setup ommers and transactions - let ommers = vec![Header::default()]; - let transactions = vec![TransactionSigned::default()]; - - // Build header template - let header = storage.build_header_template( - timestamp, - &transactions, - &ommers, - None, // no withdrawals - None, // no requests - &chain_spec, - ); - - // Verify ommers and transactions roots - assert_eq!(header.ommers_hash, proofs::calculate_ommers_root(&ommers)); - assert_eq!(header.transactions_root, proofs::calculate_transaction_root(&transactions)); - } - - // Test base fee calculation from the parent block - #[test] - fn test_base_fee_calculation() { - let mut storage = StorageInner::default(); - let chain_spec = ChainSpec::default(); - let timestamp = 1_600_000_000; - - // Set up the parent header with base fee - let base_fee = Some(100); - let parent_header = Header { base_fee_per_gas: base_fee, ..Default::default() }; - storage.headers.insert(storage.best_block, parent_header); - - // Build header template - let header = storage.build_header_template( - timestamp, - &[], // no transactions - &[], // no ommers - None, // no withdrawals - None, // no requests - &chain_spec, - ); - - // Verify base fee is correctly propagated - assert_eq!(header.base_fee_per_gas, base_fee); - } - - // Test blob gas and excess blob gas calculation when Cancun is active - #[test] - fn test_blob_gas_calculation_cancun() { - let storage = StorageInner::default(); - let chain_spec = ChainSpec { - hardforks: ChainHardforks::new(vec![( - EthereumHardfork::Cancun.boxed(), - ForkCondition::Timestamp(25), - )]), - ..Default::default() - }; - let timestamp = 26; - - // Set up a transaction with blob gas - let blob_tx = TransactionSigned { - transaction: Transaction::Eip4844(Default::default()), - ..Default::default() - }; - let transactions = vec![blob_tx]; - - // Build header template - let header = storage.build_header_template( - timestamp, - &transactions, - &[], // no ommers - None, // no withdrawals - None, // no requests - &chain_spec, - ); - - // Verify that the header has the correct fields including blob gas - assert_eq!( - header, - Header { - parent_hash: B256::ZERO, - ommers_hash: proofs::calculate_ommers_root(&[]), - transactions_root: proofs::calculate_transaction_root(&transactions), - withdrawals_root: None, - difficulty: U256::from(2), - number: 1, - gas_limit: chain_spec.max_gas_limit, - timestamp, - base_fee_per_gas: None, - blob_gas_used: Some(0), - requests_hash: None, - excess_blob_gas: Some(0), - ..Default::default() - } - ); - } -} diff --git a/crates/consensus/auto-seal/src/mode.rs b/crates/consensus/auto-seal/src/mode.rs deleted file mode 100644 index 82750c8e47b..00000000000 --- a/crates/consensus/auto-seal/src/mode.rs +++ /dev/null @@ -1,166 +0,0 @@ -//! The mode the auto seal miner is operating in. - -use alloy_primitives::TxHash; -use futures_util::{stream::Fuse, StreamExt}; -use reth_transaction_pool::{TransactionPool, ValidPoolTransaction}; -use std::{ - fmt, - pin::Pin, - sync::Arc, - task::{Context, Poll}, - time::Duration, -}; -use tokio::{sync::mpsc::Receiver, time::Interval}; -use tokio_stream::{wrappers::ReceiverStream, Stream}; - -/// Mode of operations for the `Miner` -#[derive(Debug)] -pub enum MiningMode { - /// A miner that does nothing - None, - /// A miner that listens for new transactions that are ready. - /// - /// Either one transaction will be mined per block, or any number of transactions will be - /// allowed - Auto(ReadyTransactionMiner), - /// A miner that constructs a new block every `interval` tick - FixedBlockTime(FixedBlockTimeMiner), -} - -// === impl MiningMode === - -impl MiningMode { - /// Creates a new instant mining mode that listens for new transactions and tries to build - /// non-empty blocks as soon as transactions arrive. - pub fn instant(max_transactions: usize, listener: Receiver) -> Self { - Self::Auto(ReadyTransactionMiner { - max_transactions, - has_pending_txs: None, - rx: ReceiverStream::new(listener).fuse(), - }) - } - - /// Creates a new interval miner that builds a block ever `duration`. - pub fn interval(duration: Duration) -> Self { - Self::FixedBlockTime(FixedBlockTimeMiner::new(duration)) - } - - /// polls the Pool and returns those transactions that should be put in a block, if any. - pub(crate) fn poll( - &mut self, - pool: &Pool, - cx: &mut Context<'_>, - ) -> Poll::Transaction>>>> - where - Pool: TransactionPool, - { - match self { - Self::None => Poll::Pending, - Self::Auto(miner) => miner.poll(pool, cx), - Self::FixedBlockTime(miner) => miner.poll(pool, cx), - } - } -} - -impl fmt::Display for MiningMode { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let kind = match self { - Self::None => "None", - Self::Auto(_) => "Auto", - Self::FixedBlockTime(_) => "FixedBlockTime", - }; - write!(f, "{kind}") - } -} - -/// A miner that's supposed to create a new block every `interval`, mining all transactions that are -/// ready at that time. -/// -/// The default blocktime is set to 6 seconds -#[derive(Debug)] -pub struct FixedBlockTimeMiner { - /// The interval this fixed block time miner operates with - interval: Interval, -} - -// === impl FixedBlockTimeMiner === - -impl FixedBlockTimeMiner { - /// Creates a new instance with an interval of `duration` - pub(crate) fn new(duration: Duration) -> Self { - let start = tokio::time::Instant::now() + duration; - Self { interval: tokio::time::interval_at(start, duration) } - } - - fn poll( - &mut self, - pool: &Pool, - cx: &mut Context<'_>, - ) -> Poll::Transaction>>>> - where - Pool: TransactionPool, - { - if self.interval.poll_tick(cx).is_ready() { - // drain the pool - return Poll::Ready(pool.best_transactions().collect()) - } - Poll::Pending - } -} - -impl Default for FixedBlockTimeMiner { - fn default() -> Self { - Self::new(Duration::from_secs(6)) - } -} - -/// A miner that Listens for new ready transactions -pub struct ReadyTransactionMiner { - /// how many transactions to mine per block - max_transactions: usize, - /// stores whether there are pending transactions (if known) - has_pending_txs: Option, - /// Receives hashes of transactions that are ready - rx: Fuse>, -} - -// === impl ReadyTransactionMiner === - -impl ReadyTransactionMiner { - fn poll( - &mut self, - pool: &Pool, - cx: &mut Context<'_>, - ) -> Poll::Transaction>>>> - where - Pool: TransactionPool, - { - // drain the notification stream - while let Poll::Ready(Some(_hash)) = Pin::new(&mut self.rx).poll_next(cx) { - self.has_pending_txs = Some(true); - } - - if self.has_pending_txs == Some(false) { - return Poll::Pending - } - - let transactions = pool.best_transactions().take(self.max_transactions).collect::>(); - - // there are pending transactions if we didn't drain the pool - self.has_pending_txs = Some(transactions.len() >= self.max_transactions); - - if transactions.is_empty() { - return Poll::Pending - } - - Poll::Ready(transactions) - } -} - -impl fmt::Debug for ReadyTransactionMiner { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("ReadyTransactionMiner") - .field("max_transactions", &self.max_transactions) - .finish_non_exhaustive() - } -} diff --git a/crates/consensus/auto-seal/src/task.rs b/crates/consensus/auto-seal/src/task.rs deleted file mode 100644 index 75ddda90861..00000000000 --- a/crates/consensus/auto-seal/src/task.rs +++ /dev/null @@ -1,221 +0,0 @@ -use crate::{mode::MiningMode, Storage}; -use alloy_rpc_types_engine::ForkchoiceState; -use futures_util::{future::BoxFuture, FutureExt}; -use reth_beacon_consensus::{BeaconEngineMessage, ForkchoiceStatus}; -use reth_chainspec::{EthChainSpec, EthereumHardforks}; -use reth_engine_primitives::{EngineApiMessageVersion, EngineTypes}; -use reth_evm::execute::BlockExecutorProvider; -use reth_provider::{CanonChainTracker, StateProviderFactory}; -use reth_stages_api::PipelineEvent; -use reth_tokio_util::EventStream; -use reth_transaction_pool::{TransactionPool, ValidPoolTransaction}; -use std::{ - collections::VecDeque, - future::Future, - pin::Pin, - sync::Arc, - task::{Context, Poll}, -}; -use tokio::sync::{mpsc::UnboundedSender, oneshot}; -use tracing::{debug, error, warn}; - -/// A Future that listens for new ready transactions and puts new blocks into storage -pub struct MiningTask { - /// The configured chain spec - chain_spec: Arc, - /// The client used to interact with the state - client: Client, - /// The active miner - miner: MiningMode, - /// Single active future that inserts a new block into `storage` - insert_task: Option>>>, - /// Shared storage to insert new blocks - storage: Storage, - /// Pool where transactions are stored - pool: Pool, - /// backlog of sets of transactions ready to be mined - queued: VecDeque::Transaction>>>>, - // TODO: ideally this would just be a sender of hashes - to_engine: UnboundedSender>, - /// The pipeline events to listen on - pipe_line_events: Option>, - /// The type used for block execution - block_executor: Executor, -} - -// === impl MiningTask === - -impl - MiningTask -{ - /// Creates a new instance of the task - #[allow(clippy::too_many_arguments)] - pub(crate) fn new( - chain_spec: Arc, - miner: MiningMode, - to_engine: UnboundedSender>, - storage: Storage, - client: Client, - pool: Pool, - block_executor: Executor, - ) -> Self { - Self { - chain_spec, - client, - miner, - insert_task: None, - storage, - pool, - to_engine, - queued: Default::default(), - pipe_line_events: None, - block_executor, - } - } - - /// Sets the pipeline events to listen on. - pub fn set_pipeline_events(&mut self, events: EventStream) { - self.pipe_line_events = Some(events); - } -} - -impl Future - for MiningTask -where - Client: StateProviderFactory + CanonChainTracker + Clone + Unpin + 'static, - Pool: TransactionPool + Unpin + 'static, - Engine: EngineTypes, - Executor: BlockExecutorProvider, - ChainSpec: EthChainSpec + EthereumHardforks + 'static, -{ - type Output = (); - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let this = self.get_mut(); - - // this drives block production and - loop { - if let Poll::Ready(transactions) = this.miner.poll(&this.pool, cx) { - // miner returned a set of transaction that we feed to the producer - this.queued.push_back(transactions); - } - - if this.insert_task.is_none() { - if this.queued.is_empty() { - // nothing to insert - break - } - - // ready to queue in new insert task - let storage = this.storage.clone(); - let transactions = this.queued.pop_front().expect("not empty"); - - let to_engine = this.to_engine.clone(); - let client = this.client.clone(); - let chain_spec = Arc::clone(&this.chain_spec); - let events = this.pipe_line_events.take(); - let executor = this.block_executor.clone(); - - // Create the mining future that creates a block, notifies the engine that drives - // the pipeline - this.insert_task = Some(Box::pin(async move { - let mut storage = storage.write().await; - - let transactions: Vec<_> = transactions - .into_iter() - .map(|tx| { - let recovered = tx.to_recovered_transaction(); - recovered.into_signed() - }) - .collect(); - let ommers = vec![]; - - match storage.build_and_execute( - transactions.clone(), - ommers.clone(), - &client, - chain_spec, - &executor, - ) { - Ok((new_header, _bundle_state)) => { - let state = ForkchoiceState { - head_block_hash: new_header.hash(), - finalized_block_hash: new_header.hash(), - safe_block_hash: new_header.hash(), - }; - drop(storage); - - // TODO: make this a future - // await the fcu call rx for SYNCING, then wait for a VALID response - loop { - // send the new update to the engine, this will trigger the engine - // to download and execute the block we just inserted - let (tx, rx) = oneshot::channel(); - let _ = to_engine.send(BeaconEngineMessage::ForkchoiceUpdated { - state, - payload_attrs: None, - tx, - version: EngineApiMessageVersion::default(), - }); - debug!(target: "consensus::auto", ?state, "Sent fork choice update"); - - match rx.await.unwrap() { - Ok(fcu_response) => { - match fcu_response.forkchoice_status() { - ForkchoiceStatus::Valid => break, - ForkchoiceStatus::Invalid => { - error!(target: "consensus::auto", ?fcu_response, "Forkchoice update returned invalid response"); - return None - } - ForkchoiceStatus::Syncing => { - debug!(target: "consensus::auto", ?fcu_response, "Forkchoice update returned SYNCING, waiting for VALID"); - // wait for the next fork choice update - continue - } - } - } - Err(err) => { - error!(target: "consensus::auto", %err, "Autoseal fork choice update failed"); - return None - } - } - } - - // update canon chain for rpc - client.set_canonical_head(new_header.clone()); - client.set_safe(new_header.clone()); - client.set_finalized(new_header.clone()); - } - Err(err) => { - warn!(target: "consensus::auto", %err, "failed to execute block") - } - } - - events - })); - } - - if let Some(mut fut) = this.insert_task.take() { - match fut.poll_unpin(cx) { - Poll::Ready(events) => { - this.pipe_line_events = events; - } - Poll::Pending => { - this.insert_task = Some(fut); - break - } - } - } - } - - Poll::Pending - } -} - -impl - std::fmt::Debug for MiningTask -{ - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("MiningTask").finish_non_exhaustive() - } -} diff --git a/crates/ethereum/node/Cargo.toml b/crates/ethereum/node/Cargo.toml index 49663ffc2cc..69bbeeb5b43 100644 --- a/crates/ethereum/node/Cargo.toml +++ b/crates/ethereum/node/Cargo.toml @@ -24,7 +24,6 @@ reth-network.workspace = true reth-evm.workspace = true reth-evm-ethereum.workspace = true reth-consensus.workspace = true -reth-auto-seal-consensus.workspace = true reth-beacon-consensus.workspace = true reth-rpc.workspace = true reth-node-api.workspace = true diff --git a/crates/ethereum/node/src/node.rs b/crates/ethereum/node/src/node.rs index 17a952a58d3..95542411d21 100644 --- a/crates/ethereum/node/src/node.rs +++ b/crates/ethereum/node/src/node.rs @@ -2,7 +2,6 @@ use std::sync::Arc; -use reth_auto_seal_consensus::AutoSealConsensus; use reth_basic_payload_builder::{BasicPayloadJobGenerator, BasicPayloadJobGeneratorConfig}; use reth_beacon_consensus::EthBeaconConsensus; use reth_chainspec::ChainSpec; @@ -335,11 +334,7 @@ where type Consensus = Arc; async fn build_consensus(self, ctx: &BuilderContext) -> eyre::Result { - if ctx.is_dev() { - Ok(Arc::new(AutoSealConsensus::new(ctx.chain_spec()))) - } else { - Ok(Arc::new(EthBeaconConsensus::new(ctx.chain_spec()))) - } + Ok(Arc::new(EthBeaconConsensus::new(ctx.chain_spec()))) } } diff --git a/crates/ethereum/node/tests/e2e/dev.rs b/crates/ethereum/node/tests/e2e/dev.rs index f0fcaf64524..b6d0ffcfaaa 100644 --- a/crates/ethereum/node/tests/e2e/dev.rs +++ b/crates/ethereum/node/tests/e2e/dev.rs @@ -1,12 +1,10 @@ use std::sync::Arc; -use crate::utils::eth_payload_attributes; use alloy_genesis::Genesis; use alloy_primitives::{b256, hex}; use futures::StreamExt; use reth::{args::DevArgs, rpc::api::eth::helpers::EthTransactions}; use reth_chainspec::ChainSpec; -use reth_e2e_test_utils::setup; use reth_node_api::FullNodeComponents; use reth_node_builder::{ rpc::RethRpcAddOns, EngineNodeLauncher, FullNode, NodeBuilder, NodeConfig, NodeHandle, @@ -17,16 +15,6 @@ use reth_tasks::TaskManager; #[tokio::test] async fn can_run_dev_node() -> eyre::Result<()> { - reth_tracing::init_test_tracing(); - let (mut nodes, _tasks, _) = - setup::(1, custom_chain(), true, eth_payload_attributes).await?; - - assert_chain_advances(nodes.pop().unwrap().inner).await; - Ok(()) -} - -#[tokio::test] -async fn can_run_dev_node_new_engine() -> eyre::Result<()> { reth_tracing::init_test_tracing(); let tasks = TaskManager::current(); let exec = tasks.executor(); diff --git a/crates/node/builder/Cargo.toml b/crates/node/builder/Cargo.toml index 86f755cb920..4ef2b0728e0 100644 --- a/crates/node/builder/Cargo.toml +++ b/crates/node/builder/Cargo.toml @@ -13,7 +13,6 @@ workspace = true [dependencies] ## reth -reth-auto-seal-consensus.workspace = true reth-beacon-consensus.workspace = true reth-blockchain-tree.workspace = true reth-chain-state.workspace = true diff --git a/crates/node/builder/src/launch/common.rs b/crates/node/builder/src/launch/common.rs index ac2339fa6cf..856f86c6fe0 100644 --- a/crates/node/builder/src/launch/common.rs +++ b/crates/node/builder/src/launch/common.rs @@ -5,7 +5,6 @@ use std::{sync::Arc, thread::available_parallelism}; use alloy_primitives::{BlockNumber, B256}; use eyre::{Context, OptionExt}; use rayon::ThreadPoolBuilder; -use reth_auto_seal_consensus::MiningMode; use reth_beacon_consensus::EthBeaconConsensus; use reth_blockchain_tree::{ BlockchainTree, BlockchainTreeConfig, ShareableBlockchainTree, TreeExternals, @@ -16,6 +15,7 @@ use reth_consensus::Consensus; use reth_db_api::database::Database; use reth_db_common::init::{init_genesis, InitDatabaseError}; use reth_downloaders::{bodies::noop::NoopBodiesDownloader, headers::noop::NoopHeaderDownloader}; +use reth_engine_local::MiningMode; use reth_engine_tree::tree::{InvalidBlockHook, InvalidBlockHooks, NoopInvalidBlockHook}; use reth_evm::noop::NoopBlockExecutorProvider; use reth_fs_util as fs; @@ -52,8 +52,9 @@ use reth_stages::{sets::DefaultStages, MetricEvent, PipelineBuilder, PipelineTar use reth_static_file::StaticFileProducer; use reth_tasks::TaskExecutor; use reth_tracing::tracing::{debug, error, info, warn}; +use reth_transaction_pool::TransactionPool; use tokio::sync::{ - mpsc::{unbounded_channel, Receiver, UnboundedSender}, + mpsc::{unbounded_channel, UnboundedSender}, oneshot, watch, }; @@ -386,13 +387,11 @@ impl LaunchContextWith) -> MiningMode { + pub fn dev_mining_mode(&self, pool: impl TransactionPool) -> MiningMode { if let Some(interval) = self.node_config().dev.block_time { MiningMode::interval(interval) - } else if let Some(max_transactions) = self.node_config().dev.block_max_transactions { - MiningMode::instant(max_transactions, pending_transactions_listener) } else { - MiningMode::instant(1, pending_transactions_listener) + MiningMode::instant(pool) } } } diff --git a/crates/node/builder/src/launch/engine.rs b/crates/node/builder/src/launch/engine.rs index 85401b8b958..65433176ba9 100644 --- a/crates/node/builder/src/launch/engine.rs +++ b/crates/node/builder/src/launch/engine.rs @@ -8,7 +8,7 @@ use reth_beacon_consensus::{ use reth_blockchain_tree::BlockchainTreeConfig; use reth_chainspec::EthChainSpec; use reth_consensus_debug_client::{DebugConsensusClient, EtherscanBlockProvider}; -use reth_engine_local::{LocalEngineService, LocalPayloadAttributesBuilder, MiningMode}; +use reth_engine_local::{LocalEngineService, LocalPayloadAttributesBuilder}; use reth_engine_service::service::{ChainEvent, EngineService}; use reth_engine_tree::{ engine::{EngineApiRequest, EngineRequestHandler}, @@ -208,11 +208,6 @@ where info!(target: "reth::cli", prune_config=?ctx.prune_config().unwrap_or_default(), "Pruner initialized"); let mut engine_service = if ctx.is_dev() { - let mining_mode = if let Some(block_time) = ctx.node_config().dev.block_time { - MiningMode::interval(block_time) - } else { - MiningMode::instant(ctx.components().pool().clone()) - }; let eth_service = LocalEngineService::new( ctx.consensus(), ctx.components().block_executor().clone(), @@ -225,7 +220,7 @@ where ctx.sync_metrics_tx(), consensus_engine_tx.clone(), Box::pin(consensus_engine_stream), - mining_mode, + ctx.dev_mining_mode(ctx.components().pool()), LocalPayloadAttributesBuilder::new(ctx.chain_spec()), ); diff --git a/crates/node/builder/src/launch/mod.rs b/crates/node/builder/src/launch/mod.rs index a623a7a9f23..4f9e850c97f 100644 --- a/crates/node/builder/src/launch/mod.rs +++ b/crates/node/builder/src/launch/mod.rs @@ -11,7 +11,6 @@ pub use exex::ExExLauncher; use std::{future::Future, sync::Arc}; -use alloy_primitives::utils::format_ether; use futures::{future::Either, stream, stream_select, StreamExt}; use reth_beacon_consensus::{ hooks::{EngineHooks, PruneHook, StaticFileHook}, @@ -33,7 +32,6 @@ use reth_provider::providers::BlockchainProvider; use reth_rpc::eth::RpcNodeCore; use reth_tasks::TaskExecutor; use reth_tracing::tracing::{debug, info}; -use reth_transaction_pool::TransactionPool; use tokio::sync::{mpsc::unbounded_channel, oneshot}; use tokio_stream::wrappers::UnboundedReceiverStream; @@ -210,47 +208,7 @@ where let pipeline_exex_handle = exex_manager_handle.clone().unwrap_or_else(ExExManagerHandle::empty); let (pipeline, client) = if ctx.is_dev() { - info!(target: "reth::cli", "Starting Reth in dev mode"); - - for (idx, (address, alloc)) in ctx.chain_spec().genesis().alloc.iter().enumerate() { - info!(target: "reth::cli", "Allocated Genesis Account: {:02}. {} ({} ETH)", idx, address.to_string(), format_ether(alloc.balance)); - } - - // install auto-seal - let mining_mode = - ctx.dev_mining_mode(ctx.components().pool().pending_transactions_listener()); - info!(target: "reth::cli", mode=%mining_mode, "configuring dev mining mode"); - - let (_, client, mut task) = reth_auto_seal_consensus::AutoSealBuilder::new( - ctx.chain_spec(), - ctx.blockchain_db().clone(), - ctx.components().pool().clone(), - consensus_engine_tx.clone(), - mining_mode, - ctx.components().block_executor().clone(), - ) - .build(); - - let pipeline = crate::setup::build_networked_pipeline( - &ctx.toml_config().stages, - client.clone(), - ctx.consensus(), - ctx.provider_factory().clone(), - ctx.task_executor(), - ctx.sync_metrics_tx(), - ctx.prune_config(), - max_block, - static_file_producer, - ctx.components().block_executor().clone(), - pipeline_exex_handle, - )?; - - let pipeline_events = pipeline.events(); - task.set_pipeline_events(pipeline_events); - debug!(target: "reth::cli", "Spawning auto mine task"); - ctx.task_executor().spawn(Box::pin(task)); - - (pipeline, Either::Left(client)) + eyre::bail!("Dev mode is not supported for legacy engine") } else { let pipeline = crate::setup::build_networked_pipeline( &ctx.toml_config().stages, @@ -266,7 +224,7 @@ where pipeline_exex_handle, )?; - (pipeline, Either::Right(network_client.clone())) + (pipeline, network_client.clone()) }; let pipeline_events = pipeline.events(); diff --git a/crates/optimism/node/Cargo.toml b/crates/optimism/node/Cargo.toml index deabbac5249..7674cbd37c0 100644 --- a/crates/optimism/node/Cargo.toml +++ b/crates/optimism/node/Cargo.toml @@ -16,7 +16,6 @@ reth-chainspec.workspace = true reth-engine-local.workspace = true reth-primitives.workspace = true reth-payload-builder.workspace = true -reth-auto-seal-consensus.workspace = true reth-basic-payload-builder.workspace = true reth-consensus.workspace = true reth-node-api.workspace = true @@ -76,7 +75,6 @@ optimism = [ "reth-optimism-payload-builder/optimism", "reth-beacon-consensus/optimism", "revm/optimism", - "reth-auto-seal-consensus/optimism", "reth-optimism-rpc/optimism", "reth-engine-local/optimism", "reth-optimism-consensus/optimism", diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index e39fdfc27a8..a09dfbaa562 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -467,11 +467,7 @@ where type Consensus = Arc; async fn build_consensus(self, ctx: &BuilderContext) -> eyre::Result { - if ctx.is_dev() { - Ok(Arc::new(reth_auto_seal_consensus::AutoSealConsensus::new(ctx.chain_spec()))) - } else { - Ok(Arc::new(OpBeaconConsensus::new(ctx.chain_spec()))) - } + Ok(Arc::new(OpBeaconConsensus::new(ctx.chain_spec()))) } } diff --git a/docs/repo/layout.md b/docs/repo/layout.md index 6ed91e79656..f78abe96122 100644 --- a/docs/repo/layout.md +++ b/docs/repo/layout.md @@ -82,7 +82,6 @@ The networking component mainly lives in [`net/network`](../../crates/net/networ Different consensus mechanisms. - [`consensus/common`](../../crates/consensus/common): Common consensus functions and traits (e.g. fee calculation) -- [`consensus/auto-seal`](../../crates/consensus/auto-seal): A consensus mechanism that auto-seals blocks for local development (also commonly known as "auto-mine") - [`consensus/beacon`](../../crates/consensus/beacon): Consensus mechanism that handles messages from a beacon node ("eth2") ### Execution From dbe8c83b482c4477effe2f71b20cde436c4b23bd Mon Sep 17 00:00:00 2001 From: Steven <112043913+stevencartavia@users.noreply.github.com> Date: Thu, 7 Nov 2024 15:32:48 -0600 Subject: [PATCH 062/211] renamed OptimismInvalidTransactionError to OpInvalidTransactionError (#12384) --- crates/optimism/rpc/src/error.rs | 14 +++++++------- crates/optimism/rpc/src/lib.rs | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/optimism/rpc/src/error.rs b/crates/optimism/rpc/src/error.rs index c4027340039..078da8fe4d1 100644 --- a/crates/optimism/rpc/src/error.rs +++ b/crates/optimism/rpc/src/error.rs @@ -25,7 +25,7 @@ pub enum OpEthApiError { L1BlockGasError, /// Wrapper for [`revm_primitives::InvalidTransaction`](InvalidTransaction). #[error(transparent)] - InvalidTransaction(#[from] OptimismInvalidTransactionError), + InvalidTransaction(#[from] OpInvalidTransactionError), /// Sequencer client error. #[error(transparent)] Sequencer(#[from] SequencerClientError), @@ -55,7 +55,7 @@ impl From for jsonrpsee_types::error::ErrorObject<'static> { /// Optimism specific invalid transaction errors #[derive(thiserror::Error, Debug)] -pub enum OptimismInvalidTransactionError { +pub enum OpInvalidTransactionError { /// A deposit transaction was submitted as a system transaction post-regolith. #[error("no system transactions allowed after regolith")] DepositSystemTxPostRegolith, @@ -64,18 +64,18 @@ pub enum OptimismInvalidTransactionError { HaltedDepositPostRegolith, } -impl From for jsonrpsee_types::error::ErrorObject<'static> { - fn from(err: OptimismInvalidTransactionError) -> Self { +impl From for jsonrpsee_types::error::ErrorObject<'static> { + fn from(err: OpInvalidTransactionError) -> Self { match err { - OptimismInvalidTransactionError::DepositSystemTxPostRegolith | - OptimismInvalidTransactionError::HaltedDepositPostRegolith => { + OpInvalidTransactionError::DepositSystemTxPostRegolith | + OpInvalidTransactionError::HaltedDepositPostRegolith => { rpc_err(EthRpcErrorCode::TransactionRejected.code(), err.to_string(), None) } } } } -impl TryFrom for OptimismInvalidTransactionError { +impl TryFrom for OpInvalidTransactionError { type Error = InvalidTransaction; fn try_from(err: InvalidTransaction) -> Result { diff --git a/crates/optimism/rpc/src/lib.rs b/crates/optimism/rpc/src/lib.rs index 0ff1451d05b..44d0fa35389 100644 --- a/crates/optimism/rpc/src/lib.rs +++ b/crates/optimism/rpc/src/lib.rs @@ -14,6 +14,6 @@ pub mod error; pub mod eth; pub mod sequencer; -pub use error::{OpEthApiError, OptimismInvalidTransactionError, SequencerClientError}; +pub use error::{OpEthApiError, OpInvalidTransactionError, SequencerClientError}; pub use eth::{OpEthApi, OpReceiptBuilder}; pub use sequencer::SequencerClient; From eb7bb08b51555fd42c112dbbc0bd0efa8d8d816e Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 8 Nov 2024 00:29:17 +0100 Subject: [PATCH 063/211] fix: remove independent tx from all (#12387) --- crates/transaction-pool/src/pool/best.rs | 11 +++++- crates/transaction-pool/src/pool/pending.rs | 43 +++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/crates/transaction-pool/src/pool/best.rs b/crates/transaction-pool/src/pool/best.rs index 36a14edaa23..068ef989953 100644 --- a/crates/transaction-pool/src/pool/best.rs +++ b/crates/transaction-pool/src/pool/best.rs @@ -128,6 +128,15 @@ impl BestTransactions { } } + /// Removes the currently best independent transaction from the independent set and the total + /// set. + fn pop_best(&mut self) -> Option> { + self.independent.pop_last().inspect(|best| { + let removed = self.all.remove(best.transaction.id()); + debug_assert!(removed.is_some(), "must be present in both sets"); + }) + } + /// Checks for new transactions that have come into the `PendingPool` after this iterator was /// created and inserts them fn add_new_transactions(&mut self) { @@ -167,7 +176,7 @@ impl Iterator for BestTransactions { loop { self.add_new_transactions(); // Remove the next independent tx with the highest priority - let best = self.independent.pop_last()?; + let best = self.pop_best()?; let sender_id = best.transaction.sender_id(); // skip transactions for which sender was marked as invalid diff --git a/crates/transaction-pool/src/pool/pending.rs b/crates/transaction-pool/src/pool/pending.rs index ff5269014c4..c9cfd85e288 100644 --- a/crates/transaction-pool/src/pool/pending.rs +++ b/crates/transaction-pool/src/pool/pending.rs @@ -815,4 +815,47 @@ mod tests { pending.into_iter().map(|tx| (tx.sender(), tx.nonce())).collect::>(); assert_eq!(pending, expected_pending); } + + // + #[test] + fn test_eligible_updates_promoted() { + let mut pool = PendingPool::new(MockOrdering::default()); + let mut f = MockTransactionFactory::default(); + + let num_senders = 10; + + let first_txs: Vec<_> = (0..num_senders) // + .map(|_| MockTransaction::eip1559()) + .collect(); + let second_txs: Vec<_> = + first_txs.iter().map(|tx| tx.clone().rng_hash().inc_nonce()).collect(); + + for tx in first_txs { + let valid_tx = f.validated(tx); + pool.add_transaction(Arc::new(valid_tx), 0); + } + + let mut best = pool.best(); + + for _ in 0..num_senders { + if let Some(tx) = best.next() { + assert_eq!(tx.nonce(), 0); + } else { + panic!("cannot read one of first_txs"); + } + } + + for tx in second_txs { + let valid_tx = f.validated(tx); + pool.add_transaction(Arc::new(valid_tx), 0); + } + + for _ in 0..num_senders { + if let Some(tx) = best.next() { + assert_eq!(tx.nonce(), 1); + } else { + panic!("cannot read one of second_txs"); + } + } + } } From c7b6a351133266423195349ff8b28274aceec4fc Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Fri, 8 Nov 2024 04:46:24 +0400 Subject: [PATCH 064/211] feat: bump alloy (#12391) --- Cargo.lock | 242 +++++++++++---------- Cargo.toml | 64 +++--- crates/optimism/rpc/src/eth/transaction.rs | 13 +- crates/rpc/rpc/src/eth/helpers/types.rs | 23 +- 4 files changed, 189 insertions(+), 153 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 60bf29c2a07..4fb7b26f2b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -97,9 +97,9 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "alloy-chains" -version = "0.1.46" +version = "0.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836cf02383d9ebb35502d379bcd1ae803155094077eaab9c29131d888cd5fa3e" +checksum = "18c5c520273946ecf715c0010b4e3503d7eba9893cd9ce6b7fff5654c4a3c470" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -112,9 +112,9 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7109d565c7157ee2c10beea7911a71130aa6c3cb6dfeaf66905a98f69b96a754" +checksum = "b19fd285b55dd39ae0dbc37481ad9f5f48898726f76335a2d6167a85a5fa41da" dependencies = [ "alloy-eips", "alloy-primitives", @@ -131,9 +131,9 @@ dependencies = [ [[package]] name = "alloy-contract" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f16c29a39afa238e35ee4ba06ca2e1c3a4764c2096e94c66730688a0471be7" +checksum = "4f42b1cb3fa8cba51b45795097a0d58a34569ca5db9eda48f63230e22fbc5cb5" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", @@ -198,9 +198,9 @@ dependencies = [ [[package]] name = "alloy-eips" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711de3f04cf728259ff149f725df12a8595b6b10baefafb0a0447201c72d76de" +checksum = "21aff0f2c921246398cad88e32a1d8ec14359b183afbc3dcb816873714cafc1a" dependencies = [ "alloy-eip2930", "alloy-eip7702", @@ -219,9 +219,9 @@ dependencies = [ [[package]] name = "alloy-genesis" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76b8fa6253466bd6f4b5ba3d725d350f7a05de494dd1b8d01537eafe934667e9" +checksum = "a76d899cfbfa13c5ed044383b7ae0e6a4d6ffcad3fd25e4acf71ff1c255ddae0" dependencies = [ "alloy-primitives", "alloy-serde", @@ -242,9 +242,9 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9278d6d554510136d9e0e4e51de4f5a9a4baffc8975f29e9acd01e12b2e045c" +checksum = "e244937365749c09c403d3054de39cc7dd46e3c3a12e5b164106af4903011ab1" dependencies = [ "alloy-primitives", "alloy-sol-types", @@ -256,9 +256,9 @@ dependencies = [ [[package]] name = "alloy-network" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85d356983dea86089b05674d5ef88a7168a5c34a523ef62e2e3c8a9847ce0822" +checksum = "0a28811461dc37e28db92b6d3a8c03a5883f2100b270a6294af00710bf4a0be4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -279,9 +279,9 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fbc9778e7989877465888383a7533c7318a9200d7229336bcc2b0277df36ba" +checksum = "3e517c44a97e753f10dc0736215ba4677da5e2fbc1451e3e76902e02cd6cff12" dependencies = [ "alloy-consensus", "alloy-eips", @@ -292,9 +292,9 @@ dependencies = [ [[package]] name = "alloy-node-bindings" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe5fd811738d37c56318378802b7bc3cc44e4d12b532641374309a10a04c515" +checksum = "15bf1a4b35b071c2d6f21fd3d32b8c5466cb7ed31fd4a4473a4e2ce180729121" dependencies = [ "alloy-genesis", "alloy-primitives", @@ -322,7 +322,7 @@ dependencies = [ "derive_more 1.0.0", "foldhash", "getrandom 0.2.15", - "hashbrown 0.15.0", + "hashbrown 0.15.1", "hex-literal", "indexmap 2.6.0", "itoa", @@ -341,9 +341,9 @@ dependencies = [ [[package]] name = "alloy-provider" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe3189c8cf3c3e9185862ac0d0b2a9d6bf00e4395746c7ec36307a4db0d5d486" +checksum = "56befb85784c7eb4f163b9aed7cdcaba09d5b07f8e59d6c12ad0ce1acf67c0fd" dependencies = [ "alloy-chains", "alloy-consensus", @@ -382,9 +382,9 @@ dependencies = [ [[package]] name = "alloy-pubsub" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51358f866bcb93b8440c08086557e415c455cdc8d63754fa339611a3e215b038" +checksum = "a6480f9596064db2ca8e1a4b710ea9a4ef420534e68640296a461b71f6bfadc1" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -423,9 +423,9 @@ dependencies = [ [[package]] name = "alloy-rpc-client" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d847913cea3fcd64fb1fe1247fafe15aab4060a2d24e535bbffcaa4670de9a79" +checksum = "cb49d38b3279a07e864d973323534a2c4a845e16f2c0153a509a3abcc01da7b1" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -448,9 +448,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ef8fd215cf81ddb0565815e1592a87377fa1e259db8ca4e683e6659fdf5c08" +checksum = "90be9542c6c9bb0d21ac08104ca0a3d1fb83e56f1c704f5cdcf6fb9e01fcbd75" dependencies = [ "alloy-primitives", "alloy-rpc-types-engine", @@ -461,9 +461,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-admin" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "647f703e27edad1f9c97455a6434378ea70b4ca9ae95f5e1559acf354c69bc14" +checksum = "410e7b9d67489d19ad52439b940fbf482e0823190d8245242bfff1eec44290d5" dependencies = [ "alloy-genesis", "alloy-primitives", @@ -473,9 +473,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-anvil" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6805b1626b084c231b2ec70c05090d45ce914d22e47f6cd4e8426f43098bbdf1" +checksum = "951f9106bb02ad00a2dc2eb7b400041a2c073d7fb8f33e2f1f29b2f71564f3f7" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -485,9 +485,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-beacon" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ed50d4f427bcb5bc561b3e6f45238158db6592deabcfbecb03c7ca9dadafe98" +checksum = "dab9821d5a73f56512ddd8e3db89a5bbb285353129b271c4ad6803a37c4e00ce" dependencies = [ "alloy-eips", "alloy-primitives", @@ -499,9 +499,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-debug" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e00a212581221f03d18c4239a1b985d695205a9518468a0b11ef64a143dd0724" +checksum = "ebe68f35cafc465442862421ae2d123bb58c8df25f837d8866bf5fc278b74a52" dependencies = [ "alloy-primitives", "serde", @@ -509,9 +509,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-engine" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7312fb85ef76428f8e20f50d1505494be9d081ffdb5cbf6a25c153c7b530994c" +checksum = "5ed9e7b3233cb3e0aaeaedc4e21e1ea9d99e947a7206241a9f9521c138193978" dependencies = [ "alloy-consensus", "alloy-eips", @@ -530,9 +530,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eba7afa617e7942ba5df88ca063a99e9f51e67df2de816fd52513e64926145a3" +checksum = "be10f130b8be7c2351a3ea64b4bf07020fde5be8d1ac18db9a9a3496aa22bb19" dependencies = [ "alloy-consensus", "alloy-eips", @@ -551,9 +551,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-mev" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b479e525a57388821d05c99732b3f6195128d8b74c9372329287f5e0d47d0aa" +checksum = "110f7dbee6f047915eb8915751d96402f6d02cb6e5f64286f10949eaa5bed841" dependencies = [ "alloy-eips", "alloy-primitives", @@ -564,9 +564,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-trace" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "563105a7fb420d44bd30bfe043f5bba8b6fe78432d8da99f4148aa7226d90d69" +checksum = "5d4f7f183d06db1457b58c6d618ff7ab92c97810138c148e09edb14ed2001069" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -578,9 +578,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-txpool" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0da9410a730ced6e30cd349e6d9f39bc9e37ca1bb58a39691e276d7a4061631" +checksum = "f85580d4e78ffd765086ebf640004a773e3c335ebbfaa5666e13a0640c4957fe" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -590,9 +590,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c9f13d8c9180dcced875f91f1876e428941cec151fc501637f68ad30d088d89" +checksum = "1493df14770a23b1e32d22c66fa22508d09e0a99d6923a45f179ff7887ca0cef" dependencies = [ "alloy-primitives", "arbitrary", @@ -602,9 +602,9 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "796f951bcd6a00f9fb53265676eed9fab6feb37d1eb912b70fc2654be5e5a560" +checksum = "ebff64a3b4062eba217404700d1517b9bf3ff9a7a5b2dd03f1cf8aeec3e9a6b8" dependencies = [ "alloy-primitives", "async-trait", @@ -616,9 +616,9 @@ dependencies = [ [[package]] name = "alloy-signer-local" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e2a3fb629bbe89cfba73699a4be64d6dc3bd73691f2e43f2a35448294ffbf9" +checksum = "bc1f6602be452e3bb5b6c2fe0fa0f966465f9e9bfd6ad7691bfe1bd8b74bf432" dependencies = [ "alloy-consensus", "alloy-network", @@ -704,9 +704,9 @@ dependencies = [ [[package]] name = "alloy-transport" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d315ab988e06f6b12038a3d7811957da28a8b378ff0d084b0819ebae1746ead" +checksum = "64534da7f71ecca86b3449adec19b7942fb0905b9f392f60054a02a5f686f71f" dependencies = [ "alloy-json-rpc", "base64 0.22.1", @@ -724,9 +724,9 @@ dependencies = [ [[package]] name = "alloy-transport-http" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "166449a8d8867be0978d6fa85aa56b89a27988b09e57bfd1f3b9962a9c8d5bae" +checksum = "617b5ab96f4fb64ef697a84c68ec8534c062baafbdb0529c34aaee43324f0d5a" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -739,9 +739,9 @@ dependencies = [ [[package]] name = "alloy-transport-ipc" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "716b21dce8e7ea29a5d459ed4b6d29a13a71d2b766fd84ac15e68623662b5d87" +checksum = "10043df9ea36e3a38056cdfc3a70138343caef4eec6df66d6cbfdd348d245828" dependencies = [ "alloy-json-rpc", "alloy-pubsub", @@ -758,9 +758,9 @@ dependencies = [ [[package]] name = "alloy-transport-ws" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b577974182a4e6d9b1a1ecd5a7fd48da9d239a1e214e2368d37b3179e86cd8c3" +checksum = "b6a43ecdbc8f79cb5d7f54e2118626f873ded93c8c040fb714ce6be47dc5b526" dependencies = [ "alloy-pubsub", "alloy-transport", @@ -776,9 +776,9 @@ dependencies = [ [[package]] name = "alloy-trie" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdd7f8b3a7c65ca09b3c7bdd7c7d72d7423d026f5247eda96af53d24e58315c1" +checksum = "40d8e28db02c006f7abb20f345ffb3cc99c465e36f676ba262534e654ae76042" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -817,9 +817,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.17" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -866,9 +866,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.92" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" [[package]] name = "aquamarine" @@ -886,9 +886,9 @@ dependencies = [ [[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", ] @@ -1651,9 +1651,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.34" +version = "1.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b9470d453346108f93a59222a9a1a5724db32d0a4727b7ab7ace4b4d822dc9" +checksum = "baee610e9452a8f6f0a1b6194ec09ff9e2d85dea54432acdae41aa0761c95d70" dependencies = [ "jobserver", "libc", @@ -2389,9 +2389,9 @@ dependencies = [ [[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", @@ -3551,9 +3551,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" dependencies = [ "allocator-api2", "equivalent", @@ -4012,12 +4012,23 @@ dependencies = [ [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] @@ -4094,7 +4105,7 @@ checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "arbitrary", "equivalent", - "hashbrown 0.15.0", + "hashbrown 0.15.1", "serde", ] @@ -4567,9 +4578,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.161" +version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" [[package]] name = "libloading" @@ -4740,7 +4751,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.0", + "hashbrown 0.15.1", ] [[package]] @@ -4866,7 +4877,7 @@ checksum = "15b482df36c13dd1869d73d14d28cd4855fbd6cfc32294bee109908a9f4a4ed7" dependencies = [ "crossbeam-epoch", "crossbeam-utils", - "hashbrown 0.15.0", + "hashbrown 0.15.1", "indexmap 2.6.0", "metrics", "ordered-float", @@ -5274,9 +5285,9 @@ checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "op-alloy-consensus" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dabf6e7d7d63b2c6ed746b24d334e16388c6c3921bc50172440c72aa923c6b4a" +checksum = "e33097177de330b1a83e0a882ae752ad55f23962b1e310176d1623655c18421e" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5292,9 +5303,9 @@ dependencies = [ [[package]] name = "op-alloy-genesis" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f901aa077832e22820c644d63d2e5e48601eed0f06e40f2a26d1b2a89bd17dec" +checksum = "2232ff799352932fc5484e1c63ee7bb1e74a79ac7b94a4f7318560fba21167de" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5306,9 +5317,9 @@ dependencies = [ [[package]] name = "op-alloy-network" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2e7db7997b12c1f364a3bd54b35338357f44c8e2e533a81ebf625104d80110" +checksum = "7f1021b644a8f0bf8d7f878aa5328da67c7d697e476c8e097d09e05585067713" dependencies = [ "alloy-consensus", "alloy-network", @@ -5321,9 +5332,9 @@ dependencies = [ [[package]] name = "op-alloy-protocol" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9226c7618f45f1d1e1f1112230818d5cfa719da9f5ca05fa28eaeb44d024181" +checksum = "a566c421638a3b655a2aaf59fbbdee017a7dce6acfbacead219861e14654b98d" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5341,9 +5352,9 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d60079165fe9a4be99b04865d8746c6c9c7b505be2fdce8982f677ca18c3cc10" +checksum = "72298f3f9084773dc3feaf88b08db82ceb3e3e13f98280459d869accb3f14234" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5360,9 +5371,9 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types-engine" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a5b505325e343b299b1c574b2b8542f6ac3101e0d92a1c909b2d7dd74665f1" +checksum = "f2a270e6370a0fa8a673e29bcd436cbb67b5dc88cefc1d00fbf2382673894f71" dependencies = [ "alloy-eips", "alloy-primitives", @@ -5416,9 +5427,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "ordered-float" -version = "4.3.0" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d501f1a72f71d3c063a6bbc8f7271fa73aa09fe5d6283b6571e2ed176a2537" +checksum = "c65ee1f9701bf938026630b455d5315f490640234259037edb259798b3bcf85e" dependencies = [ "num-traits", ] @@ -6020,9 +6031,9 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e346e016eacfff12233c243718197ca12f148c84e1e84268a896699b41c71780" +checksum = "7d5a626c6807713b15cac82a6acaccd6043c9a5408c24baae07611fec3f243da" dependencies = [ "cfg_aliases", "libc", @@ -9594,9 +9605,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.38" +version = "0.38.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" +checksum = "375116bee2be9ed569afe2154ea6a99dfdffd257f533f187498c2a8f5feaf4ee" dependencies = [ "bitflags 2.6.0", "errno", @@ -10318,9 +10329,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "symbolic-common" -version = "12.12.0" +version = "12.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "366f1b4c6baf6cfefc234bbd4899535fca0b06c74443039a73f6dfb2fad88d77" +checksum = "3d4d73159efebfb389d819fd479afb2dbd57dcb3e3f4b7fcfa0e675f5a46c1cb" dependencies = [ "debugid", "memmap2", @@ -10330,9 +10341,9 @@ dependencies = [ [[package]] name = "symbolic-demangle" -version = "12.12.0" +version = "12.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aba05ba5b9962ea5617baf556293720a8b2d0a282aa14ee4bf10e22efc7da8c8" +checksum = "a767859f6549c665011970874c3f541838b4835d5aaaa493d3ee383918be9f10" dependencies = [ "cpp_demangle", "rustc-demangle", @@ -10497,18 +10508,18 @@ checksum = "a38c90d48152c236a3ab59271da4f4ae63d678c5d7ad6b7714d7cb9760be5e4b" [[package]] name = "thiserror" -version = "1.0.67" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3c6efbfc763e64eb85c11c25320f0737cb7364c4b6336db90aa9ebe27a0bbd" +checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.67" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b607164372e89797d78b8e23a6d67d5d1038c1c65efd52e1389ef8b77caba2a6" +checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" dependencies = [ "proc-macro2", "quote", @@ -10665,9 +10676,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.41.0" +version = "1.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" dependencies = [ "backtrace", "bytes", @@ -10992,11 +11003,12 @@ dependencies = [ [[package]] name = "tracy-client-sys" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68613466112302fdbeabc5fa55f7d57462a0b247d5a6b7d7e09401fb471a144d" +checksum = "3637e734239e12ab152cd269302500bd063f37624ee210cd04b4936ed671f3b1" dependencies = [ "cc", + "windows-targets 0.52.6", ] [[package]] @@ -11204,12 +11216,12 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.2" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" dependencies = [ "form_urlencoded", - "idna 0.5.0", + "idna 1.0.3", "percent-encoding", "serde", ] diff --git a/Cargo.toml b/Cargo.toml index dc783f071a7..4471ce32baa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -430,46 +430,46 @@ alloy-rlp = "0.3.4" alloy-sol-types = "0.8.11" alloy-trie = { version = "0.7", default-features = false } -alloy-consensus = { version = "0.6.0", default-features = false } -alloy-contract = { version = "0.6.0", default-features = false } -alloy-eips = { version = "0.6.0", default-features = false } -alloy-genesis = { version = "0.6.0", default-features = false } -alloy-json-rpc = { version = "0.6.0", default-features = false } -alloy-network = { version = "0.6.0", default-features = false } -alloy-network-primitives = { version = "0.6.0", default-features = false } -alloy-node-bindings = { version = "0.6.0", default-features = false } -alloy-provider = { version = "0.6.0", features = [ +alloy-consensus = { version = "0.6.2", default-features = false } +alloy-contract = { version = "0.6.2", default-features = false } +alloy-eips = { version = "0.6.2", default-features = false } +alloy-genesis = { version = "0.6.2", default-features = false } +alloy-json-rpc = { version = "0.6.2", default-features = false } +alloy-network = { version = "0.6.2", default-features = false } +alloy-network-primitives = { version = "0.6.2", default-features = false } +alloy-node-bindings = { version = "0.6.2", default-features = false } +alloy-provider = { version = "0.6.2", features = [ "reqwest", ], default-features = false } -alloy-pubsub = { version = "0.6.0", default-features = false } -alloy-rpc-client = { version = "0.6.0", default-features = false } -alloy-rpc-types = { version = "0.6.0", features = [ +alloy-pubsub = { version = "0.6.2", default-features = false } +alloy-rpc-client = { version = "0.6.2", default-features = false } +alloy-rpc-types = { version = "0.6.2", features = [ "eth", ], default-features = false } -alloy-rpc-types-admin = { version = "0.6.0", default-features = false } -alloy-rpc-types-anvil = { version = "0.6.0", default-features = false } -alloy-rpc-types-beacon = { version = "0.6.0", default-features = false } -alloy-rpc-types-debug = { version = "0.6.0", default-features = false } -alloy-rpc-types-engine = { version = "0.6.0", default-features = false } -alloy-rpc-types-eth = { version = "0.6.0", default-features = false } -alloy-rpc-types-mev = { version = "0.6.0", default-features = false } -alloy-rpc-types-trace = { version = "0.6.0", default-features = false } -alloy-rpc-types-txpool = { version = "0.6.0", default-features = false } -alloy-serde = { version = "0.6.0", default-features = false } -alloy-signer = { version = "0.6.0", default-features = false } -alloy-signer-local = { version = "0.6.0", default-features = false } -alloy-transport = { version = "0.6.0" } -alloy-transport-http = { version = "0.6.0", features = [ +alloy-rpc-types-admin = { version = "0.6.2", default-features = false } +alloy-rpc-types-anvil = { version = "0.6.2", default-features = false } +alloy-rpc-types-beacon = { version = "0.6.2", default-features = false } +alloy-rpc-types-debug = { version = "0.6.2", default-features = false } +alloy-rpc-types-engine = { version = "0.6.2", default-features = false } +alloy-rpc-types-eth = { version = "0.6.2", default-features = false } +alloy-rpc-types-mev = { version = "0.6.2", default-features = false } +alloy-rpc-types-trace = { version = "0.6.2", default-features = false } +alloy-rpc-types-txpool = { version = "0.6.2", default-features = false } +alloy-serde = { version = "0.6.2", default-features = false } +alloy-signer = { version = "0.6.2", default-features = false } +alloy-signer-local = { version = "0.6.2", default-features = false } +alloy-transport = { version = "0.6.2" } +alloy-transport-http = { version = "0.6.2", features = [ "reqwest-rustls-tls", ], default-features = false } -alloy-transport-ipc = { version = "0.6.0", default-features = false } -alloy-transport-ws = { version = "0.6.0", default-features = false } +alloy-transport-ipc = { version = "0.6.2", default-features = false } +alloy-transport-ws = { version = "0.6.2", default-features = false } # op -op-alloy-rpc-types = "0.6.2" -op-alloy-rpc-types-engine = "0.6.2" -op-alloy-network = "0.6.2" -op-alloy-consensus = "0.6.2" +op-alloy-rpc-types = "0.6.3" +op-alloy-rpc-types-engine = "0.6.3" +op-alloy-network = "0.6.3" +op-alloy-consensus = "0.6.3" # misc aquamarine = "0.6" diff --git a/crates/optimism/rpc/src/eth/transaction.rs b/crates/optimism/rpc/src/eth/transaction.rs index b019ce0e97f..f62dbbf98cc 100644 --- a/crates/optimism/rpc/src/eth/transaction.rs +++ b/crates/optimism/rpc/src/eth/transaction.rs @@ -1,6 +1,6 @@ //! Loads and formats OP transaction RPC response. -use alloy_consensus::Signed; +use alloy_consensus::{Signed, Transaction as _}; use alloy_primitives::{Bytes, B256}; use alloy_rpc_types::TransactionInfo; use op_alloy_consensus::OpTxEnvelope; @@ -110,7 +110,15 @@ where .flatten() .and_then(|receipt| receipt.deposit_receipt_version); - let TransactionInfo { block_hash, block_number, index: transaction_index, .. } = tx_info; + let TransactionInfo { + block_hash, block_number, index: transaction_index, base_fee, .. + } = tx_info; + + let effective_gas_price = base_fee + .map(|base_fee| { + inner.effective_tip_per_gas(base_fee as u64).unwrap_or_default() + base_fee + }) + .unwrap_or_else(|| inner.max_fee_per_gas()); Transaction { inner: alloy_rpc_types::Transaction { @@ -119,6 +127,7 @@ where block_number, transaction_index, from, + effective_gas_price: Some(effective_gas_price), }, deposit_receipt_version, } diff --git a/crates/rpc/rpc/src/eth/helpers/types.rs b/crates/rpc/rpc/src/eth/helpers/types.rs index b86e32f046f..af0a3cbef8f 100644 --- a/crates/rpc/rpc/src/eth/helpers/types.rs +++ b/crates/rpc/rpc/src/eth/helpers/types.rs @@ -1,6 +1,6 @@ //! L1 `eth` API types. -use alloy_consensus::{Signed, TxEip4844Variant, TxEnvelope}; +use alloy_consensus::{Signed, Transaction as _, TxEip4844Variant, TxEnvelope}; use alloy_network::{Ethereum, Network}; use alloy_rpc_types::{Transaction, TransactionInfo}; use reth_primitives::{TransactionSigned, TransactionSignedEcRecovered}; @@ -24,7 +24,7 @@ where let from = tx.signer(); let TransactionSigned { transaction, signature, hash } = tx.into_signed(); - let inner = match transaction { + let inner: TxEnvelope = match transaction { reth_primitives::Transaction::Legacy(tx) => { Signed::new_unchecked(tx, signature, hash).into() } @@ -44,9 +44,24 @@ where _ => unreachable!(), }; - let TransactionInfo { block_hash, block_number, index: transaction_index, .. } = tx_info; + let TransactionInfo { + block_hash, block_number, index: transaction_index, base_fee, .. + } = tx_info; - Transaction { inner, block_hash, block_number, transaction_index, from } + let effective_gas_price = base_fee + .map(|base_fee| { + inner.effective_tip_per_gas(base_fee as u64).unwrap_or_default() + base_fee + }) + .unwrap_or_else(|| inner.max_fee_per_gas()); + + Transaction { + inner, + block_hash, + block_number, + transaction_index, + from, + effective_gas_price: Some(effective_gas_price), + } } fn otterscan_api_truncate_input(tx: &mut Self::Transaction) { From 87f328f957d3d9be478286b8e74314a5d5fabc13 Mon Sep 17 00:00:00 2001 From: Steven <112043913+stevencartavia@users.noreply.github.com> Date: Thu, 7 Nov 2024 23:33:30 -0600 Subject: [PATCH 065/211] replace BuilderBlockValidationRequestV3 with alloy type (#12396) --- Cargo.lock | 2 -- crates/ethereum/node/tests/e2e/rpc.rs | 6 +++-- crates/rpc/rpc-api/Cargo.toml | 2 -- crates/rpc/rpc-api/src/lib.rs | 5 +--- crates/rpc/rpc-api/src/validation.rs | 39 ++------------------------- crates/rpc/rpc/src/validation.rs | 6 ++--- 6 files changed, 9 insertions(+), 51 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4fb7b26f2b6..809d4be3135 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8701,8 +8701,6 @@ dependencies = [ "reth-engine-primitives", "reth-network-peers", "reth-rpc-eth-api", - "serde", - "serde_with", ] [[package]] diff --git a/crates/ethereum/node/tests/e2e/rpc.rs b/crates/ethereum/node/tests/e2e/rpc.rs index 94ae997eed6..b1a11b1b5eb 100644 --- a/crates/ethereum/node/tests/e2e/rpc.rs +++ b/crates/ethereum/node/tests/e2e/rpc.rs @@ -2,12 +2,14 @@ use crate::utils::eth_payload_attributes; use alloy_eips::{calc_next_block_base_fee, eip2718::Encodable2718}; use alloy_primitives::{Address, B256, U256}; use alloy_provider::{network::EthereumWallet, Provider, ProviderBuilder, SendableTx}; -use alloy_rpc_types_beacon::relay::{BidTrace, SignedBidSubmissionV3, SignedBidSubmissionV4}; +use alloy_rpc_types_beacon::relay::{ + BidTrace, BuilderBlockValidationRequestV3, BuilderBlockValidationRequestV4, + SignedBidSubmissionV3, SignedBidSubmissionV4, +}; use rand::{rngs::StdRng, Rng, SeedableRng}; use reth::{ payload::BuiltPayload, rpc::{ - api::{BuilderBlockValidationRequestV3, BuilderBlockValidationRequestV4}, compat::engine::payload::block_to_payload_v3, types::{engine::BlobsBundleV1, TransactionRequest}, }, diff --git a/crates/rpc/rpc-api/Cargo.toml b/crates/rpc/rpc-api/Cargo.toml index 75c06a2554c..abcdf98b544 100644 --- a/crates/rpc/rpc-api/Cargo.toml +++ b/crates/rpc/rpc-api/Cargo.toml @@ -35,8 +35,6 @@ alloy-rpc-types-engine.workspace = true # misc jsonrpsee = { workspace = true, features = ["server", "macros"] } -serde.workspace = true -serde_with.workspace = true [features] client = [ diff --git a/crates/rpc/rpc-api/src/lib.rs b/crates/rpc/rpc-api/src/lib.rs index 0a4fa9f660e..73775112dcf 100644 --- a/crates/rpc/rpc-api/src/lib.rs +++ b/crates/rpc/rpc-api/src/lib.rs @@ -46,10 +46,7 @@ pub mod servers { rpc::RpcApiServer, trace::TraceApiServer, txpool::TxPoolApiServer, - validation::{ - BlockSubmissionValidationApiServer, BuilderBlockValidationRequestV3, - BuilderBlockValidationRequestV4, - }, + validation::BlockSubmissionValidationApiServer, web3::Web3ApiServer, }; pub use reth_rpc_eth_api::{ diff --git a/crates/rpc/rpc-api/src/validation.rs b/crates/rpc/rpc-api/src/validation.rs index 797eee7ae52..5e4f2e26143 100644 --- a/crates/rpc/rpc-api/src/validation.rs +++ b/crates/rpc/rpc-api/src/validation.rs @@ -1,45 +1,10 @@ //! API for block submission validation. -use alloy_primitives::B256; use alloy_rpc_types_beacon::relay::{ - BuilderBlockValidationRequest, BuilderBlockValidationRequestV2, SignedBidSubmissionV3, - SignedBidSubmissionV4, + BuilderBlockValidationRequest, BuilderBlockValidationRequestV2, + BuilderBlockValidationRequestV3, BuilderBlockValidationRequestV4, }; use jsonrpsee::proc_macros::rpc; -use serde::{Deserialize, Serialize}; -use serde_with::{serde_as, DisplayFromStr}; - -/// A Request to validate a [`SignedBidSubmissionV3`] -/// -/// -#[serde_as] -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct BuilderBlockValidationRequestV3 { - /// The request to be validated. - #[serde(flatten)] - pub request: SignedBidSubmissionV3, - /// The registered gas limit for the validation request. - #[serde_as(as = "DisplayFromStr")] - pub registered_gas_limit: u64, - /// The parent beacon block root for the validation request. - pub parent_beacon_block_root: B256, -} - -/// A Request to validate a [`SignedBidSubmissionV4`] -/// -/// -#[serde_as] -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct BuilderBlockValidationRequestV4 { - /// The request to be validated. - #[serde(flatten)] - pub request: SignedBidSubmissionV4, - /// The registered gas limit for the validation request. - #[serde_as(as = "DisplayFromStr")] - pub registered_gas_limit: u64, - /// The parent beacon block root for the validation request. - pub parent_beacon_block_root: B256, -} /// Block validation rpc interface. #[cfg_attr(not(feature = "client"), rpc(server, namespace = "flashbots"))] diff --git a/crates/rpc/rpc/src/validation.rs b/crates/rpc/rpc/src/validation.rs index 1476180d431..5d7d00f354b 100644 --- a/crates/rpc/rpc/src/validation.rs +++ b/crates/rpc/rpc/src/validation.rs @@ -5,6 +5,7 @@ use alloy_rpc_types::engine::{ }; use alloy_rpc_types_beacon::relay::{ BidTrace, BuilderBlockValidationRequest, BuilderBlockValidationRequestV2, + BuilderBlockValidationRequestV3, BuilderBlockValidationRequestV4, }; use async_trait::async_trait; use jsonrpsee::core::RpcResult; @@ -20,10 +21,7 @@ use reth_provider::{ StateProviderFactory, WithdrawalsProvider, }; use reth_revm::database::StateProviderDatabase; -use reth_rpc_api::{ - BlockSubmissionValidationApiServer, BuilderBlockValidationRequestV3, - BuilderBlockValidationRequestV4, -}; +use reth_rpc_api::BlockSubmissionValidationApiServer; use reth_rpc_eth_types::EthApiError; use reth_rpc_server_types::{result::internal_rpc_err, ToRpcResult}; use reth_trie::HashedPostState; From c5ab4243e74f66d06a14710d194d580faab938e2 Mon Sep 17 00:00:00 2001 From: wangjingcun Date: Fri, 8 Nov 2024 18:23:02 +0800 Subject: [PATCH 066/211] chore: remove redundant words in comment (#12394) Signed-off-by: wangjingcun --- crates/net/discv4/src/lib.rs | 2 +- crates/storage/libmdbx-rs/mdbx-sys/libmdbx/mdbx.h++ | 2 +- deny.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/net/discv4/src/lib.rs b/crates/net/discv4/src/lib.rs index 788e93048f1..9ffe8451f0e 100644 --- a/crates/net/discv4/src/lib.rs +++ b/crates/net/discv4/src/lib.rs @@ -794,7 +794,7 @@ impl Discv4Service { } /// Sends a new `FindNode` packet to the node with `target` as the lookup target but checks - /// whether we should should send a new ping first to renew the endpoint proof by checking the + /// whether we should send a new ping first to renew the endpoint proof by checking the /// previously failed findNode requests. It could be that the node is no longer reachable or /// lost our entry. fn find_node_checked(&mut self, node: &NodeRecord, ctx: LookupContext) { diff --git a/crates/storage/libmdbx-rs/mdbx-sys/libmdbx/mdbx.h++ b/crates/storage/libmdbx-rs/mdbx-sys/libmdbx/mdbx.h++ index dbe94755087..767f3791280 100644 --- a/crates/storage/libmdbx-rs/mdbx-sys/libmdbx/mdbx.h++ +++ b/crates/storage/libmdbx-rs/mdbx-sys/libmdbx/mdbx.h++ @@ -851,7 +851,7 @@ struct LIBMDBX_API_TYPE slice : public ::MDBX_val { /// \brief Checks whether the content of the slice is printable. /// \param [in] disable_utf8 By default if `disable_utf8` is `false` function /// checks that content bytes are printable ASCII-7 characters or a valid UTF8 - /// sequences. Otherwise, if if `disable_utf8` is `true` function checks that + /// sequences. Otherwise, if `disable_utf8` is `true` function checks that /// content bytes are printable extended 8-bit ASCII codes. MDBX_NOTHROW_PURE_FUNCTION bool is_printable(bool disable_utf8 = false) const noexcept; diff --git a/deny.toml b/deny.toml index e5823460250..e8f60461c85 100644 --- a/deny.toml +++ b/deny.toml @@ -58,7 +58,7 @@ allow = [ # aren't accepted for every possible crate as with the normal allow list exceptions = [ # TODO: decide on MPL-2.0 handling - # These dependencies are grandfathered in in https://github.com/paradigmxyz/reth/pull/6980 + # These dependencies are grandfathered in https://github.com/paradigmxyz/reth/pull/6980 { allow = ["MPL-2.0"], name = "option-ext" }, { allow = ["MPL-2.0"], name = "webpki-roots" }, ] From f373efe01d1e79751a7619d22be2221537d33f28 Mon Sep 17 00:00:00 2001 From: Hoa Nguyen Date: Fri, 8 Nov 2024 17:36:17 +0700 Subject: [PATCH 067/211] refactor: phase out alloy-rpc-types usage (#12395) --- Cargo.lock | 29 +++++++++---------- crates/consensus/debug-client/Cargo.toml | 2 +- crates/consensus/debug-client/src/client.rs | 2 +- .../debug-client/src/providers/etherscan.rs | 2 +- .../debug-client/src/providers/rpc.rs | 2 +- crates/e2e-test-utils/Cargo.toml | 3 +- crates/e2e-test-utils/src/node.rs | 2 +- crates/e2e-test-utils/src/traits.rs | 2 +- crates/e2e-test-utils/src/transaction.rs | 2 +- crates/optimism/rpc/Cargo.toml | 1 - crates/optimism/rpc/src/error.rs | 2 +- crates/optimism/rpc/src/eth/block.rs | 2 +- crates/optimism/rpc/src/eth/receipt.rs | 2 +- crates/optimism/rpc/src/eth/transaction.rs | 4 +-- crates/rpc/rpc-api/src/anvil.rs | 2 +- crates/rpc/rpc-api/src/debug.rs | 3 +- crates/rpc/rpc-api/src/engine.rs | 8 ++--- crates/rpc/rpc-api/src/otterscan.rs | 2 +- crates/rpc/rpc-api/src/trace.rs | 5 ++-- crates/rpc/rpc-eth-api/Cargo.toml | 2 +- crates/rpc/rpc-eth-api/src/core.rs | 10 +++---- crates/rpc/rpc-eth-api/src/filter.rs | 2 +- crates/rpc/rpc-eth-api/src/helpers/block.rs | 2 +- crates/rpc/rpc-eth-api/src/helpers/call.rs | 4 +-- crates/rpc/rpc-eth-api/src/helpers/fee.rs | 2 +- .../rpc-eth-api/src/helpers/pending_block.rs | 2 +- crates/rpc/rpc-eth-api/src/helpers/spec.rs | 2 +- crates/rpc/rpc-eth-api/src/helpers/state.rs | 3 +- crates/rpc/rpc-eth-api/src/helpers/trace.rs | 2 +- .../rpc-eth-api/src/helpers/transaction.rs | 3 +- crates/rpc/rpc-eth-api/src/pubsub.rs | 2 +- crates/rpc/rpc-eth-api/src/types.rs | 4 +-- crates/rpc/rpc-eth-types/Cargo.toml | 1 - crates/rpc/rpc-eth-types/src/cache/db.rs | 2 +- crates/rpc/rpc-eth-types/src/error.rs | 2 +- crates/rpc/rpc-eth-types/src/fee_history.rs | 2 +- crates/rpc/rpc-eth-types/src/gas_oracle.rs | 2 +- crates/rpc/rpc-eth-types/src/logs_utils.rs | 8 ++--- crates/rpc/rpc-eth-types/src/receipt.rs | 4 +-- crates/rpc/rpc-eth-types/src/revm_utils.rs | 2 +- crates/rpc/rpc-eth-types/src/simulate.rs | 6 ++-- crates/rpc/rpc-eth-types/src/transaction.rs | 2 +- crates/rpc/rpc-testing-util/Cargo.toml | 1 - crates/rpc/rpc-testing-util/src/debug.rs | 3 +- crates/rpc/rpc-testing-util/src/trace.rs | 3 +- crates/rpc/rpc-testing-util/tests/it/trace.rs | 2 +- crates/rpc/rpc-types-compat/Cargo.toml | 2 +- crates/rpc/rpc-types-compat/src/block.rs | 2 +- crates/rpc/rpc-types-compat/src/proof.rs | 2 +- .../rpc-types-compat/src/transaction/mod.rs | 2 +- crates/rpc/rpc/Cargo.toml | 5 ++-- crates/rpc/rpc/src/debug.rs | 8 ++--- crates/rpc/rpc/src/engine.rs | 6 ++-- crates/rpc/rpc/src/eth/bundle.rs | 2 +- crates/rpc/rpc/src/eth/filter.rs | 2 +- crates/rpc/rpc/src/eth/helpers/block.rs | 2 +- crates/rpc/rpc/src/eth/helpers/types.rs | 2 +- crates/rpc/rpc/src/eth/pubsub.rs | 2 +- crates/rpc/rpc/src/eth/sim_bundle.rs | 2 +- crates/rpc/rpc/src/otterscan.rs | 2 +- crates/rpc/rpc/src/trace.rs | 4 +-- crates/rpc/rpc/src/validation.rs | 6 ++-- examples/custom-inspector/Cargo.toml | 2 +- examples/custom-inspector/src/main.rs | 2 +- examples/db-access/Cargo.toml | 2 +- examples/db-access/src/main.rs | 2 +- 66 files changed, 106 insertions(+), 110 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 809d4be3135..d6169e25f5f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1168,7 +1168,7 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4fa97bb310c33c811334143cf64c5bb2b7b3c06e453db6b095d7061eff8f113" dependencies = [ - "fastrand 2.1.1", + "fastrand 2.2.0", "tokio", ] @@ -2896,7 +2896,7 @@ version = "0.0.0" dependencies = [ "alloy-eips", "alloy-primitives", - "alloy-rpc-types", + "alloy-rpc-types-eth", "clap", "futures-util", "reth", @@ -2956,7 +2956,7 @@ name = "example-db-access" version = "0.0.0" dependencies = [ "alloy-primitives", - "alloy-rpc-types", + "alloy-rpc-types-eth", "eyre", "reth-chainspec", "reth-db", @@ -3115,9 +3115,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" [[package]] name = "fastrlp" @@ -6800,8 +6800,8 @@ dependencies = [ "alloy-eips", "alloy-primitives", "alloy-provider", - "alloy-rpc-types", "alloy-rpc-types-engine", + "alloy-rpc-types-eth", "auto_impl", "eyre", "futures", @@ -7051,7 +7051,8 @@ dependencies = [ "alloy-eips", "alloy-network", "alloy-primitives", - "alloy-rpc-types", + "alloy-rpc-types-engine", + "alloy-rpc-types-eth", "alloy-signer", "alloy-signer-local", "derive_more 1.0.0", @@ -8324,7 +8325,6 @@ dependencies = [ "alloy-consensus", "alloy-eips", "alloy-primitives", - "alloy-rpc-types", "alloy-rpc-types-eth", "derive_more 1.0.0", "jsonrpsee-types", @@ -8623,6 +8623,7 @@ dependencies = [ "alloy-rpc-types-admin", "alloy-rpc-types-beacon", "alloy-rpc-types-debug", + "alloy-rpc-types-engine", "alloy-rpc-types-eth", "alloy-rpc-types-mev", "alloy-rpc-types-trace", @@ -8709,7 +8710,6 @@ version = "1.1.1" dependencies = [ "alloy-eips", "alloy-primitives", - "alloy-rpc-types", "alloy-rpc-types-eth", "alloy-rpc-types-trace", "futures", @@ -8820,9 +8820,9 @@ dependencies = [ "alloy-json-rpc", "alloy-network", "alloy-primitives", - "alloy-rpc-types", "alloy-rpc-types-eth", "alloy-rpc-types-mev", + "alloy-serde", "async-trait", "auto_impl", "dyn-clone", @@ -8859,7 +8859,6 @@ dependencies = [ "alloy-consensus", "alloy-eips", "alloy-primitives", - "alloy-rpc-types", "alloy-rpc-types-eth", "alloy-sol-types", "derive_more 1.0.0", @@ -8933,9 +8932,9 @@ dependencies = [ "alloy-eips", "alloy-primitives", "alloy-rlp", - "alloy-rpc-types", "alloy-rpc-types-engine", "alloy-rpc-types-eth", + "alloy-serde", "reth-primitives", "reth-trie-common", "serde", @@ -10429,12 +10428,12 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[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 2.1.1", + "fastrand 2.2.0", "once_cell", "rustix", "windows-sys 0.59.0", diff --git a/crates/consensus/debug-client/Cargo.toml b/crates/consensus/debug-client/Cargo.toml index e73125a80bd..18e7aead306 100644 --- a/crates/consensus/debug-client/Cargo.toml +++ b/crates/consensus/debug-client/Cargo.toml @@ -21,7 +21,7 @@ reth-tracing.workspace = true alloy-consensus = { workspace = true, features = ["serde"] } alloy-eips.workspace = true alloy-provider = { workspace = true, features = ["ws"] } -alloy-rpc-types.workspace = true +alloy-rpc-types-eth.workspace = true alloy-rpc-types-engine.workspace = true alloy-primitives.workspace = true diff --git a/crates/consensus/debug-client/src/client.rs b/crates/consensus/debug-client/src/client.rs index b6993a41b90..0e2a50370b8 100644 --- a/crates/consensus/debug-client/src/client.rs +++ b/crates/consensus/debug-client/src/client.rs @@ -1,8 +1,8 @@ use alloy_consensus::Transaction; use alloy_eips::eip2718::Encodable2718; use alloy_primitives::B256; -use alloy_rpc_types::{Block, BlockTransactions}; use alloy_rpc_types_engine::{ExecutionPayloadV1, ExecutionPayloadV2, ExecutionPayloadV3}; +use alloy_rpc_types_eth::{Block, BlockTransactions}; use reth_node_api::EngineTypes; use reth_rpc_builder::auth::AuthServerHandle; use reth_tracing::tracing::warn; diff --git a/crates/consensus/debug-client/src/providers/etherscan.rs b/crates/consensus/debug-client/src/providers/etherscan.rs index 59b402f3e78..d3167b6cfab 100644 --- a/crates/consensus/debug-client/src/providers/etherscan.rs +++ b/crates/consensus/debug-client/src/providers/etherscan.rs @@ -1,6 +1,6 @@ use crate::BlockProvider; use alloy_eips::BlockNumberOrTag; -use alloy_rpc_types::Block; +use alloy_rpc_types_eth::Block; use reqwest::Client; use reth_tracing::tracing::warn; use serde::Deserialize; diff --git a/crates/consensus/debug-client/src/providers/rpc.rs b/crates/consensus/debug-client/src/providers/rpc.rs index 5312bd55b3f..787515f1a60 100644 --- a/crates/consensus/debug-client/src/providers/rpc.rs +++ b/crates/consensus/debug-client/src/providers/rpc.rs @@ -1,7 +1,7 @@ use crate::BlockProvider; use alloy_eips::BlockNumberOrTag; use alloy_provider::{Provider, ProviderBuilder}; -use alloy_rpc_types::{Block, BlockTransactionsKind}; +use alloy_rpc_types_eth::{Block, BlockTransactionsKind}; use futures::StreamExt; use tokio::sync::mpsc::Sender; diff --git a/crates/e2e-test-utils/Cargo.toml b/crates/e2e-test-utils/Cargo.toml index 67bb7455536..e56449551bb 100644 --- a/crates/e2e-test-utils/Cargo.toml +++ b/crates/e2e-test-utils/Cargo.toml @@ -41,7 +41,8 @@ tokio-stream.workspace = true serde_json.workspace = true alloy-signer.workspace = true alloy-signer-local = { workspace = true, features = ["mnemonic"] } -alloy-rpc-types.workspace = true +alloy-rpc-types-eth.workspace = true +alloy-rpc-types-engine.workspace = true alloy-network.workspace = true alloy-consensus = { workspace = true, features = ["kzg"] } tracing.workspace = true diff --git a/crates/e2e-test-utils/src/node.rs b/crates/e2e-test-utils/src/node.rs index 8b385115b3e..c3dff527eb2 100644 --- a/crates/e2e-test-utils/src/node.rs +++ b/crates/e2e-test-utils/src/node.rs @@ -1,7 +1,7 @@ use std::{marker::PhantomData, pin::Pin}; use alloy_primitives::{BlockHash, BlockNumber, Bytes, B256}; -use alloy_rpc_types::BlockNumberOrTag; +use alloy_rpc_types_eth::BlockNumberOrTag; use eyre::Ok; use futures_util::Future; use reth::{ diff --git a/crates/e2e-test-utils/src/traits.rs b/crates/e2e-test-utils/src/traits.rs index a70bbf7afb7..d14445370d4 100644 --- a/crates/e2e-test-utils/src/traits.rs +++ b/crates/e2e-test-utils/src/traits.rs @@ -1,4 +1,4 @@ -use alloy_rpc_types::engine::ExecutionPayloadEnvelopeV4; +use alloy_rpc_types_engine::ExecutionPayloadEnvelopeV4; use op_alloy_rpc_types_engine::{OpExecutionPayloadEnvelopeV3, OpExecutionPayloadEnvelopeV4}; use reth::rpc::types::engine::{ExecutionPayloadEnvelopeV3, ExecutionPayloadV3}; diff --git a/crates/e2e-test-utils/src/transaction.rs b/crates/e2e-test-utils/src/transaction.rs index 58a25dc1257..d24c5579313 100644 --- a/crates/e2e-test-utils/src/transaction.rs +++ b/crates/e2e-test-utils/src/transaction.rs @@ -4,7 +4,7 @@ use alloy_network::{ eip2718::Encodable2718, Ethereum, EthereumWallet, TransactionBuilder, TransactionBuilder4844, }; use alloy_primitives::{hex, Address, Bytes, TxKind, B256, U256}; -use alloy_rpc_types::{Authorization, TransactionInput, TransactionRequest}; +use alloy_rpc_types_eth::{Authorization, TransactionInput, TransactionRequest}; use alloy_signer::SignerSync; use alloy_signer_local::PrivateKeySigner; use eyre::Ok; diff --git a/crates/optimism/rpc/Cargo.toml b/crates/optimism/rpc/Cargo.toml index 17ebec7ff74..37b64b774a1 100644 --- a/crates/optimism/rpc/Cargo.toml +++ b/crates/optimism/rpc/Cargo.toml @@ -37,7 +37,6 @@ reth-optimism-forks.workspace = true alloy-eips.workspace = true alloy-primitives.workspace = true alloy-rpc-types-eth.workspace = true -alloy-rpc-types.workspace = true alloy-consensus.workspace = true op-alloy-network.workspace = true op-alloy-rpc-types.workspace = true diff --git a/crates/optimism/rpc/src/error.rs b/crates/optimism/rpc/src/error.rs index 078da8fe4d1..ffc698b6e98 100644 --- a/crates/optimism/rpc/src/error.rs +++ b/crates/optimism/rpc/src/error.rs @@ -1,6 +1,6 @@ //! RPC errors specific to OP. -use alloy_rpc_types::error::EthRpcErrorCode; +use alloy_rpc_types_eth::error::EthRpcErrorCode; use jsonrpsee_types::error::INTERNAL_ERROR_CODE; use reth_optimism_evm::OpBlockExecutionError; use reth_primitives::revm_primitives::{InvalidTransaction, OptimismInvalidTransaction}; diff --git a/crates/optimism/rpc/src/eth/block.rs b/crates/optimism/rpc/src/eth/block.rs index 85f36570f2e..6678fbe5df4 100644 --- a/crates/optimism/rpc/src/eth/block.rs +++ b/crates/optimism/rpc/src/eth/block.rs @@ -1,6 +1,6 @@ //! Loads and formats OP block RPC response. -use alloy_rpc_types::BlockId; +use alloy_rpc_types_eth::BlockId; use op_alloy_network::Network; use op_alloy_rpc_types::OpTransactionReceipt; use reth_chainspec::ChainSpecProvider; diff --git a/crates/optimism/rpc/src/eth/receipt.rs b/crates/optimism/rpc/src/eth/receipt.rs index 3563d4ae45d..40ee5d9fd86 100644 --- a/crates/optimism/rpc/src/eth/receipt.rs +++ b/crates/optimism/rpc/src/eth/receipt.rs @@ -1,7 +1,7 @@ //! Loads and formats OP receipt RPC response. use alloy_eips::eip2718::Encodable2718; -use alloy_rpc_types::{Log, TransactionReceipt}; +use alloy_rpc_types_eth::{Log, TransactionReceipt}; use op_alloy_consensus::{ DepositTransaction, OpDepositReceipt, OpDepositReceiptWithBloom, OpReceiptEnvelope, }; diff --git a/crates/optimism/rpc/src/eth/transaction.rs b/crates/optimism/rpc/src/eth/transaction.rs index f62dbbf98cc..90e5e33feb7 100644 --- a/crates/optimism/rpc/src/eth/transaction.rs +++ b/crates/optimism/rpc/src/eth/transaction.rs @@ -2,7 +2,7 @@ use alloy_consensus::{Signed, Transaction as _}; use alloy_primitives::{Bytes, B256}; -use alloy_rpc_types::TransactionInfo; +use alloy_rpc_types_eth::TransactionInfo; use op_alloy_consensus::OpTxEnvelope; use op_alloy_rpc_types::Transaction; use reth_node_api::FullNodeComponents; @@ -121,7 +121,7 @@ where .unwrap_or_else(|| inner.max_fee_per_gas()); Transaction { - inner: alloy_rpc_types::Transaction { + inner: alloy_rpc_types_eth::Transaction { inner, block_hash, block_number, diff --git a/crates/rpc/rpc-api/src/anvil.rs b/crates/rpc/rpc-api/src/anvil.rs index baa09166b83..0930264a63b 100644 --- a/crates/rpc/rpc-api/src/anvil.rs +++ b/crates/rpc/rpc-api/src/anvil.rs @@ -1,8 +1,8 @@ use jsonrpsee::{core::RpcResult, proc_macros::rpc}; use alloy_primitives::{Address, Bytes, B256, U256}; -use alloy_rpc_types::Block; use alloy_rpc_types_anvil::{Forking, Metadata, MineOptions, NodeInfo}; +use alloy_rpc_types_eth::Block; /// Anvil rpc interface. /// https://book.getfoundry.sh/reference/anvil/#custom-methods diff --git a/crates/rpc/rpc-api/src/debug.rs b/crates/rpc/rpc-api/src/debug.rs index d1837787d54..1b857d4a11f 100644 --- a/crates/rpc/rpc-api/src/debug.rs +++ b/crates/rpc/rpc-api/src/debug.rs @@ -1,8 +1,7 @@ use alloy_eips::{BlockId, BlockNumberOrTag}; use alloy_primitives::{Address, Bytes, B256}; -use alloy_rpc_types::{Block, Bundle, StateContext}; use alloy_rpc_types_debug::ExecutionWitness; -use alloy_rpc_types_eth::transaction::TransactionRequest; +use alloy_rpc_types_eth::{transaction::TransactionRequest, Block, Bundle, StateContext}; use alloy_rpc_types_trace::geth::{ BlockTraceResult, GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace, TraceResult, }; diff --git a/crates/rpc/rpc-api/src/engine.rs b/crates/rpc/rpc-api/src/engine.rs index d92173112eb..f78b8349be8 100644 --- a/crates/rpc/rpc-api/src/engine.rs +++ b/crates/rpc/rpc-api/src/engine.rs @@ -6,15 +6,15 @@ use alloy_eips::{eip4844::BlobAndProofV1, eip7685::Requests, BlockId, BlockNumberOrTag}; use alloy_json_rpc::RpcObject; use alloy_primitives::{Address, BlockHash, Bytes, B256, U256, U64}; -use alloy_rpc_types::{ - state::StateOverride, BlockOverrides, EIP1186AccountProofResponse, Filter, Log, SyncStatus, -}; use alloy_rpc_types_engine::{ ClientVersionV1, ExecutionPayloadBodiesV1, ExecutionPayloadInputV2, ExecutionPayloadV1, ExecutionPayloadV3, ForkchoiceState, ForkchoiceUpdated, PayloadId, PayloadStatus, TransitionConfiguration, }; -use alloy_rpc_types_eth::transaction::TransactionRequest; +use alloy_rpc_types_eth::{ + state::StateOverride, transaction::TransactionRequest, BlockOverrides, + EIP1186AccountProofResponse, Filter, Log, SyncStatus, +}; use alloy_serde::JsonStorageKey; use jsonrpsee::{core::RpcResult, proc_macros::rpc}; use reth_engine_primitives::EngineTypes; diff --git a/crates/rpc/rpc-api/src/otterscan.rs b/crates/rpc/rpc-api/src/otterscan.rs index d3e61c03104..b4679ae5cec 100644 --- a/crates/rpc/rpc-api/src/otterscan.rs +++ b/crates/rpc/rpc-api/src/otterscan.rs @@ -1,7 +1,7 @@ use alloy_eips::BlockId; use alloy_json_rpc::RpcObject; use alloy_primitives::{Address, Bytes, TxHash, B256}; -use alloy_rpc_types::Header; +use alloy_rpc_types_eth::Header; use alloy_rpc_types_trace::otterscan::{ BlockDetails, ContractCreator, InternalOperation, OtsBlockTransactions, TraceEntry, TransactionsWithReceipts, diff --git a/crates/rpc/rpc-api/src/trace.rs b/crates/rpc/rpc-api/src/trace.rs index 45059284a2d..41e2b4c1c3e 100644 --- a/crates/rpc/rpc-api/src/trace.rs +++ b/crates/rpc/rpc-api/src/trace.rs @@ -1,7 +1,8 @@ use alloy_eips::BlockId; use alloy_primitives::{map::HashSet, Bytes, B256}; -use alloy_rpc_types::{state::StateOverride, BlockOverrides, Index}; -use alloy_rpc_types_eth::transaction::TransactionRequest; +use alloy_rpc_types_eth::{ + state::StateOverride, transaction::TransactionRequest, BlockOverrides, Index, +}; use alloy_rpc_types_trace::{ filter::TraceFilter, opcode::{BlockOpcodeGas, TransactionOpcodeGas}, diff --git a/crates/rpc/rpc-eth-api/Cargo.toml b/crates/rpc/rpc-eth-api/Cargo.toml index edfd57b201d..e4b1b28074f 100644 --- a/crates/rpc/rpc-eth-api/Cargo.toml +++ b/crates/rpc/rpc-eth-api/Cargo.toml @@ -33,13 +33,13 @@ reth-trie.workspace = true reth-node-api.workspace = true # ethereum +alloy-serde.workspace = true alloy-eips.workspace = true alloy-dyn-abi = { workspace = true, features = ["eip712"] } alloy-json-rpc.workspace = true alloy-network.workspace = true alloy-primitives.workspace = true alloy-rpc-types-eth.workspace = true -alloy-rpc-types.workspace = true alloy-rpc-types-mev.workspace = true alloy-consensus.workspace = true diff --git a/crates/rpc/rpc-eth-api/src/core.rs b/crates/rpc/rpc-eth-api/src/core.rs index a89364a15db..421c10f8b41 100644 --- a/crates/rpc/rpc-eth-api/src/core.rs +++ b/crates/rpc/rpc-eth-api/src/core.rs @@ -4,14 +4,14 @@ use alloy_dyn_abi::TypedData; use alloy_eips::{eip2930::AccessListResult, BlockId, BlockNumberOrTag}; use alloy_json_rpc::RpcObject; use alloy_primitives::{Address, Bytes, B256, B64, U256, U64}; -use alloy_rpc_types::{ - serde_helpers::JsonStorageKey, +use alloy_rpc_types_eth::{ simulate::{SimulatePayload, SimulatedBlock}, state::{EvmOverrides, StateOverride}, + transaction::TransactionRequest, BlockOverrides, Bundle, EIP1186AccountProofResponse, EthCallResponse, FeeHistory, Header, Index, StateContext, SyncStatus, Work, }; -use alloy_rpc_types_eth::transaction::TransactionRequest; +use alloy_serde::JsonStorageKey; use jsonrpsee::{core::RpcResult, proc_macros::rpc}; use reth_rpc_server_types::{result::internal_rpc_err, ToRpcResult}; use tracing::trace; @@ -276,7 +276,7 @@ pub trait EthApi { &self, address: Address, block: BlockId, - ) -> RpcResult>; + ) -> RpcResult>; /// Introduced in EIP-1559, returns suggestion for the priority for dynamic fee transactions. #[method(name = "maxPriorityFeePerGas")] @@ -694,7 +694,7 @@ where &self, address: Address, block: BlockId, - ) -> RpcResult> { + ) -> RpcResult> { trace!(target: "rpc::eth", "Serving eth_getAccount"); Ok(EthState::get_account(self, address, block).await?) } diff --git a/crates/rpc/rpc-eth-api/src/filter.rs b/crates/rpc/rpc-eth-api/src/filter.rs index c73d9672843..1acba351af7 100644 --- a/crates/rpc/rpc-eth-api/src/filter.rs +++ b/crates/rpc/rpc-eth-api/src/filter.rs @@ -1,7 +1,7 @@ //! `eth_` RPC API for filtering. use alloy_json_rpc::RpcObject; -use alloy_rpc_types::{Filter, FilterChanges, FilterId, Log, PendingTransactionFilterKind}; +use alloy_rpc_types_eth::{Filter, FilterChanges, FilterId, Log, PendingTransactionFilterKind}; use jsonrpsee::{core::RpcResult, proc_macros::rpc}; /// Rpc Interface for poll-based ethereum filter API. diff --git a/crates/rpc/rpc-eth-api/src/helpers/block.rs b/crates/rpc/rpc-eth-api/src/helpers/block.rs index a9794af004a..e25ea84d699 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/block.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use alloy_eips::BlockId; -use alloy_rpc_types::{Block, Header, Index}; +use alloy_rpc_types_eth::{Block, Header, Index}; use futures::Future; use reth_primitives::{Receipt, SealedBlock, SealedBlockWithSenders}; use reth_provider::{BlockIdReader, BlockReader, BlockReaderIdExt, HeaderProvider}; diff --git a/crates/rpc/rpc-eth-api/src/helpers/call.rs b/crates/rpc/rpc-eth-api/src/helpers/call.rs index 10148fbe78b..ef29f807026 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/call.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/call.rs @@ -8,12 +8,12 @@ use crate::{ use alloy_consensus::BlockHeader; use alloy_eips::{eip1559::calc_next_block_base_fee, eip2930::AccessListResult}; use alloy_primitives::{Address, Bytes, TxKind, B256, U256}; -use alloy_rpc_types::{ +use alloy_rpc_types_eth::{ simulate::{SimBlock, SimulatePayload, SimulatedBlock}, state::{EvmOverrides, StateOverride}, + transaction::TransactionRequest, BlockId, Bundle, EthCallResponse, StateContext, TransactionInfo, }; -use alloy_rpc_types_eth::transaction::TransactionRequest; use futures::Future; use reth_chainspec::{EthChainSpec, MIN_TRANSACTION_GAS}; use reth_evm::{ConfigureEvm, ConfigureEvmEnv}; diff --git a/crates/rpc/rpc-eth-api/src/helpers/fee.rs b/crates/rpc/rpc-eth-api/src/helpers/fee.rs index 18d2d631148..8ed45d2ac08 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/fee.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/fee.rs @@ -1,7 +1,7 @@ //! Loads fee history from database. Helper trait for `eth_` fee and transaction RPC methods. use alloy_primitives::U256; -use alloy_rpc_types::{BlockNumberOrTag, FeeHistory}; +use alloy_rpc_types_eth::{BlockNumberOrTag, FeeHistory}; use futures::Future; use reth_chainspec::EthChainSpec; use reth_provider::{BlockIdReader, ChainSpecProvider, HeaderProvider}; diff --git a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs index a0065d79342..0173485aef5 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs @@ -10,7 +10,7 @@ use alloy_eips::{ eip4844::MAX_DATA_GAS_PER_BLOCK, eip7685::EMPTY_REQUESTS_HASH, merge::BEACON_NONCE, }; use alloy_primitives::{BlockNumber, B256, U256}; -use alloy_rpc_types::BlockNumberOrTag; +use alloy_rpc_types_eth::BlockNumberOrTag; use futures::Future; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_evm::{ diff --git a/crates/rpc/rpc-eth-api/src/helpers/spec.rs b/crates/rpc/rpc-eth-api/src/helpers/spec.rs index a6213017af8..9957a00a41d 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/spec.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/spec.rs @@ -1,7 +1,7 @@ //! Loads chain metadata. use alloy_primitives::{Address, U256, U64}; -use alloy_rpc_types::{Stage, SyncInfo, SyncStatus}; +use alloy_rpc_types_eth::{Stage, SyncInfo, SyncStatus}; use futures::Future; use reth_chainspec::{ChainInfo, EthereumHardforks}; use reth_errors::{RethError, RethResult}; diff --git a/crates/rpc/rpc-eth-api/src/helpers/state.rs b/crates/rpc/rpc-eth-api/src/helpers/state.rs index 6a34967058b..7bc365d91c4 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/state.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/state.rs @@ -4,7 +4,8 @@ use alloy_consensus::constants::KECCAK_EMPTY; use alloy_eips::BlockId; use alloy_primitives::{Address, Bytes, B256, U256}; -use alloy_rpc_types::{serde_helpers::JsonStorageKey, Account, EIP1186AccountProofResponse}; +use alloy_rpc_types_eth::{Account, EIP1186AccountProofResponse}; +use alloy_serde::JsonStorageKey; use futures::Future; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_errors::RethError; diff --git a/crates/rpc/rpc-eth-api/src/helpers/trace.rs b/crates/rpc/rpc-eth-api/src/helpers/trace.rs index 29bde519960..36d901fda5f 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/trace.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/trace.rs @@ -4,7 +4,7 @@ use std::{fmt::Display, sync::Arc}; use crate::{FromEvmError, RpcNodeCore}; use alloy_primitives::B256; -use alloy_rpc_types::{BlockId, TransactionInfo}; +use alloy_rpc_types_eth::{BlockId, TransactionInfo}; use futures::Future; use reth_chainspec::ChainSpecProvider; use reth_evm::{system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv}; diff --git a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs index ab94e3dd107..234008f21fe 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs @@ -6,8 +6,7 @@ use alloy_dyn_abi::TypedData; use alloy_eips::{eip2718::Encodable2718, BlockId}; use alloy_network::TransactionBuilder; use alloy_primitives::{Address, Bytes, TxHash, B256}; -use alloy_rpc_types::{BlockNumberOrTag, TransactionInfo}; -use alloy_rpc_types_eth::transaction::TransactionRequest; +use alloy_rpc_types_eth::{transaction::TransactionRequest, BlockNumberOrTag, TransactionInfo}; use futures::Future; use reth_primitives::{Receipt, SealedBlockWithSenders, TransactionMeta, TransactionSigned}; use reth_provider::{BlockNumReader, BlockReaderIdExt, ReceiptProvider, TransactionsProvider}; diff --git a/crates/rpc/rpc-eth-api/src/pubsub.rs b/crates/rpc/rpc-eth-api/src/pubsub.rs index b70dacb26fa..ecbb1fe9a83 100644 --- a/crates/rpc/rpc-eth-api/src/pubsub.rs +++ b/crates/rpc/rpc-eth-api/src/pubsub.rs @@ -1,7 +1,7 @@ //! `eth_` RPC API for pubsub subscription. use alloy_json_rpc::RpcObject; -use alloy_rpc_types::pubsub::{Params, SubscriptionKind}; +use alloy_rpc_types_eth::pubsub::{Params, SubscriptionKind}; use jsonrpsee::proc_macros::rpc; /// Ethereum pub-sub rpc interface. diff --git a/crates/rpc/rpc-eth-api/src/types.rs b/crates/rpc/rpc-eth-api/src/types.rs index 620f4523d21..b75bce026fb 100644 --- a/crates/rpc/rpc-eth-api/src/types.rs +++ b/crates/rpc/rpc-eth-api/src/types.rs @@ -6,7 +6,7 @@ use std::{ }; use alloy_network::Network; -use alloy_rpc_types::Block; +use alloy_rpc_types_eth::Block; use reth_rpc_types_compat::TransactionCompat; use crate::{AsEthApiError, FromEthApiError, FromEvmError}; @@ -22,7 +22,7 @@ pub trait EthApiTypes: Send + Sync + Clone { + Send + Sync; /// Blockchain primitive types, specific to network, e.g. block and transaction. - type NetworkTypes: Network; + type NetworkTypes: Network; /// Conversion methods for transaction RPC type. type TransactionCompat: Send + Sync + Clone + fmt::Debug; diff --git a/crates/rpc/rpc-eth-types/Cargo.toml b/crates/rpc/rpc-eth-types/Cargo.toml index 80901bcf812..9b38ed89724 100644 --- a/crates/rpc/rpc-eth-types/Cargo.toml +++ b/crates/rpc/rpc-eth-types/Cargo.toml @@ -35,7 +35,6 @@ alloy-rpc-types-eth.workspace = true revm.workspace = true revm-inspectors.workspace = true revm-primitives = { workspace = true, features = ["dev"] } -alloy-rpc-types.workspace = true alloy-eips.workspace = true # rpc diff --git a/crates/rpc/rpc-eth-types/src/cache/db.rs b/crates/rpc/rpc-eth-types/src/cache/db.rs index 627fd2b2df7..50fd4b04625 100644 --- a/crates/rpc/rpc-eth-types/src/cache/db.rs +++ b/crates/rpc/rpc-eth-types/src/cache/db.rs @@ -116,7 +116,7 @@ impl reth_storage_api::BlockHashReader for StateProviderTraitObjWrapper<'_> { fn convert_block_hash( &self, - hash_or_number: alloy_rpc_types::BlockHashOrNumber, + hash_or_number: alloy_rpc_types_eth::BlockHashOrNumber, ) -> reth_errors::ProviderResult> { self.0.convert_block_hash(hash_or_number) } diff --git a/crates/rpc/rpc-eth-types/src/error.rs b/crates/rpc/rpc-eth-types/src/error.rs index 9241e9e0b6b..641cbc88291 100644 --- a/crates/rpc/rpc-eth-types/src/error.rs +++ b/crates/rpc/rpc-eth-types/src/error.rs @@ -4,7 +4,7 @@ use std::time::Duration; use alloy_eips::BlockId; use alloy_primitives::{Address, Bytes, U256}; -use alloy_rpc_types::{error::EthRpcErrorCode, request::TransactionInputError, BlockError}; +use alloy_rpc_types_eth::{error::EthRpcErrorCode, request::TransactionInputError, BlockError}; use alloy_sol_types::decode_revert_reason; use reth_errors::RethError; use reth_primitives::revm_primitives::InvalidHeader; diff --git a/crates/rpc/rpc-eth-types/src/fee_history.rs b/crates/rpc/rpc-eth-types/src/fee_history.rs index 7692d47de99..6c8b66246f3 100644 --- a/crates/rpc/rpc-eth-types/src/fee_history.rs +++ b/crates/rpc/rpc-eth-types/src/fee_history.rs @@ -8,7 +8,7 @@ use std::{ use alloy_eips::eip1559::calc_next_block_base_fee; use alloy_primitives::B256; -use alloy_rpc_types::TxGasAndReward; +use alloy_rpc_types_eth::TxGasAndReward; use futures::{ future::{Fuse, FusedFuture}, FutureExt, Stream, StreamExt, diff --git a/crates/rpc/rpc-eth-types/src/gas_oracle.rs b/crates/rpc/rpc-eth-types/src/gas_oracle.rs index 9da373376bd..d73cd72b650 100644 --- a/crates/rpc/rpc-eth-types/src/gas_oracle.rs +++ b/crates/rpc/rpc-eth-types/src/gas_oracle.rs @@ -4,7 +4,7 @@ use alloy_consensus::constants::GWEI_TO_WEI; use alloy_eips::BlockNumberOrTag; use alloy_primitives::{B256, U256}; -use alloy_rpc_types::BlockId; +use alloy_rpc_types_eth::BlockId; use derive_more::{Deref, DerefMut, From, Into}; use itertools::Itertools; use reth_rpc_server_types::constants; diff --git a/crates/rpc/rpc-eth-types/src/logs_utils.rs b/crates/rpc/rpc-eth-types/src/logs_utils.rs index aa132675c93..3e7c9db6d68 100644 --- a/crates/rpc/rpc-eth-types/src/logs_utils.rs +++ b/crates/rpc/rpc-eth-types/src/logs_utils.rs @@ -4,7 +4,7 @@ use alloy_eips::BlockNumHash; use alloy_primitives::TxHash; -use alloy_rpc_types::{FilteredParams, Log}; +use alloy_rpc_types_eth::{FilteredParams, Log}; use reth_chainspec::ChainInfo; use reth_errors::ProviderError; use reth_primitives::{Receipt, SealedBlockWithSenders}; @@ -179,7 +179,7 @@ pub fn get_filter_block_range( #[cfg(test)] mod tests { - use alloy_rpc_types::Filter; + use alloy_rpc_types_eth::Filter; use super::*; @@ -242,8 +242,8 @@ mod tests { let start_block = info.best_number; let (from_block_number, to_block_number) = get_filter_block_range( - from_block.and_then(alloy_rpc_types::BlockNumberOrTag::as_number), - to_block.and_then(alloy_rpc_types::BlockNumberOrTag::as_number), + from_block.and_then(alloy_rpc_types_eth::BlockNumberOrTag::as_number), + to_block.and_then(alloy_rpc_types_eth::BlockNumberOrTag::as_number), start_block, info, ); diff --git a/crates/rpc/rpc-eth-types/src/receipt.rs b/crates/rpc/rpc-eth-types/src/receipt.rs index 0734b547ec8..247b4449ef5 100644 --- a/crates/rpc/rpc-eth-types/src/receipt.rs +++ b/crates/rpc/rpc-eth-types/src/receipt.rs @@ -2,7 +2,7 @@ use alloy_consensus::{ReceiptEnvelope, Transaction}; use alloy_primitives::{Address, TxKind}; -use alloy_rpc_types::{Log, ReceiptWithBloom, TransactionReceipt}; +use alloy_rpc_types_eth::{Log, ReceiptWithBloom, TransactionReceipt}; use reth_primitives::{Receipt, TransactionMeta, TransactionSigned, TxType}; use revm_primitives::calc_blob_gasprice; @@ -59,7 +59,7 @@ pub fn build_receipt( }) .collect(); - let rpc_receipt = alloy_rpc_types::Receipt { + let rpc_receipt = alloy_rpc_types_eth::Receipt { status: receipt.success.into(), cumulative_gas_used: receipt.cumulative_gas_used as u128, logs, diff --git a/crates/rpc/rpc-eth-types/src/revm_utils.rs b/crates/rpc/rpc-eth-types/src/revm_utils.rs index ee3c6e7d9a7..782ef569796 100644 --- a/crates/rpc/rpc-eth-types/src/revm_utils.rs +++ b/crates/rpc/rpc-eth-types/src/revm_utils.rs @@ -1,7 +1,7 @@ //! utilities for working with revm use alloy_primitives::{Address, B256, U256}; -use alloy_rpc_types::{ +use alloy_rpc_types_eth::{ state::{AccountOverride, StateOverride}, BlockOverrides, }; diff --git a/crates/rpc/rpc-eth-types/src/simulate.rs b/crates/rpc/rpc-eth-types/src/simulate.rs index d881b854a79..b2a9a5e62ed 100644 --- a/crates/rpc/rpc-eth-types/src/simulate.rs +++ b/crates/rpc/rpc-eth-types/src/simulate.rs @@ -2,11 +2,11 @@ use alloy_consensus::{Transaction as _, TxEip4844Variant, TxType, TypedTransaction}; use alloy_primitives::PrimitiveSignature as Signature; -use alloy_rpc_types::{ +use alloy_rpc_types_eth::{ simulate::{SimCallResult, SimulateError, SimulatedBlock}, + transaction::TransactionRequest, Block, BlockTransactionsKind, }; -use alloy_rpc_types_eth::transaction::TransactionRequest; use jsonrpsee_types::ErrorObject; use reth_primitives::{ proofs::{calculate_receipt_root, calculate_transaction_root}, @@ -225,7 +225,7 @@ pub fn build_block( .into_iter() .map(|log| { log_index += 1; - alloy_rpc_types::Log { + alloy_rpc_types_eth::Log { inner: log, log_index: Some(log_index - 1), transaction_index: Some(transaction_index as u64), diff --git a/crates/rpc/rpc-eth-types/src/transaction.rs b/crates/rpc/rpc-eth-types/src/transaction.rs index 7d2237a1b7f..bfff1cafead 100644 --- a/crates/rpc/rpc-eth-types/src/transaction.rs +++ b/crates/rpc/rpc-eth-types/src/transaction.rs @@ -3,7 +3,7 @@ //! Transaction wrapper that labels transaction with its origin. use alloy_primitives::B256; -use alloy_rpc_types::TransactionInfo; +use alloy_rpc_types_eth::TransactionInfo; use reth_primitives::TransactionSignedEcRecovered; use reth_rpc_types_compat::{ transaction::{from_recovered, from_recovered_with_block_context}, diff --git a/crates/rpc/rpc-testing-util/Cargo.toml b/crates/rpc/rpc-testing-util/Cargo.toml index e5c57502e2b..149073b1c68 100644 --- a/crates/rpc/rpc-testing-util/Cargo.toml +++ b/crates/rpc/rpc-testing-util/Cargo.toml @@ -19,7 +19,6 @@ reth-rpc-api = { workspace = true, features = ["client"] } # ethereum alloy-primitives.workspace = true alloy-rpc-types-eth.workspace = true -alloy-rpc-types.workspace = true alloy-rpc-types-trace.workspace = true alloy-eips.workspace = true diff --git a/crates/rpc/rpc-testing-util/src/debug.rs b/crates/rpc/rpc-testing-util/src/debug.rs index d4c7dce860b..a18771af3b0 100644 --- a/crates/rpc/rpc-testing-util/src/debug.rs +++ b/crates/rpc/rpc-testing-util/src/debug.rs @@ -8,8 +8,7 @@ use std::{ use alloy_eips::BlockId; use alloy_primitives::{TxHash, B256}; -use alloy_rpc_types::{Block, Transaction}; -use alloy_rpc_types_eth::transaction::TransactionRequest; +use alloy_rpc_types_eth::{transaction::TransactionRequest, Block, Transaction}; use alloy_rpc_types_trace::{ common::TraceResult, geth::{GethDebugTracerType, GethDebugTracingOptions, GethTrace}, diff --git a/crates/rpc/rpc-testing-util/src/trace.rs b/crates/rpc/rpc-testing-util/src/trace.rs index 097d582df45..b963fa69d8b 100644 --- a/crates/rpc/rpc-testing-util/src/trace.rs +++ b/crates/rpc/rpc-testing-util/src/trace.rs @@ -2,8 +2,7 @@ use alloy_eips::BlockId; use alloy_primitives::{map::HashSet, Bytes, TxHash, B256}; -use alloy_rpc_types::Index; -use alloy_rpc_types_eth::transaction::TransactionRequest; +use alloy_rpc_types_eth::{transaction::TransactionRequest, Index}; use alloy_rpc_types_trace::{ filter::TraceFilter, parity::{LocalizedTransactionTrace, TraceResults, TraceType}, diff --git a/crates/rpc/rpc-testing-util/tests/it/trace.rs b/crates/rpc/rpc-testing-util/tests/it/trace.rs index b0fccefbb46..4c5d2ccb2a6 100644 --- a/crates/rpc/rpc-testing-util/tests/it/trace.rs +++ b/crates/rpc/rpc-testing-util/tests/it/trace.rs @@ -1,7 +1,7 @@ //! Integration tests for the trace API. use alloy_primitives::map::HashSet; -use alloy_rpc_types::{Block, Transaction}; +use alloy_rpc_types_eth::{Block, Transaction}; use alloy_rpc_types_trace::{ filter::TraceFilter, parity::TraceType, tracerequest::TraceCallRequest, }; diff --git a/crates/rpc/rpc-types-compat/Cargo.toml b/crates/rpc/rpc-types-compat/Cargo.toml index b9a9e5f0361..2e45d210d17 100644 --- a/crates/rpc/rpc-types-compat/Cargo.toml +++ b/crates/rpc/rpc-types-compat/Cargo.toml @@ -17,10 +17,10 @@ reth-primitives.workspace = true reth-trie-common.workspace = true # ethereum +alloy-serde.workspace = true alloy-eips.workspace = true alloy-primitives.workspace = true alloy-rlp.workspace = true -alloy-rpc-types.workspace = true alloy-rpc-types-eth = { workspace = true, default-features = false, features = ["serde"] } alloy-rpc-types-engine.workspace = true alloy-consensus.workspace = true diff --git a/crates/rpc/rpc-types-compat/src/block.rs b/crates/rpc/rpc-types-compat/src/block.rs index 3b297ba0bc3..cfa1561c634 100644 --- a/crates/rpc/rpc-types-compat/src/block.rs +++ b/crates/rpc/rpc-types-compat/src/block.rs @@ -3,7 +3,7 @@ use alloy_consensus::Sealed; use alloy_primitives::{B256, U256}; use alloy_rlp::Encodable; -use alloy_rpc_types::{ +use alloy_rpc_types_eth::{ Block, BlockError, BlockTransactions, BlockTransactionsKind, Header, TransactionInfo, }; use reth_primitives::{Block as PrimitiveBlock, BlockWithSenders, Withdrawals}; diff --git a/crates/rpc/rpc-types-compat/src/proof.rs b/crates/rpc/rpc-types-compat/src/proof.rs index 34128801f8d..b860bc3491d 100644 --- a/crates/rpc/rpc-types-compat/src/proof.rs +++ b/crates/rpc/rpc-types-compat/src/proof.rs @@ -1,7 +1,7 @@ //! Compatibility functions for rpc proof related types. -use alloy_rpc_types::serde_helpers::JsonStorageKey; use alloy_rpc_types_eth::{EIP1186AccountProofResponse, EIP1186StorageProof}; +use alloy_serde::JsonStorageKey; use reth_trie_common::{AccountProof, StorageProof}; /// Creates a new rpc storage proof from a primitive storage proof type. diff --git a/crates/rpc/rpc-types-compat/src/transaction/mod.rs b/crates/rpc/rpc-types-compat/src/transaction/mod.rs index 27f0b0288d5..cfbaaa622fb 100644 --- a/crates/rpc/rpc-types-compat/src/transaction/mod.rs +++ b/crates/rpc/rpc-types-compat/src/transaction/mod.rs @@ -3,7 +3,7 @@ use std::fmt; use alloy_consensus::Transaction as _; -use alloy_rpc_types::{ +use alloy_rpc_types_eth::{ request::{TransactionInput, TransactionRequest}, TransactionInfo, }; diff --git a/crates/rpc/rpc/Cargo.toml b/crates/rpc/rpc/Cargo.toml index 876467d1f4b..ac3a548f9b5 100644 --- a/crates/rpc/rpc/Cargo.toml +++ b/crates/rpc/rpc/Cargo.toml @@ -47,14 +47,15 @@ alloy-genesis.workspace = true alloy-network.workspace = true alloy-primitives.workspace = true alloy-rlp.workspace = true -alloy-rpc-types.workspace = true alloy-rpc-types-beacon.workspace = true -alloy-rpc-types-eth = { workspace = true, features = ["jsonrpsee-types"] } +alloy-rpc-types.workspace = true +alloy-rpc-types-eth = { workspace = true, features = ["jsonrpsee-types", "serde"] } alloy-rpc-types-debug.workspace = true alloy-rpc-types-trace.workspace = true alloy-rpc-types-mev.workspace = true alloy-rpc-types-txpool.workspace = true alloy-rpc-types-admin.workspace = true +alloy-rpc-types-engine.workspace = true alloy-serde.workspace = true revm = { workspace = true, features = [ "optional_block_gas_limit", diff --git a/crates/rpc/rpc/src/debug.rs b/crates/rpc/rpc/src/debug.rs index 5b7e161691c..4404515e03c 100644 --- a/crates/rpc/rpc/src/debug.rs +++ b/crates/rpc/rpc/src/debug.rs @@ -1,11 +1,11 @@ use alloy_eips::{eip2718::Encodable2718, BlockId, BlockNumberOrTag}; use alloy_primitives::{Address, Bytes, B256, U256}; use alloy_rlp::{Decodable, Encodable}; -use alloy_rpc_types::{ - state::EvmOverrides, Block as RpcBlock, BlockError, Bundle, StateContext, TransactionInfo, -}; use alloy_rpc_types_debug::ExecutionWitness; -use alloy_rpc_types_eth::transaction::TransactionRequest; +use alloy_rpc_types_eth::{ + state::EvmOverrides, transaction::TransactionRequest, Block as RpcBlock, BlockError, Bundle, + StateContext, TransactionInfo, +}; use alloy_rpc_types_trace::geth::{ call::FlatCallFrame, BlockTraceResult, FourByteFrame, GethDebugBuiltInTracerType, GethDebugTracerType, GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace, diff --git a/crates/rpc/rpc/src/engine.rs b/crates/rpc/rpc/src/engine.rs index ac4de7c74e1..fca78d62d63 100644 --- a/crates/rpc/rpc/src/engine.rs +++ b/crates/rpc/rpc/src/engine.rs @@ -1,9 +1,9 @@ use alloy_eips::{BlockId, BlockNumberOrTag}; use alloy_primitives::{Address, Bytes, B256, U256, U64}; -use alloy_rpc_types::{ - state::StateOverride, BlockOverrides, EIP1186AccountProofResponse, Filter, Log, SyncStatus, +use alloy_rpc_types_eth::{ + state::StateOverride, transaction::TransactionRequest, BlockOverrides, + EIP1186AccountProofResponse, Filter, Log, SyncStatus, }; -use alloy_rpc_types_eth::transaction::TransactionRequest; use alloy_serde::JsonStorageKey; use jsonrpsee::core::RpcResult as Result; use reth_rpc_api::{EngineEthApiServer, EthApiServer, EthFilterApiServer}; diff --git a/crates/rpc/rpc/src/eth/bundle.rs b/crates/rpc/rpc/src/eth/bundle.rs index 4d72efd1f8c..db8c01c5c3b 100644 --- a/crates/rpc/rpc/src/eth/bundle.rs +++ b/crates/rpc/rpc/src/eth/bundle.rs @@ -106,7 +106,7 @@ where .into()) } - let block_id: alloy_rpc_types::BlockId = state_block_number.into(); + let block_id: alloy_rpc_types_eth::BlockId = state_block_number.into(); // Note: the block number is considered the `parent` block: let (cfg, mut block_env, at) = self.eth_api().evm_env_at(block_id).await?; diff --git a/crates/rpc/rpc/src/eth/filter.rs b/crates/rpc/rpc/src/eth/filter.rs index 3d05cdc727f..589cb801e2c 100644 --- a/crates/rpc/rpc/src/eth/filter.rs +++ b/crates/rpc/rpc/src/eth/filter.rs @@ -10,7 +10,7 @@ use std::{ }; use alloy_primitives::TxHash; -use alloy_rpc_types::{ +use alloy_rpc_types_eth::{ BlockNumHash, Filter, FilterBlockOption, FilterChanges, FilterId, FilteredParams, Log, PendingTransactionFilterKind, }; diff --git a/crates/rpc/rpc/src/eth/helpers/block.rs b/crates/rpc/rpc/src/eth/helpers/block.rs index 1e2d1802e0d..fd3b9db9da2 100644 --- a/crates/rpc/rpc/src/eth/helpers/block.rs +++ b/crates/rpc/rpc/src/eth/helpers/block.rs @@ -1,6 +1,6 @@ //! Contains RPC handler implementations specific to blocks. -use alloy_rpc_types::{BlockId, TransactionReceipt}; +use alloy_rpc_types_eth::{BlockId, TransactionReceipt}; use reth_primitives::TransactionMeta; use reth_provider::{BlockReaderIdExt, HeaderProvider}; use reth_rpc_eth_api::{ diff --git a/crates/rpc/rpc/src/eth/helpers/types.rs b/crates/rpc/rpc/src/eth/helpers/types.rs index af0a3cbef8f..19ffc55b398 100644 --- a/crates/rpc/rpc/src/eth/helpers/types.rs +++ b/crates/rpc/rpc/src/eth/helpers/types.rs @@ -2,7 +2,7 @@ use alloy_consensus::{Signed, Transaction as _, TxEip4844Variant, TxEnvelope}; use alloy_network::{Ethereum, Network}; -use alloy_rpc_types::{Transaction, TransactionInfo}; +use alloy_rpc_types_eth::{Transaction, TransactionInfo}; use reth_primitives::{TransactionSigned, TransactionSignedEcRecovered}; use reth_rpc_types_compat::TransactionCompat; diff --git a/crates/rpc/rpc/src/eth/pubsub.rs b/crates/rpc/rpc/src/eth/pubsub.rs index 922694cdba6..0702e3147ce 100644 --- a/crates/rpc/rpc/src/eth/pubsub.rs +++ b/crates/rpc/rpc/src/eth/pubsub.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use alloy_primitives::TxHash; -use alloy_rpc_types::{ +use alloy_rpc_types_eth::{ pubsub::{ Params, PubSubSyncStatus, SubscriptionKind, SubscriptionResult as EthSubscriptionResult, SyncStatusMetadata, diff --git a/crates/rpc/rpc/src/eth/sim_bundle.rs b/crates/rpc/rpc/src/eth/sim_bundle.rs index 67fd5181759..f49d7984f8b 100644 --- a/crates/rpc/rpc/src/eth/sim_bundle.rs +++ b/crates/rpc/rpc/src/eth/sim_bundle.rs @@ -2,7 +2,7 @@ use alloy_eips::BlockNumberOrTag; use alloy_primitives::U256; -use alloy_rpc_types::BlockId; +use alloy_rpc_types_eth::BlockId; use alloy_rpc_types_mev::{ BundleItem, Inclusion, Privacy, RefundConfig, SendBundleRequest, SimBundleLogs, SimBundleOverrides, SimBundleResponse, Validity, diff --git a/crates/rpc/rpc/src/otterscan.rs b/crates/rpc/rpc/src/otterscan.rs index 0585ef76459..d19dcf4d609 100644 --- a/crates/rpc/rpc/src/otterscan.rs +++ b/crates/rpc/rpc/src/otterscan.rs @@ -2,7 +2,7 @@ use alloy_consensus::Transaction; use alloy_eips::{BlockId, BlockNumberOrTag}; use alloy_network::{ReceiptResponse, TransactionResponse}; use alloy_primitives::{Address, Bytes, TxHash, B256, U256}; -use alloy_rpc_types::{BlockTransactions, Header, TransactionReceipt}; +use alloy_rpc_types_eth::{BlockTransactions, Header, TransactionReceipt}; use alloy_rpc_types_trace::{ otterscan::{ BlockDetails, ContractCreator, InternalOperation, OperationType, OtsBlockTransactions, diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 38c73b0f516..41bc0ad2098 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -1,10 +1,10 @@ use alloy_eips::BlockId; use alloy_primitives::{map::HashSet, Bytes, B256, U256}; -use alloy_rpc_types::{ +use alloy_rpc_types_eth::{ state::{EvmOverrides, StateOverride}, + transaction::TransactionRequest, BlockOverrides, Index, }; -use alloy_rpc_types_eth::transaction::TransactionRequest; use alloy_rpc_types_trace::{ filter::TraceFilter, opcode::{BlockOpcodeGas, TransactionOpcodeGas}, diff --git a/crates/rpc/rpc/src/validation.rs b/crates/rpc/rpc/src/validation.rs index 5d7d00f354b..919fe2d8591 100644 --- a/crates/rpc/rpc/src/validation.rs +++ b/crates/rpc/rpc/src/validation.rs @@ -1,12 +1,12 @@ use alloy_consensus::{BlobTransactionValidationError, EnvKzgSettings, Transaction}; use alloy_eips::eip4844::kzg_to_versioned_hash; -use alloy_rpc_types::engine::{ - BlobsBundleV1, CancunPayloadFields, ExecutionPayload, ExecutionPayloadSidecar, -}; use alloy_rpc_types_beacon::relay::{ BidTrace, BuilderBlockValidationRequest, BuilderBlockValidationRequestV2, BuilderBlockValidationRequestV3, BuilderBlockValidationRequestV4, }; +use alloy_rpc_types_engine::{ + BlobsBundleV1, CancunPayloadFields, ExecutionPayload, ExecutionPayloadSidecar, +}; use async_trait::async_trait; use jsonrpsee::core::RpcResult; use reth_chainspec::{ChainSpecProvider, EthereumHardforks}; diff --git a/examples/custom-inspector/Cargo.toml b/examples/custom-inspector/Cargo.toml index e92e90fb9d1..ee6f887e64c 100644 --- a/examples/custom-inspector/Cargo.toml +++ b/examples/custom-inspector/Cargo.toml @@ -8,7 +8,7 @@ license.workspace = true [dependencies] reth.workspace = true reth-node-ethereum.workspace = true -alloy-rpc-types.workspace = true +alloy-rpc-types-eth.workspace = true clap = { workspace = true, features = ["derive"] } futures-util.workspace = true alloy-primitives.workspace = true diff --git a/examples/custom-inspector/src/main.rs b/examples/custom-inspector/src/main.rs index 272da63a9b9..67863d00e1e 100644 --- a/examples/custom-inspector/src/main.rs +++ b/examples/custom-inspector/src/main.rs @@ -12,7 +12,7 @@ use alloy_eips::BlockNumberOrTag; use alloy_primitives::Address; -use alloy_rpc_types::state::EvmOverrides; +use alloy_rpc_types_eth::state::EvmOverrides; use clap::Parser; use futures_util::StreamExt; use reth::{ diff --git a/examples/db-access/Cargo.toml b/examples/db-access/Cargo.toml index 0a7ef9bb6b2..3310d1cbd67 100644 --- a/examples/db-access/Cargo.toml +++ b/examples/db-access/Cargo.toml @@ -14,7 +14,7 @@ reth-provider.workspace = true reth-node-ethereum.workspace = true reth-node-types.workspace = true -alloy-rpc-types.workspace = true +alloy-rpc-types-eth.workspace = true alloy-primitives.workspace = true diff --git a/examples/db-access/src/main.rs b/examples/db-access/src/main.rs index 5772461bd7a..c3e30fa1cee 100644 --- a/examples/db-access/src/main.rs +++ b/examples/db-access/src/main.rs @@ -1,5 +1,5 @@ use alloy_primitives::{Address, Sealable, B256}; -use alloy_rpc_types::{Filter, FilteredParams}; +use alloy_rpc_types_eth::{Filter, FilteredParams}; use reth_chainspec::ChainSpecBuilder; use reth_db::{open_db_read_only, DatabaseEnv}; use reth_node_ethereum::EthereumNode; From 462540fa30681bff08fea1dda37aa231e4da521f Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Fri, 8 Nov 2024 14:24:02 +0400 Subject: [PATCH 068/211] fix: pending transaction ordering (#12382) Co-authored-by: Matthias Seitz --- Cargo.lock | 1 + crates/optimism/node/Cargo.toml | 1 + crates/optimism/node/tests/e2e/p2p.rs | 15 ++++ crates/transaction-pool/src/pool/pending.rs | 79 +++++++++++------ crates/transaction-pool/src/pool/txpool.rs | 97 +++++++++++++++++---- 5 files changed, 146 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d6169e25f5f..84b660cd737 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8241,6 +8241,7 @@ dependencies = [ "alloy-rpc-types-engine", "clap", "eyre", + "futures", "op-alloy-consensus", "op-alloy-rpc-types-engine", "parking_lot", diff --git a/crates/optimism/node/Cargo.toml b/crates/optimism/node/Cargo.toml index 7674cbd37c0..07315a07f4e 100644 --- a/crates/optimism/node/Cargo.toml +++ b/crates/optimism/node/Cargo.toml @@ -66,6 +66,7 @@ tokio.workspace = true alloy-primitives.workspace = true alloy-genesis.workspace = true op-alloy-consensus.workspace = true +futures.workspace = true [features] optimism = [ diff --git a/crates/optimism/node/tests/e2e/p2p.rs b/crates/optimism/node/tests/e2e/p2p.rs index 30affa9bafb..6240b781472 100644 --- a/crates/optimism/node/tests/e2e/p2p.rs +++ b/crates/optimism/node/tests/e2e/p2p.rs @@ -1,5 +1,6 @@ use crate::utils::{advance_chain, setup}; use alloy_rpc_types_engine::PayloadStatusEnum; +use futures::StreamExt; use reth::blockchain_tree::error::BlockchainTreeError; use std::sync::Arc; use tokio::sync::Mutex; @@ -25,6 +26,19 @@ async fn can_sync() -> eyre::Result<()> { canonical_payload_chain.iter().map(|p| p.0.block().hash()).collect::>(); // On second node, sync optimistically up to block number 88a + second_node + .engine_api + .update_optimistic_forkchoice(canonical_chain[tip_index - reorg_depth - 1]) + .await?; + second_node + .wait_block( + (tip - reorg_depth - 1) as u64, + canonical_chain[tip_index - reorg_depth - 1], + true, + ) + .await?; + // We send FCU twice to ensure that pool receives canonical chain update on the second FCU + // This is required because notifications are not sent during backfill sync second_node .engine_api .update_optimistic_forkchoice(canonical_chain[tip_index - reorg_depth]) @@ -32,6 +46,7 @@ async fn can_sync() -> eyre::Result<()> { second_node .wait_block((tip - reorg_depth) as u64, canonical_chain[tip_index - reorg_depth], true) .await?; + second_node.engine_api.canonical_stream.next().await.unwrap(); // On third node, sync optimistically up to block number 90a third_node.engine_api.update_optimistic_forkchoice(canonical_chain[tip_index]).await?; diff --git a/crates/transaction-pool/src/pool/pending.rs b/crates/transaction-pool/src/pool/pending.rs index c9cfd85e288..357cea48974 100644 --- a/crates/transaction-pool/src/pool/pending.rs +++ b/crates/transaction-pool/src/pool/pending.rs @@ -8,7 +8,7 @@ use crate::{ }; use std::{ cmp::Ordering, - collections::{BTreeMap, BTreeSet}, + collections::{hash_map::Entry, BTreeMap, BTreeSet, HashMap}, ops::Bound::Unbounded, sync::Arc, }; @@ -38,14 +38,10 @@ pub struct PendingPool { all: BTreeSet>, /// The highest nonce transactions for each sender - like the `independent` set, but the /// highest instead of lowest nonce. - /// - /// Sorted by their scoring value. - highest_nonces: BTreeSet>, + highest_nonces: HashMap>, /// Independent transactions that can be included directly and don't require other /// transactions. - /// - /// Sorted by their scoring value. - independent_transactions: BTreeSet>, + independent_transactions: HashMap>, /// Keeps track of the size of this pool. /// /// See also [`PoolTransaction::size`](crate::traits::PoolTransaction::size). @@ -108,7 +104,7 @@ impl PendingPool { pub(crate) fn best(&self) -> BestTransactions { BestTransactions { all: self.by_id.clone(), - independent: self.independent_transactions.clone(), + independent: self.independent_transactions.values().cloned().collect(), invalid: Default::default(), new_transaction_receiver: Some(self.new_transaction_notifier.subscribe()), skip_blobs: false, @@ -255,17 +251,26 @@ impl PendingPool { /// Updates the independent transaction and highest nonces set, assuming the given transaction /// is being _added_ to the pool. fn update_independents_and_highest_nonces(&mut self, tx: &PendingTransaction) { - let ancestor_id = tx.transaction.id().unchecked_ancestor(); - if let Some(ancestor) = ancestor_id.and_then(|id| self.by_id.get(&id)) { - // the transaction already has an ancestor, so we only need to ensure that the - // highest nonces set actually contains the highest nonce for that sender - self.highest_nonces.remove(ancestor); - } else { - // If there's __no__ ancestor in the pool, then this transaction is independent, this is - // guaranteed because this pool is gapless. - self.independent_transactions.insert(tx.clone()); + match self.highest_nonces.entry(tx.transaction.sender_id()) { + Entry::Occupied(mut entry) => { + if entry.get().transaction.nonce() < tx.transaction.nonce() { + *entry.get_mut() = tx.clone(); + } + } + Entry::Vacant(entry) => { + entry.insert(tx.clone()); + } + } + match self.independent_transactions.entry(tx.transaction.sender_id()) { + Entry::Occupied(mut entry) => { + if entry.get().transaction.nonce() > tx.transaction.nonce() { + *entry.get_mut() = tx.clone(); + } + } + Entry::Vacant(entry) => { + entry.insert(tx.clone()); + } } - self.highest_nonces.insert(tx.clone()); } /// Returns the ancestor the given transaction, the transaction with `nonce - 1`. @@ -306,6 +311,7 @@ impl PendingPool { // send the new transaction to any existing pendingpool static file iterators if self.new_transaction_notifier.receiver_count() > 0 { + dbg!("notify"); let _ = self.new_transaction_notifier.send(tx.clone()); } @@ -320,19 +326,26 @@ impl PendingPool { &mut self, id: &TransactionId, ) -> Option>> { - // mark the next as independent if it exists - if let Some(unlocked) = self.get(&id.descendant()) { - self.independent_transactions.insert(unlocked.clone()); + if let Some(lowest) = self.independent_transactions.get(&id.sender) { + if lowest.transaction.nonce() == id.nonce { + self.independent_transactions.remove(&id.sender); + // mark the next as independent if it exists + if let Some(unlocked) = self.get(&id.descendant()) { + self.independent_transactions.insert(id.sender, unlocked.clone()); + } + } } + let tx = self.by_id.remove(id)?; self.size_of -= tx.transaction.size(); self.all.remove(&tx); - self.independent_transactions.remove(&tx); - // switch out for the next ancestor if there is one - if self.highest_nonces.remove(&tx) { + if let Some(highest) = self.highest_nonces.get(&id.sender) { + if highest.transaction.nonce() == id.nonce { + self.highest_nonces.remove(&id.sender); + } if let Some(ancestor) = self.ancestor(id) { - self.highest_nonces.insert(ancestor.clone()); + self.highest_nonces.insert(id.sender, ancestor.clone()); } } Some(tx.transaction) @@ -398,8 +411,12 @@ impl PendingPool { // we can reuse the temp array removed.clear(); + // we prefer removing transactions with lower ordering + let mut worst_transactions = self.highest_nonces.values().collect::>(); + worst_transactions.sort(); + // loop through the highest nonces set, removing transactions until we reach the limit - for tx in &self.highest_nonces { + for tx in worst_transactions { // return early if the pool is under limits if !limit.is_exceeded(original_length - total_removed, original_size - total_size) || non_local_senders == 0 @@ -513,6 +530,12 @@ impl PendingPool { self.by_id.get(id) } + /// Returns a reference to the independent transactions in the pool + #[cfg(test)] + pub(crate) const fn independent(&self) -> &HashMap> { + &self.independent_transactions + } + /// Asserts that the bijection between `by_id` and `all` is valid. #[cfg(any(test, feature = "test-utils"))] pub(crate) fn assert_invariants(&self) { @@ -668,7 +691,7 @@ mod tests { // First transaction should be evicted. assert_eq!( - pool.highest_nonces.iter().next().map(|tx| *tx.transaction.hash()), + pool.highest_nonces.values().min().map(|tx| *tx.transaction.hash()), Some(*t.hash()) ); @@ -723,7 +746,7 @@ mod tests { .collect::>(); let actual_highest_nonces = pool .highest_nonces - .iter() + .values() .map(|tx| (tx.transaction.sender(), tx.transaction.nonce())) .collect::>(); assert_eq!(expected_highest_nonces, actual_highest_nonces); diff --git a/crates/transaction-pool/src/pool/txpool.rs b/crates/transaction-pool/src/pool/txpool.rs index 1258f4a270a..1d35f742ab6 100644 --- a/crates/transaction-pool/src/pool/txpool.rs +++ b/crates/transaction-pool/src/pool/txpool.rs @@ -1676,29 +1676,17 @@ impl AllTransactions { // The next transaction of this sender let on_chain_id = TransactionId::new(transaction.sender_id(), on_chain_nonce); { - // get all transactions of the sender's account - let mut descendants = self.descendant_txs_mut(&on_chain_id).peekable(); - // Tracks the next nonce we expect if the transactions are gapless let mut next_nonce = on_chain_id.nonce; // We need to find out if the next transaction of the sender is considered pending - let mut has_parked_ancestor = if ancestor.is_none() { - // the new transaction is the next one - false - } else { - // The transaction was added above so the _inclusive_ descendants iterator - // returns at least 1 tx. - let (id, tx) = descendants.peek().expect("includes >= 1"); - if id.nonce < inserted_tx_id.nonce { - !tx.state.is_pending() - } else { - true - } - }; + // The direct descendant has _no_ parked ancestors because the `on_chain_nonce` is + // pending, so we can set this to `false` + let mut has_parked_ancestor = false; - // Traverse all transactions of the sender and update existing transactions - for (id, tx) in descendants { + // Traverse all future transactions of the sender starting with the on chain nonce, and + // update existing transactions: `[on_chain_nonce,..]` + for (id, tx) in self.descendant_txs_mut(&on_chain_id) { let current_pool = tx.subpool; // If there's a nonce gap, we can shortcircuit @@ -2902,7 +2890,7 @@ mod tests { pool.update_basefee(pool_base_fee); // 2 txs, that should put the pool over the size limit but not max txs - let a_txs = MockTransactionSet::dependent(a_sender, 0, 2, TxType::Eip1559) + let a_txs = MockTransactionSet::dependent(a_sender, 0, 3, TxType::Eip1559) .into_iter() .map(|mut tx| { tx.set_size(default_limits.max_size / 2 + 1); @@ -3257,4 +3245,75 @@ mod tests { vec![1, 2, 3] ); } + + #[test] + fn test_pending_ordering() { + let mut f = MockTransactionFactory::default(); + let mut pool = TxPool::new(MockOrdering::default(), Default::default()); + + let tx_0 = MockTransaction::eip1559().with_nonce(1).set_gas_price(100).inc_limit(); + let tx_1 = tx_0.next(); + + let v0 = f.validated(tx_0); + let v1 = f.validated(tx_1); + + // nonce gap, tx should be queued + pool.add_transaction(v0.clone(), U256::MAX, 0).unwrap(); + assert_eq!(1, pool.queued_transactions().len()); + + // nonce gap is closed on-chain, both transactions should be moved to pending + pool.add_transaction(v1, U256::MAX, 1).unwrap(); + + assert_eq!(2, pool.pending_transactions().len()); + assert_eq!(0, pool.queued_transactions().len()); + + assert_eq!( + pool.pending_pool.independent().get(&v0.sender_id()).unwrap().transaction.nonce(), + v0.nonce() + ); + } + + // + #[test] + fn one_sender_one_independent_transaction() { + let mut on_chain_balance = U256::from(4_999); // only enough for 4 txs + let mut on_chain_nonce = 40; + let mut f = MockTransactionFactory::default(); + let mut pool = TxPool::mock(); + let mut submitted_txs = Vec::new(); + + // We use a "template" because we want all txs to have the same sender. + let template = + MockTransaction::eip1559().inc_price().inc_limit().with_value(U256::from(1_001)); + + // Add 8 txs. Because the balance is only sufficient for 4, so the last 4 will be + // Queued. + for tx_nonce in 40..48 { + let tx = f.validated(template.clone().with_nonce(tx_nonce).rng_hash()); + submitted_txs.push(*tx.id()); + pool.add_transaction(tx, on_chain_balance, on_chain_nonce).unwrap(); + } + + // A block is mined with two txs (so nonce is changed from 40 to 42). + // Now the balance gets so high that it's enough to execute alltxs. + on_chain_balance = U256::from(999_999); + on_chain_nonce = 42; + pool.remove_transaction(&submitted_txs[0]); + pool.remove_transaction(&submitted_txs[1]); + + // Add 4 txs. + for tx_nonce in 48..52 { + pool.add_transaction( + f.validated(template.clone().with_nonce(tx_nonce).rng_hash()), + on_chain_balance, + on_chain_nonce, + ) + .unwrap(); + } + + let best_txs: Vec<_> = pool.pending().best().map(|tx| *tx.id()).collect(); + assert_eq!(best_txs.len(), 10); // 8 - 2 + 4 = 10 + + assert_eq!(pool.pending_pool.independent().len(), 1); + } } From 9f6f63d45a1a5b9edf3087a9210e6a9170e4c1ec Mon Sep 17 00:00:00 2001 From: Steven <112043913+stevencartavia@users.noreply.github.com> Date: Fri, 8 Nov 2024 04:50:46 -0600 Subject: [PATCH 069/211] CLI parameter to specify the broadcast channel capacity of PendingPool (#12388) Co-authored-by: Matthias Seitz --- book/cli/reth/node.md | 5 +++++ crates/node/core/src/args/txpool.rs | 13 ++++++++++--- crates/transaction-pool/src/config.rs | 6 ++++++ crates/transaction-pool/src/lib.rs | 6 +++--- 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/book/cli/reth/node.md b/book/cli/reth/node.md index 5f0090ef896..d1bca0a43b2 100644 --- a/book/cli/reth/node.md +++ b/book/cli/reth/node.md @@ -502,6 +502,11 @@ TxPool: [default: 1024] + --txpool.max-new-pending-txs-notifications + How many new pending transactions to buffer and send to in progress pending transaction iterators + + [default: 200] + Builder: --builder.extradata Block extra data set by the payload builder diff --git a/crates/node/core/src/args/txpool.rs b/crates/node/core/src/args/txpool.rs index 2e691aaa963..a8ea1d9cdba 100644 --- a/crates/node/core/src/args/txpool.rs +++ b/crates/node/core/src/args/txpool.rs @@ -9,9 +9,9 @@ use reth_transaction_pool::{ pool::{NEW_TX_LISTENER_BUFFER_SIZE, PENDING_TX_LISTENER_BUFFER_SIZE}, validate::DEFAULT_MAX_TX_INPUT_BYTES, LocalTransactionConfig, PoolConfig, PriceBumpConfig, SubPoolLimit, DEFAULT_PRICE_BUMP, - DEFAULT_TXPOOL_ADDITIONAL_VALIDATION_TASKS, REPLACE_BLOB_PRICE_BUMP, - TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER, TXPOOL_SUBPOOL_MAX_SIZE_MB_DEFAULT, - TXPOOL_SUBPOOL_MAX_TXS_DEFAULT, + DEFAULT_TXPOOL_ADDITIONAL_VALIDATION_TASKS, MAX_NEW_PENDING_TXS_NOTIFICATIONS, + REPLACE_BLOB_PRICE_BUMP, TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER, + TXPOOL_SUBPOOL_MAX_SIZE_MB_DEFAULT, TXPOOL_SUBPOOL_MAX_TXS_DEFAULT, }; /// Parameters for debugging purposes #[derive(Debug, Clone, Args, PartialEq, Eq)] @@ -86,6 +86,11 @@ pub struct TxPoolArgs { /// Maximum number of new transactions to buffer #[arg(long = "txpool.max-new-txns", alias = "txpool.max_new_txns", default_value_t = NEW_TX_LISTENER_BUFFER_SIZE)] pub new_tx_listener_buffer_size: usize, + + /// How many new pending transactions to buffer and send to in progress pending transaction + /// iterators. + #[arg(long = "txpool.max-new-pending-txs-notifications", alias = "txpool.max-new-pending-txs-notifications", default_value_t = MAX_NEW_PENDING_TXS_NOTIFICATIONS)] + pub max_new_pending_txs_notifications: usize, } impl Default for TxPoolArgs { @@ -110,6 +115,7 @@ impl Default for TxPoolArgs { additional_validation_tasks: DEFAULT_TXPOOL_ADDITIONAL_VALIDATION_TASKS, pending_tx_listener_buffer_size: PENDING_TX_LISTENER_BUFFER_SIZE, new_tx_listener_buffer_size: NEW_TX_LISTENER_BUFFER_SIZE, + max_new_pending_txs_notifications: MAX_NEW_PENDING_TXS_NOTIFICATIONS, } } } @@ -148,6 +154,7 @@ impl RethTransactionPoolConfig for TxPoolArgs { gas_limit: self.gas_limit, pending_tx_listener_buffer_size: self.pending_tx_listener_buffer_size, new_tx_listener_buffer_size: self.new_tx_listener_buffer_size, + max_new_pending_txs_notifications: self.max_new_pending_txs_notifications, } } } diff --git a/crates/transaction-pool/src/config.rs b/crates/transaction-pool/src/config.rs index d4518846258..212df34bd37 100644 --- a/crates/transaction-pool/src/config.rs +++ b/crates/transaction-pool/src/config.rs @@ -27,6 +27,9 @@ pub const DEFAULT_PRICE_BUMP: u128 = 10; /// This enforces that a blob transaction requires a 100% price bump to be replaced pub const REPLACE_BLOB_PRICE_BUMP: u128 = 100; +/// Default maximum new transactions for broadcasting. +pub const MAX_NEW_PENDING_TXS_NOTIFICATIONS: usize = 200; + /// Configuration options for the Transaction pool. #[derive(Debug, Clone)] pub struct PoolConfig { @@ -53,6 +56,8 @@ pub struct PoolConfig { pub pending_tx_listener_buffer_size: usize, /// Bound on number of new transactions from `reth_network::TransactionsManager` to buffer. pub new_tx_listener_buffer_size: usize, + /// How many new pending transactions to buffer and send iterators in progress. + pub max_new_pending_txs_notifications: usize, } impl PoolConfig { @@ -80,6 +85,7 @@ impl Default for PoolConfig { local_transactions_config: Default::default(), pending_tx_listener_buffer_size: PENDING_TX_LISTENER_BUFFER_SIZE, new_tx_listener_buffer_size: NEW_TX_LISTENER_BUFFER_SIZE, + max_new_pending_txs_notifications: MAX_NEW_PENDING_TXS_NOTIFICATIONS, } } } diff --git a/crates/transaction-pool/src/lib.rs b/crates/transaction-pool/src/lib.rs index 669cb69b0e8..8d11d7595b1 100644 --- a/crates/transaction-pool/src/lib.rs +++ b/crates/transaction-pool/src/lib.rs @@ -166,9 +166,9 @@ pub use crate::{ blobstore::{BlobStore, BlobStoreError}, config::{ LocalTransactionConfig, PoolConfig, PriceBumpConfig, SubPoolLimit, DEFAULT_PRICE_BUMP, - DEFAULT_TXPOOL_ADDITIONAL_VALIDATION_TASKS, REPLACE_BLOB_PRICE_BUMP, - TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER, TXPOOL_SUBPOOL_MAX_SIZE_MB_DEFAULT, - TXPOOL_SUBPOOL_MAX_TXS_DEFAULT, + DEFAULT_TXPOOL_ADDITIONAL_VALIDATION_TASKS, MAX_NEW_PENDING_TXS_NOTIFICATIONS, + REPLACE_BLOB_PRICE_BUMP, TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER, + TXPOOL_SUBPOOL_MAX_SIZE_MB_DEFAULT, TXPOOL_SUBPOOL_MAX_TXS_DEFAULT, }, error::PoolResult, ordering::{CoinbaseTipOrdering, Priority, TransactionOrdering}, From 02d2593b2eb9481f85dd3b3edcca3c12ddd68769 Mon Sep 17 00:00:00 2001 From: Seva Zhidkov Date: Fri, 8 Nov 2024 11:45:27 +0000 Subject: [PATCH 070/211] feat(transaction-pool): chaining & static txs for best transactions trait (#12320) Co-authored-by: Matthias Seitz --- Cargo.lock | 4 + crates/optimism/node/Cargo.toml | 27 +- crates/optimism/node/src/lib.rs | 4 + .../optimism/node/{tests/e2e => src}/utils.rs | 14 +- crates/optimism/node/tests/e2e/main.rs | 3 - crates/optimism/node/tests/e2e/p2p.rs | 2 +- crates/optimism/node/tests/it/main.rs | 3 + crates/optimism/node/tests/it/priority.rs | 190 +++++++++++ crates/optimism/payload/src/builder.rs | 33 +- crates/transaction-pool/src/pool/best.rs | 294 +++++++++++++++++- crates/transaction-pool/src/pool/mod.rs | 5 +- crates/transaction-pool/src/traits.rs | 18 ++ 12 files changed, 555 insertions(+), 42 deletions(-) rename crates/optimism/node/{tests/e2e => src}/utils.rs (79%) create mode 100644 crates/optimism/node/tests/it/priority.rs diff --git a/Cargo.lock b/Cargo.lock index 84b660cd737..95f8166ce2f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8235,10 +8235,13 @@ dependencies = [ name = "reth-optimism-node" version = "1.1.1" dependencies = [ + "alloy-consensus", "alloy-eips", "alloy-genesis", + "alloy-network", "alloy-primitives", "alloy-rpc-types-engine", + "alloy-signer-local", "clap", "eyre", "futures", @@ -8261,6 +8264,7 @@ dependencies = [ "reth-optimism-consensus", "reth-optimism-evm", "reth-optimism-forks", + "reth-optimism-node", "reth-optimism-payload-builder", "reth-optimism-rpc", "reth-payload-builder", diff --git a/crates/optimism/node/Cargo.toml b/crates/optimism/node/Cargo.toml index 07315a07f4e..c1e23e3d571 100644 --- a/crates/optimism/node/Cargo.toml +++ b/crates/optimism/node/Cargo.toml @@ -55,17 +55,23 @@ parking_lot.workspace = true # rpc serde_json.workspace = true +# test-utils dependencies +reth = { workspace = true, optional = true } +reth-e2e-test-utils = { workspace = true, optional = true } +alloy-genesis = { workspace = true, optional = true } +tokio = { workspace = true, optional = true } + [dev-dependencies] -reth.workspace = true +reth-optimism-node = { workspace = true, features = ["test-utils"] } reth-db.workspace = true -reth-e2e-test-utils.workspace = true reth-node-builder = { workspace = true, features = ["test-utils"] } reth-provider = { workspace = true, features = ["test-utils"] } reth-revm = { workspace = true, features = ["test-utils"] } -tokio.workspace = true alloy-primitives.workspace = true -alloy-genesis.workspace = true op-alloy-consensus.workspace = true +alloy-signer-local.workspace = true +alloy-network.workspace = true +alloy-consensus.workspace = true futures.workspace = true [features] @@ -79,15 +85,21 @@ optimism = [ "reth-optimism-rpc/optimism", "reth-engine-local/optimism", "reth-optimism-consensus/optimism", - "reth-db/optimism" + "reth-db/optimism", + "reth-optimism-node/optimism" ] asm-keccak = [ "reth-primitives/asm-keccak", "reth/asm-keccak", "alloy-primitives/asm-keccak", - "revm/asm-keccak" + "revm/asm-keccak", + "reth-optimism-node/asm-keccak" ] test-utils = [ + "reth", + "reth-e2e-test-utils", + "alloy-genesis", + "tokio", "reth-node-builder/test-utils", "reth-chainspec/test-utils", "reth-consensus/test-utils", @@ -100,5 +112,6 @@ test-utils = [ "reth-provider/test-utils", "reth-transaction-pool/test-utils", "reth-trie-db/test-utils", - "revm/test-utils" + "revm/test-utils", + "reth-optimism-node/test-utils" ] diff --git a/crates/optimism/node/src/lib.rs b/crates/optimism/node/src/lib.rs index 6419611067e..7af0f3b8a72 100644 --- a/crates/optimism/node/src/lib.rs +++ b/crates/optimism/node/src/lib.rs @@ -22,6 +22,10 @@ pub use node::OpNode; pub mod txpool; +/// Helpers for running test node instances. +#[cfg(feature = "test-utils")] +pub mod utils; + pub use reth_optimism_payload_builder::{ OpBuiltPayload, OpPayloadBuilder, OpPayloadBuilderAttributes, }; diff --git a/crates/optimism/node/tests/e2e/utils.rs b/crates/optimism/node/src/utils.rs similarity index 79% rename from crates/optimism/node/tests/e2e/utils.rs rename to crates/optimism/node/src/utils.rs index c3b6acddc5a..b54015fef0c 100644 --- a/crates/optimism/node/tests/e2e/utils.rs +++ b/crates/optimism/node/src/utils.rs @@ -1,3 +1,4 @@ +use crate::{node::OpAddOns, OpBuiltPayload, OpNode as OtherOpNode, OpPayloadBuilderAttributes}; use alloy_genesis::Genesis; use alloy_primitives::{Address, B256}; use reth::{rpc::types::engine::PayloadAttributes, tasks::TaskManager}; @@ -5,9 +6,6 @@ use reth_e2e_test_utils::{ transaction::TransactionTestContext, wallet::Wallet, Adapter, NodeHelperType, }; use reth_optimism_chainspec::OpChainSpecBuilder; -use reth_optimism_node::{ - node::OpAddOns, OpBuiltPayload, OpNode as OtherOpNode, OpPayloadBuilderAttributes, -}; use reth_payload_builder::EthPayloadBuilderAttributes; use std::sync::Arc; use tokio::sync::Mutex; @@ -15,8 +13,10 @@ use tokio::sync::Mutex; /// Optimism Node Helper type pub(crate) type OpNode = NodeHelperType>>; -pub(crate) async fn setup(num_nodes: usize) -> eyre::Result<(Vec, TaskManager, Wallet)> { - let genesis: Genesis = serde_json::from_str(include_str!("../assets/genesis.json")).unwrap(); +/// Creates the initial setup with `num_nodes` of the node config, started and connected. +pub async fn setup(num_nodes: usize) -> eyre::Result<(Vec, TaskManager, Wallet)> { + let genesis: Genesis = + serde_json::from_str(include_str!("../tests/assets/genesis.json")).unwrap(); reth_e2e_test_utils::setup( num_nodes, Arc::new(OpChainSpecBuilder::base_mainnet().genesis(genesis).ecotone_activated().build()), @@ -27,7 +27,7 @@ pub(crate) async fn setup(num_nodes: usize) -> eyre::Result<(Vec, TaskMa } /// Advance the chain with sequential payloads returning them in the end. -pub(crate) async fn advance_chain( +pub async fn advance_chain( length: usize, node: &mut OpNode, wallet: Arc>, @@ -49,7 +49,7 @@ pub(crate) async fn advance_chain( } /// Helper function to create a new eth payload attributes -pub(crate) fn optimism_payload_attributes(timestamp: u64) -> OpPayloadBuilderAttributes { +pub fn optimism_payload_attributes(timestamp: u64) -> OpPayloadBuilderAttributes { let attributes = PayloadAttributes { timestamp, prev_randao: B256::ZERO, diff --git a/crates/optimism/node/tests/e2e/main.rs b/crates/optimism/node/tests/e2e/main.rs index 3438c766048..7f4b22ba7e0 100644 --- a/crates/optimism/node/tests/e2e/main.rs +++ b/crates/optimism/node/tests/e2e/main.rs @@ -3,7 +3,4 @@ #[cfg(feature = "optimism")] mod p2p; -#[cfg(feature = "optimism")] -mod utils; - const fn main() {} diff --git a/crates/optimism/node/tests/e2e/p2p.rs b/crates/optimism/node/tests/e2e/p2p.rs index 6240b781472..3db4cfab869 100644 --- a/crates/optimism/node/tests/e2e/p2p.rs +++ b/crates/optimism/node/tests/e2e/p2p.rs @@ -1,7 +1,7 @@ -use crate::utils::{advance_chain, setup}; use alloy_rpc_types_engine::PayloadStatusEnum; use futures::StreamExt; use reth::blockchain_tree::error::BlockchainTreeError; +use reth_optimism_node::utils::{advance_chain, setup}; use std::sync::Arc; use tokio::sync::Mutex; diff --git a/crates/optimism/node/tests/it/main.rs b/crates/optimism/node/tests/it/main.rs index b84dd7426c2..d0533fc4541 100644 --- a/crates/optimism/node/tests/it/main.rs +++ b/crates/optimism/node/tests/it/main.rs @@ -3,4 +3,7 @@ #[cfg(feature = "optimism")] mod builder; +#[cfg(feature = "optimism")] +mod priority; + const fn main() {} diff --git a/crates/optimism/node/tests/it/priority.rs b/crates/optimism/node/tests/it/priority.rs new file mode 100644 index 00000000000..52e3bef3d91 --- /dev/null +++ b/crates/optimism/node/tests/it/priority.rs @@ -0,0 +1,190 @@ +//! Node builder test that customizes priority of transactions in the block. + +use alloy_consensus::TxEip1559; +use alloy_genesis::Genesis; +use alloy_network::TxSignerSync; +use alloy_primitives::{Address, ChainId, TxKind}; +use reth::{args::DatadirArgs, tasks::TaskManager}; +use reth_chainspec::EthChainSpec; +use reth_db::test_utils::create_test_rw_db_with_path; +use reth_e2e_test_utils::{ + node::NodeTestContext, transaction::TransactionTestContext, wallet::Wallet, +}; +use reth_node_api::{FullNodeTypes, NodeTypesWithEngine}; +use reth_node_builder::{ + components::ComponentsBuilder, EngineNodeLauncher, NodeBuilder, NodeConfig, +}; +use reth_optimism_chainspec::{OpChainSpec, OpChainSpecBuilder}; +use reth_optimism_node::{ + args::RollupArgs, + node::{ + OpAddOns, OpConsensusBuilder, OpExecutorBuilder, OpNetworkBuilder, OpPayloadBuilder, + OpPoolBuilder, + }, + utils::optimism_payload_attributes, + OpEngineTypes, OpNode, +}; +use reth_optimism_payload_builder::builder::OpPayloadTransactions; +use reth_primitives::{SealedBlock, Transaction, TransactionSigned, TransactionSignedEcRecovered}; +use reth_provider::providers::BlockchainProvider2; +use reth_transaction_pool::{ + pool::{BestPayloadTransactions, PayloadTransactionsChain, PayloadTransactionsFixed}, + PayloadTransactions, +}; +use std::sync::Arc; +use tokio::sync::Mutex; + +#[derive(Clone, Debug)] +struct CustomTxPriority { + chain_id: ChainId, +} + +impl OpPayloadTransactions for CustomTxPriority { + fn best_transactions( + &self, + pool: Pool, + attr: reth_transaction_pool::BestTransactionsAttributes, + ) -> impl PayloadTransactions + where + Pool: reth_transaction_pool::TransactionPool, + { + // Block composition: + // 1. Best transactions from the pool (up to 250k gas) + // 2. End-of-block transaction created by the node (up to 100k gas) + + // End of block transaction should send a 0-value transfer to a random address. + let sender = Wallet::default().inner; + let mut end_of_block_tx = TxEip1559 { + chain_id: self.chain_id, + nonce: 1, // it will be 2nd tx after L1 block info tx that uses the same sender + gas_limit: 21000, + max_fee_per_gas: 20e9 as u128, + to: TxKind::Call(Address::random()), + value: 0.try_into().unwrap(), + ..Default::default() + }; + let signature = sender.sign_transaction_sync(&mut end_of_block_tx).unwrap(); + let end_of_block_tx = TransactionSignedEcRecovered::from_signed_transaction( + TransactionSigned::from_transaction_and_signature( + Transaction::Eip1559(end_of_block_tx), + signature, + ), + sender.address(), + ); + + PayloadTransactionsChain::new( + BestPayloadTransactions::new(pool.best_transactions_with_attributes(attr)), + // Allow 250k gas for the transactions from the pool + Some(250_000), + PayloadTransactionsFixed::single(end_of_block_tx), + // Allow 100k gas for the end-of-block transaction + Some(100_000), + ) + } +} + +/// Builds the node with custom transaction priority service within default payload builder. +fn build_components( + chain_id: ChainId, +) -> ComponentsBuilder< + Node, + OpPoolBuilder, + OpPayloadBuilder, + OpNetworkBuilder, + OpExecutorBuilder, + OpConsensusBuilder, +> +where + Node: + FullNodeTypes>, +{ + let RollupArgs { disable_txpool_gossip, compute_pending_block, discovery_v4, .. } = + RollupArgs::default(); + ComponentsBuilder::default() + .node_types::() + .pool(OpPoolBuilder::default()) + .payload( + OpPayloadBuilder::new(compute_pending_block) + .with_transactions(CustomTxPriority { chain_id }), + ) + .network(OpNetworkBuilder { disable_txpool_gossip, disable_discovery_v4: !discovery_v4 }) + .executor(OpExecutorBuilder::default()) + .consensus(OpConsensusBuilder::default()) +} + +#[tokio::test] +async fn test_custom_block_priority_config() { + reth_tracing::init_test_tracing(); + + let genesis: Genesis = serde_json::from_str(include_str!("../assets/genesis.json")).unwrap(); + let chain_spec = + Arc::new(OpChainSpecBuilder::base_mainnet().genesis(genesis).ecotone_activated().build()); + + // This wallet is going to send: + // 1. L1 block info tx + // 2. End-of-block custom tx + let wallet = Arc::new(Mutex::new(Wallet::default().with_chain_id(chain_spec.chain().into()))); + + // Configure and launch the node. + let config = NodeConfig::new(chain_spec).with_datadir_args(DatadirArgs { + datadir: reth_db::test_utils::tempdir_path().into(), + ..Default::default() + }); + let db = create_test_rw_db_with_path( + config + .datadir + .datadir + .unwrap_or_chain_default(config.chain.chain(), config.datadir.clone()) + .db(), + ); + let tasks = TaskManager::current(); + let node_handle = NodeBuilder::new(config.clone()) + .with_database(db) + .with_types_and_provider::>() + .with_components(build_components(config.chain.chain_id())) + .with_add_ons(OpAddOns::default()) + .launch_with_fn(|builder| { + let launcher = EngineNodeLauncher::new( + tasks.executor(), + builder.config.datadir(), + Default::default(), + ); + builder.launch_with(launcher) + }) + .await + .expect("Failed to launch node"); + + // Advance the chain with a single block. + let block_payloads = NodeTestContext::new(node_handle.node, optimism_payload_attributes) + .await + .unwrap() + .advance(1, |_| { + let wallet = wallet.clone(); + Box::pin(async move { + let mut wallet = wallet.lock().await; + let tx_fut = TransactionTestContext::optimism_l1_block_info_tx( + wallet.chain_id, + wallet.inner.clone(), + // This doesn't matter in the current test (because it's only one block), + // but make sure you're not reusing the nonce from end-of-block tx + // if they have the same signer. + wallet.inner_nonce * 2, + ); + wallet.inner_nonce += 1; + tx_fut.await + }) + }) + .await + .unwrap(); + assert_eq!(block_payloads.len(), 1); + let (block_payload, _) = block_payloads.first().unwrap(); + let block_payload: SealedBlock = block_payload.block().clone(); + assert_eq!(block_payload.body.transactions.len(), 2); // L1 block info tx + end-of-block custom tx + + // Check that last transaction in the block looks like a transfer to a random address. + let end_of_block_tx = block_payload.body.transactions.last().unwrap(); + let end_of_block_tx = end_of_block_tx.transaction.as_eip1559().unwrap(); + assert_eq!(end_of_block_tx.nonce, 1); + assert_eq!(end_of_block_tx.gas_limit, 21_000); + assert!(end_of_block_tx.input.is_empty()); +} diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index dc6084f4881..42326de6ea4 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -2,7 +2,7 @@ use std::{fmt::Display, sync::Arc}; -use alloy_consensus::EMPTY_OMMER_ROOT_HASH; +use alloy_consensus::{Transaction, EMPTY_OMMER_ROOT_HASH}; use alloy_eips::merge::BEACON_NONCE; use alloy_primitives::{Address, Bytes, U256}; use alloy_rpc_types_engine::PayloadId; @@ -23,8 +23,7 @@ use reth_primitives::{ use reth_provider::{ProviderError, StateProviderFactory, StateRootProvider}; use reth_revm::database::StateProviderDatabase; use reth_transaction_pool::{ - noop::NoopTransactionPool, BestTransactions, BestTransactionsAttributes, BestTransactionsFor, - TransactionPool, + noop::NoopTransactionPool, BestTransactionsAttributes, PayloadTransactions, TransactionPool, }; use reth_trie::HashedPostState; use revm::{ @@ -39,6 +38,7 @@ use crate::{ payload::{OpBuiltPayload, OpPayloadBuilderAttributes}, }; use op_alloy_consensus::DepositTransaction; +use reth_transaction_pool::pool::BestPayloadTransactions; /// Optimism's payload builder #[derive(Debug, Clone, PartialEq, Eq)] @@ -390,7 +390,7 @@ where } } -/// A type that returns a the [`BestTransactions`] that should be included in the pool. +/// A type that returns a the [`PayloadTransactions`] that should be included in the pool. pub trait OpPayloadTransactions: Clone + Send + Sync + Unpin + 'static { /// Returns an iterator that yields the transaction in the order they should get included in the /// new payload. @@ -398,7 +398,7 @@ pub trait OpPayloadTransactions: Clone + Send + Sync + Unpin + 'static { &self, pool: Pool, attr: BestTransactionsAttributes, - ) -> BestTransactionsFor; + ) -> impl PayloadTransactions; } impl OpPayloadTransactions for () { @@ -406,8 +406,8 @@ impl OpPayloadTransactions for () { &self, pool: Pool, attr: BestTransactionsAttributes, - ) -> BestTransactionsFor { - pool.best_transactions_with_attributes(attr) + ) -> impl PayloadTransactions { + BestPayloadTransactions::new(pool.best_transactions_with_attributes(attr)) } } @@ -730,7 +730,7 @@ where &self, info: &mut ExecutionInfo, db: &mut State, - mut best_txs: BestTransactionsFor, + mut best_txs: impl PayloadTransactions, ) -> Result>, PayloadBuilderError> where DB: Database, @@ -746,19 +746,19 @@ where ); let mut evm = self.evm_config.evm_with_env(&mut *db, env); - while let Some(pool_tx) = best_txs.next() { + while let Some(tx) = best_txs.next(()) { // ensure we still have capacity for this transaction - if info.cumulative_gas_used + pool_tx.gas_limit() > block_gas_limit { + 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(&pool_tx); + best_txs.mark_invalid(tx.signer(), tx.nonce()); 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); + if tx.is_eip4844() || tx.tx_type() == TxType::Deposit as u8 { + best_txs.mark_invalid(tx.signer(), tx.nonce()); continue } @@ -767,9 +767,6 @@ where return Ok(Some(BuildOutcomeKind::Cancelled)) } - // convert tx to a signed transaction - let tx = pool_tx.to_recovered_transaction(); - // Configure the environment for the tx. *evm.tx_mut() = self.evm_config.tx_env(tx.as_signed(), tx.signer()); @@ -785,7 +782,7 @@ where // 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); + best_txs.mark_invalid(tx.signer(), tx.nonce()); } continue @@ -819,7 +816,7 @@ where // update add to total fees let miner_fee = tx - .effective_tip_per_gas(Some(base_fee)) + .effective_tip_per_gas(base_fee) .expect("fee is always valid; execution succeeded"); info.total_fees += U256::from(miner_fee) * U256::from(gas_used); diff --git a/crates/transaction-pool/src/pool/best.rs b/crates/transaction-pool/src/pool/best.rs index 068ef989953..17165611794 100644 --- a/crates/transaction-pool/src/pool/best.rs +++ b/crates/transaction-pool/src/pool/best.rs @@ -1,10 +1,12 @@ use crate::{ identifier::{SenderId, TransactionId}, pool::pending::PendingTransaction, - PoolTransaction, TransactionOrdering, ValidPoolTransaction, + PayloadTransactions, PoolTransaction, TransactionOrdering, ValidPoolTransaction, }; +use alloy_consensus::Transaction; use alloy_primitives::Address; use core::fmt; +use reth_primitives::TransactionSignedEcRecovered; use std::{ collections::{BTreeMap, BTreeSet, HashSet, VecDeque}, sync::Arc, @@ -48,7 +50,7 @@ impl Iterator for BestTransactionsWithFees { fn next(&mut self) -> Option { // find the next transaction that satisfies the base fee loop { - let best = self.best.next()?; + let best = Iterator::next(&mut self.best)?; // If both the base fee and blob fee (if applicable for EIP-4844) are satisfied, return // the transaction if best.transaction.max_fee_per_gas() >= self.base_fee as u128 && @@ -205,6 +207,49 @@ impl Iterator for BestTransactions { } } +/// Wrapper struct that allows to convert `BestTransactions` (used in tx pool) to +/// `PayloadTransactions` (used in block composition). +#[derive(Debug)] +pub struct BestPayloadTransactions +where + T: PoolTransaction>, + I: Iterator>>, +{ + invalid: HashSet
, + best: I, +} + +impl BestPayloadTransactions +where + T: PoolTransaction>, + I: Iterator>>, +{ + /// Create a new `BestPayloadTransactions` with the given iterator. + pub fn new(best: I) -> Self { + Self { invalid: Default::default(), best } + } +} + +impl PayloadTransactions for BestPayloadTransactions +where + T: PoolTransaction>, + I: Iterator>>, +{ + fn next(&mut self, _ctx: ()) -> Option { + loop { + let tx = self.best.next()?; + if self.invalid.contains(&tx.sender()) { + continue + } + return Some(tx.to_recovered_transaction()) + } + } + + fn mark_invalid(&mut self, sender: Address, _nonce: u64) { + self.invalid.insert(sender); + } +} + /// A [`BestTransactions`](crate::traits::BestTransactions) implementation that filters the /// transactions of iter with predicate. /// @@ -350,6 +395,130 @@ where } } +/// An implementation of [`crate::traits::PayloadTransactions`] that yields +/// a pre-defined set of transactions. +/// +/// This is useful to put a sequencer-specified set of transactions into the block +/// and compose it with the rest of the transactions. +#[derive(Debug)] +pub struct PayloadTransactionsFixed { + transactions: Vec, + index: usize, +} + +impl PayloadTransactionsFixed { + /// Constructs a new [`PayloadTransactionsFixed`]. + pub fn new(transactions: Vec) -> Self { + Self { transactions, index: Default::default() } + } + + /// Constructs a new [`PayloadTransactionsFixed`] with a single transaction. + pub fn single(transaction: T) -> Self { + Self { transactions: vec![transaction], index: Default::default() } + } +} + +impl PayloadTransactions for PayloadTransactionsFixed { + fn next(&mut self, _ctx: ()) -> Option { + (self.index < self.transactions.len()).then(|| { + let tx = self.transactions[self.index].clone(); + self.index += 1; + tx + }) + } + + fn mark_invalid(&mut self, _sender: Address, _nonce: u64) {} +} + +/// Wrapper over [`crate::traits::PayloadTransactions`] that combines transactions from multiple +/// `PayloadTransactions` iterators and keeps track of the gas for both of iterators. +/// +/// We can't use [`Iterator::chain`], because: +/// (a) we need to propagate the `mark_invalid` and `no_updates` +/// (b) we need to keep track of the gas +/// +/// Notes that [`PayloadTransactionsChain`] fully drains the first iterator +/// before moving to the second one. +/// +/// If the `before` iterator has transactions that are not fitting into the block, +/// the after iterator will get propagated a `mark_invalid` call for each of them. +#[derive(Debug)] +pub struct PayloadTransactionsChain { + /// Iterator that will be used first + before: B, + /// Allowed gas for the transactions from `before` iterator. If `None`, no gas limit is + /// enforced. + before_max_gas: Option, + /// Gas used by the transactions from `before` iterator + before_gas: u64, + /// Iterator that will be used after `before` iterator + after: A, + /// Allowed gas for the transactions from `after` iterator. If `None`, no gas limit is + /// enforced. + after_max_gas: Option, + /// Gas used by the transactions from `after` iterator + after_gas: u64, +} + +impl PayloadTransactionsChain { + /// Constructs a new [`PayloadTransactionsChain`]. + pub fn new( + before: B, + before_max_gas: Option, + after: A, + after_max_gas: Option, + ) -> Self { + Self { + before, + before_max_gas, + before_gas: Default::default(), + after, + after_max_gas, + after_gas: Default::default(), + } + } +} + +impl PayloadTransactions for PayloadTransactionsChain +where + B: PayloadTransactions, + A: PayloadTransactions, +{ + fn next(&mut self, ctx: ()) -> Option { + while let Some(tx) = self.before.next(ctx) { + if let Some(before_max_gas) = self.before_max_gas { + if self.before_gas + tx.transaction.gas_limit() <= before_max_gas { + self.before_gas += tx.transaction.gas_limit(); + return Some(tx); + } + self.before.mark_invalid(tx.signer(), tx.transaction.nonce()); + self.after.mark_invalid(tx.signer(), tx.transaction.nonce()); + } else { + return Some(tx); + } + } + + while let Some(tx) = self.after.next(ctx) { + if let Some(after_max_gas) = self.after_max_gas { + if self.after_gas + tx.transaction.gas_limit() <= after_max_gas { + self.after_gas += tx.transaction.gas_limit(); + return Some(tx); + } + self.after.mark_invalid(tx.signer(), tx.transaction.nonce()); + } else { + return Some(tx); + } + } + + None + } + + fn mark_invalid(&mut self, sender: Address, nonce: u64) { + self.before.mark_invalid(sender, nonce); + self.after.mark_invalid(sender, nonce); + } +} + #[cfg(test)] mod tests { use super::*; @@ -428,9 +597,9 @@ mod tests { dyn crate::traits::BestTransactions>>, > = Box::new(pool.best()); - let tx = best.next().unwrap(); - best.mark_invalid(&tx); - assert!(best.next().is_none()); + let tx = Iterator::next(&mut best).unwrap(); + crate::traits::BestTransactions::mark_invalid(&mut *best, &tx); + assert!(Iterator::next(&mut best).is_none()); } #[test] @@ -737,4 +906,119 @@ mod tests { assert_eq!(tx.nonce() % 2, 0); } } + + #[test] + fn test_best_transactions_prioritized_senders() { + let mut pool = PendingPool::new(MockOrdering::default()); + let mut f = MockTransactionFactory::default(); + + // Add 5 plain transactions from different senders with increasing gas price + for gas_price in 0..5 { + let tx = MockTransaction::eip1559().with_gas_price(gas_price); + let valid_tx = f.validated(tx); + pool.add_transaction(Arc::new(valid_tx), 0); + } + + // Add another transaction with 0 gas price that's going to be prioritized by sender + let prioritized_tx = MockTransaction::eip1559().with_gas_price(0); + let valid_prioritized_tx = f.validated(prioritized_tx.clone()); + pool.add_transaction(Arc::new(valid_prioritized_tx), 0); + + let prioritized_senders = HashSet::from([prioritized_tx.sender()]); + let best = + BestTransactionsWithPrioritizedSenders::new(prioritized_senders, 200, pool.best()); + + // Verify that the prioritized transaction is returned first + // and the rest are returned in the reverse order of gas price + let mut iter = best.into_iter(); + let top_of_block_tx = iter.next().unwrap(); + assert_eq!(top_of_block_tx.max_fee_per_gas(), 0); + assert_eq!(top_of_block_tx.sender(), prioritized_tx.sender()); + for gas_price in (0..5).rev() { + assert_eq!(iter.next().unwrap().max_fee_per_gas(), gas_price); + } + + // TODO: Test that gas limits for prioritized transactions are respected + } + + #[test] + fn test_best_transactions_chained_iterators() { + let mut priority_pool = PendingPool::new(MockOrdering::default()); + let mut pool = PendingPool::new(MockOrdering::default()); + let mut f = MockTransactionFactory::default(); + + // Block composition + // === + // (1) up to 100 gas: custom top-of-block transaction + // (2) up to 100 gas: transactions from the priority pool + // (3) up to 200 gas: only transactions from address A + // (4) up to 200 gas: only transactions from address B + // (5) until block gas limit: all transactions from the main pool + + // Notes: + // - If prioritized addresses overlap, a single transaction will be prioritized twice and + // therefore use the per-segment gas limit twice. + // - Priority pool and main pool must synchronize between each other to make sure there are + // no conflicts for the same nonce. For example, in this scenario, pools can't reject + // transactions with seemingly incorrect nonces, because previous transactions might be in + // the other pool. + + let address_top_of_block = Address::random(); + let address_in_priority_pool = Address::random(); + let address_a = Address::random(); + let address_b = Address::random(); + let address_regular = Address::random(); + + // Add transactions to the main pool + { + let prioritized_tx_a = + MockTransaction::eip1559().with_gas_price(5).with_sender(address_a); + // without our custom logic, B would be prioritized over A due to gas price: + let prioritized_tx_b = + MockTransaction::eip1559().with_gas_price(10).with_sender(address_b); + let regular_tx = + MockTransaction::eip1559().with_gas_price(15).with_sender(address_regular); + pool.add_transaction(Arc::new(f.validated(prioritized_tx_a)), 0); + pool.add_transaction(Arc::new(f.validated(prioritized_tx_b)), 0); + pool.add_transaction(Arc::new(f.validated(regular_tx)), 0); + } + + // Add transactions to the priority pool + { + let prioritized_tx = + MockTransaction::eip1559().with_gas_price(0).with_sender(address_in_priority_pool); + let valid_prioritized_tx = f.validated(prioritized_tx); + priority_pool.add_transaction(Arc::new(valid_prioritized_tx), 0); + } + + let mut block = PayloadTransactionsChain::new( + PayloadTransactionsFixed::single( + MockTransaction::eip1559().with_sender(address_top_of_block).into(), + ), + Some(100), + PayloadTransactionsChain::new( + BestPayloadTransactions::new(priority_pool.best()), + Some(100), + BestPayloadTransactions::new(BestTransactionsWithPrioritizedSenders::new( + HashSet::from([address_a]), + 200, + BestTransactionsWithPrioritizedSenders::new( + HashSet::from([address_b]), + 200, + pool.best(), + ), + )), + None, + ), + None, + ); + + assert_eq!(block.next(()).unwrap().signer(), address_top_of_block); + assert_eq!(block.next(()).unwrap().signer(), address_in_priority_pool); + assert_eq!(block.next(()).unwrap().signer(), address_a); + assert_eq!(block.next(()).unwrap().signer(), address_b); + assert_eq!(block.next(()).unwrap().signer(), address_regular); + } + + // TODO: Same nonce test } diff --git a/crates/transaction-pool/src/pool/mod.rs b/crates/transaction-pool/src/pool/mod.rs index 0841c0d3d28..76b2490b12f 100644 --- a/crates/transaction-pool/src/pool/mod.rs +++ b/crates/transaction-pool/src/pool/mod.rs @@ -106,7 +106,10 @@ use crate::{ traits::{GetPooledTransactionLimit, NewBlobSidecar, TransactionListenerKind}, validate::ValidTransaction, }; -pub use best::{BestTransactionFilter, BestTransactionsWithPrioritizedSenders}; +pub use best::{ + BestPayloadTransactions, BestTransactionFilter, BestTransactionsWithPrioritizedSenders, + PayloadTransactionsChain, PayloadTransactionsFixed, +}; pub use blob::{blob_tx_priority, fee_delta}; pub use events::{FullTransactionEvent, TransactionEvent}; pub use listener::{AllTransactionsEvents, TransactionEvents}; diff --git a/crates/transaction-pool/src/traits.rs b/crates/transaction-pool/src/traits.rs index aa99e7af615..185c08c109a 100644 --- a/crates/transaction-pool/src/traits.rs +++ b/crates/transaction-pool/src/traits.rs @@ -1501,6 +1501,24 @@ impl Stream for NewSubpoolTransactionStream { } } +/// Iterator that returns transactions for the block building process in the order they should be +/// included in the block. +/// +/// Can include transactions from the pool and other sources (alternative pools, +/// sequencer-originated transactions, etc.). +pub trait PayloadTransactions { + /// Returns the next transaction to include in the block. + fn next( + &mut self, + // In the future, `ctx` can include access to state for block building purposes. + ctx: (), + ) -> Option; + + /// Exclude descendants of the transaction with given sender and nonce from the iterator, + /// because this transaction won't be included in the block. + fn mark_invalid(&mut self, sender: Address, nonce: u64); +} + #[cfg(test)] mod tests { use super::*; From bce70311559e20db5b4b6ec37c0883d231dc2355 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Fri, 8 Nov 2024 15:57:01 +0400 Subject: [PATCH 071/211] feat: allow generic values in `tables!` macro (#12400) --- .../cli/commands/src/test_vectors/tables.rs | 21 +-- crates/storage/db/src/tables/mod.rs | 170 ++++++++++++++---- .../src/providers/static_file/manager.rs | 7 +- 3 files changed, 150 insertions(+), 48 deletions(-) diff --git a/crates/cli/commands/src/test_vectors/tables.rs b/crates/cli/commands/src/test_vectors/tables.rs index 29ba50c8d83..22e54ea1336 100644 --- a/crates/cli/commands/src/test_vectors/tables.rs +++ b/crates/cli/commands/src/test_vectors/tables.rs @@ -10,6 +10,7 @@ use proptest_arbitrary_interop::arb; use reth_db::tables; use reth_db_api::table::{DupSort, Table, TableRow}; use reth_fs_util as fs; +use reth_primitives::{Header, TransactionSignedNoHash}; use std::collections::HashSet; use tracing::error; @@ -31,16 +32,16 @@ pub fn generate_vectors(mut tables: Vec) -> Result<()> { fs::create_dir_all(VECTORS_FOLDER)?; macro_rules! generate_vector { - ($table_type:ident, $per_table:expr, TABLE) => { - generate_table_vector::(&mut runner, $per_table)?; + ($table_type:ident$(<$($generic:ident),+>)?, $per_table:expr, TABLE) => { + generate_table_vector::)?>(&mut runner, $per_table)?; }; - ($table_type:ident, $per_table:expr, DUPSORT) => { - generate_dupsort_vector::(&mut runner, $per_table)?; + ($table_type:ident$(<$($generic:ident),+>)?, $per_table:expr, DUPSORT) => { + generate_dupsort_vector::)?>(&mut runner, $per_table)?; }; } macro_rules! generate { - ([$(($table_type:ident, $per_table:expr, $table_or_dup:tt)),*]) => { + ([$(($table_type:ident$(<$($generic:ident),+>)?, $per_table:expr, $table_or_dup:tt)),*]) => { let all_tables = vec![$(stringify!($table_type).to_string(),)*]; if tables.is_empty() { @@ -50,10 +51,10 @@ pub fn generate_vectors(mut tables: Vec) -> Result<()> { for table in tables { match table.as_str() { $( - stringify!($table_type) => { - println!("Generating test vectors for {} <{}>.", stringify!($table_or_dup), tables::$table_type::NAME); + stringify!($table_type$(<$($generic),+>)?) => { + println!("Generating test vectors for {} <{}>.", stringify!($table_or_dup), tables::$table_type$(::<$($generic),+>)?::NAME); - generate_vector!($table_type, $per_table, $table_or_dup); + generate_vector!($table_type$(<$($generic),+>)?, $per_table, $table_or_dup); }, )* _ => { @@ -68,11 +69,11 @@ pub fn generate_vectors(mut tables: Vec) -> Result<()> { (CanonicalHeaders, PER_TABLE, TABLE), (HeaderTerminalDifficulties, PER_TABLE, TABLE), (HeaderNumbers, PER_TABLE, TABLE), - (Headers, PER_TABLE, TABLE), + (Headers
, PER_TABLE, TABLE), (BlockBodyIndices, PER_TABLE, TABLE), (BlockOmmers, 100, TABLE), (TransactionHashNumbers, PER_TABLE, TABLE), - (Transactions, 100, TABLE), + (Transactions, 100, TABLE), (PlainStorageState, PER_TABLE, DUPSORT), (PlainAccountState, PER_TABLE, TABLE) ]); diff --git a/crates/storage/db/src/tables/mod.rs b/crates/storage/db/src/tables/mod.rs index 27f58f8a1f3..c697c319909 100644 --- a/crates/storage/db/src/tables/mod.rs +++ b/crates/storage/db/src/tables/mod.rs @@ -106,28 +106,39 @@ macro_rules! tables { (@view $name:ident $v:ident) => { $v.view::<$name>() }; (@view $name:ident $v:ident $_subkey:ty) => { $v.view_dupsort::<$name>() }; - ($( $(#[$attr:meta])* table $name:ident; )*) => { + (@value_doc $key:ty, $value:ty) => { + concat!("[`", stringify!($value), "`]") + }; + // Don't generate links if we have generics + (@value_doc $key:ty, $value:ty, $($generic:ident),*) => { + concat!("`", stringify!($value), "`") + }; + + ($($(#[$attr:meta])* table $name:ident$(<$($generic:ident $(= $default:ty)?),*>)? { type Key = $key:ty; type Value = $value:ty; $(type SubKey = $subkey:ty;)? } )*) => { // Table marker types. $( $(#[$attr])* /// - #[doc = concat!("Marker type representing a database table mapping [`", stringify!($key), "`] to [`", stringify!($value), "`].")] + #[doc = concat!("Marker type representing a database table mapping [`", stringify!($key), "`] to ", tables!(@value_doc $key, $value, $($($generic),*)?), ".")] $( #[doc = concat!("\n\nThis table's `DUPSORT` subkey is [`", stringify!($subkey), "`].")] )? - pub struct $name { - _private: (), + pub struct $name$(<$($generic $( = $default)?),*>)? { + _private: std::marker::PhantomData<($($($generic,)*)?)>, } // Ideally this implementation wouldn't exist, but it is necessary to derive `Debug` // when a type is generic over `T: Table`. See: https://github.com/rust-lang/rust/issues/26925 - impl fmt::Debug for $name { + impl$(<$($generic),*>)? fmt::Debug for $name$(<$($generic),*>)? { fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result { unreachable!("this type cannot be instantiated") } } - impl reth_db_api::table::Table for $name { + impl$(<$($generic),*>)? reth_db_api::table::Table for $name$(<$($generic),*>)? + where + $value: reth_db_api::table::Value + 'static + { const NAME: &'static str = table_names::$name; type Key = $key; @@ -248,7 +259,7 @@ macro_rules! tables { /// use reth_db_api::table::Table; /// /// let table = Tables::Headers; - /// let result = tables_to_generic!(table, |GenericTable| GenericTable::NAME); + /// let result = tables_to_generic!(table, |GenericTable| ::NAME); /// assert_eq!(result, table.name()); /// ``` #[macro_export] @@ -269,53 +280,96 @@ macro_rules! tables { tables! { /// Stores the header hashes belonging to the canonical chain. - table CanonicalHeaders; + table CanonicalHeaders { + type Key = BlockNumber; + type Value = HeaderHash; + } /// Stores the total difficulty from a block header. - table HeaderTerminalDifficulties; + table HeaderTerminalDifficulties { + type Key = BlockNumber; + type Value = CompactU256; + } /// Stores the block number corresponding to a header. - table HeaderNumbers; + table HeaderNumbers { + type Key = BlockHash; + type Value = BlockNumber; + } /// Stores header bodies. - table Headers; + table Headers { + type Key = BlockNumber; + type Value = H; + } /// Stores block indices that contains indexes of transaction and the count of them. /// /// More information about stored indices can be found in the [`StoredBlockBodyIndices`] struct. - table BlockBodyIndices; + table BlockBodyIndices { + type Key = BlockNumber; + type Value = StoredBlockBodyIndices; + } /// Stores the uncles/ommers of the block. - table BlockOmmers; + table BlockOmmers { + type Key = BlockNumber; + type Value = StoredBlockOmmers; + } /// Stores the block withdrawals. - table BlockWithdrawals; + table BlockWithdrawals { + type Key = BlockNumber; + type Value = StoredBlockWithdrawals; + } /// Canonical only Stores the transaction body for canonical transactions. - table Transactions; + table Transactions { + type Key = TxNumber; + type Value = T; + } /// Stores the mapping of the transaction hash to the transaction number. - table TransactionHashNumbers; + table TransactionHashNumbers { + type Key = TxHash; + type Value = TxNumber; + } /// Stores the mapping of transaction number to the blocks number. /// /// The key is the highest transaction ID in the block. - table TransactionBlocks; + table TransactionBlocks { + type Key = TxNumber; + type Value = BlockNumber; + } /// Canonical only Stores transaction receipts. - table Receipts; + table Receipts { + type Key = TxNumber; + type Value = Receipt; + } /// Stores all smart contract bytecodes. /// There will be multiple accounts that have same bytecode /// So we would need to introduce reference counter. /// This will be small optimization on state. - table Bytecodes; + table Bytecodes { + type Key = B256; + type Value = Bytecode; + } /// Stores the current state of an [`Account`]. - table PlainAccountState; + table PlainAccountState { + type Key = Address; + type Value = Account; + } /// Stores the current value of a storage key. - table PlainStorageState; + table PlainStorageState { + type Key = Address; + type Value = StorageEntry; + type SubKey = B256; + } /// Stores pointers to block changeset with changes for each account key. /// @@ -335,7 +389,10 @@ tables! { /// * If there were no shard we would get `None` entry or entry of different storage key. /// /// Code example can be found in `reth_provider::HistoricalStateProviderRef` - table AccountsHistory, Value = BlockNumberList>; + table AccountsHistory { + type Key = ShardedKey
; + type Value = BlockNumberList; + } /// Stores pointers to block number changeset with changes for each storage key. /// @@ -355,55 +412,98 @@ tables! { /// * If there were no shard we would get `None` entry or entry of different storage key. /// /// Code example can be found in `reth_provider::HistoricalStateProviderRef` - table StoragesHistory; + table StoragesHistory { + type Key = StorageShardedKey; + type Value = BlockNumberList; + } /// Stores the state of an account before a certain transaction changed it. /// Change on state can be: account is created, selfdestructed, touched while empty /// or changed balance,nonce. - table AccountChangeSets; + table AccountChangeSets { + type Key = BlockNumber; + type Value = AccountBeforeTx; + type SubKey = Address; + } /// Stores the state of a storage key before a certain transaction changed it. /// If [`StorageEntry::value`] is zero, this means storage was not existing /// and needs to be removed. - table StorageChangeSets; + table StorageChangeSets { + type Key = BlockNumberAddress; + type Value = StorageEntry; + type SubKey = B256; + } /// Stores the current state of an [`Account`] indexed with `keccak256Address` /// This table is in preparation for merklization and calculation of state root. /// We are saving whole account data as it is needed for partial update when /// part of storage is changed. Benefit for merklization is that hashed addresses are sorted. - table HashedAccounts; + table HashedAccounts { + type Key = B256; + type Value = Account; + } /// Stores the current storage values indexed with `keccak256Address` and /// hash of storage key `keccak256key`. /// This table is in preparation for merklization and calculation of state root. /// Benefit for merklization is that hashed addresses/keys are sorted. - table HashedStorages; + table HashedStorages { + type Key = B256; + type Value = StorageEntry; + type SubKey = B256; + } /// Stores the current state's Merkle Patricia Tree. - table AccountsTrie; + table AccountsTrie { + type Key = StoredNibbles; + type Value = BranchNodeCompact; + } /// From HashedAddress => NibblesSubKey => Intermediate value - table StoragesTrie; + table StoragesTrie { + type Key = B256; + type Value = StorageTrieEntry; + type SubKey = StoredNibblesSubKey; + } /// Stores the transaction sender for each canonical transaction. /// It is needed to speed up execution stage and allows fetching signer without doing /// transaction signed recovery - table TransactionSenders; + table TransactionSenders { + type Key = TxNumber; + type Value = Address; + } /// Stores the highest synced block number and stage-specific checkpoint of each stage. - table StageCheckpoints; + table StageCheckpoints { + type Key = StageId; + type Value = StageCheckpoint; + } /// Stores arbitrary data to keep track of a stage first-sync progress. - table StageCheckpointProgresses>; + table StageCheckpointProgresses { + type Key = StageId; + type Value = Vec; + } /// Stores the highest pruned block number and prune mode of each prune segment. - table PruneCheckpoints; + table PruneCheckpoints { + type Key = PruneSegment; + type Value = PruneCheckpoint; + } /// Stores the history of client versions that have accessed the database with write privileges by unix timestamp in seconds. - table VersionHistory; + table VersionHistory { + type Key = u64; + type Value = ClientVersion; + } /// Stores generic chain state info, like the last finalized block. - table ChainState; + table ChainState { + type Key = ChainStateKey; + type Value = BlockNumber; + } } /// Keys for the `ChainState` table. diff --git a/crates/storage/provider/src/providers/static_file/manager.rs b/crates/storage/provider/src/providers/static_file/manager.rs index 9ccaf051463..66914b00abc 100644 --- a/crates/storage/provider/src/providers/static_file/manager.rs +++ b/crates/storage/provider/src/providers/static_file/manager.rs @@ -1645,7 +1645,7 @@ impl StatsReader for StaticFileProvider { fn count_entries(&self) -> ProviderResult { match T::NAME { tables::CanonicalHeaders::NAME | - tables::Headers::NAME | + tables::Headers::
::NAME | tables::HeaderTerminalDifficulties::NAME => Ok(self .get_highest_static_file_block(StaticFileSegment::Headers) .map(|block| block + 1) @@ -1655,10 +1655,11 @@ impl StatsReader for StaticFileProvider { .get_highest_static_file_tx(StaticFileSegment::Receipts) .map(|receipts| receipts + 1) .unwrap_or_default() as usize), - tables::Transactions::NAME => Ok(self + tables::Transactions::::NAME => Ok(self .get_highest_static_file_tx(StaticFileSegment::Transactions) .map(|txs| txs + 1) - .unwrap_or_default() as usize), + .unwrap_or_default() + as usize), _ => Err(ProviderError::UnsupportedProvider), } } From 32ebb181caa838e72740b9a50154917258506c56 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 8 Nov 2024 13:44:06 +0100 Subject: [PATCH 072/211] chore: rm duplicated cfg (#12406) --- crates/primitives/src/transaction/mod.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index 208474fc6c4..ed1a7daf1e8 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -1755,8 +1755,6 @@ pub mod serde_bincode_compat { TxEip4844, }; use alloy_primitives::{PrimitiveSignature as Signature, TxHash}; - #[cfg(feature = "optimism")] - use op_alloy_consensus::serde_bincode_compat::TxDeposit; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_with::{DeserializeAs, SerializeAs}; @@ -1784,8 +1782,7 @@ pub mod serde_bincode_compat { Eip4844(Cow<'a, TxEip4844>), Eip7702(TxEip7702<'a>), #[cfg(feature = "optimism")] - #[cfg(feature = "optimism")] - Deposit(TxDeposit<'a>), + Deposit(op_alloy_consensus::serde_bincode_compat::TxDeposit<'a>), } impl<'a> From<&'a super::Transaction> for Transaction<'a> { @@ -1797,7 +1794,9 @@ pub mod serde_bincode_compat { super::Transaction::Eip4844(tx) => Self::Eip4844(Cow::Borrowed(tx)), super::Transaction::Eip7702(tx) => Self::Eip7702(TxEip7702::from(tx)), #[cfg(feature = "optimism")] - super::Transaction::Deposit(tx) => Self::Deposit(TxDeposit::from(tx)), + super::Transaction::Deposit(tx) => { + Self::Deposit(op_alloy_consensus::serde_bincode_compat::TxDeposit::from(tx)) + } } } } @@ -1900,7 +1899,6 @@ pub mod serde_bincode_compat { #[cfg(test)] mod tests { use super::super::{serde_bincode_compat, Transaction, TransactionSigned}; - use arbitrary::Arbitrary; use rand::Rng; use reth_testing_utils::generators; From 74d7fe3075aff34e63ce64ca24b7188fc7c7c854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Narzis?= <78718413+lean-apple@users.noreply.github.com> Date: Fri, 8 Nov 2024 21:50:48 +0700 Subject: [PATCH 073/211] feat(rpc): optimize block validation with state caching (#12299) Co-authored-by: Matthias Seitz --- crates/rpc/rpc/src/validation.rs | 50 +++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/crates/rpc/rpc/src/validation.rs b/crates/rpc/rpc/src/validation.rs index 919fe2d8591..c3f2aab70bb 100644 --- a/crates/rpc/rpc/src/validation.rs +++ b/crates/rpc/rpc/src/validation.rs @@ -20,7 +20,7 @@ use reth_provider::{ AccountReader, BlockExecutionInput, BlockExecutionOutput, BlockReaderIdExt, HeaderProvider, StateProviderFactory, WithdrawalsProvider, }; -use reth_revm::database::StateProviderDatabase; +use reth_revm::{cached::CachedReads, database::StateProviderDatabase}; use reth_rpc_api::BlockSubmissionValidationApiServer; use reth_rpc_eth_types::EthApiError; use reth_rpc_server_types::{result::internal_rpc_err, ToRpcResult}; @@ -28,6 +28,7 @@ use reth_trie::HashedPostState; use revm_primitives::{Address, B256, U256}; use serde::{Deserialize, Serialize}; use std::{collections::HashSet, sync::Arc}; +use tokio::sync::RwLock; /// Configuration for validation API. #[derive(Debug, Clone, Default, Eq, PartialEq, Serialize, Deserialize)] @@ -64,7 +65,7 @@ pub enum ValidationApiError { Execution(#[from] BlockExecutionError), } -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct ValidationApiInner { /// The provider that can interact with the chain. provider: Provider, @@ -76,10 +77,15 @@ pub struct ValidationApiInner { executor_provider: E, /// Set of disallowed addresses disallow: HashSet
, + /// Cached state reads to avoid redundant disk I/O across multiple validation attempts + /// targeting the same state. Stores a tuple of (`block_hash`, `cached_reads`) for the + /// latest head block state. Uses async `RwLock` to safely handle concurrent validation + /// requests. + cached_state: RwLock<(B256, CachedReads)>, } /// The type that implements the `validation` rpc namespace trait -#[derive(Clone, Debug, derive_more::Deref)] +#[derive(Debug, derive_more::Deref)] pub struct ValidationApi { #[deref] inner: Arc>, @@ -105,10 +111,31 @@ where payload_validator, executor_provider, disallow, + cached_state: Default::default(), }); Self { inner } } + + /// Returns the cached reads for the given head hash. + async fn cached_reads(&self, head: B256) -> CachedReads { + let cache = self.inner.cached_state.read().await; + if cache.0 == head { + cache.1.clone() + } else { + Default::default() + } + } + + /// Updates the cached state for the given head hash. + async fn update_cached_reads(&self, head: B256, cached_state: CachedReads) { + let mut cache = self.inner.cached_state.write().await; + if cache.0 == head { + cache.1.extend(cached_state); + } else { + *cache = (head, cached_state) + } + } } impl ValidationApi @@ -119,12 +146,11 @@ where + HeaderProvider + AccountReader + WithdrawalsProvider - + Clone + 'static, E: BlockExecutorProvider, { /// Validates the given block and a [`BidTrace`] against it. - pub fn validate_message_against_block( + pub async fn validate_message_against_block( &self, block: SealedBlockWithSenders, message: BidTrace, @@ -168,8 +194,13 @@ where self.consensus.validate_header_against_parent(&block.header, &latest_header)?; self.validate_gas_limit(registered_gas_limit, &latest_header, &block.header)?; - let state_provider = self.provider.state_by_block_hash(latest_header.hash())?; - let executor = self.executor_provider.executor(StateProviderDatabase::new(&state_provider)); + let latest_header_hash = latest_header.hash(); + let state_provider = self.provider.state_by_block_hash(latest_header_hash)?; + + let mut request_cache = self.cached_reads(latest_header_hash).await; + + let cached_db = request_cache.as_db_mut(StateProviderDatabase::new(&state_provider)); + let executor = self.executor_provider.executor(cached_db); let block = block.unseal(); let mut accessed_blacklisted = None; @@ -186,6 +217,9 @@ where }, )?; + // update the cached reads + self.update_cached_reads(latest_header_hash, request_cache).await; + if let Some(account) = accessed_blacklisted { return Err(ValidationApiError::Blacklist(account)) } @@ -413,6 +447,7 @@ where request.request.message, request.registered_gas_limit, ) + .await .map_err(|e| RethError::Other(e.into())) .to_rpc_result() } @@ -446,6 +481,7 @@ where request.request.message, request.registered_gas_limit, ) + .await .map_err(|e| RethError::Other(e.into())) .to_rpc_result() } From 86230d99624fc8c9ef81c6e6b340b9a8c39beead Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 8 Nov 2024 15:50:57 +0100 Subject: [PATCH 074/211] chore: include path in panic (#12407) --- crates/storage/db/benches/utils.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/crates/storage/db/benches/utils.rs b/crates/storage/db/benches/utils.rs index d4ae96e0006..62c4dfe6ecb 100644 --- a/crates/storage/db/benches/utils.rs +++ b/crates/storage/db/benches/utils.rs @@ -26,13 +26,11 @@ where T::Key: Default + Clone + for<'de> serde::Deserialize<'de>, T::Value: Default + Clone + for<'de> serde::Deserialize<'de>, { + let path = + format!("{}/../../../testdata/micro/db/{}.json", env!("CARGO_MANIFEST_DIR"), T::NAME); let list: Vec> = serde_json::from_reader(std::io::BufReader::new( - std::fs::File::open(format!( - "{}/../../../testdata/micro/db/{}.json", - env!("CARGO_MANIFEST_DIR"), - T::NAME - )) - .expect("Test vectors not found. They can be generated from the workspace by calling `cargo run --bin reth --features dev -- test-vectors tables`."), + std::fs::File::open(&path) + .unwrap_or_else(|_| panic!("Test vectors not found. They can be generated from the workspace by calling `cargo run --bin reth --features dev -- test-vectors tables`: {:?}", path)) )) .unwrap(); From 0da914eaebe5fc296098e3b2f406c7250ef2abd4 Mon Sep 17 00:00:00 2001 From: Hai | RISE <150876604+hai-rise@users.noreply.github.com> Date: Fri, 8 Nov 2024 22:03:29 +0700 Subject: [PATCH 075/211] chore: enable `dbg_macro` lint (#12409) --- Cargo.toml | 1 + clippy.toml | 1 + crates/storage/db-common/src/init.rs | 5 ++++- crates/transaction-pool/src/pool/pending.rs | 1 - 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4471ce32baa..31d2ebb8d4c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -175,6 +175,7 @@ branches_sharing_code = "warn" clear_with_drain = "warn" cloned_instead_of_copied = "warn" collection_is_never_read = "warn" +dbg_macro = "warn" derive_partial_eq_without_eq = "warn" doc_markdown = "warn" empty_line_after_doc_comments = "warn" diff --git a/clippy.toml b/clippy.toml index 862c568634e..ab08b1132c1 100644 --- a/clippy.toml +++ b/clippy.toml @@ -15,3 +15,4 @@ doc-valid-idents = [ "WAL", "MessagePack", ] +allow-dbg-in-tests = true diff --git a/crates/storage/db-common/src/init.rs b/crates/storage/db-common/src/init.rs index 014751733e6..8c930b22ef8 100644 --- a/crates/storage/db-common/src/init.rs +++ b/crates/storage/db-common/src/init.rs @@ -98,7 +98,10 @@ where database_hash: block_hash, }) } - Err(e) => return Err(dbg!(e).into()), + Err(e) => { + debug!(?e); + return Err(e.into()); + } } debug!("Writing genesis block."); diff --git a/crates/transaction-pool/src/pool/pending.rs b/crates/transaction-pool/src/pool/pending.rs index 357cea48974..f4bce8c85a6 100644 --- a/crates/transaction-pool/src/pool/pending.rs +++ b/crates/transaction-pool/src/pool/pending.rs @@ -311,7 +311,6 @@ impl PendingPool { // send the new transaction to any existing pendingpool static file iterators if self.new_transaction_notifier.receiver_count() > 0 { - dbg!("notify"); let _ = self.new_transaction_notifier.send(tx.clone()); } From f03b762036cfcb2cfe71a1de7ebc3203e6761ed4 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Fri, 8 Nov 2024 16:20:26 +0100 Subject: [PATCH 076/211] feat: introduce ParallelProof (#12403) --- Cargo.lock | 1 + crates/trie/parallel/Cargo.toml | 1 + crates/trie/parallel/src/lib.rs | 3 + crates/trie/parallel/src/parallel_proof.rs | 214 +++++++++++++++++++++ 4 files changed, 219 insertions(+) create mode 100644 crates/trie/parallel/src/parallel_proof.rs diff --git a/Cargo.lock b/Cargo.lock index 95f8166ce2f..22c5cb8ae50 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9304,6 +9304,7 @@ dependencies = [ "reth-primitives", "reth-provider", "reth-trie", + "reth-trie-common", "reth-trie-db", "thiserror", "tokio", diff --git a/crates/trie/parallel/Cargo.toml b/crates/trie/parallel/Cargo.toml index cc35fe9f914..1b3e2d59be1 100644 --- a/crates/trie/parallel/Cargo.toml +++ b/crates/trie/parallel/Cargo.toml @@ -16,6 +16,7 @@ workspace = true reth-primitives.workspace = true reth-db.workspace = true reth-trie.workspace = true +reth-trie-common.workspace = true reth-trie-db.workspace = true reth-execution-errors.workspace = true reth-provider.workspace = true diff --git a/crates/trie/parallel/src/lib.rs b/crates/trie/parallel/src/lib.rs index 40a6af34758..25fcb4bac3a 100644 --- a/crates/trie/parallel/src/lib.rs +++ b/crates/trie/parallel/src/lib.rs @@ -16,6 +16,9 @@ pub mod stats; /// Implementation of parallel state root computation. pub mod parallel_root; +/// Implementation of parallel proof computation. +pub mod parallel_proof; + /// Parallel state root metrics. #[cfg(feature = "metrics")] pub mod metrics; diff --git a/crates/trie/parallel/src/parallel_proof.rs b/crates/trie/parallel/src/parallel_proof.rs new file mode 100644 index 00000000000..9c7d6b6b8b3 --- /dev/null +++ b/crates/trie/parallel/src/parallel_proof.rs @@ -0,0 +1,214 @@ +use crate::{ + parallel_root::ParallelStateRootError, stats::ParallelTrieTracker, StorageRootTargets, +}; +use alloy_primitives::{map::HashSet, B256}; +use alloy_rlp::{BufMut, Encodable}; +use itertools::Itertools; +use reth_db::DatabaseError; +use reth_execution_errors::StorageRootError; +use reth_provider::{ + providers::ConsistentDbView, BlockReader, DBProvider, DatabaseProviderFactory, ProviderError, +}; +use reth_trie::{ + hashed_cursor::{HashedCursorFactory, HashedPostStateCursorFactory}, + node_iter::{TrieElement, TrieNodeIter}, + prefix_set::{PrefixSetMut, TriePrefixSetsMut}, + proof::StorageProof, + trie_cursor::{InMemoryTrieCursorFactory, TrieCursorFactory}, + walker::TrieWalker, + HashBuilder, MultiProof, Nibbles, TrieAccount, TrieInput, +}; +use reth_trie_common::proof::ProofRetainer; +use reth_trie_db::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory}; +use std::{collections::HashMap, sync::Arc}; +use tracing::debug; + +#[cfg(feature = "metrics")] +use crate::metrics::ParallelStateRootMetrics; + +/// TODO: +#[derive(Debug)] +pub struct ParallelProof { + /// Consistent view of the database. + view: ConsistentDbView, + /// Trie input. + input: TrieInput, + /// Parallel state root metrics. + #[cfg(feature = "metrics")] + metrics: ParallelStateRootMetrics, +} + +impl ParallelProof { + /// Create new state proof generator. + pub fn new(view: ConsistentDbView, input: TrieInput) -> Self { + Self { + view, + input, + #[cfg(feature = "metrics")] + metrics: ParallelStateRootMetrics::default(), + } + } +} + +impl ParallelProof +where + Factory: DatabaseProviderFactory + Clone + Send + Sync + 'static, +{ + /// Generate a state multiproof according to specified targets. + pub fn multiproof( + self, + targets: HashMap>, + ) -> Result { + let mut tracker = ParallelTrieTracker::default(); + + let trie_nodes_sorted = Arc::new(self.input.nodes.into_sorted()); + let hashed_state_sorted = Arc::new(self.input.state.into_sorted()); + + // Extend prefix sets with targets + let mut prefix_sets = self.input.prefix_sets.clone(); + prefix_sets.extend(TriePrefixSetsMut { + account_prefix_set: PrefixSetMut::from(targets.keys().copied().map(Nibbles::unpack)), + storage_prefix_sets: targets + .iter() + .filter(|&(_hashed_address, slots)| (!slots.is_empty())) + .map(|(hashed_address, slots)| { + (*hashed_address, PrefixSetMut::from(slots.iter().map(Nibbles::unpack))) + }) + .collect(), + destroyed_accounts: Default::default(), + }); + let prefix_sets = prefix_sets.freeze(); + + let storage_root_targets = StorageRootTargets::new( + prefix_sets.account_prefix_set.iter().map(|nibbles| B256::from_slice(&nibbles.pack())), + prefix_sets.storage_prefix_sets.clone(), + ); + + // Pre-calculate storage roots for accounts which were changed. + tracker.set_precomputed_storage_roots(storage_root_targets.len() as u64); + debug!(target: "trie::parallel_state_root", len = storage_root_targets.len(), "pre-generating storage proofs"); + let mut storage_proofs = HashMap::with_capacity(storage_root_targets.len()); + for (hashed_address, prefix_set) in + storage_root_targets.into_iter().sorted_unstable_by_key(|(address, _)| *address) + { + let view = self.view.clone(); + let target_slots: HashSet = + targets.get(&hashed_address).cloned().unwrap_or_default(); + + let trie_nodes_sorted = trie_nodes_sorted.clone(); + let hashed_state_sorted = hashed_state_sorted.clone(); + + let (tx, rx) = std::sync::mpsc::sync_channel(1); + + rayon::spawn_fifo(move || { + let result = (|| -> Result<_, ParallelStateRootError> { + let provider_ro = view.provider_ro()?; + let trie_cursor_factory = InMemoryTrieCursorFactory::new( + DatabaseTrieCursorFactory::new(provider_ro.tx_ref()), + &trie_nodes_sorted, + ); + let hashed_cursor_factory = HashedPostStateCursorFactory::new( + DatabaseHashedCursorFactory::new(provider_ro.tx_ref()), + &hashed_state_sorted, + ); + + StorageProof::new_hashed( + trie_cursor_factory, + hashed_cursor_factory, + hashed_address, + ) + .with_prefix_set_mut(PrefixSetMut::from(prefix_set.iter().cloned())) + .storage_multiproof(target_slots) + .map_err(|e| { + ParallelStateRootError::StorageRoot(StorageRootError::Database( + DatabaseError::Other(e.to_string()), + )) + }) + })(); + let _ = tx.send(result); + }); + storage_proofs.insert(hashed_address, rx); + } + + let provider_ro = self.view.provider_ro()?; + let trie_cursor_factory = InMemoryTrieCursorFactory::new( + DatabaseTrieCursorFactory::new(provider_ro.tx_ref()), + &trie_nodes_sorted, + ); + let hashed_cursor_factory = HashedPostStateCursorFactory::new( + DatabaseHashedCursorFactory::new(provider_ro.tx_ref()), + &hashed_state_sorted, + ); + + // Create the walker. + let walker = TrieWalker::new( + trie_cursor_factory.account_trie_cursor().map_err(ProviderError::Database)?, + prefix_sets.account_prefix_set, + ) + .with_deletions_retained(true); + + // Create a hash builder to rebuild the root node since it is not available in the database. + let retainer: ProofRetainer = targets.keys().map(Nibbles::unpack).collect(); + let mut hash_builder = HashBuilder::default().with_proof_retainer(retainer); + + let mut storages = HashMap::default(); + let mut account_rlp = Vec::with_capacity(128); + let mut account_node_iter = TrieNodeIter::new( + walker, + hashed_cursor_factory.hashed_account_cursor().map_err(ProviderError::Database)?, + ); + while let Some(account_node) = + account_node_iter.try_next().map_err(ProviderError::Database)? + { + match account_node { + TrieElement::Branch(node) => { + hash_builder.add_branch(node.key, node.value, node.children_are_in_trie); + } + TrieElement::Leaf(hashed_address, account) => { + let storage_multiproof = match storage_proofs.remove(&hashed_address) { + Some(rx) => rx.recv().map_err(|_| { + ParallelStateRootError::StorageRoot(StorageRootError::Database( + DatabaseError::Other(format!( + "channel closed for {hashed_address}" + )), + )) + })??, + // Since we do not store all intermediate nodes in the database, there might + // be a possibility of re-adding a non-modified leaf to the hash builder. + None => { + tracker.inc_missed_leaves(); + StorageProof::new_hashed( + trie_cursor_factory.clone(), + hashed_cursor_factory.clone(), + hashed_address, + ) + .with_prefix_set_mut(Default::default()) + .storage_multiproof( + targets.get(&hashed_address).cloned().unwrap_or_default(), + ) + .map_err(|e| { + ParallelStateRootError::StorageRoot(StorageRootError::Database( + DatabaseError::Other(e.to_string()), + )) + })? + } + }; + + // Encode account + account_rlp.clear(); + let account = TrieAccount::from((account, storage_multiproof.root)); + account.encode(&mut account_rlp as &mut dyn BufMut); + + hash_builder.add_leaf(Nibbles::unpack(hashed_address), &account_rlp); + storages.insert(hashed_address, storage_multiproof); + } + } + } + let _ = hash_builder.root(); + + #[cfg(feature = "metrics")] + self.metrics.record_state_trie(tracker.finish()); + + Ok(MultiProof { account_subtree: hash_builder.take_proof_nodes(), storages }) + } +} From ba4f169f8783d78fb7e89aed76e34aa179546fc3 Mon Sep 17 00:00:00 2001 From: Roman Krasiuk Date: Fri, 8 Nov 2024 16:23:56 +0100 Subject: [PATCH 077/211] chore(db): add log for read transaciton monitor sleep time (#12408) --- crates/storage/libmdbx-rs/src/txn_manager.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/storage/libmdbx-rs/src/txn_manager.rs b/crates/storage/libmdbx-rs/src/txn_manager.rs index 716e8ee62bd..6afd4205a60 100644 --- a/crates/storage/libmdbx-rs/src/txn_manager.rs +++ b/crates/storage/libmdbx-rs/src/txn_manager.rs @@ -289,11 +289,11 @@ mod read_transactions { // Sleep not more than `READ_TRANSACTIONS_CHECK_INTERVAL`, but at least until // the closest deadline of an active read transaction - let duration_until_closest_deadline = - self.max_duration - max_active_transaction_duration.unwrap_or_default(); - std::thread::sleep( - READ_TRANSACTIONS_CHECK_INTERVAL.min(duration_until_closest_deadline), + let sleep_duration = READ_TRANSACTIONS_CHECK_INTERVAL.min( + self.max_duration - max_active_transaction_duration.unwrap_or_default(), ); + trace!(target: "libmdbx", ?sleep_duration, elapsed = ?now.elapsed(), "Putting transaction monitor to sleep"); + std::thread::sleep(sleep_duration); } }; std::thread::Builder::new() From fc484b793f0f94ffe16f7fc521736cab1ab93c7e Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 8 Nov 2024 19:28:22 +0100 Subject: [PATCH 078/211] test: fix test vectors (#12411) --- crates/cli/commands/src/test_vectors/tables.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cli/commands/src/test_vectors/tables.rs b/crates/cli/commands/src/test_vectors/tables.rs index 22e54ea1336..6b523c6edd1 100644 --- a/crates/cli/commands/src/test_vectors/tables.rs +++ b/crates/cli/commands/src/test_vectors/tables.rs @@ -51,7 +51,7 @@ pub fn generate_vectors(mut tables: Vec) -> Result<()> { for table in tables { match table.as_str() { $( - stringify!($table_type$(<$($generic),+>)?) => { + stringify!($table_type) => { println!("Generating test vectors for {} <{}>.", stringify!($table_or_dup), tables::$table_type$(::<$($generic),+>)?::NAME); generate_vector!($table_type$(<$($generic),+>)?, $per_table, $table_or_dup); From 5cfe9a9879aa6d8fb6fcafc2b38bbd25fe358eaf Mon Sep 17 00:00:00 2001 From: Steven <112043913+stevencartavia@users.noreply.github.com> Date: Fri, 8 Nov 2024 12:29:34 -0600 Subject: [PATCH 079/211] renamed OptimismHardfork to OpHardfork (#12410) --- crates/optimism/chainspec/src/base.rs | 6 +- crates/optimism/chainspec/src/base_sepolia.rs | 6 +- crates/optimism/chainspec/src/lib.rs | 132 +++++++++--------- crates/optimism/chainspec/src/op.rs | 6 +- crates/optimism/chainspec/src/op_sepolia.rs | 6 +- crates/optimism/consensus/src/proof.rs | 10 +- crates/optimism/evm/src/config.rs | 28 ++-- crates/optimism/evm/src/execute.rs | 6 +- crates/optimism/evm/src/l1.rs | 23 ++- crates/optimism/hardforks/src/dev.rs | 12 +- crates/optimism/hardforks/src/hardfork.rs | 33 ++--- crates/optimism/hardforks/src/lib.rs | 30 ++-- crates/optimism/node/src/engine.rs | 9 +- 13 files changed, 148 insertions(+), 159 deletions(-) diff --git a/crates/optimism/chainspec/src/base.rs b/crates/optimism/chainspec/src/base.rs index 7aa26bf9a64..f43457ead43 100644 --- a/crates/optimism/chainspec/src/base.rs +++ b/crates/optimism/chainspec/src/base.rs @@ -6,7 +6,7 @@ use alloy_chains::Chain; use alloy_primitives::{b256, U256}; use reth_chainspec::{once_cell_set, BaseFeeParams, BaseFeeParamsKind, ChainSpec}; use reth_ethereum_forks::EthereumHardfork; -use reth_optimism_forks::OptimismHardfork; +use reth_optimism_forks::OpHardfork; use crate::{LazyLock, OpChainSpec}; @@ -21,11 +21,11 @@ pub static BASE_MAINNET: LazyLock> = LazyLock::new(|| { "f712aa9241cc24369b143cf6dce85f0902a9731e70d66818a3a5845b296c73dd" )), paris_block_and_final_difficulty: Some((0, U256::from(0))), - hardforks: OptimismHardfork::base_mainnet(), + hardforks: OpHardfork::base_mainnet(), base_fee_params: BaseFeeParamsKind::Variable( vec![ (EthereumHardfork::London.boxed(), BaseFeeParams::optimism()), - (OptimismHardfork::Canyon.boxed(), BaseFeeParams::optimism_canyon()), + (OpHardfork::Canyon.boxed(), BaseFeeParams::optimism_canyon()), ] .into(), ), diff --git a/crates/optimism/chainspec/src/base_sepolia.rs b/crates/optimism/chainspec/src/base_sepolia.rs index b992dcabaf6..adcb9e2bc1f 100644 --- a/crates/optimism/chainspec/src/base_sepolia.rs +++ b/crates/optimism/chainspec/src/base_sepolia.rs @@ -6,7 +6,7 @@ use alloy_chains::Chain; use alloy_primitives::{b256, U256}; use reth_chainspec::{once_cell_set, BaseFeeParams, BaseFeeParamsKind, ChainSpec}; use reth_ethereum_forks::EthereumHardfork; -use reth_optimism_forks::OptimismHardfork; +use reth_optimism_forks::OpHardfork; use crate::{LazyLock, OpChainSpec}; @@ -21,11 +21,11 @@ pub static BASE_SEPOLIA: LazyLock> = LazyLock::new(|| { "0dcc9e089e30b90ddfc55be9a37dd15bc551aeee999d2e2b51414c54eaf934e4" )), paris_block_and_final_difficulty: Some((0, U256::from(0))), - hardforks: OptimismHardfork::base_sepolia(), + hardforks: OpHardfork::base_sepolia(), base_fee_params: BaseFeeParamsKind::Variable( vec![ (EthereumHardfork::London.boxed(), BaseFeeParams::base_sepolia()), - (OptimismHardfork::Canyon.boxed(), BaseFeeParams::base_sepolia_canyon()), + (OpHardfork::Canyon.boxed(), BaseFeeParams::base_sepolia_canyon()), ] .into(), ), diff --git a/crates/optimism/chainspec/src/lib.rs b/crates/optimism/chainspec/src/lib.rs index aa59e9ab3f8..7bd0e433a2d 100644 --- a/crates/optimism/chainspec/src/lib.rs +++ b/crates/optimism/chainspec/src/lib.rs @@ -96,7 +96,7 @@ impl OpChainSpecBuilder { } /// Remove the given fork from the spec. - pub fn without_fork(mut self, fork: reth_optimism_forks::OptimismHardfork) -> Self { + pub fn without_fork(mut self, fork: reth_optimism_forks::OpHardfork) -> Self { self.inner = self.inner.without_fork(fork); self } @@ -104,19 +104,17 @@ impl OpChainSpecBuilder { /// Enable Bedrock at genesis pub fn bedrock_activated(mut self) -> Self { self.inner = self.inner.paris_activated(); - self.inner = self - .inner - .with_fork(reth_optimism_forks::OptimismHardfork::Bedrock, ForkCondition::Block(0)); + self.inner = + self.inner.with_fork(reth_optimism_forks::OpHardfork::Bedrock, ForkCondition::Block(0)); self } /// Enable Regolith at genesis pub fn regolith_activated(mut self) -> Self { self = self.bedrock_activated(); - self.inner = self.inner.with_fork( - reth_optimism_forks::OptimismHardfork::Regolith, - ForkCondition::Timestamp(0), - ); + self.inner = self + .inner + .with_fork(reth_optimism_forks::OpHardfork::Regolith, ForkCondition::Timestamp(0)); self } @@ -127,7 +125,7 @@ impl OpChainSpecBuilder { self.inner = self.inner.with_fork(EthereumHardfork::Shanghai, ForkCondition::Timestamp(0)); self.inner = self .inner - .with_fork(reth_optimism_forks::OptimismHardfork::Canyon, ForkCondition::Timestamp(0)); + .with_fork(reth_optimism_forks::OpHardfork::Canyon, ForkCondition::Timestamp(0)); self } @@ -137,7 +135,7 @@ impl OpChainSpecBuilder { self.inner = self.inner.with_fork(EthereumHardfork::Cancun, ForkCondition::Timestamp(0)); self.inner = self .inner - .with_fork(reth_optimism_forks::OptimismHardfork::Ecotone, ForkCondition::Timestamp(0)); + .with_fork(reth_optimism_forks::OpHardfork::Ecotone, ForkCondition::Timestamp(0)); self } @@ -146,7 +144,7 @@ impl OpChainSpecBuilder { self = self.ecotone_activated(); self.inner = self .inner - .with_fork(reth_optimism_forks::OptimismHardfork::Fjord, ForkCondition::Timestamp(0)); + .with_fork(reth_optimism_forks::OpHardfork::Fjord, ForkCondition::Timestamp(0)); self } @@ -155,17 +153,16 @@ impl OpChainSpecBuilder { self = self.fjord_activated(); self.inner = self .inner - .with_fork(reth_optimism_forks::OptimismHardfork::Granite, ForkCondition::Timestamp(0)); + .with_fork(reth_optimism_forks::OpHardfork::Granite, ForkCondition::Timestamp(0)); self } /// Enable Holocene at genesis pub fn holocene_activated(mut self) -> Self { self = self.granite_activated(); - self.inner = self.inner.with_fork( - reth_optimism_forks::OptimismHardfork::Holocene, - ForkCondition::Timestamp(0), - ); + self.inner = self + .inner + .with_fork(reth_optimism_forks::OpHardfork::Holocene, ForkCondition::Timestamp(0)); self } @@ -194,10 +191,9 @@ impl OpChainSpec { parent: &Header, timestamp: u64, ) -> Result { - let is_holocene_activated = self.inner.is_fork_active_at_timestamp( - reth_optimism_forks::OptimismHardfork::Holocene, - timestamp, - ); + let is_holocene_activated = self + .inner + .is_fork_active_at_timestamp(reth_optimism_forks::OpHardfork::Holocene, timestamp); // If we are in the Holocene, we need to use the base fee params // from the parent block's extra data. // Else, use the base fee params (default values) from chainspec @@ -344,7 +340,7 @@ impl OptimismHardforks for OpChainSpec {} impl From for OpChainSpec { fn from(genesis: Genesis) -> Self { - use reth_optimism_forks::OptimismHardfork; + use reth_optimism_forks::OpHardfork; let optimism_genesis_info = OpGenesisInfo::extract_from(&genesis); let genesis_info = optimism_genesis_info.optimism_chain_info.genesis_info.unwrap_or_default(); @@ -363,7 +359,7 @@ impl From for OpChainSpec { (EthereumHardfork::London.boxed(), genesis.config.london_block), (EthereumHardfork::ArrowGlacier.boxed(), genesis.config.arrow_glacier_block), (EthereumHardfork::GrayGlacier.boxed(), genesis.config.gray_glacier_block), - (OptimismHardfork::Bedrock.boxed(), genesis_info.bedrock_block), + (OpHardfork::Bedrock.boxed(), genesis_info.bedrock_block), ]; let mut block_hardforks = hardfork_opts .into_iter() @@ -391,11 +387,11 @@ impl From for OpChainSpec { (EthereumHardfork::Shanghai.boxed(), genesis.config.shanghai_time), (EthereumHardfork::Cancun.boxed(), genesis.config.cancun_time), (EthereumHardfork::Prague.boxed(), genesis.config.prague_time), - (OptimismHardfork::Regolith.boxed(), genesis_info.regolith_time), - (OptimismHardfork::Canyon.boxed(), genesis_info.canyon_time), - (OptimismHardfork::Ecotone.boxed(), genesis_info.ecotone_time), - (OptimismHardfork::Fjord.boxed(), genesis_info.fjord_time), - (OptimismHardfork::Granite.boxed(), genesis_info.granite_time), + (OpHardfork::Regolith.boxed(), genesis_info.regolith_time), + (OpHardfork::Canyon.boxed(), genesis_info.canyon_time), + (OpHardfork::Ecotone.boxed(), genesis_info.ecotone_time), + (OpHardfork::Fjord.boxed(), genesis_info.fjord_time), + (OpHardfork::Granite.boxed(), genesis_info.granite_time), ]; let mut time_hardforks = time_hardfork_opts @@ -408,7 +404,7 @@ impl From for OpChainSpec { block_hardforks.append(&mut time_hardforks); // Ordered Hardforks - let mainnet_hardforks = OptimismHardfork::op_mainnet(); + let mainnet_hardforks = OpHardfork::op_mainnet(); let mainnet_order = mainnet_hardforks.forks_iter(); let mut ordered_hardforks = Vec::with_capacity(block_hardforks.len()); @@ -464,7 +460,7 @@ impl OpGenesisInfo { BaseFeeParams::new(denominator as u128, elasticity as u128), ), ( - reth_optimism_forks::OptimismHardfork::Canyon.boxed(), + reth_optimism_forks::OpHardfork::Canyon.boxed(), BaseFeeParams::new(canyon_denominator as u128, elasticity as u128), ), ] @@ -490,7 +486,7 @@ mod tests { use alloy_primitives::b256; use reth_chainspec::{test_fork_ids, BaseFeeParams, BaseFeeParamsKind}; use reth_ethereum_forks::{EthereumHardfork, ForkCondition, ForkHash, ForkId, Head}; - use reth_optimism_forks::{OptimismHardfork, OptimismHardforks}; + use reth_optimism_forks::{OpHardfork, OptimismHardforks}; use crate::*; @@ -763,19 +759,19 @@ mod tests { BaseFeeParamsKind::Constant(BaseFeeParams::new(70, 60)) ); - assert!(!chain_spec.is_fork_active_at_block(OptimismHardfork::Bedrock, 0)); - assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Regolith, 0)); - assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Canyon, 0)); - assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Ecotone, 0)); - assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Fjord, 0)); - assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Granite, 0)); - - assert!(chain_spec.is_fork_active_at_block(OptimismHardfork::Bedrock, 10)); - assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Regolith, 20)); - assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Canyon, 30)); - assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Ecotone, 40)); - assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Fjord, 50)); - assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Granite, 51)); + assert!(!chain_spec.is_fork_active_at_block(OpHardfork::Bedrock, 0)); + assert!(!chain_spec.is_fork_active_at_timestamp(OpHardfork::Regolith, 0)); + assert!(!chain_spec.is_fork_active_at_timestamp(OpHardfork::Canyon, 0)); + assert!(!chain_spec.is_fork_active_at_timestamp(OpHardfork::Ecotone, 0)); + assert!(!chain_spec.is_fork_active_at_timestamp(OpHardfork::Fjord, 0)); + assert!(!chain_spec.is_fork_active_at_timestamp(OpHardfork::Granite, 0)); + + assert!(chain_spec.is_fork_active_at_block(OpHardfork::Bedrock, 10)); + assert!(chain_spec.is_fork_active_at_timestamp(OpHardfork::Regolith, 20)); + assert!(chain_spec.is_fork_active_at_timestamp(OpHardfork::Canyon, 30)); + assert!(chain_spec.is_fork_active_at_timestamp(OpHardfork::Ecotone, 40)); + assert!(chain_spec.is_fork_active_at_timestamp(OpHardfork::Fjord, 50)); + assert!(chain_spec.is_fork_active_at_timestamp(OpHardfork::Granite, 51)); } #[test] @@ -829,25 +825,25 @@ mod tests { BaseFeeParamsKind::Variable( vec![ (EthereumHardfork::London.boxed(), BaseFeeParams::new(70, 60)), - (OptimismHardfork::Canyon.boxed(), BaseFeeParams::new(80, 60)), + (OpHardfork::Canyon.boxed(), BaseFeeParams::new(80, 60)), ] .into() ) ); - assert!(!chain_spec.is_fork_active_at_block(OptimismHardfork::Bedrock, 0)); - assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Regolith, 0)); - assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Canyon, 0)); - assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Ecotone, 0)); - assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Fjord, 0)); - assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Granite, 0)); - - assert!(chain_spec.is_fork_active_at_block(OptimismHardfork::Bedrock, 10)); - assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Regolith, 20)); - assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Canyon, 30)); - assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Ecotone, 40)); - assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Fjord, 50)); - assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Granite, 51)); + assert!(!chain_spec.is_fork_active_at_block(OpHardfork::Bedrock, 0)); + assert!(!chain_spec.is_fork_active_at_timestamp(OpHardfork::Regolith, 0)); + assert!(!chain_spec.is_fork_active_at_timestamp(OpHardfork::Canyon, 0)); + assert!(!chain_spec.is_fork_active_at_timestamp(OpHardfork::Ecotone, 0)); + assert!(!chain_spec.is_fork_active_at_timestamp(OpHardfork::Fjord, 0)); + assert!(!chain_spec.is_fork_active_at_timestamp(OpHardfork::Granite, 0)); + + assert!(chain_spec.is_fork_active_at_block(OpHardfork::Bedrock, 10)); + assert!(chain_spec.is_fork_active_at_timestamp(OpHardfork::Regolith, 20)); + assert!(chain_spec.is_fork_active_at_timestamp(OpHardfork::Canyon, 30)); + assert!(chain_spec.is_fork_active_at_timestamp(OpHardfork::Ecotone, 40)); + assert!(chain_spec.is_fork_active_at_timestamp(OpHardfork::Fjord, 50)); + assert!(chain_spec.is_fork_active_at_timestamp(OpHardfork::Granite, 51)); } #[test] @@ -921,14 +917,14 @@ mod tests { }) ); - assert!(chainspec.is_fork_active_at_block(OptimismHardfork::Bedrock, 0)); + assert!(chainspec.is_fork_active_at_block(OpHardfork::Bedrock, 0)); - assert!(chainspec.is_fork_active_at_timestamp(OptimismHardfork::Regolith, 20)); + assert!(chainspec.is_fork_active_at_timestamp(OpHardfork::Regolith, 20)); } #[test] fn test_fork_order_optimism_mainnet() { - use reth_optimism_forks::OptimismHardfork; + use reth_optimism_forks::OpHardfork; let genesis = Genesis { config: ChainConfig { @@ -984,14 +980,14 @@ mod tests { EthereumHardfork::ArrowGlacier.boxed(), EthereumHardfork::GrayGlacier.boxed(), EthereumHardfork::Paris.boxed(), - OptimismHardfork::Bedrock.boxed(), - OptimismHardfork::Regolith.boxed(), + OpHardfork::Bedrock.boxed(), + OpHardfork::Regolith.boxed(), EthereumHardfork::Shanghai.boxed(), - OptimismHardfork::Canyon.boxed(), + OpHardfork::Canyon.boxed(), EthereumHardfork::Cancun.boxed(), - OptimismHardfork::Ecotone.boxed(), - OptimismHardfork::Fjord.boxed(), - OptimismHardfork::Granite.boxed(), + OpHardfork::Ecotone.boxed(), + OpHardfork::Fjord.boxed(), + OpHardfork::Granite.boxed(), ]; assert!(expected_hardforks @@ -1022,8 +1018,8 @@ mod tests { } fn holocene_chainspec() -> Arc { - let mut hardforks = OptimismHardfork::base_sepolia(); - hardforks.insert(OptimismHardfork::Holocene.boxed(), ForkCondition::Timestamp(1800000000)); + let mut hardforks = OpHardfork::base_sepolia(); + hardforks.insert(OpHardfork::Holocene.boxed(), ForkCondition::Timestamp(1800000000)); Arc::new(OpChainSpec { inner: ChainSpec { chain: BASE_SEPOLIA.inner.chain, diff --git a/crates/optimism/chainspec/src/op.rs b/crates/optimism/chainspec/src/op.rs index 5afb236cd33..fcbe7dee7dd 100644 --- a/crates/optimism/chainspec/src/op.rs +++ b/crates/optimism/chainspec/src/op.rs @@ -7,7 +7,7 @@ use alloy_eips::eip1559::ETHEREUM_BLOCK_GAS_LIMIT; use alloy_primitives::{b256, U256}; use reth_chainspec::{once_cell_set, BaseFeeParams, BaseFeeParamsKind, ChainSpec}; use reth_ethereum_forks::EthereumHardfork; -use reth_optimism_forks::OptimismHardfork; +use reth_optimism_forks::OpHardfork; use crate::{LazyLock, OpChainSpec}; @@ -24,11 +24,11 @@ pub static OP_MAINNET: LazyLock> = LazyLock::new(|| { "7ca38a1916c42007829c55e69d3e9a73265554b586a499015373241b8a3fa48b" )), paris_block_and_final_difficulty: Some((0, U256::from(0))), - hardforks: OptimismHardfork::op_mainnet(), + hardforks: OpHardfork::op_mainnet(), base_fee_params: BaseFeeParamsKind::Variable( vec![ (EthereumHardfork::London.boxed(), BaseFeeParams::optimism()), - (OptimismHardfork::Canyon.boxed(), BaseFeeParams::optimism_canyon()), + (OpHardfork::Canyon.boxed(), BaseFeeParams::optimism_canyon()), ] .into(), ), diff --git a/crates/optimism/chainspec/src/op_sepolia.rs b/crates/optimism/chainspec/src/op_sepolia.rs index 31c9eda6bdd..35466cb2154 100644 --- a/crates/optimism/chainspec/src/op_sepolia.rs +++ b/crates/optimism/chainspec/src/op_sepolia.rs @@ -7,7 +7,7 @@ use alloy_eips::eip1559::ETHEREUM_BLOCK_GAS_LIMIT; use alloy_primitives::{b256, U256}; use reth_chainspec::{once_cell_set, BaseFeeParams, BaseFeeParamsKind, ChainSpec}; use reth_ethereum_forks::EthereumHardfork; -use reth_optimism_forks::OptimismHardfork; +use reth_optimism_forks::OpHardfork; use crate::{LazyLock, OpChainSpec}; @@ -22,11 +22,11 @@ pub static OP_SEPOLIA: LazyLock> = LazyLock::new(|| { "102de6ffb001480cc9b8b548fd05c34cd4f46ae4aa91759393db90ea0409887d" )), paris_block_and_final_difficulty: Some((0, U256::from(0))), - hardforks: OptimismHardfork::op_sepolia(), + hardforks: OpHardfork::op_sepolia(), base_fee_params: BaseFeeParamsKind::Variable( vec![ (EthereumHardfork::London.boxed(), BaseFeeParams::optimism_sepolia()), - (OptimismHardfork::Canyon.boxed(), BaseFeeParams::optimism_sepolia_canyon()), + (OpHardfork::Canyon.boxed(), BaseFeeParams::optimism_sepolia_canyon()), ] .into(), ), diff --git a/crates/optimism/consensus/src/proof.rs b/crates/optimism/consensus/src/proof.rs index b283356016c..813e451da25 100644 --- a/crates/optimism/consensus/src/proof.rs +++ b/crates/optimism/consensus/src/proof.rs @@ -2,7 +2,7 @@ use alloy_primitives::B256; use reth_chainspec::ChainSpec; -use reth_optimism_forks::OptimismHardfork; +use reth_optimism_forks::OpHardfork; use reth_primitives::{Receipt, ReceiptWithBloom, ReceiptWithBloomRef}; use reth_trie_common::root::ordered_trie_root_with_encoder; @@ -17,8 +17,8 @@ pub(crate) fn calculate_receipt_root_optimism( // encoding. In the Regolith Hardfork, we must strip the deposit nonce from the // receipts before calculating the receipt root. This was corrected in the Canyon // hardfork. - if chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Regolith, timestamp) && - !chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Canyon, timestamp) + if chain_spec.is_fork_active_at_timestamp(OpHardfork::Regolith, timestamp) && + !chain_spec.is_fork_active_at_timestamp(OpHardfork::Canyon, timestamp) { let receipts = receipts .iter() @@ -50,8 +50,8 @@ pub fn calculate_receipt_root_no_memo_optimism( // encoding. In the Regolith Hardfork, we must strip the deposit nonce from the // receipts before calculating the receipt root. This was corrected in the Canyon // hardfork. - if chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Regolith, timestamp) && - !chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Canyon, timestamp) + if chain_spec.is_fork_active_at_timestamp(OpHardfork::Regolith, timestamp) && + !chain_spec.is_fork_active_at_timestamp(OpHardfork::Canyon, timestamp) { let receipts = receipts .iter() diff --git a/crates/optimism/evm/src/config.rs b/crates/optimism/evm/src/config.rs index b00341ff677..f2d35ba56c4 100644 --- a/crates/optimism/evm/src/config.rs +++ b/crates/optimism/evm/src/config.rs @@ -1,6 +1,6 @@ use reth_ethereum_forks::{EthereumHardfork, Head}; use reth_optimism_chainspec::OpChainSpec; -use reth_optimism_forks::OptimismHardfork; +use reth_optimism_forks::OpHardfork; /// Returns the revm [`SpecId`](revm_primitives::SpecId) at the given timestamp. /// @@ -12,17 +12,17 @@ pub fn revm_spec_by_timestamp_after_bedrock( chain_spec: &OpChainSpec, timestamp: u64, ) -> revm_primitives::SpecId { - if chain_spec.fork(OptimismHardfork::Holocene).active_at_timestamp(timestamp) { + if chain_spec.fork(OpHardfork::Holocene).active_at_timestamp(timestamp) { revm_primitives::HOLOCENE - } else if chain_spec.fork(OptimismHardfork::Granite).active_at_timestamp(timestamp) { + } else if chain_spec.fork(OpHardfork::Granite).active_at_timestamp(timestamp) { revm_primitives::GRANITE - } else if chain_spec.fork(OptimismHardfork::Fjord).active_at_timestamp(timestamp) { + } else if chain_spec.fork(OpHardfork::Fjord).active_at_timestamp(timestamp) { revm_primitives::FJORD - } else if chain_spec.fork(OptimismHardfork::Ecotone).active_at_timestamp(timestamp) { + } else if chain_spec.fork(OpHardfork::Ecotone).active_at_timestamp(timestamp) { revm_primitives::ECOTONE - } else if chain_spec.fork(OptimismHardfork::Canyon).active_at_timestamp(timestamp) { + } else if chain_spec.fork(OpHardfork::Canyon).active_at_timestamp(timestamp) { revm_primitives::CANYON - } else if chain_spec.fork(OptimismHardfork::Regolith).active_at_timestamp(timestamp) { + } else if chain_spec.fork(OpHardfork::Regolith).active_at_timestamp(timestamp) { revm_primitives::REGOLITH } else { revm_primitives::BEDROCK @@ -31,19 +31,19 @@ pub fn revm_spec_by_timestamp_after_bedrock( /// Map the latest active hardfork at the given block to a revm [`SpecId`](revm_primitives::SpecId). pub fn revm_spec(chain_spec: &OpChainSpec, block: &Head) -> revm_primitives::SpecId { - if chain_spec.fork(OptimismHardfork::Holocene).active_at_head(block) { + if chain_spec.fork(OpHardfork::Holocene).active_at_head(block) { revm_primitives::HOLOCENE - } else if chain_spec.fork(OptimismHardfork::Granite).active_at_head(block) { + } else if chain_spec.fork(OpHardfork::Granite).active_at_head(block) { revm_primitives::GRANITE - } else if chain_spec.fork(OptimismHardfork::Fjord).active_at_head(block) { + } else if chain_spec.fork(OpHardfork::Fjord).active_at_head(block) { revm_primitives::FJORD - } else if chain_spec.fork(OptimismHardfork::Ecotone).active_at_head(block) { + } else if chain_spec.fork(OpHardfork::Ecotone).active_at_head(block) { revm_primitives::ECOTONE - } else if chain_spec.fork(OptimismHardfork::Canyon).active_at_head(block) { + } else if chain_spec.fork(OpHardfork::Canyon).active_at_head(block) { revm_primitives::CANYON - } else if chain_spec.fork(OptimismHardfork::Regolith).active_at_head(block) { + } else if chain_spec.fork(OpHardfork::Regolith).active_at_head(block) { revm_primitives::REGOLITH - } else if chain_spec.fork(OptimismHardfork::Bedrock).active_at_head(block) { + } else if chain_spec.fork(OpHardfork::Bedrock).active_at_head(block) { revm_primitives::BEDROCK } else if chain_spec.fork(EthereumHardfork::Prague).active_at_head(block) { revm_primitives::PRAGUE diff --git a/crates/optimism/evm/src/execute.rs b/crates/optimism/evm/src/execute.rs index 8d701cda423..2b004e6eb9d 100644 --- a/crates/optimism/evm/src/execute.rs +++ b/crates/optimism/evm/src/execute.rs @@ -19,7 +19,7 @@ use reth_evm::{ }; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_consensus::validate_block_post_execution; -use reth_optimism_forks::OptimismHardfork; +use reth_optimism_forks::OpHardfork; use reth_primitives::{BlockWithSenders, Header, Receipt, TxType}; use reth_revm::{Database, State}; use revm_primitives::{ @@ -158,7 +158,7 @@ where let mut evm = self.evm_config.evm_with_env(&mut self.state, env); let is_regolith = - self.chain_spec.fork(OptimismHardfork::Regolith).active_at_timestamp(block.timestamp); + self.chain_spec.fork(OpHardfork::Regolith).active_at_timestamp(block.timestamp); let mut cumulative_gas_used = 0; let mut receipts = Vec::with_capacity(block.body.transactions.len()); @@ -233,7 +233,7 @@ where // this is only set for post-Canyon deposit transactions. deposit_receipt_version: (transaction.is_deposit() && self.chain_spec - .is_fork_active_at_timestamp(OptimismHardfork::Canyon, block.timestamp)) + .is_fork_active_at_timestamp(OpHardfork::Canyon, block.timestamp)) .then_some(1), }); } diff --git a/crates/optimism/evm/src/l1.rs b/crates/optimism/evm/src/l1.rs index cdd33510c92..6ff841b9ddc 100644 --- a/crates/optimism/evm/src/l1.rs +++ b/crates/optimism/evm/src/l1.rs @@ -6,7 +6,7 @@ use alloy_primitives::{address, b256, hex, Address, Bytes, B256, U256}; use reth_chainspec::ChainSpec; use reth_execution_errors::BlockExecutionError; use reth_optimism_chainspec::OpChainSpec; -use reth_optimism_forks::OptimismHardfork; +use reth_optimism_forks::OpHardfork; use reth_primitives::BlockBody; use revm::{ primitives::{Bytecode, HashMap, SpecId}, @@ -215,14 +215,13 @@ impl RethL1BlockInfo for L1BlockInfo { return Ok(U256::ZERO) } - let spec_id = if chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Fjord, timestamp) - { + let spec_id = if chain_spec.is_fork_active_at_timestamp(OpHardfork::Fjord, timestamp) { SpecId::FJORD - } else if chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Ecotone, timestamp) { + } else if chain_spec.is_fork_active_at_timestamp(OpHardfork::Ecotone, timestamp) { SpecId::ECOTONE - } else if chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Regolith, timestamp) { + } else if chain_spec.is_fork_active_at_timestamp(OpHardfork::Regolith, timestamp) { SpecId::REGOLITH - } else if chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Bedrock, timestamp) { + } else if chain_spec.is_fork_active_at_timestamp(OpHardfork::Bedrock, timestamp) { SpecId::BEDROCK } else { return Err(OpBlockExecutionError::L1BlockInfoError { @@ -239,12 +238,11 @@ impl RethL1BlockInfo for L1BlockInfo { timestamp: u64, input: &[u8], ) -> Result { - let spec_id = if chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Fjord, timestamp) - { + let spec_id = if chain_spec.is_fork_active_at_timestamp(OpHardfork::Fjord, timestamp) { SpecId::FJORD - } else if chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Regolith, timestamp) { + } else if chain_spec.is_fork_active_at_timestamp(OpHardfork::Regolith, timestamp) { SpecId::REGOLITH - } else if chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Bedrock, timestamp) { + } else if chain_spec.is_fork_active_at_timestamp(OpHardfork::Bedrock, timestamp) { SpecId::BEDROCK } else { return Err(OpBlockExecutionError::L1BlockInfoError { @@ -270,9 +268,8 @@ where // If the canyon hardfork is active at the current timestamp, and it was not active at the // previous block timestamp (heuristically, block time is not perfectly constant at 2s), and the // chain is an optimism chain, then we need to force-deploy the create2 deployer contract. - if chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Canyon, timestamp) && - !chain_spec - .is_fork_active_at_timestamp(OptimismHardfork::Canyon, timestamp.saturating_sub(2)) + if chain_spec.is_fork_active_at_timestamp(OpHardfork::Canyon, timestamp) && + !chain_spec.is_fork_active_at_timestamp(OpHardfork::Canyon, timestamp.saturating_sub(2)) { trace!(target: "evm", "Forcing create2 deployer contract deployment on Canyon transition"); diff --git a/crates/optimism/hardforks/src/dev.rs b/crates/optimism/hardforks/src/dev.rs index 328ef501c46..5fe77a31402 100644 --- a/crates/optimism/hardforks/src/dev.rs +++ b/crates/optimism/hardforks/src/dev.rs @@ -24,13 +24,13 @@ pub static DEV_HARDFORKS: LazyLock = LazyLock::new(|| { EthereumHardfork::Paris.boxed(), ForkCondition::TTD { fork_block: None, total_difficulty: U256::ZERO }, ), - (crate::OptimismHardfork::Bedrock.boxed(), ForkCondition::Block(0)), - (crate::OptimismHardfork::Regolith.boxed(), ForkCondition::Timestamp(0)), + (crate::OpHardfork::Bedrock.boxed(), ForkCondition::Block(0)), + (crate::OpHardfork::Regolith.boxed(), ForkCondition::Timestamp(0)), (EthereumHardfork::Shanghai.boxed(), ForkCondition::Timestamp(0)), - (crate::OptimismHardfork::Canyon.boxed(), ForkCondition::Timestamp(0)), + (crate::OpHardfork::Canyon.boxed(), ForkCondition::Timestamp(0)), (EthereumHardfork::Cancun.boxed(), ForkCondition::Timestamp(0)), - (crate::OptimismHardfork::Ecotone.boxed(), ForkCondition::Timestamp(0)), - (crate::OptimismHardfork::Fjord.boxed(), ForkCondition::Timestamp(0)), - (crate::OptimismHardfork::Granite.boxed(), ForkCondition::Timestamp(0)), + (crate::OpHardfork::Ecotone.boxed(), ForkCondition::Timestamp(0)), + (crate::OpHardfork::Fjord.boxed(), ForkCondition::Timestamp(0)), + (crate::OpHardfork::Granite.boxed(), ForkCondition::Timestamp(0)), ]) }); diff --git a/crates/optimism/hardforks/src/hardfork.rs b/crates/optimism/hardforks/src/hardfork.rs index 440314e3711..9a9786a8fe0 100644 --- a/crates/optimism/hardforks/src/hardfork.rs +++ b/crates/optimism/hardforks/src/hardfork.rs @@ -18,7 +18,7 @@ hardfork!( /// /// When building a list of hardforks for a chain, it's still expected to mix with /// [`EthereumHardfork`]. - OptimismHardfork { + OpHardfork { /// Bedrock: . Bedrock, /// Regolith: . @@ -36,7 +36,7 @@ hardfork!( } ); -impl OptimismHardfork { +impl OpHardfork { /// Retrieves the activation block for the specified hardfork on the given chain. pub fn activation_block(self, fork: H, chain: Chain) -> Option { if chain == Chain::base_sepolia() { @@ -328,13 +328,13 @@ fn match_hardfork(fork: H, hardfork_fn: HF, optimism_hardfork_fn: OH where H: Hardfork, HF: Fn(&EthereumHardfork) -> Option, - OHF: Fn(&OptimismHardfork) -> Option, + OHF: Fn(&OpHardfork) -> Option, { let fork: &dyn Any = ⋔ if let Some(fork) = fork.downcast_ref::() { return hardfork_fn(fork) } - fork.downcast_ref::().and_then(optimism_hardfork_fn) + fork.downcast_ref::().and_then(optimism_hardfork_fn) } #[cfg(test)] @@ -346,35 +346,32 @@ mod tests { #[test] fn test_match_hardfork() { assert_eq!( - OptimismHardfork::base_mainnet_activation_block(EthereumHardfork::Cancun), + OpHardfork::base_mainnet_activation_block(EthereumHardfork::Cancun), Some(11188936) ); - assert_eq!( - OptimismHardfork::base_mainnet_activation_block(OptimismHardfork::Canyon), - Some(9101527) - ); + assert_eq!(OpHardfork::base_mainnet_activation_block(OpHardfork::Canyon), Some(9101527)); } #[test] fn check_op_hardfork_from_str() { let hardfork_str = ["beDrOck", "rEgOlITH", "cAnYoN", "eCoToNe", "FJorD", "GRaNiTe"]; let expected_hardforks = [ - OptimismHardfork::Bedrock, - OptimismHardfork::Regolith, - OptimismHardfork::Canyon, - OptimismHardfork::Ecotone, - OptimismHardfork::Fjord, - OptimismHardfork::Granite, + OpHardfork::Bedrock, + OpHardfork::Regolith, + OpHardfork::Canyon, + OpHardfork::Ecotone, + OpHardfork::Fjord, + OpHardfork::Granite, ]; - let hardforks: Vec = - hardfork_str.iter().map(|h| OptimismHardfork::from_str(h).unwrap()).collect(); + let hardforks: Vec = + hardfork_str.iter().map(|h| OpHardfork::from_str(h).unwrap()).collect(); assert_eq!(hardforks, expected_hardforks); } #[test] fn check_nonexistent_hardfork_from_str() { - assert!(OptimismHardfork::from_str("not a hardfork").is_err()); + assert!(OpHardfork::from_str("not a hardfork").is_err()); } } diff --git a/crates/optimism/hardforks/src/lib.rs b/crates/optimism/hardforks/src/lib.rs index bac0d0e04ed..df159161e0e 100644 --- a/crates/optimism/hardforks/src/lib.rs +++ b/crates/optimism/hardforks/src/lib.rs @@ -14,47 +14,47 @@ pub mod hardfork; mod dev; pub use dev::DEV_HARDFORKS; -pub use hardfork::OptimismHardfork; +pub use hardfork::OpHardfork; use reth_ethereum_forks::EthereumHardforks; /// Extends [`EthereumHardforks`] with optimism helper methods. pub trait OptimismHardforks: EthereumHardforks { - /// Convenience method to check if [`OptimismHardfork::Bedrock`] is active at a given block + /// Convenience method to check if [`OpHardfork::Bedrock`] is active at a given block /// number. fn is_bedrock_active_at_block(&self, block_number: u64) -> bool { - self.fork(OptimismHardfork::Bedrock).active_at_block(block_number) + self.fork(OpHardfork::Bedrock).active_at_block(block_number) } - /// Returns `true` if [`Canyon`](OptimismHardfork::Canyon) is active at given block timestamp. + /// Returns `true` if [`Canyon`](OpHardfork::Canyon) is active at given block timestamp. fn is_canyon_active_at_timestamp(&self, timestamp: u64) -> bool { - self.fork(OptimismHardfork::Canyon).active_at_timestamp(timestamp) + self.fork(OpHardfork::Canyon).active_at_timestamp(timestamp) } - /// Returns `true` if [`Ecotone`](OptimismHardfork::Ecotone) is active at given block timestamp. + /// Returns `true` if [`Ecotone`](OpHardfork::Ecotone) is active at given block timestamp. fn is_ecotone_active_at_timestamp(&self, timestamp: u64) -> bool { - self.fork(OptimismHardfork::Ecotone).active_at_timestamp(timestamp) + self.fork(OpHardfork::Ecotone).active_at_timestamp(timestamp) } - /// Returns `true` if [`Fjord`](OptimismHardfork::Fjord) is active at given block timestamp. + /// Returns `true` if [`Fjord`](OpHardfork::Fjord) is active at given block timestamp. fn is_fjord_active_at_timestamp(&self, timestamp: u64) -> bool { - self.fork(OptimismHardfork::Fjord).active_at_timestamp(timestamp) + self.fork(OpHardfork::Fjord).active_at_timestamp(timestamp) } - /// Returns `true` if [`Granite`](OptimismHardfork::Granite) is active at given block timestamp. + /// Returns `true` if [`Granite`](OpHardfork::Granite) is active at given block timestamp. fn is_granite_active_at_timestamp(&self, timestamp: u64) -> bool { - self.fork(OptimismHardfork::Granite).active_at_timestamp(timestamp) + self.fork(OpHardfork::Granite).active_at_timestamp(timestamp) } - /// Returns `true` if [`Holocene`](OptimismHardfork::Holocene) is active at given block + /// Returns `true` if [`Holocene`](OpHardfork::Holocene) is active at given block /// timestamp. fn is_holocene_active_at_timestamp(&self, timestamp: u64) -> bool { - self.fork(OptimismHardfork::Holocene).active_at_timestamp(timestamp) + self.fork(OpHardfork::Holocene).active_at_timestamp(timestamp) } - /// Returns `true` if [`Regolith`](OptimismHardfork::Regolith) is active at given block + /// Returns `true` if [`Regolith`](OpHardfork::Regolith) is active at given block /// timestamp. fn is_regolith_active_at_timestamp(&self, timestamp: u64) -> bool { - self.fork(OptimismHardfork::Regolith).active_at_timestamp(timestamp) + self.fork(OpHardfork::Regolith).active_at_timestamp(timestamp) } } diff --git a/crates/optimism/node/src/engine.rs b/crates/optimism/node/src/engine.rs index e337a23551e..7400f149a96 100644 --- a/crates/optimism/node/src/engine.rs +++ b/crates/optimism/node/src/engine.rs @@ -14,7 +14,7 @@ use reth_node_api::{ validate_version_specific_fields, EngineTypes, EngineValidator, }; use reth_optimism_chainspec::OpChainSpec; -use reth_optimism_forks::{OptimismHardfork, OptimismHardforks}; +use reth_optimism_forks::{OpHardfork, OptimismHardforks}; use reth_optimism_payload_builder::{OpBuiltPayload, OpPayloadBuilderAttributes}; /// The types used in the optimism beacon consensus engine. @@ -81,7 +81,7 @@ pub fn validate_withdrawals_presence( timestamp: u64, has_withdrawals: bool, ) -> Result<(), EngineObjectValidationError> { - let is_shanghai = chain_spec.fork(OptimismHardfork::Canyon).active_at_timestamp(timestamp); + let is_shanghai = chain_spec.fork(OpHardfork::Canyon).active_at_timestamp(timestamp); match version { EngineApiMessageVersion::V1 => { @@ -178,10 +178,9 @@ mod test { use super::*; fn get_chainspec(is_holocene: bool) -> Arc { - let mut hardforks = OptimismHardfork::base_sepolia(); + let mut hardforks = OpHardfork::base_sepolia(); if is_holocene { - hardforks - .insert(OptimismHardfork::Holocene.boxed(), ForkCondition::Timestamp(1800000000)); + hardforks.insert(OpHardfork::Holocene.boxed(), ForkCondition::Timestamp(1800000000)); } Arc::new(OpChainSpec { inner: ChainSpec { From f86efcc800b4e8f0884b76cd9960dc9f584aae31 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sat, 9 Nov 2024 08:29:27 +0100 Subject: [PATCH 080/211] chore: clippy happy (#12419) --- crates/node/core/src/args/payload_builder.rs | 2 +- crates/node/core/src/version.rs | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/crates/node/core/src/args/payload_builder.rs b/crates/node/core/src/args/payload_builder.rs index 524a93195de..cd7ba7dccfb 100644 --- a/crates/node/core/src/args/payload_builder.rs +++ b/crates/node/core/src/args/payload_builder.rs @@ -86,7 +86,7 @@ impl TypedValueParser for ExtradataValueParser { ) -> Result { let val = value.to_str().ok_or_else(|| clap::Error::new(clap::error::ErrorKind::InvalidUtf8))?; - if val.as_bytes().len() > MAXIMUM_EXTRA_DATA_SIZE { + if val.len() > MAXIMUM_EXTRA_DATA_SIZE { return Err(clap::Error::raw( clap::error::ErrorKind::InvalidValue, format!( diff --git a/crates/node/core/src/version.rs b/crates/node/core/src/version.rs index 84fcf3f0f11..4bf2dc56f39 100644 --- a/crates/node/core/src/version.rs +++ b/crates/node/core/src/version.rs @@ -144,9 +144,6 @@ mod tests { #[test] fn assert_extradata_less_32bytes() { let extradata = default_extradata(); - assert!( - extradata.as_bytes().len() <= 32, - "extradata must be less than 32 bytes: {extradata}" - ) + assert!(extradata.len() <= 32, "extradata must be less than 32 bytes: {extradata}") } } From 7a65cce1e1dd456d1af5202f6604bc8cf8dcff18 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sat, 9 Nov 2024 08:29:41 +0100 Subject: [PATCH 081/211] chore: rm fqs for NodeCore (#12418) --- crates/rpc/rpc/src/debug.rs | 8 ++++---- crates/rpc/rpc/src/eth/bundle.rs | 4 ++-- crates/rpc/rpc/src/eth/sim_bundle.rs | 8 ++------ crates/rpc/rpc/src/trace.rs | 4 ++-- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/crates/rpc/rpc/src/debug.rs b/crates/rpc/rpc/src/debug.rs index 4404515e03c..a74d1b5a155 100644 --- a/crates/rpc/rpc/src/debug.rs +++ b/crates/rpc/rpc/src/debug.rs @@ -27,7 +27,7 @@ use reth_revm::database::StateProviderDatabase; use reth_rpc_api::DebugApiServer; use reth_rpc_eth_api::{ helpers::{EthApiSpec, EthTransactions, TraceExt}, - EthApiTypes, FromEthApiError, RpcNodeCore, + EthApiTypes, FromEthApiError, }; use reth_rpc_eth_types::{EthApiError, StateCacheDb}; use reth_rpc_server_types::{result::internal_rpc_err, ToRpcResult}; @@ -115,7 +115,7 @@ where env: Env::boxed( cfg.cfg_env.clone(), block_env.clone(), - RpcNodeCore::evm_config(this.eth_api()).tx_env(tx, *signer), + this.eth_api().evm_config().tx_env(tx, *signer), ), handler_cfg: cfg.handler_cfg, }; @@ -264,7 +264,7 @@ where env: Env::boxed( cfg.cfg_env.clone(), block_env, - RpcNodeCore::evm_config(this.eth_api()).tx_env(tx.as_signed(), tx.signer()), + this.eth_api().evm_config().tx_env(tx.as_signed(), tx.signer()), ), handler_cfg: cfg.handler_cfg, }; @@ -533,7 +533,7 @@ where env: Env::boxed( cfg.cfg_env.clone(), block_env.clone(), - RpcNodeCore::evm_config(this.eth_api()).tx_env(tx, *signer), + this.eth_api().evm_config().tx_env(tx, *signer), ), handler_cfg: cfg.handler_cfg, }; diff --git a/crates/rpc/rpc/src/eth/bundle.rs b/crates/rpc/rpc/src/eth/bundle.rs index db8c01c5c3b..a2e0be30437 100644 --- a/crates/rpc/rpc/src/eth/bundle.rs +++ b/crates/rpc/rpc/src/eth/bundle.rs @@ -167,7 +167,7 @@ where let mut total_gas_fess = U256::ZERO; let mut hasher = Keccak256::new(); - let mut evm = RpcNodeCore::evm_config(ð_api).evm_with_env(db, env); + let mut evm = eth_api.evm_config().evm_with_env(db, env); let mut results = Vec::with_capacity(transactions.len()); let mut transactions = transactions.into_iter().peekable(); @@ -188,7 +188,7 @@ where .effective_tip_per_gas(basefee) .ok_or_else(|| RpcInvalidTransactionError::FeeCapTooLow) .map_err(Eth::Error::from_eth_err)?; - RpcNodeCore::evm_config(ð_api).fill_tx_env(evm.tx_mut(), &tx, signer); + eth_api.evm_config().fill_tx_env(evm.tx_mut(), &tx, signer); let ResultAndState { result, state } = evm.transact().map_err(Eth::Error::from_evm_err)?; diff --git a/crates/rpc/rpc/src/eth/sim_bundle.rs b/crates/rpc/rpc/src/eth/sim_bundle.rs index f49d7984f8b..40d951f755f 100644 --- a/crates/rpc/rpc/src/eth/sim_bundle.rs +++ b/crates/rpc/rpc/src/eth/sim_bundle.rs @@ -307,7 +307,7 @@ where let mut refundable_value = U256::ZERO; let mut body_logs: Vec = Vec::new(); - let mut evm = RpcNodeCore::evm_config(ð_api).evm_with_env(db, env); + let mut evm = eth_api.evm_config().evm_with_env(db, env); for item in &flattened_bundle { // Check inclusion constraints @@ -323,11 +323,7 @@ where ) .into()); } - RpcNodeCore::evm_config(ð_api).fill_tx_env( - evm.tx_mut(), - &item.tx, - item.signer, - ); + eth_api.evm_config().fill_tx_env(evm.tx_mut(), &item.tx, item.signer); let ResultAndState { result, state } = evm.transact().map_err(EthApiError::from_eth_err)?; diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 41bc0ad2098..45c5f1a3bc3 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -22,7 +22,7 @@ use reth_primitives::Header; use reth_provider::{BlockReader, ChainSpecProvider, EvmEnvProvider, StateProviderFactory}; use reth_revm::database::StateProviderDatabase; use reth_rpc_api::TraceApiServer; -use reth_rpc_eth_api::{helpers::TraceExt, FromEthApiError, RpcNodeCore}; +use reth_rpc_eth_api::{helpers::TraceExt, FromEthApiError}; use reth_rpc_eth_types::{error::EthApiError, utils::recover_raw_transaction}; use reth_tasks::pool::BlockingTaskGuard; use revm::{ @@ -122,7 +122,7 @@ where let env = EnvWithHandlerCfg::new_with_cfg_env( cfg, block, - RpcNodeCore::evm_config(self.eth_api()).tx_env(tx.as_signed(), tx.signer()), + self.eth_api().evm_config().tx_env(tx.as_signed(), tx.signer()), ); let config = TracingInspectorConfig::from_parity_config(&trace_types); From b5fce61738d28a8d5c76a925025d78f833c11963 Mon Sep 17 00:00:00 2001 From: nk_ysg Date: Sat, 9 Nov 2024 15:42:37 +0800 Subject: [PATCH 082/211] ecies: use align_num value (#12139) Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com> --- crates/net/ecies/src/algorithm.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/crates/net/ecies/src/algorithm.rs b/crates/net/ecies/src/algorithm.rs index e4266d9a06f..f799b6c7f6c 100644 --- a/crates/net/ecies/src/algorithm.rs +++ b/crates/net/ecies/src/algorithm.rs @@ -688,7 +688,7 @@ impl ECIES { pub fn body_len(&self) -> usize { let len = self.body_size.unwrap(); - (if len % 16 == 0 { len } else { (len / 16 + 1) * 16 }) + 16 + Self::align_16(len) + 16 } #[cfg(test)] @@ -699,7 +699,7 @@ impl ECIES { } pub fn write_body(&mut self, out: &mut BytesMut, data: &[u8]) { - let len = if data.len() % 16 == 0 { data.len() } else { (data.len() / 16 + 1) * 16 }; + let len = Self::align_16(data.len()); let old_len = out.len(); out.resize(old_len + len, 0); @@ -732,6 +732,14 @@ impl ECIES { self.ingress_aes.as_mut().unwrap().apply_keystream(ret); Ok(split_at_mut(ret, size)?.0) } + + /// Returns `num` aligned to 16. + /// + /// `` + #[inline] + const fn align_16(num: usize) -> usize { + (num + (16 - 1)) & !(16 - 1) + } } #[cfg(test)] From d2f494bd88b17af65244473bfe81e676dc8c422f Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Sat, 9 Nov 2024 08:55:06 +0100 Subject: [PATCH 083/211] primitives: replace primitive `Withdrawals` with alloy (#12119) Co-authored-by: joshieDo <93316087+joshieDo@users.noreply.github.com> Co-authored-by: Matthias Seitz --- .../cli/commands/src/test_vectors/compact.rs | 5 +- crates/evm/src/state_change.rs | 4 +- crates/optimism/storage/src/lib.rs | 4 +- crates/primitives-traits/src/lib.rs | 2 +- crates/primitives-traits/src/withdrawal.rs | 85 ++----------------- crates/storage/codecs/src/alloy/withdrawal.rs | 29 ++++++- crates/storage/db-api/src/models/mod.rs | 4 +- 7 files changed, 41 insertions(+), 92 deletions(-) diff --git a/crates/cli/commands/src/test_vectors/compact.rs b/crates/cli/commands/src/test_vectors/compact.rs index c2995170057..c498718e9fc 100644 --- a/crates/cli/commands/src/test_vectors/compact.rs +++ b/crates/cli/commands/src/test_vectors/compact.rs @@ -1,3 +1,4 @@ +use alloy_eips::eip4895::Withdrawals; use alloy_primitives::{hex, private::getrandom::getrandom, PrimitiveSignature, TxKind}; use arbitrary::Arbitrary; use eyre::{Context, Result}; @@ -22,7 +23,7 @@ use reth_db::{ use reth_fs_util as fs; use reth_primitives::{ Account, Log, LogData, Receipt, ReceiptWithBloom, StorageEntry, Transaction, - TransactionSignedNoHash, TxType, Withdrawals, + TransactionSignedNoHash, TxType, }; use reth_prune_types::{PruneCheckpoint, PruneMode}; use reth_stages_types::{ @@ -75,7 +76,6 @@ compact_types!( // reth-primitives Account, Receipt, - Withdrawals, ReceiptWithBloom, // reth_codecs::alloy Authorization, @@ -83,6 +83,7 @@ compact_types!( Header, HeaderExt, Withdrawal, + Withdrawals, TxEip2930, TxEip1559, TxEip4844, diff --git a/crates/evm/src/state_change.rs b/crates/evm/src/state_change.rs index 2d91ac30eeb..0e207fc2dbe 100644 --- a/crates/evm/src/state_change.rs +++ b/crates/evm/src/state_change.rs @@ -4,7 +4,7 @@ use alloy_eips::eip4895::Withdrawal; use alloy_primitives::{map::HashMap, Address, U256}; use reth_chainspec::EthereumHardforks; use reth_consensus_common::calc; -use reth_primitives::{Block, Withdrawals}; +use reth_primitives::Block; /// Collect all balance changes at the end of the block. /// @@ -37,7 +37,7 @@ pub fn post_block_balance_increments( insert_post_block_withdrawals_balance_increments( chain_spec, block.timestamp, - block.body.withdrawals.as_ref().map(Withdrawals::as_ref), + block.body.withdrawals.as_ref().map(|w| w.as_slice()), &mut balance_increments, ); diff --git a/crates/optimism/storage/src/lib.rs b/crates/optimism/storage/src/lib.rs index 347b690c5c7..c3b8a71feea 100644 --- a/crates/optimism/storage/src/lib.rs +++ b/crates/optimism/storage/src/lib.rs @@ -16,7 +16,7 @@ mod tests { CompactClientVersion, CompactU256, CompactU64, StoredBlockBodyIndices, StoredBlockOmmers, StoredBlockWithdrawals, }; - use reth_primitives::{Account, Receipt, ReceiptWithBloom, Withdrawals}; + use reth_primitives::{Account, Receipt, ReceiptWithBloom}; use reth_prune_types::{PruneCheckpoint, PruneMode, PruneSegment}; use reth_stages_types::{ AccountHashingCheckpoint, CheckpointBlockRange, EntitiesCheckpoint, ExecutionCheckpoint, @@ -47,7 +47,6 @@ mod tests { assert_eq!(StoredBlockOmmers::bitflag_encoded_bytes(), 0); assert_eq!(StoredBlockWithdrawals::bitflag_encoded_bytes(), 0); assert_eq!(StorageHashingCheckpoint::bitflag_encoded_bytes(), 1); - assert_eq!(Withdrawals::bitflag_encoded_bytes(), 0); // In case of failure, refer to the documentation of the // [`validate_bitflag_backwards_compat`] macro for detailed instructions on handling @@ -73,6 +72,5 @@ mod tests { validate_bitflag_backwards_compat!(StoredBlockOmmers, UnusedBits::Zero); validate_bitflag_backwards_compat!(StoredBlockWithdrawals, UnusedBits::Zero); validate_bitflag_backwards_compat!(StorageHashingCheckpoint, UnusedBits::NotZero); - validate_bitflag_backwards_compat!(Withdrawals, UnusedBits::Zero); } } diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index 3316e713541..9f27726aeca 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -37,7 +37,7 @@ pub mod block; pub use block::{body::BlockBody, Block, FullBlock}; mod withdrawal; -pub use withdrawal::Withdrawals; +pub use withdrawal::{Withdrawal, Withdrawals}; mod error; pub use error::{GotExpected, GotExpectedBoxed}; diff --git a/crates/primitives-traits/src/withdrawal.rs b/crates/primitives-traits/src/withdrawal.rs index 8f072afa578..9c6d8b69797 100644 --- a/crates/primitives-traits/src/withdrawal.rs +++ b/crates/primitives-traits/src/withdrawal.rs @@ -1,86 +1,11 @@ //! [EIP-4895](https://eips.ethereum.org/EIPS/eip-4895) Withdrawal types. -use alloc::vec::Vec; -use alloy_eips::eip4895::Withdrawal; -use alloy_rlp::{RlpDecodableWrapper, RlpEncodableWrapper}; -use derive_more::{AsRef, Deref, DerefMut, From, IntoIterator}; -use reth_codecs::{add_arbitrary_tests, Compact}; -use serde::{Deserialize, Serialize}; +/// Re-export from `alloy_eips`. +#[doc(inline)] +pub use alloy_eips::eip4895::Withdrawal; /// Represents a collection of Withdrawals. -#[derive( - Debug, - Clone, - PartialEq, - Eq, - Default, - Hash, - From, - AsRef, - Deref, - DerefMut, - IntoIterator, - RlpEncodableWrapper, - RlpDecodableWrapper, - Serialize, - Deserialize, - Compact, -)] -#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] -#[add_arbitrary_tests(compact)] -#[as_ref(forward)] -pub struct Withdrawals(Vec); - -impl Withdrawals { - /// Create a new Withdrawals instance. - pub const fn new(withdrawals: Vec) -> Self { - Self(withdrawals) - } - - /// Calculate the total size, including capacity, of the Withdrawals. - #[inline] - pub fn total_size(&self) -> usize { - self.capacity() * core::mem::size_of::() - } - - /// Calculate a heuristic for the in-memory size of the [Withdrawals]. - #[inline] - pub fn size(&self) -> usize { - self.len() * core::mem::size_of::() - } - - /// Get an iterator over the Withdrawals. - pub fn iter(&self) -> core::slice::Iter<'_, Withdrawal> { - self.0.iter() - } - - /// Get a mutable iterator over the Withdrawals. - pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, Withdrawal> { - self.0.iter_mut() - } - - /// Convert [Self] into raw vec of withdrawals. - pub fn into_inner(self) -> Vec { - self.0 - } -} - -impl<'a> IntoIterator for &'a Withdrawals { - type Item = &'a Withdrawal; - type IntoIter = core::slice::Iter<'a, Withdrawal>; - fn into_iter(self) -> Self::IntoIter { - self.iter() - } -} - -impl<'a> IntoIterator for &'a mut Withdrawals { - type Item = &'a mut Withdrawal; - type IntoIter = core::slice::IterMut<'a, Withdrawal>; - - fn into_iter(self) -> Self::IntoIter { - self.iter_mut() - } -} +pub type Withdrawals = alloy_eips::eip4895::Withdrawals; #[cfg(test)] mod tests { @@ -89,6 +14,8 @@ mod tests { use alloy_rlp::{RlpDecodable, RlpEncodable}; use proptest::proptest; use proptest_arbitrary_interop::arb; + use reth_codecs::{add_arbitrary_tests, Compact}; + use serde::{Deserialize, Serialize}; /// This type is kept for compatibility tests after the codec support was added to alloy-eips /// Withdrawal type natively diff --git a/crates/storage/codecs/src/alloy/withdrawal.rs b/crates/storage/codecs/src/alloy/withdrawal.rs index 8aa5671798d..09e80d1faa7 100644 --- a/crates/storage/codecs/src/alloy/withdrawal.rs +++ b/crates/storage/codecs/src/alloy/withdrawal.rs @@ -1,7 +1,8 @@ //! Compact implementation for [`AlloyWithdrawal`] use crate::Compact; -use alloy_eips::eip4895::Withdrawal as AlloyWithdrawal; +use alloc::vec::Vec; +use alloy_eips::eip4895::{Withdrawal as AlloyWithdrawal, Withdrawals}; use alloy_primitives::Address; use reth_codecs_derive::add_arbitrary_tests; @@ -53,6 +54,22 @@ impl Compact for AlloyWithdrawal { } } +impl Compact for Withdrawals { + fn to_compact(&self, buf: &mut B) -> usize + where + B: bytes::BufMut + AsMut<[u8]>, + { + self.as_ref().to_compact(buf) + } + + fn from_compact(mut buf: &[u8], _: usize) -> (Self, &[u8]) { + let (withdrawals, new_buf) = Vec::from_compact(buf, buf.len()); + buf = new_buf; + let alloy_withdrawals = Self::new(withdrawals); + (alloy_withdrawals, buf) + } +} + #[cfg(test)] mod tests { use super::*; @@ -61,12 +78,20 @@ mod tests { proptest! { #[test] - fn roundtrip(withdrawal in arb::()) { + fn roundtrip_withdrawal(withdrawal in arb::()) { let mut compacted_withdrawal = Vec::::new(); let len = withdrawal.to_compact(&mut compacted_withdrawal); let (decoded, _) = AlloyWithdrawal::from_compact(&compacted_withdrawal, len); assert_eq!(withdrawal, decoded) } + + #[test] + fn roundtrip_withdrawals(withdrawals in arb::()) { + let mut compacted_withdrawals = Vec::::new(); + let len = withdrawals.to_compact(&mut compacted_withdrawals); + let (decoded, _) = Withdrawals::from_compact(&compacted_withdrawals, len); + assert_eq!(withdrawals, decoded); + } } // each value in the database has an extra field named flags that encodes metadata about other diff --git a/crates/storage/db-api/src/models/mod.rs b/crates/storage/db-api/src/models/mod.rs index b077027f297..fc3351b73b6 100644 --- a/crates/storage/db-api/src/models/mod.rs +++ b/crates/storage/db-api/src/models/mod.rs @@ -313,7 +313,7 @@ mod tests { fn test_ensure_backwards_compatibility() { use super::*; use reth_codecs::{test_utils::UnusedBits, validate_bitflag_backwards_compat}; - use reth_primitives::{Account, Receipt, ReceiptWithBloom, Withdrawals}; + use reth_primitives::{Account, Receipt, ReceiptWithBloom}; use reth_prune_types::{PruneCheckpoint, PruneMode, PruneSegment}; use reth_stages_types::{ AccountHashingCheckpoint, CheckpointBlockRange, EntitiesCheckpoint, @@ -341,7 +341,6 @@ mod tests { assert_eq!(StoredBlockOmmers::bitflag_encoded_bytes(), 0); assert_eq!(StoredBlockWithdrawals::bitflag_encoded_bytes(), 0); assert_eq!(StorageHashingCheckpoint::bitflag_encoded_bytes(), 1); - assert_eq!(Withdrawals::bitflag_encoded_bytes(), 0); validate_bitflag_backwards_compat!(Account, UnusedBits::NotZero); validate_bitflag_backwards_compat!(AccountHashingCheckpoint, UnusedBits::NotZero); @@ -364,6 +363,5 @@ mod tests { validate_bitflag_backwards_compat!(StoredBlockOmmers, UnusedBits::Zero); validate_bitflag_backwards_compat!(StoredBlockWithdrawals, UnusedBits::Zero); validate_bitflag_backwards_compat!(StorageHashingCheckpoint, UnusedBits::NotZero); - validate_bitflag_backwards_compat!(Withdrawals, UnusedBits::Zero); } } From 08451ef278dfaa8818738d7d67e653833c52f6b7 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sat, 9 Nov 2024 10:05:15 +0100 Subject: [PATCH 084/211] chore: rm unused file (#12420) --- .../{transaction/mod.rs => transaction.rs} | 0 .../src/transaction/signature.rs | 52 ------------------- 2 files changed, 52 deletions(-) rename crates/rpc/rpc-types-compat/src/{transaction/mod.rs => transaction.rs} (100%) delete mode 100644 crates/rpc/rpc-types-compat/src/transaction/signature.rs diff --git a/crates/rpc/rpc-types-compat/src/transaction/mod.rs b/crates/rpc/rpc-types-compat/src/transaction.rs similarity index 100% rename from crates/rpc/rpc-types-compat/src/transaction/mod.rs rename to crates/rpc/rpc-types-compat/src/transaction.rs diff --git a/crates/rpc/rpc-types-compat/src/transaction/signature.rs b/crates/rpc/rpc-types-compat/src/transaction/signature.rs deleted file mode 100644 index 77ae365b2da..00000000000 --- a/crates/rpc/rpc-types-compat/src/transaction/signature.rs +++ /dev/null @@ -1,52 +0,0 @@ -use alloy_primitives::{Signature as PrimitiveSignature, U256}; -use alloy_rpc_types::{Parity, Signature}; -use reth_primitives::{transaction::legacy_parity, TxType}; - -/// Creates a new rpc signature from a legacy [primitive -/// signature](alloy_primitives::Signature), using the give chain id to compute the signature's -/// recovery id. -/// -/// If the chain id is `Some`, the recovery id is computed according to [EIP-155](https://eips.ethereum.org/EIPS/eip-155). -pub fn from_legacy_primitive_signature( - signature: PrimitiveSignature, - chain_id: Option, -) -> Signature { - Signature { - r: signature.r(), - s: signature.s(), - v: U256::from(legacy_parity(&signature, chain_id).to_u64()), - y_parity: None, - } -} - -/// Creates a new rpc signature from a non-legacy [primitive -/// signature](alloy_primitives::Signature). This sets the `v` value to `0` or `1` depending on -/// the signature's `odd_y_parity`. -pub fn from_typed_primitive_signature(signature: PrimitiveSignature) -> Signature { - Signature { - r: signature.r(), - s: signature.s(), - v: U256::from(signature.v().y_parity_byte()), - y_parity: Some(Parity(signature.v().y_parity())), - } -} - -/// Creates a new rpc signature from a legacy [primitive -/// signature](alloy_primitives::Signature). -/// -/// The tx type is used to determine whether or not to use the `chain_id` to compute the -/// signature's recovery id. -/// -/// If the transaction is a legacy transaction, it will use the `chain_id` to compute the -/// signature's recovery id. If the transaction is a typed transaction, it will set the `v` -/// value to `0` or `1` depending on the signature's `odd_y_parity`. -pub fn from_primitive_signature( - signature: PrimitiveSignature, - tx_type: TxType, - chain_id: Option, -) -> Signature { - match tx_type { - TxType::Legacy => from_legacy_primitive_signature(signature, chain_id), - _ => from_typed_primitive_signature(signature), - } -} From 430fe0de18547f38786a212f365364c1d4902b77 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Sat, 9 Nov 2024 10:20:25 +0100 Subject: [PATCH 085/211] chore(sdk): Add `NodePrimitives::Transaction` and `NodePrimitives::SignedTx` (#12330) Co-authored-by: Matthias Seitz --- Cargo.lock | 1 - crates/ethereum/node/src/node.rs | 3 ++- crates/node/types/Cargo.toml | 1 - crates/node/types/src/lib.rs | 11 ++++++----- crates/optimism/node/src/node.rs | 3 ++- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 22c5cb8ae50..3433f063ff1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8106,7 +8106,6 @@ dependencies = [ "reth-chainspec", "reth-db-api", "reth-engine-primitives", - "reth-primitives", "reth-primitives-traits", "reth-trie-db", ] diff --git a/crates/ethereum/node/src/node.rs b/crates/ethereum/node/src/node.rs index 95542411d21..e545a3c73c4 100644 --- a/crates/ethereum/node/src/node.rs +++ b/crates/ethereum/node/src/node.rs @@ -25,7 +25,7 @@ use reth_node_builder::{ BuilderContext, Node, NodeAdapter, NodeComponentsBuilder, PayloadBuilderConfig, PayloadTypes, }; use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService}; -use reth_primitives::{Block, Header, Receipt}; +use reth_primitives::{Block, Header, Receipt, TransactionSigned}; use reth_provider::CanonStateSubscriptions; use reth_rpc::EthApi; use reth_tracing::tracing::{debug, info}; @@ -43,6 +43,7 @@ pub struct EthPrimitives; impl NodePrimitives for EthPrimitives { type Block = Block; + type SignedTx = TransactionSigned; type Receipt = Receipt; } diff --git a/crates/node/types/Cargo.toml b/crates/node/types/Cargo.toml index 21facae5460..cc33aac30ff 100644 --- a/crates/node/types/Cargo.toml +++ b/crates/node/types/Cargo.toml @@ -15,6 +15,5 @@ workspace = true reth-chainspec.workspace = true reth-db-api.workspace = true reth-engine-primitives.workspace = true -reth-primitives.workspace = true reth-primitives-traits.workspace = true reth-trie-db.workspace = true diff --git a/crates/node/types/src/lib.rs b/crates/node/types/src/lib.rs index 6c3ed9ca46e..afb650ada2b 100644 --- a/crates/node/types/src/lib.rs +++ b/crates/node/types/src/lib.rs @@ -8,28 +8,29 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -pub use reth_primitives_traits::{Block, BlockBody}; - -use std::marker::PhantomData; - use reth_chainspec::EthChainSpec; use reth_db_api::{ database_metrics::{DatabaseMetadata, DatabaseMetrics}, Database, }; use reth_engine_primitives::EngineTypes; +pub use reth_primitives_traits::{Block, BlockBody}; use reth_trie_db::StateCommitment; +use std::marker::PhantomData; /// Configures all the primitive types of the node. pub trait NodePrimitives { /// Block primitive. type Block; + /// Signed version of the transaction type. + type SignedTx; /// A receipt. type Receipt; } impl NodePrimitives for () { - type Block = reth_primitives::Block; + type Block = (); + type SignedTx = (); type Receipt = (); } diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index a09dfbaa562..c375c36a87d 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -24,7 +24,7 @@ use reth_optimism_evm::{OpEvmConfig, OpExecutionStrategyFactory}; use reth_optimism_payload_builder::builder::OpPayloadTransactions; use reth_optimism_rpc::OpEthApi; use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService}; -use reth_primitives::{Block, Header, Receipt}; +use reth_primitives::{Block, Header, Receipt, TransactionSigned}; use reth_provider::CanonStateSubscriptions; use reth_tracing::tracing::{debug, info}; use reth_transaction_pool::{ @@ -46,6 +46,7 @@ pub struct OpPrimitives; impl NodePrimitives for OpPrimitives { type Block = Block; + type SignedTx = TransactionSigned; type Receipt = Receipt; } From a299f501ce3ca8a7dfc13a9845a6d701e2a05e62 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Sat, 9 Nov 2024 10:53:33 +0100 Subject: [PATCH 086/211] chore(sdk): payload builder AT on `NodeComponents` and `FullNodeComponents` (#11529) Co-authored-by: Matthias Seitz --- Cargo.lock | 2 -- crates/exex/exex/Cargo.toml | 1 - crates/exex/exex/src/context.rs | 13 +++------- crates/node/api/Cargo.toml | 1 - crates/node/api/src/node.rs | 15 ++++++----- crates/node/builder/src/builder/states.rs | 25 ++++++++++--------- crates/node/builder/src/components/builder.rs | 19 ++++++++------ crates/node/builder/src/components/mod.rs | 13 +++++----- crates/node/builder/src/rpc.rs | 11 ++++---- crates/optimism/node/src/node.rs | 12 ++++++--- 10 files changed, 57 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3433f063ff1..98fe61e94c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7540,7 +7540,6 @@ dependencies = [ "reth-metrics", "reth-node-api", "reth-node-core", - "reth-payload-builder", "reth-primitives", "reth-primitives-traits", "reth-provider", @@ -7885,7 +7884,6 @@ dependencies = [ "reth-network-api", "reth-node-core", "reth-node-types", - "reth-payload-builder", "reth-payload-primitives", "reth-primitives", "reth-provider", diff --git a/crates/exex/exex/Cargo.toml b/crates/exex/exex/Cargo.toml index 903e11e784e..f7ab4fce5df 100644 --- a/crates/exex/exex/Cargo.toml +++ b/crates/exex/exex/Cargo.toml @@ -25,7 +25,6 @@ reth-fs-util.workspace = true reth-metrics.workspace = true reth-node-api.workspace = true reth-node-core.workspace = true -reth-payload-builder.workspace = true reth-primitives = { workspace = true, features = ["secp256k1"] } reth-primitives-traits.workspace = true reth-provider.workspace = true diff --git a/crates/exex/exex/src/context.rs b/crates/exex/exex/src/context.rs index 23d772b738a..4e0d9f5956c 100644 --- a/crates/exex/exex/src/context.rs +++ b/crates/exex/exex/src/context.rs @@ -1,14 +1,12 @@ -use std::fmt::Debug; - +use crate::{ExExContextDyn, ExExEvent, ExExNotifications, ExExNotificationsStream}; use reth_exex_types::ExExHead; -use reth_node_api::{FullNodeComponents, NodeTypes, NodeTypesWithEngine}; +use reth_node_api::{FullNodeComponents, NodeTypes}; use reth_node_core::node_config::NodeConfig; use reth_primitives::Head; use reth_tasks::TaskExecutor; +use std::fmt::Debug; use tokio::sync::mpsc::UnboundedSender; -use crate::{ExExContextDyn, ExExEvent, ExExNotifications, ExExNotificationsStream}; - /// Captures the context that an `ExEx` has access to. pub struct ExExContext { /// The current head of the blockchain at launch. @@ -97,10 +95,7 @@ where } /// Returns the handle to the payload builder service. - pub fn payload_builder( - &self, - ) -> &reth_payload_builder::PayloadBuilderHandle<::Engine> - { + pub fn payload_builder(&self) -> &Node::PayloadBuilder { self.components.payload_builder() } diff --git a/crates/node/api/Cargo.toml b/crates/node/api/Cargo.toml index 6b263d6c532..b2bf001862e 100644 --- a/crates/node/api/Cargo.toml +++ b/crates/node/api/Cargo.toml @@ -18,7 +18,6 @@ reth-evm.workspace = true reth-provider.workspace = true reth-engine-primitives.workspace = true reth-transaction-pool.workspace = true -reth-payload-builder.workspace = true reth-payload-primitives.workspace = true reth-tasks.workspace = true reth-network-api.workspace = true diff --git a/crates/node/api/src/node.rs b/crates/node/api/src/node.rs index b016e01c295..253145ea9eb 100644 --- a/crates/node/api/src/node.rs +++ b/crates/node/api/src/node.rs @@ -1,7 +1,6 @@ //! Traits for configuring a node. -use std::{future::Future, marker::PhantomData}; - +use crate::ConfigureEvm; use alloy_rpc_types_engine::JwtSecret; use reth_beacon_consensus::BeaconConsensusEngineHandle; use reth_consensus::Consensus; @@ -9,13 +8,12 @@ use reth_evm::execute::BlockExecutorProvider; use reth_network_api::FullNetwork; use reth_node_core::node_config::NodeConfig; use reth_node_types::{NodeTypes, NodeTypesWithDB, NodeTypesWithEngine}; -use reth_payload_builder::PayloadBuilderHandle; +use reth_payload_primitives::PayloadBuilder; use reth_primitives::Header; use reth_provider::FullProvider; use reth_tasks::TaskExecutor; use reth_transaction_pool::TransactionPool; - -use crate::ConfigureEvm; +use std::{future::Future, marker::PhantomData}; /// A helper trait that is downstream of the [`NodeTypesWithEngine`] trait and adds stateful /// components to the node. @@ -63,6 +61,9 @@ pub trait FullNodeComponents: FullNodeTypes + Clone + 'static { /// Network API. type Network: FullNetwork; + /// Builds new blocks. + type PayloadBuilder: PayloadBuilder + Clone; + /// Returns the transaction pool of the node. fn pool(&self) -> &Self::Pool; @@ -79,9 +80,7 @@ pub trait FullNodeComponents: FullNodeTypes + Clone + 'static { fn network(&self) -> &Self::Network; /// Returns the handle to the payload builder service. - fn payload_builder( - &self, - ) -> &PayloadBuilderHandle<::Engine>; + fn payload_builder(&self) -> &Self::PayloadBuilder; /// Returns the provider of the node. fn provider(&self) -> &Self::Provider; diff --git a/crates/node/builder/src/builder/states.rs b/crates/node/builder/src/builder/states.rs index ca5a57d0db6..16b7d668ca3 100644 --- a/crates/node/builder/src/builder/states.rs +++ b/crates/node/builder/src/builder/states.rs @@ -5,16 +5,6 @@ //! The node builder process is essentially a state machine that transitions through various states //! before the node can be launched. -use std::{fmt, future::Future}; - -use reth_exex::ExExContext; -use reth_node_api::{ - FullNodeComponents, FullNodeTypes, NodeAddOns, NodeTypes, NodeTypesWithDB, NodeTypesWithEngine, -}; -use reth_node_core::node_config::NodeConfig; -use reth_payload_builder::PayloadBuilderHandle; -use reth_tasks::TaskExecutor; - use crate::{ components::{NodeComponents, NodeComponentsBuilder}, hooks::NodeHooks, @@ -22,6 +12,13 @@ use crate::{ rpc::{RethRpcAddOns, RethRpcServerHandles, RpcContext}, AddOns, FullNode, }; +use reth_exex::ExExContext; +use reth_node_api::{ + FullNodeComponents, FullNodeTypes, NodeAddOns, NodeTypes, NodeTypesWithDB, PayloadBuilder, +}; +use reth_node_core::node_config::NodeConfig; +use reth_tasks::TaskExecutor; +use std::{fmt, future::Future}; /// A node builder that also has the configured types. pub struct NodeBuilderWithTypes { @@ -91,12 +88,16 @@ impl> FullNodeTypes for NodeAdapter type Provider = T::Provider; } -impl> FullNodeComponents for NodeAdapter { +impl> FullNodeComponents for NodeAdapter +where + C::PayloadBuilder: PayloadBuilder, +{ type Pool = C::Pool; type Evm = C::Evm; type Executor = C::Executor; type Consensus = C::Consensus; type Network = C::Network; + type PayloadBuilder = C::PayloadBuilder; fn pool(&self) -> &Self::Pool { self.components.pool() @@ -118,7 +119,7 @@ impl> FullNodeComponents for NodeAdapter< self.components.network() } - fn payload_builder(&self) -> &PayloadBuilderHandle<::Engine> { + fn payload_builder(&self) -> &Self::PayloadBuilder { self.components.payload_builder() } diff --git a/crates/node/builder/src/components/builder.rs b/crates/node/builder/src/components/builder.rs index 48a0ba9b5fd..41ce36858d8 100644 --- a/crates/node/builder/src/components/builder.rs +++ b/crates/node/builder/src/components/builder.rs @@ -1,12 +1,5 @@ //! A generic [`NodeComponentsBuilder`] -use std::{future::Future, marker::PhantomData}; - -use reth_consensus::Consensus; -use reth_evm::execute::BlockExecutorProvider; -use reth_primitives::Header; -use reth_transaction_pool::TransactionPool; - use crate::{ components::{ Components, ConsensusBuilder, ExecutorBuilder, NetworkBuilder, NodeComponents, @@ -14,6 +7,13 @@ use crate::{ }, BuilderContext, ConfigureEvm, FullNodeTypes, }; +use reth_consensus::Consensus; +use reth_evm::execute::BlockExecutorProvider; +use reth_node_api::NodeTypesWithEngine; +use reth_payload_builder::PayloadBuilderHandle; +use reth_primitives::Header; +use reth_transaction_pool::TransactionPool; +use std::{future::Future, marker::PhantomData}; /// A generic, general purpose and customizable [`NodeComponentsBuilder`] implementation. /// @@ -358,7 +358,10 @@ impl Default for ComponentsBuilder<(), (), (), (), (), ()> { /// A type that's responsible for building the components of the node. pub trait NodeComponentsBuilder: Send { /// The components for the node with the given types - type Components: NodeComponents; + type Components: NodeComponents< + Node, + PayloadBuilder = PayloadBuilderHandle<::Engine>, + >; /// Consumes the type and returns the created components. fn build_components( diff --git a/crates/node/builder/src/components/mod.rs b/crates/node/builder/src/components/mod.rs index 42001fc1005..29b667d5409 100644 --- a/crates/node/builder/src/components/mod.rs +++ b/crates/node/builder/src/components/mod.rs @@ -21,6 +21,7 @@ pub use network::*; pub use payload::*; pub use pool::*; +use crate::{ConfigureEvm, FullNodeTypes}; use reth_consensus::Consensus; use reth_evm::execute::BlockExecutorProvider; use reth_network::NetworkHandle; @@ -30,8 +31,6 @@ use reth_payload_builder::PayloadBuilderHandle; use reth_primitives::Header; use reth_transaction_pool::TransactionPool; -use crate::{ConfigureEvm, FullNodeTypes}; - /// An abstraction over the components of a node, consisting of: /// - evm and executor /// - transaction pool @@ -53,6 +52,9 @@ pub trait NodeComponents: Clone + Unpin + Send + Sync + 'stati /// Network API. type Network: FullNetwork; + /// Builds new blocks. + type PayloadBuilder: Clone; + /// Returns the transaction pool of the node. fn pool(&self) -> &Self::Pool; @@ -69,7 +71,7 @@ pub trait NodeComponents: Clone + Unpin + Send + Sync + 'stati fn network(&self) -> &Self::Network; /// Returns the handle to the payload builder service. - fn payload_builder(&self) -> &PayloadBuilderHandle<::Engine>; + fn payload_builder(&self) -> &Self::PayloadBuilder; } /// All the components of the node. @@ -105,6 +107,7 @@ where type Executor = Executor; type Consensus = Cons; type Network = NetworkHandle; + type PayloadBuilder = PayloadBuilderHandle<::Engine>; fn pool(&self) -> &Self::Pool { &self.transaction_pool @@ -126,9 +129,7 @@ where &self.network } - fn payload_builder( - &self, - ) -> &PayloadBuilderHandle<::Engine> { + fn payload_builder(&self) -> &Self::PayloadBuilder { &self.payload_builder } } diff --git a/crates/node/builder/src/rpc.rs b/crates/node/builder/src/rpc.rs index 8af1527cbcd..4530bbe7014 100644 --- a/crates/node/builder/src/rpc.rs +++ b/crates/node/builder/src/rpc.rs @@ -16,7 +16,7 @@ use reth_node_core::{ node_config::NodeConfig, version::{CARGO_PKG_VERSION, CLIENT_CODE, NAME_CLIENT, VERGEN_GIT_SHA}, }; -use reth_payload_builder::PayloadBuilderHandle; +use reth_payload_builder::PayloadStore; use reth_provider::providers::ProviderNodeTypes; use reth_rpc::{ eth::{EthApiTypes, FullEthApiServer}, @@ -294,9 +294,7 @@ where } /// Returns the handle to the payload builder service - pub fn payload_builder( - &self, - ) -> &PayloadBuilderHandle<::Engine> { + pub fn payload_builder(&self) -> &Node::PayloadBuilder { self.node.payload_builder() } } @@ -402,7 +400,10 @@ where impl NodeAddOns for RpcAddOns where - N: FullNodeComponents, + N: FullNodeComponents< + Types: ProviderNodeTypes, + PayloadBuilder: Into::Engine>>, + >, EthApi: EthApiTypes + FullEthApiServer + AddDevSigners + Unpin + 'static, EV: EngineValidatorBuilder, { diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index c375c36a87d..6edab570e29 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -23,7 +23,7 @@ use reth_optimism_consensus::OpBeaconConsensus; use reth_optimism_evm::{OpEvmConfig, OpExecutionStrategyFactory}; use reth_optimism_payload_builder::builder::OpPayloadTransactions; use reth_optimism_rpc::OpEthApi; -use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService}; +use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService, PayloadStore}; use reth_primitives::{Block, Header, Receipt, TransactionSigned}; use reth_provider::CanonStateSubscriptions; use reth_tracing::tracing::{debug, info}; @@ -149,7 +149,10 @@ impl OpAddOns { impl NodeAddOns for OpAddOns where - N: FullNodeComponents>, + N: FullNodeComponents< + Types: NodeTypes, + PayloadBuilder: Into::Engine>>, + >, OpEngineValidator: EngineValidator<::Engine>, { type Handle = RpcHandle>; @@ -164,7 +167,10 @@ where impl RethRpcAddOns for OpAddOns where - N: FullNodeComponents>, + N: FullNodeComponents< + Types: NodeTypes, + PayloadBuilder: Into::Engine>>, + >, OpEngineValidator: EngineValidator<::Engine>, { type EthApi = OpEthApi; From ae257f5685b07451c836aed10f2ceeb0e69619a4 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sat, 9 Nov 2024 13:51:45 +0100 Subject: [PATCH 087/211] chore: restrict payload builder error type (#12423) --- crates/payload/primitives/src/traits.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/payload/primitives/src/traits.rs b/crates/payload/primitives/src/traits.rs index 7ae558b9945..a77f516da8d 100644 --- a/crates/payload/primitives/src/traits.rs +++ b/crates/payload/primitives/src/traits.rs @@ -1,4 +1,4 @@ -use crate::{PayloadEvents, PayloadKind, PayloadTypes}; +use crate::{PayloadBuilderError, PayloadEvents, PayloadKind, PayloadTypes}; use alloy_eips::{eip4895::Withdrawal, eip7685::Requests}; use alloy_primitives::{Address, B256, U256}; use alloy_rpc_types_engine::{PayloadAttributes as EthPayloadAttributes, PayloadId}; @@ -12,7 +12,7 @@ pub trait PayloadBuilder: Send + Unpin { /// The Payload type for the builder. type PayloadType: PayloadTypes; /// The error type returned by the builder. - type Error; + type Error: Into; /// Sends a message to the service to start building a new payload for the given payload. /// From 59ebebaa6332982b970c7544803bb3bf5390787e Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Sat, 9 Nov 2024 14:09:46 +0100 Subject: [PATCH 088/211] primitives: rm alloy `Withdrawals` reexport (#12421) Co-authored-by: Matthias Seitz --- Cargo.lock | 3 +++ crates/blockchain-tree/src/blockchain_tree.rs | 3 +-- crates/consensus/common/src/validation.rs | 9 +++++---- .../ethereum/engine-primitives/src/payload.rs | 4 ++-- crates/optimism/payload/src/payload.rs | 4 ++-- crates/payload/basic/src/lib.rs | 4 ++-- crates/payload/basic/src/stack.rs | 3 ++- crates/payload/primitives/src/traits.rs | 7 +++++-- crates/primitives-traits/src/lib.rs | 2 +- crates/primitives-traits/src/withdrawal.rs | 3 --- crates/primitives/src/block.rs | 9 ++++----- crates/primitives/src/lib.rs | 2 +- crates/rpc/rpc-engine-api/tests/it/payload.rs | 3 ++- crates/rpc/rpc-types-compat/src/block.rs | 6 +++--- .../rpc/rpc-types-compat/src/engine/payload.rs | 3 ++- crates/storage/db-models/Cargo.toml | 18 ++++++++++-------- crates/storage/db-models/src/blocks.rs | 2 +- .../src/providers/blockchain_provider.rs | 12 ++++++------ .../provider/src/providers/consistent.rs | 4 ++-- .../provider/src/providers/database/mod.rs | 7 +++++-- .../src/providers/database/provider.rs | 6 ++++-- crates/storage/provider/src/providers/mod.rs | 7 +++++-- .../src/providers/static_file/manager.rs | 7 +++++-- .../storage/provider/src/test_utils/blocks.rs | 4 ++-- crates/storage/provider/src/test_utils/mock.rs | 7 +++++-- crates/storage/provider/src/test_utils/noop.rs | 7 +++++-- crates/storage/storage-api/src/withdrawals.rs | 6 ++++-- examples/custom-engine-types/Cargo.toml | 1 + examples/custom-engine-types/src/main.rs | 2 +- testing/ef-tests/Cargo.toml | 13 +++++++++---- testing/ef-tests/src/models.rs | 3 ++- testing/testing-utils/src/generators.rs | 4 ++-- 32 files changed, 104 insertions(+), 71 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 98fe61e94c7..f81a026bd5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2611,6 +2611,7 @@ dependencies = [ name = "ef-tests" version = "1.1.1" dependencies = [ + "alloy-eips", "alloy-primitives", "alloy-rlp", "rayon", @@ -2852,6 +2853,7 @@ dependencies = [ name = "example-custom-engine-types" version = "0.0.0" dependencies = [ + "alloy-eips", "alloy-genesis", "alloy-primitives", "alloy-rpc-types", @@ -6915,6 +6917,7 @@ dependencies = [ name = "reth-db-models" version = "1.1.1" dependencies = [ + "alloy-eips", "alloy-primitives", "arbitrary", "bytes", diff --git a/crates/blockchain-tree/src/blockchain_tree.rs b/crates/blockchain-tree/src/blockchain_tree.rs index 64705e5ccb5..20d1cfe9f1d 100644 --- a/crates/blockchain-tree/src/blockchain_tree.rs +++ b/crates/blockchain-tree/src/blockchain_tree.rs @@ -1375,7 +1375,7 @@ where mod tests { use super::*; use alloy_consensus::{TxEip1559, EMPTY_ROOT_HASH}; - use alloy_eips::eip1559::INITIAL_BASE_FEE; + use alloy_eips::{eip1559::INITIAL_BASE_FEE, eip4895::Withdrawals}; use alloy_genesis::{Genesis, GenesisAccount}; use alloy_primitives::{keccak256, Address, PrimitiveSignature as Signature, Sealable, B256}; use assert_matches::assert_matches; @@ -1390,7 +1390,6 @@ mod tests { proofs::{calculate_receipt_root, calculate_transaction_root}, revm_primitives::AccountInfo, Account, BlockBody, Header, Transaction, TransactionSigned, TransactionSignedEcRecovered, - Withdrawals, }; use reth_provider::{ test_utils::{ diff --git a/crates/consensus/common/src/validation.rs b/crates/consensus/common/src/validation.rs index 46a9e4d1572..5a74433e58b 100644 --- a/crates/consensus/common/src/validation.rs +++ b/crates/consensus/common/src/validation.rs @@ -275,7 +275,10 @@ pub fn validate_against_parent_4844( mod tests { use super::*; use alloy_consensus::{TxEip4844, EMPTY_OMMER_ROOT_HASH, EMPTY_ROOT_HASH}; - use alloy_eips::{eip4895::Withdrawal, BlockHashOrNumber}; + use alloy_eips::{ + eip4895::{Withdrawal, Withdrawals}, + BlockHashOrNumber, + }; use alloy_primitives::{ hex_literal::hex, Address, BlockHash, BlockNumber, Bytes, PrimitiveSignature as Signature, Sealable, U256, @@ -283,9 +286,7 @@ mod tests { use mockall::mock; use rand::Rng; use reth_chainspec::ChainSpecBuilder; - use reth_primitives::{ - proofs, Account, BlockBody, Transaction, TransactionSigned, Withdrawals, - }; + use reth_primitives::{proofs, Account, BlockBody, Transaction, TransactionSigned}; use reth_storage_api::{ errors::provider::ProviderResult, AccountReader, HeaderProvider, WithdrawalsProvider, }; diff --git a/crates/ethereum/engine-primitives/src/payload.rs b/crates/ethereum/engine-primitives/src/payload.rs index 3fe4e76e63f..094a1df2657 100644 --- a/crates/ethereum/engine-primitives/src/payload.rs +++ b/crates/ethereum/engine-primitives/src/payload.rs @@ -1,6 +1,6 @@ //! Contains types required for building a payload. -use alloy_eips::{eip4844::BlobTransactionSidecar, eip7685::Requests}; +use alloy_eips::{eip4844::BlobTransactionSidecar, eip4895::Withdrawals, eip7685::Requests}; use alloy_primitives::{Address, B256, U256}; use alloy_rlp::Encodable; use alloy_rpc_types_engine::{ @@ -9,7 +9,7 @@ use alloy_rpc_types_engine::{ }; use reth_chain_state::ExecutedBlock; use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes}; -use reth_primitives::{SealedBlock, Withdrawals}; +use reth_primitives::SealedBlock; use reth_rpc_types_compat::engine::payload::{ block_to_payload_v1, block_to_payload_v3, convert_block_to_payload_field_v2, }; diff --git a/crates/optimism/payload/src/payload.rs b/crates/optimism/payload/src/payload.rs index 37224716c75..36f11ee628b 100644 --- a/crates/optimism/payload/src/payload.rs +++ b/crates/optimism/payload/src/payload.rs @@ -2,7 +2,7 @@ use alloy_eips::{ eip1559::BaseFeeParams, eip2718::Decodable2718, eip4844::BlobTransactionSidecar, - eip7685::Requests, + eip4895::Withdrawals, eip7685::Requests, }; use alloy_primitives::{keccak256, Address, Bytes, B256, B64, U256}; use alloy_rlp::Encodable; @@ -16,7 +16,7 @@ use reth_chainspec::EthereumHardforks; use reth_optimism_chainspec::OpChainSpec; use reth_payload_builder::EthPayloadBuilderAttributes; use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes}; -use reth_primitives::{transaction::WithEncoded, SealedBlock, TransactionSigned, Withdrawals}; +use reth_primitives::{transaction::WithEncoded, SealedBlock, TransactionSigned}; use reth_rpc_types_compat::engine::payload::{ block_to_payload_v1, block_to_payload_v3, convert_block_to_payload_field_v2, }; diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index 0fc63a5a149..6f2038ba4b4 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -10,7 +10,7 @@ use crate::metrics::PayloadBuilderMetrics; use alloy_consensus::constants::EMPTY_WITHDRAWALS; -use alloy_eips::merge::SLOT_DURATION; +use alloy_eips::{eip4895::Withdrawals, merge::SLOT_DURATION}; use alloy_primitives::{Bytes, B256, U256}; use futures_core::ready; use futures_util::FutureExt; @@ -20,7 +20,7 @@ use reth_payload_builder::{KeepPayloadJobAlive, PayloadId, PayloadJob, PayloadJo use reth_payload_primitives::{ BuiltPayload, PayloadBuilderAttributes, PayloadBuilderError, PayloadKind, }; -use reth_primitives::{constants::RETH_CLIENT_VERSION, proofs, SealedHeader, Withdrawals}; +use reth_primitives::{constants::RETH_CLIENT_VERSION, proofs, SealedHeader}; use reth_provider::{BlockReaderIdExt, CanonStateNotification, StateProviderFactory}; use reth_revm::cached::CachedReads; use reth_tasks::TaskSpawner; diff --git a/crates/payload/basic/src/stack.rs b/crates/payload/basic/src/stack.rs index 722399ab278..45a3f3b4244 100644 --- a/crates/payload/basic/src/stack.rs +++ b/crates/payload/basic/src/stack.rs @@ -3,10 +3,11 @@ use crate::{ PayloadConfig, }; +use alloy_eips::eip4895::Withdrawals; use alloy_primitives::{Address, B256, U256}; use reth_payload_builder::PayloadId; use reth_payload_primitives::BuiltPayload; -use reth_primitives::{SealedBlock, Withdrawals}; +use reth_primitives::SealedBlock; use alloy_eips::eip7685::Requests; use std::{error::Error, fmt}; diff --git a/crates/payload/primitives/src/traits.rs b/crates/payload/primitives/src/traits.rs index a77f516da8d..160808854a9 100644 --- a/crates/payload/primitives/src/traits.rs +++ b/crates/payload/primitives/src/traits.rs @@ -1,9 +1,12 @@ use crate::{PayloadBuilderError, PayloadEvents, PayloadKind, PayloadTypes}; -use alloy_eips::{eip4895::Withdrawal, eip7685::Requests}; +use alloy_eips::{ + eip4895::{Withdrawal, Withdrawals}, + eip7685::Requests, +}; use alloy_primitives::{Address, B256, U256}; use alloy_rpc_types_engine::{PayloadAttributes as EthPayloadAttributes, PayloadId}; use reth_chain_state::ExecutedBlock; -use reth_primitives::{SealedBlock, Withdrawals}; +use reth_primitives::SealedBlock; use tokio::sync::oneshot; /// A type that can request, subscribe to and resolve payloads. diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index 9f27726aeca..ec93f2a2163 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -37,7 +37,7 @@ pub mod block; pub use block::{body::BlockBody, Block, FullBlock}; mod withdrawal; -pub use withdrawal::{Withdrawal, Withdrawals}; +pub use withdrawal::Withdrawal; mod error; pub use error::{GotExpected, GotExpectedBoxed}; diff --git a/crates/primitives-traits/src/withdrawal.rs b/crates/primitives-traits/src/withdrawal.rs index 9c6d8b69797..699229684ec 100644 --- a/crates/primitives-traits/src/withdrawal.rs +++ b/crates/primitives-traits/src/withdrawal.rs @@ -4,9 +4,6 @@ #[doc(inline)] pub use alloy_eips::eip4895::Withdrawal; -/// Represents a collection of Withdrawals. -pub type Withdrawals = alloy_eips::eip4895::Withdrawals; - #[cfg(test)] mod tests { use super::*; diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index 5f32728489c..54bcb27293c 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -1,8 +1,6 @@ -use crate::{ - GotExpected, Header, SealedHeader, TransactionSigned, TransactionSignedEcRecovered, Withdrawals, -}; +use crate::{GotExpected, Header, SealedHeader, TransactionSigned, TransactionSignedEcRecovered}; use alloc::vec::Vec; -use alloy_eips::eip2718::Encodable2718; +use alloy_eips::{eip2718::Encodable2718, eip4895::Withdrawals}; use alloy_primitives::{Address, Bytes, Sealable, B256}; use alloy_rlp::{Decodable, Encodable, RlpDecodable, RlpEncodable}; use derive_more::{Deref, DerefMut}; @@ -655,8 +653,9 @@ impl<'a> arbitrary::Arbitrary<'a> for BlockBody { pub(super) mod serde_bincode_compat { use alloc::{borrow::Cow, vec::Vec}; use alloy_consensus::serde_bincode_compat::Header; + use alloy_eips::eip4895::Withdrawals; use alloy_primitives::Address; - use reth_primitives_traits::{serde_bincode_compat::SealedHeader, Withdrawals}; + use reth_primitives_traits::serde_bincode_compat::SealedHeader; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_with::{DeserializeAs, SerializeAs}; diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index c16c4d3f42f..f44e1ee6a09 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -42,7 +42,7 @@ pub use receipt::{ }; pub use reth_primitives_traits::{ logs_bloom, Account, Bytecode, GotExpected, GotExpectedBoxed, Header, HeaderError, Log, - LogData, SealedHeader, StorageEntry, Withdrawals, + LogData, SealedHeader, StorageEntry, }; pub use static_file::StaticFileSegment; diff --git a/crates/rpc/rpc-engine-api/tests/it/payload.rs b/crates/rpc/rpc-engine-api/tests/it/payload.rs index febbc291e35..f341fd0474c 100644 --- a/crates/rpc/rpc-engine-api/tests/it/payload.rs +++ b/crates/rpc/rpc-engine-api/tests/it/payload.rs @@ -1,5 +1,6 @@ //! Some payload tests +use alloy_eips::eip4895::Withdrawals; use alloy_primitives::{Bytes, Sealable, U256}; use alloy_rlp::{Decodable, Error as RlpError}; use alloy_rpc_types_engine::{ @@ -7,7 +8,7 @@ use alloy_rpc_types_engine::{ PayloadError, }; use assert_matches::assert_matches; -use reth_primitives::{proofs, Block, SealedBlock, SealedHeader, TransactionSigned, Withdrawals}; +use reth_primitives::{proofs, Block, SealedBlock, SealedHeader, TransactionSigned}; use reth_rpc_types_compat::engine::payload::{ block_to_payload, block_to_payload_v1, convert_to_payload_body_v1, try_into_sealed_block, try_payload_v1_to_block, diff --git a/crates/rpc/rpc-types-compat/src/block.rs b/crates/rpc/rpc-types-compat/src/block.rs index cfa1561c634..41bd057dfd6 100644 --- a/crates/rpc/rpc-types-compat/src/block.rs +++ b/crates/rpc/rpc-types-compat/src/block.rs @@ -1,14 +1,14 @@ //! Compatibility functions for rpc `Block` type. +use crate::{transaction::from_recovered_with_block_context, TransactionCompat}; use alloy_consensus::Sealed; +use alloy_eips::eip4895::Withdrawals; use alloy_primitives::{B256, U256}; use alloy_rlp::Encodable; use alloy_rpc_types_eth::{ Block, BlockError, BlockTransactions, BlockTransactionsKind, Header, TransactionInfo, }; -use reth_primitives::{Block as PrimitiveBlock, BlockWithSenders, Withdrawals}; - -use crate::{transaction::from_recovered_with_block_context, TransactionCompat}; +use reth_primitives::{Block as PrimitiveBlock, BlockWithSenders}; /// Converts the given primitive block into a [`Block`] response with the given /// [`BlockTransactionsKind`] diff --git a/crates/rpc/rpc-types-compat/src/engine/payload.rs b/crates/rpc/rpc-types-compat/src/engine/payload.rs index b4c45a61781..9050b0cced1 100644 --- a/crates/rpc/rpc-types-compat/src/engine/payload.rs +++ b/crates/rpc/rpc-types-compat/src/engine/payload.rs @@ -4,6 +4,7 @@ use alloy_consensus::{constants::MAXIMUM_EXTRA_DATA_SIZE, EMPTY_OMMER_ROOT_HASH}; use alloy_eips::{ eip2718::{Decodable2718, Encodable2718}, + eip4895::Withdrawals, eip7685::Requests, }; use alloy_primitives::{B256, U256}; @@ -14,7 +15,7 @@ use alloy_rpc_types_engine::{ }; use reth_primitives::{ proofs::{self}, - Block, BlockBody, Header, SealedBlock, TransactionSigned, Withdrawals, + Block, BlockBody, Header, SealedBlock, TransactionSigned, }; /// Converts [`ExecutionPayloadV1`] to [`Block`] diff --git a/crates/storage/db-models/Cargo.toml b/crates/storage/db-models/Cargo.toml index 44b291959ba..59d95c2263d 100644 --- a/crates/storage/db-models/Cargo.toml +++ b/crates/storage/db-models/Cargo.toml @@ -18,6 +18,7 @@ reth-primitives-traits.workspace = true # ethereum alloy-primitives.workspace = true +alloy-eips.workspace = true # codecs modular-bitfield.workspace = true @@ -42,14 +43,15 @@ test-fuzz.workspace = true [features] test-utils = [ - "reth-primitives-traits/test-utils", - "arbitrary", - "reth-codecs/test-utils" + "reth-primitives-traits/test-utils", + "arbitrary", + "reth-codecs/test-utils", ] arbitrary = [ - "reth-primitives-traits/arbitrary", - "dep:arbitrary", - "dep:proptest", - "alloy-primitives/arbitrary", - "reth-codecs/arbitrary" + "reth-primitives-traits/arbitrary", + "dep:arbitrary", + "dep:proptest", + "alloy-primitives/arbitrary", + "alloy-eips/arbitrary", + "reth-codecs/arbitrary", ] diff --git a/crates/storage/db-models/src/blocks.rs b/crates/storage/db-models/src/blocks.rs index b4399dc1e27..ed1d7fb6772 100644 --- a/crates/storage/db-models/src/blocks.rs +++ b/crates/storage/db-models/src/blocks.rs @@ -1,8 +1,8 @@ use std::ops::Range; +use alloy_eips::eip4895::Withdrawals; use alloy_primitives::TxNumber; use reth_codecs::{add_arbitrary_tests, Compact}; -use reth_primitives_traits::Withdrawals; use serde::{Deserialize, Serialize}; /// Total number of transactions. diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index 669a3555931..dbfb4f7b872 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -9,7 +9,10 @@ use crate::{ StageCheckpointReader, StateProviderBox, StateProviderFactory, StateReader, StaticFileProviderFactory, TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; -use alloy_eips::{eip4895::Withdrawal, BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag}; +use alloy_eips::{ + eip4895::{Withdrawal, Withdrawals}, + BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, +}; use alloy_primitives::{Address, BlockHash, BlockNumber, Sealable, TxHash, TxNumber, B256, U256}; use alloy_rpc_types_engine::ForkchoiceState; use reth_chain_state::{ @@ -25,7 +28,6 @@ use reth_node_types::NodeTypesWithDB; use reth_primitives::{ Account, Block, BlockWithSenders, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, StorageEntry, TransactionMeta, TransactionSigned, TransactionSignedNoHash, - Withdrawals, }; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; @@ -768,7 +770,7 @@ mod tests { BlockWriter, CanonChainTracker, ProviderFactory, StaticFileProviderFactory, StaticFileWriter, }; - use alloy_eips::{BlockHashOrNumber, BlockNumHash, BlockNumberOrTag}; + use alloy_eips::{eip4895::Withdrawals, BlockHashOrNumber, BlockNumHash, BlockNumberOrTag}; use alloy_primitives::{BlockNumber, TxNumber, B256}; use itertools::Itertools; use rand::Rng; @@ -786,9 +788,7 @@ mod tests { use reth_db_api::{cursor::DbCursorRO, transaction::DbTx}; use reth_errors::ProviderError; use reth_execution_types::{Chain, ExecutionOutcome}; - use reth_primitives::{ - Receipt, SealedBlock, StaticFileSegment, TransactionSignedNoHash, Withdrawals, - }; + use reth_primitives::{Receipt, SealedBlock, StaticFileSegment, TransactionSignedNoHash}; use reth_storage_api::{ BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt, BlockSource, ChangeSetReader, DatabaseProviderFactory, HeaderProvider, ReceiptProvider, diff --git a/crates/storage/provider/src/providers/consistent.rs b/crates/storage/provider/src/providers/consistent.rs index 786a2f2b108..98f7820e34a 100644 --- a/crates/storage/provider/src/providers/consistent.rs +++ b/crates/storage/provider/src/providers/consistent.rs @@ -7,7 +7,8 @@ use crate::{ TransactionsProvider, WithdrawalsProvider, }; use alloy_eips::{ - eip4895::Withdrawal, BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, HashOrNumber, + eip4895::{Withdrawal, Withdrawals}, + BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, HashOrNumber, }; use alloy_primitives::{Address, BlockHash, BlockNumber, Sealable, TxHash, TxNumber, B256, U256}; use reth_chain_state::{BlockState, CanonicalInMemoryState, MemoryOverlayStateProviderRef}; @@ -19,7 +20,6 @@ use reth_execution_types::{BundleStateInit, ExecutionOutcome, RevertsInit}; use reth_primitives::{ Account, Block, BlockWithSenders, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, StorageEntry, TransactionMeta, TransactionSigned, TransactionSignedNoHash, - Withdrawals, }; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; diff --git a/crates/storage/provider/src/providers/database/mod.rs b/crates/storage/provider/src/providers/database/mod.rs index 38918f52c23..bb532329ee3 100644 --- a/crates/storage/provider/src/providers/database/mod.rs +++ b/crates/storage/provider/src/providers/database/mod.rs @@ -7,7 +7,10 @@ use crate::{ PruneCheckpointReader, StageCheckpointReader, StateProviderBox, StaticFileProviderFactory, TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; -use alloy_eips::{eip4895::Withdrawal, BlockHashOrNumber}; +use alloy_eips::{ + eip4895::{Withdrawal, Withdrawals}, + BlockHashOrNumber, +}; use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256}; use core::fmt; use reth_chainspec::{ChainInfo, EthereumHardforks}; @@ -18,7 +21,7 @@ use reth_evm::ConfigureEvmEnv; use reth_node_types::NodeTypesWithDB; use reth_primitives::{ Block, BlockWithSenders, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, - StaticFileSegment, TransactionMeta, TransactionSigned, TransactionSignedNoHash, Withdrawals, + StaticFileSegment, TransactionMeta, TransactionSigned, TransactionSignedNoHash, }; use reth_prune_types::{PruneCheckpoint, PruneModes, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index c76f77572ab..9ba20306f37 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -15,7 +15,10 @@ use crate::{ StaticFileProviderFactory, StatsReader, StorageReader, StorageTrieWriter, TransactionVariant, TransactionsProvider, TransactionsProviderExt, TrieWriter, WithdrawalsProvider, }; -use alloy_eips::{eip4895::Withdrawal, BlockHashOrNumber}; +use alloy_eips::{ + eip4895::{Withdrawal, Withdrawals}, + BlockHashOrNumber, +}; use alloy_primitives::{keccak256, Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256}; use itertools::{izip, Itertools}; use rayon::slice::ParallelSliceMut; @@ -42,7 +45,6 @@ use reth_primitives::{ Account, Block, BlockBody, BlockWithSenders, Bytecode, GotExpected, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, StaticFileSegment, StorageEntry, TransactionMeta, TransactionSigned, TransactionSignedEcRecovered, TransactionSignedNoHash, - Withdrawals, }; use reth_prune_types::{PruneCheckpoint, PruneModes, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; diff --git a/crates/storage/provider/src/providers/mod.rs b/crates/storage/provider/src/providers/mod.rs index 5e95c6ce0db..c859ddba8a5 100644 --- a/crates/storage/provider/src/providers/mod.rs +++ b/crates/storage/provider/src/providers/mod.rs @@ -7,7 +7,10 @@ use crate::{ StageCheckpointReader, StateProviderBox, StateProviderFactory, StaticFileProviderFactory, TransactionVariant, TransactionsProvider, TreeViewer, WithdrawalsProvider, }; -use alloy_eips::{eip4895::Withdrawal, BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag}; +use alloy_eips::{ + eip4895::{Withdrawal, Withdrawals}, + BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, +}; use alloy_primitives::{Address, BlockHash, BlockNumber, Sealable, TxHash, TxNumber, B256, U256}; use reth_blockchain_tree_api::{ error::{CanonicalError, InsertBlockError}, @@ -21,7 +24,7 @@ use reth_evm::ConfigureEvmEnv; use reth_node_types::NodeTypesWithDB; use reth_primitives::{ Account, Block, BlockWithSenders, Header, Receipt, SealedBlock, SealedBlockWithSenders, - SealedHeader, TransactionMeta, TransactionSigned, TransactionSignedNoHash, Withdrawals, + SealedHeader, TransactionMeta, TransactionSigned, TransactionSignedNoHash, }; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; diff --git a/crates/storage/provider/src/providers/static_file/manager.rs b/crates/storage/provider/src/providers/static_file/manager.rs index 66914b00abc..cb270a6da46 100644 --- a/crates/storage/provider/src/providers/static_file/manager.rs +++ b/crates/storage/provider/src/providers/static_file/manager.rs @@ -7,7 +7,10 @@ use crate::{ ReceiptProvider, StageCheckpointReader, StatsReader, TransactionVariant, TransactionsProvider, TransactionsProviderExt, WithdrawalsProvider, }; -use alloy_eips::{eip4895::Withdrawal, BlockHashOrNumber}; +use alloy_eips::{ + eip4895::{Withdrawal, Withdrawals}, + BlockHashOrNumber, +}; use alloy_primitives::{keccak256, Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256}; use dashmap::DashMap; use notify::{RecommendedWatcher, RecursiveMode, Watcher}; @@ -31,7 +34,7 @@ use reth_primitives::{ DEFAULT_BLOCKS_PER_STATIC_FILE, }, Block, BlockWithSenders, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, - StaticFileSegment, TransactionMeta, TransactionSigned, TransactionSignedNoHash, Withdrawals, + StaticFileSegment, TransactionMeta, TransactionSigned, TransactionSignedNoHash, }; use reth_stages_types::{PipelineTarget, StageId}; use reth_storage_api::DBProvider; diff --git a/crates/storage/provider/src/test_utils/blocks.rs b/crates/storage/provider/src/test_utils/blocks.rs index 2c9c108139c..19a6cbf6a5c 100644 --- a/crates/storage/provider/src/test_utils/blocks.rs +++ b/crates/storage/provider/src/test_utils/blocks.rs @@ -6,14 +6,14 @@ use alloy_primitives::{ U256, }; -use alloy_eips::eip4895::Withdrawal; +use alloy_eips::eip4895::{Withdrawal, Withdrawals}; use alloy_primitives::PrimitiveSignature as Signature; use reth_db::tables; use reth_db_api::{database::Database, models::StoredBlockBodyIndices}; use reth_node_types::NodeTypes; use reth_primitives::{ Account, BlockBody, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, - Transaction, TransactionSigned, TxType, Withdrawals, + Transaction, TransactionSigned, TxType, }; use reth_trie::root::{state_root_unhashed, storage_root_unhashed}; use revm::{db::BundleState, primitives::AccountInfo}; diff --git a/crates/storage/provider/src/test_utils/mock.rs b/crates/storage/provider/src/test_utils/mock.rs index b5593b9040d..6e4331566db 100644 --- a/crates/storage/provider/src/test_utils/mock.rs +++ b/crates/storage/provider/src/test_utils/mock.rs @@ -6,7 +6,10 @@ use crate::{ StateRootProvider, TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; use alloy_consensus::constants::EMPTY_ROOT_HASH; -use alloy_eips::{eip4895::Withdrawal, BlockHashOrNumber, BlockId, BlockNumberOrTag}; +use alloy_eips::{ + eip4895::{Withdrawal, Withdrawals}, + BlockHashOrNumber, BlockId, BlockNumberOrTag, +}; use alloy_primitives::{ keccak256, map::{HashMap, HashSet}, @@ -23,7 +26,7 @@ use reth_node_types::NodeTypes; use reth_primitives::{ Account, Block, BlockWithSenders, Bytecode, GotExpected, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, TransactionMeta, TransactionSigned, - TransactionSignedNoHash, Withdrawals, + TransactionSignedNoHash, }; use reth_stages_types::{StageCheckpoint, StageId}; use reth_storage_api::{ diff --git a/crates/storage/provider/src/test_utils/noop.rs b/crates/storage/provider/src/test_utils/noop.rs index 65c08306239..7c3848b4a53 100644 --- a/crates/storage/provider/src/test_utils/noop.rs +++ b/crates/storage/provider/src/test_utils/noop.rs @@ -4,7 +4,10 @@ use std::{ sync::Arc, }; -use alloy_eips::{eip4895::Withdrawal, BlockHashOrNumber, BlockId, BlockNumberOrTag}; +use alloy_eips::{ + eip4895::{Withdrawal, Withdrawals}, + BlockHashOrNumber, BlockId, BlockNumberOrTag, +}; use alloy_primitives::{ map::{HashMap, HashSet}, Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, TxHash, TxNumber, B256, U256, @@ -20,7 +23,7 @@ use reth_evm::ConfigureEvmEnv; use reth_primitives::{ Account, Block, BlockWithSenders, Bytecode, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, TransactionMeta, TransactionSigned, - TransactionSignedNoHash, Withdrawals, + TransactionSignedNoHash, }; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; diff --git a/crates/storage/storage-api/src/withdrawals.rs b/crates/storage/storage-api/src/withdrawals.rs index ba422a3b33b..47aa4944410 100644 --- a/crates/storage/storage-api/src/withdrawals.rs +++ b/crates/storage/storage-api/src/withdrawals.rs @@ -1,5 +1,7 @@ -use alloy_eips::{eip4895::Withdrawal, BlockHashOrNumber}; -use reth_primitives::Withdrawals; +use alloy_eips::{ + eip4895::{Withdrawal, Withdrawals}, + BlockHashOrNumber, +}; use reth_storage_errors::provider::ProviderResult; /// Client trait for fetching [Withdrawal] related data. diff --git a/examples/custom-engine-types/Cargo.toml b/examples/custom-engine-types/Cargo.toml index 1fbb3c4947a..9afd16bea16 100644 --- a/examples/custom-engine-types/Cargo.toml +++ b/examples/custom-engine-types/Cargo.toml @@ -20,6 +20,7 @@ reth-trie-db.workspace = true alloy-genesis.workspace = true alloy-rpc-types = { workspace = true, features = ["engine"] } alloy-primitives.workspace = true +alloy-eips.workspace = true eyre.workspace = true tokio.workspace = true diff --git a/examples/custom-engine-types/src/main.rs b/examples/custom-engine-types/src/main.rs index 896a4b55f6b..704ecb7e3c4 100644 --- a/examples/custom-engine-types/src/main.rs +++ b/examples/custom-engine-types/src/main.rs @@ -22,6 +22,7 @@ use std::{convert::Infallible, sync::Arc}; use serde::{Deserialize, Serialize}; use thiserror::Error; +use alloy_eips::eip4895::Withdrawals; use alloy_genesis::Genesis; use alloy_primitives::{Address, B256}; use alloy_rpc_types::{ @@ -68,7 +69,6 @@ use reth_payload_builder::{ EthBuiltPayload, EthPayloadBuilderAttributes, PayloadBuilderError, PayloadBuilderHandle, PayloadBuilderService, }; -use reth_primitives::Withdrawals; use reth_tracing::{RethTracer, Tracer}; use reth_trie_db::MerklePatriciaTrie; diff --git a/testing/ef-tests/Cargo.toml b/testing/ef-tests/Cargo.toml index a56c44ec3db..de46f62675c 100644 --- a/testing/ef-tests/Cargo.toml +++ b/testing/ef-tests/Cargo.toml @@ -14,15 +14,19 @@ workspace = true [features] ef-tests = [] asm-keccak = [ - "reth-primitives/asm-keccak", - "alloy-primitives/asm-keccak", - "revm/asm-keccak" + "reth-primitives/asm-keccak", + "alloy-primitives/asm-keccak", + "revm/asm-keccak", ] [dependencies] reth-chainspec.workspace = true reth-primitives.workspace = true -reth-db = { workspace = true, features = ["mdbx", "test-utils", "disable-lock"] } +reth-db = { workspace = true, features = [ + "mdbx", + "test-utils", + "disable-lock", +] } reth-db-api.workspace = true reth-provider = { workspace = true, features = ["test-utils"] } reth-stages.workspace = true @@ -33,6 +37,7 @@ revm = { workspace = true, features = ["secp256k1", "blst", "c-kzg"] } alloy-rlp.workspace = true alloy-primitives.workspace = true +alloy-eips.workspace = true walkdir = "2.3.3" serde.workspace = true diff --git a/testing/ef-tests/src/models.rs b/testing/ef-tests/src/models.rs index b5dc073c1da..2b6b3baa81e 100644 --- a/testing/ef-tests/src/models.rs +++ b/testing/ef-tests/src/models.rs @@ -1,6 +1,7 @@ //! Shared models for use crate::{assert::assert_equal, Error}; +use alloy_eips::eip4895::Withdrawals; use alloy_primitives::{keccak256, Address, Bloom, Bytes, B256, B64, U256}; use reth_chainspec::{ChainSpec, ChainSpecBuilder}; use reth_db::tables; @@ -9,7 +10,7 @@ use reth_db_api::{ transaction::{DbTx, DbTxMut}, }; use reth_primitives::{ - Account as RethAccount, Bytecode, Header as RethHeader, SealedHeader, StorageEntry, Withdrawals, + Account as RethAccount, Bytecode, Header as RethHeader, SealedHeader, StorageEntry, }; use serde::Deserialize; use std::{collections::BTreeMap, ops::Deref}; diff --git a/testing/testing-utils/src/generators.rs b/testing/testing-utils/src/generators.rs index 57c9acedfea..c24840a2633 100644 --- a/testing/testing-utils/src/generators.rs +++ b/testing/testing-utils/src/generators.rs @@ -1,7 +1,7 @@ //! Generators for different data structures like block headers, block bodies and ranges of those. use alloy_consensus::{Transaction as _, TxLegacy}; -use alloy_eips::eip4895::Withdrawal; +use alloy_eips::eip4895::{Withdrawal, Withdrawals}; use alloy_primitives::{Address, BlockNumber, Bytes, Sealable, TxKind, B256, U256}; pub use rand::Rng; use rand::{ @@ -9,7 +9,7 @@ use rand::{ }; use reth_primitives::{ proofs, sign_message, Account, BlockBody, Header, Log, Receipt, SealedBlock, SealedHeader, - StorageEntry, Transaction, TransactionSigned, Withdrawals, + StorageEntry, Transaction, TransactionSigned, }; use secp256k1::{Keypair, Secp256k1}; use std::{ From 1b1f0f3ef863b8f9ee19e35ba462c409711f62ed Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sat, 9 Nov 2024 17:58:31 +0100 Subject: [PATCH 089/211] chore: add Sync to PayloadBuilder (#12425) --- crates/payload/primitives/src/traits.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/payload/primitives/src/traits.rs b/crates/payload/primitives/src/traits.rs index 160808854a9..d66b0add459 100644 --- a/crates/payload/primitives/src/traits.rs +++ b/crates/payload/primitives/src/traits.rs @@ -11,7 +11,7 @@ use tokio::sync::oneshot; /// A type that can request, subscribe to and resolve payloads. #[async_trait::async_trait] -pub trait PayloadBuilder: Send + Unpin { +pub trait PayloadBuilder: Send + Sync + Unpin { /// The Payload type for the builder. type PayloadType: PayloadTypes; /// The error type returned by the builder. From 7eaa0a8f9f63424eb095ffca11060948ad273c79 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sat, 9 Nov 2024 18:27:18 +0100 Subject: [PATCH 090/211] chore: add PayloadBuilder to RpcNodeCore (#12428) --- crates/optimism/rpc/src/eth/mod.rs | 6 ++++++ crates/rpc/rpc-eth-api/src/node.rs | 12 ++++++++++++ crates/rpc/rpc/src/eth/core.rs | 5 +++++ 3 files changed, 23 insertions(+) diff --git a/crates/optimism/rpc/src/eth/mod.rs b/crates/optimism/rpc/src/eth/mod.rs index dc6e8e59fa6..624602bba38 100644 --- a/crates/optimism/rpc/src/eth/mod.rs +++ b/crates/optimism/rpc/src/eth/mod.rs @@ -121,6 +121,7 @@ where type Pool = N::Pool; type Evm = ::Evm; type Network = ::Network; + type PayloadBuilder = (); #[inline] fn pool(&self) -> &Self::Pool { @@ -137,6 +138,11 @@ where self.inner.network() } + #[inline] + fn payload_builder(&self) -> &Self::PayloadBuilder { + &() + } + #[inline] fn provider(&self) -> &Self::Provider { self.inner.provider() diff --git a/crates/rpc/rpc-eth-api/src/node.rs b/crates/rpc/rpc-eth-api/src/node.rs index 4ae79c08341..12dbe8f6664 100644 --- a/crates/rpc/rpc-eth-api/src/node.rs +++ b/crates/rpc/rpc-eth-api/src/node.rs @@ -19,6 +19,9 @@ pub trait RpcNodeCore: Clone + Send + Sync { /// Network API. type Network: Send + Sync + Clone; + /// Builds new blocks. + type PayloadBuilder: Send + Sync + Clone; + /// Returns the transaction pool of the node. fn pool(&self) -> &Self::Pool; @@ -28,6 +31,9 @@ pub trait RpcNodeCore: Clone + Send + Sync { /// Returns the handle to the network fn network(&self) -> &Self::Network; + /// Returns the handle to the payload builder service. + fn payload_builder(&self) -> &Self::PayloadBuilder; + /// Returns the provider of the node. fn provider(&self) -> &Self::Provider; } @@ -40,6 +46,7 @@ where type Pool = T::Pool; type Evm = ::Evm; type Network = ::Network; + type PayloadBuilder = ::PayloadBuilder; #[inline] fn pool(&self) -> &Self::Pool { @@ -56,6 +63,11 @@ where FullNodeComponents::network(self) } + #[inline] + fn payload_builder(&self) -> &Self::PayloadBuilder { + FullNodeComponents::payload_builder(self) + } + #[inline] fn provider(&self) -> &Self::Provider { FullNodeComponents::provider(self) diff --git a/crates/rpc/rpc/src/eth/core.rs b/crates/rpc/rpc/src/eth/core.rs index c491ca21dfb..f945aa446b5 100644 --- a/crates/rpc/rpc/src/eth/core.rs +++ b/crates/rpc/rpc/src/eth/core.rs @@ -151,6 +151,7 @@ where type Pool = Pool; type Evm = EvmConfig; type Network = Network; + type PayloadBuilder = (); fn pool(&self) -> &Self::Pool { self.inner.pool() @@ -164,6 +165,10 @@ where self.inner.network() } + fn payload_builder(&self) -> &Self::PayloadBuilder { + &() + } + fn provider(&self) -> &Self::Provider { self.inner.provider() } From c1b4fd84c5e7a2ae39037760c953af9ba4eeb90a Mon Sep 17 00:00:00 2001 From: ftupas <35031356+ftupas@users.noreply.github.com> Date: Sun, 10 Nov 2024 13:25:55 +0100 Subject: [PATCH 091/211] refactor: remove trait bound on `TxType` (#12379) --- Cargo.lock | 37 +++++ Cargo.toml | 1 + crates/primitives-traits/src/tx_type.rs | 1 - crates/primitives/Cargo.toml | 1 + crates/primitives/src/transaction/tx_type.rs | 166 +++++++------------ 5 files changed, 95 insertions(+), 111 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f81a026bd5c..0434d038411 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6271,6 +6271,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "relative-path" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" + [[package]] name = "reqwest" version = "0.12.9" @@ -8462,6 +8468,7 @@ dependencies = [ "reth-testing-utils", "reth-trie-common", "revm-primitives", + "rstest", "secp256k1", "serde", "serde_json", @@ -9530,6 +9537,36 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746" +[[package]] +name = "rstest" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a2c585be59b6b5dd66a9d2084aa1d8bd52fbdb806eafdeffb52791147862035" +dependencies = [ + "futures", + "futures-timer", + "rstest_macros", + "rustc_version 0.4.1", +] + +[[package]] +name = "rstest_macros" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "825ea780781b15345a146be27eaefb05085e337e869bff01b4306a4fd4a9ad5a" +dependencies = [ + "cfg-if", + "glob", + "proc-macro-crate", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version 0.4.1", + "syn 2.0.87", + "unicode-ident", +] + [[package]] name = "ruint" version = "1.12.3" diff --git a/Cargo.toml b/Cargo.toml index 31d2ebb8d4c..7608756b12a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -596,6 +596,7 @@ serial_test = { default-features = false, version = "3" } similar-asserts = { version = "1.5.0", features = ["serde"] } tempfile = "3.8" test-fuzz = "6" +rstest = "0.23.0" tikv-jemalloc-ctl = "0.6" tikv-jemallocator = "0.6" diff --git a/crates/primitives-traits/src/tx_type.rs b/crates/primitives-traits/src/tx_type.rs index aebf7584fe9..058f02a7ee6 100644 --- a/crates/primitives-traits/src/tx_type.rs +++ b/crates/primitives-traits/src/tx_type.rs @@ -13,7 +13,6 @@ pub trait TxType: + TryFrom + TryFrom + TryFrom - + From + Debug + Display + Clone diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index 04d96aa369a..5bef33e15ef 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -79,6 +79,7 @@ proptest.workspace = true rand.workspace = true serde_json.workspace = true test-fuzz.workspace = true +rstest.workspace = true criterion.workspace = true pprof = { workspace = true, features = [ diff --git a/crates/primitives/src/transaction/tx_type.rs b/crates/primitives/src/transaction/tx_type.rs index eff1c17a71a..0cfb2ff9d67 100644 --- a/crates/primitives/src/transaction/tx_type.rs +++ b/crates/primitives/src/transaction/tx_type.rs @@ -217,128 +217,74 @@ impl Decodable for TxType { } } -impl From for TxType { - fn from(value: alloy_consensus::TxType) -> Self { - match value { - alloy_consensus::TxType::Legacy => Self::Legacy, - alloy_consensus::TxType::Eip2930 => Self::Eip2930, - alloy_consensus::TxType::Eip1559 => Self::Eip1559, - alloy_consensus::TxType::Eip4844 => Self::Eip4844, - alloy_consensus::TxType::Eip7702 => Self::Eip7702, - } - } -} - #[cfg(test)] mod tests { use alloy_primitives::hex; - use rand::Rng; use reth_codecs::Compact; + use rstest::rstest; use super::*; - #[test] - fn test_u64_to_tx_type() { - // Test for Legacy transaction - assert_eq!(TxType::try_from(U64::from(LEGACY_TX_TYPE_ID)).unwrap(), TxType::Legacy); - - // Test for EIP2930 transaction - assert_eq!(TxType::try_from(U64::from(EIP2930_TX_TYPE_ID)).unwrap(), TxType::Eip2930); - - // Test for EIP1559 transaction - assert_eq!(TxType::try_from(U64::from(EIP1559_TX_TYPE_ID)).unwrap(), TxType::Eip1559); - - // Test for EIP4844 transaction - assert_eq!(TxType::try_from(U64::from(EIP4844_TX_TYPE_ID)).unwrap(), TxType::Eip4844); - - // Test for EIP7702 transaction - assert_eq!(TxType::try_from(U64::from(EIP7702_TX_TYPE_ID)).unwrap(), TxType::Eip7702); - - // Test for Deposit transaction - #[cfg(feature = "optimism")] - assert_eq!(TxType::try_from(U64::from(DEPOSIT_TX_TYPE_ID)).unwrap(), TxType::Deposit); - - // For transactions with unsupported values - assert!(TxType::try_from(U64::from(EIP7702_TX_TYPE_ID + 1)).is_err()); + #[rstest] + #[case(U64::from(LEGACY_TX_TYPE_ID), Ok(TxType::Legacy))] + #[case(U64::from(EIP2930_TX_TYPE_ID), Ok(TxType::Eip2930))] + #[case(U64::from(EIP1559_TX_TYPE_ID), Ok(TxType::Eip1559))] + #[case(U64::from(EIP4844_TX_TYPE_ID), Ok(TxType::Eip4844))] + #[case(U64::from(EIP7702_TX_TYPE_ID), Ok(TxType::Eip7702))] + #[cfg_attr(feature = "optimism", case(U64::from(DEPOSIT_TX_TYPE_ID), Ok(TxType::Deposit)))] + #[case(U64::MAX, Err("invalid tx type"))] + fn test_u64_to_tx_type(#[case] input: U64, #[case] expected: Result) { + let tx_type_result = TxType::try_from(input); + assert_eq!(tx_type_result, expected); } - #[test] - fn test_txtype_to_compat() { - let cases = vec![ - (TxType::Legacy, COMPACT_IDENTIFIER_LEGACY, vec![]), - (TxType::Eip2930, COMPACT_IDENTIFIER_EIP2930, vec![]), - (TxType::Eip1559, COMPACT_IDENTIFIER_EIP1559, vec![]), - (TxType::Eip4844, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP4844_TX_TYPE_ID]), - (TxType::Eip7702, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID]), - #[cfg(feature = "optimism")] - (TxType::Deposit, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![DEPOSIT_TX_TYPE_ID]), - ]; - - for (tx_type, expected_identifier, expected_buf) in cases { - let mut buf = vec![]; - let identifier = tx_type.to_compact(&mut buf); - assert_eq!( - identifier, expected_identifier, - "Unexpected identifier for TxType {tx_type:?}", - ); - assert_eq!(buf, expected_buf, "Unexpected buffer for TxType {tx_type:?}"); - } + #[rstest] + #[case(TxType::Legacy, COMPACT_IDENTIFIER_LEGACY, vec![])] + #[case(TxType::Eip2930, COMPACT_IDENTIFIER_EIP2930, vec![])] + #[case(TxType::Eip1559, COMPACT_IDENTIFIER_EIP1559, vec![])] + #[case(TxType::Eip4844, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP4844_TX_TYPE_ID])] + #[case(TxType::Eip7702, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID])] + #[cfg_attr(feature = "optimism", case(TxType::Deposit, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![DEPOSIT_TX_TYPE_ID]))] + fn test_txtype_to_compact( + #[case] tx_type: TxType, + #[case] expected_identifier: usize, + #[case] expected_buf: Vec, + ) { + let mut buf = vec![]; + let identifier = tx_type.to_compact(&mut buf); + + assert_eq!(identifier, expected_identifier, "Unexpected identifier for TxType {tx_type:?}",); + assert_eq!(buf, expected_buf, "Unexpected buffer for TxType {tx_type:?}",); } - #[test] - fn test_txtype_from_compact() { - let cases = vec![ - (TxType::Legacy, COMPACT_IDENTIFIER_LEGACY, vec![]), - (TxType::Eip2930, COMPACT_IDENTIFIER_EIP2930, vec![]), - (TxType::Eip1559, COMPACT_IDENTIFIER_EIP1559, vec![]), - (TxType::Eip4844, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP4844_TX_TYPE_ID]), - (TxType::Eip7702, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID]), - #[cfg(feature = "optimism")] - (TxType::Deposit, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![DEPOSIT_TX_TYPE_ID]), - ]; - - for (expected_type, identifier, buf) in cases { - let (actual_type, remaining_buf) = TxType::from_compact(&buf, identifier); - assert_eq!(actual_type, expected_type, "Unexpected TxType for identifier {identifier}",); - assert!( - remaining_buf.is_empty(), - "Buffer not fully consumed for identifier {identifier}", - ); - } + #[rstest] + #[case(TxType::Legacy, COMPACT_IDENTIFIER_LEGACY, vec![])] + #[case(TxType::Eip2930, COMPACT_IDENTIFIER_EIP2930, vec![])] + #[case(TxType::Eip1559, COMPACT_IDENTIFIER_EIP1559, vec![])] + #[case(TxType::Eip4844, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP4844_TX_TYPE_ID])] + #[case(TxType::Eip7702, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID])] + #[cfg_attr(feature = "optimism", case(TxType::Deposit, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![DEPOSIT_TX_TYPE_ID]))] + fn test_txtype_from_compact( + #[case] expected_type: TxType, + #[case] identifier: usize, + #[case] buf: Vec, + ) { + let (actual_type, remaining_buf) = TxType::from_compact(&buf, identifier); + + assert_eq!(actual_type, expected_type, "Unexpected TxType for identifier {identifier}"); + assert!(remaining_buf.is_empty(), "Buffer not fully consumed for identifier {identifier}"); } - #[test] - fn decode_tx_type() { - // Test for Legacy transaction - let tx_type = TxType::decode(&mut &hex!("80")[..]).unwrap(); - assert_eq!(tx_type, TxType::Legacy); - - // Test for EIP2930 transaction - let tx_type = TxType::decode(&mut &[EIP2930_TX_TYPE_ID][..]).unwrap(); - assert_eq!(tx_type, TxType::Eip2930); - - // Test for EIP1559 transaction - let tx_type = TxType::decode(&mut &[EIP1559_TX_TYPE_ID][..]).unwrap(); - assert_eq!(tx_type, TxType::Eip1559); - - // Test for EIP4844 transaction - let tx_type = TxType::decode(&mut &[EIP4844_TX_TYPE_ID][..]).unwrap(); - assert_eq!(tx_type, TxType::Eip4844); - - // Test for EIP7702 transaction - let tx_type = TxType::decode(&mut &[EIP7702_TX_TYPE_ID][..]).unwrap(); - assert_eq!(tx_type, TxType::Eip7702); - - // Test random byte not in range - let buf = [rand::thread_rng().gen_range(EIP7702_TX_TYPE_ID + 1..=u8::MAX)]; - assert!(TxType::decode(&mut &buf[..]).is_err()); - - // Test for Deposit transaction - #[cfg(feature = "optimism")] - { - let buf = [DEPOSIT_TX_TYPE_ID]; - let tx_type = TxType::decode(&mut &buf[..]).unwrap(); - assert_eq!(tx_type, TxType::Deposit); - } + #[rstest] + #[case(&hex!("80"), Ok(TxType::Legacy))] + #[case(&[EIP2930_TX_TYPE_ID], Ok(TxType::Eip2930))] + #[case(&[EIP1559_TX_TYPE_ID], Ok(TxType::Eip1559))] + #[case(&[EIP4844_TX_TYPE_ID], Ok(TxType::Eip4844))] + #[case(&[EIP7702_TX_TYPE_ID], Ok(TxType::Eip7702))] + #[case(&[u8::MAX], Err(alloy_rlp::Error::InputTooShort))] + #[cfg_attr(feature = "optimism", case(&[DEPOSIT_TX_TYPE_ID], Ok(TxType::Deposit)))] + fn decode_tx_type(#[case] input: &[u8], #[case] expected: Result) { + let tx_type_result = TxType::decode(&mut &input[..]); + assert_eq!(tx_type_result, expected) } } From 23ec0af51de8c7d6e1ca4c91c52cffa5dd17a05d Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Sun, 10 Nov 2024 13:56:36 +0100 Subject: [PATCH 092/211] chore(sdk): auto trait bounds `NodePrimitives` (#12398) --- crates/ethereum/node/src/node.rs | 2 +- crates/node/types/src/lib.rs | 15 +++++++++------ crates/optimism/node/src/node.rs | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/crates/ethereum/node/src/node.rs b/crates/ethereum/node/src/node.rs index e545a3c73c4..68ed879d223 100644 --- a/crates/ethereum/node/src/node.rs +++ b/crates/ethereum/node/src/node.rs @@ -38,7 +38,7 @@ use reth_trie_db::MerklePatriciaTrie; use crate::{EthEngineTypes, EthEvmConfig}; /// Ethereum primitive types. -#[derive(Debug)] +#[derive(Debug, Default, Clone)] pub struct EthPrimitives; impl NodePrimitives for EthPrimitives { diff --git a/crates/node/types/src/lib.rs b/crates/node/types/src/lib.rs index afb650ada2b..7f4bd4f5722 100644 --- a/crates/node/types/src/lib.rs +++ b/crates/node/types/src/lib.rs @@ -8,24 +8,27 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +pub use reth_primitives_traits::{Block, BlockBody}; + +use core::fmt; +use std::marker::PhantomData; + use reth_chainspec::EthChainSpec; use reth_db_api::{ database_metrics::{DatabaseMetadata, DatabaseMetrics}, Database, }; use reth_engine_primitives::EngineTypes; -pub use reth_primitives_traits::{Block, BlockBody}; use reth_trie_db::StateCommitment; -use std::marker::PhantomData; /// Configures all the primitive types of the node. -pub trait NodePrimitives { +pub trait NodePrimitives: Send + Sync + Unpin + Clone + Default + fmt::Debug { /// Block primitive. - type Block; + type Block: Send + Sync + Unpin + Clone + Default + fmt::Debug + 'static; /// Signed version of the transaction type. - type SignedTx; + type SignedTx: Send + Sync + Unpin + Clone + Default + fmt::Debug + 'static; /// A receipt. - type Receipt; + type Receipt: Send + Sync + Unpin + Clone + Default + fmt::Debug + 'static; } impl NodePrimitives for () { diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index 6edab570e29..323148e276b 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -41,7 +41,7 @@ use crate::{ }; /// Optimism primitive types. -#[derive(Debug)] +#[derive(Debug, Default, Clone)] pub struct OpPrimitives; impl NodePrimitives for OpPrimitives { From 7110397f8959950dee3a6c8e0057113d90ccc3e1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 10 Nov 2024 12:58:26 +0000 Subject: [PATCH 093/211] chore(deps): weekly `cargo update` (#12433) Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com> --- Cargo.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0434d038411..f532ccc5093 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -91,9 +91,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +checksum = "611cc2ae7d2e242c457e4be7f97036b8ad9ca152b499f53faf99b1ed8fc2553f" [[package]] name = "alloy-chains" @@ -1651,9 +1651,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.36" +version = "1.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baee610e9452a8f6f0a1b6194ec09ff9e2d85dea54432acdae41aa0761c95d70" +checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf" dependencies = [ "jobserver", "libc", @@ -2186,9 +2186,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", @@ -9886,9 +9886,9 @@ dependencies = [ [[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", @@ -10041,9 +10041,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 = [ "once_cell", "parking_lot", @@ -10053,9 +10053,9 @@ 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", From 3774100a0513e3d33246b3936aac74ef7251f4be Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Sun, 10 Nov 2024 14:11:58 +0100 Subject: [PATCH 094/211] chore(sdk): impl `SignedTransaction` for `TransactionSigned` (#12187) --- crates/primitives/src/transaction/mod.rs | 145 ++++++++++++----------- 1 file changed, 73 insertions(+), 72 deletions(-) diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index ed1a7daf1e8..685fd29a3c0 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -1297,96 +1297,35 @@ impl TransactionSigned { } } -impl alloy_consensus::Transaction for TransactionSigned { - fn chain_id(&self) -> Option { - self.deref().chain_id() - } - - fn nonce(&self) -> u64 { - self.deref().nonce() - } - - fn gas_limit(&self) -> u64 { - self.deref().gas_limit() - } - - fn gas_price(&self) -> Option { - self.deref().gas_price() - } - - fn max_fee_per_gas(&self) -> u128 { - self.deref().max_fee_per_gas() - } - - fn max_priority_fee_per_gas(&self) -> Option { - self.deref().max_priority_fee_per_gas() - } - - fn max_fee_per_blob_gas(&self) -> Option { - self.deref().max_fee_per_blob_gas() - } - - fn priority_fee_or_price(&self) -> u128 { - self.deref().priority_fee_or_price() - } - - fn value(&self) -> U256 { - self.deref().value() - } - - fn input(&self) -> &Bytes { - self.deref().input() - } - - fn ty(&self) -> u8 { - self.deref().ty() - } - - fn access_list(&self) -> Option<&AccessList> { - self.deref().access_list() - } - - fn blob_versioned_hashes(&self) -> Option<&[B256]> { - alloy_consensus::Transaction::blob_versioned_hashes(self.deref()) - } - - fn authorization_list(&self) -> Option<&[SignedAuthorization]> { - self.deref().authorization_list() - } - - fn kind(&self) -> TxKind { - self.deref().kind() - } -} - impl SignedTransaction for TransactionSigned { type Transaction = Transaction; fn tx_hash(&self) -> &TxHash { - Self::hash_ref(self) + &self.hash } fn transaction(&self) -> &Self::Transaction { - Self::transaction(self) + &self.transaction } fn signature(&self) -> &Signature { - Self::signature(self) + &self.signature } fn recover_signer(&self) -> Option
{ - Self::recover_signer(self) + let signature_hash = self.signature_hash(); + recover_signer(&self.signature, signature_hash) } fn recover_signer_unchecked(&self) -> Option
{ - Self::recover_signer_unchecked(self) + let signature_hash = self.signature_hash(); + recover_signer_unchecked(&self.signature, signature_hash) } - fn from_transaction_and_signature( - transaction: Self::Transaction, - signature: Signature, - ) -> Self { - Self::from_transaction_and_signature(transaction, signature) + fn from_transaction_and_signature(transaction: Transaction, signature: Signature) -> Self { + let mut initial_tx = Self { transaction, hash: Default::default(), signature }; + initial_tx.hash = initial_tx.recalculate_hash(); + initial_tx } fn fill_tx_env(&self, tx_env: &mut TxEnv, sender: Address) { @@ -1469,6 +1408,68 @@ impl SignedTransaction for TransactionSigned { } } +impl alloy_consensus::Transaction for TransactionSigned { + fn chain_id(&self) -> Option { + self.deref().chain_id() + } + + fn nonce(&self) -> u64 { + self.deref().nonce() + } + + fn gas_limit(&self) -> u64 { + self.deref().gas_limit() + } + + fn gas_price(&self) -> Option { + self.deref().gas_price() + } + + fn max_fee_per_gas(&self) -> u128 { + self.deref().max_fee_per_gas() + } + + fn max_priority_fee_per_gas(&self) -> Option { + self.deref().max_priority_fee_per_gas() + } + + fn max_fee_per_blob_gas(&self) -> Option { + self.deref().max_fee_per_blob_gas() + } + + fn priority_fee_or_price(&self) -> u128 { + self.deref().priority_fee_or_price() + } + + fn value(&self) -> U256 { + self.deref().value() + } + + fn input(&self) -> &Bytes { + self.deref().input() + } + + fn ty(&self) -> u8 { + self.deref().ty() + } + + fn access_list(&self) -> Option<&AccessList> { + self.deref().access_list() + } + + fn blob_versioned_hashes(&self) -> Option<&[B256]> { + alloy_consensus::Transaction::blob_versioned_hashes(self.deref()) + } + + fn authorization_list(&self) -> Option<&[SignedAuthorization]> { + self.deref().authorization_list() + } + + fn kind(&self) -> TxKind { + self.deref().kind() + } +} + impl From for TransactionSigned { fn from(recovered: TransactionSignedEcRecovered) -> Self { recovered.signed_transaction From b893a8879d666f8d512b38a133209268a5a88dc1 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sun, 10 Nov 2024 21:03:19 +0100 Subject: [PATCH 095/211] chore: fix deny (#12439) --- deny.toml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/deny.toml b/deny.toml index e8f60461c85..8d0807f9de5 100644 --- a/deny.toml +++ b/deny.toml @@ -4,8 +4,12 @@ [advisories] yanked = "warn" ignore = [ - # proc-macro-error 1.0.4 unmaintained https://rustsec.org/advisories/RUSTSEC-2024-0370 - "RUSTSEC-2024-0370" + # https://rustsec.org/advisories/RUSTSEC-2024-0379 used by boa (js-tracer) + "RUSTSEC-2024-0379", + # https://rustsec.org/advisories/RUSTSEC-2024-0384 used by sse example + "RUSTSEC-2024-0384", + # https://rustsec.org/advisories/RUSTSEC-2024-0388 used by ssz, will be removed https://github.com/sigp/ethereum_ssz/pull/34 + "RUSTSEC-2024-0388" ] # This section is considered when running `cargo deny check bans`. From 365f6a1f69bad747c54077d3ff6cb31a1891b334 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Mon, 11 Nov 2024 14:59:41 +0400 Subject: [PATCH 096/211] feat: `NetworkPrimitives` (#12435) --- crates/net/eth-wire-types/src/blocks.rs | 58 ++++------ crates/net/eth-wire-types/src/broadcast.rs | 15 +-- crates/net/eth-wire-types/src/lib.rs | 3 + crates/net/eth-wire-types/src/message.rs | 101 +++++++++++------- crates/net/eth-wire-types/src/primitives.rs | 83 ++++++++++++++ crates/net/eth-wire-types/src/transactions.rs | 35 +++--- crates/net/eth-wire/src/ethstream.rs | 27 +++-- crates/net/eth-wire/tests/new_block.rs | 6 +- .../net/eth-wire/tests/pooled_transactions.rs | 7 +- crates/primitives/src/transaction/pooled.rs | 4 + 10 files changed, 226 insertions(+), 113 deletions(-) create mode 100644 crates/net/eth-wire-types/src/primitives.rs diff --git a/crates/net/eth-wire-types/src/blocks.rs b/crates/net/eth-wire-types/src/blocks.rs index c24fc45022f..a7835ae8641 100644 --- a/crates/net/eth-wire-types/src/blocks.rs +++ b/crates/net/eth-wire-types/src/blocks.rs @@ -5,8 +5,7 @@ use crate::HeadersDirection; use alloy_eips::BlockHashOrNumber; use alloy_primitives::B256; use alloy_rlp::{RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper}; -use reth_codecs_derive::add_arbitrary_tests; -use reth_primitives::{BlockBody, Header}; +use reth_codecs_derive::{add_arbitrary_tests, generate_tests}; /// A request for a peer to return block headers starting at the requested block. /// The peer must return at most [`limit`](#structfield.limit) headers. @@ -41,34 +40,16 @@ pub struct GetBlockHeaders { /// The response to [`GetBlockHeaders`], containing headers if any headers were found. #[derive(Clone, Debug, PartialEq, Eq, RlpEncodableWrapper, RlpDecodableWrapper, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[add_arbitrary_tests(rlp, 10)] -pub struct BlockHeaders( +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] +pub struct BlockHeaders( /// The requested headers. - pub Vec
, + pub Vec, ); -#[cfg(any(test, feature = "arbitrary"))] -impl<'a> arbitrary::Arbitrary<'a> for BlockHeaders { - fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { - let headers_count: usize = u.int_in_range(0..=10)?; - let mut headers = Vec::with_capacity(headers_count); - - for _ in 0..headers_count { - headers.push(reth_primitives::generate_valid_header( - u.arbitrary()?, - u.arbitrary()?, - u.arbitrary()?, - u.arbitrary()?, - u.arbitrary()?, - )) - } - - Ok(Self(headers)) - } -} +generate_tests!(#[rlp, 10] BlockHeaders, EthBlockHeadersTests); -impl From> for BlockHeaders { - fn from(headers: Vec
) -> Self { +impl From> for BlockHeaders { + fn from(headers: Vec) -> Self { Self(headers) } } @@ -94,14 +75,15 @@ impl From> for GetBlockBodies { #[derive(Clone, Debug, PartialEq, Eq, RlpEncodableWrapper, RlpDecodableWrapper, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] -#[add_arbitrary_tests(rlp, 16)] -pub struct BlockBodies( +pub struct BlockBodies( /// The requested block bodies, each of which should correspond to a hash in the request. - pub Vec, + pub Vec, ); -impl From> for BlockBodies { - fn from(bodies: Vec) -> Self { +generate_tests!(#[rlp, 16] BlockBodies, EthBlockBodiesTests); + +impl From> for BlockBodies { + fn from(bodies: Vec) -> Self { Self(bodies) } } @@ -116,11 +98,9 @@ mod tests { use alloy_eips::BlockHashOrNumber; use alloy_primitives::{hex, PrimitiveSignature as Signature, TxKind, U256}; use alloy_rlp::{Decodable, Encodable}; - use reth_primitives::{Header, Transaction, TransactionSigned}; + use reth_primitives::{BlockBody, Header, Transaction, TransactionSigned}; use std::str::FromStr; - use super::BlockBody; - #[test] fn decode_hash() { // this is a valid 32 byte rlp string @@ -254,7 +234,7 @@ mod tests { // [ (f90202) 0x0457 = 1111, [ (f901fc) [ (f901f9) header ] ] ] let expected = hex!("f90202820457f901fcf901f9a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008208ae820d0582115c8215b3821a0a827788a00000000000000000000000000000000000000000000000000000000000000000880000000000000000"); let mut data = vec![]; - RequestPair:: { + RequestPair::> { request_id: 1111, message: BlockHeaders(vec![ Header { @@ -289,7 +269,7 @@ mod tests { #[test] fn decode_block_header() { let data = hex!("f90202820457f901fcf901f9a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008208ae820d0582115c8215b3821a0a827788a00000000000000000000000000000000000000000000000000000000000000000880000000000000000"); - let expected = RequestPair:: { + let expected = RequestPair::> { request_id: 1111, message: BlockHeaders(vec![ Header { @@ -357,7 +337,7 @@ mod tests { fn encode_block_bodies() { let expected = hex!("f902dc820457f902d6f902d3f8d2f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afbf901fcf901f9a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008208ae820d0582115c8215b3821a0a827788a00000000000000000000000000000000000000000000000000000000000000000880000000000000000"); let mut data = vec![]; - let request = RequestPair:: { + let request = RequestPair::> { request_id: 1111, message: BlockBodies(vec![ BlockBody { @@ -428,7 +408,7 @@ mod tests { #[test] fn decode_block_bodies() { let data = hex!("f902dc820457f902d6f902d3f8d2f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afbf901fcf901f9a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008208ae820d0582115c8215b3821a0a827788a00000000000000000000000000000000000000000000000000000000000000000880000000000000000"); - let expected = RequestPair:: { + let expected = RequestPair::> { request_id: 1111, message: BlockBodies(vec![ BlockBody { @@ -504,7 +484,7 @@ mod tests { let body = BlockBodies::default(); let mut buf = Vec::new(); body.encode(&mut buf); - let decoded = BlockBodies::decode(&mut buf.as_slice()).unwrap(); + let decoded = BlockBodies::::decode(&mut buf.as_slice()).unwrap(); assert_eq!(body, decoded); } } diff --git a/crates/net/eth-wire-types/src/broadcast.rs b/crates/net/eth-wire-types/src/broadcast.rs index 2ef6083a500..03222706992 100644 --- a/crates/net/eth-wire-types/src/broadcast.rs +++ b/crates/net/eth-wire-types/src/broadcast.rs @@ -1,14 +1,14 @@ //! Types for broadcasting new data. -use crate::{EthMessage, EthVersion}; +use crate::{EthMessage, EthVersion, NetworkPrimitives}; use alloy_rlp::{ Decodable, Encodable, RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper, }; use alloy_primitives::{Bytes, TxHash, B256, U128}; use derive_more::{Constructor, Deref, DerefMut, From, IntoIterator}; -use reth_codecs_derive::add_arbitrary_tests; -use reth_primitives::{Block, PooledTransactionsElement, TransactionSigned}; +use reth_codecs_derive::{add_arbitrary_tests, generate_tests}; +use reth_primitives::{PooledTransactionsElement, TransactionSigned}; use std::{ collections::{HashMap, HashSet}, @@ -75,14 +75,15 @@ impl From for Vec { #[derive(Clone, Debug, PartialEq, Eq, RlpEncodable, RlpDecodable, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] -#[add_arbitrary_tests(rlp, 25)] -pub struct NewBlock { +pub struct NewBlock { /// A new block. - pub block: Block, + pub block: B, /// The current total difficulty. pub td: U128, } +generate_tests!(#[rlp, 25] NewBlock, EthNewBlockTests); + /// This informs peers of transactions that have appeared on the network and are not yet included /// in a block. #[derive(Clone, Debug, PartialEq, Eq, RlpEncodableWrapper, RlpDecodableWrapper, Default)] @@ -269,7 +270,7 @@ impl NewPooledTransactionHashes { } } -impl From for EthMessage { +impl From for EthMessage { fn from(value: NewPooledTransactionHashes) -> Self { match value { NewPooledTransactionHashes::Eth66(msg) => Self::NewPooledTransactionHashes66(msg), diff --git a/crates/net/eth-wire-types/src/lib.rs b/crates/net/eth-wire-types/src/lib.rs index 0e8fd5df98a..ac7ea55d0b9 100644 --- a/crates/net/eth-wire-types/src/lib.rs +++ b/crates/net/eth-wire-types/src/lib.rs @@ -40,3 +40,6 @@ pub use disconnect_reason::*; pub mod capability; pub use capability::*; + +pub mod primitives; +pub use primitives::*; diff --git a/crates/net/eth-wire-types/src/message.rs b/crates/net/eth-wire-types/src/message.rs index 8546bfe14c8..cca6600d11e 100644 --- a/crates/net/eth-wire-types/src/message.rs +++ b/crates/net/eth-wire-types/src/message.rs @@ -11,7 +11,7 @@ use super::{ GetNodeData, GetPooledTransactions, GetReceipts, NewBlock, NewPooledTransactionHashes66, NewPooledTransactionHashes68, NodeData, PooledTransactions, Receipts, Status, Transactions, }; -use crate::{EthVersion, SharedTransactions}; +use crate::{EthNetworkPrimitives, EthVersion, NetworkPrimitives, SharedTransactions}; use alloy_primitives::bytes::{Buf, BufMut}; use alloy_rlp::{length_of_length, Decodable, Encodable, Header}; @@ -35,14 +35,18 @@ pub enum MessageError { /// An `eth` protocol message, containing a message ID and payload. #[derive(Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct ProtocolMessage { +pub struct ProtocolMessage { /// The unique identifier representing the type of the Ethereum message. pub message_type: EthMessageID, /// The content of the message, including specific data based on the message type. - pub message: EthMessage, + #[cfg_attr( + feature = "serde", + serde(bound = "EthMessage: serde::Serialize + serde::de::DeserializeOwned") + )] + pub message: EthMessage, } -impl ProtocolMessage { +impl ProtocolMessage { /// Create a new `ProtocolMessage` from a message type and message rlp bytes. pub fn decode_message(version: EthVersion, buf: &mut &[u8]) -> Result { let message_type = EthMessageID::decode(buf)?; @@ -78,7 +82,7 @@ impl ProtocolMessage { EthMessage::GetBlockHeaders(request_pair) } EthMessageID::BlockHeaders => { - let request_pair = RequestPair::::decode(buf)?; + let request_pair = RequestPair::>::decode(buf)?; EthMessage::BlockHeaders(request_pair) } EthMessageID::GetBlockBodies => { @@ -86,7 +90,7 @@ impl ProtocolMessage { EthMessage::GetBlockBodies(request_pair) } EthMessageID::BlockBodies => { - let request_pair = RequestPair::::decode(buf)?; + let request_pair = RequestPair::>::decode(buf)?; EthMessage::BlockBodies(request_pair) } EthMessageID::GetPooledTransactions => { @@ -124,7 +128,7 @@ impl ProtocolMessage { } } -impl Encodable for ProtocolMessage { +impl Encodable for ProtocolMessage { /// Encodes the protocol message into bytes. The message type is encoded as a single byte and /// prepended to the message. fn encode(&self, out: &mut dyn BufMut) { @@ -136,23 +140,23 @@ impl Encodable for ProtocolMessage { } } -impl From for ProtocolMessage { - fn from(message: EthMessage) -> Self { +impl From> for ProtocolMessage { + fn from(message: EthMessage) -> Self { Self { message_type: message.message_id(), message } } } /// Represents messages that can be sent to multiple peers. -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct ProtocolBroadcastMessage { +#[derive(Clone, Debug)] +pub struct ProtocolBroadcastMessage { /// The unique identifier representing the type of the Ethereum message. pub message_type: EthMessageID, /// The content of the message to be broadcasted, including specific data based on the message /// type. - pub message: EthBroadcastMessage, + pub message: EthBroadcastMessage, } -impl Encodable for ProtocolBroadcastMessage { +impl Encodable for ProtocolBroadcastMessage { /// Encodes the protocol message into bytes. The message type is encoded as a single byte and /// prepended to the message. fn encode(&self, out: &mut dyn BufMut) { @@ -164,8 +168,8 @@ impl Encodable for ProtocolBroadcastMessage { } } -impl From for ProtocolBroadcastMessage { - fn from(message: EthBroadcastMessage) -> Self { +impl From> for ProtocolBroadcastMessage { + fn from(message: EthBroadcastMessage) -> Self { Self { message_type: message.message_id(), message } } } @@ -189,13 +193,17 @@ impl From for ProtocolBroadcastMessage { /// [`NewPooledTransactionHashes68`] is defined. #[derive(Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub enum EthMessage { +pub enum EthMessage { /// Represents a Status message required for the protocol handshake. Status(Status), /// Represents a `NewBlockHashes` message broadcast to the network. NewBlockHashes(NewBlockHashes), /// Represents a `NewBlock` message broadcast to the network. - NewBlock(Box), + #[cfg_attr( + feature = "serde", + serde(bound = "N::Block: serde::Serialize + serde::de::DeserializeOwned") + )] + NewBlock(Box>), /// Represents a Transactions message broadcast to the network. Transactions(Transactions), /// Represents a `NewPooledTransactionHashes` message for eth/66 version. @@ -206,11 +214,19 @@ pub enum EthMessage { /// Represents a `GetBlockHeaders` request-response pair. GetBlockHeaders(RequestPair), /// Represents a `BlockHeaders` request-response pair. - BlockHeaders(RequestPair), + #[cfg_attr( + feature = "serde", + serde(bound = "N::BlockHeader: serde::Serialize + serde::de::DeserializeOwned") + )] + BlockHeaders(RequestPair>), /// Represents a `GetBlockBodies` request-response pair. GetBlockBodies(RequestPair), /// Represents a `BlockBodies` request-response pair. - BlockBodies(RequestPair), + #[cfg_attr( + feature = "serde", + serde(bound = "N::BlockBody: serde::Serialize + serde::de::DeserializeOwned") + )] + BlockBodies(RequestPair>), /// Represents a `GetPooledTransactions` request-response pair. GetPooledTransactions(RequestPair), /// Represents a `PooledTransactions` request-response pair. @@ -225,7 +241,7 @@ pub enum EthMessage { Receipts(RequestPair), } -impl EthMessage { +impl EthMessage { /// Returns the message's ID. pub const fn message_id(&self) -> EthMessageID { match self { @@ -250,7 +266,7 @@ impl EthMessage { } } -impl Encodable for EthMessage { +impl Encodable for EthMessage { fn encode(&self, out: &mut dyn BufMut) { match self { Self::Status(status) => status.encode(out), @@ -301,16 +317,16 @@ impl Encodable for EthMessage { /// /// Note: This is only useful for outgoing messages. #[derive(Clone, Debug, PartialEq, Eq)] -pub enum EthBroadcastMessage { +pub enum EthBroadcastMessage { /// Represents a new block broadcast message. - NewBlock(Arc), + NewBlock(Arc>), /// Represents a transactions broadcast message. Transactions(SharedTransactions), } // === impl EthBroadcastMessage === -impl EthBroadcastMessage { +impl EthBroadcastMessage { /// Returns the message's ID. pub const fn message_id(&self) -> EthMessageID { match self { @@ -320,7 +336,7 @@ impl EthBroadcastMessage { } } -impl Encodable for EthBroadcastMessage { +impl Encodable for EthBroadcastMessage { fn encode(&self, out: &mut dyn BufMut) { match self { Self::NewBlock(new_block) => new_block.encode(out), @@ -502,8 +518,8 @@ where mod tests { use super::MessageError; use crate::{ - message::RequestPair, EthMessage, EthMessageID, EthVersion, GetNodeData, NodeData, - ProtocolMessage, + message::RequestPair, EthMessage, EthMessageID, EthNetworkPrimitives, EthVersion, + GetNodeData, NodeData, ProtocolMessage, }; use alloy_primitives::hex; use alloy_rlp::{Decodable, Encodable, Error}; @@ -516,20 +532,30 @@ mod tests { #[test] fn test_removed_message_at_eth67() { - let get_node_data = - EthMessage::GetNodeData(RequestPair { request_id: 1337, message: GetNodeData(vec![]) }); + let get_node_data = EthMessage::::GetNodeData(RequestPair { + request_id: 1337, + message: GetNodeData(vec![]), + }); let buf = encode(ProtocolMessage { message_type: EthMessageID::GetNodeData, message: get_node_data, }); - let msg = ProtocolMessage::decode_message(crate::EthVersion::Eth67, &mut &buf[..]); + let msg = ProtocolMessage::::decode_message( + crate::EthVersion::Eth67, + &mut &buf[..], + ); assert!(matches!(msg, Err(MessageError::Invalid(..)))); - let node_data = - EthMessage::NodeData(RequestPair { request_id: 1337, message: NodeData(vec![]) }); + let node_data = EthMessage::::NodeData(RequestPair { + request_id: 1337, + message: NodeData(vec![]), + }); let buf = encode(ProtocolMessage { message_type: EthMessageID::NodeData, message: node_data }); - let msg = ProtocolMessage::decode_message(crate::EthVersion::Eth67, &mut &buf[..]); + let msg = ProtocolMessage::::decode_message( + crate::EthVersion::Eth67, + &mut &buf[..], + ); assert!(matches!(msg, Err(MessageError::Invalid(..)))); } @@ -578,10 +604,11 @@ mod tests { #[test] fn empty_block_bodies_protocol() { - let empty_block_bodies = ProtocolMessage::from(EthMessage::BlockBodies(RequestPair { - request_id: 0, - message: Default::default(), - })); + let empty_block_bodies = + ProtocolMessage::from(EthMessage::::BlockBodies(RequestPair { + request_id: 0, + message: Default::default(), + })); let mut buf = Vec::new(); empty_block_bodies.encode(&mut buf); let decoded = diff --git a/crates/net/eth-wire-types/src/primitives.rs b/crates/net/eth-wire-types/src/primitives.rs new file mode 100644 index 00000000000..ca85fa69ad6 --- /dev/null +++ b/crates/net/eth-wire-types/src/primitives.rs @@ -0,0 +1,83 @@ +//! Abstraction over primitive types in network messages. + +use std::fmt::Debug; + +use alloy_rlp::{Decodable, Encodable}; + +/// Abstraction over primitive types which might appear in network messages. See +/// [`crate::EthMessage`] for more context. +pub trait NetworkPrimitives: + Send + Sync + Unpin + Clone + Debug + PartialEq + Eq + 'static +{ + /// The block header type. + type BlockHeader: Encodable + + Decodable + + Send + + Sync + + Unpin + + Clone + + Debug + + PartialEq + + Eq + + 'static; + /// The block body type. + type BlockBody: Encodable + + Decodable + + Send + + Sync + + Unpin + + Clone + + Debug + + PartialEq + + Eq + + 'static; + /// Full block type. + type Block: Encodable + + Decodable + + Send + + Sync + + Unpin + + Clone + + Debug + + PartialEq + + Eq + + 'static; + + /// The transaction type which peers announce in `Transactions` messages. It is different from + /// `PooledTransactions` to account for Ethereum case where EIP-4844 transactions are not being + /// announced and can only be explicitly requested from peers. + type BroadcastedTransaction: Encodable + + Decodable + + Send + + Sync + + Unpin + + Clone + + Debug + + PartialEq + + Eq + + 'static; + /// The transaction type which peers return in `PooledTransactions` messages. + type PooledTransaction: Encodable + + Decodable + + Send + + Sync + + Unpin + + Clone + + Debug + + PartialEq + + Eq + + 'static; +} + +/// Primitive types used by Ethereum network. +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] +#[non_exhaustive] +pub struct EthNetworkPrimitives; + +impl NetworkPrimitives for EthNetworkPrimitives { + type BlockHeader = reth_primitives::Header; + type BlockBody = reth_primitives::BlockBody; + type Block = reth_primitives::Block; + type BroadcastedTransaction = reth_primitives::TransactionSigned; + type PooledTransaction = reth_primitives::PooledTransactionsElement; +} diff --git a/crates/net/eth-wire-types/src/transactions.rs b/crates/net/eth-wire-types/src/transactions.rs index 97d18001f13..dfedcb6f83e 100644 --- a/crates/net/eth-wire-types/src/transactions.rs +++ b/crates/net/eth-wire-types/src/transactions.rs @@ -1,12 +1,11 @@ //! Implements the `GetPooledTransactions` and `PooledTransactions` message types. +use alloy_eips::eip2718::Encodable2718; use alloy_primitives::B256; use alloy_rlp::{RlpDecodableWrapper, RlpEncodableWrapper}; use derive_more::{Constructor, Deref, IntoIterator}; use reth_codecs_derive::add_arbitrary_tests; -use reth_primitives::{ - transaction::TransactionConversionError, PooledTransactionsElement, TransactionSigned, -}; +use reth_primitives::{transaction::TransactionConversionError, PooledTransactionsElement}; /// A list of transaction hashes that the peer would like transaction bodies for. #[derive(Clone, Debug, PartialEq, Eq, RlpEncodableWrapper, RlpDecodableWrapper, Default)] @@ -42,38 +41,46 @@ where Eq, RlpEncodableWrapper, RlpDecodableWrapper, - Default, IntoIterator, Deref, Constructor, )] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct PooledTransactions( +pub struct PooledTransactions( /// The transaction bodies, each of which should correspond to a requested hash. - pub Vec, + pub Vec, ); -impl PooledTransactions { +impl PooledTransactions { /// Returns an iterator over the transaction hashes in this response. - pub fn hashes(&self) -> impl Iterator + '_ { - self.0.iter().map(|tx| tx.hash()) + pub fn hashes(&self) -> impl Iterator + '_ { + self.0.iter().map(|tx| tx.trie_hash()) } } -impl TryFrom> for PooledTransactions { +impl TryFrom> for PooledTransactions +where + T: TryFrom, +{ type Error = TransactionConversionError; - fn try_from(txs: Vec) -> Result { - txs.into_iter().map(PooledTransactionsElement::try_from).collect() + fn try_from(txs: Vec) -> Result { + txs.into_iter().map(T::try_from).collect() } } -impl FromIterator for PooledTransactions { - fn from_iter>(iter: I) -> Self { +impl FromIterator for PooledTransactions { + fn from_iter>(iter: I) -> Self { Self(iter.into_iter().collect()) } } +impl Default for PooledTransactions { + fn default() -> Self { + Self(Default::default()) + } +} + #[cfg(test)] mod tests { use crate::{message::RequestPair, GetPooledTransactions, PooledTransactions}; diff --git a/crates/net/eth-wire/src/ethstream.rs b/crates/net/eth-wire/src/ethstream.rs index 8ae599b6792..795dd630780 100644 --- a/crates/net/eth-wire/src/ethstream.rs +++ b/crates/net/eth-wire/src/ethstream.rs @@ -2,7 +2,8 @@ use crate::{ errors::{EthHandshakeError, EthStreamError}, message::{EthBroadcastMessage, ProtocolBroadcastMessage}, p2pstream::HANDSHAKE_TIMEOUT, - CanDisconnect, DisconnectReason, EthMessage, EthVersion, ProtocolMessage, Status, + CanDisconnect, DisconnectReason, EthMessage, EthNetworkPrimitives, EthVersion, ProtocolMessage, + Status, }; use alloy_primitives::bytes::{Bytes, BytesMut}; use futures::{ready, Sink, SinkExt, StreamExt}; @@ -87,7 +88,12 @@ where // we need to encode and decode here on our own because we don't have an `EthStream` yet // The max length for a status with TTD is: + self.inner - .send(alloy_rlp::encode(ProtocolMessage::from(EthMessage::Status(status))).into()) + .send( + alloy_rlp::encode(ProtocolMessage::from( + EthMessage::::Status(status), + )) + .into(), + ) .await?; let their_msg_res = self.inner.next().await; @@ -106,14 +112,15 @@ where } let version = status.version; - let msg = match ProtocolMessage::decode_message(version, &mut their_msg.as_ref()) { - Ok(m) => m, - Err(err) => { - debug!("decode error in eth handshake: msg={their_msg:x}"); - self.inner.disconnect(DisconnectReason::DisconnectRequested).await?; - return Err(EthStreamError::InvalidMessage(err)) - } - }; + let msg: ProtocolMessage = + match ProtocolMessage::decode_message(version, &mut their_msg.as_ref()) { + Ok(m) => m, + Err(err) => { + debug!("decode error in eth handshake: msg={their_msg:x}"); + self.inner.disconnect(DisconnectReason::DisconnectRequested).await?; + return Err(EthStreamError::InvalidMessage(err)) + } + }; // The following checks should match the checks in go-ethereum: // https://github.com/ethereum/go-ethereum/blob/9244d5cd61f3ea5a7645fdf2a1a96d53421e412f/eth/protocols/eth/handshake.go#L87-L89 diff --git a/crates/net/eth-wire/tests/new_block.rs b/crates/net/eth-wire/tests/new_block.rs index 266752b74ab..366bf26a3a2 100644 --- a/crates/net/eth-wire/tests/new_block.rs +++ b/crates/net/eth-wire/tests/new_block.rs @@ -11,7 +11,7 @@ fn decode_new_block_network() { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("testdata/new_block_network_rlp"); let data = fs::read_to_string(network_data_path).expect("Unable to read file"); let hex_data = hex::decode(data.trim()).unwrap(); - let _txs = NewBlock::decode(&mut &hex_data[..]).unwrap(); + let _txs: NewBlock = NewBlock::decode(&mut &hex_data[..]).unwrap(); } #[test] @@ -20,7 +20,7 @@ fn decode_new_block_network_bsc_one() { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("testdata/bsc_new_block_network_one"); let data = fs::read_to_string(network_data_path).expect("Unable to read file"); let hex_data = hex::decode(data.trim()).unwrap(); - let _txs = NewBlock::decode(&mut &hex_data[..]).unwrap(); + let _txs: NewBlock = NewBlock::decode(&mut &hex_data[..]).unwrap(); } #[test] @@ -29,5 +29,5 @@ fn decode_new_block_network_bsc_two() { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("testdata/bsc_new_block_network_two"); let data = fs::read_to_string(network_data_path).expect("Unable to read file"); let hex_data = hex::decode(data.trim()).unwrap(); - let _txs = NewBlock::decode(&mut &hex_data[..]).unwrap(); + let _txs: NewBlock = NewBlock::decode(&mut &hex_data[..]).unwrap(); } diff --git a/crates/net/eth-wire/tests/pooled_transactions.rs b/crates/net/eth-wire/tests/pooled_transactions.rs index 6690f42631a..22c5fcc3329 100644 --- a/crates/net/eth-wire/tests/pooled_transactions.rs +++ b/crates/net/eth-wire/tests/pooled_transactions.rs @@ -12,7 +12,7 @@ use test_fuzz::test_fuzz; #[test_fuzz] fn roundtrip_pooled_transactions(hex_data: Vec) -> Result<(), alloy_rlp::Error> { let input_rlp = &mut &hex_data[..]; - let txs = match PooledTransactions::decode(input_rlp) { + let txs: PooledTransactions = match PooledTransactions::decode(input_rlp) { Ok(txs) => txs, Err(e) => return Err(e), }; @@ -28,7 +28,7 @@ fn roundtrip_pooled_transactions(hex_data: Vec) -> Result<(), alloy_rlp::Err assert_eq!(expected_encoding, buf); // now do another decoding, on what we encoded - this should succeed - let txs2 = PooledTransactions::decode(&mut &buf[..]).unwrap(); + let txs2: PooledTransactions = PooledTransactions::decode(&mut &buf[..]).unwrap(); // ensure that the payload length is the same assert_eq!(txs.length(), txs2.length()); @@ -54,7 +54,8 @@ fn decode_request_pair_pooled_blob_transactions() { .join("testdata/request_pair_pooled_blob_transactions"); let data = fs::read_to_string(network_data_path).expect("Unable to read file"); let hex_data = hex::decode(data.trim()).unwrap(); - let _txs = ProtocolMessage::decode_message(EthVersion::Eth68, &mut &hex_data[..]).unwrap(); + let _txs: ProtocolMessage = + ProtocolMessage::decode_message(EthVersion::Eth68, &mut &hex_data[..]).unwrap(); } #[test] diff --git a/crates/primitives/src/transaction/pooled.rs b/crates/primitives/src/transaction/pooled.rs index 0d48dd5a443..86cd40a8fe6 100644 --- a/crates/primitives/src/transaction/pooled.rs +++ b/crates/primitives/src/transaction/pooled.rs @@ -434,6 +434,10 @@ impl Encodable2718 for PooledTransactionsElement { } } } + + fn trie_hash(&self) -> B256 { + *self.hash() + } } impl Decodable2718 for PooledTransactionsElement { From de6813093d1a657888b864a64d1d87d68e5f9bd4 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Mon, 11 Nov 2024 12:23:07 +0100 Subject: [PATCH 097/211] chore(trie): rename reth-trie-parallel modules (#12444) --- crates/blockchain-tree/src/chain.rs | 2 +- crates/engine/tree/src/tree/mod.rs | 2 +- crates/engine/tree/src/tree/root.rs | 2 +- crates/trie/parallel/benches/root.rs | 2 +- crates/trie/parallel/src/lib.rs | 4 ++-- crates/trie/parallel/src/{parallel_proof.rs => proof.rs} | 4 +--- crates/trie/parallel/src/{parallel_root.rs => root.rs} | 0 7 files changed, 7 insertions(+), 9 deletions(-) rename crates/trie/parallel/src/{parallel_proof.rs => proof.rs} (98%) rename crates/trie/parallel/src/{parallel_root.rs => root.rs} (100%) diff --git a/crates/blockchain-tree/src/chain.rs b/crates/blockchain-tree/src/chain.rs index 09ba5c3f851..6ac39c31670 100644 --- a/crates/blockchain-tree/src/chain.rs +++ b/crates/blockchain-tree/src/chain.rs @@ -23,7 +23,7 @@ use reth_provider::{ }; use reth_revm::database::StateProviderDatabase; use reth_trie::{updates::TrieUpdates, HashedPostState, TrieInput}; -use reth_trie_parallel::parallel_root::ParallelStateRoot; +use reth_trie_parallel::root::ParallelStateRoot; use std::{ collections::BTreeMap, ops::{Deref, DerefMut}, diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index 11dd95e5583..e89960d9870 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -43,7 +43,7 @@ use reth_provider::{ use reth_revm::database::StateProviderDatabase; use reth_stages_api::ControlFlow; use reth_trie::{updates::TrieUpdates, HashedPostState, TrieInput}; -use reth_trie_parallel::parallel_root::{ParallelStateRoot, ParallelStateRootError}; +use reth_trie_parallel::root::{ParallelStateRoot, ParallelStateRootError}; use revm_primitives::ResultAndState; use std::{ cmp::Ordering, diff --git a/crates/engine/tree/src/tree/root.rs b/crates/engine/tree/src/tree/root.rs index dc039d418eb..fbf6c348138 100644 --- a/crates/engine/tree/src/tree/root.rs +++ b/crates/engine/tree/src/tree/root.rs @@ -4,7 +4,7 @@ use futures::Stream; use pin_project::pin_project; use reth_provider::providers::ConsistentDbView; use reth_trie::{updates::TrieUpdates, TrieInput}; -use reth_trie_parallel::parallel_root::ParallelStateRootError; +use reth_trie_parallel::root::ParallelStateRootError; use revm_primitives::{EvmState, B256}; use std::{ future::Future, diff --git a/crates/trie/parallel/benches/root.rs b/crates/trie/parallel/benches/root.rs index d1ffe49dd0a..eb5b6575b9f 100644 --- a/crates/trie/parallel/benches/root.rs +++ b/crates/trie/parallel/benches/root.rs @@ -13,7 +13,7 @@ use reth_trie::{ TrieInput, }; use reth_trie_db::{DatabaseHashedCursorFactory, DatabaseStateRoot}; -use reth_trie_parallel::parallel_root::ParallelStateRoot; +use reth_trie_parallel::root::ParallelStateRoot; use std::collections::HashMap; pub fn calculate_state_root(c: &mut Criterion) { diff --git a/crates/trie/parallel/src/lib.rs b/crates/trie/parallel/src/lib.rs index 25fcb4bac3a..5be2a658387 100644 --- a/crates/trie/parallel/src/lib.rs +++ b/crates/trie/parallel/src/lib.rs @@ -14,10 +14,10 @@ pub use storage_root_targets::StorageRootTargets; pub mod stats; /// Implementation of parallel state root computation. -pub mod parallel_root; +pub mod root; /// Implementation of parallel proof computation. -pub mod parallel_proof; +pub mod proof; /// Parallel state root metrics. #[cfg(feature = "metrics")] diff --git a/crates/trie/parallel/src/parallel_proof.rs b/crates/trie/parallel/src/proof.rs similarity index 98% rename from crates/trie/parallel/src/parallel_proof.rs rename to crates/trie/parallel/src/proof.rs index 9c7d6b6b8b3..4cb99b50d0c 100644 --- a/crates/trie/parallel/src/parallel_proof.rs +++ b/crates/trie/parallel/src/proof.rs @@ -1,6 +1,4 @@ -use crate::{ - parallel_root::ParallelStateRootError, stats::ParallelTrieTracker, StorageRootTargets, -}; +use crate::{root::ParallelStateRootError, stats::ParallelTrieTracker, StorageRootTargets}; use alloy_primitives::{map::HashSet, B256}; use alloy_rlp::{BufMut, Encodable}; use itertools::Itertools; diff --git a/crates/trie/parallel/src/parallel_root.rs b/crates/trie/parallel/src/root.rs similarity index 100% rename from crates/trie/parallel/src/parallel_root.rs rename to crates/trie/parallel/src/root.rs From 9ff80977b528e8e30a994aa45ab3406d620417f0 Mon Sep 17 00:00:00 2001 From: Steven <112043913+stevencartavia@users.noreply.github.com> Date: Mon, 11 Nov 2024 05:24:59 -0600 Subject: [PATCH 098/211] renamed OptimismHardforks to OpHardforks (#12441) --- crates/optimism/chainspec/src/lib.rs | 6 +++--- crates/optimism/consensus/src/lib.rs | 2 +- crates/optimism/evm/src/l1.rs | 2 +- crates/optimism/hardforks/src/lib.rs | 2 +- crates/optimism/node/src/engine.rs | 2 +- crates/optimism/payload/src/builder.rs | 2 +- crates/optimism/rpc/src/eth/receipt.rs | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/crates/optimism/chainspec/src/lib.rs b/crates/optimism/chainspec/src/lib.rs index 7bd0e433a2d..018e75a924c 100644 --- a/crates/optimism/chainspec/src/lib.rs +++ b/crates/optimism/chainspec/src/lib.rs @@ -35,7 +35,7 @@ use reth_chainspec::{ }; use reth_ethereum_forks::{ChainHardforks, EthereumHardfork, ForkCondition, Hardfork}; use reth_network_peers::NodeRecord; -use reth_optimism_forks::OptimismHardforks; +use reth_optimism_forks::OpHardforks; use reth_primitives_traits::Header; #[cfg(feature = "std")] pub(crate) use std::sync::LazyLock; @@ -336,7 +336,7 @@ impl EthereumHardforks for OpChainSpec { } } -impl OptimismHardforks for OpChainSpec {} +impl OpHardforks for OpChainSpec {} impl From for OpChainSpec { fn from(genesis: Genesis) -> Self { @@ -486,7 +486,7 @@ mod tests { use alloy_primitives::b256; use reth_chainspec::{test_fork_ids, BaseFeeParams, BaseFeeParamsKind}; use reth_ethereum_forks::{EthereumHardfork, ForkCondition, ForkHash, ForkId, Head}; - use reth_optimism_forks::{OpHardfork, OptimismHardforks}; + use reth_optimism_forks::{OpHardfork, OpHardforks}; use crate::*; diff --git a/crates/optimism/consensus/src/lib.rs b/crates/optimism/consensus/src/lib.rs index bf1428815d0..565294358b8 100644 --- a/crates/optimism/consensus/src/lib.rs +++ b/crates/optimism/consensus/src/lib.rs @@ -20,7 +20,7 @@ use reth_consensus_common::validation::{ validate_shanghai_withdrawals, }; use reth_optimism_chainspec::OpChainSpec; -use reth_optimism_forks::OptimismHardforks; +use reth_optimism_forks::OpHardforks; use reth_primitives::{BlockWithSenders, GotExpected, Header, SealedBlock, SealedHeader}; use std::{sync::Arc, time::SystemTime}; diff --git a/crates/optimism/evm/src/l1.rs b/crates/optimism/evm/src/l1.rs index 6ff841b9ddc..143399a5ab7 100644 --- a/crates/optimism/evm/src/l1.rs +++ b/crates/optimism/evm/src/l1.rs @@ -297,7 +297,7 @@ where mod tests { use alloy_eips::eip2718::Decodable2718; use reth_optimism_chainspec::OP_MAINNET; - use reth_optimism_forks::OptimismHardforks; + use reth_optimism_forks::OpHardforks; use reth_primitives::{Block, BlockBody, TransactionSigned}; use super::*; diff --git a/crates/optimism/hardforks/src/lib.rs b/crates/optimism/hardforks/src/lib.rs index df159161e0e..3915bcf6cbd 100644 --- a/crates/optimism/hardforks/src/lib.rs +++ b/crates/optimism/hardforks/src/lib.rs @@ -19,7 +19,7 @@ pub use hardfork::OpHardfork; use reth_ethereum_forks::EthereumHardforks; /// Extends [`EthereumHardforks`] with optimism helper methods. -pub trait OptimismHardforks: EthereumHardforks { +pub trait OpHardforks: EthereumHardforks { /// Convenience method to check if [`OpHardfork::Bedrock`] is active at a given block /// number. fn is_bedrock_active_at_block(&self, block_number: u64) -> bool { diff --git a/crates/optimism/node/src/engine.rs b/crates/optimism/node/src/engine.rs index 7400f149a96..b79f4f81388 100644 --- a/crates/optimism/node/src/engine.rs +++ b/crates/optimism/node/src/engine.rs @@ -14,7 +14,7 @@ use reth_node_api::{ validate_version_specific_fields, EngineTypes, EngineValidator, }; use reth_optimism_chainspec::OpChainSpec; -use reth_optimism_forks::{OpHardfork, OptimismHardforks}; +use reth_optimism_forks::{OpHardfork, OpHardforks}; use reth_optimism_payload_builder::{OpBuiltPayload, OpPayloadBuilderAttributes}; /// The types used in the optimism beacon consensus engine. diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index 42326de6ea4..47ef376b705 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -13,7 +13,7 @@ use reth_evm::{system_calls::SystemCaller, ConfigureEvm, NextBlockEnvAttributes} use reth_execution_types::ExecutionOutcome; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_consensus::calculate_receipt_root_no_memo_optimism; -use reth_optimism_forks::OptimismHardforks; +use reth_optimism_forks::OpHardforks; use reth_payload_primitives::{PayloadBuilderAttributes, PayloadBuilderError}; use reth_primitives::{ proofs, diff --git a/crates/optimism/rpc/src/eth/receipt.rs b/crates/optimism/rpc/src/eth/receipt.rs index 40ee5d9fd86..f3d16b4adb5 100644 --- a/crates/optimism/rpc/src/eth/receipt.rs +++ b/crates/optimism/rpc/src/eth/receipt.rs @@ -9,7 +9,7 @@ use op_alloy_rpc_types::{L1BlockInfo, OpTransactionReceipt, OpTransactionReceipt use reth_node_api::{FullNodeComponents, NodeTypes}; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_evm::RethL1BlockInfo; -use reth_optimism_forks::OptimismHardforks; +use reth_optimism_forks::OpHardforks; use reth_primitives::{Receipt, TransactionMeta, TransactionSigned, TxType}; use reth_provider::ChainSpecProvider; use reth_rpc_eth_api::{helpers::LoadReceipt, FromEthApiError, RpcReceipt}; From 56b5937691d656c0de1e21d25406da8a77caba32 Mon Sep 17 00:00:00 2001 From: Steven <112043913+stevencartavia@users.noreply.github.com> Date: Mon, 11 Nov 2024 05:56:06 -0600 Subject: [PATCH 099/211] Move payload_attributes function to trait (#12427) --- crates/payload/builder/src/service.rs | 24 ++++++++++++------------ crates/payload/primitives/src/traits.rs | 6 ++++++ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/crates/payload/builder/src/service.rs b/crates/payload/builder/src/service.rs index 43beaf82c38..2c9975cb4c3 100644 --- a/crates/payload/builder/src/service.rs +++ b/crates/payload/builder/src/service.rs @@ -156,6 +156,18 @@ where let _ = self.to_service.send(PayloadServiceCommand::Subscribe(tx)); Ok(PayloadEvents { receiver: rx.await? }) } + + /// Returns the payload attributes associated with the given identifier. + /// + /// Note: this returns the attributes of the payload and does not resolve the job. + async fn payload_attributes( + &self, + id: PayloadId, + ) -> Option> { + let (tx, rx) = oneshot::channel(); + self.to_service.send(PayloadServiceCommand::PayloadAttributes(id, tx)).ok()?; + rx.await.ok()? + } } impl PayloadBuilderHandle @@ -169,18 +181,6 @@ where pub const fn new(to_service: mpsc::UnboundedSender>) -> Self { Self { to_service } } - - /// Returns the payload attributes associated with the given identifier. - /// - /// Note: this returns the attributes of the payload and does not resolve the job. - async fn payload_attributes( - &self, - id: PayloadId, - ) -> Option> { - let (tx, rx) = oneshot::channel(); - self.to_service.send(PayloadServiceCommand::PayloadAttributes(id, tx)).ok()?; - rx.await.ok()? - } } impl Clone for PayloadBuilderHandle diff --git a/crates/payload/primitives/src/traits.rs b/crates/payload/primitives/src/traits.rs index d66b0add459..86f04a5b550 100644 --- a/crates/payload/primitives/src/traits.rs +++ b/crates/payload/primitives/src/traits.rs @@ -50,6 +50,12 @@ pub trait PayloadBuilder: Send + Sync + Unpin { /// Sends a message to the service to subscribe to payload events. /// Returns a receiver that will receive them. async fn subscribe(&self) -> Result, Self::Error>; + + /// Returns the payload attributes associated with the given identifier. + async fn payload_attributes( + &self, + id: PayloadId, + ) -> Option::PayloadBuilderAttributes, Self::Error>>; } /// Represents a built payload type that contains a built [`SealedBlock`] and can be converted into From 5d5f44202406fba424f9472bf70636a0f8f3c2ae Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Mon, 11 Nov 2024 12:58:34 +0100 Subject: [PATCH 100/211] chore(sdk): define helper trait `FullNodePrimitives` (#12331) --- Cargo.lock | 16 ++++++------ crates/node/types/Cargo.toml | 7 ++++++ crates/node/types/src/lib.rs | 25 ++++++++++++++++--- crates/primitives-traits/src/block/body.rs | 7 ++++-- crates/primitives-traits/src/block/mod.rs | 7 ++++-- crates/primitives-traits/src/lib.rs | 2 +- crates/primitives-traits/src/receipt.rs | 9 ++++++- .../primitives-traits/src/transaction/mod.rs | 9 ++++--- .../src/transaction/signed.rs | 8 +++--- crates/primitives-traits/src/tx_type.rs | 23 +++++++++-------- 10 files changed, 79 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f532ccc5093..f8587ab2798 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -91,9 +91,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.19" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611cc2ae7d2e242c457e4be7f97036b8ad9ca152b499f53faf99b1ed8fc2553f" +checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" [[package]] name = "alloy-chains" @@ -9645,9 +9645,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.39" +version = "0.38.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375116bee2be9ed569afe2154ea6a99dfdffd257f533f187498c2a8f5feaf4ee" +checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" dependencies = [ "bitflags 2.6.0", "errno", @@ -10548,18 +10548,18 @@ checksum = "a38c90d48152c236a3ab59271da4f4ae63d678c5d7ad6b7714d7cb9760be5e4b" [[package]] name = "thiserror" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", diff --git a/crates/node/types/Cargo.toml b/crates/node/types/Cargo.toml index cc33aac30ff..588fe7c4062 100644 --- a/crates/node/types/Cargo.toml +++ b/crates/node/types/Cargo.toml @@ -17,3 +17,10 @@ reth-db-api.workspace = true reth-engine-primitives.workspace = true reth-primitives-traits.workspace = true reth-trie-db.workspace = true + +[features] +default = ["std"] +std = [ + "reth-primitives-traits/std", + "reth-chainspec/std", +] \ No newline at end of file diff --git a/crates/node/types/src/lib.rs b/crates/node/types/src/lib.rs index 7f4bd4f5722..f2bd16280f8 100644 --- a/crates/node/types/src/lib.rs +++ b/crates/node/types/src/lib.rs @@ -7,11 +7,11 @@ )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(not(feature = "std"), no_std)] -pub use reth_primitives_traits::{Block, BlockBody}; +pub use reth_primitives_traits::{Block, BlockBody, FullBlock, FullReceipt, FullSignedTx}; -use core::fmt; -use std::marker::PhantomData; +use core::{fmt, marker::PhantomData}; use reth_chainspec::EthChainSpec; use reth_db_api::{ @@ -37,6 +37,25 @@ impl NodePrimitives for () { type Receipt = (); } +/// Helper trait that sets trait bounds on [`NodePrimitives`]. +pub trait FullNodePrimitives: Send + Sync + Unpin + Clone + Default + fmt::Debug { + /// Block primitive. + type Block: FullBlock>; + /// Signed version of the transaction type. + type SignedTx: FullSignedTx; + /// A receipt. + type Receipt: FullReceipt; +} + +impl NodePrimitives for T +where + T: FullNodePrimitives, +{ + type Block = T::Block; + type SignedTx = T::SignedTx; + type Receipt = T::Receipt; +} + /// The type that configures the essential types of an Ethereum-like node. /// /// This includes the primitive types of a node and chain specification. diff --git a/crates/primitives-traits/src/block/body.rs b/crates/primitives-traits/src/block/body.rs index c9b673ec724..9b703c0d2f1 100644 --- a/crates/primitives-traits/src/block/body.rs +++ b/crates/primitives-traits/src/block/body.rs @@ -10,11 +10,14 @@ use crate::Block; /// Abstraction for block's body. pub trait BlockBody: - Clone + Send + + Sync + + Unpin + + Clone + + Default + fmt::Debug + PartialEq + Eq - + Default + serde::Serialize + for<'de> serde::Deserialize<'de> + alloy_rlp::Encodable diff --git a/crates/primitives-traits/src/block/mod.rs b/crates/primitives-traits/src/block/mod.rs index 519987606ee..125d587e42a 100644 --- a/crates/primitives-traits/src/block/mod.rs +++ b/crates/primitives-traits/src/block/mod.rs @@ -20,11 +20,14 @@ impl FullBlock for T where T: Block + Compact {} // todo: make with senders extension trait, so block can be impl by block type already containing // senders pub trait Block: - fmt::Debug + Send + + Sync + + Unpin + Clone + + Default + + fmt::Debug + PartialEq + Eq - + Default + serde::Serialize + for<'a> serde::Deserialize<'a> + From<(Self::Header, Self::Body)> diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index ec93f2a2163..6208f913c9c 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -22,7 +22,7 @@ pub mod account; pub use account::{Account, Bytecode}; pub mod receipt; -pub use receipt::Receipt; +pub use receipt::{FullReceipt, Receipt}; pub mod transaction; pub use transaction::{ diff --git a/crates/primitives-traits/src/receipt.rs b/crates/primitives-traits/src/receipt.rs index 5c317dc49a2..6ab006b89b5 100644 --- a/crates/primitives-traits/src/receipt.rs +++ b/crates/primitives-traits/src/receipt.rs @@ -1,5 +1,7 @@ //! Receipt abstraction +use core::fmt; + use alloy_consensus::TxReceipt; use reth_codecs::Compact; use serde::{Deserialize, Serialize}; @@ -11,8 +13,13 @@ impl FullReceipt for T where T: Receipt + Compact {} /// Abstraction of a receipt. pub trait Receipt: - TxReceipt + Send + + Sync + + Unpin + + Clone + Default + + fmt::Debug + + TxReceipt + alloy_rlp::Encodable + alloy_rlp::Decodable + Serialize diff --git a/crates/primitives-traits/src/transaction/mod.rs b/crates/primitives-traits/src/transaction/mod.rs index a1ad81ab327..7fd0ec88b31 100644 --- a/crates/primitives-traits/src/transaction/mod.rs +++ b/crates/primitives-traits/src/transaction/mod.rs @@ -1,6 +1,6 @@ //! Transaction abstraction -use core::{fmt::Debug, hash::Hash}; +use core::{fmt, hash::Hash}; use alloy_primitives::{TxKind, B256}; @@ -12,9 +12,12 @@ pub mod signed; #[allow(dead_code)] /// Abstraction of a transaction. pub trait Transaction: - Debug - + Default + Send + + Sync + + Unpin + Clone + + Default + + fmt::Debug + Eq + PartialEq + Hash diff --git a/crates/primitives-traits/src/transaction/signed.rs b/crates/primitives-traits/src/transaction/signed.rs index c40403865df..02e908aec6c 100644 --- a/crates/primitives-traits/src/transaction/signed.rs +++ b/crates/primitives-traits/src/transaction/signed.rs @@ -16,13 +16,15 @@ impl FullSignedTx for T where T: SignedTransaction + Co /// A signed transaction. pub trait SignedTransaction: - fmt::Debug + Send + + Sync + + Unpin + Clone + + Default + + fmt::Debug + PartialEq + Eq + Hash - + Send - + Sync + serde::Serialize + for<'a> serde::Deserialize<'a> + alloy_rlp::Encodable diff --git a/crates/primitives-traits/src/tx_type.rs b/crates/primitives-traits/src/tx_type.rs index 058f02a7ee6..a25a7d659bd 100644 --- a/crates/primitives-traits/src/tx_type.rs +++ b/crates/primitives-traits/src/tx_type.rs @@ -1,27 +1,28 @@ +use core::fmt; + use alloy_eips::eip2718::Eip2718Error; use alloy_primitives::{U64, U8}; use alloy_rlp::{Decodable, Encodable}; -use core::fmt::{Debug, Display}; /// Trait representing the behavior of a transaction type. pub trait TxType: - Into - + Into + Send + + Sync + + Unpin + + Clone + + Copy + + Default + + fmt::Debug + + fmt::Display + PartialEq + Eq + PartialEq + + Into + + Into + TryFrom + TryFrom + TryFrom - + Debug - + Display - + Clone - + Copy - + Default + Encodable + Decodable - + Send - + Sync - + 'static { } From 78e70d622996b9787f4432313df508e0f1bf27cc Mon Sep 17 00:00:00 2001 From: Tuan Tran Date: Mon, 11 Nov 2024 19:00:57 +0700 Subject: [PATCH 101/211] chore: move `new_payload_v2` into type EngineAPI (#12431) --- crates/rpc/rpc-engine-api/src/engine_api.rs | 22 ++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/crates/rpc/rpc-engine-api/src/engine_api.rs b/crates/rpc/rpc-engine-api/src/engine_api.rs index a017c50678f..afe50d915fa 100644 --- a/crates/rpc/rpc-engine-api/src/engine_api.rs +++ b/crates/rpc/rpc-engine-api/src/engine_api.rs @@ -174,6 +174,20 @@ where .inspect(|_| self.inner.on_new_payload_response())?) } + /// Metered version of `new_payload_v2`. + pub async fn new_payload_v2_metered( + &self, + payload: ExecutionPayloadInputV2, + ) -> EngineApiResult { + let start = Instant::now(); + let gas_used = payload.execution_payload.gas_used; + let res = Self::new_payload_v2(self, payload).await; + let elapsed = start.elapsed(); + self.inner.metrics.latency.new_payload_v2.record(elapsed); + self.inner.metrics.new_payload_response.update_response_metrics(&res, gas_used, elapsed); + res + } + /// See also pub async fn new_payload_v3( &self, @@ -690,13 +704,7 @@ where /// See also async fn new_payload_v2(&self, payload: ExecutionPayloadInputV2) -> RpcResult { trace!(target: "rpc::engine", "Serving engine_newPayloadV2"); - let start = Instant::now(); - let gas_used = payload.execution_payload.gas_used; - let res = Self::new_payload_v2(self, payload).await; - let elapsed = start.elapsed(); - self.inner.metrics.latency.new_payload_v2.record(elapsed); - self.inner.metrics.new_payload_response.update_response_metrics(&res, gas_used, elapsed); - Ok(res?) + Ok(self.new_payload_v2_metered(payload).await?) } /// Handler for `engine_newPayloadV3` From cdce7ee345b11068047738c2e1cc7762b073698e Mon Sep 17 00:00:00 2001 From: Tuan Tran Date: Mon, 11 Nov 2024 19:16:43 +0700 Subject: [PATCH 102/211] chore: move `new_payload_v1` into type EngineAPI (#12430) --- crates/rpc/rpc-engine-api/src/engine_api.rs | 22 ++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/crates/rpc/rpc-engine-api/src/engine_api.rs b/crates/rpc/rpc-engine-api/src/engine_api.rs index afe50d915fa..1a5e415bb2d 100644 --- a/crates/rpc/rpc-engine-api/src/engine_api.rs +++ b/crates/rpc/rpc-engine-api/src/engine_api.rs @@ -153,6 +153,20 @@ where .inspect(|_| self.inner.on_new_payload_response())?) } + /// Metered version of `new_payload_v1`. + async fn new_payload_v1_metered( + &self, + payload: ExecutionPayloadV1, + ) -> EngineApiResult { + let start = Instant::now(); + let gas_used = payload.gas_used; + let res = Self::new_payload_v1(self, payload).await; + let elapsed = start.elapsed(); + self.inner.metrics.latency.new_payload_v1.record(elapsed); + self.inner.metrics.new_payload_response.update_response_metrics(&res, gas_used, elapsed); + res + } + /// See also pub async fn new_payload_v2( &self, @@ -691,13 +705,7 @@ where /// Caution: This should not accept the `withdrawals` field async fn new_payload_v1(&self, payload: ExecutionPayloadV1) -> RpcResult { trace!(target: "rpc::engine", "Serving engine_newPayloadV1"); - let start = Instant::now(); - let gas_used = payload.gas_used; - let res = Self::new_payload_v1(self, payload).await; - let elapsed = start.elapsed(); - self.inner.metrics.latency.new_payload_v1.record(elapsed); - self.inner.metrics.new_payload_response.update_response_metrics(&res, gas_used, elapsed); - Ok(res?) + Ok(self.new_payload_v1_metered(payload).await?) } /// Handler for `engine_newPayloadV2` From 29b9238394741da9480c8327d8c2c7d0204b78ba Mon Sep 17 00:00:00 2001 From: Kien Trinh <51135161+kien6034@users.noreply.github.com> Date: Mon, 11 Nov 2024 19:23:52 +0700 Subject: [PATCH 103/211] [refactor] move `new_payload_v3` into EngineAPI (#12442) Co-authored-by: Matthias Seitz --- crates/rpc/rpc-engine-api/src/engine_api.rs | 26 ++++++++++++++------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/crates/rpc/rpc-engine-api/src/engine_api.rs b/crates/rpc/rpc-engine-api/src/engine_api.rs index 1a5e415bb2d..eeb5fcbf187 100644 --- a/crates/rpc/rpc-engine-api/src/engine_api.rs +++ b/crates/rpc/rpc-engine-api/src/engine_api.rs @@ -233,6 +233,23 @@ where .inspect(|_| self.inner.on_new_payload_response())?) } + // Metrics version of `new_payload_v3` + async fn new_payload_v3_metered( + &self, + payload: ExecutionPayloadV3, + versioned_hashes: Vec, + parent_beacon_block_root: B256, + ) -> RpcResult { + let start = Instant::now(); + let gas_used = payload.payload_inner.payload_inner.gas_used; + let res = + Self::new_payload_v3(self, payload, versioned_hashes, parent_beacon_block_root).await; + let elapsed = start.elapsed(); + self.inner.metrics.latency.new_payload_v3.record(elapsed); + self.inner.metrics.new_payload_response.update_response_metrics(&res, gas_used, elapsed); + Ok(res?) + } + /// See also pub async fn new_payload_v4( &self, @@ -724,14 +741,7 @@ where parent_beacon_block_root: B256, ) -> RpcResult { trace!(target: "rpc::engine", "Serving engine_newPayloadV3"); - let start = Instant::now(); - let gas_used = payload.payload_inner.payload_inner.gas_used; - let res = - Self::new_payload_v3(self, payload, versioned_hashes, parent_beacon_block_root).await; - let elapsed = start.elapsed(); - self.inner.metrics.latency.new_payload_v3.record(elapsed); - self.inner.metrics.new_payload_response.update_response_metrics(&res, gas_used, elapsed); - Ok(res?) + Ok(self.new_payload_v3_metered(payload, versioned_hashes, parent_beacon_block_root).await?) } /// Handler for `engine_newPayloadV4` From b0329ee4d72cd63aad20539a222d72815521c674 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Mon, 11 Nov 2024 13:52:21 +0100 Subject: [PATCH 104/211] chore(sdk): impl `Receipt` for `reth_primitives::Receipt` (#12446) --- Cargo.lock | 8 ++-- crates/primitives-traits/src/receipt.rs | 4 ++ crates/primitives/src/receipt.rs | 51 ++++++++++++++++++++++--- 3 files changed, 53 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f8587ab2798..0c64ed9a910 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -91,9 +91,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.20" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" +checksum = "611cc2ae7d2e242c457e4be7f97036b8ad9ca152b499f53faf99b1ed8fc2553f" [[package]] name = "alloy-chains" @@ -9645,9 +9645,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.40" +version = "0.38.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" +checksum = "375116bee2be9ed569afe2154ea6a99dfdffd257f533f187498c2a8f5feaf4ee" dependencies = [ "bitflags 2.6.0", "errno", diff --git a/crates/primitives-traits/src/receipt.rs b/crates/primitives-traits/src/receipt.rs index 6ab006b89b5..bfcd99b08ec 100644 --- a/crates/primitives-traits/src/receipt.rs +++ b/crates/primitives-traits/src/receipt.rs @@ -3,6 +3,7 @@ use core::fmt; use alloy_consensus::TxReceipt; +use alloy_primitives::B256; use reth_codecs::Compact; use serde::{Deserialize, Serialize}; @@ -27,4 +28,7 @@ pub trait Receipt: { /// Returns transaction type. fn tx_type(&self) -> u8; + + /// Calculates the receipts root of all receipts in a block. + fn receipts_root(receipts: &[&Self]) -> B256; } diff --git a/crates/primitives/src/receipt.rs b/crates/primitives/src/receipt.rs index e60bddb9d79..f3750b70a65 100644 --- a/crates/primitives/src/receipt.rs +++ b/crates/primitives/src/receipt.rs @@ -1,18 +1,21 @@ -#[cfg(feature = "reth-codec")] -use crate::compression::{RECEIPT_COMPRESSOR, RECEIPT_DECOMPRESSOR}; -use crate::TxType; use alloc::{vec, vec::Vec}; -use alloy_consensus::constants::{ - EIP1559_TX_TYPE_ID, EIP2930_TX_TYPE_ID, EIP4844_TX_TYPE_ID, EIP7702_TX_TYPE_ID, +use core::{cmp::Ordering, ops::Deref}; + +use alloy_consensus::{ + constants::{EIP1559_TX_TYPE_ID, EIP2930_TX_TYPE_ID, EIP4844_TX_TYPE_ID, EIP7702_TX_TYPE_ID}, + Eip658Value, TxReceipt, }; use alloy_eips::eip2718::Encodable2718; use alloy_primitives::{Bloom, Log, B256}; use alloy_rlp::{length_of_length, Decodable, Encodable, RlpDecodable, RlpEncodable}; use bytes::{Buf, BufMut}; -use core::{cmp::Ordering, ops::Deref}; use derive_more::{DerefMut, From, IntoIterator}; use serde::{Deserialize, Serialize}; +#[cfg(feature = "reth-codec")] +use crate::compression::{RECEIPT_COMPRESSOR, RECEIPT_DECOMPRESSOR}; +use crate::TxType; + /// Receipt containing result of transaction execution. #[derive( Clone, Debug, PartialEq, Eq, Default, RlpEncodable, RlpDecodable, Serialize, Deserialize, @@ -64,6 +67,42 @@ impl Receipt { } } +// todo: replace with alloy receipt +impl TxReceipt for Receipt { + fn status_or_post_state(&self) -> Eip658Value { + self.success.into() + } + + fn status(&self) -> bool { + self.success + } + + fn bloom(&self) -> Bloom { + alloy_primitives::logs_bloom(self.logs.iter()) + } + + fn cumulative_gas_used(&self) -> u128 { + self.cumulative_gas_used as u128 + } + + fn logs(&self) -> &[Log] { + &self.logs + } +} + +impl reth_primitives_traits::Receipt for Receipt { + fn tx_type(&self) -> u8 { + self.tx_type as u8 + } + + fn receipts_root(_receipts: &[&Self]) -> B256 { + #[cfg(feature = "optimism")] + panic!("This should not be called in optimism mode. Use `optimism_receipts_root_slow` instead."); + #[cfg(not(feature = "optimism"))] + crate::proofs::calculate_receipt_root_no_memo(_receipts) + } +} + /// A collection of receipts organized as a two-dimensional vector. #[derive( Clone, From 0014248cd008037c5dc4570be23d5047b019bb76 Mon Sep 17 00:00:00 2001 From: Kien Trinh <51135161+kien6034@users.noreply.github.com> Date: Mon, 11 Nov 2024 19:57:02 +0700 Subject: [PATCH 105/211] [refactor] move `new_payload_v4` into EngineAPI (#12445) Co-authored-by: Matthias Seitz --- crates/rpc/rpc-engine-api/src/engine_api.rs | 46 ++++++++++++++------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/crates/rpc/rpc-engine-api/src/engine_api.rs b/crates/rpc/rpc-engine-api/src/engine_api.rs index eeb5fcbf187..666154f3b22 100644 --- a/crates/rpc/rpc-engine-api/src/engine_api.rs +++ b/crates/rpc/rpc-engine-api/src/engine_api.rs @@ -282,6 +282,30 @@ where .inspect(|_| self.inner.on_new_payload_response())?) } + /// Metrics version of `new_payload_v4` + async fn new_payload_v4_metered( + &self, + payload: ExecutionPayloadV3, + versioned_hashes: Vec, + parent_beacon_block_root: B256, + execution_requests: Requests, + ) -> RpcResult { + let start = Instant::now(); + let gas_used = payload.payload_inner.payload_inner.gas_used; + let res = Self::new_payload_v4( + self, + payload, + versioned_hashes, + parent_beacon_block_root, + execution_requests, + ) + .await; + let elapsed = start.elapsed(); + self.inner.metrics.latency.new_payload_v4.record(elapsed); + self.inner.metrics.new_payload_response.update_response_metrics(&res, gas_used, elapsed); + Ok(res?) + } + /// Sends a message to the beacon consensus engine to update the fork choice _without_ /// withdrawals. /// @@ -754,20 +778,14 @@ where execution_requests: Requests, ) -> RpcResult { trace!(target: "rpc::engine", "Serving engine_newPayloadV4"); - let start = Instant::now(); - let gas_used = payload.payload_inner.payload_inner.gas_used; - let res = Self::new_payload_v4( - self, - payload, - versioned_hashes, - parent_beacon_block_root, - execution_requests, - ) - .await; - let elapsed = start.elapsed(); - self.inner.metrics.latency.new_payload_v4.record(elapsed); - self.inner.metrics.new_payload_response.update_response_metrics(&res, gas_used, elapsed); - Ok(res?) + Ok(self + .new_payload_v4_metered( + payload, + versioned_hashes, + parent_beacon_block_root, + execution_requests, + ) + .await?) } /// Handler for `engine_forkchoiceUpdatedV1` From 97736353447e4e5a9f9323ecf3b5839fe7ef8190 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Mon, 11 Nov 2024 14:10:40 +0100 Subject: [PATCH 106/211] chore(sdk): make `Receipts` generic over receipt (#12447) --- crates/primitives/src/receipt.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/crates/primitives/src/receipt.rs b/crates/primitives/src/receipt.rs index f3750b70a65..3258d4be6eb 100644 --- a/crates/primitives/src/receipt.rs +++ b/crates/primitives/src/receipt.rs @@ -117,12 +117,12 @@ impl reth_primitives_traits::Receipt for Receipt { DerefMut, IntoIterator, )] -pub struct Receipts { +pub struct Receipts { /// A two-dimensional vector of optional `Receipt` instances. - pub receipt_vec: Vec>>, + pub receipt_vec: Vec>>, } -impl Receipts { +impl Receipts { /// Returns the length of the `Receipts` vector. pub fn len(&self) -> usize { self.receipt_vec.len() @@ -134,26 +134,26 @@ impl Receipts { } /// Push a new vector of receipts into the `Receipts` collection. - pub fn push(&mut self, receipts: Vec>) { + pub fn push(&mut self, receipts: Vec>) { self.receipt_vec.push(receipts); } /// Retrieves all recorded receipts from index and calculates the root using the given closure. - pub fn root_slow(&self, index: usize, f: impl FnOnce(&[&Receipt]) -> B256) -> Option { + pub fn root_slow(&self, index: usize, f: impl FnOnce(&[&T]) -> B256) -> Option { let receipts = self.receipt_vec[index].iter().map(Option::as_ref).collect::>>()?; Some(f(receipts.as_slice())) } } -impl From> for Receipts { - fn from(block_receipts: Vec) -> Self { +impl From> for Receipts { + fn from(block_receipts: Vec) -> Self { Self { receipt_vec: vec![block_receipts.into_iter().map(Option::Some).collect()] } } } -impl FromIterator>> for Receipts { - fn from_iter>>>(iter: I) -> Self { +impl FromIterator>> for Receipts { + fn from_iter>>>(iter: I) -> Self { iter.into_iter().collect::>().into() } } From c4f10bd11b57cef4ed189867483de447ed457f68 Mon Sep 17 00:00:00 2001 From: clabby Date: Mon, 11 Nov 2024 10:19:50 -0500 Subject: [PATCH 107/211] feat(spec): Holocene activation time for {OP/Base} Sepolia (#12453) --- crates/optimism/chainspec/src/lib.rs | 29 +++++++++++++++++++---- crates/optimism/hardforks/src/hardfork.rs | 8 +++++-- crates/optimism/node/src/engine.rs | 28 ++++++++++------------ 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/crates/optimism/chainspec/src/lib.rs b/crates/optimism/chainspec/src/lib.rs index 018e75a924c..a835b02bd1d 100644 --- a/crates/optimism/chainspec/src/lib.rs +++ b/crates/optimism/chainspec/src/lib.rs @@ -392,6 +392,7 @@ impl From for OpChainSpec { (OpHardfork::Ecotone.boxed(), genesis_info.ecotone_time), (OpHardfork::Fjord.boxed(), genesis_info.fjord_time), (OpHardfork::Granite.boxed(), genesis_info.granite_time), + (OpHardfork::Holocene.boxed(), genesis_info.holocene_time), ]; let mut time_hardforks = time_hardfork_opts @@ -572,7 +573,11 @@ mod tests { ), ( Head { number: 0, timestamp: 1723478400, ..Default::default() }, - ForkId { hash: ForkHash([0x75, 0xde, 0xa4, 0x1e]), next: 0 }, + ForkId { hash: ForkHash([0x75, 0xde, 0xa4, 0x1e]), next: 1732201200 }, + ), + ( + Head { number: 0, timestamp: 1732201200, ..Default::default() }, + ForkId { hash: ForkHash([0x98, 0x1c, 0x21, 0x69]), next: 0 }, ), ], ); @@ -639,7 +644,11 @@ mod tests { ), ( Head { number: 0, timestamp: 1723478400, ..Default::default() }, - ForkId { hash: ForkHash([0x5e, 0xdf, 0xa3, 0xb6]), next: 0 }, + ForkId { hash: ForkHash([0x5e, 0xdf, 0xa3, 0xb6]), next: 1732201200 }, + ), + ( + Head { number: 0, timestamp: 1732201200, ..Default::default() }, + ForkId { hash: ForkHash([0x59, 0x5e, 0x2e, 0x6e]), next: 0 }, ), ], ); @@ -721,6 +730,7 @@ mod tests { "ecotoneTime": 40, "fjordTime": 50, "graniteTime": 51, + "holoceneTime": 52, "optimism": { "eip1559Elasticity": 60, "eip1559Denominator": 70 @@ -742,6 +752,8 @@ mod tests { assert_eq!(actual_fjord_timestamp, Some(serde_json::Value::from(50)).as_ref()); let actual_granite_timestamp = genesis.config.extra_fields.get("graniteTime"); assert_eq!(actual_granite_timestamp, Some(serde_json::Value::from(51)).as_ref()); + let actual_holocene_timestamp = genesis.config.extra_fields.get("holoceneTime"); + assert_eq!(actual_holocene_timestamp, Some(serde_json::Value::from(52)).as_ref()); let optimism_object = genesis.config.extra_fields.get("optimism").unwrap(); assert_eq!( @@ -765,6 +777,7 @@ mod tests { assert!(!chain_spec.is_fork_active_at_timestamp(OpHardfork::Ecotone, 0)); assert!(!chain_spec.is_fork_active_at_timestamp(OpHardfork::Fjord, 0)); assert!(!chain_spec.is_fork_active_at_timestamp(OpHardfork::Granite, 0)); + assert!(!chain_spec.is_fork_active_at_timestamp(OpHardfork::Holocene, 0)); assert!(chain_spec.is_fork_active_at_block(OpHardfork::Bedrock, 10)); assert!(chain_spec.is_fork_active_at_timestamp(OpHardfork::Regolith, 20)); @@ -772,6 +785,7 @@ mod tests { assert!(chain_spec.is_fork_active_at_timestamp(OpHardfork::Ecotone, 40)); assert!(chain_spec.is_fork_active_at_timestamp(OpHardfork::Fjord, 50)); assert!(chain_spec.is_fork_active_at_timestamp(OpHardfork::Granite, 51)); + assert!(chain_spec.is_fork_active_at_timestamp(OpHardfork::Holocene, 52)); } #[test] @@ -785,6 +799,7 @@ mod tests { "ecotoneTime": 40, "fjordTime": 50, "graniteTime": 51, + "holoceneTime": 52, "optimism": { "eip1559Elasticity": 60, "eip1559Denominator": 70, @@ -807,6 +822,8 @@ mod tests { assert_eq!(actual_fjord_timestamp, Some(serde_json::Value::from(50)).as_ref()); let actual_granite_timestamp = genesis.config.extra_fields.get("graniteTime"); assert_eq!(actual_granite_timestamp, Some(serde_json::Value::from(51)).as_ref()); + let actual_holocene_timestamp = genesis.config.extra_fields.get("holoceneTime"); + assert_eq!(actual_holocene_timestamp, Some(serde_json::Value::from(52)).as_ref()); let optimism_object = genesis.config.extra_fields.get("optimism").unwrap(); assert_eq!( @@ -837,6 +854,7 @@ mod tests { assert!(!chain_spec.is_fork_active_at_timestamp(OpHardfork::Ecotone, 0)); assert!(!chain_spec.is_fork_active_at_timestamp(OpHardfork::Fjord, 0)); assert!(!chain_spec.is_fork_active_at_timestamp(OpHardfork::Granite, 0)); + assert!(!chain_spec.is_fork_active_at_timestamp(OpHardfork::Holocene, 0)); assert!(chain_spec.is_fork_active_at_block(OpHardfork::Bedrock, 10)); assert!(chain_spec.is_fork_active_at_timestamp(OpHardfork::Regolith, 20)); @@ -844,6 +862,7 @@ mod tests { assert!(chain_spec.is_fork_active_at_timestamp(OpHardfork::Ecotone, 40)); assert!(chain_spec.is_fork_active_at_timestamp(OpHardfork::Fjord, 50)); assert!(chain_spec.is_fork_active_at_timestamp(OpHardfork::Granite, 51)); + assert!(chain_spec.is_fork_active_at_timestamp(OpHardfork::Holocene, 52)); } #[test] @@ -955,6 +974,7 @@ mod tests { (String::from("ecotoneTime"), 0.into()), (String::from("fjordTime"), 0.into()), (String::from("graniteTime"), 0.into()), + (String::from("holoceneTime"), 0.into()), ] .into_iter() .collect(), @@ -988,6 +1008,7 @@ mod tests { OpHardfork::Ecotone.boxed(), OpHardfork::Fjord.boxed(), OpHardfork::Granite.boxed(), + OpHardfork::Holocene.boxed(), ]; assert!(expected_hardforks @@ -1036,7 +1057,7 @@ mod tests { } #[test] - fn test_get_base_fee_holocene_nonce_not_set() { + fn test_get_base_fee_holocene_extra_data_not_set() { let op_chain_spec = holocene_chainspec(); let parent = Header { base_fee_per_gas: Some(1), @@ -1058,7 +1079,7 @@ mod tests { } #[test] - fn test_get_base_fee_holocene_nonce_set() { + fn test_get_base_fee_holocene_extra_data_set() { let op_chain_spec = holocene_chainspec(); let parent = Header { base_fee_per_gas: Some(1), diff --git a/crates/optimism/hardforks/src/hardfork.rs b/crates/optimism/hardforks/src/hardfork.rs index 9a9786a8fe0..91b2584e4f9 100644 --- a/crates/optimism/hardforks/src/hardfork.rs +++ b/crates/optimism/hardforks/src/hardfork.rs @@ -158,7 +158,7 @@ impl OpHardfork { Self::Ecotone => Some(1708534800), Self::Fjord => Some(1716998400), Self::Granite => Some(1723478400), - Self::Holocene => None, + Self::Holocene => Some(1732201200), }, ) } @@ -257,6 +257,7 @@ impl OpHardfork { (Self::Ecotone.boxed(), ForkCondition::Timestamp(1708534800)), (Self::Fjord.boxed(), ForkCondition::Timestamp(1716998400)), (Self::Granite.boxed(), ForkCondition::Timestamp(1723478400)), + (Self::Holocene.boxed(), ForkCondition::Timestamp(1732201200)), ]) } @@ -288,6 +289,7 @@ impl OpHardfork { (Self::Ecotone.boxed(), ForkCondition::Timestamp(1708534800)), (Self::Fjord.boxed(), ForkCondition::Timestamp(1716998400)), (Self::Granite.boxed(), ForkCondition::Timestamp(1723478400)), + (Self::Holocene.boxed(), ForkCondition::Timestamp(1732201200)), ]) } @@ -354,7 +356,8 @@ mod tests { #[test] fn check_op_hardfork_from_str() { - let hardfork_str = ["beDrOck", "rEgOlITH", "cAnYoN", "eCoToNe", "FJorD", "GRaNiTe"]; + let hardfork_str = + ["beDrOck", "rEgOlITH", "cAnYoN", "eCoToNe", "FJorD", "GRaNiTe", "hOlOcEnE"]; let expected_hardforks = [ OpHardfork::Bedrock, OpHardfork::Regolith, @@ -362,6 +365,7 @@ mod tests { OpHardfork::Ecotone, OpHardfork::Fjord, OpHardfork::Granite, + OpHardfork::Holocene, ]; let hardforks: Vec = diff --git a/crates/optimism/node/src/engine.rs b/crates/optimism/node/src/engine.rs index b79f4f81388..69755d10446 100644 --- a/crates/optimism/node/src/engine.rs +++ b/crates/optimism/node/src/engine.rs @@ -172,16 +172,12 @@ mod test { use crate::engine; use alloy_primitives::{b64, Address, B256, B64}; use alloy_rpc_types_engine::PayloadAttributes; - use reth_chainspec::ForkCondition; use reth_optimism_chainspec::BASE_SEPOLIA; use super::*; - fn get_chainspec(is_holocene: bool) -> Arc { - let mut hardforks = OpHardfork::base_sepolia(); - if is_holocene { - hardforks.insert(OpHardfork::Holocene.boxed(), ForkCondition::Timestamp(1800000000)); - } + fn get_chainspec() -> Arc { + let hardforks = OpHardfork::base_sepolia(); Arc::new(OpChainSpec { inner: ChainSpec { chain: BASE_SEPOLIA.inner.chain, @@ -217,8 +213,8 @@ mod test { #[test] fn test_well_formed_attributes_pre_holocene() { - let validator = OpEngineValidator::new(get_chainspec(false)); - let attributes = get_attributes(None, 1799999999); + let validator = OpEngineValidator::new(get_chainspec()); + let attributes = get_attributes(None, 1732201199); let result = Date: Mon, 11 Nov 2024 17:21:39 +0100 Subject: [PATCH 108/211] chore(sdk): define new `BlockHeader` trait (#12452) --- crates/evm/Cargo.toml | 1 + crates/evm/src/lib.rs | 7 +-- crates/primitives-traits/src/block/header.rs | 49 ++++++++++++++++++++ crates/primitives-traits/src/block/mod.rs | 10 ++-- crates/primitives-traits/src/lib.rs | 8 +++- 5 files changed, 65 insertions(+), 10 deletions(-) create mode 100644 crates/primitives-traits/src/block/header.rs diff --git a/crates/evm/Cargo.toml b/crates/evm/Cargo.toml index c895110209b..9d6a616af98 100644 --- a/crates/evm/Cargo.toml +++ b/crates/evm/Cargo.toml @@ -30,6 +30,7 @@ revm-primitives.workspace = true # alloy alloy-primitives.workspace = true alloy-eips.workspace = true +alloy-consensus.workspace = true auto_impl.workspace = true futures-util.workspace = true diff --git a/crates/evm/src/lib.rs b/crates/evm/src/lib.rs index e30ff9b1a7a..d20dbe4594a 100644 --- a/crates/evm/src/lib.rs +++ b/crates/evm/src/lib.rs @@ -17,13 +17,15 @@ extern crate alloc; -use crate::builder::RethEvmBuilder; +use alloy_consensus::BlockHeader as _; use alloy_primitives::{Address, Bytes, B256, U256}; use reth_primitives::TransactionSigned; use reth_primitives_traits::BlockHeader; use revm::{Database, Evm, GetInspector}; use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, Env, EnvWithHandlerCfg, SpecId, TxEnv}; +use crate::builder::RethEvmBuilder; + pub mod builder; pub mod either; pub mod execute; @@ -33,7 +35,6 @@ pub mod noop; pub mod provider; pub mod state_change; pub mod system_calls; - #[cfg(any(test, feature = "test-utils"))] /// test helpers for mocking executor pub mod test_utils; @@ -155,7 +156,7 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static { block_env.coinbase = header.beneficiary(); block_env.timestamp = U256::from(header.timestamp()); if after_merge { - block_env.prevrandao = Some(header.mix_hash()); + block_env.prevrandao = header.mix_hash(); block_env.difficulty = U256::ZERO; } else { block_env.difficulty = header.difficulty(); diff --git a/crates/primitives-traits/src/block/header.rs b/crates/primitives-traits/src/block/header.rs new file mode 100644 index 00000000000..8ad85a5961a --- /dev/null +++ b/crates/primitives-traits/src/block/header.rs @@ -0,0 +1,49 @@ +//! Block header data primitive. + +use core::fmt; + +use alloy_primitives::Sealable; +use reth_codecs::Compact; + +/// Helper trait that unifies all behaviour required by block header to support full node +/// operations. +pub trait FullBlockHeader: BlockHeader + Compact {} + +impl FullBlockHeader for T where T: BlockHeader + Compact {} + +/// Abstraction of a block header. +pub trait BlockHeader: + Send + + Sync + + Unpin + + Clone + + Default + + fmt::Debug + + PartialEq + + Eq + + serde::Serialize + + for<'de> serde::Deserialize<'de> + + alloy_rlp::Encodable + + alloy_rlp::Decodable + + alloy_consensus::BlockHeader + + Sealable +{ +} + +impl BlockHeader for T where + T: Send + + Sync + + Unpin + + Clone + + Default + + fmt::Debug + + PartialEq + + Eq + + serde::Serialize + + for<'de> serde::Deserialize<'de> + + alloy_rlp::Encodable + + alloy_rlp::Decodable + + alloy_consensus::BlockHeader + + Sealable +{ +} diff --git a/crates/primitives-traits/src/block/mod.rs b/crates/primitives-traits/src/block/mod.rs index 125d587e42a..185b61e9782 100644 --- a/crates/primitives-traits/src/block/mod.rs +++ b/crates/primitives-traits/src/block/mod.rs @@ -1,19 +1,19 @@ //! Block abstraction. pub mod body; +pub mod header; use alloc::{fmt, vec::Vec}; -use alloy_consensus::BlockHeader; -use alloy_primitives::{Address, Sealable, B256}; +use alloy_primitives::{Address, B256}; use reth_codecs::Compact; -use crate::BlockBody; +use crate::{BlockBody, BlockHeader, FullBlockHeader}; /// Helper trait that unifies all behaviour required by block to support full node operations. pub trait FullBlock: Block + Compact {} -impl FullBlock for T where T: Block + Compact {} +impl FullBlock for T where T: Block + Compact {} /// Abstraction of block data type. // todo: make sealable super-trait, depends on @@ -34,7 +34,7 @@ pub trait Block: + Into<(Self::Header, Self::Body)> { /// Header part of the block. - type Header: BlockHeader + Sealable; + type Header: BlockHeader; /// The block's body contains the transactions in the block. type Body: BlockBody; diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index 6208f913c9c..3d8aea04e3d 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -34,7 +34,11 @@ mod integer_list; pub use integer_list::{IntegerList, IntegerListError}; pub mod block; -pub use block::{body::BlockBody, Block, FullBlock}; +pub use block::{ + body::BlockBody, + header::{BlockHeader, FullBlockHeader}, + Block, FullBlock, +}; mod withdrawal; pub use withdrawal::Withdrawal; @@ -56,7 +60,7 @@ pub use tx_type::TxType; pub mod header; #[cfg(any(test, feature = "arbitrary", feature = "test-utils"))] pub use header::test_utils; -pub use header::{BlockHeader, Header, HeaderError, SealedHeader}; +pub use header::{Header, HeaderError, SealedHeader}; /// Bincode-compatible serde implementations for common abstracted types in Reth. /// From 24b3e63ab3a43674f77ada8d19372e9759ff7e11 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Mon, 11 Nov 2024 20:35:01 +0400 Subject: [PATCH 109/211] feat: make Consensus trait generic over block parts (#12451) --- crates/consensus/common/src/validation.rs | 47 ++++++++++++- crates/consensus/consensus/src/lib.rs | 34 +++++++--- crates/consensus/consensus/src/noop.rs | 25 +++++-- crates/consensus/consensus/src/test_utils.rs | 51 +++++++++++--- crates/ethereum/consensus/src/lib.rs | 14 +++- .../src/headers/reverse_headers.rs | 2 +- crates/net/network/src/fetch/mod.rs | 4 +- crates/net/p2p/src/full_block.rs | 66 ++++--------------- crates/net/p2p/src/test_utils/headers.rs | 6 +- crates/optimism/consensus/src/lib.rs | 18 +++-- crates/primitives-traits/src/header/sealed.rs | 14 ++-- crates/primitives/src/block.rs | 52 ++++++++++----- 12 files changed, 219 insertions(+), 114 deletions(-) diff --git a/crates/consensus/common/src/validation.rs b/crates/consensus/common/src/validation.rs index 5a74433e58b..c10116f2276 100644 --- a/crates/consensus/common/src/validation.rs +++ b/crates/consensus/common/src/validation.rs @@ -4,7 +4,9 @@ use alloy_consensus::constants::MAXIMUM_EXTRA_DATA_SIZE; use alloy_eips::eip4844::{DATA_GAS_PER_BLOB, MAX_DATA_GAS_PER_BLOCK}; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_consensus::ConsensusError; -use reth_primitives::{EthereumHardfork, GotExpected, Header, SealedBlock, SealedHeader}; +use reth_primitives::{ + BlockBody, EthereumHardfork, GotExpected, Header, SealedBlock, SealedHeader, +}; use revm_primitives::calc_excess_blob_gas; /// Gas used needs to be less than gas limit. Gas used is going to be checked after execution. @@ -73,6 +75,49 @@ pub fn validate_cancun_gas(block: &SealedBlock) -> Result<(), ConsensusError> { Ok(()) } +/// Ensures the block response data matches the header. +/// +/// This ensures the body response items match the header's hashes: +/// - ommer hash +/// - transaction root +/// - withdrawals root +pub fn validate_body_against_header( + body: &BlockBody, + header: &SealedHeader, +) -> Result<(), ConsensusError> { + let ommers_hash = body.calculate_ommers_root(); + if header.ommers_hash != ommers_hash { + return Err(ConsensusError::BodyOmmersHashDiff( + GotExpected { got: ommers_hash, expected: header.ommers_hash }.into(), + )) + } + + let tx_root = body.calculate_tx_root(); + if header.transactions_root != tx_root { + return Err(ConsensusError::BodyTransactionRootDiff( + GotExpected { got: tx_root, expected: header.transactions_root }.into(), + )) + } + + match (header.withdrawals_root, &body.withdrawals) { + (Some(header_withdrawals_root), Some(withdrawals)) => { + let withdrawals = withdrawals.as_slice(); + let withdrawals_root = reth_primitives::proofs::calculate_withdrawals_root(withdrawals); + if withdrawals_root != header_withdrawals_root { + return Err(ConsensusError::BodyWithdrawalsRootDiff( + GotExpected { got: withdrawals_root, expected: header_withdrawals_root }.into(), + )) + } + } + (None, None) => { + // this is ok because we assume the fork is not active in this case + } + _ => return Err(ConsensusError::WithdrawalsRootUnexpected), + } + + Ok(()) +} + /// Validate a block without regard for state: /// /// - Compares the ommer hash in the block header to the block body diff --git a/crates/consensus/consensus/src/lib.rs b/crates/consensus/consensus/src/lib.rs index 4bf5da3b152..91ec42608c1 100644 --- a/crates/consensus/consensus/src/lib.rs +++ b/crates/consensus/consensus/src/lib.rs @@ -15,8 +15,8 @@ use alloc::{fmt::Debug, vec::Vec}; use alloy_eips::eip7685::Requests; use alloy_primitives::{BlockHash, BlockNumber, Bloom, B256, U256}; use reth_primitives::{ - constants::MINIMUM_GAS_LIMIT, BlockWithSenders, GotExpected, GotExpectedBoxed, Header, - InvalidTransactionError, Receipt, SealedBlock, SealedHeader, + constants::MINIMUM_GAS_LIMIT, BlockBody, BlockWithSenders, GotExpected, GotExpectedBoxed, + Header, InvalidTransactionError, Receipt, SealedBlock, SealedHeader, }; /// A consensus implementation that does nothing. @@ -44,11 +44,11 @@ impl<'a> PostExecutionInput<'a> { /// Consensus is a protocol that chooses canonical chain. #[auto_impl::auto_impl(&, Arc)] -pub trait Consensus: Debug + Send + Sync { +pub trait Consensus: Debug + Send + Sync { /// Validate if header is correct and follows consensus specification. /// /// This is called on standalone header to check if all hashes are correct. - fn validate_header(&self, header: &SealedHeader) -> Result<(), ConsensusError>; + fn validate_header(&self, header: &SealedHeader) -> Result<(), ConsensusError>; /// Validate that the header information regarding parent are correct. /// This checks the block number, timestamp, basefee and gas limit increment. @@ -61,8 +61,8 @@ pub trait Consensus: Debug + Send + Sync { /// Note: Validating header against its parent does not include other Consensus validations. fn validate_header_against_parent( &self, - header: &SealedHeader, - parent: &SealedHeader, + header: &SealedHeader, + parent: &SealedHeader, ) -> Result<(), ConsensusError>; /// Validates the given headers @@ -71,7 +71,13 @@ pub trait Consensus: Debug + Send + Sync { /// on its own and valid against its parent. /// /// Note: this expects that the headers are in natural order (ascending block number) - fn validate_header_range(&self, headers: &[SealedHeader]) -> Result<(), HeaderConsensusError> { + fn validate_header_range( + &self, + headers: &[SealedHeader], + ) -> Result<(), HeaderConsensusError> + where + H: Clone, + { if let Some((initial_header, remaining_headers)) = headers.split_first() { self.validate_header(initial_header) .map_err(|e| HeaderConsensusError(e, initial_header.clone()))?; @@ -94,10 +100,17 @@ pub trait Consensus: Debug + Send + Sync { /// Note: validating headers with TD does not include other Consensus validation. fn validate_header_with_total_difficulty( &self, - header: &Header, + header: &H, total_difficulty: U256, ) -> Result<(), ConsensusError>; + /// Ensures that body field values match the header. + fn validate_body_against_header( + &self, + body: &B, + header: &SealedHeader, + ) -> Result<(), ConsensusError>; + /// Validate a block disregarding world state, i.e. things that can be checked before sender /// recovery and execution. /// @@ -107,7 +120,8 @@ pub trait Consensus: Debug + Send + Sync { /// **This should not be called for the genesis block**. /// /// Note: validating blocks does not include other validations of the Consensus - fn validate_block_pre_execution(&self, block: &SealedBlock) -> Result<(), ConsensusError>; + fn validate_block_pre_execution(&self, block: &SealedBlock) + -> Result<(), ConsensusError>; /// Validate a block considering world state, i.e. things that can not be checked before /// execution. @@ -407,4 +421,4 @@ impl From for ConsensusError { /// `HeaderConsensusError` combines a `ConsensusError` with the `SealedHeader` it relates to. #[derive(derive_more::Display, derive_more::Error, Debug)] #[display("Consensus error: {_0}, Invalid header: {_1:?}")] -pub struct HeaderConsensusError(ConsensusError, SealedHeader); +pub struct HeaderConsensusError(ConsensusError, SealedHeader); diff --git a/crates/consensus/consensus/src/noop.rs b/crates/consensus/consensus/src/noop.rs index 53bdb72afb2..9b72f89b176 100644 --- a/crates/consensus/consensus/src/noop.rs +++ b/crates/consensus/consensus/src/noop.rs @@ -1,34 +1,45 @@ use crate::{Consensus, ConsensusError, PostExecutionInput}; use alloy_primitives::U256; -use reth_primitives::{BlockWithSenders, Header, SealedBlock, SealedHeader}; +use reth_primitives::{BlockWithSenders, SealedBlock, SealedHeader}; /// A Consensus implementation that does nothing. #[derive(Debug, Copy, Clone, Default)] #[non_exhaustive] pub struct NoopConsensus; -impl Consensus for NoopConsensus { - fn validate_header(&self, _header: &SealedHeader) -> Result<(), ConsensusError> { +impl Consensus for NoopConsensus { + fn validate_header(&self, _header: &SealedHeader) -> Result<(), ConsensusError> { Ok(()) } fn validate_header_against_parent( &self, - _header: &SealedHeader, - _parent: &SealedHeader, + _header: &SealedHeader, + _parent: &SealedHeader, ) -> Result<(), ConsensusError> { Ok(()) } fn validate_header_with_total_difficulty( &self, - _header: &Header, + _header: &H, _total_difficulty: U256, ) -> Result<(), ConsensusError> { Ok(()) } - fn validate_block_pre_execution(&self, _block: &SealedBlock) -> Result<(), ConsensusError> { + fn validate_body_against_header( + &self, + _body: &B, + _header: &SealedHeader, + ) -> Result<(), ConsensusError> { + Ok(()) + } + + fn validate_block_pre_execution( + &self, + _block: &SealedBlock, + ) -> Result<(), ConsensusError> { Ok(()) } diff --git a/crates/consensus/consensus/src/test_utils.rs b/crates/consensus/consensus/src/test_utils.rs index 43694720917..52926ec323e 100644 --- a/crates/consensus/consensus/src/test_utils.rs +++ b/crates/consensus/consensus/src/test_utils.rs @@ -1,18 +1,25 @@ use crate::{Consensus, ConsensusError, PostExecutionInput}; use alloy_primitives::U256; use core::sync::atomic::{AtomicBool, Ordering}; -use reth_primitives::{BlockWithSenders, Header, SealedBlock, SealedHeader}; +use reth_primitives::{BlockWithSenders, SealedBlock, SealedHeader}; /// Consensus engine implementation for testing #[derive(Debug)] pub struct TestConsensus { /// Flag whether the header validation should purposefully fail fail_validation: AtomicBool, + /// Separate flag for setting whether `validate_body_against_header` should fail. It is needed + /// for testing networking logic for which the body failing this check is getting completely + /// rejected while more high-level failures are handled by the sync logic. + fail_body_against_header: AtomicBool, } impl Default for TestConsensus { fn default() -> Self { - Self { fail_validation: AtomicBool::new(false) } + Self { + fail_validation: AtomicBool::new(false), + fail_body_against_header: AtomicBool::new(false), + } } } @@ -24,12 +31,23 @@ impl TestConsensus { /// Update the validation flag. pub fn set_fail_validation(&self, val: bool) { - self.fail_validation.store(val, Ordering::SeqCst) + self.fail_validation.store(val, Ordering::SeqCst); + self.fail_body_against_header.store(val, Ordering::SeqCst); + } + + /// Returns the body validation flag. + pub fn fail_body_against_header(&self) -> bool { + self.fail_body_against_header.load(Ordering::SeqCst) + } + + /// Update the body validation flag. + pub fn set_fail_body_against_header(&self, val: bool) { + self.fail_body_against_header.store(val, Ordering::SeqCst); } } -impl Consensus for TestConsensus { - fn validate_header(&self, _header: &SealedHeader) -> Result<(), ConsensusError> { +impl Consensus for TestConsensus { + fn validate_header(&self, _header: &SealedHeader) -> Result<(), ConsensusError> { if self.fail_validation() { Err(ConsensusError::BaseFeeMissing) } else { @@ -39,8 +57,8 @@ impl Consensus for TestConsensus { fn validate_header_against_parent( &self, - _header: &SealedHeader, - _parent: &SealedHeader, + _header: &SealedHeader, + _parent: &SealedHeader, ) -> Result<(), ConsensusError> { if self.fail_validation() { Err(ConsensusError::BaseFeeMissing) @@ -51,7 +69,7 @@ impl Consensus for TestConsensus { fn validate_header_with_total_difficulty( &self, - _header: &Header, + _header: &H, _total_difficulty: U256, ) -> Result<(), ConsensusError> { if self.fail_validation() { @@ -61,7 +79,22 @@ impl Consensus for TestConsensus { } } - fn validate_block_pre_execution(&self, _block: &SealedBlock) -> Result<(), ConsensusError> { + fn validate_body_against_header( + &self, + _body: &B, + _header: &SealedHeader, + ) -> Result<(), ConsensusError> { + if self.fail_body_against_header() { + Err(ConsensusError::BaseFeeMissing) + } else { + Ok(()) + } + } + + fn validate_block_pre_execution( + &self, + _block: &SealedBlock, + ) -> Result<(), ConsensusError> { if self.fail_validation() { Err(ConsensusError::BaseFeeMissing) } else { diff --git a/crates/ethereum/consensus/src/lib.rs b/crates/ethereum/consensus/src/lib.rs index 07c2a71e8cf..d5cf692928f 100644 --- a/crates/ethereum/consensus/src/lib.rs +++ b/crates/ethereum/consensus/src/lib.rs @@ -15,11 +15,11 @@ use reth_consensus::{Consensus, ConsensusError, PostExecutionInput}; use reth_consensus_common::validation::{ validate_4844_header_standalone, validate_against_parent_4844, validate_against_parent_eip1559_base_fee, validate_against_parent_hash_number, - validate_against_parent_timestamp, validate_block_pre_execution, validate_header_base_fee, - validate_header_extradata, validate_header_gas, + validate_against_parent_timestamp, validate_block_pre_execution, validate_body_against_header, + validate_header_base_fee, validate_header_extradata, validate_header_gas, }; use reth_primitives::{ - constants::MINIMUM_GAS_LIMIT, BlockWithSenders, Header, SealedBlock, SealedHeader, + constants::MINIMUM_GAS_LIMIT, BlockBody, BlockWithSenders, Header, SealedBlock, SealedHeader, }; use std::{fmt::Debug, sync::Arc, time::SystemTime}; @@ -212,6 +212,14 @@ impl Consensu Ok(()) } + fn validate_body_against_header( + &self, + body: &BlockBody, + header: &SealedHeader, + ) -> Result<(), ConsensusError> { + validate_body_against_header(body, header) + } + fn validate_block_pre_execution(&self, block: &SealedBlock) -> Result<(), ConsensusError> { validate_block_pre_execution(block, &self.chain_spec) } diff --git a/crates/net/downloaders/src/headers/reverse_headers.rs b/crates/net/downloaders/src/headers/reverse_headers.rs index 941d140b39d..f0c28dc5d9f 100644 --- a/crates/net/downloaders/src/headers/reverse_headers.rs +++ b/crates/net/downloaders/src/headers/reverse_headers.rs @@ -1310,7 +1310,7 @@ mod tests { fn test_head_update() { let client = Arc::new(TestHeadersClient::default()); - let header = SealedHeader::default(); + let header: SealedHeader = SealedHeader::default(); let mut downloader = ReverseHeadersDownloaderBuilder::default() .build(Arc::clone(&client), Arc::new(TestConsensus::default())); diff --git a/crates/net/network/src/fetch/mod.rs b/crates/net/network/src/fetch/mod.rs index f5c0006bc3a..d37fa8b4f4a 100644 --- a/crates/net/network/src/fetch/mod.rs +++ b/crates/net/network/src/fetch/mod.rs @@ -473,7 +473,6 @@ mod tests { use super::*; use crate::{peers::PeersManager, PeersConfig}; use alloy_primitives::B512; - use reth_primitives::SealedHeader; use std::future::poll_fn; #[tokio::test(flavor = "multi_thread")] @@ -590,8 +589,7 @@ mod tests { }, response: tx, }; - let mut header = SealedHeader::default().unseal(); - header.number = 0u64; + let header = Header { number: 0, ..Default::default() }; (req, header) }; diff --git a/crates/net/p2p/src/full_block.rs b/crates/net/p2p/src/full_block.rs index e5129b68674..a61d4ea126d 100644 --- a/crates/net/p2p/src/full_block.rs +++ b/crates/net/p2p/src/full_block.rs @@ -6,10 +6,10 @@ use crate::{ BlockClient, }; use alloy_primitives::{Sealable, B256}; -use reth_consensus::{Consensus, ConsensusError}; +use reth_consensus::Consensus; use reth_eth_wire_types::HeadersDirection; use reth_network_peers::WithPeerId; -use reth_primitives::{BlockBody, GotExpected, Header, SealedBlock, SealedHeader}; +use reth_primitives::{BlockBody, Header, SealedBlock, SealedHeader}; use std::{ cmp::Reverse, collections::{HashMap, VecDeque}, @@ -55,6 +55,7 @@ where let client = self.client.clone(); FetchFullBlockFuture { hash, + consensus: self.consensus.clone(), request: FullBlockRequest { header: Some(client.get_header(hash.into())), body: Some(client.get_block_body(hash)), @@ -110,6 +111,7 @@ where Client: BlockClient, { client: Client, + consensus: Arc, hash: B256, request: FullBlockRequest, header: Option, @@ -142,7 +144,8 @@ where BodyResponse::Validated(body) => Some(SealedBlock::new(header, body)), BodyResponse::PendingValidation(resp) => { // ensure the block is valid, else retry - if let Err(err) = ensure_valid_body_response(&header, resp.data()) { + if let Err(err) = self.consensus.validate_body_against_header(resp.data(), &header) + { debug!(target: "downloaders", %err, hash=?header.hash(), "Received wrong body"); self.client.report_bad_message(resp.peer_id()); self.header = Some(header); @@ -156,7 +159,7 @@ where fn on_block_response(&mut self, resp: WithPeerId) { if let Some(ref header) = self.header { - if let Err(err) = ensure_valid_body_response(header, resp.data()) { + if let Err(err) = self.consensus.validate_body_against_header(resp.data(), header) { debug!(target: "downloaders", %err, hash=?header.hash(), "Received wrong body"); self.client.report_bad_message(resp.peer_id()); return @@ -306,50 +309,6 @@ enum BodyResponse { /// Still needs to be validated against header PendingValidation(WithPeerId), } - -/// Ensures the block response data matches the header. -/// -/// This ensures the body response items match the header's hashes: -/// - ommer hash -/// - transaction root -/// - withdrawals root -fn ensure_valid_body_response( - header: &SealedHeader, - block: &BlockBody, -) -> Result<(), ConsensusError> { - let ommers_hash = block.calculate_ommers_root(); - if header.ommers_hash != ommers_hash { - return Err(ConsensusError::BodyOmmersHashDiff( - GotExpected { got: ommers_hash, expected: header.ommers_hash }.into(), - )) - } - - let tx_root = block.calculate_tx_root(); - if header.transactions_root != tx_root { - return Err(ConsensusError::BodyTransactionRootDiff( - GotExpected { got: tx_root, expected: header.transactions_root }.into(), - )) - } - - match (header.withdrawals_root, &block.withdrawals) { - (Some(header_withdrawals_root), Some(withdrawals)) => { - let withdrawals = withdrawals.as_slice(); - let withdrawals_root = reth_primitives::proofs::calculate_withdrawals_root(withdrawals); - if withdrawals_root != header_withdrawals_root { - return Err(ConsensusError::BodyWithdrawalsRootDiff( - GotExpected { got: withdrawals_root, expected: header_withdrawals_root }.into(), - )) - } - } - (None, None) => { - // this is ok because we assume the fork is not active in this case - } - _ => return Err(ConsensusError::WithdrawalsRootUnexpected), - } - - Ok(()) -} - /// A future that downloads a range of full blocks from the network. /// /// This first fetches the headers for the given range using the inner `Client`. Once the request @@ -446,7 +405,9 @@ where BodyResponse::Validated(body) => body, BodyResponse::PendingValidation(resp) => { // ensure the block is valid, else retry - if let Err(err) = ensure_valid_body_response(header, resp.data()) { + if let Err(err) = + self.consensus.validate_body_against_header(resp.data(), header) + { debug!(target: "downloaders", %err, hash=?header.hash(), "Received wrong body in range response"); self.client.report_bad_message(resp.peer_id()); @@ -695,7 +656,7 @@ mod tests { #[tokio::test] async fn download_single_full_block() { let client = TestFullBlockClient::default(); - let header = SealedHeader::default(); + let header: SealedHeader = SealedHeader::default(); let body = BlockBody::default(); client.insert(header.clone(), body.clone()); let client = FullBlockClient::test_client(client); @@ -707,7 +668,7 @@ mod tests { #[tokio::test] async fn download_single_full_block_range() { let client = TestFullBlockClient::default(); - let header = SealedHeader::default(); + let header: SealedHeader = SealedHeader::default(); let body = BlockBody::default(); client.insert(header.clone(), body.clone()); let client = FullBlockClient::test_client(client); @@ -722,7 +683,7 @@ mod tests { client: &TestFullBlockClient, range: Range, ) -> (SealedHeader, BlockBody) { - let mut sealed_header = SealedHeader::default(); + let mut sealed_header: SealedHeader = SealedHeader::default(); let body = BlockBody::default(); for _ in range { let (mut header, hash) = sealed_header.split(); @@ -785,6 +746,7 @@ mod tests { let test_consensus = reth_consensus::test_utils::TestConsensus::default(); test_consensus.set_fail_validation(true); + test_consensus.set_fail_body_against_header(false); let client = FullBlockClient::new(client, Arc::new(test_consensus)); let received = client.get_full_block_range(header.hash(), range_length as u64).await; diff --git a/crates/net/p2p/src/test_utils/headers.rs b/crates/net/p2p/src/test_utils/headers.rs index e61183d22e4..4f603f6339b 100644 --- a/crates/net/p2p/src/test_utils/headers.rs +++ b/crates/net/p2p/src/test_utils/headers.rs @@ -143,8 +143,10 @@ impl Stream for TestDownload { return Poll::Ready(None) } - let empty = SealedHeader::default(); - if let Err(error) = this.consensus.validate_header_against_parent(&empty, &empty) { + let empty: SealedHeader = SealedHeader::default(); + if let Err(error) = + Consensus::<_>::validate_header_against_parent(&this.consensus, &empty, &empty) + { this.done = true; return Poll::Ready(Some(Err(DownloadError::HeaderValidation { hash: empty.hash(), diff --git a/crates/optimism/consensus/src/lib.rs b/crates/optimism/consensus/src/lib.rs index 565294358b8..476b259529e 100644 --- a/crates/optimism/consensus/src/lib.rs +++ b/crates/optimism/consensus/src/lib.rs @@ -15,13 +15,15 @@ use reth_chainspec::EthereumHardforks; use reth_consensus::{Consensus, ConsensusError, PostExecutionInput}; use reth_consensus_common::validation::{ validate_against_parent_4844, validate_against_parent_eip1559_base_fee, - validate_against_parent_hash_number, validate_against_parent_timestamp, validate_cancun_gas, - validate_header_base_fee, validate_header_extradata, validate_header_gas, - validate_shanghai_withdrawals, + validate_against_parent_hash_number, validate_against_parent_timestamp, + validate_body_against_header, validate_cancun_gas, validate_header_base_fee, + validate_header_extradata, validate_header_gas, validate_shanghai_withdrawals, }; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_forks::OpHardforks; -use reth_primitives::{BlockWithSenders, GotExpected, Header, SealedBlock, SealedHeader}; +use reth_primitives::{ + BlockBody, BlockWithSenders, GotExpected, Header, SealedBlock, SealedHeader, +}; use std::{sync::Arc, time::SystemTime}; mod proof; @@ -119,6 +121,14 @@ impl Consensus for OpBeaconConsensus { Ok(()) } + fn validate_body_against_header( + &self, + body: &BlockBody, + header: &SealedHeader, + ) -> Result<(), ConsensusError> { + validate_body_against_header(body, header) + } + fn validate_block_pre_execution(&self, block: &SealedBlock) -> Result<(), ConsensusError> { // Check ommers hash let ommers_hash = reth_primitives::proofs::calculate_ommers_root(&block.body.ommers); diff --git a/crates/primitives-traits/src/header/sealed.rs b/crates/primitives-traits/src/header/sealed.rs index 7552ece31f1..799f698f1c5 100644 --- a/crates/primitives-traits/src/header/sealed.rs +++ b/crates/primitives-traits/src/header/sealed.rs @@ -30,12 +30,10 @@ impl SealedHeader { pub const fn new(header: H, hash: BlockHash) -> Self { Self { header, hash } } -} -impl SealedHeader { /// Returns the sealed Header fields. #[inline] - pub const fn header(&self) -> &Header { + pub const fn header(&self) -> &H { &self.header } @@ -46,15 +44,17 @@ impl SealedHeader { } /// Extract raw header that can be modified. - pub fn unseal(self) -> Header { + pub fn unseal(self) -> H { self.header } /// This is the inverse of [`Header::seal_slow`] which returns the raw header and hash. - pub fn split(self) -> (Header, BlockHash) { + pub fn split(self) -> (H, BlockHash) { (self.header, self.hash) } +} +impl SealedHeader { /// Return the number hash tuple. pub fn num_hash(&self) -> BlockNumHash { BlockNumHash::new(self.number, self.hash) @@ -67,9 +67,9 @@ impl SealedHeader { } } -impl Default for SealedHeader { +impl Default for SealedHeader { fn default() -> Self { - let sealed = Header::default().seal_slow(); + let sealed = H::default().seal_slow(); let (header, hash) = sealed.into_parts(); Self { header, hash } } diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index 54bcb27293c..b54a7bd0f78 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -256,22 +256,21 @@ impl BlockWithSenders { /// Sealed Ethereum full block. /// /// Withdrawals can be optionally included at the end of the RLP encoded message. -#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] #[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(rlp, 32))] -#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, Deref, DerefMut)] -pub struct SealedBlock { +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Deref, DerefMut)] +pub struct SealedBlock { /// Locked block header. #[deref] #[deref_mut] - pub header: SealedHeader, + pub header: SealedHeader, /// Block body. - pub body: BlockBody, + pub body: B, } -impl SealedBlock { +impl SealedBlock { /// Create a new sealed block instance using the sealed header and block body. #[inline] - pub const fn new(header: SealedHeader, body: BlockBody) -> Self { + pub const fn new(header: SealedHeader, body: B) -> Self { Self { header, body } } @@ -281,16 +280,18 @@ impl SealedBlock { self.header.hash() } - /// Splits the sealed block into underlying components + /// Splits the [`BlockBody`] and [`SealedHeader`] into separate components #[inline] - pub fn split(self) -> (SealedHeader, Vec, Vec
) { - (self.header, self.body.transactions, self.body.ommers) + pub fn split_header_body(self) -> (SealedHeader, B) { + (self.header, self.body) } +} - /// Splits the [`BlockBody`] and [`SealedHeader`] into separate components +impl SealedBlock { + /// Splits the sealed block into underlying components #[inline] - pub fn split_header_body(self) -> (SealedHeader, BlockBody) { - (self.header, self.body) + pub fn split(self) -> (SealedHeader, Vec, Vec
) { + (self.header, self.body.transactions, self.body.ommers) } /// Returns an iterator over all blob transactions of the block @@ -436,6 +437,27 @@ impl From for Block { } } +impl Default for SealedBlock +where + SealedHeader: Default, + B: Default, +{ + fn default() -> Self { + Self { header: Default::default(), body: Default::default() } + } +} + +#[cfg(any(test, feature = "arbitrary"))] +impl<'a, H, B> arbitrary::Arbitrary<'a> for SealedBlock +where + SealedHeader: arbitrary::Arbitrary<'a>, + B: arbitrary::Arbitrary<'a>, +{ + fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { + Ok(Self { header: u.arbitrary()?, body: u.arbitrary()? }) + } +} + /// Sealed block with senders recovered from transactions. #[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, Deref, DerefMut)] pub struct SealedBlockWithSenders { @@ -503,7 +525,7 @@ impl SealedBlockWithSenders { #[cfg(any(test, feature = "arbitrary"))] impl<'a> arbitrary::Arbitrary<'a> for SealedBlockWithSenders { fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { - let block = SealedBlock::arbitrary(u)?; + let block: SealedBlock = SealedBlock::arbitrary(u)?; let senders = block .body @@ -1083,7 +1105,7 @@ mod tests { #[test] fn test_default_seal() { - let block = SealedBlock::default(); + let block: SealedBlock = SealedBlock::default(); let sealed = block.hash(); let block = block.unseal(); let block = block.seal_slow(); From eccff7d24b991746af8a51346cd54361b5992bca Mon Sep 17 00:00:00 2001 From: Tuan Tran Date: Mon, 11 Nov 2024 23:54:00 +0700 Subject: [PATCH 110/211] chore(reth_primitives): Use trait for `size` methods in primitive types (#12201) Co-authored-by: Matthias Seitz --- Cargo.lock | 4 +++ crates/net/downloaders/Cargo.toml | 4 ++- crates/net/downloaders/src/bodies/bodies.rs | 1 + crates/net/downloaders/src/bodies/request.rs | 1 + crates/net/p2p/Cargo.toml | 8 +++-- crates/net/p2p/src/bodies/response.rs | 21 +++++++------ crates/primitives-traits/src/header/sealed.rs | 6 +++- crates/primitives-traits/src/lib.rs | 4 +++ crates/primitives-traits/src/size.rs | 5 +++ crates/primitives/src/block.rs | 23 +++++++++----- crates/primitives/src/transaction/mod.rs | 31 ++++++++++--------- crates/prune/prune/Cargo.toml | 1 + .../src/segments/user/receipts_by_logs.rs | 2 +- crates/transaction-pool/Cargo.toml | 10 ++++-- .../transaction-pool/src/test_utils/mock.rs | 2 +- crates/transaction-pool/src/validate/eth.rs | 3 +- 16 files changed, 84 insertions(+), 42 deletions(-) create mode 100644 crates/primitives-traits/src/size.rs diff --git a/Cargo.lock b/Cargo.lock index 0c64ed9a910..0990a469950 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7039,6 +7039,7 @@ dependencies = [ "reth-network-p2p", "reth-network-peers", "reth-primitives", + "reth-primitives-traits", "reth-provider", "reth-storage-api", "reth-tasks", @@ -7828,6 +7829,7 @@ dependencies = [ "reth-network-peers", "reth-network-types", "reth-primitives", + "reth-primitives-traits", "reth-storage-errors", "tokio", "tracing", @@ -8570,6 +8572,7 @@ dependencies = [ "reth-errors", "reth-exex-types", "reth-metrics", + "reth-primitives-traits", "reth-provider", "reth-prune-types", "reth-stages", @@ -9192,6 +9195,7 @@ dependencies = [ "reth-fs-util", "reth-metrics", "reth-primitives", + "reth-primitives-traits", "reth-provider", "reth-storage-api", "reth-tasks", diff --git a/crates/net/downloaders/Cargo.toml b/crates/net/downloaders/Cargo.toml index 272db6fc6d1..69a59f698de 100644 --- a/crates/net/downloaders/Cargo.toml +++ b/crates/net/downloaders/Cargo.toml @@ -18,6 +18,7 @@ reth-consensus.workspace = true reth-network-p2p.workspace = true reth-network-peers.workspace = true reth-primitives.workspace = true +reth-primitives-traits.workspace = true reth-storage-api.workspace = true reth-tasks.workspace = true @@ -80,5 +81,6 @@ test-utils = [ "reth-chainspec/test-utils", "reth-primitives/test-utils", "reth-db-api?/test-utils", - "reth-provider/test-utils" + "reth-provider/test-utils", + "reth-primitives-traits/test-utils" ] diff --git a/crates/net/downloaders/src/bodies/bodies.rs b/crates/net/downloaders/src/bodies/bodies.rs index 314f3a09084..af113fdb38b 100644 --- a/crates/net/downloaders/src/bodies/bodies.rs +++ b/crates/net/downloaders/src/bodies/bodies.rs @@ -14,6 +14,7 @@ use reth_network_p2p::{ error::{DownloadError, DownloadResult}, }; use reth_primitives::SealedHeader; +use reth_primitives_traits::size::InMemorySize; use reth_storage_api::HeaderProvider; use reth_tasks::{TaskSpawner, TokioTaskExecutor}; use std::{ diff --git a/crates/net/downloaders/src/bodies/request.rs b/crates/net/downloaders/src/bodies/request.rs index c2b36732b51..5ab44ed0811 100644 --- a/crates/net/downloaders/src/bodies/request.rs +++ b/crates/net/downloaders/src/bodies/request.rs @@ -9,6 +9,7 @@ use reth_network_p2p::{ }; use reth_network_peers::{PeerId, WithPeerId}; use reth_primitives::{BlockBody, GotExpected, SealedBlock, SealedHeader}; +use reth_primitives_traits::InMemorySize; use std::{ collections::VecDeque, mem, diff --git a/crates/net/p2p/Cargo.toml b/crates/net/p2p/Cargo.toml index 3b6d74c9dbe..89855396925 100644 --- a/crates/net/p2p/Cargo.toml +++ b/crates/net/p2p/Cargo.toml @@ -14,6 +14,7 @@ workspace = true [dependencies] # reth reth-primitives.workspace = true +reth-primitives-traits.workspace = true reth-eth-wire-types.workspace = true reth-consensus.workspace = true reth-network-peers.workspace = true @@ -32,7 +33,6 @@ tokio = { workspace = true, features = ["sync"] } auto_impl.workspace = true tracing.workspace = true derive_more.workspace = true - parking_lot = { workspace = true, optional = true } [dev-dependencies] @@ -47,11 +47,13 @@ test-utils = [ "reth-consensus/test-utils", "parking_lot", "reth-network-types/test-utils", - "reth-primitives/test-utils" + "reth-primitives/test-utils", + "reth-primitives-traits/test-utils" ] std = [ "reth-consensus/std", "reth-primitives/std", "alloy-eips/std", - "alloy-primitives/std" + "alloy-primitives/std", + "reth-primitives-traits/std" ] diff --git a/crates/net/p2p/src/bodies/response.rs b/crates/net/p2p/src/bodies/response.rs index 8ae840fbf66..0a45008acd8 100644 --- a/crates/net/p2p/src/bodies/response.rs +++ b/crates/net/p2p/src/bodies/response.rs @@ -1,5 +1,6 @@ use alloy_primitives::{BlockNumber, U256}; use reth_primitives::{SealedBlock, SealedHeader}; +use reth_primitives_traits::InMemorySize; /// The block response #[derive(PartialEq, Eq, Debug, Clone)] @@ -19,15 +20,6 @@ impl BlockResponse { } } - /// Calculates a heuristic for the in-memory size of the [`BlockResponse`]. - #[inline] - pub fn size(&self) -> usize { - match self { - Self::Full(block) => SealedBlock::size(block), - Self::Empty(header) => SealedHeader::size(header), - } - } - /// Return the block number pub fn block_number(&self) -> BlockNumber { self.header().number @@ -41,3 +33,14 @@ impl BlockResponse { } } } + +impl InMemorySize for BlockResponse { + /// Calculates a heuristic for the in-memory size of the [`BlockResponse`]. + #[inline] + fn size(&self) -> usize { + match self { + Self::Full(block) => SealedBlock::size(block), + Self::Empty(header) => SealedHeader::size(header), + } + } +} diff --git a/crates/primitives-traits/src/header/sealed.rs b/crates/primitives-traits/src/header/sealed.rs index 799f698f1c5..995c13748b3 100644 --- a/crates/primitives-traits/src/header/sealed.rs +++ b/crates/primitives-traits/src/header/sealed.rs @@ -1,3 +1,5 @@ +use crate::InMemorySize; + use super::Header; use alloy_consensus::Sealed; use alloy_eips::BlockNumHash; @@ -59,10 +61,12 @@ impl SealedHeader { pub fn num_hash(&self) -> BlockNumHash { BlockNumHash::new(self.number, self.hash) } +} +impl InMemorySize for SealedHeader { /// Calculates a heuristic for the in-memory size of the [`SealedHeader`]. #[inline] - pub fn size(&self) -> usize { + fn size(&self) -> usize { self.header.size() + mem::size_of::() } } diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index 3d8aea04e3d..6fcb725cfa4 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -73,3 +73,7 @@ pub use header::{Header, HeaderError, SealedHeader}; pub mod serde_bincode_compat { pub use super::header::{serde_bincode_compat as header, serde_bincode_compat::*}; } + +/// Heuristic size trait +pub mod size; +pub use size::InMemorySize; diff --git a/crates/primitives-traits/src/size.rs b/crates/primitives-traits/src/size.rs new file mode 100644 index 00000000000..173f8cedc9e --- /dev/null +++ b/crates/primitives-traits/src/size.rs @@ -0,0 +1,5 @@ +/// Trait for calculating a heuristic for the in-memory size of a struct. +pub trait InMemorySize { + /// Returns a heuristic for the in-memory size of a struct. + fn size(&self) -> usize; +} diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index b54a7bd0f78..275f86c5b45 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -6,6 +6,7 @@ use alloy_rlp::{Decodable, Encodable, RlpDecodable, RlpEncodable}; use derive_more::{Deref, DerefMut}; #[cfg(any(test, feature = "arbitrary"))] pub use reth_primitives_traits::test_utils::{generate_valid_header, valid_header_strategy}; +use reth_primitives_traits::InMemorySize; use serde::{Deserialize, Serialize}; /// Ethereum full block. @@ -84,10 +85,12 @@ impl Block { let senders = self.senders()?; Some(BlockWithSenders { block: self, senders }) } +} +impl InMemorySize for Block { /// Calculates a heuristic for the in-memory size of the [`Block`]. #[inline] - pub fn size(&self) -> usize { + fn size(&self) -> usize { self.header.size() + self.body.size() } } @@ -376,12 +379,6 @@ impl SealedBlock { Block { header: self.header.unseal(), body: self.body } } - /// Calculates a heuristic for the in-memory size of the [`SealedBlock`]. - #[inline] - pub fn size(&self) -> usize { - self.header.size() + self.body.size() - } - /// Calculates the total gas used by blob transactions in the sealed block. pub fn blob_gas_used(&self) -> u64 { self.blob_transactions().iter().filter_map(|tx| tx.blob_gas_used()).sum() @@ -431,6 +428,14 @@ impl SealedBlock { } } +impl InMemorySize for SealedBlock { + /// Calculates a heuristic for the in-memory size of the [`SealedBlock`]. + #[inline] + fn size(&self) -> usize { + self.header.size() + self.body.size() + } +} + impl From for Block { fn from(block: SealedBlock) -> Self { block.unseal() @@ -625,10 +630,12 @@ impl BlockBody { pub fn transactions(&self) -> impl Iterator + '_ { self.transactions.iter() } +} +impl InMemorySize for BlockBody { /// Calculates a heuristic for the in-memory size of the [`BlockBody`]. #[inline] - pub fn size(&self) -> usize { + fn size(&self) -> usize { self.transactions.iter().map(TransactionSigned::size).sum::() + self.transactions.capacity() * core::mem::size_of::() + self.ommers.iter().map(Header::size).sum::() + diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index 685fd29a3c0..485de92ea89 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -24,6 +24,7 @@ use once_cell::sync::Lazy as LazyLock; #[cfg(feature = "optimism")] use op_alloy_consensus::DepositTransaction; use rayon::prelude::{IntoParallelIterator, ParallelIterator}; +use reth_primitives_traits::InMemorySize; use serde::{Deserialize, Serialize}; use signature::decode_with_eip155_chain_id; #[cfg(feature = "std")] @@ -472,20 +473,6 @@ impl Transaction { } } - /// Calculates a heuristic for the in-memory size of the [Transaction]. - #[inline] - pub fn size(&self) -> usize { - match self { - Self::Legacy(tx) => tx.size(), - Self::Eip2930(tx) => tx.size(), - Self::Eip1559(tx) => tx.size(), - Self::Eip4844(tx) => tx.size(), - Self::Eip7702(tx) => tx.size(), - #[cfg(feature = "optimism")] - Self::Deposit(tx) => tx.size(), - } - } - /// Returns true if the transaction is a legacy transaction. #[inline] pub const fn is_legacy(&self) -> bool { @@ -557,6 +544,22 @@ impl Transaction { } } +impl InMemorySize for Transaction { + /// Calculates a heuristic for the in-memory size of the [Transaction]. + #[inline] + fn size(&self) -> usize { + match self { + Self::Legacy(tx) => tx.size(), + Self::Eip2930(tx) => tx.size(), + Self::Eip1559(tx) => tx.size(), + Self::Eip4844(tx) => tx.size(), + Self::Eip7702(tx) => tx.size(), + #[cfg(feature = "optimism")] + Self::Deposit(tx) => tx.size(), + } + } +} + #[cfg(any(test, feature = "reth-codec"))] impl reth_codecs::Compact for Transaction { // Serializes the TxType to the buffer if necessary, returning 2 bits of the type as an diff --git a/crates/prune/prune/Cargo.toml b/crates/prune/prune/Cargo.toml index 2f2a37d5ba6..4df9ace8133 100644 --- a/crates/prune/prune/Cargo.toml +++ b/crates/prune/prune/Cargo.toml @@ -41,6 +41,7 @@ rustc-hash.workspace = true # reth reth-db = { workspace = true, features = ["test-utils"] } reth-stages = { workspace = true, features = ["test-utils"] } +reth-primitives-traits = { workspace = true, features = ["arbitrary"] } reth-testing-utils.workspace = true reth-tracing.workspace = true diff --git a/crates/prune/prune/src/segments/user/receipts_by_logs.rs b/crates/prune/prune/src/segments/user/receipts_by_logs.rs index ee2accee1b3..ee404b074c3 100644 --- a/crates/prune/prune/src/segments/user/receipts_by_logs.rs +++ b/crates/prune/prune/src/segments/user/receipts_by_logs.rs @@ -10,7 +10,6 @@ use reth_prune_types::{ SegmentOutput, MINIMUM_PRUNING_DISTANCE, }; use tracing::{instrument, trace}; - #[derive(Debug)] pub struct ReceiptsByLogs { config: ReceiptsLogPruneConfig, @@ -223,6 +222,7 @@ mod tests { use assert_matches::assert_matches; use reth_db::tables; use reth_db_api::{cursor::DbCursorRO, transaction::DbTx}; + use reth_primitives_traits::InMemorySize; use reth_provider::{DatabaseProviderFactory, PruneCheckpointReader, TransactionsProvider}; use reth_prune_types::{PruneLimiter, PruneMode, PruneSegment, ReceiptsLogPruneConfig}; use reth_stages::test_utils::{StorageKind, TestStageDB}; diff --git a/crates/transaction-pool/Cargo.toml b/crates/transaction-pool/Cargo.toml index 1bfb10d86d7..7c760c81c54 100644 --- a/crates/transaction-pool/Cargo.toml +++ b/crates/transaction-pool/Cargo.toml @@ -17,6 +17,7 @@ reth-chain-state.workspace = true reth-chainspec.workspace = true reth-eth-wire-types.workspace = true reth-primitives = { workspace = true, features = ["c-kzg", "secp256k1"] } +reth-primitives-traits.workspace = true reth-execution-types.workspace = true reth-fs-util.workspace = true reth-storage-api.workspace = true @@ -50,6 +51,7 @@ bitflags.workspace = true auto_impl.workspace = true smallvec.workspace = true + # testing rand = { workspace = true, optional = true } paste = { workspace = true, optional = true } @@ -84,7 +86,7 @@ serde = [ "parking_lot/serde", "rand?/serde", "revm/serde", - "smallvec/serde" + "smallvec/serde", ] test-utils = [ "rand", @@ -94,7 +96,8 @@ test-utils = [ "reth-chainspec/test-utils", "reth-primitives/test-utils", "reth-provider/test-utils", - "revm/test-utils" + "revm/test-utils", + "reth-primitives-traits/test-utils", ] arbitrary = [ "proptest", @@ -107,7 +110,8 @@ arbitrary = [ "alloy-primitives/arbitrary", "bitflags/arbitrary", "revm/arbitrary", - "smallvec/arbitrary" + "reth-primitives-traits/arbitrary", + "smallvec/arbitrary", ] [[bench]] diff --git a/crates/transaction-pool/src/test_utils/mock.rs b/crates/transaction-pool/src/test_utils/mock.rs index 92f74665279..fc43349f3f1 100644 --- a/crates/transaction-pool/src/test_utils/mock.rs +++ b/crates/transaction-pool/src/test_utils/mock.rs @@ -28,7 +28,6 @@ use reth_primitives::{ transaction::TryFromRecoveredTransactionError, PooledTransactionsElementEcRecovered, Transaction, TransactionSigned, TransactionSignedEcRecovered, TxType, }; - use std::{ops::Range, sync::Arc, time::Instant, vec::IntoIter}; /// A transaction pool implementation using [`MockOrdering`] for transaction ordering. @@ -1007,6 +1006,7 @@ impl proptest::arbitrary::Arbitrary for MockTransaction { fn arbitrary_with(_: Self::Parameters) -> Self::Strategy { use proptest::prelude::Strategy; use proptest_arbitrary_interop::arb; + use reth_primitives_traits::size::InMemorySize; arb::<(Transaction, Address, B256)>() .prop_map(|(tx, sender, tx_hash)| match &tx { diff --git a/crates/transaction-pool/src/validate/eth.rs b/crates/transaction-pool/src/validate/eth.rs index 62e9f3f2917..d5f7101eb55 100644 --- a/crates/transaction-pool/src/validate/eth.rs +++ b/crates/transaction-pool/src/validate/eth.rs @@ -17,7 +17,8 @@ use alloy_consensus::constants::{ }; use alloy_eips::eip4844::MAX_BLOBS_PER_BLOCK; use reth_chainspec::{ChainSpec, EthereumHardforks}; -use reth_primitives::{GotExpected, InvalidTransactionError, SealedBlock}; +use reth_primitives::{InvalidTransactionError, SealedBlock}; +use reth_primitives_traits::GotExpected; use reth_storage_api::{AccountReader, StateProviderFactory}; use reth_tasks::TaskSpawner; use revm::{ From 2f8a2f0fbb29019c11a0e495528146fdcc09229c Mon Sep 17 00:00:00 2001 From: malik Date: Mon, 11 Nov 2024 19:12:24 +0100 Subject: [PATCH 111/211] chore: remove unnecessary clone (#12455) --- crates/chain-state/src/in_memory.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/chain-state/src/in_memory.rs b/crates/chain-state/src/in_memory.rs index 6bef197bea9..bfae8113e3e 100644 --- a/crates/chain-state/src/in_memory.rs +++ b/crates/chain-state/src/in_memory.rs @@ -338,7 +338,7 @@ impl CanonicalInMemoryState { // re-insert the blocks in natural order and connect them to their parent blocks for block in old_blocks { let parent = blocks.get(&block.block().parent_hash).cloned(); - let block_state = BlockState::with_parent(block.clone(), parent); + let block_state = BlockState::with_parent(block, parent); let hash = block_state.hash(); let number = block_state.number(); From 5edca402b04cc27c5dad8b62c34d44210040f2e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96zg=C3=BCn=20=C3=96zerk?= Date: Tue, 12 Nov 2024 12:07:05 +0300 Subject: [PATCH 112/211] feat(op): define OpTxType (#12443) --- Cargo.lock | 6 + crates/optimism/primitives/Cargo.toml | 6 + crates/optimism/primitives/src/lib.rs | 1 + crates/optimism/primitives/src/op_tx_type.rs | 189 +++++++++++++++++++ crates/primitives-traits/src/tx_type.rs | 22 +++ 5 files changed, 224 insertions(+) create mode 100644 crates/optimism/primitives/src/op_tx_type.rs diff --git a/Cargo.lock b/Cargo.lock index 0990a469950..f2a9310c485 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8327,8 +8327,14 @@ name = "reth-optimism-primitives" version = "1.1.1" dependencies = [ "alloy-consensus", + "alloy-eips", "alloy-primitives", + "alloy-rlp", + "bytes", + "derive_more 1.0.0", + "op-alloy-consensus", "reth-primitives", + "reth-primitives-traits", ] [[package]] diff --git a/crates/optimism/primitives/Cargo.toml b/crates/optimism/primitives/Cargo.toml index a2d4c20a8b7..bc11c358504 100644 --- a/crates/optimism/primitives/Cargo.toml +++ b/crates/optimism/primitives/Cargo.toml @@ -13,5 +13,11 @@ workspace = true [dependencies] reth-primitives.workspace = true +reth-primitives-traits.workspace = true alloy-primitives.workspace = true alloy-consensus.workspace = true +op-alloy-consensus.workspace = true +alloy-eips.workspace = true +alloy-rlp.workspace = true +derive_more.workspace = true +bytes.workspace = true diff --git a/crates/optimism/primitives/src/lib.rs b/crates/optimism/primitives/src/lib.rs index 659900b9adb..f8d8e511498 100644 --- a/crates/optimism/primitives/src/lib.rs +++ b/crates/optimism/primitives/src/lib.rs @@ -8,3 +8,4 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] pub mod bedrock; +pub mod op_tx_type; diff --git a/crates/optimism/primitives/src/op_tx_type.rs b/crates/optimism/primitives/src/op_tx_type.rs new file mode 100644 index 00000000000..b317bb05c9c --- /dev/null +++ b/crates/optimism/primitives/src/op_tx_type.rs @@ -0,0 +1,189 @@ +//! newtype pattern on `op_alloy_consensus::OpTxType`. +//! `OpTxType` implements `reth_primitives_traits::TxType`. +//! This type is required because a `Compact` impl is needed on the deposit tx type. + +use alloy_primitives::{U64, U8}; +use alloy_rlp::{Decodable, Encodable, Error}; +use bytes::BufMut; +use core::fmt::Debug; +use derive_more::{ + derive::{From, Into}, + Display, +}; +use op_alloy_consensus::OpTxType as AlloyOpTxType; +use std::convert::TryFrom; + +/// Wrapper type for `AlloyOpTxType` to implement `TxType` trait. +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Display, Ord, Hash, From, Into)] +#[into(u8)] +pub struct OpTxType(AlloyOpTxType); + +impl From for U8 { + fn from(tx_type: OpTxType) -> Self { + Self::from(u8::from(tx_type)) + } +} + +impl TryFrom for OpTxType { + type Error = Error; + + fn try_from(value: u8) -> Result { + AlloyOpTxType::try_from(value) + .map(OpTxType) + .map_err(|_| Error::Custom("Invalid transaction type")) + } +} + +impl Default for OpTxType { + fn default() -> Self { + Self(AlloyOpTxType::Legacy) + } +} + +impl PartialEq for OpTxType { + fn eq(&self, other: &u8) -> bool { + let self_as_u8: u8 = (*self).into(); + &self_as_u8 == other + } +} + +impl TryFrom for OpTxType { + type Error = Error; + + fn try_from(value: u64) -> Result { + if value > u8::MAX as u64 { + return Err(Error::Custom("value out of range")); + } + Self::try_from(value as u8) + } +} + +impl TryFrom for OpTxType { + type Error = Error; + + fn try_from(value: U64) -> Result { + let u64_value: u64 = value.try_into().map_err(|_| Error::Custom("value out of range"))?; + Self::try_from(u64_value) + } +} + +impl Encodable for OpTxType { + fn length(&self) -> usize { + let value: u8 = (*self).into(); + value.length() + } + + fn encode(&self, out: &mut dyn BufMut) { + let value: u8 = (*self).into(); + value.encode(out); + } +} + +impl Decodable for OpTxType { + fn decode(buf: &mut &[u8]) -> Result { + // Decode the u8 value from RLP + let value = if buf.is_empty() { + return Err(alloy_rlp::Error::InputTooShort); + } else if buf[0] == 0x80 { + 0 // Special case: RLP encoding for integer 0 is `b"\x80"` + } else { + u8::decode(buf)? + }; + + Self::try_from(value).map_err(|_| alloy_rlp::Error::Custom("Invalid transaction type")) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use bytes::BytesMut; + + #[test] + fn test_from_alloy_op_tx_type() { + let alloy_tx = AlloyOpTxType::Legacy; + let op_tx: OpTxType = OpTxType::from(alloy_tx); + assert_eq!(op_tx, OpTxType(AlloyOpTxType::Legacy)); + } + + #[test] + fn test_from_op_tx_type_to_u8() { + let op_tx = OpTxType(AlloyOpTxType::Legacy); + let tx_type_u8: u8 = op_tx.into(); + assert_eq!(tx_type_u8, AlloyOpTxType::Legacy as u8); + } + + #[test] + fn test_from_op_tx_type_to_u8_u8() { + let op_tx = OpTxType(AlloyOpTxType::Legacy); + let tx_type_u8: U8 = op_tx.into(); + assert_eq!(tx_type_u8, U8::from(AlloyOpTxType::Legacy as u8)); + } + + #[test] + fn test_try_from_u8() { + let op_tx = OpTxType::try_from(AlloyOpTxType::Legacy as u8).unwrap(); + assert_eq!(op_tx, OpTxType(AlloyOpTxType::Legacy)); + } + + #[test] + fn test_try_from_invalid_u8() { + let invalid_value: u8 = 255; + let result = OpTxType::try_from(invalid_value); + assert_eq!(result, Err(Error::Custom("Invalid transaction type"))); + } + + #[test] + fn test_try_from_u64() { + let op_tx = OpTxType::try_from(AlloyOpTxType::Legacy as u64).unwrap(); + assert_eq!(op_tx, OpTxType(AlloyOpTxType::Legacy)); + } + + #[test] + fn test_try_from_u64_out_of_range() { + let result = OpTxType::try_from(u64::MAX); + assert_eq!(result, Err(Error::Custom("value out of range"))); + } + + #[test] + fn test_try_from_u64_within_range() { + let valid_value: U64 = U64::from(AlloyOpTxType::Legacy as u64); + let op_tx = OpTxType::try_from(valid_value).unwrap(); + assert_eq!(op_tx, OpTxType(AlloyOpTxType::Legacy)); + } + + #[test] + fn test_default() { + let default_tx = OpTxType::default(); + assert_eq!(default_tx, OpTxType(AlloyOpTxType::Legacy)); + } + + #[test] + fn test_partial_eq_u8() { + let op_tx = OpTxType(AlloyOpTxType::Legacy); + assert_eq!(op_tx, AlloyOpTxType::Legacy as u8); + } + + #[test] + fn test_encodable() { + let op_tx = OpTxType(AlloyOpTxType::Legacy); + let mut buf = BytesMut::new(); + op_tx.encode(&mut buf); + assert_eq!(buf, BytesMut::from(&[0x80][..])); + } + + #[test] + fn test_decodable_success() { + // Using the RLP-encoded form of 0, which is `b"\x80"` + let mut buf: &[u8] = &[0x80]; + let decoded_tx = OpTxType::decode(&mut buf).unwrap(); + assert_eq!(decoded_tx, OpTxType(AlloyOpTxType::Legacy)); + } + + #[test] + fn test_decodable_invalid() { + let mut buf: &[u8] = &[255]; + let result = OpTxType::decode(&mut buf); + assert!(result.is_err()); + } +} diff --git a/crates/primitives-traits/src/tx_type.rs b/crates/primitives-traits/src/tx_type.rs index a25a7d659bd..6ca55879442 100644 --- a/crates/primitives-traits/src/tx_type.rs +++ b/crates/primitives-traits/src/tx_type.rs @@ -26,3 +26,25 @@ pub trait TxType: + Decodable { } + +impl TxType for T where + T: Send + + Sync + + Unpin + + Clone + + Copy + + Default + + fmt::Debug + + fmt::Display + + PartialEq + + Eq + + PartialEq + + Into + + Into + + TryFrom + + TryFrom + + TryFrom + + Encodable + + Decodable +{ +} From f38503c2bc8d5de6e71393a3b232c2b6f3369f29 Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:58:36 +0700 Subject: [PATCH 113/211] chore: move `(Full)NodePrimitives` to `reth-primitive-traits` (#12461) Co-authored-by: Emilia Hane --- crates/node/types/src/lib.rs | 41 +++------------------------- crates/primitives-traits/src/lib.rs | 4 +++ crates/primitives-traits/src/node.rs | 38 ++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 37 deletions(-) create mode 100644 crates/primitives-traits/src/node.rs diff --git a/crates/node/types/src/lib.rs b/crates/node/types/src/lib.rs index f2bd16280f8..f8770a3c014 100644 --- a/crates/node/types/src/lib.rs +++ b/crates/node/types/src/lib.rs @@ -9,9 +9,11 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![cfg_attr(not(feature = "std"), no_std)] -pub use reth_primitives_traits::{Block, BlockBody, FullBlock, FullReceipt, FullSignedTx}; +pub use reth_primitives_traits::{ + Block, BlockBody, FullBlock, FullNodePrimitives, FullReceipt, FullSignedTx, NodePrimitives, +}; -use core::{fmt, marker::PhantomData}; +use core::marker::PhantomData; use reth_chainspec::EthChainSpec; use reth_db_api::{ @@ -21,41 +23,6 @@ use reth_db_api::{ use reth_engine_primitives::EngineTypes; use reth_trie_db::StateCommitment; -/// Configures all the primitive types of the node. -pub trait NodePrimitives: Send + Sync + Unpin + Clone + Default + fmt::Debug { - /// Block primitive. - type Block: Send + Sync + Unpin + Clone + Default + fmt::Debug + 'static; - /// Signed version of the transaction type. - type SignedTx: Send + Sync + Unpin + Clone + Default + fmt::Debug + 'static; - /// A receipt. - type Receipt: Send + Sync + Unpin + Clone + Default + fmt::Debug + 'static; -} - -impl NodePrimitives for () { - type Block = (); - type SignedTx = (); - type Receipt = (); -} - -/// Helper trait that sets trait bounds on [`NodePrimitives`]. -pub trait FullNodePrimitives: Send + Sync + Unpin + Clone + Default + fmt::Debug { - /// Block primitive. - type Block: FullBlock>; - /// Signed version of the transaction type. - type SignedTx: FullSignedTx; - /// A receipt. - type Receipt: FullReceipt; -} - -impl NodePrimitives for T -where - T: FullNodePrimitives, -{ - type Block = T::Block; - type SignedTx = T::SignedTx; - type Receipt = T::Receipt; -} - /// The type that configures the essential types of an Ethereum-like node. /// /// This includes the primitive types of a node and chain specification. diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index 6fcb725cfa4..babc0f42e0b 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -77,3 +77,7 @@ pub mod serde_bincode_compat { /// Heuristic size trait pub mod size; pub use size::InMemorySize; + +/// Node traits +pub mod node; +pub use node::{FullNodePrimitives, NodePrimitives}; diff --git a/crates/primitives-traits/src/node.rs b/crates/primitives-traits/src/node.rs new file mode 100644 index 00000000000..921942841d4 --- /dev/null +++ b/crates/primitives-traits/src/node.rs @@ -0,0 +1,38 @@ +use core::fmt; + +use crate::{BlockBody, FullBlock, FullReceipt, FullSignedTx}; + +/// Configures all the primitive types of the node. +pub trait NodePrimitives: Send + Sync + Unpin + Clone + Default + fmt::Debug { + /// Block primitive. + type Block: Send + Sync + Unpin + Clone + Default + fmt::Debug + 'static; + /// Signed version of the transaction type. + type SignedTx: Send + Sync + Unpin + Clone + Default + fmt::Debug + 'static; + /// A receipt. + type Receipt: Send + Sync + Unpin + Clone + Default + fmt::Debug + 'static; +} + +impl NodePrimitives for () { + type Block = (); + type SignedTx = (); + type Receipt = (); +} + +/// Helper trait that sets trait bounds on [`NodePrimitives`]. +pub trait FullNodePrimitives: Send + Sync + Unpin + Clone + Default + fmt::Debug { + /// Block primitive. + type Block: FullBlock>; + /// Signed version of the transaction type. + type SignedTx: FullSignedTx; + /// A receipt. + type Receipt: FullReceipt; +} + +impl NodePrimitives for T +where + T: FullNodePrimitives, +{ + type Block = T::Block; + type SignedTx = T::SignedTx; + type Receipt = T::Receipt; +} From c261532a27e99f05c6f5838e2b2acccf9e41ddf4 Mon Sep 17 00:00:00 2001 From: c0np4nn4 Date: Tue, 12 Nov 2024 17:15:52 +0700 Subject: [PATCH 114/211] chore: move trie functions to alloy (#12438) --- Cargo.lock | 3 +++ crates/optimism/consensus/Cargo.toml | 1 + crates/optimism/consensus/src/proof.rs | 2 +- crates/primitives/Cargo.toml | 9 +++++--- crates/primitives/src/proofs.rs | 2 +- crates/trie/common/src/proofs.rs | 3 ++- crates/trie/common/src/root.rs | 32 -------------------------- crates/trie/trie/Cargo.toml | 4 +++- 8 files changed, 17 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f2a9310c485..1bf11ac9baa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8191,6 +8191,7 @@ version = "1.1.1" dependencies = [ "alloy-consensus", "alloy-primitives", + "alloy-trie", "reth-chainspec", "reth-consensus", "reth-consensus-common", @@ -8451,6 +8452,7 @@ dependencies = [ "alloy-rlp", "alloy-rpc-types", "alloy-serde", + "alloy-trie", "arbitrary", "assert_matches", "bincode", @@ -9226,6 +9228,7 @@ dependencies = [ "alloy-consensus", "alloy-primitives", "alloy-rlp", + "alloy-trie", "auto_impl", "bincode", "criterion", diff --git a/crates/optimism/consensus/Cargo.toml b/crates/optimism/consensus/Cargo.toml index e2520c89340..0dffceaddca 100644 --- a/crates/optimism/consensus/Cargo.toml +++ b/crates/optimism/consensus/Cargo.toml @@ -26,6 +26,7 @@ reth-optimism-chainspec.workspace = true # ethereum alloy-primitives.workspace = true alloy-consensus.workspace = true +alloy-trie.workspace = true tracing.workspace = true diff --git a/crates/optimism/consensus/src/proof.rs b/crates/optimism/consensus/src/proof.rs index 813e451da25..18e64a467ff 100644 --- a/crates/optimism/consensus/src/proof.rs +++ b/crates/optimism/consensus/src/proof.rs @@ -1,10 +1,10 @@ //! Helper function for Receipt root calculation for Optimism hardforks. use alloy_primitives::B256; +use alloy_trie::root::ordered_trie_root_with_encoder; use reth_chainspec::ChainSpec; use reth_optimism_forks::OpHardfork; use reth_primitives::{Receipt, ReceiptWithBloom, ReceiptWithBloomRef}; -use reth_trie_common::root::ordered_trie_root_with_encoder; /// Calculates the receipt root for a header. pub(crate) fn calculate_receipt_root_optimism( diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index 5bef33e15ef..1a4c33c7180 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -16,7 +16,6 @@ workspace = true reth-primitives-traits.workspace = true reth-ethereum-forks.workspace = true reth-static-file-types.workspace = true -reth-trie-common.workspace = true revm-primitives = { workspace = true, features = ["serde"] } reth-codecs = { workspace = true, optional = true } @@ -28,6 +27,7 @@ alloy-rlp = { workspace = true, features = ["arrayvec"] } alloy-rpc-types = { workspace = true, optional = true } alloy-serde = { workspace = true, optional = true } alloy-eips = { workspace = true, features = ["serde"] } +alloy-trie = { workspace = true, features = ["serde"] } # optimism op-alloy-rpc-types = { workspace = true, optional = true } @@ -66,6 +66,7 @@ reth-chainspec.workspace = true reth-codecs = { workspace = true, features = ["test-utils"] } reth-primitives-traits = { workspace = true, features = ["arbitrary"] } reth-testing-utils.workspace = true +reth-trie-common.workspace = true revm-primitives = { workspace = true, features = ["arbitrary"] } alloy-eips = { workspace = true, features = ["arbitrary"] } @@ -102,6 +103,7 @@ std = [ "revm-primitives/std", "secp256k1?/std", "serde/std", + "alloy-trie/std" ] reth-codec = ["dep:reth-codecs", "dep:zstd", "dep:modular-bitfield", "std"] asm-keccak = ["alloy-primitives/asm-keccak", "revm-primitives/asm-keccak"] @@ -115,14 +117,15 @@ arbitrary = [ "revm-primitives/arbitrary", "secp256k1", "reth-chainspec/arbitrary", - "reth-trie-common/arbitrary", "alloy-consensus/arbitrary", "alloy-primitives/arbitrary", "alloy-rpc-types?/arbitrary", "alloy-serde?/arbitrary", "op-alloy-consensus?/arbitrary", "op-alloy-rpc-types?/arbitrary", - "reth-codecs?/arbitrary" + "reth-codecs?/arbitrary", + "alloy-trie/arbitrary", + "reth-trie-common/arbitrary" ] secp256k1 = ["dep:secp256k1"] c-kzg = [ diff --git a/crates/primitives/src/proofs.rs b/crates/primitives/src/proofs.rs index 000244d2c54..10b7bc2530b 100644 --- a/crates/primitives/src/proofs.rs +++ b/crates/primitives/src/proofs.rs @@ -5,7 +5,7 @@ use alloc::vec::Vec; use alloy_consensus::EMPTY_OMMER_ROOT_HASH; use alloy_eips::{eip2718::Encodable2718, eip4895::Withdrawal}; use alloy_primitives::{keccak256, B256}; -use reth_trie_common::root::{ordered_trie_root, ordered_trie_root_with_encoder}; +use alloy_trie::root::{ordered_trie_root, ordered_trie_root_with_encoder}; /// Calculate a transaction root. /// diff --git a/crates/trie/common/src/proofs.rs b/crates/trie/common/src/proofs.rs index a94b2b96fbd..108910a1384 100644 --- a/crates/trie/common/src/proofs.rs +++ b/crates/trie/common/src/proofs.rs @@ -234,11 +234,12 @@ impl StorageProof { #[cfg(any(test, feature = "test-utils"))] pub mod triehash { use alloy_primitives::{keccak256, B256}; + use alloy_rlp::RlpEncodable; use hash_db::Hasher; use plain_hasher::PlainHasher; /// A [Hasher] that calculates a keccak256 hash of the given data. - #[derive(Default, Debug, Clone, PartialEq, Eq)] + #[derive(Default, Debug, Clone, PartialEq, Eq, RlpEncodable)] #[non_exhaustive] pub struct KeccakHasher; diff --git a/crates/trie/common/src/root.rs b/crates/trie/common/src/root.rs index 20f3ba1366d..dbcbf4200d7 100644 --- a/crates/trie/common/src/root.rs +++ b/crates/trie/common/src/root.rs @@ -18,38 +18,6 @@ pub const fn adjust_index_for_rlp(i: usize, len: usize) -> usize { } } -/// Compute a trie root of the collection of rlp encodable items. -pub fn ordered_trie_root(items: &[T]) -> B256 { - ordered_trie_root_with_encoder(items, |item, buf| item.encode(buf)) -} - -/// Compute a trie root of the collection of items with a custom encoder. -pub fn ordered_trie_root_with_encoder(items: &[T], mut encode: F) -> B256 -where - F: FnMut(&T, &mut Vec), -{ - if items.is_empty() { - return alloy_trie::EMPTY_ROOT_HASH; - } - - let mut value_buffer = Vec::new(); - - let mut hb = HashBuilder::default(); - let items_len = items.len(); - for i in 0..items_len { - let index = adjust_index_for_rlp(i, items_len); - - let index_buffer = alloy_rlp::encode_fixed_size(&index); - - value_buffer.clear(); - encode(&items[index], &mut value_buffer); - - hb.add_leaf(Nibbles::unpack(&index_buffer), &value_buffer); - } - - hb.root() -} - /// Hashes and sorts account keys, then proceeds to calculating the root hash of the state /// represented as MPT. /// See [`state_root_unsorted`] for more info. diff --git a/crates/trie/trie/Cargo.toml b/crates/trie/trie/Cargo.toml index 134a3055c2b..6136fa8e56b 100644 --- a/crates/trie/trie/Cargo.toml +++ b/crates/trie/trie/Cargo.toml @@ -25,6 +25,7 @@ revm.workspace = true alloy-rlp.workspace = true alloy-primitives.workspace = true alloy-consensus.workspace = true +alloy-trie.workspace = true # tracing tracing.workspace = true @@ -68,7 +69,8 @@ serde = [ "dep:serde", "alloy-consensus/serde", "alloy-primitives/serde", - "revm/serde" + "revm/serde", + "alloy-trie/serde" ] serde-bincode-compat = [ "serde_with", From bad7a4f0c90aebdc76a45e8fca8d2719b50d1ae1 Mon Sep 17 00:00:00 2001 From: Darshan Kathiriya <8559992+lakshya-sky@users.noreply.github.com> Date: Tue, 12 Nov 2024 05:31:32 -0500 Subject: [PATCH 115/211] use result for `TransactionCompact::fill`. (#12170) Co-authored-by: Emilia Hane Co-authored-by: dkathiriya --- Cargo.lock | 1 + crates/optimism/rpc/src/error.rs | 8 ++++- crates/optimism/rpc/src/eth/transaction.rs | 12 +++---- crates/rpc/rpc-eth-api/src/core.rs | 3 +- crates/rpc/rpc-eth-api/src/helpers/block.rs | 3 +- crates/rpc/rpc-eth-api/src/helpers/mod.rs | 1 - .../rpc-eth-api/src/helpers/transaction.rs | 6 ++-- crates/rpc/rpc-eth-api/src/lib.rs | 4 ++- crates/rpc/rpc-eth-api/src/types.rs | 15 ++++++-- .../src/error/api.rs} | 9 ++--- .../src/{error.rs => error/mod.rs} | 5 ++- crates/rpc/rpc-eth-types/src/simulate.rs | 11 +++--- crates/rpc/rpc-eth-types/src/transaction.rs | 5 ++- crates/rpc/rpc-types-compat/Cargo.toml | 1 + crates/rpc/rpc-types-compat/src/block.rs | 11 +++--- .../rpc/rpc-types-compat/src/transaction.rs | 14 ++++++-- crates/rpc/rpc/src/eth/filter.rs | 15 +++++--- crates/rpc/rpc/src/eth/helpers/types.rs | 9 +++-- crates/rpc/rpc/src/eth/pubsub.rs | 19 +++++++++-- crates/rpc/rpc/src/txpool.rs | 34 +++++++++++-------- 20 files changed, 124 insertions(+), 62 deletions(-) rename crates/rpc/{rpc-eth-api/src/helpers/error.rs => rpc-eth-types/src/error/api.rs} (87%) rename crates/rpc/rpc-eth-types/src/{error.rs => error/mod.rs} (99%) diff --git a/Cargo.lock b/Cargo.lock index 1bf11ac9baa..38a87ebf930 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8958,6 +8958,7 @@ dependencies = [ "alloy-rpc-types-engine", "alloy-rpc-types-eth", "alloy-serde", + "jsonrpsee-types", "reth-primitives", "reth-trie-common", "serde", diff --git a/crates/optimism/rpc/src/error.rs b/crates/optimism/rpc/src/error.rs index ffc698b6e98..1dd7a639eac 100644 --- a/crates/optimism/rpc/src/error.rs +++ b/crates/optimism/rpc/src/error.rs @@ -1,6 +1,6 @@ //! RPC errors specific to OP. -use alloy_rpc_types_eth::error::EthRpcErrorCode; +use alloy_rpc_types_eth::{error::EthRpcErrorCode, BlockError}; use jsonrpsee_types::error::INTERNAL_ERROR_CODE; use reth_optimism_evm::OpBlockExecutionError; use reth_primitives::revm_primitives::{InvalidTransaction, OptimismInvalidTransaction}; @@ -113,3 +113,9 @@ impl From for jsonrpsee_types::error::ErrorObject<'static> ) } } + +impl From for OpEthApiError { + fn from(error: BlockError) -> Self { + Self::Eth(error.into()) + } +} diff --git a/crates/optimism/rpc/src/eth/transaction.rs b/crates/optimism/rpc/src/eth/transaction.rs index 90e5e33feb7..3ff7cb10df1 100644 --- a/crates/optimism/rpc/src/eth/transaction.rs +++ b/crates/optimism/rpc/src/eth/transaction.rs @@ -15,7 +15,7 @@ use reth_rpc_eth_api::{ use reth_rpc_eth_types::utils::recover_raw_transaction; use reth_transaction_pool::{PoolTransaction, TransactionOrigin, TransactionPool}; -use crate::{OpEthApi, SequencerClient}; +use crate::{OpEthApi, OpEthApiError, SequencerClient}; impl EthTransactions for OpEthApi where @@ -76,12 +76,13 @@ where N: FullNodeComponents, { type Transaction = Transaction; + type Error = OpEthApiError; fn fill( &self, tx: TransactionSignedEcRecovered, tx_info: TransactionInfo, - ) -> Self::Transaction { + ) -> Result { let from = tx.signer(); let TransactionSigned { transaction, signature, hash } = tx.into_signed(); @@ -106,8 +107,7 @@ where .inner .provider() .receipt_by_hash(hash) - .ok() // todo: change sig to return result - .flatten() + .map_err(Self::Error::from_eth_err)? .and_then(|receipt| receipt.deposit_receipt_version); let TransactionInfo { @@ -120,7 +120,7 @@ where }) .unwrap_or_else(|| inner.max_fee_per_gas()); - Transaction { + Ok(Transaction { inner: alloy_rpc_types_eth::Transaction { inner, block_hash, @@ -130,7 +130,7 @@ where effective_gas_price: Some(effective_gas_price), }, deposit_receipt_version, - } + }) } fn otterscan_api_truncate_input(tx: &mut Self::Transaction) { diff --git a/crates/rpc/rpc-eth-api/src/core.rs b/crates/rpc/rpc-eth-api/src/core.rs index 421c10f8b41..8072021d990 100644 --- a/crates/rpc/rpc-eth-api/src/core.rs +++ b/crates/rpc/rpc-eth-api/src/core.rs @@ -501,7 +501,8 @@ where trace!(target: "rpc::eth", ?hash, "Serving eth_getTransactionByHash"); Ok(EthTransactions::transaction_by_hash(self, hash) .await? - .map(|tx| tx.into_transaction(self.tx_resp_builder()))) + .map(|tx| tx.into_transaction(self.tx_resp_builder())) + .transpose()?) } /// Handler for: `eth_getRawTransactionByBlockHashAndIndex` diff --git a/crates/rpc/rpc-eth-api/src/helpers/block.rs b/crates/rpc/rpc-eth-api/src/helpers/block.rs index e25ea84d699..7125857b898 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/block.rs @@ -64,8 +64,7 @@ pub trait EthBlocks: LoadBlock { full.into(), Some(block_hash), self.tx_resp_builder(), - ) - .map_err(Self::Error::from_eth_err)?; + )?; Ok(Some(block)) } } diff --git a/crates/rpc/rpc-eth-api/src/helpers/mod.rs b/crates/rpc/rpc-eth-api/src/helpers/mod.rs index 8adb0e281e7..a881330b045 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/mod.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/mod.rs @@ -17,7 +17,6 @@ pub mod block; pub mod blocking_task; pub mod call; -pub mod error; pub mod fee; pub mod pending_block; pub mod receipt; diff --git a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs index 234008f21fe..ca4b0322e72 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs @@ -208,7 +208,7 @@ pub trait EthTransactions: LoadTransaction { tx.clone().with_signer(*signer), tx_info, self.tx_resp_builder(), - ))) + )?)) } } @@ -233,7 +233,7 @@ pub trait EthTransactions: LoadTransaction { RpcNodeCore::pool(self).get_transaction_by_sender_and_nonce(sender, nonce) { let transaction = tx.transaction.clone().into_consensus(); - return Ok(Some(from_recovered(transaction.into(), self.tx_resp_builder()))); + return Ok(Some(from_recovered(transaction.into(), self.tx_resp_builder())?)); } } @@ -291,7 +291,7 @@ pub trait EthTransactions: LoadTransaction { ) }) }) - .ok_or(EthApiError::HeaderNotFound(block_id).into()) + .ok_or(EthApiError::HeaderNotFound(block_id))? .map(Some) } } diff --git a/crates/rpc/rpc-eth-api/src/lib.rs b/crates/rpc/rpc-eth-api/src/lib.rs index fa9737f84f0..cb97a03e8b8 100644 --- a/crates/rpc/rpc-eth-api/src/lib.rs +++ b/crates/rpc/rpc-eth-api/src/lib.rs @@ -20,12 +20,14 @@ pub mod node; pub mod pubsub; pub mod types; +pub use reth_rpc_eth_types::error::{ + AsEthApiError, FromEthApiError, FromEvmError, IntoEthApiError, +}; pub use reth_rpc_types_compat::TransactionCompat; pub use bundle::{EthBundleApiServer, EthCallBundleApiServer}; pub use core::{EthApiServer, FullEthApiServer}; pub use filter::EthFilterApiServer; -pub use helpers::error::{AsEthApiError, FromEthApiError, FromEvmError, IntoEthApiError}; pub use node::{RpcNodeCore, RpcNodeCoreExt}; pub use pubsub::EthPubSubApiServer; pub use types::{EthApiTypes, FullEthApiTypes, RpcBlock, RpcReceipt, RpcTransaction}; diff --git a/crates/rpc/rpc-eth-api/src/types.rs b/crates/rpc/rpc-eth-api/src/types.rs index b75bce026fb..12ff090d37c 100644 --- a/crates/rpc/rpc-eth-api/src/types.rs +++ b/crates/rpc/rpc-eth-api/src/types.rs @@ -39,15 +39,26 @@ pub type RpcBlock = Block, ::HeaderResponse>; /// Adapter for network specific receipt type. pub type RpcReceipt = ::ReceiptResponse; +/// Adapter for network specific error type. +pub type RpcError = ::Error; + /// Helper trait holds necessary trait bounds on [`EthApiTypes`] to implement `eth` API. pub trait FullEthApiTypes: - EthApiTypes>> + EthApiTypes< + TransactionCompat: TransactionCompat< + Transaction = RpcTransaction, + Error = RpcError, + >, +> { } impl FullEthApiTypes for T where T: EthApiTypes< - TransactionCompat: TransactionCompat>, + TransactionCompat: TransactionCompat< + Transaction = RpcTransaction, + Error = RpcError, + >, > { } diff --git a/crates/rpc/rpc-eth-api/src/helpers/error.rs b/crates/rpc/rpc-eth-types/src/error/api.rs similarity index 87% rename from crates/rpc/rpc-eth-api/src/helpers/error.rs rename to crates/rpc/rpc-eth-types/src/error/api.rs index 1d991b8e65b..419f530c4e2 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/error.rs +++ b/crates/rpc/rpc-eth-types/src/error/api.rs @@ -1,9 +1,10 @@ //! Helper traits to wrap generic l1 errors, in network specific error type configured in -//! [`EthApiTypes`](crate::EthApiTypes). +//! `reth_rpc_eth_api::EthApiTypes`. -use reth_rpc_eth_types::EthApiError; use revm_primitives::EVMError; +use crate::EthApiError; + /// Helper trait to wrap core [`EthApiError`]. pub trait FromEthApiError: From { /// Converts from error via [`EthApiError`]. @@ -51,7 +52,7 @@ pub trait AsEthApiError { fn as_err(&self) -> Option<&EthApiError>; /// Returns `true` if error is - /// [`RpcInvalidTransactionError::GasTooHigh`](reth_rpc_eth_types::RpcInvalidTransactionError::GasTooHigh). + /// [`RpcInvalidTransactionError::GasTooHigh`](crate::RpcInvalidTransactionError::GasTooHigh). fn is_gas_too_high(&self) -> bool { if let Some(err) = self.as_err() { return err.is_gas_too_high() @@ -61,7 +62,7 @@ pub trait AsEthApiError { } /// Returns `true` if error is - /// [`RpcInvalidTransactionError::GasTooLow`](reth_rpc_eth_types::RpcInvalidTransactionError::GasTooLow). + /// [`RpcInvalidTransactionError::GasTooLow`](crate::RpcInvalidTransactionError::GasTooLow). fn is_gas_too_low(&self) -> bool { if let Some(err) = self.as_err() { return err.is_gas_too_low() diff --git a/crates/rpc/rpc-eth-types/src/error.rs b/crates/rpc/rpc-eth-types/src/error/mod.rs similarity index 99% rename from crates/rpc/rpc-eth-types/src/error.rs rename to crates/rpc/rpc-eth-types/src/error/mod.rs index 641cbc88291..99c41daea37 100644 --- a/crates/rpc/rpc-eth-types/src/error.rs +++ b/crates/rpc/rpc-eth-types/src/error/mod.rs @@ -1,6 +1,9 @@ //! Implementation specific Errors for the `eth_` namespace. -use std::time::Duration; +pub mod api; +pub use api::{AsEthApiError, FromEthApiError, FromEvmError, IntoEthApiError}; + +use core::time::Duration; use alloy_eips::BlockId; use alloy_primitives::{Address, Bytes, U256}; diff --git a/crates/rpc/rpc-eth-types/src/simulate.rs b/crates/rpc/rpc-eth-types/src/simulate.rs index b2a9a5e62ed..91aaa25430e 100644 --- a/crates/rpc/rpc-eth-types/src/simulate.rs +++ b/crates/rpc/rpc-eth-types/src/simulate.rs @@ -21,8 +21,9 @@ use revm::{db::CacheDB, Database}; use revm_primitives::{keccak256, Address, BlockEnv, Bytes, ExecutionResult, TxKind, B256, U256}; use crate::{ - cache::db::StateProviderTraitObjWrapper, error::ToRpcError, EthApiError, RevertError, - RpcInvalidTransactionError, + cache::db::StateProviderTraitObjWrapper, + error::{api::FromEthApiError, ToRpcError}, + EthApiError, RevertError, RpcInvalidTransactionError, }; /// Errors which may occur during `eth_simulateV1` execution. @@ -170,7 +171,7 @@ where /// Handles outputs of the calls execution and builds a [`SimulatedBlock`]. #[expect(clippy::complexity)] -pub fn build_block( +pub fn build_block>( results: Vec<(Address, ExecutionResult)>, transactions: Vec, block_env: &BlockEnv, @@ -179,7 +180,7 @@ pub fn build_block( full_transactions: bool, db: &CacheDB>>, tx_resp_builder: &T, -) -> Result>, EthApiError> { +) -> Result>, T::Error> { let mut calls: Vec = Vec::with_capacity(results.len()); let mut senders = Vec::with_capacity(results.len()); let mut receipts = Vec::with_capacity(results.len()); @@ -272,7 +273,7 @@ pub fn build_block( } } - let state_root = db.db.state_root(hashed_state)?; + let state_root = db.db.state_root(hashed_state).map_err(T::Error::from_eth_err)?; let header = reth_primitives::Header { beneficiary: block_env.coinbase, diff --git a/crates/rpc/rpc-eth-types/src/transaction.rs b/crates/rpc/rpc-eth-types/src/transaction.rs index bfff1cafead..a4ede0a1a4e 100644 --- a/crates/rpc/rpc-eth-types/src/transaction.rs +++ b/crates/rpc/rpc-eth-types/src/transaction.rs @@ -41,7 +41,10 @@ impl TransactionSource { } /// Conversion into network specific transaction type. - pub fn into_transaction(self, resp_builder: &T) -> T::Transaction { + pub fn into_transaction( + self, + resp_builder: &T, + ) -> Result { match self { Self::Pool(tx) => from_recovered(tx, resp_builder), Self::Block { transaction, index, block_hash, block_number, base_fee } => { diff --git a/crates/rpc/rpc-types-compat/Cargo.toml b/crates/rpc/rpc-types-compat/Cargo.toml index 2e45d210d17..887986ada12 100644 --- a/crates/rpc/rpc-types-compat/Cargo.toml +++ b/crates/rpc/rpc-types-compat/Cargo.toml @@ -27,6 +27,7 @@ alloy-consensus.workspace = true # io serde.workspace = true +jsonrpsee-types.workspace = true [dev-dependencies] serde_json.workspace = true diff --git a/crates/rpc/rpc-types-compat/src/block.rs b/crates/rpc/rpc-types-compat/src/block.rs index 41bd057dfd6..43086b311bd 100644 --- a/crates/rpc/rpc-types-compat/src/block.rs +++ b/crates/rpc/rpc-types-compat/src/block.rs @@ -1,15 +1,16 @@ //! Compatibility functions for rpc `Block` type. -use crate::{transaction::from_recovered_with_block_context, TransactionCompat}; use alloy_consensus::Sealed; use alloy_eips::eip4895::Withdrawals; use alloy_primitives::{B256, U256}; use alloy_rlp::Encodable; use alloy_rpc_types_eth::{ - Block, BlockError, BlockTransactions, BlockTransactionsKind, Header, TransactionInfo, + Block, BlockTransactions, BlockTransactionsKind, Header, TransactionInfo, }; use reth_primitives::{Block as PrimitiveBlock, BlockWithSenders}; +use crate::{transaction::from_recovered_with_block_context, TransactionCompat}; + /// Converts the given primitive block into a [`Block`] response with the given /// [`BlockTransactionsKind`] /// @@ -20,7 +21,7 @@ pub fn from_block( kind: BlockTransactionsKind, block_hash: Option, tx_resp_builder: &T, -) -> Result, BlockError> { +) -> Result, T::Error> { match kind { BlockTransactionsKind::Hashes => { Ok(from_block_with_tx_hashes::(block, total_difficulty, block_hash)) @@ -63,7 +64,7 @@ pub fn from_block_full( total_difficulty: U256, block_hash: Option, tx_resp_builder: &T, -) -> Result, BlockError> { +) -> Result, T::Error> { let block_hash = block_hash.unwrap_or_else(|| block.block.header.hash_slow()); let block_number = block.block.number; let base_fee_per_gas = block.block.base_fee_per_gas; @@ -88,7 +89,7 @@ pub fn from_block_full( from_recovered_with_block_context::(signed_tx_ec_recovered, tx_info, tx_resp_builder) }) - .collect::>(); + .collect::, T::Error>>()?; Ok(from_block_with_transactions( block_length, diff --git a/crates/rpc/rpc-types-compat/src/transaction.rs b/crates/rpc/rpc-types-compat/src/transaction.rs index cfbaaa622fb..9e8fae67096 100644 --- a/crates/rpc/rpc-types-compat/src/transaction.rs +++ b/crates/rpc/rpc-types-compat/src/transaction.rs @@ -1,5 +1,6 @@ //! Compatibility functions for rpc `Transaction` type. +use core::error; use std::fmt; use alloy_consensus::Transaction as _; @@ -19,7 +20,7 @@ pub fn from_recovered_with_block_context( tx: TransactionSignedEcRecovered, tx_info: TransactionInfo, resp_builder: &T, -) -> T::Transaction { +) -> Result { resp_builder.fill(tx, tx_info) } @@ -28,7 +29,7 @@ pub fn from_recovered_with_block_context( pub fn from_recovered( tx: TransactionSignedEcRecovered, resp_builder: &T, -) -> T::Transaction { +) -> Result { resp_builder.fill(tx, TransactionInfo::default()) } @@ -43,9 +44,16 @@ pub trait TransactionCompat: Send + Sync + Unpin + Clone + fmt::Debug { + Clone + fmt::Debug; + /// RPC transaction error type. + type Error: error::Error + Into>; + /// Create a new rpc transaction result for a _pending_ signed transaction, setting block /// environment related fields to `None`. - fn fill(&self, tx: TransactionSignedEcRecovered, tx_inf: TransactionInfo) -> Self::Transaction; + fn fill( + &self, + tx: TransactionSignedEcRecovered, + tx_inf: TransactionInfo, + ) -> Result; /// Truncates the input of a transaction to only the first 4 bytes. // todo: remove in favour of using constructor on `TransactionResponse` or similar diff --git a/crates/rpc/rpc/src/eth/filter.rs b/crates/rpc/rpc/src/eth/filter.rs index 589cb801e2c..3782780f5a6 100644 --- a/crates/rpc/rpc/src/eth/filter.rs +++ b/crates/rpc/rpc/src/eth/filter.rs @@ -34,7 +34,7 @@ use tokio::{ sync::{mpsc::Receiver, Mutex}, time::MissedTickBehavior, }; -use tracing::trace; +use tracing::{error, trace}; /// The maximum number of headers we read at once when handling a range filter. const MAX_HEADERS_RANGE: u64 = 1_000; // with ~530bytes per header this is ~500kb @@ -625,10 +625,15 @@ where let mut prepared_stream = self.txs_stream.lock().await; while let Ok(tx) = prepared_stream.try_recv() { - pending_txs.push(from_recovered( - tx.transaction.to_recovered_transaction(), - &self.tx_resp_builder, - )) + match from_recovered(tx.transaction.to_recovered_transaction(), &self.tx_resp_builder) { + Ok(tx) => pending_txs.push(tx), + Err(err) => { + error!(target: "rpc", + %err, + "Failed to fill txn with block context" + ); + } + } } FilterChanges::Transactions(pending_txs) } diff --git a/crates/rpc/rpc/src/eth/helpers/types.rs b/crates/rpc/rpc/src/eth/helpers/types.rs index 19ffc55b398..d1ce84bc0b7 100644 --- a/crates/rpc/rpc/src/eth/helpers/types.rs +++ b/crates/rpc/rpc/src/eth/helpers/types.rs @@ -4,6 +4,7 @@ use alloy_consensus::{Signed, Transaction as _, TxEip4844Variant, TxEnvelope}; use alloy_network::{Ethereum, Network}; use alloy_rpc_types_eth::{Transaction, TransactionInfo}; use reth_primitives::{TransactionSigned, TransactionSignedEcRecovered}; +use reth_rpc_eth_types::EthApiError; use reth_rpc_types_compat::TransactionCompat; /// Builds RPC transaction response for l1. @@ -16,11 +17,13 @@ where { type Transaction = ::TransactionResponse; + type Error = EthApiError; + fn fill( &self, tx: TransactionSignedEcRecovered, tx_info: TransactionInfo, - ) -> Self::Transaction { + ) -> Result { let from = tx.signer(); let TransactionSigned { transaction, signature, hash } = tx.into_signed(); @@ -54,14 +57,14 @@ where }) .unwrap_or_else(|| inner.max_fee_per_gas()); - Transaction { + Ok(Transaction { inner, block_hash, block_number, transaction_index, from, effective_gas_price: Some(effective_gas_price), - } + }) } fn otterscan_api_truncate_input(tx: &mut Self::Transaction) { diff --git a/crates/rpc/rpc/src/eth/pubsub.rs b/crates/rpc/rpc/src/eth/pubsub.rs index 0702e3147ce..8ea6d1f87c8 100644 --- a/crates/rpc/rpc/src/eth/pubsub.rs +++ b/crates/rpc/rpc/src/eth/pubsub.rs @@ -27,6 +27,7 @@ use tokio_stream::{ wrappers::{BroadcastStream, ReceiverStream}, Stream, }; +use tracing::error; /// `Eth` pubsub RPC implementation. /// @@ -146,11 +147,23 @@ where match params { Params::Bool(true) => { // full transaction objects requested - let stream = pubsub.full_pending_transaction_stream().map(|tx| { - EthSubscriptionResult::FullTransaction(Box::new(from_recovered( + let stream = pubsub.full_pending_transaction_stream().filter_map(|tx| { + let tx_value = match from_recovered( tx.transaction.to_recovered_transaction(), &tx_resp_builder, - ))) + ) { + Ok(tx) => { + Some(EthSubscriptionResult::FullTransaction(Box::new(tx))) + } + Err(err) => { + error!(target = "rpc", + %err, + "Failed to fill transaction with block context" + ); + None + } + }; + std::future::ready(tx_value) }); return pipe_from_stream(accepted_sink, stream).await } diff --git a/crates/rpc/rpc/src/txpool.rs b/crates/rpc/rpc/src/txpool.rs index d03e10ca75a..3e46183b466 100644 --- a/crates/rpc/rpc/src/txpool.rs +++ b/crates/rpc/rpc/src/txpool.rs @@ -1,3 +1,4 @@ +use core::fmt; use std::collections::BTreeMap; use alloy_consensus::Transaction; @@ -6,7 +7,7 @@ use alloy_rpc_types_txpool::{ TxpoolContent, TxpoolContentFrom, TxpoolInspect, TxpoolInspectSummary, TxpoolStatus, }; use async_trait::async_trait; -use jsonrpsee::core::RpcResult as Result; +use jsonrpsee::core::RpcResult; use reth_primitives::TransactionSignedEcRecovered; use reth_rpc_api::TxPoolApiServer; use reth_rpc_types_compat::{transaction::from_recovered, TransactionCompat}; @@ -35,33 +36,36 @@ where Pool: TransactionPool + 'static, Eth: TransactionCompat, { - fn content(&self) -> TxpoolContent { + fn content(&self) -> Result, Eth::Error> { #[inline] fn insert( tx: &Tx, content: &mut BTreeMap>, resp_builder: &RpcTxB, - ) where + ) -> Result<(), RpcTxB::Error> + where Tx: PoolTransaction>, RpcTxB: TransactionCompat, { content.entry(tx.sender()).or_default().insert( tx.nonce().to_string(), - from_recovered(tx.clone().into_consensus().into(), resp_builder), + from_recovered(tx.clone().into_consensus().into(), resp_builder)?, ); + + Ok(()) } let AllPoolTransactions { pending, queued } = self.pool.all_transactions(); let mut content = TxpoolContent { pending: BTreeMap::new(), queued: BTreeMap::new() }; for pending in pending { - insert::<_, Eth>(&pending.transaction, &mut content.pending, &self.tx_resp_builder); + insert::<_, Eth>(&pending.transaction, &mut content.pending, &self.tx_resp_builder)?; } for queued in queued { - insert::<_, Eth>(&queued.transaction, &mut content.queued, &self.tx_resp_builder); + insert::<_, Eth>(&queued.transaction, &mut content.queued, &self.tx_resp_builder)?; } - content + Ok(content) } } @@ -76,7 +80,7 @@ where /// Ref: [Here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_status) /// /// Handler for `txpool_status` - async fn txpool_status(&self) -> Result { + async fn txpool_status(&self) -> RpcResult { trace!(target: "rpc::eth", "Serving txpool_status"); let all = self.pool.all_transactions(); Ok(TxpoolStatus { pending: all.pending.len() as u64, queued: all.queued.len() as u64 }) @@ -88,7 +92,7 @@ where /// See [here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_inspect) for more details /// /// Handler for `txpool_inspect` - async fn txpool_inspect(&self) -> Result { + async fn txpool_inspect(&self) -> RpcResult { trace!(target: "rpc::eth", "Serving txpool_inspect"); #[inline] @@ -131,9 +135,9 @@ where async fn txpool_content_from( &self, from: Address, - ) -> Result> { + ) -> RpcResult> { trace!(target: "rpc::eth", ?from, "Serving txpool_contentFrom"); - Ok(self.content().remove_from(&from)) + Ok(self.content().map_err(Into::into)?.remove_from(&from)) } /// Returns the details of all transactions currently pending for inclusion in the next @@ -141,14 +145,14 @@ where /// /// See [here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_content) for more details /// Handler for `txpool_content` - async fn txpool_content(&self) -> Result> { + async fn txpool_content(&self) -> RpcResult> { trace!(target: "rpc::eth", "Serving txpool_content"); - Ok(self.content()) + Ok(self.content().map_err(Into::into)?) } } -impl std::fmt::Debug for TxPoolApi { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl fmt::Debug for TxPoolApi { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("TxpoolApi").finish_non_exhaustive() } } From b5f7eca72f80ffc26602e962a37b7b79b797de1a Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Tue, 12 Nov 2024 11:38:00 +0100 Subject: [PATCH 116/211] chore(sdk): make `ExecutionOutcome` generic over receipt (#12448) Co-authored-by: Federico Gimenez --- Cargo.lock | 1 + crates/engine/util/src/reorg.rs | 2 +- crates/evm/execution-types/Cargo.toml | 7 +- .../execution-types/src/execution_outcome.rs | 82 +++++++++++-------- crates/optimism/evm/src/lib.rs | 2 +- crates/primitives-traits/src/receipt.rs | 2 +- crates/storage/provider/src/writer/mod.rs | 9 +- 7 files changed, 61 insertions(+), 44 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 38a87ebf930..bd3a93eda7a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7518,6 +7518,7 @@ dependencies = [ "rand 0.8.5", "reth-execution-errors", "reth-primitives", + "reth-primitives-traits", "reth-trie", "revm", "serde", diff --git a/crates/engine/util/src/reorg.rs b/crates/engine/util/src/reorg.rs index 69831389a65..169b6f5ede7 100644 --- a/crates/engine/util/src/reorg.rs +++ b/crates/engine/util/src/reorg.rs @@ -375,7 +375,7 @@ where // and 4788 contract call state.merge_transitions(BundleRetention::PlainState); - let outcome = ExecutionOutcome::new( + let outcome: ExecutionOutcome = ExecutionOutcome::new( state.take_bundle(), Receipts::from(vec![receipts]), reorg_target.number, diff --git a/crates/evm/execution-types/Cargo.toml b/crates/evm/execution-types/Cargo.toml index b6af3dee9af..13b0aef8ad4 100644 --- a/crates/evm/execution-types/Cargo.toml +++ b/crates/evm/execution-types/Cargo.toml @@ -14,6 +14,7 @@ workspace = true reth-primitives.workspace = true reth-execution-errors.workspace = true reth-trie.workspace = true +reth-primitives-traits.workspace = true revm.workspace = true @@ -43,14 +44,16 @@ serde = [ ] serde-bincode-compat = [ "reth-primitives/serde-bincode-compat", + "reth-primitives-traits/serde-bincode-compat", "reth-trie/serde-bincode-compat", "serde_with", - "alloy-eips/serde-bincode-compat" + "alloy-eips/serde-bincode-compat", ] std = [ "reth-primitives/std", "alloy-eips/std", "alloy-primitives/std", "revm/std", - "serde?/std" + "serde?/std", + "reth-primitives-traits/std", ] diff --git a/crates/evm/execution-types/src/execution_outcome.rs b/crates/evm/execution-types/src/execution_outcome.rs index 026e6b37c42..c1d9c701650 100644 --- a/crates/evm/execution-types/src/execution_outcome.rs +++ b/crates/evm/execution-types/src/execution_outcome.rs @@ -1,13 +1,16 @@ -use crate::BlockExecutionOutput; +use std::collections::HashMap; + use alloy_eips::eip7685::Requests; use alloy_primitives::{Address, BlockNumber, Bloom, Log, B256, U256}; -use reth_primitives::{logs_bloom, Account, Bytecode, Receipt, Receipts, StorageEntry}; +use reth_primitives::{logs_bloom, Account, Bytecode, Receipts, StorageEntry}; +use reth_primitives_traits::Receipt; use reth_trie::HashedPostState; use revm::{ db::{states::BundleState, BundleAccount}, primitives::AccountInfo, }; -use std::collections::HashMap; + +use crate::BlockExecutionOutput; /// Represents a changed account #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -33,7 +36,7 @@ impl ChangedAccount { /// blocks, capturing the resulting state, receipts, and requests following the execution. #[derive(Default, Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct ExecutionOutcome { +pub struct ExecutionOutcome { /// Bundle state with reverts. pub bundle: BundleState, /// The collection of receipts. @@ -41,7 +44,7 @@ pub struct ExecutionOutcome { /// The inner vector stores receipts ordered by transaction number. /// /// If receipt is None it means it is pruned. - pub receipts: Receipts, + pub receipts: Receipts, /// First block of bundle state. pub first_block: BlockNumber, /// The collection of EIP-7685 requests. @@ -63,14 +66,14 @@ pub type AccountRevertInit = (Option>, Vec); /// Type used to initialize revms reverts. pub type RevertsInit = HashMap>; -impl ExecutionOutcome { +impl ExecutionOutcome { /// Creates a new `ExecutionOutcome`. /// /// This constructor initializes a new `ExecutionOutcome` instance with the provided /// bundle state, receipts, first block number, and EIP-7685 requests. pub const fn new( bundle: BundleState, - receipts: Receipts, + receipts: Receipts, first_block: BlockNumber, requests: Vec, ) -> Self { @@ -85,7 +88,7 @@ impl ExecutionOutcome { state_init: BundleStateInit, revert_init: RevertsInit, contracts_init: impl IntoIterator, - receipts: Receipts, + receipts: Receipts, first_block: BlockNumber, requests: Vec, ) -> Self { @@ -180,27 +183,33 @@ impl ExecutionOutcome { } /// Returns an iterator over all block logs. - pub fn logs(&self, block_number: BlockNumber) -> Option> { + pub fn logs(&self, block_number: BlockNumber) -> Option> + where + T: Receipt, + { let index = self.block_number_to_index(block_number)?; - Some(self.receipts[index].iter().filter_map(|r| Some(r.as_ref()?.logs.iter())).flatten()) + Some(self.receipts[index].iter().filter_map(|r| Some(r.as_ref()?.logs().iter())).flatten()) } /// Return blocks logs bloom - pub fn block_logs_bloom(&self, block_number: BlockNumber) -> Option { + pub fn block_logs_bloom(&self, block_number: BlockNumber) -> Option + where + T: Receipt, + { Some(logs_bloom(self.logs(block_number)?)) } /// Returns the receipt root for all recorded receipts. /// Note: this function calculated Bloom filters for every receipt and created merkle trees /// of receipt. This is a expensive operation. - pub fn receipts_root_slow(&self, _block_number: BlockNumber) -> Option { + pub fn receipts_root_slow(&self, _block_number: BlockNumber) -> Option + where + T: Receipt, + { #[cfg(feature = "optimism")] panic!("This should not be called in optimism mode. Use `optimism_receipts_root_slow` instead."); #[cfg(not(feature = "optimism"))] - self.receipts.root_slow( - self.block_number_to_index(_block_number)?, - reth_primitives::proofs::calculate_receipt_root_no_memo, - ) + self.receipts.root_slow(self.block_number_to_index(_block_number)?, T::receipts_root) } /// Returns the receipt root for all recorded receipts. @@ -209,23 +218,23 @@ impl ExecutionOutcome { pub fn generic_receipts_root_slow( &self, block_number: BlockNumber, - f: impl FnOnce(&[&Receipt]) -> B256, + f: impl FnOnce(&[&T]) -> B256, ) -> Option { self.receipts.root_slow(self.block_number_to_index(block_number)?, f) } /// Returns reference to receipts. - pub const fn receipts(&self) -> &Receipts { + pub const fn receipts(&self) -> &Receipts { &self.receipts } /// Returns mutable reference to receipts. - pub fn receipts_mut(&mut self) -> &mut Receipts { + pub fn receipts_mut(&mut self) -> &mut Receipts { &mut self.receipts } /// Return all block receipts - pub fn receipts_by_block(&self, block_number: BlockNumber) -> &[Option] { + pub fn receipts_by_block(&self, block_number: BlockNumber) -> &[Option] { let Some(index) = self.block_number_to_index(block_number) else { return &[] }; &self.receipts[index] } @@ -277,7 +286,10 @@ impl ExecutionOutcome { /// # Panics /// /// If the target block number is not included in the state block range. - pub fn split_at(self, at: BlockNumber) -> (Option, Self) { + pub fn split_at(self, at: BlockNumber) -> (Option, Self) + where + T: Clone, + { if at == self.first_block { return (None, self) } @@ -329,7 +341,7 @@ impl ExecutionOutcome { } /// Create a new instance with updated receipts. - pub fn with_receipts(mut self, receipts: Receipts) -> Self { + pub fn with_receipts(mut self, receipts: Receipts) -> Self { self.receipts = receipts; self } @@ -352,8 +364,8 @@ impl ExecutionOutcome { } } -impl From<(BlockExecutionOutput, BlockNumber)> for ExecutionOutcome { - fn from(value: (BlockExecutionOutput, BlockNumber)) -> Self { +impl From<(BlockExecutionOutput, BlockNumber)> for ExecutionOutcome { + fn from(value: (BlockExecutionOutput, BlockNumber)) -> Self { Self { bundle: value.0.state, receipts: Receipts::from(value.0.receipts), @@ -385,7 +397,7 @@ mod tests { // Create a Receipts object with a vector of receipt vectors let receipts = Receipts { - receipt_vec: vec![vec![Some(Receipt { + receipt_vec: vec![vec![Some(reth_primitives::Receipt { tx_type: TxType::Legacy, cumulative_gas_used: 46913, logs: vec![], @@ -447,7 +459,7 @@ mod tests { fn test_block_number_to_index() { // Create a Receipts object with a vector of receipt vectors let receipts = Receipts { - receipt_vec: vec![vec![Some(Receipt { + receipt_vec: vec![vec![Some(reth_primitives::Receipt { tx_type: TxType::Legacy, cumulative_gas_used: 46913, logs: vec![], @@ -482,7 +494,7 @@ mod tests { fn test_get_logs() { // Create a Receipts object with a vector of receipt vectors let receipts = Receipts { - receipt_vec: vec![vec![Some(Receipt { + receipt_vec: vec![vec![Some(reth_primitives::Receipt { tx_type: TxType::Legacy, cumulative_gas_used: 46913, logs: vec![Log::::default()], @@ -514,7 +526,7 @@ mod tests { fn test_receipts_by_block() { // Create a Receipts object with a vector of receipt vectors let receipts = Receipts { - receipt_vec: vec![vec![Some(Receipt { + receipt_vec: vec![vec![Some(reth_primitives::Receipt { tx_type: TxType::Legacy, cumulative_gas_used: 46913, logs: vec![Log::::default()], @@ -540,7 +552,7 @@ mod tests { // Assert that the receipts for block number 123 match the expected receipts assert_eq!( receipts_by_block, - vec![&Some(Receipt { + vec![&Some(reth_primitives::Receipt { tx_type: TxType::Legacy, cumulative_gas_used: 46913, logs: vec![Log::::default()], @@ -554,7 +566,7 @@ mod tests { fn test_receipts_len() { // Create a Receipts object with a vector of receipt vectors let receipts = Receipts { - receipt_vec: vec![vec![Some(Receipt { + receipt_vec: vec![vec![Some(reth_primitives::Receipt { tx_type: TxType::Legacy, cumulative_gas_used: 46913, logs: vec![Log::::default()], @@ -563,7 +575,7 @@ mod tests { }; // Create an empty Receipts object - let receipts_empty = Receipts { receipt_vec: vec![] }; + let receipts_empty: Receipts = Receipts { receipt_vec: vec![] }; // Define the first block number let first_block = 123; @@ -602,7 +614,7 @@ mod tests { #[cfg(not(feature = "optimism"))] fn test_revert_to() { // Create a random receipt object - let receipt = Receipt { + let receipt = reth_primitives::Receipt { tx_type: TxType::Legacy, cumulative_gas_used: 46913, logs: vec![], @@ -651,7 +663,7 @@ mod tests { #[cfg(not(feature = "optimism"))] fn test_extend_execution_outcome() { // Create a Receipt object with specific attributes. - let receipt = Receipt { + let receipt = reth_primitives::Receipt { tx_type: TxType::Legacy, cumulative_gas_used: 46913, logs: vec![], @@ -695,7 +707,7 @@ mod tests { #[cfg(not(feature = "optimism"))] fn test_split_at_execution_outcome() { // Create a random receipt object - let receipt = Receipt { + let receipt = reth_primitives::Receipt { tx_type: TxType::Legacy, cumulative_gas_used: 46913, logs: vec![], @@ -803,7 +815,7 @@ mod tests { }, ); - let execution_outcome = ExecutionOutcome { + let execution_outcome: ExecutionOutcome = ExecutionOutcome { bundle: bundle_state, receipts: Receipts::default(), first_block: 0, diff --git a/crates/optimism/evm/src/lib.rs b/crates/optimism/evm/src/lib.rs index 8f0f75782f4..cfa7dfa5849 100644 --- a/crates/optimism/evm/src/lib.rs +++ b/crates/optimism/evm/src/lib.rs @@ -820,7 +820,7 @@ mod tests { }; // Create an empty Receipts object - let receipts_empty = Receipts { receipt_vec: vec![] }; + let receipts_empty = Receipts:: { receipt_vec: vec![] }; // Define the first block number let first_block = 123; diff --git a/crates/primitives-traits/src/receipt.rs b/crates/primitives-traits/src/receipt.rs index bfcd99b08ec..68917d62812 100644 --- a/crates/primitives-traits/src/receipt.rs +++ b/crates/primitives-traits/src/receipt.rs @@ -29,6 +29,6 @@ pub trait Receipt: /// Returns transaction type. fn tx_type(&self) -> u8; - /// Calculates the receipts root of all receipts in a block. + /// Calculates the receipts root of the given receipts. fn receipts_root(receipts: &[&Self]) -> B256; } diff --git a/crates/storage/provider/src/writer/mod.rs b/crates/storage/provider/src/writer/mod.rs index 37092a5dd51..6ca024b0a9f 100644 --- a/crates/storage/provider/src/writer/mod.rs +++ b/crates/storage/provider/src/writer/mod.rs @@ -1129,7 +1129,8 @@ mod tests { let bundle = state.take_bundle(); - let outcome = ExecutionOutcome::new(bundle, Receipts::default(), 1, Vec::new()); + let outcome: ExecutionOutcome = + ExecutionOutcome::new(bundle, Receipts::default(), 1, Vec::new()); let mut writer = UnifiedStorageWriter::from_database(&provider); writer .write_to_storage(outcome, OriginalValuesKnown::Yes) @@ -1375,7 +1376,7 @@ mod tests { #[test] fn revert_to_indices() { - let base = ExecutionOutcome { + let base: ExecutionOutcome = ExecutionOutcome { bundle: BundleState::default(), receipts: vec![vec![Some(Receipt::default()); 2]; 7].into(), first_block: 10, @@ -1441,7 +1442,7 @@ mod tests { assert_eq!( StateRoot::overlay_root( tx, - ExecutionOutcome::new( + ExecutionOutcome::::new( state.bundle_state.clone(), Receipts::default(), 0, @@ -1592,7 +1593,7 @@ mod tests { .build(); assert_eq!(previous_state.reverts.len(), 1); - let mut test = ExecutionOutcome { + let mut test: ExecutionOutcome = ExecutionOutcome { bundle: present_state, receipts: vec![vec![Some(Receipt::default()); 2]; 1].into(), first_block: 2, From a2e11977d8e873b2229af32db52432fc0382dadb Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Tue, 12 Nov 2024 11:52:26 +0100 Subject: [PATCH 117/211] chore(sdk): Add `InMemorySize` as super trait of data primitive traits (#12465) --- crates/primitives-traits/src/block/body.rs | 6 ++---- crates/primitives-traits/src/block/mod.rs | 6 ++---- crates/primitives-traits/src/transaction/mod.rs | 6 +++--- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/crates/primitives-traits/src/block/body.rs b/crates/primitives-traits/src/block/body.rs index 9b703c0d2f1..14941ffed0f 100644 --- a/crates/primitives-traits/src/block/body.rs +++ b/crates/primitives-traits/src/block/body.rs @@ -6,7 +6,7 @@ use alloy_consensus::{BlockHeader, Transaction, TxType}; use alloy_eips::{eip4895::Withdrawal, eip7685::Requests}; use alloy_primitives::{Address, B256}; -use crate::Block; +use crate::{Block, InMemorySize}; /// Abstraction for block's body. pub trait BlockBody: @@ -22,6 +22,7 @@ pub trait BlockBody: + for<'de> serde::Deserialize<'de> + alloy_rlp::Encodable + alloy_rlp::Decodable + + InMemorySize { /// Ordered list of signed transactions as committed in block. // todo: requires trait for signed transaction @@ -93,7 +94,4 @@ pub trait BlockBody: fn blob_versioned_hashes(&self) -> Vec<&B256> { self.blob_versioned_hashes_iter().collect() } - - /// Calculates a heuristic for the in-memory size of the [`BlockBody`]. - fn size(&self) -> usize; } diff --git a/crates/primitives-traits/src/block/mod.rs b/crates/primitives-traits/src/block/mod.rs index 185b61e9782..cfc9e9a5503 100644 --- a/crates/primitives-traits/src/block/mod.rs +++ b/crates/primitives-traits/src/block/mod.rs @@ -8,7 +8,7 @@ use alloc::{fmt, vec::Vec}; use alloy_primitives::{Address, B256}; use reth_codecs::Compact; -use crate::{BlockBody, BlockHeader, FullBlockHeader}; +use crate::{BlockBody, BlockHeader, FullBlockHeader, InMemorySize}; /// Helper trait that unifies all behaviour required by block to support full node operations. pub trait FullBlock: Block + Compact {} @@ -32,6 +32,7 @@ pub trait Block: + for<'a> serde::Deserialize<'a> + From<(Self::Header, Self::Body)> + Into<(Self::Header, Self::Body)> + + InMemorySize { /// Header part of the block. type Header: BlockHeader; @@ -104,7 +105,4 @@ pub trait Block: // todo: can be default impl if sealed block type is made generic over header and body and // migrated to alloy fn with_recovered_senders(self) -> Option>; - - /// Calculates a heuristic for the in-memory size of the [`Block`]. - fn size(&self) -> usize; } diff --git a/crates/primitives-traits/src/transaction/mod.rs b/crates/primitives-traits/src/transaction/mod.rs index 7fd0ec88b31..d5061ca3909 100644 --- a/crates/primitives-traits/src/transaction/mod.rs +++ b/crates/primitives-traits/src/transaction/mod.rs @@ -7,6 +7,8 @@ use alloy_primitives::{TxKind, B256}; use reth_codecs::Compact; use serde::{Deserialize, Serialize}; +use crate::InMemorySize; + pub mod signed; #[allow(dead_code)] @@ -26,6 +28,7 @@ pub trait Transaction: + alloy_rlp::Decodable + for<'de> Deserialize<'de> + alloy_consensus::Transaction + + InMemorySize + MaybeArbitrary { /// Heavy operation that return signature hash over rlp encoded transaction. @@ -45,9 +48,6 @@ pub trait Transaction: /// This encodes the transaction _without_ the signature, and is only suitable for creating a /// hash intended for signing. fn encode_without_signature(&self, out: &mut dyn bytes::BufMut); - - /// Calculates a heuristic for the in-memory size of the [Transaction]. - fn size(&self) -> usize; } #[cfg(not(feature = "arbitrary"))] From 9f29107abb15b64d45843204e2e0fb32c65a5233 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Tue, 12 Nov 2024 12:11:37 +0100 Subject: [PATCH 118/211] chore(sdk): add `NodePrimitives::TxType` (#12332) --- crates/ethereum/node/src/node.rs | 3 ++- crates/optimism/node/src/node.rs | 3 ++- crates/primitives-traits/src/lib.rs | 2 +- crates/primitives-traits/src/node.rs | 10 ++++++++-- crates/primitives-traits/src/tx_type.rs | 7 +++++++ 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/crates/ethereum/node/src/node.rs b/crates/ethereum/node/src/node.rs index 68ed879d223..b37d0227a78 100644 --- a/crates/ethereum/node/src/node.rs +++ b/crates/ethereum/node/src/node.rs @@ -25,7 +25,7 @@ use reth_node_builder::{ BuilderContext, Node, NodeAdapter, NodeComponentsBuilder, PayloadBuilderConfig, PayloadTypes, }; use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService}; -use reth_primitives::{Block, Header, Receipt, TransactionSigned}; +use reth_primitives::{Block, Header, Receipt, TransactionSigned, TxType}; use reth_provider::CanonStateSubscriptions; use reth_rpc::EthApi; use reth_tracing::tracing::{debug, info}; @@ -44,6 +44,7 @@ pub struct EthPrimitives; impl NodePrimitives for EthPrimitives { type Block = Block; type SignedTx = TransactionSigned; + type TxType = TxType; type Receipt = Receipt; } diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index 323148e276b..e97924d4b55 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -24,7 +24,7 @@ use reth_optimism_evm::{OpEvmConfig, OpExecutionStrategyFactory}; use reth_optimism_payload_builder::builder::OpPayloadTransactions; use reth_optimism_rpc::OpEthApi; use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService, PayloadStore}; -use reth_primitives::{Block, Header, Receipt, TransactionSigned}; +use reth_primitives::{Block, Header, Receipt, TransactionSigned, TxType}; use reth_provider::CanonStateSubscriptions; use reth_tracing::tracing::{debug, info}; use reth_transaction_pool::{ @@ -47,6 +47,7 @@ pub struct OpPrimitives; impl NodePrimitives for OpPrimitives { type Block = Block; type SignedTx = TransactionSigned; + type TxType = TxType; type Receipt = Receipt; } diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index babc0f42e0b..afcc74a894d 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -54,7 +54,7 @@ pub use storage::StorageEntry; /// Transaction types pub mod tx_type; -pub use tx_type::TxType; +pub use tx_type::{FullTxType, TxType}; /// Common header types pub mod header; diff --git a/crates/primitives-traits/src/node.rs b/crates/primitives-traits/src/node.rs index 921942841d4..cebbbe202e8 100644 --- a/crates/primitives-traits/src/node.rs +++ b/crates/primitives-traits/src/node.rs @@ -1,6 +1,6 @@ use core::fmt; -use crate::{BlockBody, FullBlock, FullReceipt, FullSignedTx}; +use crate::{BlockBody, FullBlock, FullReceipt, FullSignedTx, FullTxType}; /// Configures all the primitive types of the node. pub trait NodePrimitives: Send + Sync + Unpin + Clone + Default + fmt::Debug { @@ -8,6 +8,8 @@ pub trait NodePrimitives: Send + Sync + Unpin + Clone + Default + fmt::Debug { type Block: Send + Sync + Unpin + Clone + Default + fmt::Debug + 'static; /// Signed version of the transaction type. type SignedTx: Send + Sync + Unpin + Clone + Default + fmt::Debug + 'static; + /// Transaction envelope type ID. + type TxType: Send + Sync + Unpin + Clone + Default + fmt::Debug + 'static; /// A receipt. type Receipt: Send + Sync + Unpin + Clone + Default + fmt::Debug + 'static; } @@ -15,6 +17,7 @@ pub trait NodePrimitives: Send + Sync + Unpin + Clone + Default + fmt::Debug { impl NodePrimitives for () { type Block = (); type SignedTx = (); + type TxType = (); type Receipt = (); } @@ -24,15 +27,18 @@ pub trait FullNodePrimitives: Send + Sync + Unpin + Clone + Default + fmt::Debug type Block: FullBlock>; /// Signed version of the transaction type. type SignedTx: FullSignedTx; + /// Transaction envelope type ID. + type TxType: FullTxType; /// A receipt. type Receipt: FullReceipt; } impl NodePrimitives for T where - T: FullNodePrimitives, + T: FullNodePrimitives, { type Block = T::Block; type SignedTx = T::SignedTx; + type TxType = T::TxType; type Receipt = T::Receipt; } diff --git a/crates/primitives-traits/src/tx_type.rs b/crates/primitives-traits/src/tx_type.rs index 6ca55879442..e0bf28d2a99 100644 --- a/crates/primitives-traits/src/tx_type.rs +++ b/crates/primitives-traits/src/tx_type.rs @@ -3,6 +3,13 @@ use core::fmt; use alloy_eips::eip2718::Eip2718Error; use alloy_primitives::{U64, U8}; use alloy_rlp::{Decodable, Encodable}; +use reth_codecs::Compact; + +/// Helper trait that unifies all behaviour required by transaction type ID to support full node +/// operations. +pub trait FullTxType: TxType + Compact {} + +impl FullTxType for T where T: TxType + Compact {} /// Trait representing the behavior of a transaction type. pub trait TxType: From 179aa047072a4b9d7fb51db555d6566a9122dd77 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Tue, 12 Nov 2024 12:29:51 +0100 Subject: [PATCH 119/211] test(trie): add ParallelProof unit test (#12413) --- crates/trie/common/src/proofs.rs | 4 +- crates/trie/parallel/src/proof.rs | 89 ++++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 4 deletions(-) diff --git a/crates/trie/common/src/proofs.rs b/crates/trie/common/src/proofs.rs index 108910a1384..f6eaf3960ec 100644 --- a/crates/trie/common/src/proofs.rs +++ b/crates/trie/common/src/proofs.rs @@ -17,7 +17,7 @@ use std::collections::HashMap; /// The state multiproof of target accounts and multiproofs of their storage tries. /// Multiproof is effectively a state subtrie that only contains the nodes /// in the paths of target accounts. -#[derive(Clone, Default, Debug)] +#[derive(Clone, Default, Debug, PartialEq, Eq)] pub struct MultiProof { /// State trie multiproof for requested accounts. pub account_subtree: ProofNodes, @@ -79,7 +79,7 @@ impl MultiProof { } /// The merkle multiproof of storage trie. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct StorageMultiProof { /// Storage trie root. pub root: B256, diff --git a/crates/trie/parallel/src/proof.rs b/crates/trie/parallel/src/proof.rs index 4cb99b50d0c..bafb9917c60 100644 --- a/crates/trie/parallel/src/proof.rs +++ b/crates/trie/parallel/src/proof.rs @@ -1,5 +1,8 @@ use crate::{root::ParallelStateRootError, stats::ParallelTrieTracker, StorageRootTargets}; -use alloy_primitives::{map::HashSet, B256}; +use alloy_primitives::{ + map::{HashMap, HashSet}, + B256, +}; use alloy_rlp::{BufMut, Encodable}; use itertools::Itertools; use reth_db::DatabaseError; @@ -18,7 +21,7 @@ use reth_trie::{ }; use reth_trie_common::proof::ProofRetainer; use reth_trie_db::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory}; -use std::{collections::HashMap, sync::Arc}; +use std::sync::Arc; use tracing::debug; #[cfg(feature = "metrics")] @@ -210,3 +213,85 @@ where Ok(MultiProof { account_subtree: hash_builder.take_proof_nodes(), storages }) } } + +#[cfg(test)] +mod tests { + use super::*; + use alloy_primitives::{keccak256, map::DefaultHashBuilder, Address, U256}; + use rand::Rng; + use reth_primitives::{Account, StorageEntry}; + use reth_provider::{test_utils::create_test_provider_factory, HashingWriter}; + use reth_trie::proof::Proof; + + #[test] + fn random_parallel_proof() { + let factory = create_test_provider_factory(); + let consistent_view = ConsistentDbView::new(factory.clone(), None); + + let mut rng = rand::thread_rng(); + let state = (0..100) + .map(|_| { + let address = Address::random(); + let account = + Account { balance: U256::from(rng.gen::()), ..Default::default() }; + let mut storage = HashMap::::default(); + let has_storage = rng.gen_bool(0.7); + if has_storage { + for _ in 0..100 { + storage.insert( + B256::from(U256::from(rng.gen::())), + U256::from(rng.gen::()), + ); + } + } + (address, (account, storage)) + }) + .collect::>(); + + { + let provider_rw = factory.provider_rw().unwrap(); + provider_rw + .insert_account_for_hashing( + state.iter().map(|(address, (account, _))| (*address, Some(*account))), + ) + .unwrap(); + provider_rw + .insert_storage_for_hashing(state.iter().map(|(address, (_, storage))| { + ( + *address, + storage + .iter() + .map(|(slot, value)| StorageEntry { key: *slot, value: *value }), + ) + })) + .unwrap(); + provider_rw.commit().unwrap(); + } + + let mut targets = + HashMap::, DefaultHashBuilder>::default(); + for (address, (_, storage)) in state.iter().take(10) { + let hashed_address = keccak256(*address); + let mut target_slots = HashSet::::default(); + + for (slot, _) in storage.iter().take(5) { + target_slots.insert(*slot); + } + + if !target_slots.is_empty() { + targets.insert(hashed_address, target_slots); + } + } + + let provider_rw = factory.provider_rw().unwrap(); + let trie_cursor_factory = DatabaseTrieCursorFactory::new(provider_rw.tx_ref()); + let hashed_cursor_factory = DatabaseHashedCursorFactory::new(provider_rw.tx_ref()); + + assert_eq!( + ParallelProof::new(consistent_view, Default::default()) + .multiproof(targets.clone()) + .unwrap(), + Proof::new(trie_cursor_factory, hashed_cursor_factory).multiproof(targets).unwrap() + ); + } +} From 6c1833de315eb9012a9581747cc309d0456afdca Mon Sep 17 00:00:00 2001 From: malik Date: Tue, 12 Nov 2024 12:48:39 +0100 Subject: [PATCH 120/211] chore: remove unessarcy clone (#12463) --- crates/chain-state/src/in_memory.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/chain-state/src/in_memory.rs b/crates/chain-state/src/in_memory.rs index bfae8113e3e..8794bb393ca 100644 --- a/crates/chain-state/src/in_memory.rs +++ b/crates/chain-state/src/in_memory.rs @@ -269,7 +269,7 @@ impl CanonicalInMemoryState { // insert the new blocks for block in new_blocks { let parent = blocks.get(&block.block().parent_hash).cloned(); - let block_state = BlockState::with_parent(block.clone(), parent); + let block_state = BlockState::with_parent(block, parent); let hash = block_state.hash(); let number = block_state.number(); From c44edf5ce26cb326002169ec666f22ff4819bbeb Mon Sep 17 00:00:00 2001 From: Steven <112043913+stevencartavia@users.noreply.github.com> Date: Tue, 12 Nov 2024 06:15:28 -0600 Subject: [PATCH 121/211] make PayloadStore operate on PayloadBuilder (#12460) Co-authored-by: Matthias Seitz --- crates/node/builder/src/rpc.rs | 5 ++- crates/optimism/node/src/node.rs | 8 ++-- crates/payload/builder/src/service.rs | 22 +++++---- crates/payload/primitives/src/lib.rs | 2 +- crates/payload/primitives/src/traits.rs | 60 ++++++++++++++++++++++++- 5 files changed, 81 insertions(+), 16 deletions(-) diff --git a/crates/node/builder/src/rpc.rs b/crates/node/builder/src/rpc.rs index 4530bbe7014..9680c221d7c 100644 --- a/crates/node/builder/src/rpc.rs +++ b/crates/node/builder/src/rpc.rs @@ -17,6 +17,7 @@ use reth_node_core::{ version::{CARGO_PKG_VERSION, CLIENT_CODE, NAME_CLIENT, VERGEN_GIT_SHA}, }; use reth_payload_builder::PayloadStore; +use reth_payload_primitives::PayloadBuilder; use reth_provider::providers::ProviderNodeTypes; use reth_rpc::{ eth::{EthApiTypes, FullEthApiServer}, @@ -402,7 +403,7 @@ impl NodeAddOns for RpcAddOns where N: FullNodeComponents< Types: ProviderNodeTypes, - PayloadBuilder: Into::Engine>>, + PayloadBuilder: PayloadBuilder::Engine>, >, EthApi: EthApiTypes + FullEthApiServer + AddDevSigners + Unpin + 'static, EV: EngineValidatorBuilder, @@ -426,7 +427,7 @@ where node.provider().clone(), config.chain.clone(), beacon_engine_handle, - node.payload_builder().clone().into(), + PayloadStore::new(node.payload_builder().clone()), node.pool().clone(), Box::new(node.task_executor().clone()), client, diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index e97924d4b55..efc8964ffab 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -7,7 +7,7 @@ use reth_chainspec::{EthChainSpec, Hardforks}; use reth_evm::{execute::BasicBlockExecutorProvider, ConfigureEvm}; use reth_network::{NetworkConfig, NetworkHandle, NetworkManager, PeersInfo}; use reth_node_api::{ - AddOnsContext, EngineValidator, FullNodeComponents, NodeAddOns, NodePrimitives, + AddOnsContext, EngineValidator, FullNodeComponents, NodeAddOns, NodePrimitives, PayloadBuilder, }; use reth_node_builder::{ components::{ @@ -23,7 +23,7 @@ use reth_optimism_consensus::OpBeaconConsensus; use reth_optimism_evm::{OpEvmConfig, OpExecutionStrategyFactory}; use reth_optimism_payload_builder::builder::OpPayloadTransactions; use reth_optimism_rpc::OpEthApi; -use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService, PayloadStore}; +use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService}; use reth_primitives::{Block, Header, Receipt, TransactionSigned, TxType}; use reth_provider::CanonStateSubscriptions; use reth_tracing::tracing::{debug, info}; @@ -152,7 +152,7 @@ impl NodeAddOns for OpAddOns where N: FullNodeComponents< Types: NodeTypes, - PayloadBuilder: Into::Engine>>, + PayloadBuilder: PayloadBuilder::Engine>, >, OpEngineValidator: EngineValidator<::Engine>, { @@ -170,7 +170,7 @@ impl RethRpcAddOns for OpAddOns where N: FullNodeComponents< Types: NodeTypes, - PayloadBuilder: Into::Engine>>, + PayloadBuilder: PayloadBuilder::Engine>, >, OpEngineValidator: EngineValidator<::Engine>, { diff --git a/crates/payload/builder/src/service.rs b/crates/payload/builder/src/service.rs index 2c9975cb4c3..267a1e355b0 100644 --- a/crates/payload/builder/src/service.rs +++ b/crates/payload/builder/src/service.rs @@ -12,12 +12,13 @@ use futures_util::{future::FutureExt, Stream, StreamExt}; use reth_chain_state::CanonStateNotification; use reth_payload_primitives::{ BuiltPayload, Events, PayloadBuilder, PayloadBuilderAttributes, PayloadBuilderError, - PayloadEvents, PayloadKind, PayloadTypes, + PayloadEvents, PayloadKind, PayloadStoreExt, PayloadTypes, }; use std::{ fmt, future::Future, pin::Pin, + sync::Arc, task::{Context, Poll}, }; use tokio::sync::{ @@ -30,13 +31,14 @@ use tracing::{debug, info, trace, warn}; type PayloadFuture

= Pin> + Send + Sync>>; /// A communication channel to the [`PayloadBuilderService`] that can retrieve payloads. +/// +/// This type is intended to be used to retrieve payloads from the service (e.g. from the engine +/// API). #[derive(Debug)] pub struct PayloadStore { - inner: PayloadBuilderHandle, + inner: Arc>, } -// === impl PayloadStore === - impl PayloadStore where T: PayloadTypes, @@ -82,12 +84,16 @@ where } } -impl Clone for PayloadStore +impl PayloadStore where T: PayloadTypes, { - fn clone(&self) -> Self { - Self { inner: self.inner.clone() } + /// Create a new instance + pub fn new

(inner: P) -> Self + where + P: PayloadStoreExt + 'static, + { + Self { inner: Arc::new(inner) } } } @@ -96,7 +102,7 @@ where T: PayloadTypes, { fn from(inner: PayloadBuilderHandle) -> Self { - Self { inner } + Self::new(inner) } } diff --git a/crates/payload/primitives/src/lib.rs b/crates/payload/primitives/src/lib.rs index 7013d9fd913..3604ff5d8d8 100644 --- a/crates/payload/primitives/src/lib.rs +++ b/crates/payload/primitives/src/lib.rs @@ -20,7 +20,7 @@ pub use crate::events::{Events, PayloadEvents}; mod traits; pub use traits::{ BuiltPayload, PayloadAttributes, PayloadAttributesBuilder, PayloadBuilder, - PayloadBuilderAttributes, + PayloadBuilderAttributes, PayloadStoreExt, }; mod payload; diff --git a/crates/payload/primitives/src/traits.rs b/crates/payload/primitives/src/traits.rs index 86f04a5b550..197a7fe3af9 100644 --- a/crates/payload/primitives/src/traits.rs +++ b/crates/payload/primitives/src/traits.rs @@ -7,11 +7,12 @@ use alloy_primitives::{Address, B256, U256}; use alloy_rpc_types_engine::{PayloadAttributes as EthPayloadAttributes, PayloadId}; use reth_chain_state::ExecutedBlock; use reth_primitives::SealedBlock; +use std::fmt::Debug; use tokio::sync::oneshot; /// A type that can request, subscribe to and resolve payloads. #[async_trait::async_trait] -pub trait PayloadBuilder: Send + Sync + Unpin { +pub trait PayloadBuilder: Debug + Send + Sync + Unpin { /// The Payload type for the builder. type PayloadType: PayloadTypes; /// The error type returned by the builder. @@ -58,6 +59,63 @@ pub trait PayloadBuilder: Send + Sync + Unpin { ) -> Option::PayloadBuilderAttributes, Self::Error>>; } +/// A helper trait for internal usage to retrieve and resolve payloads. +#[async_trait::async_trait] +pub trait PayloadStoreExt: Debug + Send + Sync + Unpin { + /// Resolves the payload job and returns the best payload that has been built so far. + async fn resolve_kind( + &self, + id: PayloadId, + kind: PayloadKind, + ) -> Option>; + + /// Resolves the payload job as fast and possible and returns the best payload that has been + /// built so far. + async fn resolve(&self, id: PayloadId) -> Option> { + self.resolve_kind(id, PayloadKind::Earliest).await + } + + /// Returns the best payload for the given identifier. + async fn best_payload( + &self, + id: PayloadId, + ) -> Option>; + + /// Returns the payload attributes associated with the given identifier. + async fn payload_attributes( + &self, + id: PayloadId, + ) -> Option>; +} + +#[async_trait::async_trait] +impl PayloadStoreExt for P +where + P: PayloadBuilder, +{ + async fn resolve_kind( + &self, + id: PayloadId, + kind: PayloadKind, + ) -> Option> { + Some(PayloadBuilder::resolve_kind(self, id, kind).await?.map_err(Into::into)) + } + + async fn best_payload( + &self, + id: PayloadId, + ) -> Option> { + Some(PayloadBuilder::best_payload(self, id).await?.map_err(Into::into)) + } + + async fn payload_attributes( + &self, + id: PayloadId, + ) -> Option> { + Some(PayloadBuilder::payload_attributes(self, id).await?.map_err(Into::into)) + } +} + /// Represents a built payload type that contains a built [`SealedBlock`] and can be converted into /// engine API execution payloads. pub trait BuiltPayload: Send + Sync + std::fmt::Debug { From a620d7c2f1b23c26973b6b07946ea7571bfc2efa Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Tue, 12 Nov 2024 14:00:06 +0100 Subject: [PATCH 122/211] chore(deps): bump alloy to 0.6.3 (#12468) --- Cargo.lock | 182 ++++++++++++----------- Cargo.toml | 56 +++---- crates/primitives/src/transaction/mod.rs | 13 ++ 3 files changed, 137 insertions(+), 114 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bd3a93eda7a..798852f8061 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -91,9 +91,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.19" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611cc2ae7d2e242c457e4be7f97036b8ad9ca152b499f53faf99b1ed8fc2553f" +checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" [[package]] name = "alloy-chains" @@ -112,9 +112,9 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b19fd285b55dd39ae0dbc37481ad9f5f48898726f76335a2d6167a85a5fa41da" +checksum = "ef11c6b2dfbf77dca7bafc6759860391395f07c04d5486f2a2e2563d2961639b" dependencies = [ "alloy-eips", "alloy-primitives", @@ -131,9 +131,9 @@ dependencies = [ [[package]] name = "alloy-contract" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f42b1cb3fa8cba51b45795097a0d58a34569ca5db9eda48f63230e22fbc5cb5" +checksum = "8faa407ef916bfe0677c52c9b2258ce0698c53e9e15a837d1501e3ae9e57421a" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", @@ -198,9 +198,9 @@ dependencies = [ [[package]] name = "alloy-eips" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21aff0f2c921246398cad88e32a1d8ec14359b183afbc3dcb816873714cafc1a" +checksum = "33d6c0c1744a7af7d325dca6b5c5bb431a6307c0961088f7a236ca2694c4a87e" dependencies = [ "alloy-eip2930", "alloy-eip7702", @@ -219,9 +219,9 @@ dependencies = [ [[package]] name = "alloy-genesis" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76d899cfbfa13c5ed044383b7ae0e6a4d6ffcad3fd25e4acf71ff1c255ddae0" +checksum = "95a5a0a01ef6ec3cd3ebd52a7b3bc7f8a92b23e478e69c07abd94abf05e6b48e" dependencies = [ "alloy-primitives", "alloy-serde", @@ -242,9 +242,9 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e244937365749c09c403d3054de39cc7dd46e3c3a12e5b164106af4903011ab1" +checksum = "65fd0e2cff5ab68defc5050ff9e81cb053c5b52cf4809fc8786664898e29ae75" dependencies = [ "alloy-primitives", "alloy-sol-types", @@ -256,9 +256,9 @@ dependencies = [ [[package]] name = "alloy-network" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a28811461dc37e28db92b6d3a8c03a5883f2100b270a6294af00710bf4a0be4" +checksum = "96c9eca0c04ca8a663966ce7f5b19c03927f2b4d82910cb76cb4008490cfa838" dependencies = [ "alloy-consensus", "alloy-eips", @@ -279,9 +279,9 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e517c44a97e753f10dc0736215ba4677da5e2fbc1451e3e76902e02cd6cff12" +checksum = "e4c3050f19dc93a7f09fef670c8db04a15e7e2901494ca40decbce323be69643" dependencies = [ "alloy-consensus", "alloy-eips", @@ -292,9 +292,9 @@ dependencies = [ [[package]] name = "alloy-node-bindings" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15bf1a4b35b071c2d6f21fd3d32b8c5466cb7ed31fd4a4473a4e2ce180729121" +checksum = "b5ebd44d0ab30f1018dc1ff01686ea1a3ae732601841a4fb277c9d0b3a34bf50" dependencies = [ "alloy-genesis", "alloy-primitives", @@ -341,9 +341,9 @@ dependencies = [ [[package]] name = "alloy-provider" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56befb85784c7eb4f163b9aed7cdcaba09d5b07f8e59d6c12ad0ce1acf67c0fd" +checksum = "df8e5a28e7c4c04afc0f20b2aecf6f9214d6cfd5009187c0b8616a8f8918739c" dependencies = [ "alloy-chains", "alloy-consensus", @@ -382,9 +382,9 @@ dependencies = [ [[package]] name = "alloy-pubsub" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6480f9596064db2ca8e1a4b710ea9a4ef420534e68640296a461b71f6bfadc1" +checksum = "365dd813ec271a14febc31ea8ed64185856534f5644511f0c7a2961db060d878" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -423,9 +423,9 @@ dependencies = [ [[package]] name = "alloy-rpc-client" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb49d38b3279a07e864d973323534a2c4a845e16f2c0153a509a3abcc01da7b1" +checksum = "0336362936bb9fef88f27d51f2ede8c15cdfdb7f81b042e74257770052547101" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -448,9 +448,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90be9542c6c9bb0d21ac08104ca0a3d1fb83e56f1c704f5cdcf6fb9e01fcbd75" +checksum = "ac9a46bc01bc27dbf4dd27d46986eda661ffe99e78aea3078a77b8c064072b01" dependencies = [ "alloy-primitives", "alloy-rpc-types-engine", @@ -461,9 +461,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-admin" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "410e7b9d67489d19ad52439b940fbf482e0823190d8245242bfff1eec44290d5" +checksum = "82845a6f1ed33ef4edf79aa7cb091df31a532675921fb85041fbd8d6e029093d" dependencies = [ "alloy-genesis", "alloy-primitives", @@ -473,9 +473,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-anvil" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "951f9106bb02ad00a2dc2eb7b400041a2c073d7fb8f33e2f1f29b2f71564f3f7" +checksum = "0e73c06c3e44866d304fe28e8cebc8354f99fe405cc7c9bd23ed92eaebca3c07" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -485,9 +485,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-beacon" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dab9821d5a73f56512ddd8e3db89a5bbb285353129b271c4ad6803a37c4e00ce" +checksum = "2f9f6f071674c62424b62e22307aa83a35a0b1b84820649cc82034a50389ddc6" dependencies = [ "alloy-eips", "alloy-primitives", @@ -499,9 +499,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-debug" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebe68f35cafc465442862421ae2d123bb58c8df25f837d8866bf5fc278b74a52" +checksum = "63a857818fe47dacaa7cc7a9cdcfee212cf1ebf119ab7bd157065d434671892d" dependencies = [ "alloy-primitives", "serde", @@ -509,9 +509,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-engine" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ed9e7b3233cb3e0aaeaedc4e21e1ea9d99e947a7206241a9f9521c138193978" +checksum = "2ee44332315ef1adde384e44db3b5724d74d0cd0e0856a681c4db2b4da3a423e" dependencies = [ "alloy-consensus", "alloy-eips", @@ -530,9 +530,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be10f130b8be7c2351a3ea64b4bf07020fde5be8d1ac18db9a9a3496aa22bb19" +checksum = "d58fa055e02d04bc70443ecce984951fb5be02d2c843c640ca48237cdec66af1" dependencies = [ "alloy-consensus", "alloy-eips", @@ -551,9 +551,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-mev" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "110f7dbee6f047915eb8915751d96402f6d02cb6e5f64286f10949eaa5bed841" +checksum = "debf779b847b058b7c9cdef576f5ef539bc3032c5f6e5c1c2f51820b4f74e6d9" dependencies = [ "alloy-eips", "alloy-primitives", @@ -564,9 +564,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-trace" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f7f183d06db1457b58c6d618ff7ab92c97810138c148e09edb14ed2001069" +checksum = "1319edeae0e5f453424d658f8f450a5b1090b9ee6c0c014dc216b42f11c9dc57" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -578,9 +578,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-txpool" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f85580d4e78ffd765086ebf640004a773e3c335ebbfaa5666e13a0640c4957fe" +checksum = "5fcb4b823dcd7228a89be1be85a4fa8008ad6d91b169b61f75f36b6e7386f37b" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -590,9 +590,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1493df14770a23b1e32d22c66fa22508d09e0a99d6923a45f179ff7887ca0cef" +checksum = "feafd71e0e252b063fe4b07962beedf0445e66b07b4b44af178863d21e75b0fa" dependencies = [ "alloy-primitives", "arbitrary", @@ -602,9 +602,9 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebff64a3b4062eba217404700d1517b9bf3ff9a7a5b2dd03f1cf8aeec3e9a6b8" +checksum = "ebad84d52550351438ec7f151dbc551f870c31eecf23b473df5b779a91eee8ca" dependencies = [ "alloy-primitives", "async-trait", @@ -616,9 +616,9 @@ dependencies = [ [[package]] name = "alloy-signer-local" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc1f6602be452e3bb5b6c2fe0fa0f966465f9e9bfd6ad7691bfe1bd8b74bf432" +checksum = "ed742d76943b5ebaabfdf3d0d8b69a4377fc2981c7955a807e33a3469aed0cdc" dependencies = [ "alloy-consensus", "alloy-network", @@ -704,9 +704,9 @@ dependencies = [ [[package]] name = "alloy-transport" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64534da7f71ecca86b3449adec19b7942fb0905b9f392f60054a02a5f686f71f" +checksum = "da63700a2b3176b3009a6d3672d0c657280a517dcec7659c991c55e863a83165" dependencies = [ "alloy-json-rpc", "base64 0.22.1", @@ -724,9 +724,9 @@ dependencies = [ [[package]] name = "alloy-transport-http" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617b5ab96f4fb64ef697a84c68ec8534c062baafbdb0529c34aaee43324f0d5a" +checksum = "6613c3abc567b710217d241650ef73cfb8df9bcdc2ef23fdedabf363637e2a00" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -739,9 +739,9 @@ dependencies = [ [[package]] name = "alloy-transport-ipc" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10043df9ea36e3a38056cdfc3a70138343caef4eec6df66d6cbfdd348d245828" +checksum = "7087a28734aac88a606884cdde8c89ad053bd1c0580c787e31f917a8e4a7cbdd" dependencies = [ "alloy-json-rpc", "alloy-pubsub", @@ -758,9 +758,9 @@ dependencies = [ [[package]] name = "alloy-transport-ws" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a43ecdbc8f79cb5d7f54e2118626f873ded93c8c040fb714ce6be47dc5b526" +checksum = "672797b3f7bcbe67f712f9e8e5703b22f24594bd2b248a90916bdb58811b8b6e" dependencies = [ "alloy-pubsub", "alloy-transport", @@ -1530,7 +1530,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" dependencies = [ "memchr", - "regex-automata 0.4.8", + "regex-automata 0.4.9", "serde", ] @@ -1651,9 +1651,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.37" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf" +checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8" dependencies = [ "jobserver", "libc", @@ -1998,9 +1998,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6" dependencies = [ "libc", ] @@ -4111,6 +4111,12 @@ dependencies = [ "serde", ] +[[package]] +name = "indoc" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" + [[package]] name = "infer" version = "0.2.3" @@ -4167,10 +4173,14 @@ 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", + "indoc", + "pretty_assertions", + "proc-macro2", "quote", "syn 2.0.87", ] @@ -5287,9 +5297,9 @@ checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "op-alloy-consensus" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33097177de330b1a83e0a882ae752ad55f23962b1e310176d1623655c18421e" +checksum = "3b5745eca869a0b476fbd34025ac40c06a15c46ffc10d6b1c40d21475b05f835" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5305,9 +5315,9 @@ dependencies = [ [[package]] name = "op-alloy-genesis" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2232ff799352932fc5484e1c63ee7bb1e74a79ac7b94a4f7318560fba21167de" +checksum = "aa6b2f26a84984213bc12649dfd8466a46ddeede3b8d2d936583000a8362b117" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5319,9 +5329,9 @@ dependencies = [ [[package]] name = "op-alloy-network" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f1021b644a8f0bf8d7f878aa5328da67c7d697e476c8e097d09e05585067713" +checksum = "67085a07a35e71db0a95ac923a2de2c186a37c5f376a1e4dee19b5ef8a6ffcaa" dependencies = [ "alloy-consensus", "alloy-network", @@ -5334,9 +5344,9 @@ dependencies = [ [[package]] name = "op-alloy-protocol" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a566c421638a3b655a2aaf59fbbdee017a7dce6acfbacead219861e14654b98d" +checksum = "880331b1b7718236a016eb7ac5530abcf7d5ca8b7ad78ac6c3dc8f73826ce9ee" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5354,9 +5364,9 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72298f3f9084773dc3feaf88b08db82ceb3e3e13f98280459d869accb3f14234" +checksum = "69b75a52c8659756cfe1119f7711e94749c8dec6ad82408f3c55641ae413fb83" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5373,9 +5383,9 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types-engine" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2a270e6370a0fa8a673e29bcd436cbb67b5dc88cefc1d00fbf2382673894f71" +checksum = "622eabdff1739ef163aeb8e8385d5936fa54c14cfa55b06f72f1c8faa987f715" dependencies = [ "alloy-eips", "alloy-primitives", @@ -6225,7 +6235,7 @@ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.8", + "regex-automata 0.4.9", "regex-syntax 0.8.5", ] @@ -6240,9 +6250,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", @@ -9660,9 +9670,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.39" +version = "0.38.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375116bee2be9ed569afe2154ea6a99dfdffd257f533f187498c2a8f5feaf4ee" +checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" dependencies = [ "bitflags 2.6.0", "errno", @@ -9950,18 +9960,18 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 7608756b12a..b06380de8d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -431,40 +431,40 @@ alloy-rlp = "0.3.4" alloy-sol-types = "0.8.11" alloy-trie = { version = "0.7", default-features = false } -alloy-consensus = { version = "0.6.2", default-features = false } -alloy-contract = { version = "0.6.2", default-features = false } -alloy-eips = { version = "0.6.2", default-features = false } -alloy-genesis = { version = "0.6.2", default-features = false } -alloy-json-rpc = { version = "0.6.2", default-features = false } -alloy-network = { version = "0.6.2", default-features = false } -alloy-network-primitives = { version = "0.6.2", default-features = false } -alloy-node-bindings = { version = "0.6.2", default-features = false } -alloy-provider = { version = "0.6.2", features = [ +alloy-consensus = { version = "0.6.3", default-features = false } +alloy-contract = { version = "0.6.3", default-features = false } +alloy-eips = { version = "0.6.3", default-features = false } +alloy-genesis = { version = "0.6.3", default-features = false } +alloy-json-rpc = { version = "0.6.3", default-features = false } +alloy-network = { version = "0.6.3", default-features = false } +alloy-network-primitives = { version = "0.6.3", default-features = false } +alloy-node-bindings = { version = "0.6.3", default-features = false } +alloy-provider = { version = "0.6.3", features = [ "reqwest", ], default-features = false } -alloy-pubsub = { version = "0.6.2", default-features = false } -alloy-rpc-client = { version = "0.6.2", default-features = false } -alloy-rpc-types = { version = "0.6.2", features = [ +alloy-pubsub = { version = "0.6.3", default-features = false } +alloy-rpc-client = { version = "0.6.3", default-features = false } +alloy-rpc-types = { version = "0.6.3", features = [ "eth", ], default-features = false } -alloy-rpc-types-admin = { version = "0.6.2", default-features = false } -alloy-rpc-types-anvil = { version = "0.6.2", default-features = false } -alloy-rpc-types-beacon = { version = "0.6.2", default-features = false } -alloy-rpc-types-debug = { version = "0.6.2", default-features = false } -alloy-rpc-types-engine = { version = "0.6.2", default-features = false } -alloy-rpc-types-eth = { version = "0.6.2", default-features = false } -alloy-rpc-types-mev = { version = "0.6.2", default-features = false } -alloy-rpc-types-trace = { version = "0.6.2", default-features = false } -alloy-rpc-types-txpool = { version = "0.6.2", default-features = false } -alloy-serde = { version = "0.6.2", default-features = false } -alloy-signer = { version = "0.6.2", default-features = false } -alloy-signer-local = { version = "0.6.2", default-features = false } -alloy-transport = { version = "0.6.2" } -alloy-transport-http = { version = "0.6.2", features = [ +alloy-rpc-types-admin = { version = "0.6.3", default-features = false } +alloy-rpc-types-anvil = { version = "0.6.3", default-features = false } +alloy-rpc-types-beacon = { version = "0.6.3", default-features = false } +alloy-rpc-types-debug = { version = "0.6.3", default-features = false } +alloy-rpc-types-engine = { version = "0.6.3", default-features = false } +alloy-rpc-types-eth = { version = "0.6.3", default-features = false } +alloy-rpc-types-mev = { version = "0.6.3", default-features = false } +alloy-rpc-types-trace = { version = "0.6.3", default-features = false } +alloy-rpc-types-txpool = { version = "0.6.3", default-features = false } +alloy-serde = { version = "0.6.3", default-features = false } +alloy-signer = { version = "0.6.3", default-features = false } +alloy-signer-local = { version = "0.6.3", default-features = false } +alloy-transport = { version = "0.6.3" } +alloy-transport-http = { version = "0.6.3", features = [ "reqwest-rustls-tls", ], default-features = false } -alloy-transport-ipc = { version = "0.6.2", default-features = false } -alloy-transport-ws = { version = "0.6.2", default-features = false } +alloy-transport-ipc = { version = "0.6.3", default-features = false } +alloy-transport-ws = { version = "0.6.3", default-features = false } # op op-alloy-rpc-types = "0.6.3" diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index 485de92ea89..366f59696b2 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -751,6 +751,15 @@ impl alloy_consensus::Transaction for Transaction { } } + fn is_dynamic_fee(&self) -> bool { + match self { + Self::Legacy(_) | Self::Eip2930(_) => false, + Self::Eip1559(_) | Self::Eip4844(_) | Self::Eip7702(_) => true, + #[cfg(feature = "optimism")] + Self::Deposit(_) => false, + } + } + fn value(&self) -> U256 { match self { Self::Legacy(tx) => tx.value(), @@ -1444,6 +1453,10 @@ impl alloy_consensus::Transaction for TransactionSigned { self.deref().priority_fee_or_price() } + fn is_dynamic_fee(&self) -> bool { + self.deref().is_dynamic_fee() + } + fn value(&self) -> U256 { self.deref().value() } From 3a337cd7d4ad8c14569d20141fdcc2b1c54dbdf3 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Tue, 12 Nov 2024 15:04:07 +0100 Subject: [PATCH 123/211] chore(deps): Update op-alloy to 0.6.4 in manifest (#12472) --- Cargo.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b06380de8d7..cd7054ea1e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -467,10 +467,10 @@ alloy-transport-ipc = { version = "0.6.3", default-features = false } alloy-transport-ws = { version = "0.6.3", default-features = false } # op -op-alloy-rpc-types = "0.6.3" -op-alloy-rpc-types-engine = "0.6.3" -op-alloy-network = "0.6.3" -op-alloy-consensus = "0.6.3" +op-alloy-rpc-types = "0.6.4" +op-alloy-rpc-types-engine = "0.6.4" +op-alloy-network = "0.6.4" +op-alloy-consensus = "0.6.4" # misc aquamarine = "0.6" From aece53ae88990bb8d0849b60e9649f68781dd03e Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Tue, 12 Nov 2024 19:13:21 +0400 Subject: [PATCH 124/211] feat: make downloaders and clients generic over block parts (#12469) Co-authored-by: Matthias Seitz --- Cargo.lock | 6 +- bin/reth/Cargo.toml | 1 + bin/reth/src/commands/debug_cmd/execution.rs | 11 +- .../commands/debug_cmd/in_memory_merkle.rs | 4 +- crates/consensus/beacon/src/engine/mod.rs | 8 +- crates/consensus/beacon/src/engine/sync.rs | 8 +- .../consensus/beacon/src/engine/test_utils.rs | 12 +- crates/engine/service/src/service.rs | 8 +- crates/engine/tree/src/download.rs | 12 +- crates/net/downloaders/Cargo.toml | 1 + crates/net/downloaders/src/bodies/bodies.rs | 48 +++--- crates/net/downloaders/src/bodies/noop.rs | 5 +- crates/net/downloaders/src/bodies/queue.rs | 7 +- crates/net/downloaders/src/bodies/request.rs | 20 ++- crates/net/downloaders/src/bodies/task.rs | 30 ++-- crates/net/downloaders/src/file_client.rs | 2 + crates/net/downloaders/src/headers/noop.rs | 5 +- .../src/headers/reverse_headers.rs | 161 ++++++++++-------- crates/net/downloaders/src/headers/task.rs | 40 +++-- .../src/test_utils/bodies_client.rs | 1 + crates/net/eth-wire-types/Cargo.toml | 1 + crates/net/eth-wire-types/src/message.rs | 2 +- crates/net/eth-wire-types/src/primitives.rs | 4 +- crates/net/eth-wire/src/capability.rs | 11 +- crates/net/eth-wire/src/ethstream.rs | 102 ++++++----- crates/net/eth-wire/src/multiplex.rs | 16 +- crates/net/network-api/src/downloaders.rs | 7 +- crates/net/network-api/src/events.rs | 69 ++++++-- crates/net/network-api/src/lib.rs | 5 +- crates/net/network/Cargo.toml | 1 + crates/net/network/src/fetch/client.rs | 18 +- crates/net/network/src/fetch/mod.rs | 54 +++--- crates/net/network/src/message.rs | 27 +-- crates/net/network/src/network.rs | 9 +- crates/net/network/src/state.rs | 29 ++-- crates/net/p2p/Cargo.toml | 4 +- crates/net/p2p/src/bodies/client.rs | 13 +- crates/net/p2p/src/bodies/downloader.rs | 9 +- crates/net/p2p/src/bodies/response.rs | 11 +- crates/net/p2p/src/either.rs | 6 +- crates/net/p2p/src/error.rs | 9 +- crates/net/p2p/src/full_block.rs | 92 +++++----- crates/net/p2p/src/headers/client.rs | 10 +- crates/net/p2p/src/headers/downloader.rs | 25 ++- crates/net/p2p/src/headers/error.rs | 8 +- crates/net/p2p/src/lib.rs | 11 ++ crates/net/p2p/src/test_utils/bodies.rs | 1 + crates/net/p2p/src/test_utils/full_block.rs | 4 + crates/net/p2p/src/test_utils/headers.rs | 5 +- crates/node/builder/src/launch/common.rs | 2 +- crates/node/builder/src/setup.rs | 8 +- crates/node/core/Cargo.toml | 3 +- crates/node/core/src/node_config.rs | 11 +- crates/node/core/src/utils.rs | 21 ++- crates/primitives-traits/src/block/header.rs | 6 +- crates/primitives-traits/src/header/sealed.rs | 4 +- crates/primitives-traits/src/size.rs | 6 + crates/primitives/src/block.rs | 3 +- crates/stages/stages/src/stages/bodies.rs | 9 +- crates/stages/stages/src/stages/headers.rs | 14 +- 60 files changed, 631 insertions(+), 409 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 798852f8061..4792cb094de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6391,6 +6391,7 @@ dependencies = [ "reth-payload-primitives", "reth-payload-validator", "reth-primitives", + "reth-primitives-traits", "reth-provider", "reth-prune", "reth-revm", @@ -7029,6 +7030,7 @@ dependencies = [ name = "reth-downloaders" version = "1.1.1" dependencies = [ + "alloy-consensus", "alloy-eips", "alloy-primitives", "alloy-rlp", @@ -7829,6 +7831,7 @@ dependencies = [ name = "reth-network-p2p" version = "1.1.1" dependencies = [ + "alloy-consensus", "alloy-eips", "alloy-primitives", "auto_impl", @@ -7997,7 +8000,7 @@ dependencies = [ "reth-chainspec", "reth-cli-util", "reth-config", - "reth-consensus-common", + "reth-consensus", "reth-db", "reth-discv4", "reth-discv5", @@ -8006,6 +8009,7 @@ dependencies = [ "reth-network-p2p", "reth-network-peers", "reth-primitives", + "reth-primitives-traits", "reth-prune-types", "reth-rpc-eth-types", "reth-rpc-server-types", diff --git a/bin/reth/Cargo.toml b/bin/reth/Cargo.toml index ffd1998b24e..a152bea2681 100644 --- a/bin/reth/Cargo.toml +++ b/bin/reth/Cargo.toml @@ -19,6 +19,7 @@ reth-ethereum-cli.workspace = true reth-chainspec.workspace = true reth-config.workspace = true reth-primitives.workspace = true +reth-primitives-traits.workspace = true reth-fs-util.workspace = true reth-db = { workspace = true, features = ["mdbx"] } reth-db-api.workspace = true diff --git a/bin/reth/src/commands/debug_cmd/execution.rs b/bin/reth/src/commands/debug_cmd/execution.rs index cc584c89287..9056d3424c7 100644 --- a/bin/reth/src/commands/debug_cmd/execution.rs +++ b/bin/reth/src/commands/debug_cmd/execution.rs @@ -21,7 +21,7 @@ use reth_downloaders::{ use reth_exex::ExExManagerHandle; use reth_network::{BlockDownloaderProvider, NetworkEventListenerProvider, NetworkHandle}; use reth_network_api::NetworkInfo; -use reth_network_p2p::{headers::client::HeadersClient, BlockClient}; +use reth_network_p2p::{headers::client::HeadersClient, EthBlockClient}; use reth_node_api::{NodeTypesWithDB, NodeTypesWithDBAdapter, NodeTypesWithEngine}; use reth_node_ethereum::EthExecutorProvider; use reth_provider::{ @@ -68,7 +68,7 @@ impl> Command { static_file_producer: StaticFileProducer>, ) -> eyre::Result> where - Client: BlockClient + 'static, + Client: EthBlockClient + 'static, { // building network downloaders using the fetch client let header_downloader = ReverseHeadersDownloaderBuilder::new(config.stages.headers) @@ -137,11 +137,14 @@ impl> Command { Ok(network) } - async fn fetch_block_hash( + async fn fetch_block_hash( &self, client: Client, block: BlockNumber, - ) -> eyre::Result { + ) -> eyre::Result + where + Client: HeadersClient, + { info!(target: "reth::cli", ?block, "Fetching block from the network."); loop { match get_single_header(&client, BlockHashOrNumber::Number(block)).await { diff --git a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs index 2c56da9b4cf..bc36578a327 100644 --- a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs +++ b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs @@ -7,6 +7,7 @@ use crate::{ use alloy_eips::BlockHashOrNumber; use backon::{ConstantBuilder, Retryable}; use clap::Parser; +use reth_beacon_consensus::EthBeaconConsensus; use reth_chainspec::ChainSpec; use reth_cli::chainspec::ChainSpecParser; use reth_cli_commands::common::{AccessRights, Environment, EnvironmentArgs}; @@ -124,7 +125,8 @@ impl> Command { let client = fetch_client.clone(); let chain = provider_factory.chain_spec(); - let block = (move || get_single_body(client.clone(), Arc::clone(&chain), header.clone())) + let consensus = Arc::new(EthBeaconConsensus::new(chain.clone())); + let block = (move || get_single_body(client.clone(), header.clone(), consensus.clone())) .retry(backoff) .notify( |err, _| warn!(target: "reth::cli", "Error requesting body: {err}. Retrying..."), diff --git a/crates/consensus/beacon/src/engine/mod.rs b/crates/consensus/beacon/src/engine/mod.rs index 65904196e1c..8d385a64b8e 100644 --- a/crates/consensus/beacon/src/engine/mod.rs +++ b/crates/consensus/beacon/src/engine/mod.rs @@ -14,7 +14,7 @@ use reth_engine_primitives::{EngineApiMessageVersion, EngineTypes, PayloadTypes} use reth_errors::{BlockValidationError, ProviderResult, RethError, RethResult}; use reth_network_p2p::{ sync::{NetworkSyncUpdater, SyncState}, - BlockClient, + EthBlockClient, }; use reth_node_types::NodeTypesWithEngine; use reth_payload_builder::PayloadBuilderHandle; @@ -174,7 +174,7 @@ type PendingForkchoiceUpdate = pub struct BeaconConsensusEngine where N: EngineNodeTypes, - Client: BlockClient, + Client: EthBlockClient, BT: BlockchainTreeEngine + BlockReader + BlockIdReader @@ -237,7 +237,7 @@ where + StageCheckpointReader + ChainSpecProvider + 'static, - Client: BlockClient + 'static, + Client: EthBlockClient + 'static, { /// Create a new instance of the [`BeaconConsensusEngine`]. #[allow(clippy::too_many_arguments)] @@ -1799,7 +1799,7 @@ where impl Future for BeaconConsensusEngine where N: EngineNodeTypes, - Client: BlockClient + 'static, + Client: EthBlockClient + 'static, BT: BlockchainTreeEngine + BlockReader + BlockIdReader diff --git a/crates/consensus/beacon/src/engine/sync.rs b/crates/consensus/beacon/src/engine/sync.rs index 9426ca19712..17d5d2281a3 100644 --- a/crates/consensus/beacon/src/engine/sync.rs +++ b/crates/consensus/beacon/src/engine/sync.rs @@ -8,7 +8,7 @@ use alloy_primitives::{BlockNumber, B256}; use futures::FutureExt; use reth_network_p2p::{ full_block::{FetchFullBlockFuture, FetchFullBlockRangeFuture, FullBlockClient}, - BlockClient, + EthBlockClient, }; use reth_primitives::SealedBlock; use reth_provider::providers::ProviderNodeTypes; @@ -34,7 +34,7 @@ use tracing::trace; pub(crate) struct EngineSyncController where N: ProviderNodeTypes, - Client: BlockClient, + Client: EthBlockClient, { /// A downloader that can download full blocks from the network. full_block_client: FullBlockClient, @@ -64,7 +64,7 @@ where impl EngineSyncController where N: ProviderNodeTypes, - Client: BlockClient + 'static, + Client: EthBlockClient + 'static, { /// Create a new instance pub(crate) fn new( @@ -522,7 +522,7 @@ mod tests { ) -> EngineSyncController> where N: ProviderNodeTypes, - Client: BlockClient + 'static, + Client: EthBlockClient + 'static, { let client = self .client diff --git a/crates/consensus/beacon/src/engine/test_utils.rs b/crates/consensus/beacon/src/engine/test_utils.rs index 6e03aebfa8d..3c69e7f55c3 100644 --- a/crates/consensus/beacon/src/engine/test_utils.rs +++ b/crates/consensus/beacon/src/engine/test_utils.rs @@ -24,7 +24,9 @@ use reth_ethereum_engine_primitives::EthEngineTypes; use reth_evm::{either::Either, test_utils::MockExecutorProvider}; use reth_evm_ethereum::execute::EthExecutorProvider; use reth_exex_types::FinishedExExHeight; -use reth_network_p2p::{sync::NoopSyncStateUpdater, test_utils::NoopFullBlockClient, BlockClient}; +use reth_network_p2p::{ + sync::NoopSyncStateUpdater, test_utils::NoopFullBlockClient, EthBlockClient, +}; use reth_payload_builder::test_utils::spawn_test_payload_service; use reth_primitives::SealedHeader; use reth_provider::{ @@ -237,7 +239,7 @@ impl TestConsensusEngineBuilder { client: Client, ) -> NetworkedTestConsensusEngineBuilder where - Client: BlockClient + 'static, + Client: EthBlockClient + 'static, { NetworkedTestConsensusEngineBuilder { base_config: self, client: Some(client) } } @@ -264,7 +266,7 @@ pub struct NetworkedTestConsensusEngineBuilder { impl NetworkedTestConsensusEngineBuilder where - Client: BlockClient + 'static, + Client: EthBlockClient + 'static, { /// Set the pipeline execution outputs to use for the test consensus engine. #[allow(dead_code)] @@ -319,7 +321,7 @@ where client: ClientType, ) -> NetworkedTestConsensusEngineBuilder where - ClientType: BlockClient + 'static, + ClientType: EthBlockClient + 'static, { NetworkedTestConsensusEngineBuilder { base_config: self.base_config, client: Some(client) } } @@ -450,7 +452,7 @@ pub fn spawn_consensus_engine( engine: TestBeaconConsensusEngine, ) -> oneshot::Receiver> where - Client: BlockClient + 'static, + Client: EthBlockClient + 'static, { let (tx, rx) = oneshot::channel(); tokio::spawn(async move { diff --git a/crates/engine/service/src/service.rs b/crates/engine/service/src/service.rs index 198438d457f..d383af6caa6 100644 --- a/crates/engine/service/src/service.rs +++ b/crates/engine/service/src/service.rs @@ -15,7 +15,7 @@ pub use reth_engine_tree::{ engine::EngineApiEvent, }; use reth_evm::execute::BlockExecutorProvider; -use reth_network_p2p::BlockClient; +use reth_network_p2p::EthBlockClient; use reth_node_types::NodeTypesWithEngine; use reth_payload_builder::PayloadBuilderHandle; use reth_payload_validator::ExecutionPayloadValidator; @@ -49,7 +49,7 @@ type EngineServiceType = ChainOrchestrator< pub struct EngineService where N: EngineNodeTypes, - Client: BlockClient + 'static, + Client: EthBlockClient + 'static, E: BlockExecutorProvider + 'static, { orchestrator: EngineServiceType, @@ -59,7 +59,7 @@ where impl EngineService where N: EngineNodeTypes, - Client: BlockClient + 'static, + Client: EthBlockClient + 'static, E: BlockExecutorProvider + 'static, { /// Constructor for `EngineService`. @@ -124,7 +124,7 @@ where impl Stream for EngineService where N: EngineNodeTypes, - Client: BlockClient + 'static, + Client: EthBlockClient + 'static, E: BlockExecutorProvider + 'static, { type Item = ChainEvent; diff --git a/crates/engine/tree/src/download.rs b/crates/engine/tree/src/download.rs index 9ecec70ae36..667808a4d62 100644 --- a/crates/engine/tree/src/download.rs +++ b/crates/engine/tree/src/download.rs @@ -6,12 +6,13 @@ use futures::FutureExt; use reth_consensus::Consensus; use reth_network_p2p::{ full_block::{FetchFullBlockFuture, FetchFullBlockRangeFuture, FullBlockClient}, - BlockClient, + BlockClient, EthBlockClient, }; use reth_primitives::{SealedBlock, SealedBlockWithSenders}; use std::{ cmp::{Ordering, Reverse}, collections::{binary_heap::PeekMut, BinaryHeap, HashSet, VecDeque}, + fmt::Debug, sync::Arc, task::{Context, Poll}, }; @@ -72,10 +73,13 @@ where impl BasicBlockDownloader where - Client: BlockClient + 'static, + Client: EthBlockClient + 'static, { /// Create a new instance - pub fn new(client: Client, consensus: Arc) -> Self { + pub fn new( + client: Client, + consensus: Arc>, + ) -> Self { Self { full_block_client: FullBlockClient::new(client, consensus), inflight_full_block_requests: Vec::new(), @@ -182,7 +186,7 @@ where impl BlockDownloader for BasicBlockDownloader where - Client: BlockClient + 'static, + Client: EthBlockClient, { /// Handles incoming download actions. fn on_action(&mut self, action: DownloadAction) { diff --git a/crates/net/downloaders/Cargo.toml b/crates/net/downloaders/Cargo.toml index 69a59f698de..38e46bb6011 100644 --- a/crates/net/downloaders/Cargo.toml +++ b/crates/net/downloaders/Cargo.toml @@ -28,6 +28,7 @@ reth-db-api = { workspace = true, optional = true } reth-testing-utils = { workspace = true, optional = true } # ethereum +alloy-consensus.workspace = true alloy-eips.workspace = true alloy-primitives.workspace = true alloy-rlp.workspace = true diff --git a/crates/net/downloaders/src/bodies/bodies.rs b/crates/net/downloaders/src/bodies/bodies.rs index af113fdb38b..02a36c8e8cd 100644 --- a/crates/net/downloaders/src/bodies/bodies.rs +++ b/crates/net/downloaders/src/bodies/bodies.rs @@ -37,7 +37,7 @@ pub struct BodiesDownloader { /// The bodies client client: Arc, /// The consensus client - consensus: Arc, + consensus: Arc>, /// The database handle provider: Provider, /// The maximum number of non-empty blocks per one request @@ -57,16 +57,16 @@ pub struct BodiesDownloader { /// Requests in progress in_progress_queue: BodiesRequestQueue, /// Buffered responses - buffered_responses: BinaryHeap, + buffered_responses: BinaryHeap>, /// Queued body responses that can be returned for insertion into the database. - queued_bodies: Vec, + queued_bodies: Vec>, /// The bodies downloader metrics. metrics: BodyDownloaderMetrics, } impl BodiesDownloader where - B: BodiesClient + 'static, + B: BodiesClient + 'static, Provider: HeaderProvider + Unpin + 'static, { /// Returns the next contiguous request. @@ -191,14 +191,14 @@ where } /// Queues bodies and sets the latest queued block number - fn queue_bodies(&mut self, bodies: Vec) { + fn queue_bodies(&mut self, bodies: Vec>) { self.latest_queued_block_number = Some(bodies.last().expect("is not empty").block_number()); self.queued_bodies.extend(bodies); self.metrics.queued_blocks.set(self.queued_bodies.len() as f64); } /// Removes the next response from the buffer. - fn pop_buffered_response(&mut self) -> Option { + fn pop_buffered_response(&mut self) -> Option> { let resp = self.buffered_responses.pop()?; self.metrics.buffered_responses.decrement(1.); self.buffered_blocks_size_bytes -= resp.size(); @@ -208,10 +208,10 @@ where } /// Adds a new response to the internal buffer - fn buffer_bodies_response(&mut self, response: Vec) { + fn buffer_bodies_response(&mut self, response: Vec>) { // take into account capacity let size = response.iter().map(BlockResponse::size).sum::() + - response.capacity() * mem::size_of::(); + response.capacity() * mem::size_of::>(); let response = OrderedBodiesResponse { resp: response, size }; let response_len = response.len(); @@ -225,7 +225,7 @@ where } /// Returns a response if it's first block number matches the next expected. - fn try_next_buffered(&mut self) -> Option> { + fn try_next_buffered(&mut self) -> Option>> { if let Some(next) = self.buffered_responses.peek() { let expected = self.next_expected_block_number(); let next_block_range = next.block_range(); @@ -251,7 +251,7 @@ where /// Returns the next batch of block bodies that can be returned if we have enough buffered /// bodies - fn try_split_next_batch(&mut self) -> Option> { + fn try_split_next_batch(&mut self) -> Option>> { if self.queued_bodies.len() >= self.stream_batch_size { let next_batch = self.queued_bodies.drain(..self.stream_batch_size).collect::>(); self.queued_bodies.shrink_to_fit(); @@ -283,12 +283,12 @@ where Self: BodyDownloader + 'static, { /// Spawns the downloader task via [`tokio::task::spawn`] - pub fn into_task(self) -> TaskDownloader { + pub fn into_task(self) -> TaskDownloader<::Body> { self.into_task_with(&TokioTaskExecutor::default()) } /// Convert the downloader into a [`TaskDownloader`] by spawning it via the given spawner. - pub fn into_task_with(self, spawner: &S) -> TaskDownloader + pub fn into_task_with(self, spawner: &S) -> TaskDownloader<::Body> where S: TaskSpawner, { @@ -298,9 +298,11 @@ where impl BodyDownloader for BodiesDownloader where - B: BodiesClient + 'static, + B: BodiesClient + 'static, Provider: HeaderProvider + Unpin + 'static, { + type Body = B::Body; + /// Set a new download range (exclusive). /// /// This method will drain all queued bodies, filter out ones outside the range and put them @@ -346,10 +348,10 @@ where impl Stream for BodiesDownloader where - B: BodiesClient + 'static, + B: BodiesClient + 'static, Provider: HeaderProvider + Unpin + 'static, { - type Item = BodyDownloaderResult; + type Item = BodyDownloaderResult; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.get_mut(); @@ -431,13 +433,13 @@ where } #[derive(Debug)] -struct OrderedBodiesResponse { - resp: Vec, +struct OrderedBodiesResponse { + resp: Vec>, /// The total size of the response in bytes size: usize, } -impl OrderedBodiesResponse { +impl OrderedBodiesResponse { /// Returns the block number of the first element /// /// # Panics @@ -468,21 +470,21 @@ impl OrderedBodiesResponse { } } -impl PartialEq for OrderedBodiesResponse { +impl PartialEq for OrderedBodiesResponse { fn eq(&self, other: &Self) -> bool { self.first_block_number() == other.first_block_number() } } -impl Eq for OrderedBodiesResponse {} +impl Eq for OrderedBodiesResponse {} -impl PartialOrd for OrderedBodiesResponse { +impl PartialOrd for OrderedBodiesResponse { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl Ord for OrderedBodiesResponse { +impl Ord for OrderedBodiesResponse { fn cmp(&self, other: &Self) -> Ordering { self.first_block_number().cmp(&other.first_block_number()).reverse() } @@ -562,7 +564,7 @@ impl BodiesDownloaderBuilder { pub fn build( self, client: B, - consensus: Arc, + consensus: Arc>, provider: Provider, ) -> BodiesDownloader where diff --git a/crates/net/downloaders/src/bodies/noop.rs b/crates/net/downloaders/src/bodies/noop.rs index e70c534a0e3..494a5f2ef2e 100644 --- a/crates/net/downloaders/src/bodies/noop.rs +++ b/crates/net/downloaders/src/bodies/noop.rs @@ -4,6 +4,7 @@ use reth_network_p2p::{ bodies::{downloader::BodyDownloader, response::BlockResponse}, error::{DownloadError, DownloadResult}, }; +use reth_primitives::BlockBody; use std::ops::RangeInclusive; /// A [`BodyDownloader`] implementation that does nothing. @@ -12,13 +13,15 @@ use std::ops::RangeInclusive; pub struct NoopBodiesDownloader; impl BodyDownloader for NoopBodiesDownloader { + type Body = BlockBody; + fn set_download_range(&mut self, _: RangeInclusive) -> DownloadResult<()> { Ok(()) } } impl Stream for NoopBodiesDownloader { - type Item = Result, DownloadError>; + type Item = Result>, DownloadError>; fn poll_next( self: std::pin::Pin<&mut Self>, diff --git a/crates/net/downloaders/src/bodies/queue.rs b/crates/net/downloaders/src/bodies/queue.rs index db7ff71cfc9..54404d0da38 100644 --- a/crates/net/downloaders/src/bodies/queue.rs +++ b/crates/net/downloaders/src/bodies/queue.rs @@ -9,6 +9,7 @@ use reth_network_p2p::{ error::DownloadResult, }; use reth_primitives::SealedHeader; +use reth_primitives_traits::InMemorySize; use std::{ pin::Pin, sync::Arc, @@ -57,7 +58,7 @@ where pub(crate) fn push_new_request( &mut self, client: Arc, - consensus: Arc, + consensus: Arc>, request: Vec, ) { // Set last max requested block number @@ -77,9 +78,9 @@ where impl Stream for BodiesRequestQueue where - B: BodiesClient + 'static, + B: BodiesClient + 'static, { - type Item = DownloadResult>; + type Item = DownloadResult>>; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.get_mut().inner.poll_next_unpin(cx) diff --git a/crates/net/downloaders/src/bodies/request.rs b/crates/net/downloaders/src/bodies/request.rs index 5ab44ed0811..7b99c81d89e 100644 --- a/crates/net/downloaders/src/bodies/request.rs +++ b/crates/net/downloaders/src/bodies/request.rs @@ -39,7 +39,7 @@ use std::{ /// and eventually disconnected. pub(crate) struct BodiesRequestFuture { client: Arc, - consensus: Arc, + consensus: Arc>, metrics: BodyDownloaderMetrics, /// Metrics for individual responses. This can be used to observe how the size (in bytes) of /// responses change while bodies are being downloaded. @@ -47,7 +47,7 @@ pub(crate) struct BodiesRequestFuture { // Headers to download. The collection is shrunk as responses are buffered. pending_headers: VecDeque, /// Internal buffer for all blocks - buffer: Vec, + buffer: Vec>, fut: Option, /// Tracks how many bodies we requested in the last request. last_request_len: Option, @@ -60,7 +60,7 @@ where /// Returns an empty future. Use [`BodiesRequestFuture::with_headers`] to set the request. pub(crate) fn new( client: Arc, - consensus: Arc, + consensus: Arc>, metrics: BodyDownloaderMetrics, ) -> Self { Self { @@ -115,7 +115,10 @@ where /// Process block response. /// Returns an error if the response is invalid. - fn on_block_response(&mut self, response: WithPeerId>) -> DownloadResult<()> { + fn on_block_response(&mut self, response: WithPeerId>) -> DownloadResult<()> + where + B::Body: InMemorySize, + { let (peer_id, bodies) = response.split(); let request_len = self.last_request_len.unwrap_or_default(); let response_len = bodies.len(); @@ -158,7 +161,10 @@ where /// /// This method removes headers from the internal collection. /// If the response fails validation, then the header will be put back. - fn try_buffer_blocks(&mut self, bodies: Vec) -> DownloadResult<()> { + fn try_buffer_blocks(&mut self, bodies: Vec) -> DownloadResult<()> + where + B::Body: InMemorySize, + { let bodies_capacity = bodies.capacity(); let bodies_len = bodies.len(); let mut bodies = bodies.into_iter().peekable(); @@ -208,9 +214,9 @@ where impl Future for BodiesRequestFuture where - B: BodiesClient + 'static, + B: BodiesClient + 'static, { - type Output = DownloadResult>; + type Output = DownloadResult>>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.get_mut(); diff --git a/crates/net/downloaders/src/bodies/task.rs b/crates/net/downloaders/src/bodies/task.rs index eeafb7ab121..2caf3199188 100644 --- a/crates/net/downloaders/src/bodies/task.rs +++ b/crates/net/downloaders/src/bodies/task.rs @@ -23,15 +23,15 @@ pub const BODIES_TASK_BUFFER_SIZE: usize = 4; /// A [BodyDownloader] that drives a spawned [BodyDownloader] on a spawned task. #[derive(Debug)] #[pin_project] -pub struct TaskDownloader { +pub struct TaskDownloader { #[pin] - from_downloader: ReceiverStream, + from_downloader: ReceiverStream>, to_downloader: UnboundedSender>, } // === impl TaskDownloader === -impl TaskDownloader { +impl TaskDownloader { /// Spawns the given `downloader` via [`tokio::task::spawn`] returns a [`TaskDownloader`] that's /// connected to that task. /// @@ -45,12 +45,16 @@ impl TaskDownloader { /// use reth_consensus::Consensus; /// use reth_downloaders::bodies::{bodies::BodiesDownloaderBuilder, task::TaskDownloader}; /// use reth_network_p2p::bodies::client::BodiesClient; + /// use reth_primitives_traits::InMemorySize; /// use reth_storage_api::HeaderProvider; /// use std::sync::Arc; /// - /// fn t( + /// fn t< + /// B: BodiesClient + 'static, + /// Provider: HeaderProvider + Unpin + 'static, + /// >( /// client: Arc, - /// consensus: Arc, + /// consensus: Arc>, /// provider: Provider, /// ) { /// let downloader = BodiesDownloaderBuilder::default().build(client, consensus, provider); @@ -59,7 +63,7 @@ impl TaskDownloader { /// ``` pub fn spawn(downloader: T) -> Self where - T: BodyDownloader + 'static, + T: BodyDownloader + 'static, { Self::spawn_with(downloader, &TokioTaskExecutor::default()) } @@ -68,7 +72,7 @@ impl TaskDownloader { /// that's connected to that task. pub fn spawn_with(downloader: T, spawner: &S) -> Self where - T: BodyDownloader + 'static, + T: BodyDownloader + 'static, S: TaskSpawner, { let (bodies_tx, bodies_rx) = mpsc::channel(BODIES_TASK_BUFFER_SIZE); @@ -86,15 +90,17 @@ impl TaskDownloader { } } -impl BodyDownloader for TaskDownloader { +impl BodyDownloader for TaskDownloader { + type Body = B; + fn set_download_range(&mut self, range: RangeInclusive) -> DownloadResult<()> { let _ = self.to_downloader.send(range); Ok(()) } } -impl Stream for TaskDownloader { - type Item = BodyDownloaderResult; +impl Stream for TaskDownloader { + type Item = BodyDownloaderResult; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.project().from_downloader.poll_next(cx) @@ -102,9 +108,9 @@ impl Stream for TaskDownloader { } /// A [`BodyDownloader`] that runs on its own task -struct SpawnedDownloader { +struct SpawnedDownloader { updates: UnboundedReceiverStream>, - bodies_tx: PollSender, + bodies_tx: PollSender>, downloader: T, } diff --git a/crates/net/downloaders/src/file_client.rs b/crates/net/downloaders/src/file_client.rs index 5b21c82fb3f..df35146e940 100644 --- a/crates/net/downloaders/src/file_client.rs +++ b/crates/net/downloaders/src/file_client.rs @@ -265,6 +265,7 @@ impl FromReader for FileClient { } impl HeadersClient for FileClient { + type Header = Header; type Output = HeadersFut; fn get_headers_with_priority( @@ -315,6 +316,7 @@ impl HeadersClient for FileClient { } impl BodiesClient for FileClient { + type Body = BlockBody; type Output = BodiesFut; fn get_block_bodies_with_priority( diff --git a/crates/net/downloaders/src/headers/noop.rs b/crates/net/downloaders/src/headers/noop.rs index 210655f7e26..58da7312387 100644 --- a/crates/net/downloaders/src/headers/noop.rs +++ b/crates/net/downloaders/src/headers/noop.rs @@ -1,3 +1,4 @@ +use alloy_consensus::Header; use futures::Stream; use reth_network_p2p::headers::{ downloader::{HeaderDownloader, SyncTarget}, @@ -11,6 +12,8 @@ use reth_primitives::SealedHeader; pub struct NoopHeaderDownloader; impl HeaderDownloader for NoopHeaderDownloader { + type Header = Header; + fn update_local_head(&mut self, _: SealedHeader) {} fn update_sync_target(&mut self, _: SyncTarget) {} @@ -19,7 +22,7 @@ impl HeaderDownloader for NoopHeaderDownloader { } impl Stream for NoopHeaderDownloader { - type Item = Result, HeadersDownloaderError>; + type Item = Result, HeadersDownloaderError

>; fn poll_next( self: std::pin::Pin<&mut Self>, diff --git a/crates/net/downloaders/src/headers/reverse_headers.rs b/crates/net/downloaders/src/headers/reverse_headers.rs index f0c28dc5d9f..9532b4b3a35 100644 --- a/crates/net/downloaders/src/headers/reverse_headers.rs +++ b/crates/net/downloaders/src/headers/reverse_headers.rs @@ -2,6 +2,7 @@ use super::task::TaskDownloader; use crate::metrics::HeaderDownloaderMetrics; +use alloy_consensus::BlockHeader; use alloy_eips::BlockHashOrNumber; use alloy_primitives::{BlockNumber, Sealable, B256}; use futures::{stream::Stream, FutureExt}; @@ -19,7 +20,7 @@ use reth_network_p2p::{ priority::Priority, }; use reth_network_peers::PeerId; -use reth_primitives::{GotExpected, Header, SealedHeader}; +use reth_primitives::{GotExpected, SealedHeader}; use reth_tasks::{TaskSpawner, TokioTaskExecutor}; use std::{ cmp::{Ordering, Reverse}, @@ -39,14 +40,14 @@ const REQUESTS_PER_PEER_MULTIPLIER: usize = 5; /// Wrapper for internal downloader errors. #[derive(Error, Debug)] -enum ReverseHeadersDownloaderError { +enum ReverseHeadersDownloaderError { #[error(transparent)] - Downloader(#[from] HeadersDownloaderError), + Downloader(#[from] HeadersDownloaderError), #[error(transparent)] Response(#[from] Box), } -impl From for ReverseHeadersDownloaderError { +impl From for ReverseHeadersDownloaderError { fn from(value: HeadersResponseError) -> Self { Self::Response(Box::new(value)) } @@ -66,17 +67,17 @@ impl From for ReverseHeadersDownloaderError { #[derive(Debug)] pub struct ReverseHeadersDownloader { /// Consensus client used to validate headers - consensus: Arc, + consensus: Arc>, /// Client used to download headers. client: Arc, /// The local head of the chain. - local_head: Option, + local_head: Option>, /// Block we want to close the gap to. sync_target: Option, /// The block number to use for requests. next_request_block_number: u64, /// Keeps track of the block we need to validate next. - lowest_validated_header: Option, + lowest_validated_header: Option>, /// Tip block number to start validating from (in reverse) next_chain_tip_block_number: u64, /// The batch size per one request @@ -97,11 +98,11 @@ pub struct ReverseHeadersDownloader { /// requests in progress in_progress_queue: FuturesUnordered>, /// Buffered, unvalidated responses - buffered_responses: BinaryHeap, + buffered_responses: BinaryHeap>, /// Buffered, _sorted_ and validated headers ready to be returned. /// /// Note: headers are sorted from high to low - queued_validated_headers: Vec, + queued_validated_headers: Vec>, /// Header downloader metrics. metrics: HeaderDownloaderMetrics, } @@ -110,7 +111,7 @@ pub struct ReverseHeadersDownloader { impl ReverseHeadersDownloader where - H: HeadersClient + 'static, + H: HeadersClient + 'static, { /// Convenience method to create a [`ReverseHeadersDownloaderBuilder`] without importing it pub fn builder() -> ReverseHeadersDownloaderBuilder { @@ -120,7 +121,7 @@ where /// Returns the block number the local node is at. #[inline] fn local_block_number(&self) -> Option { - self.local_head.as_ref().map(|h| h.number) + self.local_head.as_ref().map(|h| h.number()) } /// Returns the existing local head block number @@ -130,7 +131,7 @@ where /// If the local head has not been set. #[inline] fn existing_local_block_number(&self) -> BlockNumber { - self.local_head.as_ref().expect("is initialized").number + self.local_head.as_ref().expect("is initialized").number() } /// Returns the existing sync target. @@ -197,14 +198,14 @@ where /// `lowest_validated_header`. /// /// This only returns `None` if we haven't fetched the initial chain tip yet. - fn lowest_validated_header(&self) -> Option<&SealedHeader> { + fn lowest_validated_header(&self) -> Option<&SealedHeader> { self.queued_validated_headers.last().or(self.lowest_validated_header.as_ref()) } /// Validate that the received header matches the expected sync target. fn validate_sync_target( &self, - header: &SealedHeader, + header: &SealedHeader, request: HeadersRequest, peer_id: PeerId, ) -> Result<(), Box> { @@ -220,12 +221,12 @@ where ), })) } - SyncTargetBlock::Number(number) if header.number != number => { + SyncTargetBlock::Number(number) if header.number() != number => { Err(Box::new(HeadersResponseError { request, peer_id: Some(peer_id), error: DownloadError::InvalidTipNumber(GotExpected { - got: header.number, + got: header.number(), expected: number, }), })) @@ -244,9 +245,9 @@ where fn process_next_headers( &mut self, request: HeadersRequest, - headers: Vec
, + headers: Vec, peer_id: PeerId, - ) -> Result<(), ReverseHeadersDownloaderError> { + ) -> Result<(), ReverseHeadersDownloaderError> { let mut validated = Vec::with_capacity(headers.len()); let sealed_headers = headers @@ -280,17 +281,17 @@ where if let Some((last_header, head)) = validated .last_mut() .zip(self.local_head.as_ref()) - .filter(|(last, head)| last.number == head.number + 1) + .filter(|(last, head)| last.number() == head.number() + 1) { // Every header must be valid on its own - if let Err(error) = self.consensus.validate_header(last_header) { + if let Err(error) = self.consensus.validate_header(&*last_header) { trace!(target: "downloaders::headers", %error, "Failed to validate header"); return Err(HeadersResponseError { request, peer_id: Some(peer_id), error: DownloadError::HeaderValidation { hash: head.hash(), - number: head.number, + number: head.number(), error: Box::new(error), }, } @@ -299,9 +300,9 @@ where // If the header is valid on its own, but not against its parent, we return it as // detached head error. - if let Err(error) = self.consensus.validate_header_against_parent(last_header, head) { + if let Err(error) = self.consensus.validate_header_against_parent(&*last_header, head) { // Replace the last header with a detached variant - error!(target: "downloaders::headers", %error, number = last_header.number, hash = ?last_header.hash(), "Header cannot be attached to known canonical chain"); + error!(target: "downloaders::headers", %error, number = last_header.number(), hash = ?last_header.hash(), "Header cannot be attached to known canonical chain"); return Err(HeadersDownloaderError::DetachedHead { local_head: Box::new(head.clone()), header: Box::new(last_header.clone()), @@ -313,7 +314,7 @@ where // update tracked block info (falling block number) self.next_chain_tip_block_number = - validated.last().expect("exists").number.saturating_sub(1); + validated.last().expect("exists").number().saturating_sub(1); self.queued_validated_headers.extend(validated); Ok(()) @@ -345,7 +346,7 @@ where let skip = self .queued_validated_headers .iter() - .take_while(|last| last.number > target_block_number) + .take_while(|last| last.number() > target_block_number) .count(); // removes all headers that are higher than current target self.queued_validated_headers.drain(..skip); @@ -360,8 +361,8 @@ where /// Handles the response for the request for the sync target fn on_sync_target_outcome( &mut self, - response: HeadersRequestOutcome, - ) -> Result<(), ReverseHeadersDownloaderError> { + response: HeadersRequestOutcome, + ) -> Result<(), ReverseHeadersDownloaderError> { let sync_target = self.existing_sync_target(); let HeadersRequestOutcome { request, outcome } = response; match outcome { @@ -372,7 +373,7 @@ where self.metrics.total_downloaded.increment(headers.len() as u64); // sort headers from highest to lowest block number - headers.sort_unstable_by_key(|h| Reverse(h.number)); + headers.sort_unstable_by_key(|h| Reverse(h.number())); if headers.is_empty() { return Err(HeadersResponseError { @@ -401,12 +402,12 @@ where } } SyncTargetBlock::Number(number) => { - if target.number != number { + if target.number() != number { return Err(HeadersResponseError { request, peer_id: Some(peer_id), error: DownloadError::InvalidTipNumber(GotExpected { - got: target.number, + got: target.number(), expected: number, }), } @@ -415,17 +416,17 @@ where } } - trace!(target: "downloaders::headers", head=?self.local_block_number(), hash=?target.hash(), number=%target.number, "Received sync target"); + trace!(target: "downloaders::headers", head=?self.local_block_number(), hash=?target.hash(), number=%target.number(), "Received sync target"); // This is the next block we need to start issuing requests from - let parent_block_number = target.number.saturating_sub(1); - self.on_block_number_update(target.number, parent_block_number); + let parent_block_number = target.number().saturating_sub(1); + self.on_block_number_update(target.number(), parent_block_number); self.queued_validated_headers.push(target); // try to validate all buffered responses blocked by this successful response self.try_validate_buffered() - .map(Err::<(), ReverseHeadersDownloaderError>) + .map(Err::<(), ReverseHeadersDownloaderError>) .transpose()?; Ok(()) @@ -439,8 +440,8 @@ where /// Invoked when we received a response fn on_headers_outcome( &mut self, - response: HeadersRequestOutcome, - ) -> Result<(), ReverseHeadersDownloaderError> { + response: HeadersRequestOutcome, + ) -> Result<(), ReverseHeadersDownloaderError> { let requested_block_number = response.block_number(); let HeadersRequestOutcome { request, outcome } = response; @@ -475,19 +476,19 @@ where } // sort headers from highest to lowest block number - headers.sort_unstable_by_key(|h| Reverse(h.number)); + headers.sort_unstable_by_key(|h| Reverse(h.number())); // validate the response let highest = &headers[0]; - trace!(target: "downloaders::headers", requested_block_number, highest=?highest.number, "Validating non-empty headers response"); + trace!(target: "downloaders::headers", requested_block_number, highest=?highest.number(), "Validating non-empty headers response"); - if highest.number != requested_block_number { + if highest.number() != requested_block_number { return Err(HeadersResponseError { request, peer_id: Some(peer_id), error: DownloadError::HeadersResponseStartBlockMismatch(GotExpected { - got: highest.number, + got: highest.number(), expected: requested_block_number, }), } @@ -495,14 +496,14 @@ where } // check if the response is the next expected - if highest.number == self.next_chain_tip_block_number { + if highest.number() == self.next_chain_tip_block_number { // is next response, validate it self.process_next_headers(request, headers, peer_id)?; // try to validate all buffered responses blocked by this successful response self.try_validate_buffered() - .map(Err::<(), ReverseHeadersDownloaderError>) + .map(Err::<(), ReverseHeadersDownloaderError>) .transpose()?; - } else if highest.number > self.existing_local_block_number() { + } else if highest.number() > self.existing_local_block_number() { self.metrics.buffered_responses.increment(1.); // can't validate yet self.buffered_responses.push(OrderedHeadersResponse { @@ -549,7 +550,7 @@ where /// Attempts to validate the buffered responses /// /// Returns an error if the next expected response was popped, but failed validation. - fn try_validate_buffered(&mut self) -> Option { + fn try_validate_buffered(&mut self) -> Option> { loop { // Check to see if we've already received the next value let next_response = self.buffered_responses.peek_mut()?; @@ -598,7 +599,11 @@ where } /// Validate whether the header is valid in relation to it's parent - fn validate(&self, header: &SealedHeader, parent: &SealedHeader) -> DownloadResult<()> { + fn validate( + &self, + header: &SealedHeader, + parent: &SealedHeader, + ) -> DownloadResult<()> { validate_header_download(&self.consensus, header, parent) } @@ -614,7 +619,7 @@ where } /// Splits off the next batch of headers - fn split_next_batch(&mut self) -> Vec { + fn split_next_batch(&mut self) -> Vec> { let batch_size = self.stream_batch_size.min(self.queued_validated_headers.len()); let mut rem = self.queued_validated_headers.split_off(batch_size); std::mem::swap(&mut rem, &mut self.queued_validated_headers); @@ -644,12 +649,15 @@ where Self: HeaderDownloader + 'static, { /// Spawns the downloader task via [`tokio::task::spawn`] - pub fn into_task(self) -> TaskDownloader { + pub fn into_task(self) -> TaskDownloader<::Header> { self.into_task_with(&TokioTaskExecutor::default()) } /// Convert the downloader into a [`TaskDownloader`] by spawning it via the given `spawner`. - pub fn into_task_with(self, spawner: &S) -> TaskDownloader + pub fn into_task_with( + self, + spawner: &S, + ) -> TaskDownloader<::Header> where S: TaskSpawner, { @@ -659,11 +667,17 @@ where impl HeaderDownloader for ReverseHeadersDownloader where - H: HeadersClient + 'static, + H: HeadersClient + 'static, { - fn update_local_head(&mut self, head: SealedHeader) { + type Header = H::Header; + + fn update_local_head(&mut self, head: SealedHeader) { // ensure we're only yielding headers that are in range and follow the current local head. - while self.queued_validated_headers.last().is_some_and(|last| last.number <= head.number) { + while self + .queued_validated_headers + .last() + .is_some_and(|last| last.number() <= head.number()) + { // headers are sorted high to low self.queued_validated_headers.pop(); } @@ -686,7 +700,7 @@ where .queued_validated_headers .first() .filter(|h| h.hash() == tip) - .map(|h| h.number) + .map(|h| h.number()) { self.sync_target = Some(new_sync_target.with_number(target_number)); return @@ -740,9 +754,9 @@ where impl Stream for ReverseHeadersDownloader where - H: HeadersClient + 'static, + H: HeadersClient + 'static, { - type Item = HeadersDownloaderResult>; + type Item = HeadersDownloaderResult>, H::Header>; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.get_mut(); @@ -883,18 +897,18 @@ where } } -/// A future that returns a list of [`Header`] on success. +/// A future that returns a list of headers on success. #[derive(Debug)] struct HeadersRequestFuture { request: Option, fut: F, } -impl Future for HeadersRequestFuture +impl Future for HeadersRequestFuture where - F: Future>> + Sync + Send + Unpin, + F: Future>> + Sync + Send + Unpin, { - type Output = HeadersRequestOutcome; + type Output = HeadersRequestOutcome; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.get_mut(); @@ -906,14 +920,14 @@ where } /// The outcome of the [`HeadersRequestFuture`] -struct HeadersRequestOutcome { +struct HeadersRequestOutcome { request: HeadersRequest, - outcome: PeerRequestResult>, + outcome: PeerRequestResult>, } // === impl OrderedHeadersResponse === -impl HeadersRequestOutcome { +impl HeadersRequestOutcome { fn block_number(&self) -> u64 { self.request.start.as_number().expect("is number") } @@ -921,35 +935,35 @@ impl HeadersRequestOutcome { /// Wrapper type to order responses #[derive(Debug)] -struct OrderedHeadersResponse { - headers: Vec
, +struct OrderedHeadersResponse { + headers: Vec, request: HeadersRequest, peer_id: PeerId, } // === impl OrderedHeadersResponse === -impl OrderedHeadersResponse { +impl OrderedHeadersResponse { fn block_number(&self) -> u64 { self.request.start.as_number().expect("is number") } } -impl PartialEq for OrderedHeadersResponse { +impl PartialEq for OrderedHeadersResponse { fn eq(&self, other: &Self) -> bool { self.block_number() == other.block_number() } } -impl Eq for OrderedHeadersResponse {} +impl Eq for OrderedHeadersResponse {} -impl PartialOrd for OrderedHeadersResponse { +impl PartialOrd for OrderedHeadersResponse { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl Ord for OrderedHeadersResponse { +impl Ord for OrderedHeadersResponse { fn cmp(&self, other: &Self) -> Ordering { self.block_number().cmp(&other.block_number()) } @@ -1156,7 +1170,11 @@ impl ReverseHeadersDownloaderBuilder { /// Build [`ReverseHeadersDownloader`] with provided consensus /// and header client implementations - pub fn build(self, client: H, consensus: Arc) -> ReverseHeadersDownloader + pub fn build( + self, + client: H, + consensus: Arc>, + ) -> ReverseHeadersDownloader where H: HeadersClient + 'static, { @@ -1214,6 +1232,7 @@ fn calc_next_request( mod tests { use super::*; use crate::headers::test_utils::child_header; + use alloy_consensus::Header; use assert_matches::assert_matches; use reth_consensus::test_utils::TestConsensus; use reth_network_p2p::test_utils::TestHeadersClient; @@ -1296,7 +1315,7 @@ mod tests { assert!(downloader.sync_target_request.is_some()); downloader.sync_target_request.take(); - let target = SyncTarget::Gap(SealedHeader::new(Header::default(), B256::random())); + let target = SyncTarget::Gap(SealedHeader::new(Default::default(), B256::random())); downloader.update_sync_target(target); assert!(downloader.sync_target_request.is_none()); assert_matches!( @@ -1373,7 +1392,7 @@ mod tests { fn test_resp_order() { let mut heap = BinaryHeap::new(); let hi = 1u64; - heap.push(OrderedHeadersResponse { + heap.push(OrderedHeadersResponse::
{ headers: vec![], request: HeadersRequest { start: hi.into(), limit: 0, direction: Default::default() }, peer_id: Default::default(), diff --git a/crates/net/downloaders/src/headers/task.rs b/crates/net/downloaders/src/headers/task.rs index b3fa27fde59..81c4cd80da3 100644 --- a/crates/net/downloaders/src/headers/task.rs +++ b/crates/net/downloaders/src/headers/task.rs @@ -22,15 +22,15 @@ pub const HEADERS_TASK_BUFFER_SIZE: usize = 8; /// A [HeaderDownloader] that drives a spawned [HeaderDownloader] on a spawned task. #[derive(Debug)] #[pin_project] -pub struct TaskDownloader { +pub struct TaskDownloader { #[pin] - from_downloader: ReceiverStream>>, - to_downloader: UnboundedSender, + from_downloader: ReceiverStream>, H>>, + to_downloader: UnboundedSender>, } // === impl TaskDownloader === -impl TaskDownloader { +impl TaskDownloader { /// Spawns the given `downloader` via [`tokio::task::spawn`] and returns a [`TaskDownloader`] /// that's connected to that task. /// @@ -46,7 +46,8 @@ impl TaskDownloader { /// # use reth_downloaders::headers::task::TaskDownloader; /// # use reth_consensus::Consensus; /// # use reth_network_p2p::headers::client::HeadersClient; - /// # fn t(consensus:Arc, client: Arc) { + /// # use reth_primitives_traits::BlockHeader; + /// # fn t + 'static>(consensus:Arc>, client: Arc) { /// let downloader = ReverseHeadersDownloader::::builder().build( /// client, /// consensus @@ -55,7 +56,7 @@ impl TaskDownloader { /// # } pub fn spawn(downloader: T) -> Self where - T: HeaderDownloader + 'static, + T: HeaderDownloader
+ 'static, { Self::spawn_with(downloader, &TokioTaskExecutor::default()) } @@ -64,7 +65,7 @@ impl TaskDownloader { /// that's connected to that task. pub fn spawn_with(downloader: T, spawner: &S) -> Self where - T: HeaderDownloader + 'static, + T: HeaderDownloader
+ 'static, S: TaskSpawner, { let (headers_tx, headers_rx) = mpsc::channel(HEADERS_TASK_BUFFER_SIZE); @@ -81,12 +82,14 @@ impl TaskDownloader { } } -impl HeaderDownloader for TaskDownloader { - fn update_sync_gap(&mut self, head: SealedHeader, target: SyncTarget) { +impl HeaderDownloader for TaskDownloader { + type Header = H; + + fn update_sync_gap(&mut self, head: SealedHeader, target: SyncTarget) { let _ = self.to_downloader.send(DownloaderUpdates::UpdateSyncGap(head, target)); } - fn update_local_head(&mut self, head: SealedHeader) { + fn update_local_head(&mut self, head: SealedHeader) { let _ = self.to_downloader.send(DownloaderUpdates::UpdateLocalHead(head)); } @@ -99,8 +102,8 @@ impl HeaderDownloader for TaskDownloader { } } -impl Stream for TaskDownloader { - type Item = HeadersDownloaderResult>; +impl Stream for TaskDownloader { + type Item = HeadersDownloaderResult>, H>; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.project().from_downloader.poll_next(cx) @@ -108,9 +111,10 @@ impl Stream for TaskDownloader { } /// A [`HeaderDownloader`] that runs on its own task -struct SpawnedDownloader { - updates: UnboundedReceiverStream, - headers_tx: PollSender>>, +#[expect(clippy::complexity)] +struct SpawnedDownloader { + updates: UnboundedReceiverStream>, + headers_tx: PollSender>, T::Header>>, downloader: T, } @@ -170,9 +174,9 @@ impl Future for SpawnedDownloader { } /// Commands delegated tot the spawned [`HeaderDownloader`] -enum DownloaderUpdates { - UpdateSyncGap(SealedHeader, SyncTarget), - UpdateLocalHead(SealedHeader), +enum DownloaderUpdates { + UpdateSyncGap(SealedHeader, SyncTarget), + UpdateLocalHead(SealedHeader), UpdateSyncTarget(SyncTarget), SetBatchSize(usize), } diff --git a/crates/net/downloaders/src/test_utils/bodies_client.rs b/crates/net/downloaders/src/test_utils/bodies_client.rs index be8373f8235..d84d92363ee 100644 --- a/crates/net/downloaders/src/test_utils/bodies_client.rs +++ b/crates/net/downloaders/src/test_utils/bodies_client.rs @@ -78,6 +78,7 @@ impl DownloadClient for TestBodiesClient { } impl BodiesClient for TestBodiesClient { + type Body = BlockBody; type Output = BodiesFut; fn get_block_bodies_with_priority( diff --git a/crates/net/eth-wire-types/Cargo.toml b/crates/net/eth-wire-types/Cargo.toml index 1d2b5487245..582ab7557f3 100644 --- a/crates/net/eth-wire-types/Cargo.toml +++ b/crates/net/eth-wire-types/Cargo.toml @@ -18,6 +18,7 @@ reth-codecs-derive.workspace = true reth-primitives.workspace = true # ethereum +alloy-consensus.workspace = true alloy-chains = { workspace = true, features = ["rlp"] } alloy-eips.workspace = true alloy-primitives.workspace = true diff --git a/crates/net/eth-wire-types/src/message.rs b/crates/net/eth-wire-types/src/message.rs index cca6600d11e..2a6d973ffc3 100644 --- a/crates/net/eth-wire-types/src/message.rs +++ b/crates/net/eth-wire-types/src/message.rs @@ -148,7 +148,7 @@ impl From> for ProtocolMessage { /// Represents messages that can be sent to multiple peers. #[derive(Clone, Debug)] -pub struct ProtocolBroadcastMessage { +pub struct ProtocolBroadcastMessage { /// The unique identifier representing the type of the Ethereum message. pub message_type: EthMessageID, /// The content of the message to be broadcasted, including specific data based on the message diff --git a/crates/net/eth-wire-types/src/primitives.rs b/crates/net/eth-wire-types/src/primitives.rs index ca85fa69ad6..04b8b429e2a 100644 --- a/crates/net/eth-wire-types/src/primitives.rs +++ b/crates/net/eth-wire-types/src/primitives.rs @@ -2,6 +2,7 @@ use std::fmt::Debug; +use alloy_consensus::BlockHeader; use alloy_rlp::{Decodable, Encodable}; /// Abstraction over primitive types which might appear in network messages. See @@ -10,7 +11,8 @@ pub trait NetworkPrimitives: Send + Sync + Unpin + Clone + Debug + PartialEq + Eq + 'static { /// The block header type. - type BlockHeader: Encodable + type BlockHeader: BlockHeader + + Encodable + Decodable + Send + Sync diff --git a/crates/net/eth-wire/src/capability.rs b/crates/net/eth-wire/src/capability.rs index d60e500744c..625971e0e7b 100644 --- a/crates/net/eth-wire/src/capability.rs +++ b/crates/net/eth-wire/src/capability.rs @@ -5,10 +5,11 @@ use crate::{ p2pstream::MAX_RESERVED_MESSAGE_ID, protocol::{ProtoVersion, Protocol}, version::ParseVersionError, - Capability, EthMessage, EthMessageID, EthVersion, + Capability, EthMessageID, EthVersion, }; use alloy_primitives::bytes::Bytes; use derive_more::{Deref, DerefMut}; +use reth_eth_wire_types::{EthMessage, EthNetworkPrimitives, NetworkPrimitives}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; use std::{ @@ -30,9 +31,13 @@ pub struct RawCapabilityMessage { /// network. #[derive(Debug)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub enum CapabilityMessage { +pub enum CapabilityMessage { /// Eth sub-protocol message. - Eth(EthMessage), + #[cfg_attr( + feature = "serde", + serde(bound = "EthMessage: Serialize + serde::de::DeserializeOwned") + )] + Eth(EthMessage), /// Any other capability message. Other(RawCapabilityMessage), } diff --git a/crates/net/eth-wire/src/ethstream.rs b/crates/net/eth-wire/src/ethstream.rs index 795dd630780..c971f6182ce 100644 --- a/crates/net/eth-wire/src/ethstream.rs +++ b/crates/net/eth-wire/src/ethstream.rs @@ -8,6 +8,7 @@ use crate::{ use alloy_primitives::bytes::{Bytes, BytesMut}; use futures::{ready, Sink, SinkExt, StreamExt}; use pin_project::pin_project; +use reth_eth_wire_types::NetworkPrimitives; use reth_primitives::{ForkFilter, GotExpected}; use std::{ pin::Pin, @@ -54,32 +55,32 @@ where /// Consumes the [`UnauthedEthStream`] and returns an [`EthStream`] after the `Status` /// handshake is completed successfully. This also returns the `Status` message sent by the /// remote peer. - pub async fn handshake( + pub async fn handshake( self, status: Status, fork_filter: ForkFilter, - ) -> Result<(EthStream, Status), EthStreamError> { + ) -> Result<(EthStream, Status), EthStreamError> { self.handshake_with_timeout(status, fork_filter, HANDSHAKE_TIMEOUT).await } /// Wrapper around handshake which enforces a timeout. - pub async fn handshake_with_timeout( + pub async fn handshake_with_timeout( self, status: Status, fork_filter: ForkFilter, timeout_limit: Duration, - ) -> Result<(EthStream, Status), EthStreamError> { + ) -> Result<(EthStream, Status), EthStreamError> { timeout(timeout_limit, Self::handshake_without_timeout(self, status, fork_filter)) .await .map_err(|_| EthStreamError::StreamTimeout)? } /// Handshake with no timeout - pub async fn handshake_without_timeout( + pub async fn handshake_without_timeout( mut self, status: Status, fork_filter: ForkFilter, - ) -> Result<(EthStream, Status), EthStreamError> { + ) -> Result<(EthStream, Status), EthStreamError> { trace!( %status, "sending eth status to peer" @@ -89,10 +90,8 @@ where // The max length for a status with TTD is: + self.inner .send( - alloy_rlp::encode(ProtocolMessage::from( - EthMessage::::Status(status), - )) - .into(), + alloy_rlp::encode(ProtocolMessage::::from(EthMessage::::Status(status))) + .into(), ) .await?; @@ -112,15 +111,14 @@ where } let version = status.version; - let msg: ProtocolMessage = - match ProtocolMessage::decode_message(version, &mut their_msg.as_ref()) { - Ok(m) => m, - Err(err) => { - debug!("decode error in eth handshake: msg={their_msg:x}"); - self.inner.disconnect(DisconnectReason::DisconnectRequested).await?; - return Err(EthStreamError::InvalidMessage(err)) - } - }; + let msg = match ProtocolMessage::::decode_message(version, &mut their_msg.as_ref()) { + Ok(m) => m, + Err(err) => { + debug!("decode error in eth handshake: msg={their_msg:x}"); + self.inner.disconnect(DisconnectReason::DisconnectRequested).await?; + return Err(EthStreamError::InvalidMessage(err)) + } + }; // The following checks should match the checks in go-ethereum: // https://github.com/ethereum/go-ethereum/blob/9244d5cd61f3ea5a7645fdf2a1a96d53421e412f/eth/protocols/eth/handshake.go#L87-L89 @@ -194,19 +192,21 @@ where /// compatible with eth-networking protocol messages, which get RLP encoded/decoded. #[pin_project] #[derive(Debug)] -pub struct EthStream { +pub struct EthStream { /// Negotiated eth version. version: EthVersion, #[pin] inner: S, + + _pd: std::marker::PhantomData, } -impl EthStream { +impl EthStream { /// Creates a new unauthed [`EthStream`] from a provided stream. You will need /// to manually handshake a peer. #[inline] pub const fn new(version: EthVersion, inner: S) -> Self { - Self { version, inner } + Self { version, inner, _pd: std::marker::PhantomData } } /// Returns the eth version. @@ -234,15 +234,16 @@ impl EthStream { } } -impl EthStream +impl EthStream where S: Sink + Unpin, EthStreamError: From, + N: NetworkPrimitives, { /// Same as [`Sink::start_send`] but accepts a [`EthBroadcastMessage`] instead. pub fn start_send_broadcast( &mut self, - item: EthBroadcastMessage, + item: EthBroadcastMessage, ) -> Result<(), EthStreamError> { self.inner.start_send_unpin(Bytes::from(alloy_rlp::encode( ProtocolBroadcastMessage::from(item), @@ -252,12 +253,13 @@ where } } -impl Stream for EthStream +impl Stream for EthStream where S: Stream> + Unpin, EthStreamError: From, + N: NetworkPrimitives, { - type Item = Result; + type Item = Result, EthStreamError>; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); @@ -299,10 +301,11 @@ where } } -impl Sink for EthStream +impl Sink> for EthStream where S: CanDisconnect + Unpin, EthStreamError: From<>::Error>, + N: NetworkPrimitives, { type Error = EthStreamError; @@ -310,7 +313,7 @@ where self.project().inner.poll_ready(cx).map_err(Into::into) } - fn start_send(self: Pin<&mut Self>, item: EthMessage) -> Result<(), Self::Error> { + fn start_send(self: Pin<&mut Self>, item: EthMessage) -> Result<(), Self::Error> { if matches!(item, EthMessage::Status(_)) { // TODO: to disconnect here we would need to do something similar to P2PStream's // start_disconnect, which would ideally be a part of the CanDisconnect trait, or at @@ -340,10 +343,11 @@ where } } -impl CanDisconnect for EthStream +impl CanDisconnect> for EthStream where S: CanDisconnect + Send, EthStreamError: From<>::Error>, + N: NetworkPrimitives, { async fn disconnect(&mut self, reason: DisconnectReason) -> Result<(), EthStreamError> { self.inner.disconnect(reason).await.map_err(Into::into) @@ -365,6 +369,7 @@ mod tests { use futures::{SinkExt, StreamExt}; use reth_chainspec::NamedChain; use reth_ecies::stream::ECIESStream; + use reth_eth_wire_types::EthNetworkPrimitives; use reth_network_peers::pk2id; use reth_primitives::{ForkFilter, Head}; use secp256k1::{SecretKey, SECP256K1}; @@ -397,7 +402,7 @@ mod tests { let (incoming, _) = listener.accept().await.unwrap(); let stream = PassthroughCodec::default().framed(incoming); let (_, their_status) = UnauthedEthStream::new(stream) - .handshake(status_clone, fork_filter_clone) + .handshake::(status_clone, fork_filter_clone) .await .unwrap(); @@ -409,8 +414,10 @@ mod tests { let sink = PassthroughCodec::default().framed(outgoing); // try to connect - let (_, their_status) = - UnauthedEthStream::new(sink).handshake(status, fork_filter).await.unwrap(); + let (_, their_status) = UnauthedEthStream::new(sink) + .handshake::(status, fork_filter) + .await + .unwrap(); // their status is a clone of our status, these should be equal assert_eq!(their_status, status); @@ -444,7 +451,7 @@ mod tests { let (incoming, _) = listener.accept().await.unwrap(); let stream = PassthroughCodec::default().framed(incoming); let (_, their_status) = UnauthedEthStream::new(stream) - .handshake(status_clone, fork_filter_clone) + .handshake::(status_clone, fork_filter_clone) .await .unwrap(); @@ -456,8 +463,10 @@ mod tests { let sink = PassthroughCodec::default().framed(outgoing); // try to connect - let (_, their_status) = - UnauthedEthStream::new(sink).handshake(status, fork_filter).await.unwrap(); + let (_, their_status) = UnauthedEthStream::new(sink) + .handshake::(status, fork_filter) + .await + .unwrap(); // their status is a clone of our status, these should be equal assert_eq!(their_status, status); @@ -490,8 +499,9 @@ mod tests { // roughly based off of the design of tokio::net::TcpListener let (incoming, _) = listener.accept().await.unwrap(); let stream = PassthroughCodec::default().framed(incoming); - let handshake_res = - UnauthedEthStream::new(stream).handshake(status_clone, fork_filter_clone).await; + let handshake_res = UnauthedEthStream::new(stream) + .handshake::(status_clone, fork_filter_clone) + .await; // make sure the handshake fails due to td too high assert!(matches!( @@ -506,7 +516,9 @@ mod tests { let sink = PassthroughCodec::default().framed(outgoing); // try to connect - let handshake_res = UnauthedEthStream::new(sink).handshake(status, fork_filter).await; + let handshake_res = UnauthedEthStream::new(sink) + .handshake::(status, fork_filter) + .await; // this handshake should also fail due to td too high assert!(matches!( @@ -524,7 +536,7 @@ mod tests { async fn can_write_and_read_cleartext() { let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); let local_addr = listener.local_addr().unwrap(); - let test_msg = EthMessage::NewBlockHashes( + let test_msg: EthMessage = EthMessage::NewBlockHashes( vec![ BlockHashNumber { hash: B256::random(), number: 5 }, BlockHashNumber { hash: B256::random(), number: 6 }, @@ -559,7 +571,7 @@ mod tests { let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); let local_addr = listener.local_addr().unwrap(); let server_key = SecretKey::new(&mut rand::thread_rng()); - let test_msg = EthMessage::NewBlockHashes( + let test_msg: EthMessage = EthMessage::NewBlockHashes( vec![ BlockHashNumber { hash: B256::random(), number: 5 }, BlockHashNumber { hash: B256::random(), number: 6 }, @@ -601,7 +613,7 @@ mod tests { let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); let local_addr = listener.local_addr().unwrap(); let server_key = SecretKey::new(&mut rand::thread_rng()); - let test_msg = EthMessage::NewBlockHashes( + let test_msg: EthMessage = EthMessage::NewBlockHashes( vec![ BlockHashNumber { hash: B256::random(), number: 5 }, BlockHashNumber { hash: B256::random(), number: 6 }, @@ -705,7 +717,7 @@ mod tests { let (incoming, _) = listener.accept().await.unwrap(); let stream = PassthroughCodec::default().framed(incoming); let (_, their_status) = UnauthedEthStream::new(stream) - .handshake(status_clone, fork_filter_clone) + .handshake::(status_clone, fork_filter_clone) .await .unwrap(); @@ -718,7 +730,11 @@ mod tests { // try to connect let handshake_result = UnauthedEthStream::new(sink) - .handshake_with_timeout(status, fork_filter, Duration::from_secs(1)) + .handshake_with_timeout::( + status, + fork_filter, + Duration::from_secs(1), + ) .await; // Assert that a timeout error occurred diff --git a/crates/net/eth-wire/src/multiplex.rs b/crates/net/eth-wire/src/multiplex.rs index d1d977aba78..6f882f40887 100644 --- a/crates/net/eth-wire/src/multiplex.rs +++ b/crates/net/eth-wire/src/multiplex.rs @@ -24,6 +24,7 @@ use crate::{ }; use bytes::{Bytes, BytesMut}; use futures::{Sink, SinkExt, Stream, StreamExt, TryStream, TryStreamExt}; +use reth_eth_wire_types::NetworkPrimitives; use reth_primitives::ForkFilter; use tokio::sync::{mpsc, mpsc::UnboundedSender}; use tokio_stream::wrappers::UnboundedReceiverStream; @@ -204,11 +205,11 @@ impl RlpxProtocolMultiplexer { /// Converts this multiplexer into a [`RlpxSatelliteStream`] with eth protocol as the given /// primary protocol. - pub async fn into_eth_satellite_stream( + pub async fn into_eth_satellite_stream( self, status: Status, fork_filter: ForkFilter, - ) -> Result<(RlpxSatelliteStream>, Status), EthStreamError> + ) -> Result<(RlpxSatelliteStream>, Status), EthStreamError> where St: Stream> + Sink + Unpin, { @@ -674,6 +675,7 @@ mod tests { }, UnauthedP2PStream, }; + use reth_eth_wire_types::EthNetworkPrimitives; use tokio::{net::TcpListener, sync::oneshot}; use tokio_util::codec::Decoder; @@ -693,7 +695,7 @@ mod tests { UnauthedP2PStream::new(stream).handshake(server_hello).await.unwrap(); let (_eth_stream, _) = UnauthedEthStream::new(p2p_stream) - .handshake(other_status, other_fork_filter) + .handshake::(other_status, other_fork_filter) .await .unwrap(); @@ -708,7 +710,9 @@ mod tests { .into_satellite_stream_with_handshake( eth.capability().as_ref(), move |proxy| async move { - UnauthedEthStream::new(proxy).handshake(status, fork_filter).await + UnauthedEthStream::new(proxy) + .handshake::(status, fork_filter) + .await }, ) .await @@ -731,7 +735,7 @@ mod tests { let (conn, _) = UnauthedP2PStream::new(stream).handshake(server_hello).await.unwrap(); let (mut st, _their_status) = RlpxProtocolMultiplexer::new(conn) - .into_eth_satellite_stream(other_status, other_fork_filter) + .into_eth_satellite_stream::(other_status, other_fork_filter) .await .unwrap(); @@ -762,7 +766,7 @@ mod tests { let conn = connect_passthrough(local_addr, test_hello().0).await; let (mut st, _their_status) = RlpxProtocolMultiplexer::new(conn) - .into_eth_satellite_stream(status, fork_filter) + .into_eth_satellite_stream::(status, fork_filter) .await .unwrap(); diff --git a/crates/net/network-api/src/downloaders.rs b/crates/net/network-api/src/downloaders.rs index f081c16ed81..cbfe816134e 100644 --- a/crates/net/network-api/src/downloaders.rs +++ b/crates/net/network-api/src/downloaders.rs @@ -1,5 +1,7 @@ //! API related to syncing blocks. +use std::fmt::Debug; + use futures::Future; use reth_network_p2p::BlockClient; use tokio::sync::oneshot; @@ -7,10 +9,13 @@ use tokio::sync::oneshot; /// Provides client for downloading blocks. #[auto_impl::auto_impl(&, Arc)] pub trait BlockDownloaderProvider { + /// The client this type can provide. + type Client: BlockClient + Send + Sync + Clone + 'static; + /// Returns a new [`BlockClient`], used for fetching blocks from peers. /// /// The client is the entrypoint for sending block requests to the network. fn fetch_client( &self, - ) -> impl Future> + Send; + ) -> impl Future> + Send; } diff --git a/crates/net/network-api/src/events.rs b/crates/net/network-api/src/events.rs index d2bd66d1fdd..af392b6f9ea 100644 --- a/crates/net/network-api/src/events.rs +++ b/crates/net/network-api/src/events.rs @@ -4,8 +4,9 @@ use std::{fmt, net::SocketAddr, sync::Arc}; use reth_eth_wire_types::{ message::RequestPair, BlockBodies, BlockHeaders, Capabilities, DisconnectReason, EthMessage, - EthVersion, GetBlockBodies, GetBlockHeaders, GetNodeData, GetPooledTransactions, GetReceipts, - NodeData, PooledTransactions, Receipts, Status, + EthNetworkPrimitives, EthVersion, GetBlockBodies, GetBlockHeaders, GetNodeData, + GetPooledTransactions, GetReceipts, NetworkPrimitives, NodeData, PooledTransactions, Receipts, + Status, }; use reth_ethereum_forks::ForkId; use reth_network_p2p::error::{RequestError, RequestResult}; @@ -30,8 +31,8 @@ pub trait NetworkEventListenerProvider: Send + Sync { /// /// This includes any event types that may be relevant to tasks, for metrics, keep track of peers /// etc. -#[derive(Debug, Clone)] -pub enum NetworkEvent { +#[derive(Debug)] +pub enum NetworkEvent { /// Closed the peer session. SessionClosed { /// The identifier of the peer to which a session was closed. @@ -50,7 +51,7 @@ pub enum NetworkEvent { /// Capabilities the peer announced capabilities: Arc, /// A request channel to the session task. - messages: PeerRequestSender, + messages: PeerRequestSender, /// The status of the peer to which a session was established. status: Arc, /// negotiated eth version of the session @@ -62,6 +63,35 @@ pub enum NetworkEvent { PeerRemoved(PeerId), } +impl Clone for NetworkEvent { + fn clone(&self) -> Self { + match self { + Self::SessionClosed { peer_id, reason } => { + Self::SessionClosed { peer_id: *peer_id, reason: *reason } + } + Self::SessionEstablished { + peer_id, + remote_addr, + client_version, + capabilities, + messages, + status, + version, + } => Self::SessionEstablished { + peer_id: *peer_id, + remote_addr: *remote_addr, + client_version: client_version.clone(), + capabilities: capabilities.clone(), + messages: messages.clone(), + status: status.clone(), + version: *version, + }, + Self::PeerAdded(peer) => Self::PeerAdded(*peer), + Self::PeerRemoved(peer) => Self::PeerRemoved(*peer), + } + } +} + /// Events produced by the `Discovery` manager. #[derive(Debug, Clone, PartialEq, Eq)] pub enum DiscoveryEvent { @@ -98,7 +128,7 @@ pub enum DiscoveredEvent { /// Protocol related request messages that expect a response #[derive(Debug)] -pub enum PeerRequest { +pub enum PeerRequest { /// Requests block headers from the peer. /// /// The response should be sent through the channel. @@ -106,7 +136,7 @@ pub enum PeerRequest { /// The request for block headers. request: GetBlockHeaders, /// The channel to send the response for block headers. - response: oneshot::Sender>, + response: oneshot::Sender>>, }, /// Requests block bodies from the peer. /// @@ -115,7 +145,7 @@ pub enum PeerRequest { /// The request for block bodies. request: GetBlockBodies, /// The channel to send the response for block bodies. - response: oneshot::Sender>, + response: oneshot::Sender>>, }, /// Requests pooled transactions from the peer. /// @@ -148,7 +178,7 @@ pub enum PeerRequest { // === impl PeerRequest === -impl PeerRequest { +impl PeerRequest { /// Invoked if we received a response which does not match the request pub fn send_bad_response(self) { self.send_err_response(RequestError::BadResponse) @@ -166,7 +196,7 @@ impl PeerRequest { } /// Returns the [`EthMessage`] for this type - pub fn create_request_message(&self, request_id: u64) -> EthMessage { + pub fn create_request_message(&self, request_id: u64) -> EthMessage { match self { Self::GetBlockHeaders { request, .. } => { EthMessage::GetBlockHeaders(RequestPair { request_id, message: *request }) @@ -199,24 +229,29 @@ impl PeerRequest { } /// A Cloneable connection for sending _requests_ directly to the session of a peer. -#[derive(Clone)] -pub struct PeerRequestSender { +pub struct PeerRequestSender { /// id of the remote node. pub peer_id: PeerId, /// The Sender half connected to a session. - pub to_session_tx: mpsc::Sender, + pub to_session_tx: mpsc::Sender, +} + +impl Clone for PeerRequestSender { + fn clone(&self) -> Self { + Self { peer_id: self.peer_id, to_session_tx: self.to_session_tx.clone() } + } } // === impl PeerRequestSender === -impl PeerRequestSender { +impl PeerRequestSender { /// Constructs a new sender instance that's wired to a session - pub const fn new(peer_id: PeerId, to_session_tx: mpsc::Sender) -> Self { + pub const fn new(peer_id: PeerId, to_session_tx: mpsc::Sender) -> Self { Self { peer_id, to_session_tx } } /// Attempts to immediately send a message on this Sender - pub fn try_send(&self, req: PeerRequest) -> Result<(), mpsc::error::TrySendError> { + pub fn try_send(&self, req: R) -> Result<(), mpsc::error::TrySendError> { self.to_session_tx.try_send(req) } @@ -226,7 +261,7 @@ impl PeerRequestSender { } } -impl fmt::Debug for PeerRequestSender { +impl fmt::Debug for PeerRequestSender { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("PeerRequestSender").field("peer_id", &self.peer_id).finish_non_exhaustive() } diff --git a/crates/net/network-api/src/lib.rs b/crates/net/network-api/src/lib.rs index 6163c873003..986d490c34f 100644 --- a/crates/net/network-api/src/lib.rs +++ b/crates/net/network-api/src/lib.rs @@ -36,6 +36,7 @@ pub use events::{ use std::{future::Future, net::SocketAddr, sync::Arc, time::Instant}; use reth_eth_wire_types::{capability::Capabilities, DisconnectReason, EthVersion, Status}; +use reth_network_p2p::EthBlockClient; use reth_network_peers::NodeRecord; /// The `PeerId` type. @@ -43,7 +44,7 @@ pub type PeerId = alloy_primitives::B512; /// Helper trait that unifies network API needed to launch node. pub trait FullNetwork: - BlockDownloaderProvider + BlockDownloaderProvider + NetworkSyncUpdater + NetworkInfo + NetworkEventListenerProvider @@ -55,7 +56,7 @@ pub trait FullNetwork: } impl FullNetwork for T where - T: BlockDownloaderProvider + T: BlockDownloaderProvider + NetworkSyncUpdater + NetworkInfo + NetworkEventListenerProvider diff --git a/crates/net/network/Cargo.toml b/crates/net/network/Cargo.toml index f444aa7fe27..148eef34b36 100644 --- a/crates/net/network/Cargo.toml +++ b/crates/net/network/Cargo.toml @@ -34,6 +34,7 @@ reth-network-peers = { workspace = true, features = ["net"] } reth-network-types.workspace = true # ethereum +alloy-consensus.workspace = true alloy-eips.workspace = true alloy-primitives.workspace = true alloy-rlp.workspace = true diff --git a/crates/net/network/src/fetch/client.rs b/crates/net/network/src/fetch/client.rs index c47ee5d234f..584c079b8d8 100644 --- a/crates/net/network/src/fetch/client.rs +++ b/crates/net/network/src/fetch/client.rs @@ -7,6 +7,7 @@ use std::sync::{ use alloy_primitives::B256; use futures::{future, future::Either}; +use reth_eth_wire::{EthNetworkPrimitives, NetworkPrimitives}; use reth_network_api::test_utils::PeersHandle; use reth_network_p2p::{ bodies::client::{BodiesClient, BodiesFut}, @@ -17,7 +18,6 @@ use reth_network_p2p::{ }; use reth_network_peers::PeerId; use reth_network_types::ReputationChangeKind; -use reth_primitives::Header; use tokio::sync::{mpsc::UnboundedSender, oneshot}; use crate::{fetch::DownloadRequest, flattened_response::FlattenedResponse}; @@ -30,16 +30,16 @@ use crate::{fetch::DownloadRequest, flattened_response::FlattenedResponse}; /// /// include_mmd!("docs/mermaid/fetch-client.mmd") #[derive(Debug, Clone)] -pub struct FetchClient { +pub struct FetchClient { /// Sender half of the request channel. - pub(crate) request_tx: UnboundedSender, + pub(crate) request_tx: UnboundedSender>, /// The handle to the peers pub(crate) peers_handle: PeersHandle, /// Number of active peer sessions the node's currently handling. pub(crate) num_active_peers: Arc, } -impl DownloadClient for FetchClient { +impl DownloadClient for FetchClient { fn report_bad_message(&self, peer_id: PeerId) { self.peers_handle.reputation_change(peer_id, ReputationChangeKind::BadMessage); } @@ -53,8 +53,9 @@ impl DownloadClient for FetchClient { // or an error. type HeadersClientFuture = Either, future::Ready>; -impl HeadersClient for FetchClient { - type Output = HeadersClientFuture>>; +impl HeadersClient for FetchClient { + type Header = N::BlockHeader; + type Output = HeadersClientFuture>>; /// Sends a `GetBlockHeaders` request to an available peer. fn get_headers_with_priority( @@ -75,8 +76,9 @@ impl HeadersClient for FetchClient { } } -impl BodiesClient for FetchClient { - type Output = BodiesFut; +impl BodiesClient for FetchClient { + type Body = N::BlockBody; + type Output = BodiesFut; /// Sends a `GetBlockBodies` request to an available peer. fn get_block_bodies_with_priority( diff --git a/crates/net/network/src/fetch/mod.rs b/crates/net/network/src/fetch/mod.rs index d37fa8b4f4a..8af6300b705 100644 --- a/crates/net/network/src/fetch/mod.rs +++ b/crates/net/network/src/fetch/mod.rs @@ -15,7 +15,7 @@ use std::{ use alloy_primitives::B256; use futures::StreamExt; -use reth_eth_wire::{GetBlockBodies, GetBlockHeaders}; +use reth_eth_wire::{EthNetworkPrimitives, GetBlockBodies, GetBlockHeaders, NetworkPrimitives}; use reth_network_api::test_utils::PeersHandle; use reth_network_p2p::{ error::{EthResponseValidator, PeerRequestResult, RequestError, RequestResult}, @@ -24,12 +24,14 @@ use reth_network_p2p::{ }; use reth_network_peers::PeerId; use reth_network_types::ReputationChangeKind; -use reth_primitives::{BlockBody, Header}; use tokio::sync::{mpsc, mpsc::UnboundedSender, oneshot}; use tokio_stream::wrappers::UnboundedReceiverStream; use crate::message::BlockRequest; +type InflightHeadersRequest = Request>>; +type InflightBodiesRequest = Request, PeerRequestResult>>; + /// Manages data fetching operations. /// /// This type is hooked into the staged sync pipeline and delegates download request to available @@ -37,13 +39,11 @@ use crate::message::BlockRequest; /// /// This type maintains a list of connected peers that are available for requests. #[derive(Debug)] -pub struct StateFetcher { +pub struct StateFetcher { /// Currently active [`GetBlockHeaders`] requests - inflight_headers_requests: - HashMap>>>, + inflight_headers_requests: HashMap>, /// Currently active [`GetBlockBodies`] requests - inflight_bodies_requests: - HashMap, PeerRequestResult>>>, + inflight_bodies_requests: HashMap>, /// The list of _available_ peers for requests. peers: HashMap, /// The handle to the peers manager @@ -51,16 +51,16 @@ pub struct StateFetcher { /// Number of active peer sessions the node's currently handling. num_active_peers: Arc, /// Requests queued for processing - queued_requests: VecDeque, + queued_requests: VecDeque>, /// Receiver for new incoming download requests - download_requests_rx: UnboundedReceiverStream, + download_requests_rx: UnboundedReceiverStream>, /// Sender for download requests, used to detach a [`FetchClient`] - download_requests_tx: UnboundedSender, + download_requests_tx: UnboundedSender>, } // === impl StateSyncer === -impl StateFetcher { +impl StateFetcher { pub(crate) fn new(peers_handle: PeersHandle, num_active_peers: Arc) -> Self { let (download_requests_tx, download_requests_rx) = mpsc::unbounded_channel(); Self { @@ -217,7 +217,7 @@ impl StateFetcher { /// Handles a new request to a peer. /// /// Caution: this assumes the peer exists and is idle - fn prepare_block_request(&mut self, peer_id: PeerId, req: DownloadRequest) -> BlockRequest { + fn prepare_block_request(&mut self, peer_id: PeerId, req: DownloadRequest) -> BlockRequest { // update the peer's state if let Some(peer) = self.peers.get_mut(&peer_id) { peer.state = req.peer_state(); @@ -260,7 +260,7 @@ impl StateFetcher { pub(crate) fn on_block_headers_response( &mut self, peer_id: PeerId, - res: RequestResult>, + res: RequestResult>, ) -> Option { let is_error = res.is_err(); let maybe_reputation_change = res.reputation_change_err(); @@ -296,7 +296,7 @@ impl StateFetcher { pub(crate) fn on_block_bodies_response( &mut self, peer_id: PeerId, - res: RequestResult>, + res: RequestResult>, ) -> Option { let is_likely_bad_response = res.as_ref().map_or(true, |bodies| bodies.is_empty()); @@ -315,7 +315,7 @@ impl StateFetcher { } /// Returns a new [`FetchClient`] that can send requests to this type. - pub(crate) fn client(&self) -> FetchClient { + pub(crate) fn client(&self) -> FetchClient { FetchClient { request_tx: self.download_requests_tx.clone(), peers_handle: self.peers_handle.clone(), @@ -405,24 +405,24 @@ struct Request { /// Requests that can be sent to the Syncer from a [`FetchClient`] #[derive(Debug)] -pub(crate) enum DownloadRequest { +pub(crate) enum DownloadRequest { /// Download the requested headers and send response through channel GetBlockHeaders { request: HeadersRequest, - response: oneshot::Sender>>, + response: oneshot::Sender>>, priority: Priority, }, /// Download the requested headers and send response through channel GetBlockBodies { request: Vec, - response: oneshot::Sender>>, + response: oneshot::Sender>>, priority: Priority, }, } // === impl DownloadRequest === -impl DownloadRequest { +impl DownloadRequest { /// Returns the corresponding state for a peer that handles the request. const fn peer_state(&self) -> PeerState { match self { @@ -472,13 +472,14 @@ pub(crate) enum BlockResponseOutcome { mod tests { use super::*; use crate::{peers::PeersManager, PeersConfig}; + use alloy_consensus::Header; use alloy_primitives::B512; use std::future::poll_fn; #[tokio::test(flavor = "multi_thread")] async fn test_poll_fetcher() { let manager = PeersManager::new(PeersConfig::default()); - let mut fetcher = StateFetcher::new(manager.handle(), Default::default()); + let mut fetcher: StateFetcher = StateFetcher::new(manager.handle(), Default::default()); poll_fn(move |cx| { assert!(fetcher.poll(cx).is_pending()); @@ -498,7 +499,7 @@ mod tests { #[tokio::test] async fn test_peer_rotation() { let manager = PeersManager::new(PeersConfig::default()); - let mut fetcher = StateFetcher::new(manager.handle(), Default::default()); + let mut fetcher: StateFetcher = StateFetcher::new(manager.handle(), Default::default()); // Add a few random peers let peer1 = B512::random(); let peer2 = B512::random(); @@ -521,7 +522,7 @@ mod tests { #[tokio::test] async fn test_peer_prioritization() { let manager = PeersManager::new(PeersConfig::default()); - let mut fetcher = StateFetcher::new(manager.handle(), Default::default()); + let mut fetcher: StateFetcher = StateFetcher::new(manager.handle(), Default::default()); // Add a few random peers let peer1 = B512::random(); let peer2 = B512::random(); @@ -546,7 +547,7 @@ mod tests { #[tokio::test] async fn test_on_block_headers_response() { let manager = PeersManager::new(PeersConfig::default()); - let mut fetcher = StateFetcher::new(manager.handle(), Default::default()); + let mut fetcher: StateFetcher = StateFetcher::new(manager.handle(), Default::default()); let peer_id = B512::random(); assert_eq!(fetcher.on_block_headers_response(peer_id, Ok(vec![Header::default()])), None); @@ -576,7 +577,7 @@ mod tests { #[tokio::test] async fn test_header_response_outcome() { let manager = PeersManager::new(PeersConfig::default()); - let mut fetcher = StateFetcher::new(manager.handle(), Default::default()); + let mut fetcher: StateFetcher = StateFetcher::new(manager.handle(), Default::default()); let peer_id = B512::random(); let request_pair = || { @@ -610,7 +611,10 @@ mod tests { let outcome = fetcher.on_block_headers_response(peer_id, Err(RequestError::Timeout)).unwrap(); - assert!(EthResponseValidator::reputation_change_err(&Err(RequestError::Timeout)).is_some()); + assert!(EthResponseValidator::reputation_change_err(&Err::, _>( + RequestError::Timeout + )) + .is_some()); match outcome { BlockResponseOutcome::BadResponse(peer, _) => { diff --git a/crates/net/network/src/message.rs b/crates/net/network/src/message.rs index 6b8287fe51c..bdb13875f12 100644 --- a/crates/net/network/src/message.rs +++ b/crates/net/network/src/message.rs @@ -12,12 +12,13 @@ use alloy_primitives::{Bytes, B256}; use futures::FutureExt; use reth_eth_wire::{ capability::RawCapabilityMessage, message::RequestPair, BlockBodies, BlockHeaders, EthMessage, - GetBlockBodies, GetBlockHeaders, NewBlock, NewBlockHashes, NewPooledTransactionHashes, - NodeData, PooledTransactions, Receipts, SharedTransactions, Transactions, + EthNetworkPrimitives, GetBlockBodies, GetBlockHeaders, NetworkPrimitives, NewBlock, + NewBlockHashes, NewPooledTransactionHashes, NodeData, PooledTransactions, Receipts, + SharedTransactions, Transactions, }; use reth_network_api::PeerRequest; use reth_network_p2p::error::{RequestError, RequestResult}; -use reth_primitives::{BlockBody, Header, PooledTransactionsElement, ReceiptWithBloom}; +use reth_primitives::{PooledTransactionsElement, ReceiptWithBloom}; use tokio::sync::oneshot; /// Internal form of a `NewBlock` message @@ -74,16 +75,16 @@ pub enum BlockRequest { /// Corresponding variant for [`PeerRequest`]. #[derive(Debug)] -pub enum PeerResponse { +pub enum PeerResponse { /// Represents a response to a request for block headers. BlockHeaders { /// The receiver channel for the response to a block headers request. - response: oneshot::Receiver>, + response: oneshot::Receiver>>, }, /// Represents a response to a request for block bodies. BlockBodies { /// The receiver channel for the response to a block bodies request. - response: oneshot::Receiver>, + response: oneshot::Receiver>>, }, /// Represents a response to a request for pooled transactions. PooledTransactions { @@ -104,9 +105,9 @@ pub enum PeerResponse { // === impl PeerResponse === -impl PeerResponse { +impl PeerResponse { /// Polls the type to completion. - pub(crate) fn poll(&mut self, cx: &mut Context<'_>) -> Poll { + pub(crate) fn poll(&mut self, cx: &mut Context<'_>) -> Poll> { macro_rules! poll_request { ($response:ident, $item:ident, $cx:ident) => { match ready!($response.poll_unpin($cx)) { @@ -139,11 +140,11 @@ impl PeerResponse { /// All response variants for [`PeerResponse`] #[derive(Debug)] -pub enum PeerResponseResult { +pub enum PeerResponseResult { /// Represents a result containing block headers or an error. - BlockHeaders(RequestResult>), + BlockHeaders(RequestResult>), /// Represents a result containing block bodies or an error. - BlockBodies(RequestResult>), + BlockBodies(RequestResult>), /// Represents a result containing pooled transactions or an error. PooledTransactions(RequestResult>), /// Represents a result containing node data or an error. @@ -154,9 +155,9 @@ pub enum PeerResponseResult { // === impl PeerResponseResult === -impl PeerResponseResult { +impl PeerResponseResult { /// Converts this response into an [`EthMessage`] - pub fn try_into_message(self, id: u64) -> RequestResult { + pub fn try_into_message(self, id: u64) -> RequestResult> { macro_rules! to_message { ($response:ident, $item:ident, $request_id:ident) => { match $response { diff --git a/crates/net/network/src/network.rs b/crates/net/network/src/network.rs index 594ad4d155d..4175757e0cf 100644 --- a/crates/net/network/src/network.rs +++ b/crates/net/network/src/network.rs @@ -18,10 +18,7 @@ use reth_network_api::{ NetworkEventListenerProvider, NetworkInfo, NetworkStatus, PeerInfo, PeerRequest, Peers, PeersInfo, }; -use reth_network_p2p::{ - sync::{NetworkSyncUpdater, SyncState, SyncStateProvider}, - BlockClient, -}; +use reth_network_p2p::sync::{NetworkSyncUpdater, SyncState, SyncStateProvider}; use reth_network_peers::{NodeRecord, PeerId}; use reth_network_types::{PeerAddr, PeerKind, Reputation, ReputationChangeKind}; use reth_primitives::{Head, TransactionSigned}; @@ -400,7 +397,9 @@ impl NetworkSyncUpdater for NetworkHandle { } impl BlockDownloaderProvider for NetworkHandle { - async fn fetch_client(&self) -> Result { + type Client = FetchClient; + + async fn fetch_client(&self) -> Result { let (tx, rx) = oneshot::channel(); let _ = self.manager().send(NetworkHandleMessage::FetchClient(tx)); rx.await diff --git a/crates/net/network/src/state.rs b/crates/net/network/src/state.rs index 5caa656a98e..9ad7b53518b 100644 --- a/crates/net/network/src/state.rs +++ b/crates/net/network/src/state.rs @@ -14,7 +14,10 @@ use std::{ use alloy_primitives::B256; use rand::seq::SliceRandom; -use reth_eth_wire::{BlockHashNumber, Capabilities, DisconnectReason, NewBlockHashes, Status}; +use reth_eth_wire::{ + BlockHashNumber, Capabilities, DisconnectReason, EthNetworkPrimitives, NetworkPrimitives, + NewBlockHashes, Status, +}; use reth_network_api::{DiscoveredEvent, DiscoveryEvent, PeerRequest, PeerRequestSender}; use reth_network_peers::PeerId; use reth_network_types::{PeerAddr, PeerKind}; @@ -69,9 +72,9 @@ impl Deref for BlockNumReader { /// /// This type is also responsible for responding for received request. #[derive(Debug)] -pub struct NetworkState { +pub struct NetworkState { /// All active peers and their state. - active_peers: HashMap, + active_peers: HashMap>, /// Manages connections to peers. peers_manager: PeersManager, /// Buffered messages until polled. @@ -88,10 +91,10 @@ pub struct NetworkState { /// The fetcher streams `RLPx` related requests on a per-peer basis to this type. This type /// will then queue in the request and notify the fetcher once the result has been /// received. - state_fetcher: StateFetcher, + state_fetcher: StateFetcher, } -impl NetworkState { +impl NetworkState { /// Create a new state instance with the given params pub(crate) fn new( client: BlockNumReader, @@ -126,7 +129,7 @@ impl NetworkState { } /// Returns a new [`FetchClient`] - pub(crate) fn fetch_client(&self) -> FetchClient { + pub(crate) fn fetch_client(&self) -> FetchClient { self.state_fetcher.client() } @@ -144,7 +147,7 @@ impl NetworkState { peer: PeerId, capabilities: Arc, status: Arc, - request_tx: PeerRequestSender, + request_tx: PeerRequestSender>, timeout: Arc, ) { debug_assert!(!self.active_peers.contains_key(&peer), "Already connected; not possible"); @@ -399,7 +402,11 @@ impl NetworkState { /// Delegates the response result to the fetcher which may return an outcome specific /// instruction that needs to be handled in [`Self::on_block_response_outcome`]. This could be /// a follow-up request or an instruction to slash the peer's reputation. - fn on_eth_response(&mut self, peer: PeerId, resp: PeerResponseResult) -> Option { + fn on_eth_response( + &mut self, + peer: PeerId, + resp: PeerResponseResult, + ) -> Option { match resp { PeerResponseResult::BlockHeaders(res) => { let outcome = self.state_fetcher.on_block_headers_response(peer, res)?; @@ -492,16 +499,16 @@ impl NetworkState { /// /// For example known blocks,so we can decide what to announce. #[derive(Debug)] -pub(crate) struct ActivePeer { +pub(crate) struct ActivePeer { /// Best block of the peer. pub(crate) best_hash: B256, /// The capabilities of the remote peer. #[allow(dead_code)] pub(crate) capabilities: Arc, /// A communication channel directly to the session task. - pub(crate) request_tx: PeerRequestSender, + pub(crate) request_tx: PeerRequestSender>, /// The response receiver for a currently active request to that peer. - pub(crate) pending_response: Option, + pub(crate) pending_response: Option>, /// Blocks we know the peer has. pub(crate) blocks: LruCache, } diff --git a/crates/net/p2p/Cargo.toml b/crates/net/p2p/Cargo.toml index 89855396925..9348bf2d041 100644 --- a/crates/net/p2p/Cargo.toml +++ b/crates/net/p2p/Cargo.toml @@ -22,6 +22,7 @@ reth-network-types.workspace = true reth-storage-errors.workspace = true # ethereum +alloy-consensus.workspace = true alloy-eips.workspace = true alloy-primitives.workspace = true @@ -55,5 +56,6 @@ std = [ "reth-primitives/std", "alloy-eips/std", "alloy-primitives/std", - "reth-primitives-traits/std" + "reth-primitives-traits/std", + "alloy-consensus/std", ] diff --git a/crates/net/p2p/src/bodies/client.rs b/crates/net/p2p/src/bodies/client.rs index 2a4b57c2345..d48fccc6d00 100644 --- a/crates/net/p2p/src/bodies/client.rs +++ b/crates/net/p2p/src/bodies/client.rs @@ -9,13 +9,16 @@ use futures::{Future, FutureExt}; use reth_primitives::BlockBody; /// The bodies future type -pub type BodiesFut = Pin>> + Send + Sync>>; +pub type BodiesFut = + Pin>> + Send + Sync>>; /// A client capable of downloading block bodies. #[auto_impl::auto_impl(&, Arc, Box)] pub trait BodiesClient: DownloadClient { + /// The body type this client fetches. + type Body: Send + Sync + Unpin + 'static; /// The output of the request future for querying block bodies. - type Output: Future>> + Sync + Send + Unpin; + type Output: Future>> + Sync + Send + Unpin; /// Fetches the block body for the requested block. fn get_block_bodies(&self, hashes: Vec) -> Self::Output { @@ -49,11 +52,11 @@ pub struct SingleBodyRequest { fut: Fut, } -impl Future for SingleBodyRequest +impl Future for SingleBodyRequest where - Fut: Future>> + Sync + Send + Unpin, + Fut: Future>> + Sync + Send + Unpin, { - type Output = PeerRequestResult>; + type Output = PeerRequestResult>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let resp = ready!(self.get_mut().fut.poll_unpin(cx)); diff --git a/crates/net/p2p/src/bodies/downloader.rs b/crates/net/p2p/src/bodies/downloader.rs index b55229fa242..f335b21438b 100644 --- a/crates/net/p2p/src/bodies/downloader.rs +++ b/crates/net/p2p/src/bodies/downloader.rs @@ -5,14 +5,19 @@ use futures::Stream; use std::ops::RangeInclusive; /// Body downloader return type. -pub type BodyDownloaderResult = DownloadResult>; +pub type BodyDownloaderResult = DownloadResult>>; /// A downloader capable of fetching and yielding block bodies from block headers. /// /// A downloader represents a distinct strategy for submitting requests to download block bodies, /// while a [`BodiesClient`][crate::bodies::client::BodiesClient] represents a client capable of /// fulfilling these requests. -pub trait BodyDownloader: Send + Sync + Stream + Unpin { +pub trait BodyDownloader: + Send + Sync + Stream> + Unpin +{ + /// The type of the body that is being downloaded. + type Body: Send + Sync + Unpin + 'static; + /// Method for setting the download range. fn set_download_range(&mut self, range: RangeInclusive) -> DownloadResult<()>; } diff --git a/crates/net/p2p/src/bodies/response.rs b/crates/net/p2p/src/bodies/response.rs index 0a45008acd8..8737647bd79 100644 --- a/crates/net/p2p/src/bodies/response.rs +++ b/crates/net/p2p/src/bodies/response.rs @@ -1,17 +1,17 @@ use alloy_primitives::{BlockNumber, U256}; -use reth_primitives::{SealedBlock, SealedHeader}; +use reth_primitives::{BlockBody, SealedBlock, SealedHeader}; use reth_primitives_traits::InMemorySize; /// The block response #[derive(PartialEq, Eq, Debug, Clone)] -pub enum BlockResponse { +pub enum BlockResponse { /// Full block response (with transactions or ommers) - Full(SealedBlock), + Full(SealedBlock), /// The empty block response Empty(SealedHeader), } -impl BlockResponse { +impl BlockResponse { /// Return the reference to the response header pub const fn header(&self) -> &SealedHeader { match self { @@ -34,8 +34,7 @@ impl BlockResponse { } } -impl InMemorySize for BlockResponse { - /// Calculates a heuristic for the in-memory size of the [`BlockResponse`]. +impl InMemorySize for BlockResponse { #[inline] fn size(&self) -> usize { match self { diff --git a/crates/net/p2p/src/either.rs b/crates/net/p2p/src/either.rs index 30650069b91..3f1182bd482 100644 --- a/crates/net/p2p/src/either.rs +++ b/crates/net/p2p/src/either.rs @@ -32,8 +32,9 @@ where impl BodiesClient for Either where A: BodiesClient, - B: BodiesClient, + B: BodiesClient, { + type Body = A::Body; type Output = Either; fn get_block_bodies_with_priority( @@ -51,8 +52,9 @@ where impl HeadersClient for Either where A: HeadersClient, - B: HeadersClient, + B: HeadersClient
, { + type Header = A::Header; type Output = Either; fn get_headers_with_priority( diff --git a/crates/net/p2p/src/error.rs b/crates/net/p2p/src/error.rs index 9394a9fdf6c..181a0b96b3c 100644 --- a/crates/net/p2p/src/error.rs +++ b/crates/net/p2p/src/error.rs @@ -1,13 +1,14 @@ use std::ops::RangeInclusive; use super::headers::client::HeadersRequest; +use alloy_consensus::BlockHeader; use alloy_eips::BlockHashOrNumber; use alloy_primitives::{BlockNumber, B256}; use derive_more::{Display, Error}; use reth_consensus::ConsensusError; use reth_network_peers::WithPeerId; use reth_network_types::ReputationChangeKind; -use reth_primitives::{GotExpected, GotExpectedBoxed, Header}; +use reth_primitives::{GotExpected, GotExpectedBoxed}; use reth_storage_errors::{db::DatabaseError, provider::ProviderError}; use tokio::sync::{mpsc, oneshot}; @@ -26,7 +27,7 @@ pub trait EthResponseValidator { fn reputation_change_err(&self) -> Option; } -impl EthResponseValidator for RequestResult> { +impl EthResponseValidator for RequestResult> { fn is_likely_bad_headers_response(&self, request: &HeadersRequest) -> bool { match self { Ok(headers) => { @@ -38,7 +39,7 @@ impl EthResponseValidator for RequestResult> { match request.start { BlockHashOrNumber::Number(block_number) => { - headers.first().is_some_and(|header| block_number != header.number) + headers.first().is_some_and(|header| block_number != header.number()) } BlockHashOrNumber::Hash(_) => { // we don't want to hash the header @@ -216,6 +217,8 @@ impl From for DownloadError { #[cfg(test)] mod tests { + use alloy_consensus::Header; + use super::*; #[test] diff --git a/crates/net/p2p/src/full_block.rs b/crates/net/p2p/src/full_block.rs index a61d4ea126d..8f176f8da8a 100644 --- a/crates/net/p2p/src/full_block.rs +++ b/crates/net/p2p/src/full_block.rs @@ -5,16 +5,18 @@ use crate::{ headers::client::{HeadersClient, SingleHeaderRequest}, BlockClient, }; +use alloy_consensus::BlockHeader; use alloy_primitives::{Sealable, B256}; use reth_consensus::Consensus; use reth_eth_wire_types::HeadersDirection; use reth_network_peers::WithPeerId; -use reth_primitives::{BlockBody, Header, SealedBlock, SealedHeader}; +use reth_primitives::{SealedBlock, SealedHeader}; use std::{ cmp::Reverse, collections::{HashMap, VecDeque}, fmt::Debug, future::Future, + hash::Hash, pin::Pin, sync::Arc, task::{ready, Context, Poll}, @@ -23,14 +25,23 @@ use tracing::debug; /// A Client that can fetch full blocks from the network. #[derive(Debug, Clone)] -pub struct FullBlockClient { +pub struct FullBlockClient +where + Client: BlockClient, +{ client: Client, - consensus: Arc, + consensus: Arc>, } -impl FullBlockClient { +impl FullBlockClient +where + Client: BlockClient, +{ /// Creates a new instance of `FullBlockClient`. - pub fn new(client: Client, consensus: Arc) -> Self { + pub fn new( + client: Client, + consensus: Arc>, + ) -> Self { Self { client, consensus } } @@ -111,16 +122,16 @@ where Client: BlockClient, { client: Client, - consensus: Arc, + consensus: Arc>, hash: B256, request: FullBlockRequest, - header: Option, - body: Option, + header: Option>, + body: Option>, } impl FetchFullBlockFuture where - Client: BlockClient, + Client: BlockClient, { /// Returns the hash of the block being requested. pub const fn hash(&self) -> &B256 { @@ -129,11 +140,11 @@ where /// If the header request is already complete, this returns the block number pub fn block_number(&self) -> Option { - self.header.as_ref().map(|h| h.number) + self.header.as_ref().map(|h| h.number()) } /// Returns the [`SealedBlock`] if the request is complete and valid. - fn take_block(&mut self) -> Option { + fn take_block(&mut self) -> Option> { if self.header.is_none() || self.body.is_none() { return None } @@ -157,7 +168,7 @@ where } } - fn on_block_response(&mut self, resp: WithPeerId) { + fn on_block_response(&mut self, resp: WithPeerId) { if let Some(ref header) = self.header { if let Err(err) = self.consensus.validate_body_against_header(resp.data(), header) { debug!(target: "downloaders", %err, hash=?header.hash(), "Received wrong body"); @@ -173,9 +184,9 @@ where impl Future for FetchFullBlockFuture where - Client: BlockClient + 'static, + Client: BlockClient + 'static, { - type Output = SealedBlock; + type Output = SealedBlock; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.get_mut(); @@ -252,7 +263,7 @@ where impl Debug for FetchFullBlockFuture where - Client: BlockClient, + Client: BlockClient, { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("FetchFullBlockFuture") @@ -275,7 +286,7 @@ impl FullBlockRequest where Client: BlockClient, { - fn poll(&mut self, cx: &mut Context<'_>) -> Poll { + fn poll(&mut self, cx: &mut Context<'_>) -> Poll> { if let Some(fut) = Pin::new(&mut self.header).as_pin_mut() { if let Poll::Ready(res) = fut.poll(cx) { self.header = None; @@ -296,18 +307,18 @@ where /// The result of a request for a single header or body. This is yielded by the `FullBlockRequest` /// future. -enum ResponseResult { - Header(PeerRequestResult>), - Body(PeerRequestResult>), +enum ResponseResult { + Header(PeerRequestResult>), + Body(PeerRequestResult>), } /// The response of a body request. #[derive(Debug)] -enum BodyResponse { +enum BodyResponse { /// Already validated against transaction root of header - Validated(BlockBody), + Validated(B), /// Still needs to be validated against header - PendingValidation(WithPeerId), + PendingValidation(WithPeerId), } /// A future that downloads a range of full blocks from the network. /// @@ -330,7 +341,7 @@ where /// The client used to fetch headers and bodies. client: Client, /// The consensus instance used to validate the blocks. - consensus: Arc, + consensus: Arc>, /// The block hash to start fetching from (inclusive). start_hash: B256, /// How many blocks to fetch: `len([start_hash, ..]) == count` @@ -338,16 +349,16 @@ where /// Requests for headers and bodies that are in progress. request: FullBlockRangeRequest, /// Fetched headers. - headers: Option>, + headers: Option>>, /// The next headers to request bodies for. This is drained as responses are received. - pending_headers: VecDeque, + pending_headers: VecDeque>, /// The bodies that have been received so far. - bodies: HashMap, + bodies: HashMap, BodyResponse>, } impl FetchFullBlockRangeFuture where - Client: BlockClient, + Client: BlockClient, { /// Returns the block hashes for the given range, if they are available. pub fn range_block_hashes(&self) -> Option> { @@ -362,14 +373,14 @@ where /// Inserts a block body, matching it with the `next_header`. /// /// Note: this assumes the response matches the next header in the queue. - fn insert_body(&mut self, body_response: BodyResponse) { + fn insert_body(&mut self, body_response: BodyResponse) { if let Some(header) = self.pending_headers.pop_front() { self.bodies.insert(header, body_response); } } /// Inserts multiple block bodies. - fn insert_bodies(&mut self, bodies: impl IntoIterator) { + fn insert_bodies(&mut self, bodies: impl IntoIterator>) { for body in bodies { self.insert_body(body); } @@ -388,7 +399,7 @@ where /// /// These are returned in falling order starting with the requested `hash`, i.e. with /// descending block numbers. - fn take_blocks(&mut self) -> Option> { + fn take_blocks(&mut self) -> Option>> { if !self.is_bodies_complete() { // not done with bodies yet return None @@ -445,7 +456,7 @@ where Some(valid_responses) } - fn on_headers_response(&mut self, headers: WithPeerId>) { + fn on_headers_response(&mut self, headers: WithPeerId>) { let (peer, mut headers_falling) = headers .map(|h| { h.into_iter() @@ -461,7 +472,7 @@ where // fill in the response if it's the correct length if headers_falling.len() == self.count as usize { // sort headers from highest to lowest block number - headers_falling.sort_unstable_by_key(|h| Reverse(h.number)); + headers_falling.sort_unstable_by_key(|h| Reverse(h.number())); // check the starting hash if headers_falling[0].hash() == self.start_hash { @@ -512,9 +523,9 @@ where impl Future for FetchFullBlockRangeFuture where - Client: BlockClient + 'static, + Client: BlockClient + 'static, { - type Output = Vec; + type Output = Vec>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.get_mut(); @@ -621,7 +632,10 @@ impl FullBlockRangeRequest where Client: BlockClient, { - fn poll(&mut self, cx: &mut Context<'_>) -> Poll { + fn poll( + &mut self, + cx: &mut Context<'_>, + ) -> Poll> { if let Some(fut) = Pin::new(&mut self.headers).as_pin_mut() { if let Poll::Ready(res) = fut.poll(cx) { self.headers = None; @@ -642,13 +656,15 @@ where // The result of a request for headers or block bodies. This is yielded by the // `FullBlockRangeRequest` future. -enum RangeResponseResult { - Header(PeerRequestResult>), - Body(PeerRequestResult>), +enum RangeResponseResult { + Header(PeerRequestResult>), + Body(PeerRequestResult>), } #[cfg(test)] mod tests { + use reth_primitives::BlockBody; + use super::*; use crate::test_utils::TestFullBlockClient; use std::ops::Range; diff --git a/crates/net/p2p/src/headers/client.rs b/crates/net/p2p/src/headers/client.rs index b73ea4e925f..585f2ab18a0 100644 --- a/crates/net/p2p/src/headers/client.rs +++ b/crates/net/p2p/src/headers/client.rs @@ -27,8 +27,10 @@ pub type HeadersFut = Pin> /// The block headers downloader client #[auto_impl::auto_impl(&, Arc, Box)] pub trait HeadersClient: DownloadClient { + /// The header type this client fetches. + type Header: Send + Sync + Unpin; /// The headers future type - type Output: Future>> + Sync + Send + Unpin; + type Output: Future>> + Sync + Send + Unpin; /// Sends the header request to the p2p network and returns the header response received from a /// peer. @@ -73,11 +75,11 @@ pub struct SingleHeaderRequest { fut: Fut, } -impl Future for SingleHeaderRequest +impl Future for SingleHeaderRequest where - Fut: Future>> + Sync + Send + Unpin, + Fut: Future>> + Sync + Send + Unpin, { - type Output = PeerRequestResult>; + type Output = PeerRequestResult>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let resp = ready!(self.get_mut().fut.poll_unpin(cx)); diff --git a/crates/net/p2p/src/headers/downloader.rs b/crates/net/p2p/src/headers/downloader.rs index 5565880ed39..59ecb58b84d 100644 --- a/crates/net/p2p/src/headers/downloader.rs +++ b/crates/net/p2p/src/headers/downloader.rs @@ -1,5 +1,6 @@ use super::error::HeadersDownloaderResult; use crate::error::{DownloadError, DownloadResult}; +use alloy_consensus::BlockHeader; use alloy_eips::BlockHashOrNumber; use alloy_primitives::B256; use futures::Stream; @@ -13,19 +14,25 @@ use reth_primitives::SealedHeader; /// /// A [`HeaderDownloader`] is a [Stream] that returns batches of headers. pub trait HeaderDownloader: - Send + Sync + Stream>> + Unpin + Send + + Sync + + Stream>, Self::Header>> + + Unpin { + /// The header type being downloaded. + type Header: Send + Sync + Unpin + 'static; + /// Updates the gap to sync which ranges from local head to the sync target /// /// See also [`HeaderDownloader::update_sync_target`] and /// [`HeaderDownloader::update_local_head`] - fn update_sync_gap(&mut self, head: SealedHeader, target: SyncTarget) { + fn update_sync_gap(&mut self, head: SealedHeader, target: SyncTarget) { self.update_local_head(head); self.update_sync_target(target); } /// Updates the block number of the local database - fn update_local_head(&mut self, head: SealedHeader); + fn update_local_head(&mut self, head: SealedHeader); /// Updates the target we want to sync to fn update_sync_target(&mut self, target: SyncTarget); @@ -74,23 +81,23 @@ impl SyncTarget { /// Validate whether the header is valid in relation to it's parent /// /// Returns Ok(false) if the -pub fn validate_header_download( - consensus: &dyn Consensus, - header: &SealedHeader, - parent: &SealedHeader, +pub fn validate_header_download( + consensus: &dyn Consensus, + header: &SealedHeader, + parent: &SealedHeader, ) -> DownloadResult<()> { // validate header against parent consensus.validate_header_against_parent(header, parent).map_err(|error| { DownloadError::HeaderValidation { hash: header.hash(), - number: header.number, + number: header.number(), error: Box::new(error), } })?; // validate header standalone consensus.validate_header(header).map_err(|error| DownloadError::HeaderValidation { hash: header.hash(), - number: header.number, + number: header.number(), error: Box::new(error), })?; Ok(()) diff --git a/crates/net/p2p/src/headers/error.rs b/crates/net/p2p/src/headers/error.rs index b22aae9248e..8757bb215f5 100644 --- a/crates/net/p2p/src/headers/error.rs +++ b/crates/net/p2p/src/headers/error.rs @@ -3,19 +3,19 @@ use reth_consensus::ConsensusError; use reth_primitives::SealedHeader; /// Header downloader result -pub type HeadersDownloaderResult = Result; +pub type HeadersDownloaderResult = Result>; /// Error variants that can happen when sending requests to a session. #[derive(Debug, Clone, Eq, PartialEq, Display, Error)] -pub enum HeadersDownloaderError { +pub enum HeadersDownloaderError { /// The downloaded header cannot be attached to the local head, /// but is valid otherwise. #[display("valid downloaded header cannot be attached to the local head: {error}")] DetachedHead { /// The local head we attempted to attach to. - local_head: Box, + local_head: Box>, /// The header we attempted to attach. - header: Box, + header: Box>, /// The error that occurred when attempting to attach the header. #[error(source)] error: Box, diff --git a/crates/net/p2p/src/lib.rs b/crates/net/p2p/src/lib.rs index 2ba8012f0ae..98d83c2d1a8 100644 --- a/crates/net/p2p/src/lib.rs +++ b/crates/net/p2p/src/lib.rs @@ -52,3 +52,14 @@ pub use headers::client::HeadersClient; pub trait BlockClient: HeadersClient + BodiesClient + Unpin + Clone {} impl BlockClient for T where T: HeadersClient + BodiesClient + Unpin + Clone {} + +/// The [`BlockClient`] providing Ethereum block parts. +pub trait EthBlockClient: + BlockClient
+{ +} + +impl EthBlockClient for T where + T: BlockClient
+{ +} diff --git a/crates/net/p2p/src/test_utils/bodies.rs b/crates/net/p2p/src/test_utils/bodies.rs index cfd29212916..0689d403f2c 100644 --- a/crates/net/p2p/src/test_utils/bodies.rs +++ b/crates/net/p2p/src/test_utils/bodies.rs @@ -36,6 +36,7 @@ impl BodiesClient for TestBodiesClient where F: Fn(Vec) -> PeerRequestResult> + Send + Sync, { + type Body = BlockBody; type Output = BodiesFut; fn get_block_bodies_with_priority( diff --git a/crates/net/p2p/src/test_utils/full_block.rs b/crates/net/p2p/src/test_utils/full_block.rs index 8a13f69325d..97d867531ad 100644 --- a/crates/net/p2p/src/test_utils/full_block.rs +++ b/crates/net/p2p/src/test_utils/full_block.rs @@ -40,6 +40,7 @@ impl DownloadClient for NoopFullBlockClient { /// Implements the `BodiesClient` trait for the `NoopFullBlockClient` struct. impl BodiesClient for NoopFullBlockClient { + type Body = BlockBody; /// Defines the output type of the function. type Output = futures::future::Ready>>; @@ -65,6 +66,7 @@ impl BodiesClient for NoopFullBlockClient { } impl HeadersClient for NoopFullBlockClient { + type Header = Header; /// The output type representing a future containing a peer request result with a vector of /// headers. type Output = futures::future::Ready>>; @@ -152,6 +154,7 @@ impl DownloadClient for TestFullBlockClient { /// Implements the `HeadersClient` trait for the `TestFullBlockClient` struct. impl HeadersClient for TestFullBlockClient { + type Header = Header; /// Specifies the associated output type. type Output = futures::future::Ready>>; @@ -205,6 +208,7 @@ impl HeadersClient for TestFullBlockClient { /// Implements the `BodiesClient` trait for the `TestFullBlockClient` struct. impl BodiesClient for TestFullBlockClient { + type Body = BlockBody; /// Defines the output type of the function. type Output = futures::future::Ready>>; diff --git a/crates/net/p2p/src/test_utils/headers.rs b/crates/net/p2p/src/test_utils/headers.rs index 4f603f6339b..d8d4bbc6b7a 100644 --- a/crates/net/p2p/src/test_utils/headers.rs +++ b/crates/net/p2p/src/test_utils/headers.rs @@ -62,6 +62,8 @@ impl TestHeaderDownloader { } impl HeaderDownloader for TestHeaderDownloader { + type Header = Header; + fn update_local_head(&mut self, _head: SealedHeader) {} fn update_sync_target(&mut self, _target: SyncTarget) {} @@ -72,7 +74,7 @@ impl HeaderDownloader for TestHeaderDownloader { } impl Stream for TestHeaderDownloader { - type Item = HeadersDownloaderResult>; + type Item = HeadersDownloaderResult, Header>; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.get_mut(); @@ -229,6 +231,7 @@ impl DownloadClient for TestHeadersClient { } impl HeadersClient for TestHeadersClient { + type Header = Header; type Output = TestHeadersFut; fn get_headers_with_priority( diff --git a/crates/node/builder/src/launch/common.rs b/crates/node/builder/src/launch/common.rs index 856f86c6fe0..ec4912fdd86 100644 --- a/crates/node/builder/src/launch/common.rs +++ b/crates/node/builder/src/launch/common.rs @@ -760,7 +760,7 @@ where /// necessary pub async fn max_block(&self, client: C) -> eyre::Result> where - C: HeadersClient, + C: HeadersClient
, { self.node_config().max_block(client, self.provider_factory().clone()).await } diff --git a/crates/node/builder/src/setup.rs b/crates/node/builder/src/setup.rs index 3591868ddad..d8405dad77f 100644 --- a/crates/node/builder/src/setup.rs +++ b/crates/node/builder/src/setup.rs @@ -12,7 +12,7 @@ use reth_downloaders::{ use reth_evm::execute::BlockExecutorProvider; use reth_exex::ExExManagerHandle; use reth_network_p2p::{ - bodies::downloader::BodyDownloader, headers::downloader::HeaderDownloader, BlockClient, + bodies::downloader::BodyDownloader, headers::downloader::HeaderDownloader, EthBlockClient, }; use reth_provider::{providers::ProviderNodeTypes, ProviderFactory}; use reth_stages::{prelude::DefaultStages, stages::ExecutionStage, Pipeline, StageSet}; @@ -38,7 +38,7 @@ pub fn build_networked_pipeline( ) -> eyre::Result> where N: ProviderNodeTypes, - Client: BlockClient + 'static, + Client: EthBlockClient + 'static, Executor: BlockExecutorProvider, { // building network downloaders using the fetch client @@ -84,8 +84,8 @@ pub fn build_pipeline( ) -> eyre::Result> where N: ProviderNodeTypes, - H: HeaderDownloader + 'static, - B: BodyDownloader + 'static, + H: HeaderDownloader
+ 'static, + B: BodyDownloader + 'static, Executor: BlockExecutorProvider, { let mut builder = Pipeline::::builder(); diff --git a/crates/node/core/Cargo.toml b/crates/node/core/Cargo.toml index 1c6c9d98c80..c667a56293c 100644 --- a/crates/node/core/Cargo.toml +++ b/crates/node/core/Cargo.toml @@ -13,7 +13,9 @@ workspace = true [dependencies] # reth reth-chainspec.workspace = true +reth-consensus.workspace = true reth-primitives.workspace = true +reth-primitives-traits.workspace = true reth-cli-util.workspace = true reth-db = { workspace = true, features = ["mdbx"] } reth-storage-errors.workspace = true @@ -30,7 +32,6 @@ reth-discv4.workspace = true reth-discv5.workspace = true reth-net-nat.workspace = true reth-network-peers.workspace = true -reth-consensus-common.workspace = true reth-prune-types.workspace = true reth-stages-types.workspace = true diff --git a/crates/node/core/src/node_config.rs b/crates/node/core/src/node_config.rs index 3848772c415..24d5588b688 100644 --- a/crates/node/core/src/node_config.rs +++ b/crates/node/core/src/node_config.rs @@ -8,6 +8,7 @@ use crate::{ dirs::{ChainPath, DataDirPath}, utils::get_single_header, }; +use alloy_consensus::BlockHeader; use eyre::eyre; use reth_chainspec::{ChainSpec, EthChainSpec, MAINNET}; use reth_config::config::PruneConfig; @@ -273,7 +274,7 @@ impl NodeConfig { ) -> eyre::Result> where Provider: HeaderProvider, - Client: HeadersClient, + Client: HeadersClient, { let max_block = if let Some(block) = self.debug.max_block { Some(block) @@ -332,7 +333,7 @@ impl NodeConfig { ) -> ProviderResult where Provider: HeaderProvider, - Client: HeadersClient, + Client: HeadersClient, { let header = provider.header_by_hash_or_number(tip.into())?; @@ -342,7 +343,7 @@ impl NodeConfig { return Ok(header.number) } - Ok(self.fetch_tip_from_network(client, tip.into()).await.number) + Ok(self.fetch_tip_from_network(client, tip.into()).await.number()) } /// Attempt to look up the block with the given number and return the header. @@ -352,9 +353,9 @@ impl NodeConfig { &self, client: Client, tip: BlockHashOrNumber, - ) -> SealedHeader + ) -> SealedHeader where - Client: HeadersClient, + Client: HeadersClient, { info!(target: "reth::cli", ?tip, "Fetching tip block from the network."); let mut fetch_failures = 0; diff --git a/crates/node/core/src/utils.rs b/crates/node/core/src/utils.rs index a04d4e324e1..7aeb14c4c0e 100644 --- a/crates/node/core/src/utils.rs +++ b/crates/node/core/src/utils.rs @@ -1,12 +1,12 @@ //! Utility functions for node startup and shutdown, for example path parsing and retrieving single //! blocks from the network. +use alloy_consensus::BlockHeader; use alloy_eips::BlockHashOrNumber; use alloy_primitives::Sealable; use alloy_rpc_types_engine::{JwtError, JwtSecret}; use eyre::Result; -use reth_chainspec::ChainSpec; -use reth_consensus_common::validation::validate_block_pre_execution; +use reth_consensus::Consensus; use reth_network_p2p::{ bodies::client::BodiesClient, headers::client::{HeadersClient, HeadersDirection, HeadersRequest}, @@ -16,7 +16,6 @@ use reth_primitives::{SealedBlock, SealedHeader}; use std::{ env::VarError, path::{Path, PathBuf}, - sync::Arc, }; use tracing::{debug, info}; @@ -41,9 +40,9 @@ pub fn get_or_create_jwt_secret_from_path(path: &Path) -> Result( client: Client, id: BlockHashOrNumber, -) -> Result +) -> Result> where - Client: HeadersClient, + Client: HeadersClient, { let request = HeadersRequest { direction: HeadersDirection::Rising, limit: 1, start: id }; @@ -61,7 +60,7 @@ where let valid = match id { BlockHashOrNumber::Hash(hash) => header.hash() == hash, - BlockHashOrNumber::Number(number) => header.number == number, + BlockHashOrNumber::Number(number) => header.number() == number, }; if !valid { @@ -77,11 +76,11 @@ where } /// Get a body from network based on header -pub async fn get_single_body( +pub async fn get_single_body( client: Client, - chain_spec: Arc, - header: SealedHeader, -) -> Result + header: SealedHeader, + consensus: impl Consensus, +) -> Result> where Client: BodiesClient, { @@ -95,7 +94,7 @@ where let body = response.unwrap(); let block = SealedBlock { header, body }; - validate_block_pre_execution(&block, &chain_spec)?; + consensus.validate_block_pre_execution(&block)?; Ok(block) } diff --git a/crates/primitives-traits/src/block/header.rs b/crates/primitives-traits/src/block/header.rs index 8ad85a5961a..7ab76f24987 100644 --- a/crates/primitives-traits/src/block/header.rs +++ b/crates/primitives-traits/src/block/header.rs @@ -5,6 +5,8 @@ use core::fmt; use alloy_primitives::Sealable; use reth_codecs::Compact; +use crate::InMemorySize; + /// Helper trait that unifies all behaviour required by block header to support full node /// operations. pub trait FullBlockHeader: BlockHeader + Compact {} @@ -21,12 +23,11 @@ pub trait BlockHeader: + fmt::Debug + PartialEq + Eq - + serde::Serialize - + for<'de> serde::Deserialize<'de> + alloy_rlp::Encodable + alloy_rlp::Decodable + alloy_consensus::BlockHeader + Sealable + + InMemorySize { } @@ -45,5 +46,6 @@ impl BlockHeader for T where + alloy_rlp::Decodable + alloy_consensus::BlockHeader + Sealable + + InMemorySize { } diff --git a/crates/primitives-traits/src/header/sealed.rs b/crates/primitives-traits/src/header/sealed.rs index 995c13748b3..b0fe4434298 100644 --- a/crates/primitives-traits/src/header/sealed.rs +++ b/crates/primitives-traits/src/header/sealed.rs @@ -56,10 +56,10 @@ impl SealedHeader { } } -impl SealedHeader { +impl SealedHeader { /// Return the number hash tuple. pub fn num_hash(&self) -> BlockNumHash { - BlockNumHash::new(self.number, self.hash) + BlockNumHash::new(self.number(), self.hash) } } diff --git a/crates/primitives-traits/src/size.rs b/crates/primitives-traits/src/size.rs index 173f8cedc9e..0c250688e05 100644 --- a/crates/primitives-traits/src/size.rs +++ b/crates/primitives-traits/src/size.rs @@ -3,3 +3,9 @@ pub trait InMemorySize { /// Returns a heuristic for the in-memory size of a struct. fn size(&self) -> usize; } + +impl InMemorySize for alloy_consensus::Header { + fn size(&self) -> usize { + self.size() + } +} diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index 275f86c5b45..c0586ed6a8f 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -428,8 +428,7 @@ impl SealedBlock { } } -impl InMemorySize for SealedBlock { - /// Calculates a heuristic for the in-memory size of the [`SealedBlock`]. +impl InMemorySize for SealedBlock { #[inline] fn size(&self) -> usize { self.header.size() + self.body.size() diff --git a/crates/stages/stages/src/stages/bodies.rs b/crates/stages/stages/src/stages/bodies.rs index 06a5250913e..021a9ab192c 100644 --- a/crates/stages/stages/src/stages/bodies.rs +++ b/crates/stages/stages/src/stages/bodies.rs @@ -60,7 +60,7 @@ pub struct BodyStage { /// The body downloader. downloader: D, /// Block response buffer. - buffer: Option>, + buffer: Option>>, } impl BodyStage { @@ -70,9 +70,10 @@ impl BodyStage { } } -impl Stage for BodyStage +impl Stage for BodyStage where Provider: DBProvider + StaticFileProviderFactory + StatsReader + BlockReader, + D: BodyDownloader, { /// Return the id of the stage fn id(&self) -> StageId { @@ -889,6 +890,8 @@ mod tests { } impl BodyDownloader for TestBodyDownloader { + type Body = BlockBody; + fn set_download_range( &mut self, range: RangeInclusive, @@ -909,7 +912,7 @@ mod tests { } impl Stream for TestBodyDownloader { - type Item = BodyDownloaderResult; + type Item = BodyDownloaderResult; fn poll_next(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { let this = self.get_mut(); diff --git a/crates/stages/stages/src/stages/headers.rs b/crates/stages/stages/src/stages/headers.rs index 49e687a96a1..2be78b88169 100644 --- a/crates/stages/stages/src/stages/headers.rs +++ b/crates/stages/stages/src/stages/headers.rs @@ -194,7 +194,7 @@ where impl Stage for HeaderStage where P: HeaderSyncGapProvider, - D: HeaderDownloader, + D: HeaderDownloader
, Provider: DBProvider + StaticFileProviderFactory, { /// Return the id of the stage @@ -441,7 +441,9 @@ mod tests { } } - impl StageTestRunner for HeadersTestRunner { + impl + 'static> StageTestRunner + for HeadersTestRunner + { type S = HeaderStage, D>; fn db(&self) -> &TestStageDB { @@ -459,7 +461,9 @@ mod tests { } } - impl ExecuteStageTestRunner for HeadersTestRunner { + impl + 'static> ExecuteStageTestRunner + for HeadersTestRunner + { type Seed = Vec; fn seed_execution(&mut self, input: ExecInput) -> Result { @@ -537,7 +541,9 @@ mod tests { } } - impl UnwindStageTestRunner for HeadersTestRunner { + impl + 'static> UnwindStageTestRunner + for HeadersTestRunner + { fn validate_unwind(&self, input: UnwindInput) -> Result<(), TestRunnerError> { self.check_no_header_entry_above(input.unwind_to) } From 0cd34f911ca693a08d31d37e54abc575efdf9696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Narzis?= <78718413+lean-apple@users.noreply.github.com> Date: Tue, 12 Nov 2024 22:27:28 +0700 Subject: [PATCH 125/211] feat: add ovm `BlockFileCodec` (#12247) Co-authored-by: Emilia Hane --- Cargo.lock | 4 + crates/consensus/beacon/Cargo.toml | 17 +- crates/net/downloaders/Cargo.toml | 13 +- crates/net/downloaders/src/file_client.rs | 3 +- crates/optimism/cli/Cargo.toml | 26 +- crates/optimism/cli/src/lib.rs | 5 + crates/optimism/cli/src/ovm_file_codec.rs | 382 ++++++++++++++++++++++ crates/primitives/src/transaction/mod.rs | 12 +- 8 files changed, 439 insertions(+), 23 deletions(-) create mode 100644 crates/optimism/cli/src/ovm_file_codec.rs diff --git a/Cargo.lock b/Cargo.lock index 4792cb094de..7d9772a3909 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8158,9 +8158,12 @@ dependencies = [ name = "reth-optimism-cli" version = "1.1.1" dependencies = [ + "alloy-consensus", + "alloy-eips", "alloy-primitives", "alloy-rlp", "clap", + "derive_more 1.0.0", "eyre", "futures-util", "op-alloy-consensus", @@ -8194,6 +8197,7 @@ dependencies = [ "reth-static-file", "reth-static-file-types", "reth-tracing", + "serde", "tempfile", "tokio", "tokio-util", diff --git a/crates/consensus/beacon/Cargo.toml b/crates/consensus/beacon/Cargo.toml index d3aa5124668..0139be2f680 100644 --- a/crates/consensus/beacon/Cargo.toml +++ b/crates/consensus/beacon/Cargo.toml @@ -73,15 +73,16 @@ reth-exex-types.workspace = true reth-prune-types.workspace = true reth-chainspec.workspace = true alloy-genesis.workspace = true - assert_matches.workspace = true [features] optimism = [ - "reth-chainspec", - "reth-primitives/optimism", - "reth-provider/optimism", - "reth-blockchain-tree/optimism", - "reth-db/optimism", - "reth-db-api/optimism", -] + "reth-blockchain-tree/optimism", + "reth-chainspec", + "reth-db-api/optimism", + "reth-db/optimism", + "reth-downloaders/optimism", + "reth-primitives/optimism", + "reth-provider/optimism", + "reth-downloaders/optimism" +] \ No newline at end of file diff --git a/crates/net/downloaders/Cargo.toml b/crates/net/downloaders/Cargo.toml index 38e46bb6011..f4cc134ec48 100644 --- a/crates/net/downloaders/Cargo.toml +++ b/crates/net/downloaders/Cargo.toml @@ -46,9 +46,9 @@ reth-metrics.workspace = true metrics.workspace = true # misc -tracing.workspace = true rayon.workspace = true thiserror.workspace = true +tracing.workspace = true tempfile = { workspace = true, optional = true } itertools.workspace = true @@ -72,9 +72,16 @@ rand.workspace = true tempfile.workspace = true [features] +optimism = [ + "reth-primitives/optimism", + "reth-db?/optimism", + "reth-db-api?/optimism", + "reth-provider/optimism" +] + test-utils = [ - "dep:tempfile", - "dep:reth-db-api", + "tempfile", + "reth-db-api", "reth-db/test-utils", "reth-consensus/test-utils", "reth-network-p2p/test-utils", diff --git a/crates/net/downloaders/src/file_client.rs b/crates/net/downloaders/src/file_client.rs index df35146e940..9f539a5774d 100644 --- a/crates/net/downloaders/src/file_client.rs +++ b/crates/net/downloaders/src/file_client.rs @@ -19,9 +19,8 @@ use tokio_stream::StreamExt; use tokio_util::codec::FramedRead; use tracing::{debug, trace, warn}; -use crate::receipt_file_client::FromReceiptReader; - use super::file_codec::BlockFileCodec; +use crate::receipt_file_client::FromReceiptReader; /// Default byte length of chunk to read from chain file. /// diff --git a/crates/optimism/cli/Cargo.toml b/crates/optimism/cli/Cargo.toml index a2ba71214f5..198e5377ec4 100644 --- a/crates/optimism/cli/Cargo.toml +++ b/crates/optimism/cli/Cargo.toml @@ -47,11 +47,15 @@ reth-node-builder.workspace = true reth-tracing.workspace = true # eth +alloy-eips.workspace = true +alloy-consensus = { workspace = true, optional = true } alloy-primitives.workspace = true alloy-rlp.workspace = true # misc futures-util.workspace = true +derive_more = { workspace = true, optional = true } +serde = { workspace = true, optional = true } clap = { workspace = true, features = ["derive", "env"] } @@ -67,9 +71,7 @@ eyre.workspace = true # reth test-vectors proptest = { workspace = true, optional = true } -op-alloy-consensus = { workspace = true, features = [ - "arbitrary", -], optional = true } +op-alloy-consensus = { workspace = true, optional = true } [dev-dependencies] @@ -80,6 +82,10 @@ reth-cli-commands.workspace = true [features] optimism = [ + "op-alloy-consensus", + "alloy-consensus", + "dep:derive_more", + "dep:serde", "reth-primitives/optimism", "reth-optimism-evm/optimism", "reth-provider/optimism", @@ -87,7 +93,8 @@ optimism = [ "reth-optimism-node/optimism", "reth-execution-types/optimism", "reth-db/optimism", - "reth-db-api/optimism" + "reth-db-api/optimism", + "reth-downloaders/optimism" ] asm-keccak = [ "alloy-primitives/asm-keccak", @@ -104,6 +111,13 @@ jemalloc = [ dev = [ "dep:proptest", - "reth-cli-commands/arbitrary", - "op-alloy-consensus" + "reth-cli-commands/arbitrary" +] +serde = [ + "alloy-consensus?/serde", + "alloy-eips/serde", + "alloy-primitives/serde", + "op-alloy-consensus?/serde", + "reth-execution-types/serde", + "reth-provider/serde" ] diff --git a/crates/optimism/cli/src/lib.rs b/crates/optimism/cli/src/lib.rs index b3c7c86d1d1..23eaa99b521 100644 --- a/crates/optimism/cli/src/lib.rs +++ b/crates/optimism/cli/src/lib.rs @@ -27,6 +27,11 @@ pub mod commands; /// made for op-erigon's import needs). pub mod receipt_file_codec; +/// OVM block, same as EVM block at bedrock, except for signature of deposit transaction +/// not having a signature back then. +/// Enables decoding and encoding `Block` types within file contexts. +pub mod ovm_file_codec; + pub use commands::{import::ImportOpCommand, import_receipts::ImportReceiptsOpCommand}; use reth_optimism_chainspec::OpChainSpec; diff --git a/crates/optimism/cli/src/ovm_file_codec.rs b/crates/optimism/cli/src/ovm_file_codec.rs new file mode 100644 index 00000000000..624305c4b6e --- /dev/null +++ b/crates/optimism/cli/src/ovm_file_codec.rs @@ -0,0 +1,382 @@ +use alloy_consensus::{ + transaction::{from_eip155_value, RlpEcdsaTx}, + Header, TxEip1559, TxEip2930, TxEip4844, TxEip7702, TxLegacy, +}; +use alloy_eips::{ + eip2718::{Decodable2718, Eip2718Error, Eip2718Result, Encodable2718}, + eip4895::Withdrawals, +}; +use alloy_primitives::{ + bytes::{Buf, BytesMut}, + keccak256, PrimitiveSignature as Signature, TxHash, B256, U256, +}; +use alloy_rlp::{Decodable, Error as RlpError, RlpDecodable}; +use derive_more::{AsRef, Deref}; +use op_alloy_consensus::TxDeposit; +use reth_downloaders::file_client::FileClientError; +use reth_primitives::transaction::{Transaction, TxType}; +use serde::{Deserialize, Serialize}; +use tokio_util::codec::Decoder; + +#[allow(dead_code)] +/// Specific codec for reading raw block bodies from a file +/// with optimism-specific signature handling +pub(crate) struct OvmBlockFileCodec; + +impl Decoder for OvmBlockFileCodec { + type Item = Block; + type Error = FileClientError; + + fn decode(&mut self, src: &mut BytesMut) -> Result, Self::Error> { + if src.is_empty() { + return Ok(None); + } + + let buf_slice = &mut src.as_ref(); + let body = + Block::decode(buf_slice).map_err(|err| FileClientError::Rlp(err, src.to_vec()))?; + src.advance(src.len() - buf_slice.len()); + + Ok(Some(body)) + } +} + +/// OVM block, same as EVM block but with different transaction signature handling +/// Pre-bedrock system transactions on Optimism were sent from the zero address +/// with an empty signature, +#[derive(Debug, Clone, PartialEq, Eq, RlpDecodable)] +pub struct Block { + /// Block header + pub header: Header, + /// Block body + pub body: BlockBody, +} + +impl Block { + /// Decodes a `Block` from the given byte slice. + pub fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { + let header = Header::decode(buf)?; + let body = BlockBody::decode(buf)?; + Ok(Self { header, body }) + } +} + +/// The body of a block for OVM +#[derive(Debug, Clone, PartialEq, Eq, Default, RlpDecodable)] +#[rlp(trailing)] +pub struct BlockBody { + /// Transactions in the block + pub transactions: Vec, + /// Uncle headers for the given block + pub ommers: Vec
, + /// Withdrawals in the block. + pub withdrawals: Option, +} + +/// Signed transaction. +#[derive(Debug, Clone, PartialEq, Eq, Hash, AsRef, Deref, Serialize, Deserialize)] +pub struct TransactionSigned { + /// Transaction hash + pub hash: TxHash, + /// The transaction signature values + pub signature: Signature, + /// Raw transaction info + #[deref] + #[as_ref] + pub transaction: Transaction, +} + +impl Default for TransactionSigned { + fn default() -> Self { + Self { + hash: Default::default(), + signature: Signature::test_signature(), + transaction: Default::default(), + } + } +} + +impl AsRef for TransactionSigned { + fn as_ref(&self) -> &Self { + self + } +} + +// === impl TransactionSigned === +impl TransactionSigned { + /// Calculate transaction hash, eip2728 transaction does not contain rlp header and start with + /// tx type. + pub fn recalculate_hash(&self) -> B256 { + keccak256(self.encoded_2718()) + } + + /// Create a new signed transaction from a transaction and its signature. + /// + /// This will also calculate the transaction hash using its encoding. + pub fn from_transaction_and_signature(transaction: Transaction, signature: Signature) -> Self { + let mut initial_tx = Self { transaction, hash: Default::default(), signature }; + initial_tx.hash = initial_tx.recalculate_hash(); + initial_tx + } + + /// Decodes legacy transaction from the data buffer into a tuple. + /// + /// This expects `rlp(legacy_tx)` + /// + /// Refer to the docs for [`Self::decode_rlp_legacy_transaction`] for details on the exact + /// format expected. + pub(crate) fn decode_rlp_legacy_transaction_tuple( + data: &mut &[u8], + ) -> alloy_rlp::Result<(TxLegacy, TxHash, Signature)> { + let original_encoding = *data; + + let header = alloy_rlp::Header::decode(data)?; + let remaining_len = data.len(); + + let transaction_payload_len = header.payload_length; + + if transaction_payload_len > remaining_len { + return Err(RlpError::InputTooShort); + } + + let mut transaction = TxLegacy { + nonce: Decodable::decode(data)?, + gas_price: Decodable::decode(data)?, + gas_limit: Decodable::decode(data)?, + to: Decodable::decode(data)?, + value: Decodable::decode(data)?, + input: Decodable::decode(data)?, + chain_id: None, + }; + + let v: u64 = Decodable::decode(data)?; + let r: U256 = Decodable::decode(data)?; + let s: U256 = Decodable::decode(data)?; + + let tx_length = header.payload_length + header.length(); + let hash = keccak256(&original_encoding[..tx_length]); + + // Handle both pre-bedrock and regular cases + let (signature, chain_id) = if v == 0 && r.is_zero() && s.is_zero() { + // Pre-bedrock system transactions case + (Signature::new(r, s, false), None) + } else { + // Regular transaction case + let (parity, chain_id) = from_eip155_value(v) + .ok_or(alloy_rlp::Error::Custom("invalid parity for legacy transaction"))?; + (Signature::new(r, s, parity), chain_id) + }; + + // Set chain ID and verify length + transaction.chain_id = chain_id; + let decoded = remaining_len - data.len(); + if decoded != transaction_payload_len { + return Err(RlpError::UnexpectedLength); + } + + Ok((transaction, hash, signature)) + } + + /// Decodes legacy transaction from the data buffer. + /// + /// This should be used _only_ be used in general transaction decoding methods, which have + /// already ensured that the input is a legacy transaction with the following format: + /// `rlp(legacy_tx)` + /// + /// Legacy transactions are encoded as lists, so the input should start with a RLP list header. + /// + /// This expects `rlp(legacy_tx)` + // TODO: make buf advancement semantics consistent with `decode_enveloped_typed_transaction`, + // so decoding methods do not need to manually advance the buffer + pub fn decode_rlp_legacy_transaction(data: &mut &[u8]) -> alloy_rlp::Result { + let (transaction, hash, signature) = Self::decode_rlp_legacy_transaction_tuple(data)?; + let signed = Self { transaction: Transaction::Legacy(transaction), hash, signature }; + Ok(signed) + } +} + +impl Decodable for TransactionSigned { + /// This `Decodable` implementation only supports decoding rlp encoded transactions as it's used + /// by p2p. + /// + /// The p2p encoding format always includes an RLP header, although the type RLP header depends + /// on whether or not the transaction is a legacy transaction. + /// + /// If the transaction is a legacy transaction, it is just encoded as a RLP list: + /// `rlp(tx-data)`. + /// + /// If the transaction is a typed transaction, it is encoded as a RLP string: + /// `rlp(tx-type || rlp(tx-data))` + /// + /// This can be used for decoding all signed transactions in p2p `BlockBodies` responses. + /// + /// This cannot be used for decoding EIP-4844 transactions in p2p `PooledTransactions`, since + /// the EIP-4844 variant of [`TransactionSigned`] does not include the blob sidecar. + /// + /// For a method suitable for decoding pooled transactions, see \[`PooledTransactionsElement`\]. + /// + /// CAUTION: Due to a quirk in [`Header::decode`], this method will succeed even if a typed + /// transaction is encoded in this format, and does not start with a RLP header: + /// `tx-type || rlp(tx-data)`. + /// + /// This is because [`Header::decode`] does not advance the buffer, and returns a length-1 + /// string header if the first byte is less than `0xf7`. + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { + Self::network_decode(buf).map_err(Into::into) + } +} + +impl Encodable2718 for TransactionSigned { + fn type_flag(&self) -> Option { + match self.transaction.tx_type() { + TxType::Legacy => None, + tx_type => Some(tx_type as u8), + } + } + + fn encode_2718_len(&self) -> usize { + match &self.transaction { + Transaction::Legacy(legacy_tx) => legacy_tx.eip2718_encoded_length(&self.signature), + Transaction::Eip2930(access_list_tx) => { + access_list_tx.eip2718_encoded_length(&self.signature) + } + Transaction::Eip1559(dynamic_fee_tx) => { + dynamic_fee_tx.eip2718_encoded_length(&self.signature) + } + Transaction::Eip4844(blob_tx) => blob_tx.eip2718_encoded_length(&self.signature), + Transaction::Eip7702(set_code_tx) => { + set_code_tx.eip2718_encoded_length(&self.signature) + } + Transaction::Deposit(deposit_tx) => deposit_tx.eip2718_encoded_length(), + } + } + fn encode_2718(&self, out: &mut dyn alloy_rlp::BufMut) { + self.transaction.eip2718_encode(&self.signature, out) + } +} + +impl Decodable2718 for TransactionSigned { + fn typed_decode(ty: u8, buf: &mut &[u8]) -> Eip2718Result { + match ty.try_into().map_err(|_| Eip2718Error::UnexpectedType(ty))? { + TxType::Legacy => Err(Eip2718Error::UnexpectedType(0)), + TxType::Eip2930 => { + let (tx, signature, hash) = TxEip2930::rlp_decode_signed(buf)?.into_parts(); + Ok(Self { transaction: Transaction::Eip2930(tx), signature, hash }) + } + TxType::Eip1559 => { + let (tx, signature, hash) = TxEip1559::rlp_decode_signed(buf)?.into_parts(); + Ok(Self { transaction: Transaction::Eip1559(tx), signature, hash }) + } + TxType::Eip7702 => { + let (tx, signature, hash) = TxEip7702::rlp_decode_signed(buf)?.into_parts(); + Ok(Self { transaction: Transaction::Eip7702(tx), signature, hash }) + } + TxType::Eip4844 => { + let (tx, signature, hash) = TxEip4844::rlp_decode_signed(buf)?.into_parts(); + Ok(Self { transaction: Transaction::Eip4844(tx), signature, hash }) + } + TxType::Deposit => Ok(Self::from_transaction_and_signature( + Transaction::Deposit(TxDeposit::rlp_decode(buf)?), + TxDeposit::signature(), + )), + } + } + + fn fallback_decode(buf: &mut &[u8]) -> Eip2718Result { + Ok(Self::decode_rlp_legacy_transaction(buf)?) + } +} + +#[cfg(test)] +mod tests { + use crate::ovm_file_codec::TransactionSigned; + use alloy_primitives::{address, hex, TxKind, B256, U256}; + use reth_primitives::transaction::Transaction; + const DEPOSIT_FUNCTION_SELECTOR: [u8; 4] = [0xb6, 0xb5, 0x5f, 0x25]; + use alloy_rlp::Decodable; + + #[test] + fn test_decode_legacy_transactions() { + // Test Case 1: contract deposit - regular L2 transaction calling deposit() function + // tx: https://optimistic.etherscan.io/getRawTx?tx=0x7860252963a2df21113344f323035ef59648638a571eef742e33d789602c7a1c + let deposit_tx_bytes = hex!("f88881f0830f481c830c6e4594a75127121d28a9bf848f3b70e7eea26570aa770080a4b6b55f2500000000000000000000000000000000000000000000000000000000000710b238a0d5c622d92ddf37f9c18a3465a572f74d8b1aeaf50c1cfb10b3833242781fd45fa02c4f1d5819bf8b70bf651e7a063b7db63c55bd336799c6ae3e5bc72ad6ef3def"); + let deposit_decoded = TransactionSigned::decode(&mut &deposit_tx_bytes[..]).unwrap(); + + // Verify deposit transaction + let deposit_tx = match &deposit_decoded.transaction { + Transaction::Legacy(ref tx) => tx, + _ => panic!("Expected legacy transaction for NFT deposit"), + }; + + assert_eq!( + deposit_tx.to, + TxKind::Call(address!("a75127121d28a9bf848f3b70e7eea26570aa7700")) + ); + assert_eq!(deposit_tx.nonce, 240); + assert_eq!(deposit_tx.gas_price, 1001500); + assert_eq!(deposit_tx.gas_limit, 814661); + assert_eq!(deposit_tx.value, U256::ZERO); + assert_eq!(&deposit_tx.input.as_ref()[0..4], DEPOSIT_FUNCTION_SELECTOR); + assert_eq!(deposit_tx.chain_id, Some(10)); + assert_eq!( + deposit_decoded.signature.r(), + U256::from_str_radix( + "d5c622d92ddf37f9c18a3465a572f74d8b1aeaf50c1cfb10b3833242781fd45f", + 16 + ) + .unwrap() + ); + assert_eq!( + deposit_decoded.signature.s(), + U256::from_str_radix( + "2c4f1d5819bf8b70bf651e7a063b7db63c55bd336799c6ae3e5bc72ad6ef3def", + 16 + ) + .unwrap() + ); + + // Test Case 2: pre-bedrock system transaction from block 105235052 + // tx: https://optimistic.etherscan.io/getRawTx?tx=0xe20b11349681dd049f8df32f5cdbb4c68d46b537685defcd86c7fa42cfe75b9e + let system_tx_bytes = hex!("f9026c830d899383124f808302a77e94a0cc33dd6f4819d473226257792afe230ec3c67f80b902046c459a280000000000000000000000004d73adb72bc3dd368966edd0f0b2148401a178e2000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000647fac7f00000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000084704316e5000000000000000000000000000000000000000000000000000000000000006e10975631049de3c008989b0d8c19fc720dc556ca01abfbd794c6eb5075dd000d000000000000000000000000000000000000000000000000000000000000001410975631049de3c008989b0d8c19fc720dc556ca01abfbd794c6eb5075dd000d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000082a39325251d44e11f3b6d92f9382438eb6c8b5068d4a488d4f177b26f2ca20db34ae53467322852afcc779f25eafd124c5586f54b9026497ba934403d4c578e3c1b5aa754c918ee2ecd25402df656c2419717e4017a7aecb84af3914fd3c7bf6930369c4e6ff76950246b98e354821775f02d33cdbee5ef6aed06c15b75691692d31c00000000000000000000000000000000000000000000000000000000000038a0e8991e95e66d809f4b6fb0af27c31368ca0f30e657165c428aa681ec5ea25bbea013ed325bd97365087ec713e9817d252b59113ea18430b71a5890c4eeb6b9efc4"); + let system_decoded = TransactionSigned::decode(&mut &system_tx_bytes[..]).unwrap(); + + // Verify system transaction + assert!(system_decoded.is_legacy()); + + let system_tx = match &system_decoded.transaction { + Transaction::Legacy(ref tx) => tx, + _ => panic!("Expected Legacy transaction"), + }; + + assert_eq!(system_tx.nonce, 887187); + assert_eq!(system_tx.gas_price, 1200000); + assert_eq!(system_tx.gas_limit, 173950); + assert_eq!( + system_tx.to, + TxKind::Call(address!("a0cc33dd6f4819d473226257792afe230ec3c67f")) + ); + assert_eq!(system_tx.value, U256::ZERO); + assert_eq!(system_tx.chain_id, Some(10)); + + assert_eq!( + system_decoded.signature.r(), + U256::from_str_radix( + "e8991e95e66d809f4b6fb0af27c31368ca0f30e657165c428aa681ec5ea25bbe", + 16 + ) + .unwrap() + ); + assert_eq!( + system_decoded.signature.s(), + U256::from_str_radix( + "13ed325bd97365087ec713e9817d252b59113ea18430b71a5890c4eeb6b9efc4", + 16 + ) + .unwrap() + ); + assert_eq!( + system_decoded.hash, + B256::from(hex!("e20b11349681dd049f8df32f5cdbb4c68d46b537685defcd86c7fa42cfe75b9e")) + ); + } +} diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index 366f59696b2..26815fc38de 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -48,8 +48,12 @@ mod error; mod meta; mod pooled; mod sidecar; -mod signature; mod tx_type; + +/// Handling transaction signature operations, including signature recovery, +/// applying chain IDs, and EIP-2 validation. +pub mod signature; + pub(crate) mod util; mod variant; @@ -70,9 +74,9 @@ use revm_primitives::{AuthorizationList, TxEnv}; /// Either a transaction hash or number. pub type TxHashOrNumber = BlockHashOrNumber; -// Expected number of transactions where we can expect a speed-up by recovering the senders in -// parallel. -pub(crate) static PARALLEL_SENDER_RECOVERY_THRESHOLD: LazyLock = +/// Expected number of transactions where we can expect a speed-up by recovering the senders in +/// parallel. +pub static PARALLEL_SENDER_RECOVERY_THRESHOLD: LazyLock = LazyLock::new(|| match rayon::current_num_threads() { 0..=1 => usize::MAX, 2..=8 => 10, From e6a6fc4c2e188c71b6dc67e67549cf38d0bb1d46 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 12 Nov 2024 16:37:21 +0100 Subject: [PATCH 126/211] chore: only fetch deposit info for deposit tx (#12474) --- crates/optimism/rpc/src/eth/transaction.rs | 24 ++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/crates/optimism/rpc/src/eth/transaction.rs b/crates/optimism/rpc/src/eth/transaction.rs index 3ff7cb10df1..20aa379a0c1 100644 --- a/crates/optimism/rpc/src/eth/transaction.rs +++ b/crates/optimism/rpc/src/eth/transaction.rs @@ -85,6 +85,7 @@ where ) -> Result { let from = tx.signer(); let TransactionSigned { transaction, signature, hash } = tx.into_signed(); + let mut deposit_receipt_version = None; let inner = match transaction { reth_primitives::Transaction::Legacy(tx) => { @@ -100,16 +101,23 @@ where reth_primitives::Transaction::Eip7702(tx) => { Signed::new_unchecked(tx, signature, hash).into() } - reth_primitives::Transaction::Deposit(tx) => OpTxEnvelope::Deposit(tx), + reth_primitives::Transaction::Deposit(tx) => { + let deposit_info = self + .inner + .provider() + .receipt_by_hash(hash) + .map_err(Self::Error::from_eth_err)? + .and_then(|receipt| receipt.deposit_receipt_version.zip(receipt.deposit_nonce)); + + if let Some((version, _)) = deposit_info { + deposit_receipt_version = Some(version); + // TODO: set nonce + } + + OpTxEnvelope::Deposit(tx) + } }; - let deposit_receipt_version = self - .inner - .provider() - .receipt_by_hash(hash) - .map_err(Self::Error::from_eth_err)? - .and_then(|receipt| receipt.deposit_receipt_version); - let TransactionInfo { block_hash, block_number, index: transaction_index, base_fee, .. } = tx_info; From 4a8eb7a0c0a08504f1241d421b85d588e7bc3915 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 12 Nov 2024 18:19:06 +0100 Subject: [PATCH 127/211] chore: add DUPSORT trait const (#12477) --- crates/storage/db-api/src/table.rs | 3 +++ crates/storage/db/src/tables/mod.rs | 1 + crates/storage/db/src/tables/raw.rs | 2 ++ 3 files changed, 6 insertions(+) diff --git a/crates/storage/db-api/src/table.rs b/crates/storage/db-api/src/table.rs index 963457af05c..acdc8efc78f 100644 --- a/crates/storage/db-api/src/table.rs +++ b/crates/storage/db-api/src/table.rs @@ -88,6 +88,9 @@ pub trait Table: Send + Sync + Debug + 'static { /// The table's name. const NAME: &'static str; + /// Whether the table is also a `DUPSORT` table. + const DUPSORT: bool; + /// Key element of `Table`. /// /// Sorting should be taken into account when encoding this. diff --git a/crates/storage/db/src/tables/mod.rs b/crates/storage/db/src/tables/mod.rs index c697c319909..cf7d23a1272 100644 --- a/crates/storage/db/src/tables/mod.rs +++ b/crates/storage/db/src/tables/mod.rs @@ -140,6 +140,7 @@ macro_rules! tables { $value: reth_db_api::table::Value + 'static { const NAME: &'static str = table_names::$name; + const DUPSORT: bool = tables!(@bool $($subkey)?); type Key = $key; type Value = $value; diff --git a/crates/storage/db/src/tables/raw.rs b/crates/storage/db/src/tables/raw.rs index 6b6de41613e..453116ee5e3 100644 --- a/crates/storage/db/src/tables/raw.rs +++ b/crates/storage/db/src/tables/raw.rs @@ -14,6 +14,7 @@ pub struct RawTable { impl Table for RawTable { const NAME: &'static str = T::NAME; + const DUPSORT: bool = false; type Key = RawKey; type Value = RawValue; @@ -28,6 +29,7 @@ pub struct RawDupSort { impl Table for RawDupSort { const NAME: &'static str = T::NAME; + const DUPSORT: bool = true; type Key = RawKey; type Value = RawValue; From fa5daef07dd262eb7fc0f78f07752b8bedbc3fa7 Mon Sep 17 00:00:00 2001 From: Panagiotis Ganelis <50522617+PanGan21@users.noreply.github.com> Date: Tue, 12 Nov 2024 19:35:51 +0100 Subject: [PATCH 128/211] chore: Move `HistoryWriter` trait to `storage-api` and reexport it from old `provider` crate (#12480) --- Cargo.lock | 1 + crates/storage/provider/src/lib.rs | 3 +++ crates/storage/provider/src/traits/mod.rs | 3 --- crates/storage/storage-api/Cargo.toml | 1 + .../{provider/src/traits => storage-api/src}/history.rs | 0 crates/storage/storage-api/src/lib.rs | 3 +++ 6 files changed, 8 insertions(+), 3 deletions(-) rename crates/storage/{provider/src/traits => storage-api/src}/history.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 7d9772a3909..0ad5c1acd6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9120,6 +9120,7 @@ dependencies = [ "alloy-primitives", "auto_impl", "reth-chainspec", + "reth-db", "reth-db-api", "reth-db-models", "reth-execution-types", diff --git a/crates/storage/provider/src/lib.rs b/crates/storage/provider/src/lib.rs index 894a41620c5..2b002fe11ec 100644 --- a/crates/storage/provider/src/lib.rs +++ b/crates/storage/provider/src/lib.rs @@ -46,6 +46,9 @@ pub use reth_chain_state::{ CanonStateNotifications, CanonStateSubscriptions, }; +// reexport HistoryWriter trait +pub use reth_storage_api::HistoryWriter; + pub(crate) fn to_range>(bounds: R) -> std::ops::Range { let start = match bounds.start_bound() { std::ops::Bound::Included(&v) => v, diff --git a/crates/storage/provider/src/traits/mod.rs b/crates/storage/provider/src/traits/mod.rs index c31c7c1e2f2..722721525bf 100644 --- a/crates/storage/provider/src/traits/mod.rs +++ b/crates/storage/provider/src/traits/mod.rs @@ -26,9 +26,6 @@ pub use hashing::HashingWriter; mod trie; pub use trie::{StorageTrieWriter, TrieWriter}; -mod history; -pub use history::HistoryWriter; - mod static_file_provider; pub use static_file_provider::StaticFileProviderFactory; diff --git a/crates/storage/storage-api/Cargo.toml b/crates/storage/storage-api/Cargo.toml index 0ae8b284588..32aadc1922d 100644 --- a/crates/storage/storage-api/Cargo.toml +++ b/crates/storage/storage-api/Cargo.toml @@ -22,6 +22,7 @@ reth-prune-types.workspace = true reth-stages-types.workspace = true reth-storage-errors.workspace = true reth-trie.workspace = true +reth-db.workspace = true # ethereum alloy-eips.workspace = true diff --git a/crates/storage/provider/src/traits/history.rs b/crates/storage/storage-api/src/history.rs similarity index 100% rename from crates/storage/provider/src/traits/history.rs rename to crates/storage/storage-api/src/history.rs diff --git a/crates/storage/storage-api/src/lib.rs b/crates/storage/storage-api/src/lib.rs index 4e589242a91..21d02325afe 100644 --- a/crates/storage/storage-api/src/lib.rs +++ b/crates/storage/storage-api/src/lib.rs @@ -53,3 +53,6 @@ mod database_provider; pub use database_provider::*; pub mod noop; + +mod history; +pub use history::*; From b39957612a88640272a051858bad5cab840d6287 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Tue, 12 Nov 2024 23:29:42 +0400 Subject: [PATCH 129/211] feat: make more network components generic over primitives (#12481) --- Cargo.lock | 2 + crates/net/eth-wire-types/Cargo.toml | 5 +- crates/net/eth-wire-types/src/primitives.rs | 5 +- crates/net/network/Cargo.toml | 4 +- crates/net/network/src/import.rs | 22 ++-- crates/net/network/src/message.rs | 15 +-- crates/net/network/src/session/active.rs | 109 ++++++++++---------- crates/net/network/src/session/conn.rs | 34 +++--- crates/net/network/src/session/handle.rs | 22 ++-- crates/net/network/src/session/mod.rs | 54 +++++----- crates/net/network/src/state.rs | 25 +++-- crates/net/network/src/swarm.rs | 42 ++++---- crates/primitives-traits/src/block/body.rs | 7 +- crates/primitives-traits/src/block/mod.rs | 73 +------------ crates/primitives/src/block.rs | 13 +++ 15 files changed, 197 insertions(+), 235 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0ad5c1acd6a..5ce7b0c0ec7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7349,6 +7349,7 @@ dependencies = [ "reth-chainspec", "reth-codecs-derive", "reth-primitives", + "reth-primitives-traits", "serde", "thiserror", ] @@ -7784,6 +7785,7 @@ dependencies = [ "reth-network-peers", "reth-network-types", "reth-primitives", + "reth-primitives-traits", "reth-provider", "reth-storage-api", "reth-tasks", diff --git a/crates/net/eth-wire-types/Cargo.toml b/crates/net/eth-wire-types/Cargo.toml index 582ab7557f3..9ce712bf87a 100644 --- a/crates/net/eth-wire-types/Cargo.toml +++ b/crates/net/eth-wire-types/Cargo.toml @@ -16,9 +16,9 @@ workspace = true reth-chainspec.workspace = true reth-codecs-derive.workspace = true reth-primitives.workspace = true +reth-primitives-traits.workspace = true # ethereum -alloy-consensus.workspace = true alloy-chains = { workspace = true, features = ["rlp"] } alloy-eips.workspace = true alloy-primitives.workspace = true @@ -54,7 +54,8 @@ arbitrary = [ "reth-chainspec/arbitrary", "alloy-consensus/arbitrary", "alloy-eips/arbitrary", - "alloy-primitives/arbitrary" + "alloy-primitives/arbitrary", + "reth-primitives-traits/arbitrary", ] serde = [ "dep:serde", diff --git a/crates/net/eth-wire-types/src/primitives.rs b/crates/net/eth-wire-types/src/primitives.rs index 04b8b429e2a..15cfaaff0a2 100644 --- a/crates/net/eth-wire-types/src/primitives.rs +++ b/crates/net/eth-wire-types/src/primitives.rs @@ -2,8 +2,8 @@ use std::fmt::Debug; -use alloy_consensus::BlockHeader; use alloy_rlp::{Decodable, Encodable}; +use reth_primitives_traits::{Block, BlockHeader}; /// Abstraction over primitive types which might appear in network messages. See /// [`crate::EthMessage`] for more context. @@ -34,7 +34,8 @@ pub trait NetworkPrimitives: + Eq + 'static; /// Full block type. - type Block: Encodable + type Block: Block
+ + Encodable + Decodable + Send + Sync diff --git a/crates/net/network/Cargo.toml b/crates/net/network/Cargo.toml index 148eef34b36..09f81e63e54 100644 --- a/crates/net/network/Cargo.toml +++ b/crates/net/network/Cargo.toml @@ -16,6 +16,7 @@ workspace = true reth-chainspec.workspace = true reth-fs-util.workspace = true reth-primitives = { workspace = true, features = ["secp256k1"] } +reth-primitives-traits.workspace = true reth-net-banlist.workspace = true reth-network-api.workspace = true reth-network-p2p.workspace = true @@ -130,7 +131,8 @@ test-utils = [ "reth-discv4/test-utils", "reth-network/test-utils", "reth-network-p2p/test-utils", - "reth-primitives/test-utils" + "reth-primitives/test-utils", + "reth-primitives-traits/test-utils", ] [[bench]] diff --git a/crates/net/network/src/import.rs b/crates/net/network/src/import.rs index 201dc3e4f78..749b3c347b3 100644 --- a/crates/net/network/src/import.rs +++ b/crates/net/network/src/import.rs @@ -7,7 +7,7 @@ use reth_network_peers::PeerId; use crate::message::NewBlockMessage; /// Abstraction over block import. -pub trait BlockImport: std::fmt::Debug + Send + Sync { +pub trait BlockImport: std::fmt::Debug + Send + Sync { /// Invoked for a received `NewBlock` broadcast message from the peer. /// /// > When a `NewBlock` announcement message is received from a peer, the client first verifies @@ -15,35 +15,35 @@ pub trait BlockImport: std::fmt::Debug + Send + Sync { /// /// This is supposed to start verification. The results are then expected to be returned via /// [`BlockImport::poll`]. - fn on_new_block(&mut self, peer_id: PeerId, incoming_block: NewBlockMessage); + fn on_new_block(&mut self, peer_id: PeerId, incoming_block: NewBlockMessage); /// Returns the results of a [`BlockImport::on_new_block`] - fn poll(&mut self, cx: &mut Context<'_>) -> Poll; + fn poll(&mut self, cx: &mut Context<'_>) -> Poll>; } /// Outcome of the [`BlockImport`]'s block handling. #[derive(Debug)] -pub struct BlockImportOutcome { +pub struct BlockImportOutcome { /// Sender of the `NewBlock` message. pub peer: PeerId, /// The result after validating the block - pub result: Result, + pub result: Result, BlockImportError>, } /// Represents the successful validation of a received `NewBlock` message. #[derive(Debug)] -pub enum BlockValidation { +pub enum BlockValidation { /// Basic Header validity check, after which the block should be relayed to peers via a /// `NewBlock` message ValidHeader { /// received block - block: NewBlockMessage, + block: NewBlockMessage, }, /// Successfully imported: state-root matches after execution. The block should be relayed via /// `NewBlockHashes` ValidBlock { /// validated block. - block: NewBlockMessage, + block: NewBlockMessage, }, } @@ -62,10 +62,10 @@ pub enum BlockImportError { #[non_exhaustive] pub struct ProofOfStakeBlockImport; -impl BlockImport for ProofOfStakeBlockImport { - fn on_new_block(&mut self, _peer_id: PeerId, _incoming_block: NewBlockMessage) {} +impl BlockImport for ProofOfStakeBlockImport { + fn on_new_block(&mut self, _peer_id: PeerId, _incoming_block: NewBlockMessage) {} - fn poll(&mut self, _cx: &mut Context<'_>) -> Poll { + fn poll(&mut self, _cx: &mut Context<'_>) -> Poll> { Poll::Pending } } diff --git a/crates/net/network/src/message.rs b/crates/net/network/src/message.rs index bdb13875f12..3040577415c 100644 --- a/crates/net/network/src/message.rs +++ b/crates/net/network/src/message.rs @@ -8,6 +8,7 @@ use std::{ task::{ready, Context, Poll}, }; +use alloy_consensus::BlockHeader; use alloy_primitives::{Bytes, B256}; use futures::FutureExt; use reth_eth_wire::{ @@ -23,30 +24,30 @@ use tokio::sync::oneshot; /// Internal form of a `NewBlock` message #[derive(Debug, Clone)] -pub struct NewBlockMessage { +pub struct NewBlockMessage { /// Hash of the block pub hash: B256, /// Raw received message - pub block: Arc, + pub block: Arc>, } // === impl NewBlockMessage === -impl NewBlockMessage { +impl NewBlockMessage { /// Returns the block number of the block pub fn number(&self) -> u64 { - self.block.block.header.number + self.block.block.header().number() } } /// All Bi-directional eth-message variants that can be sent to a session or received from a /// session. #[derive(Debug)] -pub enum PeerMessage { +pub enum PeerMessage { /// Announce new block hashes NewBlockHashes(NewBlockHashes), /// Broadcast new block. - NewBlock(NewBlockMessage), + NewBlock(NewBlockMessage), /// Received transactions _from_ the peer ReceivedTransaction(Transactions), /// Broadcast transactions _from_ local _to_ a peer. @@ -54,7 +55,7 @@ pub enum PeerMessage { /// Send new pooled transactions PooledTransactions(NewPooledTransactionHashes), /// All `eth` request variants. - EthRequest(PeerRequest), + EthRequest(PeerRequest), /// Other than eth namespace message Other(RawCapabilityMessage), } diff --git a/crates/net/network/src/session/active.rs b/crates/net/network/src/session/active.rs index 10048823c54..f979a912cd4 100644 --- a/crates/net/network/src/session/active.rs +++ b/crates/net/network/src/session/active.rs @@ -11,18 +11,20 @@ use std::{ time::{Duration, Instant}, }; +use alloy_primitives::Sealable; use futures::{stream::Fuse, SinkExt, StreamExt}; use metrics::Gauge; use reth_eth_wire::{ errors::{EthHandshakeError, EthStreamError, P2PStreamError}, message::{EthBroadcastMessage, RequestPair}, - Capabilities, DisconnectP2P, DisconnectReason, EthMessage, + Capabilities, DisconnectP2P, DisconnectReason, EthMessage, NetworkPrimitives, }; use reth_metrics::common::mpsc::MeteredPollSender; use reth_network_api::PeerRequest; use reth_network_p2p::error::RequestError; use reth_network_peers::PeerId; use reth_network_types::session::config::INITIAL_REQUEST_TIMEOUT; +use reth_primitives_traits::Block; use rustc_hash::FxHashMap; use tokio::{ sync::{mpsc::error::TrySendError, oneshot}, @@ -62,11 +64,11 @@ const TIMEOUT_SCALING: u32 = 3; /// - incoming requests/broadcasts _from remote_ via the connection /// - responses for handled ETH requests received from the remote peer. #[allow(dead_code)] -pub(crate) struct ActiveSession { +pub(crate) struct ActiveSession { /// Keeps track of request ids. pub(crate) next_id: u64, /// The underlying connection. - pub(crate) conn: EthRlpxConnection, + pub(crate) conn: EthRlpxConnection, /// Identifier of the node we're connected to. pub(crate) remote_peer_id: PeerId, /// The address we're connected to. @@ -76,19 +78,19 @@ pub(crate) struct ActiveSession { /// Internal identifier of this session pub(crate) session_id: SessionId, /// Incoming commands from the manager - pub(crate) commands_rx: ReceiverStream, + pub(crate) commands_rx: ReceiverStream>, /// Sink to send messages to the [`SessionManager`](super::SessionManager). - pub(crate) to_session_manager: MeteredPollSender, + pub(crate) to_session_manager: MeteredPollSender>, /// A message that needs to be delivered to the session manager - pub(crate) pending_message_to_session: Option, + pub(crate) pending_message_to_session: Option>, /// Incoming internal requests which are delegated to the remote peer. - pub(crate) internal_request_tx: Fuse>, + pub(crate) internal_request_tx: Fuse>>, /// All requests sent to the remote peer we're waiting on a response - pub(crate) inflight_requests: FxHashMap, + pub(crate) inflight_requests: FxHashMap>>, /// All requests that were sent by the remote peer and we're waiting on an internal response - pub(crate) received_requests_from_remote: Vec, + pub(crate) received_requests_from_remote: Vec>, /// Buffered messages that should be handled and sent to the peer. - pub(crate) queued_outgoing: QueuedOutgoingMessages, + pub(crate) queued_outgoing: QueuedOutgoingMessages, /// The maximum time we wait for a response from a peer. pub(crate) internal_request_timeout: Arc, /// Interval when to check for timed out requests. @@ -97,10 +99,11 @@ pub(crate) struct ActiveSession { /// considered a protocol violation and the session will initiate a drop. pub(crate) protocol_breach_request_timeout: Duration, /// Used to reserve a slot to guarantee that the termination message is delivered - pub(crate) terminate_message: Option<(PollSender, ActiveSessionMessage)>, + pub(crate) terminate_message: + Option<(PollSender>, ActiveSessionMessage)>, } -impl ActiveSession { +impl ActiveSession { /// Returns `true` if the session is currently in the process of disconnecting fn is_disconnecting(&self) -> bool { self.conn.inner().is_disconnecting() @@ -122,7 +125,7 @@ impl ActiveSession { /// Handle a message read from the connection. /// /// Returns an error if the message is considered to be in violation of the protocol. - fn on_incoming_message(&mut self, msg: EthMessage) -> OnIncomingMessageOutcome { + fn on_incoming_message(&mut self, msg: EthMessage) -> OnIncomingMessageOutcome { /// A macro that handles an incoming request /// This creates a new channel and tries to send the sender half to the session while /// storing the receiver half internally so the pending response can be polled. @@ -182,7 +185,7 @@ impl ActiveSession { } EthMessage::NewBlock(msg) => { let block = - NewBlockMessage { hash: msg.block.header.hash_slow(), block: Arc::new(*msg) }; + NewBlockMessage { hash: msg.block.header().hash_slow(), block: Arc::new(*msg) }; self.try_emit_broadcast(PeerMessage::NewBlock(block)).into() } EthMessage::Transactions(msg) => { @@ -238,7 +241,7 @@ impl ActiveSession { } /// Handle an internal peer request that will be sent to the remote. - fn on_internal_peer_request(&mut self, request: PeerRequest, deadline: Instant) { + fn on_internal_peer_request(&mut self, request: PeerRequest, deadline: Instant) { let request_id = self.next_id(); let msg = request.create_request_message(request_id); self.queued_outgoing.push_back(msg.into()); @@ -251,7 +254,7 @@ impl ActiveSession { } /// Handle a message received from the internal network - fn on_internal_peer_message(&mut self, msg: PeerMessage) { + fn on_internal_peer_message(&mut self, msg: PeerMessage) { match msg { PeerMessage::NewBlockHashes(msg) => { self.queued_outgoing.push_back(EthMessage::NewBlockHashes(msg).into()); @@ -289,7 +292,7 @@ impl ActiveSession { /// Handle a Response to the peer /// /// This will queue the response to be sent to the peer - fn handle_outgoing_response(&mut self, id: u64, resp: PeerResponseResult) { + fn handle_outgoing_response(&mut self, id: u64, resp: PeerResponseResult) { match resp.try_into_message(id) { Ok(msg) => { self.queued_outgoing.push_back(msg.into()); @@ -304,7 +307,7 @@ impl ActiveSession { /// /// Returns the message if the bounded channel is currently unable to handle this message. #[allow(clippy::result_large_err)] - fn try_emit_broadcast(&self, message: PeerMessage) -> Result<(), ActiveSessionMessage> { + fn try_emit_broadcast(&self, message: PeerMessage) -> Result<(), ActiveSessionMessage> { let Some(sender) = self.to_session_manager.inner().get_ref() else { return Ok(()) }; match sender @@ -330,7 +333,7 @@ impl ActiveSession { /// /// Returns the message if the bounded channel is currently unable to handle this message. #[allow(clippy::result_large_err)] - fn try_emit_request(&self, message: PeerMessage) -> Result<(), ActiveSessionMessage> { + fn try_emit_request(&self, message: PeerMessage) -> Result<(), ActiveSessionMessage> { let Some(sender) = self.to_session_manager.inner().get_ref() else { return Ok(()) }; match sender @@ -470,7 +473,7 @@ impl ActiveSession { } } -impl Future for ActiveSession { +impl Future for ActiveSession { type Output = (); fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { @@ -656,20 +659,20 @@ impl Future for ActiveSession { } /// Tracks a request received from the peer -pub(crate) struct ReceivedRequest { +pub(crate) struct ReceivedRequest { /// Protocol Identifier request_id: u64, /// Receiver half of the channel that's supposed to receive the proper response. - rx: PeerResponse, + rx: PeerResponse, /// Timestamp when we read this msg from the wire. #[allow(dead_code)] received: Instant, } /// A request that waits for a response from the peer -pub(crate) struct InflightRequest { +pub(crate) struct InflightRequest { /// Request we sent to peer and the internal response channel - request: RequestState, + request: RequestState, /// Instant when the request was sent timestamp: Instant, /// Time limit for the response @@ -678,7 +681,7 @@ pub(crate) struct InflightRequest { // === impl InflightRequest === -impl InflightRequest { +impl InflightRequest> { /// Returns true if the request is timedout #[inline] fn is_timed_out(&self, now: Instant) -> bool { @@ -703,17 +706,19 @@ impl InflightRequest { } /// All outcome variants when handling an incoming message -enum OnIncomingMessageOutcome { +enum OnIncomingMessageOutcome { /// Message successfully handled. Ok, /// Message is considered to be in violation of the protocol - BadMessage { error: EthStreamError, message: EthMessage }, + BadMessage { error: EthStreamError, message: EthMessage }, /// Currently no capacity to handle the message - NoCapacity(ActiveSessionMessage), + NoCapacity(ActiveSessionMessage), } -impl From> for OnIncomingMessageOutcome { - fn from(res: Result<(), ActiveSessionMessage>) -> Self { +impl From>> + for OnIncomingMessageOutcome +{ + fn from(res: Result<(), ActiveSessionMessage>) -> Self { match res { Ok(_) => Self::Ok, Err(msg) => Self::NoCapacity(msg), @@ -721,29 +726,29 @@ impl From> for OnIncomingMessageOutcome { } } -enum RequestState { +enum RequestState { /// Waiting for the response - Waiting(PeerRequest), + Waiting(R), /// Request already timed out TimedOut, } /// Outgoing messages that can be sent over the wire. -pub(crate) enum OutgoingMessage { +pub(crate) enum OutgoingMessage { /// A message that is owned. - Eth(EthMessage), + Eth(EthMessage), /// A message that may be shared by multiple sessions. - Broadcast(EthBroadcastMessage), + Broadcast(EthBroadcastMessage), } -impl From for OutgoingMessage { - fn from(value: EthMessage) -> Self { +impl From> for OutgoingMessage { + fn from(value: EthMessage) -> Self { Self::Eth(value) } } -impl From for OutgoingMessage { - fn from(value: EthBroadcastMessage) -> Self { +impl From> for OutgoingMessage { + fn from(value: EthBroadcastMessage) -> Self { Self::Broadcast(value) } } @@ -760,22 +765,22 @@ fn calculate_new_timeout(current_timeout: Duration, estimated_rtt: Duration) -> } /// A helper struct that wraps the queue of outgoing messages and a metric to track their count -pub(crate) struct QueuedOutgoingMessages { - messages: VecDeque, +pub(crate) struct QueuedOutgoingMessages { + messages: VecDeque>, count: Gauge, } -impl QueuedOutgoingMessages { +impl QueuedOutgoingMessages { pub(crate) const fn new(metric: Gauge) -> Self { Self { messages: VecDeque::new(), count: metric } } - pub(crate) fn push_back(&mut self, message: OutgoingMessage) { + pub(crate) fn push_back(&mut self, message: OutgoingMessage) { self.messages.push_back(message); self.count.increment(1); } - pub(crate) fn pop_front(&mut self) -> Option { + pub(crate) fn pop_front(&mut self) -> Option> { self.messages.pop_front().inspect(|_| self.count.decrement(1)) } @@ -791,8 +796,8 @@ mod tests { use reth_chainspec::MAINNET; use reth_ecies::stream::ECIESStream; use reth_eth_wire::{ - EthStream, GetBlockBodies, HelloMessageWithProtocols, P2PStream, Status, StatusBuilder, - UnauthedEthStream, UnauthedP2PStream, + EthNetworkPrimitives, EthStream, GetBlockBodies, HelloMessageWithProtocols, P2PStream, + Status, StatusBuilder, UnauthedEthStream, UnauthedP2PStream, }; use reth_network_peers::pk2id; use reth_network_types::session::config::PROTOCOL_BREACH_REQUEST_TIMEOUT; @@ -808,11 +813,11 @@ mod tests { HelloMessageWithProtocols::builder(pk2id(&server_key.public_key(SECP256K1))).build() } - struct SessionBuilder { + struct SessionBuilder { _remote_capabilities: Arc, - active_session_tx: mpsc::Sender, - active_session_rx: ReceiverStream, - to_sessions: Vec>, + active_session_tx: mpsc::Sender>, + active_session_rx: ReceiverStream>, + to_sessions: Vec>>, secret_key: SecretKey, local_peer_id: PeerId, hello: HelloMessageWithProtocols, @@ -821,7 +826,7 @@ mod tests { next_id: usize, } - impl SessionBuilder { + impl SessionBuilder { fn next_id(&mut self) -> SessionId { let id = self.next_id; self.next_id += 1; @@ -858,7 +863,7 @@ mod tests { }) } - async fn connect_incoming(&mut self, stream: TcpStream) -> ActiveSession { + async fn connect_incoming(&mut self, stream: TcpStream) -> ActiveSession { let remote_addr = stream.local_addr().unwrap(); let session_id = self.next_id(); let (_disconnect_tx, disconnect_rx) = oneshot::channel(); diff --git a/crates/net/network/src/session/conn.rs b/crates/net/network/src/session/conn.rs index 628c880c8ea..5329f01028b 100644 --- a/crates/net/network/src/session/conn.rs +++ b/crates/net/network/src/session/conn.rs @@ -11,16 +11,16 @@ use reth_eth_wire::{ errors::EthStreamError, message::EthBroadcastMessage, multiplex::{ProtocolProxy, RlpxSatelliteStream}, - EthMessage, EthStream, EthVersion, P2PStream, + EthMessage, EthNetworkPrimitives, EthStream, EthVersion, NetworkPrimitives, P2PStream, }; use tokio::net::TcpStream; /// The type of the underlying peer network connection. -pub type EthPeerConnection = EthStream>>; +pub type EthPeerConnection = EthStream>, N>; /// Various connection types that at least support the ETH protocol. -pub type EthSatelliteConnection = - RlpxSatelliteStream, EthStream>; +pub type EthSatelliteConnection = + RlpxSatelliteStream, EthStream>; /// Connection types that support the ETH protocol. /// @@ -30,14 +30,14 @@ pub type EthSatelliteConnection = // This type is boxed because the underlying stream is ~6KB, // mostly coming from `P2PStream`'s `snap::Encoder` (2072), and `ECIESStream` (3600). #[derive(Debug)] -pub enum EthRlpxConnection { +pub enum EthRlpxConnection { /// A connection that only supports the ETH protocol. - EthOnly(Box), + EthOnly(Box>), /// A connection that supports the ETH protocol and __at least one other__ `RLPx` protocol. - Satellite(Box), + Satellite(Box>), } -impl EthRlpxConnection { +impl EthRlpxConnection { /// Returns the negotiated ETH version. #[inline] pub(crate) const fn version(&self) -> EthVersion { @@ -78,7 +78,7 @@ impl EthRlpxConnection { #[inline] pub fn start_send_broadcast( &mut self, - item: EthBroadcastMessage, + item: EthBroadcastMessage, ) -> Result<(), EthStreamError> { match self { Self::EthOnly(conn) => conn.start_send_broadcast(item), @@ -87,16 +87,16 @@ impl EthRlpxConnection { } } -impl From for EthRlpxConnection { +impl From> for EthRlpxConnection { #[inline] - fn from(conn: EthPeerConnection) -> Self { + fn from(conn: EthPeerConnection) -> Self { Self::EthOnly(Box::new(conn)) } } -impl From for EthRlpxConnection { +impl From> for EthRlpxConnection { #[inline] - fn from(conn: EthSatelliteConnection) -> Self { + fn from(conn: EthSatelliteConnection) -> Self { Self::Satellite(Box::new(conn)) } } @@ -112,22 +112,22 @@ macro_rules! delegate_call { } } -impl Stream for EthRlpxConnection { - type Item = Result; +impl Stream for EthRlpxConnection { + type Item = Result, EthStreamError>; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { delegate_call!(self.poll_next(cx)) } } -impl Sink for EthRlpxConnection { +impl Sink> for EthRlpxConnection { type Error = EthStreamError; fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { delegate_call!(self.poll_ready(cx)) } - fn start_send(self: Pin<&mut Self>, item: EthMessage) -> Result<(), Self::Error> { + fn start_send(self: Pin<&mut Self>, item: EthMessage) -> Result<(), Self::Error> { delegate_call!(self.start_send(item)) } diff --git a/crates/net/network/src/session/handle.rs b/crates/net/network/src/session/handle.rs index a022e670419..f80428630d9 100644 --- a/crates/net/network/src/session/handle.rs +++ b/crates/net/network/src/session/handle.rs @@ -5,7 +5,7 @@ use std::{io, net::SocketAddr, sync::Arc, time::Instant}; use reth_ecies::ECIESError; use reth_eth_wire::{ capability::CapabilityMessage, errors::EthStreamError, Capabilities, DisconnectReason, - EthVersion, Status, + EthVersion, NetworkPrimitives, Status, }; use reth_network_api::PeerInfo; use reth_network_peers::{NodeRecord, PeerId}; @@ -54,7 +54,7 @@ impl PendingSessionHandle { /// Within an active session that supports the `Ethereum Wire Protocol `, three high-level tasks can /// be performed: chain synchronization, block propagation and transaction exchange. #[derive(Debug)] -pub struct ActiveSessionHandle { +pub struct ActiveSessionHandle { /// The direction of the session pub(crate) direction: Direction, /// The assigned id for this session @@ -68,7 +68,7 @@ pub struct ActiveSessionHandle { /// Announced capabilities of the peer. pub(crate) capabilities: Arc, /// Sender half of the command channel used send commands _to_ the spawned session - pub(crate) commands_to_session: mpsc::Sender, + pub(crate) commands_to_session: mpsc::Sender>, /// The client's name and version pub(crate) client_version: Arc, /// The address we're connected to @@ -81,7 +81,7 @@ pub struct ActiveSessionHandle { // === impl ActiveSessionHandle === -impl ActiveSessionHandle { +impl ActiveSessionHandle { /// Sends a disconnect command to the session. pub fn disconnect(&self, reason: Option) { // Note: we clone the sender which ensures the channel has capacity to send the message @@ -93,7 +93,7 @@ impl ActiveSessionHandle { pub async fn try_disconnect( &self, reason: Option, - ) -> Result<(), SendError> { + ) -> Result<(), SendError>> { self.commands_to_session.clone().send(SessionCommand::Disconnect { reason }).await } @@ -162,7 +162,7 @@ impl ActiveSessionHandle { /// /// A session starts with a `Handshake`, followed by a `Hello` message which #[derive(Debug)] -pub enum PendingSessionEvent { +pub enum PendingSessionEvent { /// Represents a successful `Hello` and `Status` exchange: Established { /// An internal identifier for the established session @@ -179,7 +179,7 @@ pub enum PendingSessionEvent { status: Arc, /// The actual connection stream which can be used to send and receive `eth` protocol /// messages - conn: EthRlpxConnection, + conn: EthRlpxConnection, /// The direction of the session, either `Inbound` or `Outgoing` direction: Direction, /// The remote node's user agent, usually containing the client name and version @@ -222,20 +222,20 @@ pub enum PendingSessionEvent { /// Commands that can be sent to the spawned session. #[derive(Debug)] -pub enum SessionCommand { +pub enum SessionCommand { /// Disconnect the connection Disconnect { /// Why the disconnect was initiated reason: Option, }, /// Sends a message to the peer - Message(PeerMessage), + Message(PeerMessage), } /// Message variants an active session can produce and send back to the /// [`SessionManager`](crate::session::SessionManager) #[derive(Debug)] -pub enum ActiveSessionMessage { +pub enum ActiveSessionMessage { /// Session was gracefully disconnected. Disconnected { /// The remote node's public key @@ -257,7 +257,7 @@ pub enum ActiveSessionMessage { /// Identifier of the remote peer. peer_id: PeerId, /// Message received from the peer. - message: PeerMessage, + message: PeerMessage, }, /// Received a message that does not match the announced capabilities of the peer. InvalidMessage { diff --git a/crates/net/network/src/session/mod.rs b/crates/net/network/src/session/mod.rs index 30b1cda9da9..a95f0e88910 100644 --- a/crates/net/network/src/session/mod.rs +++ b/crates/net/network/src/session/mod.rs @@ -28,11 +28,11 @@ use futures::{future::Either, io, FutureExt, StreamExt}; use reth_ecies::{stream::ECIESStream, ECIESError}; use reth_eth_wire::{ capability::CapabilityMessage, errors::EthStreamError, multiplex::RlpxProtocolMultiplexer, - Capabilities, DisconnectReason, EthVersion, HelloMessageWithProtocols, Status, - UnauthedEthStream, UnauthedP2PStream, + Capabilities, DisconnectReason, EthVersion, HelloMessageWithProtocols, NetworkPrimitives, + Status, UnauthedEthStream, UnauthedP2PStream, }; use reth_metrics::common::mpsc::MeteredPollSender; -use reth_network_api::PeerRequestSender; +use reth_network_api::{PeerRequest, PeerRequestSender}; use reth_network_peers::PeerId; use reth_network_types::SessionsConfig; use reth_primitives::{ForkFilter, ForkId, ForkTransition, Head}; @@ -62,7 +62,7 @@ pub struct SessionId(usize); /// Manages a set of sessions. #[must_use = "Session Manager must be polled to process session events."] #[derive(Debug)] -pub struct SessionManager { +pub struct SessionManager { /// Tracks the identifier for the next session. next_id: usize, /// Keeps track of all sessions @@ -93,21 +93,21 @@ pub struct SessionManager { /// session is authenticated, it can be moved to the `active_session` set. pending_sessions: FxHashMap, /// All active sessions that are ready to exchange messages. - active_sessions: HashMap, + active_sessions: HashMap>, /// The original Sender half of the [`PendingSessionEvent`] channel. /// /// When a new (pending) session is created, the corresponding [`PendingSessionHandle`] will /// get a clone of this sender half. - pending_sessions_tx: mpsc::Sender, + pending_sessions_tx: mpsc::Sender>, /// Receiver half that listens for [`PendingSessionEvent`] produced by pending sessions. - pending_session_rx: ReceiverStream, + pending_session_rx: ReceiverStream>, /// The original Sender half of the [`ActiveSessionMessage`] channel. /// /// When active session state is reached, the corresponding [`ActiveSessionHandle`] will get a /// clone of this sender half. - active_session_tx: MeteredPollSender, + active_session_tx: MeteredPollSender>, /// Receiver half that listens for [`ActiveSessionMessage`] produced by pending sessions. - active_session_rx: ReceiverStream, + active_session_rx: ReceiverStream>, /// Additional `RLPx` sub-protocols to be used by the session manager. extra_protocols: RlpxSubProtocols, /// Tracks the ongoing graceful disconnections attempts for incoming connections. @@ -118,7 +118,7 @@ pub struct SessionManager { // === impl SessionManager === -impl SessionManager { +impl SessionManager { /// Creates a new empty [`SessionManager`]. #[allow(clippy::too_many_arguments)] pub fn new( @@ -182,7 +182,7 @@ impl SessionManager { } /// Returns a borrowed reference to the active sessions. - pub const fn active_sessions(&self) -> &HashMap { + pub const fn active_sessions(&self) -> &HashMap> { &self.active_sessions } @@ -348,7 +348,7 @@ impl SessionManager { } /// Sends a message to the peer's session - pub fn send_message(&mut self, peer_id: &PeerId, msg: PeerMessage) { + pub fn send_message(&mut self, peer_id: &PeerId, msg: PeerMessage) { if let Some(session) = self.active_sessions.get_mut(peer_id) { let _ = session.commands_to_session.try_send(SessionCommand::Message(msg)).inspect_err( |e| { @@ -373,7 +373,7 @@ impl SessionManager { } /// Removes the [`PendingSessionHandle`] if it exists. - fn remove_active_session(&mut self, id: &PeerId) -> Option { + fn remove_active_session(&mut self, id: &PeerId) -> Option> { let session = self.active_sessions.remove(id)?; self.counter.dec_active(&session.direction); Some(session) @@ -411,7 +411,7 @@ impl SessionManager { /// This polls all the session handles and returns [`SessionEvent`]. /// /// Active sessions are prioritized. - pub(crate) fn poll(&mut self, cx: &mut Context<'_>) -> Poll { + pub(crate) fn poll(&mut self, cx: &mut Context<'_>) -> Poll> { // Poll events from active sessions match self.active_session_rx.poll_next_unpin(cx) { Poll::Pending => {} @@ -663,7 +663,7 @@ impl DisconnectionsCounter { /// Events produced by the [`SessionManager`] #[derive(Debug)] -pub enum SessionEvent { +pub enum SessionEvent { /// A new session was successfully authenticated. /// /// This session is now able to exchange data. @@ -681,7 +681,7 @@ pub enum SessionEvent { /// The Status message the peer sent during the `eth` handshake status: Arc, /// The channel for sending messages to the peer with the session - messages: PeerRequestSender, + messages: PeerRequestSender>, /// The direction of the session, either `Inbound` or `Outgoing` direction: Direction, /// The maximum time that the session waits for a response from the peer before timing out @@ -702,7 +702,7 @@ pub enum SessionEvent { /// The remote node's public key peer_id: PeerId, /// Message received from the peer. - message: PeerMessage, + message: PeerMessage, }, /// Received a message that does not match the announced capabilities of the peer. InvalidMessage { @@ -797,12 +797,12 @@ impl PendingSessionHandshakeError { pub struct ExceedsSessionLimit(pub(crate) u32); /// Starts a pending session authentication with a timeout. -pub(crate) async fn pending_session_with_timeout( +pub(crate) async fn pending_session_with_timeout( timeout: Duration, session_id: SessionId, remote_addr: SocketAddr, direction: Direction, - events: mpsc::Sender, + events: mpsc::Sender>, f: F, ) where F: Future, @@ -823,11 +823,11 @@ pub(crate) async fn pending_session_with_timeout( /// /// This will wait for the _incoming_ handshake request and answer it. #[allow(clippy::too_many_arguments)] -pub(crate) async fn start_pending_incoming_session( +pub(crate) async fn start_pending_incoming_session( disconnect_rx: oneshot::Receiver<()>, session_id: SessionId, stream: TcpStream, - events: mpsc::Sender, + events: mpsc::Sender>, remote_addr: SocketAddr, secret_key: SecretKey, hello: HelloMessageWithProtocols, @@ -854,9 +854,9 @@ pub(crate) async fn start_pending_incoming_session( /// Starts the authentication process for a connection initiated by a remote peer. #[instrument(skip_all, fields(%remote_addr, peer_id), target = "net")] #[allow(clippy::too_many_arguments)] -async fn start_pending_outbound_session( +async fn start_pending_outbound_session( disconnect_rx: oneshot::Receiver<()>, - events: mpsc::Sender, + events: mpsc::Sender>, session_id: SessionId, remote_addr: SocketAddr, remote_peer_id: PeerId, @@ -903,9 +903,9 @@ async fn start_pending_outbound_session( /// Authenticates a session #[allow(clippy::too_many_arguments)] -async fn authenticate( +async fn authenticate( disconnect_rx: oneshot::Receiver<()>, - events: mpsc::Sender, + events: mpsc::Sender>, stream: TcpStream, session_id: SessionId, remote_addr: SocketAddr, @@ -986,7 +986,7 @@ async fn get_ecies_stream( /// If additional [`RlpxSubProtocolHandlers`] are provided, the hello message will be updated to /// also negotiate the additional protocols. #[allow(clippy::too_many_arguments)] -async fn authenticate_stream( +async fn authenticate_stream( stream: UnauthedP2PStream>, session_id: SessionId, remote_addr: SocketAddr, @@ -996,7 +996,7 @@ async fn authenticate_stream( mut status: Status, fork_filter: ForkFilter, mut extra_handlers: RlpxSubProtocolHandlers, -) -> PendingSessionEvent { +) -> PendingSessionEvent { // Add extra protocols to the hello message extra_handlers.retain(|handler| hello.try_add_protocol(handler.protocol()).is_ok()); diff --git a/crates/net/network/src/state.rs b/crates/net/network/src/state.rs index 9ad7b53518b..3bafbf25856 100644 --- a/crates/net/network/src/state.rs +++ b/crates/net/network/src/state.rs @@ -12,6 +12,7 @@ use std::{ task::{Context, Poll}, }; +use alloy_consensus::BlockHeader; use alloy_primitives::B256; use rand::seq::SliceRandom; use reth_eth_wire::{ @@ -22,6 +23,7 @@ use reth_network_api::{DiscoveredEvent, DiscoveryEvent, PeerRequest, PeerRequest use reth_network_peers::PeerId; use reth_network_types::{PeerAddr, PeerKind}; use reth_primitives::ForkId; +use reth_primitives_traits::Block; use tokio::sync::oneshot; use tracing::{debug, trace}; @@ -78,7 +80,7 @@ pub struct NetworkState { /// Manages connections to peers. peers_manager: PeersManager, /// Buffered messages until polled. - queued_messages: VecDeque, + queued_messages: VecDeque>, /// The client type that can interact with the chain. /// /// This type is used to fetch the block number after we established a session and received the @@ -185,12 +187,12 @@ impl NetworkState { /// > the total number of peers) using the `NewBlock` message. /// /// See also - pub(crate) fn announce_new_block(&mut self, msg: NewBlockMessage) { + pub(crate) fn announce_new_block(&mut self, msg: NewBlockMessage) { // send a `NewBlock` message to a fraction of the connected peers (square root of the total // number of peers) let num_propagate = (self.active_peers.len() as f64).sqrt() as u64 + 1; - let number = msg.block.block.header.number; + let number = msg.block.block.header().number(); let mut count = 0; // Shuffle to propagate to a random sample of peers on every block announcement @@ -227,8 +229,8 @@ impl NetworkState { /// Completes the block propagation process started in [`NetworkState::announce_new_block()`] /// but sending `NewBlockHash` broadcast to all peers that haven't seen it yet. - pub(crate) fn announce_new_block_hash(&mut self, msg: NewBlockMessage) { - let number = msg.block.block.header.number; + pub(crate) fn announce_new_block_hash(&mut self, msg: NewBlockMessage) { + let number = msg.block.block.header().number(); let hashes = NewBlockHashes(vec![BlockHashNumber { hash: msg.hash, number }]); for (peer_id, peer) in &mut self.active_peers { if peer.blocks.contains(&msg.hash) { @@ -385,7 +387,10 @@ impl NetworkState { } /// Handle the outcome of processed response, for example directly queue another request. - fn on_block_response_outcome(&mut self, outcome: BlockResponseOutcome) -> Option { + fn on_block_response_outcome( + &mut self, + outcome: BlockResponseOutcome, + ) -> Option> { match outcome { BlockResponseOutcome::Request(peer, request) => { self.handle_block_request(peer, request); @@ -406,7 +411,7 @@ impl NetworkState { &mut self, peer: PeerId, resp: PeerResponseResult, - ) -> Option { + ) -> Option> { match resp { PeerResponseResult::BlockHeaders(res) => { let outcome = self.state_fetcher.on_block_headers_response(peer, res)?; @@ -421,7 +426,7 @@ impl NetworkState { } /// Advances the state - pub(crate) fn poll(&mut self, cx: &mut Context<'_>) -> Poll { + pub(crate) fn poll(&mut self, cx: &mut Context<'_>) -> Poll> { loop { // drain buffered messages if let Some(message) = self.queued_messages.pop_front() { @@ -515,13 +520,13 @@ pub(crate) struct ActivePeer { /// Message variants triggered by the [`NetworkState`] #[derive(Debug)] -pub(crate) enum StateAction { +pub(crate) enum StateAction { /// Dispatch a `NewBlock` message to the peer NewBlock { /// Target of the message peer_id: PeerId, /// The `NewBlock` message - block: NewBlockMessage, + block: NewBlockMessage, }, NewBlockHashes { /// Target of the message diff --git a/crates/net/network/src/swarm.rs b/crates/net/network/src/swarm.rs index c1fe9f9e231..655934f207a 100644 --- a/crates/net/network/src/swarm.rs +++ b/crates/net/network/src/swarm.rs @@ -9,9 +9,9 @@ use std::{ use futures::Stream; use reth_eth_wire::{ capability::CapabilityMessage, errors::EthStreamError, Capabilities, DisconnectReason, - EthVersion, Status, + EthNetworkPrimitives, EthVersion, NetworkPrimitives, Status, }; -use reth_network_api::PeerRequestSender; +use reth_network_api::{PeerRequest, PeerRequestSender}; use reth_network_peers::PeerId; use tracing::trace; @@ -50,23 +50,23 @@ use crate::{ /// `include_mmd!("docs/mermaid/swarm.mmd`") #[derive(Debug)] #[must_use = "Swarm does nothing unless polled"] -pub(crate) struct Swarm { +pub(crate) struct Swarm { /// Listens for new incoming connections. incoming: ConnectionListener, /// All sessions. - sessions: SessionManager, + sessions: SessionManager, /// Tracks the entire state of the network and handles events received from the sessions. - state: NetworkState, + state: NetworkState, } // === impl Swarm === -impl Swarm { +impl Swarm { /// Configures a new swarm instance. pub(crate) const fn new( incoming: ConnectionListener, - sessions: SessionManager, - state: NetworkState, + sessions: SessionManager, + state: NetworkState, ) -> Self { Self { incoming, sessions, state } } @@ -77,12 +77,12 @@ impl Swarm { } /// Access to the state. - pub(crate) const fn state(&self) -> &NetworkState { + pub(crate) const fn state(&self) -> &NetworkState { &self.state } /// Mutable access to the state. - pub(crate) fn state_mut(&mut self) -> &mut NetworkState { + pub(crate) fn state_mut(&mut self) -> &mut NetworkState { &mut self.state } @@ -92,17 +92,17 @@ impl Swarm { } /// Access to the [`SessionManager`]. - pub(crate) const fn sessions(&self) -> &SessionManager { + pub(crate) const fn sessions(&self) -> &SessionManager { &self.sessions } /// Mutable access to the [`SessionManager`]. - pub(crate) fn sessions_mut(&mut self) -> &mut SessionManager { + pub(crate) fn sessions_mut(&mut self) -> &mut SessionManager { &mut self.sessions } } -impl Swarm { +impl Swarm { /// Triggers a new outgoing connection to the given node pub(crate) fn dial_outbound(&mut self, remote_addr: SocketAddr, remote_id: PeerId) { self.sessions.dial_outbound(remote_addr, remote_id) @@ -112,7 +112,7 @@ impl Swarm { /// /// This either updates the state or produces a new [`SwarmEvent`] that is bubbled up to the /// manager. - fn on_session_event(&mut self, event: SessionEvent) -> Option { + fn on_session_event(&mut self, event: SessionEvent) -> Option> { match event { SessionEvent::SessionEstablished { peer_id, @@ -181,7 +181,7 @@ impl Swarm { /// Callback for events produced by [`ConnectionListener`]. /// /// Depending on the event, this will produce a new [`SwarmEvent`]. - fn on_connection(&mut self, event: ListenerEvent) -> Option { + fn on_connection(&mut self, event: ListenerEvent) -> Option> { match event { ListenerEvent::Error(err) => return Some(SwarmEvent::TcpListenerError(err)), ListenerEvent::ListenerClosed { local_address: address } => { @@ -229,7 +229,7 @@ impl Swarm { } /// Hook for actions pulled from the state - fn on_state_action(&mut self, event: StateAction) -> Option { + fn on_state_action(&mut self, event: StateAction) -> Option> { match event { StateAction::Connect { remote_addr, peer_id } => { self.dial_outbound(remote_addr, peer_id); @@ -286,8 +286,8 @@ impl Swarm { } } -impl Stream for Swarm { - type Item = SwarmEvent; +impl Stream for Swarm { + type Item = SwarmEvent; /// This advances all components. /// @@ -338,13 +338,13 @@ impl Stream for Swarm { /// All events created or delegated by the [`Swarm`] that represents changes to the state of the /// network. -pub(crate) enum SwarmEvent { +pub(crate) enum SwarmEvent { /// Events related to the actual network protocol. ValidMessage { /// The peer that sent the message peer_id: PeerId, /// Message received from the peer - message: PeerMessage, + message: PeerMessage, }, /// Received a message that does not match the announced capabilities of the peer. InvalidCapabilityMessage { @@ -394,7 +394,7 @@ pub(crate) enum SwarmEvent { capabilities: Arc, /// negotiated eth version version: EthVersion, - messages: PeerRequestSender, + messages: PeerRequestSender>, status: Arc, direction: Direction, }, diff --git a/crates/primitives-traits/src/block/body.rs b/crates/primitives-traits/src/block/body.rs index 14941ffed0f..6ec184a2154 100644 --- a/crates/primitives-traits/src/block/body.rs +++ b/crates/primitives-traits/src/block/body.rs @@ -6,7 +6,7 @@ use alloy_consensus::{BlockHeader, Transaction, TxType}; use alloy_eips::{eip4895::Withdrawal, eip7685::Requests}; use alloy_primitives::{Address, B256}; -use crate::{Block, InMemorySize}; +use crate::InMemorySize; /// Abstraction for block's body. pub trait BlockBody: @@ -47,11 +47,6 @@ pub trait BlockBody: /// Returns [`Requests`] in block, if any. fn requests(&self) -> Option<&Requests>; - /// Create a [`Block`] from the body and its header. - fn into_block>(self, header: Self::Header) -> T { - T::from((header, self)) - } - /// Calculate the transaction root for the block body. fn calculate_tx_root(&self) -> B256; diff --git a/crates/primitives-traits/src/block/mod.rs b/crates/primitives-traits/src/block/mod.rs index cfc9e9a5503..33008c4381d 100644 --- a/crates/primitives-traits/src/block/mod.rs +++ b/crates/primitives-traits/src/block/mod.rs @@ -3,12 +3,11 @@ pub mod body; pub mod header; -use alloc::{fmt, vec::Vec}; +use alloc::fmt; -use alloy_primitives::{Address, B256}; use reth_codecs::Compact; -use crate::{BlockBody, BlockHeader, FullBlockHeader, InMemorySize}; +use crate::{BlockHeader, FullBlockHeader, InMemorySize}; /// Helper trait that unifies all behaviour required by block to support full node operations. pub trait FullBlock: Block + Compact {} @@ -30,79 +29,17 @@ pub trait Block: + Eq + serde::Serialize + for<'a> serde::Deserialize<'a> - + From<(Self::Header, Self::Body)> - + Into<(Self::Header, Self::Body)> + InMemorySize { /// Header part of the block. type Header: BlockHeader; /// The block's body contains the transactions in the block. - type Body: BlockBody; + type Body: Send + Sync + Unpin + 'static; - /// A block and block hash. - type SealedBlock; - - /// A block and addresses of senders of transactions in it. - type BlockWithSenders; - - /// Returns reference to [`BlockHeader`] type. + /// Returns reference to block header. fn header(&self) -> &Self::Header; - /// Returns reference to [`BlockBody`] type. + /// Returns reference to block body. fn body(&self) -> &Self::Body; - - /// Calculate the header hash and seal the block so that it can't be changed. - // todo: can be default impl if sealed block type is made generic over header and body and - // migrated to alloy - fn seal_slow(self) -> Self::SealedBlock; - - /// Seal the block with a known hash. - /// - /// WARNING: This method does not perform validation whether the hash is correct. - // todo: can be default impl if sealed block type is made generic over header and body and - // migrated to alloy - fn seal(self, hash: B256) -> Self::SealedBlock; - - /// Expensive operation that recovers transaction signer. See - /// `SealedBlockWithSenders`. - fn senders(&self) -> Option> { - self.body().recover_signers() - } - - /// Transform into a `BlockWithSenders`. - /// - /// # Panics - /// - /// If the number of senders does not match the number of transactions in the block - /// and the signer recovery for one of the transactions fails. - /// - /// Note: this is expected to be called with blocks read from disk. - #[track_caller] - fn with_senders_unchecked(self, senders: Vec
) -> Self::BlockWithSenders { - self.try_with_senders_unchecked(senders).expect("stored block is valid") - } - - /// Transform into a `BlockWithSenders` using the given senders. - /// - /// If the number of senders does not match the number of transactions in the block, this falls - /// back to manually recovery, but _without ensuring that the signature has a low `s` value_. - /// See also `SignedTransaction::recover_signer_unchecked`. - /// - /// Returns an error if a signature is invalid. - // todo: can be default impl if block with senders type is made generic over block and migrated - // to alloy - #[track_caller] - fn try_with_senders_unchecked( - self, - senders: Vec
, - ) -> Result, Self>; - - /// **Expensive**. Transform into a `BlockWithSenders` by recovering senders in the contained - /// transactions. - /// - /// Returns `None` if a transaction is invalid. - // todo: can be default impl if sealed block type is made generic over header and body and - // migrated to alloy - fn with_recovered_senders(self) -> Option>; } diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index c0586ed6a8f..6743cab3dc3 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -87,6 +87,19 @@ impl Block { } } +impl reth_primitives_traits::Block for Block { + type Header = Header; + type Body = BlockBody; + + fn body(&self) -> &Self::Body { + &self.body + } + + fn header(&self) -> &Self::Header { + &self.header + } +} + impl InMemorySize for Block { /// Calculates a heuristic for the in-memory size of the [`Block`]. #[inline] From 98841676847980245107f03500a48fa5e8fb0436 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 12 Nov 2024 20:40:29 +0100 Subject: [PATCH 130/211] chore: move standalone types to types crate (#12483) --- crates/static-file/static-file/src/lib.rs | 4 +- .../static-file/src/static_file_producer.rs | 36 +---------------- .../{static-file => types}/src/event.rs | 2 +- crates/static-file/types/src/lib.rs | 40 +++++++++++++++++++ 4 files changed, 43 insertions(+), 39 deletions(-) rename crates/static-file/{static-file => types}/src/event.rs (87%) diff --git a/crates/static-file/static-file/src/lib.rs b/crates/static-file/static-file/src/lib.rs index 1bfe4134e95..6c95baaae92 100644 --- a/crates/static-file/static-file/src/lib.rs +++ b/crates/static-file/static-file/src/lib.rs @@ -7,14 +7,12 @@ )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -mod event; pub mod segments; mod static_file_producer; -pub use event::StaticFileProducerEvent; pub use static_file_producer::{ StaticFileProducer, StaticFileProducerInner, StaticFileProducerResult, - StaticFileProducerWithResult, StaticFileTargets, + StaticFileProducerWithResult, }; // Re-export for convenience. diff --git a/crates/static-file/static-file/src/static_file_producer.rs b/crates/static-file/static-file/src/static_file_producer.rs index 2c442aedfa3..0f07ec32821 100644 --- a/crates/static-file/static-file/src/static_file_producer.rs +++ b/crates/static-file/static-file/src/static_file_producer.rs @@ -10,7 +10,7 @@ use reth_provider::{ }; use reth_prune_types::PruneModes; use reth_stages_types::StageId; -use reth_static_file_types::HighestStaticFiles; +use reth_static_file_types::{HighestStaticFiles, StaticFileTargets}; use reth_storage_errors::provider::ProviderResult; use reth_tokio_util::{EventSender, EventStream}; use std::{ @@ -66,40 +66,6 @@ pub struct StaticFileProducerInner { event_sender: EventSender, } -/// Static File targets, per data segment, measured in [`BlockNumber`]. -#[derive(Debug, Clone, Eq, PartialEq)] -pub struct StaticFileTargets { - headers: Option>, - receipts: Option>, - transactions: Option>, -} - -impl StaticFileTargets { - /// Returns `true` if any of the targets are [Some]. - pub const fn any(&self) -> bool { - self.headers.is_some() || self.receipts.is_some() || self.transactions.is_some() - } - - // Returns `true` if all targets are either [`None`] or has beginning of the range equal to the - // highest static_file. - fn is_contiguous_to_highest_static_files(&self, static_files: HighestStaticFiles) -> bool { - [ - (self.headers.as_ref(), static_files.headers), - (self.receipts.as_ref(), static_files.receipts), - (self.transactions.as_ref(), static_files.transactions), - ] - .iter() - .all(|(target_block_range, highest_static_fileted_block)| { - target_block_range.map_or(true, |target_block_range| { - *target_block_range.start() == - highest_static_fileted_block.map_or(0, |highest_static_fileted_block| { - highest_static_fileted_block + 1 - }) - }) - }) - } -} - impl StaticFileProducerInner { fn new(provider: Provider, prune_modes: PruneModes) -> Self { Self { provider, prune_modes, event_sender: Default::default() } diff --git a/crates/static-file/static-file/src/event.rs b/crates/static-file/types/src/event.rs similarity index 87% rename from crates/static-file/static-file/src/event.rs rename to crates/static-file/types/src/event.rs index a11333ce53a..1e5d2cb6032 100644 --- a/crates/static-file/static-file/src/event.rs +++ b/crates/static-file/types/src/event.rs @@ -1,7 +1,7 @@ use crate::StaticFileTargets; use std::time::Duration; -/// An event emitted by a [`StaticFileProducer`][crate::StaticFileProducer]. +/// An event emitted by the static file producer. #[derive(Debug, PartialEq, Eq, Clone)] pub enum StaticFileProducerEvent { /// Emitted when static file producer started running. diff --git a/crates/static-file/types/src/lib.rs b/crates/static-file/types/src/lib.rs index 6e954a781b7..4e9bf90f1c9 100644 --- a/crates/static-file/types/src/lib.rs +++ b/crates/static-file/types/src/lib.rs @@ -9,11 +9,14 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] mod compression; +mod event; mod segment; use alloy_primitives::BlockNumber; pub use compression::Compression; +pub use event::StaticFileProducerEvent; pub use segment::{SegmentConfig, SegmentHeader, SegmentRangeInclusive, StaticFileSegment}; +use std::ops::RangeInclusive; /// Default static file block count. pub const DEFAULT_BLOCKS_PER_STATIC_FILE: u64 = 500_000; @@ -62,6 +65,43 @@ impl HighestStaticFiles { } } +/// Static File targets, per data segment, measured in [`BlockNumber`]. +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct StaticFileTargets { + /// Targeted range of headers. + pub headers: Option>, + /// Targeted range of receipts. + pub receipts: Option>, + /// Targeted range of transactions. + pub transactions: Option>, +} + +impl StaticFileTargets { + /// Returns `true` if any of the targets are [Some]. + pub const fn any(&self) -> bool { + self.headers.is_some() || self.receipts.is_some() || self.transactions.is_some() + } + + /// Returns `true` if all targets are either [`None`] or has beginning of the range equal to the + /// highest static file. + pub fn is_contiguous_to_highest_static_files(&self, static_files: HighestStaticFiles) -> bool { + [ + (self.headers.as_ref(), static_files.headers), + (self.receipts.as_ref(), static_files.receipts), + (self.transactions.as_ref(), static_files.transactions), + ] + .iter() + .all(|(target_block_range, highest_static_fileted_block)| { + target_block_range.map_or(true, |target_block_range| { + *target_block_range.start() == + highest_static_fileted_block.map_or(0, |highest_static_fileted_block| { + highest_static_fileted_block + 1 + }) + }) + }) + } +} + /// Each static file has a fixed number of blocks. This gives out the range where the requested /// block is positioned. Used for segment filename. pub const fn find_fixed_range( From b6558f6bcf83e3ea7c1cf755492406f0cc3c2577 Mon Sep 17 00:00:00 2001 From: clabby Date: Tue, 12 Nov 2024 15:57:41 -0500 Subject: [PATCH 131/211] chore: Update Holocene timestamp for Sepolia (#12479) --- crates/optimism/chainspec/src/lib.rs | 12 ++++++------ crates/optimism/hardforks/src/hardfork.rs | 6 +++--- crates/optimism/node/src/engine.rs | 10 +++++----- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/crates/optimism/chainspec/src/lib.rs b/crates/optimism/chainspec/src/lib.rs index a835b02bd1d..c110c4b0821 100644 --- a/crates/optimism/chainspec/src/lib.rs +++ b/crates/optimism/chainspec/src/lib.rs @@ -573,11 +573,11 @@ mod tests { ), ( Head { number: 0, timestamp: 1723478400, ..Default::default() }, - ForkId { hash: ForkHash([0x75, 0xde, 0xa4, 0x1e]), next: 1732201200 }, + ForkId { hash: ForkHash([0x75, 0xde, 0xa4, 0x1e]), next: 1732633200 }, ), ( - Head { number: 0, timestamp: 1732201200, ..Default::default() }, - ForkId { hash: ForkHash([0x98, 0x1c, 0x21, 0x69]), next: 0 }, + Head { number: 0, timestamp: 1732633200, ..Default::default() }, + ForkId { hash: ForkHash([0x4a, 0x1c, 0x79, 0x2e]), next: 0 }, ), ], ); @@ -644,11 +644,11 @@ mod tests { ), ( Head { number: 0, timestamp: 1723478400, ..Default::default() }, - ForkId { hash: ForkHash([0x5e, 0xdf, 0xa3, 0xb6]), next: 1732201200 }, + ForkId { hash: ForkHash([0x5e, 0xdf, 0xa3, 0xb6]), next: 1732633200 }, ), ( - Head { number: 0, timestamp: 1732201200, ..Default::default() }, - ForkId { hash: ForkHash([0x59, 0x5e, 0x2e, 0x6e]), next: 0 }, + Head { number: 0, timestamp: 1732633200, ..Default::default() }, + ForkId { hash: ForkHash([0x8b, 0x5e, 0x76, 0x29]), next: 0 }, ), ], ); diff --git a/crates/optimism/hardforks/src/hardfork.rs b/crates/optimism/hardforks/src/hardfork.rs index 91b2584e4f9..661816ae5fe 100644 --- a/crates/optimism/hardforks/src/hardfork.rs +++ b/crates/optimism/hardforks/src/hardfork.rs @@ -158,7 +158,7 @@ impl OpHardfork { Self::Ecotone => Some(1708534800), Self::Fjord => Some(1716998400), Self::Granite => Some(1723478400), - Self::Holocene => Some(1732201200), + Self::Holocene => Some(1732633200), }, ) } @@ -257,7 +257,7 @@ impl OpHardfork { (Self::Ecotone.boxed(), ForkCondition::Timestamp(1708534800)), (Self::Fjord.boxed(), ForkCondition::Timestamp(1716998400)), (Self::Granite.boxed(), ForkCondition::Timestamp(1723478400)), - (Self::Holocene.boxed(), ForkCondition::Timestamp(1732201200)), + (Self::Holocene.boxed(), ForkCondition::Timestamp(1732633200)), ]) } @@ -289,7 +289,7 @@ impl OpHardfork { (Self::Ecotone.boxed(), ForkCondition::Timestamp(1708534800)), (Self::Fjord.boxed(), ForkCondition::Timestamp(1716998400)), (Self::Granite.boxed(), ForkCondition::Timestamp(1723478400)), - (Self::Holocene.boxed(), ForkCondition::Timestamp(1732201200)), + (Self::Holocene.boxed(), ForkCondition::Timestamp(1732633200)), ]) } diff --git a/crates/optimism/node/src/engine.rs b/crates/optimism/node/src/engine.rs index 69755d10446..dd4d0c13f24 100644 --- a/crates/optimism/node/src/engine.rs +++ b/crates/optimism/node/src/engine.rs @@ -214,7 +214,7 @@ mod test { #[test] fn test_well_formed_attributes_pre_holocene() { let validator = OpEngineValidator::new(get_chainspec()); - let attributes = get_attributes(None, 1732201199); + let attributes = get_attributes(None, 1732633199); let result = Date: Tue, 12 Nov 2024 21:58:16 +0100 Subject: [PATCH 132/211] chore: Move`StatsReader` trait to storage-api and reexport it from old provider crate (#12485) --- crates/storage/provider/src/lib.rs | 4 ++-- crates/storage/provider/src/traits/mod.rs | 3 --- crates/storage/storage-api/src/lib.rs | 3 +++ .../storage/{provider/src/traits => storage-api/src}/stats.rs | 0 4 files changed, 5 insertions(+), 5 deletions(-) rename crates/storage/{provider/src/traits => storage-api/src}/stats.rs (100%) diff --git a/crates/storage/provider/src/lib.rs b/crates/storage/provider/src/lib.rs index 2b002fe11ec..deccdea2831 100644 --- a/crates/storage/provider/src/lib.rs +++ b/crates/storage/provider/src/lib.rs @@ -46,8 +46,8 @@ pub use reth_chain_state::{ CanonStateNotifications, CanonStateSubscriptions, }; -// reexport HistoryWriter trait -pub use reth_storage_api::HistoryWriter; +// reexport traits to avoid breaking changes +pub use reth_storage_api::{HistoryWriter, StatsReader}; pub(crate) fn to_range>(bounds: R) -> std::ops::Range { let start = match bounds.start_bound() { diff --git a/crates/storage/provider/src/traits/mod.rs b/crates/storage/provider/src/traits/mod.rs index 722721525bf..3034eda8044 100644 --- a/crates/storage/provider/src/traits/mod.rs +++ b/crates/storage/provider/src/traits/mod.rs @@ -29,9 +29,6 @@ pub use trie::{StorageTrieWriter, TrieWriter}; mod static_file_provider; pub use static_file_provider::StaticFileProviderFactory; -mod stats; -pub use stats::StatsReader; - mod full; pub use full::{FullProvider, FullRpcProvider}; diff --git a/crates/storage/storage-api/src/lib.rs b/crates/storage/storage-api/src/lib.rs index 21d02325afe..4980335066f 100644 --- a/crates/storage/storage-api/src/lib.rs +++ b/crates/storage/storage-api/src/lib.rs @@ -56,3 +56,6 @@ pub mod noop; mod history; pub use history::*; + +mod stats; +pub use stats::*; diff --git a/crates/storage/provider/src/traits/stats.rs b/crates/storage/storage-api/src/stats.rs similarity index 100% rename from crates/storage/provider/src/traits/stats.rs rename to crates/storage/storage-api/src/stats.rs From 3c5668600073f07138797bb3d87e589b4f5d0184 Mon Sep 17 00:00:00 2001 From: Ayodeji Akinola Date: Wed, 13 Nov 2024 00:12:45 +0100 Subject: [PATCH 133/211] feat(rpc): add compression to JSON-RPC (#12352) --- Cargo.lock | 10 +- Cargo.toml | 4 +- crates/rpc/rpc-builder/src/lib.rs | 19 +- crates/rpc/rpc-layer/Cargo.toml | 3 +- crates/rpc/rpc-layer/src/compression_layer.rs | 169 ++++++++++++++++++ crates/rpc/rpc-layer/src/lib.rs | 2 + 6 files changed, 195 insertions(+), 12 deletions(-) create mode 100644 crates/rpc/rpc-layer/src/compression_layer.rs diff --git a/Cargo.lock b/Cargo.lock index 5ce7b0c0ec7..ab53c0862ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8944,12 +8944,14 @@ version = "1.1.1" dependencies = [ "alloy-rpc-types-engine", "http", + "http-body-util", "jsonrpsee", "jsonrpsee-http-client", "pin-project", "reqwest", "tokio", "tower 0.4.13", + "tower-http", "tracing", ] @@ -10904,12 +10906,12 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.5.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" +checksum = "8437150ab6bbc8c5f0f519e3d5ed4aa883a83dd4cdd3d1b21f9482936046cb97" dependencies = [ "async-compression", - "base64 0.21.7", + "base64 0.22.1", "bitflags 2.6.0", "bytes", "futures-core", @@ -10926,7 +10928,7 @@ dependencies = [ "pin-project-lite", "tokio", "tokio-util", - "tower 0.4.13", + "tower 0.5.1", "tower-layer", "tower-service", "tracing", diff --git a/Cargo.toml b/Cargo.toml index cd7054ea1e7..9f46533014a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -552,7 +552,8 @@ hyper-util = "0.1.5" pin-project = "1.0.12" reqwest = { version = "0.12", default-features = false } tower = "0.4" -tower-http = "0.5" +tower-http = "0.6" + # p2p discv5 = "0.8.0" @@ -567,6 +568,7 @@ jsonrpsee-types = "0.24" # http http = "1.0" http-body = "1.0" +http-body-util = "0.1.2" jsonwebtoken = "9" proptest-arbitrary-interop = "0.1.0" diff --git a/crates/rpc/rpc-builder/src/lib.rs b/crates/rpc/rpc-builder/src/lib.rs index 385b92af3d0..40e40962349 100644 --- a/crates/rpc/rpc-builder/src/lib.rs +++ b/crates/rpc/rpc-builder/src/lib.rs @@ -166,6 +166,7 @@ use std::{ time::{Duration, SystemTime, UNIX_EPOCH}, }; +use crate::{auth::AuthRpcModule, error::WsHttpSamePortError, metrics::RpcRequestMetrics}; use error::{ConflictingModules, RpcError, ServerKind}; use eth::DynEthApiBuilder; use http::{header::AUTHORIZATION, HeaderMap}; @@ -197,15 +198,13 @@ use reth_rpc_eth_api::{ EthApiServer, EthApiTypes, FullEthApiServer, RpcBlock, RpcReceipt, RpcTransaction, }; use reth_rpc_eth_types::{EthConfig, EthStateCache, EthSubscriptionIdProvider}; -use reth_rpc_layer::{AuthLayer, Claims, JwtAuthValidator, JwtSecret}; +use reth_rpc_layer::{AuthLayer, Claims, CompressionLayer, JwtAuthValidator, JwtSecret}; use reth_tasks::{pool::BlockingTaskGuard, TaskSpawner, TokioTaskExecutor}; use reth_transaction_pool::{noop::NoopTransactionPool, TransactionPool}; use serde::{Deserialize, Serialize}; use tower::Layer; use tower_http::cors::CorsLayer; -use crate::{auth::AuthRpcModule, error::WsHttpSamePortError, metrics::RpcRequestMetrics}; - pub use cors::CorsDomainError; // re-export for convenience @@ -1647,6 +1646,12 @@ impl RpcServerConfig { jwt_secret.map(|secret| AuthLayer::new(JwtAuthValidator::new(secret))) } + /// Returns a [`CompressionLayer`] that adds compression support (gzip, deflate, brotli, zstd) + /// based on the client's `Accept-Encoding` header + fn maybe_compression_layer() -> Option { + Some(CompressionLayer::new()) + } + /// Builds and starts the configured server(s): http, ws, ipc. /// /// If both http and ws are on the same port, they are combined into one server. @@ -1711,7 +1716,8 @@ impl RpcServerConfig { .set_http_middleware( tower::ServiceBuilder::new() .option_layer(Self::maybe_cors_layer(cors)?) - .option_layer(Self::maybe_jwt_layer(self.jwt_secret)), + .option_layer(Self::maybe_jwt_layer(self.jwt_secret)) + .option_layer(Self::maybe_compression_layer()), ) .set_rpc_middleware( self.rpc_middleware.clone().layer( @@ -1783,8 +1789,9 @@ impl RpcServerConfig { .http_only() .set_http_middleware( tower::ServiceBuilder::new() - .option_layer(Self::maybe_cors_layer(self.http_cors_domains.clone())?) - .option_layer(Self::maybe_jwt_layer(self.jwt_secret)), + .option_layer(Self::maybe_cors_layer(self.ws_cors_domains.clone())?) + .option_layer(Self::maybe_jwt_layer(self.jwt_secret)) + .option_layer(Self::maybe_compression_layer()), ) .set_rpc_middleware( self.rpc_middleware.clone().layer( diff --git a/crates/rpc/rpc-layer/Cargo.toml b/crates/rpc/rpc-layer/Cargo.toml index ec8dcb8229e..d44e5e89f01 100644 --- a/crates/rpc/rpc-layer/Cargo.toml +++ b/crates/rpc/rpc-layer/Cargo.toml @@ -17,10 +17,11 @@ http.workspace = true jsonrpsee-http-client.workspace = true pin-project.workspace = true tower.workspace = true - +tower-http = { workspace = true, features = ["full"] } tracing.workspace = true [dev-dependencies] reqwest.workspace = true tokio = { workspace = true, features = ["macros"] } jsonrpsee = { workspace = true, features = ["server"] } +http-body-util.workspace=true diff --git a/crates/rpc/rpc-layer/src/compression_layer.rs b/crates/rpc/rpc-layer/src/compression_layer.rs new file mode 100644 index 00000000000..cf15f04aa78 --- /dev/null +++ b/crates/rpc/rpc-layer/src/compression_layer.rs @@ -0,0 +1,169 @@ +use jsonrpsee_http_client::{HttpBody, HttpRequest, HttpResponse}; +use std::{ + future::Future, + pin::Pin, + task::{Context, Poll}, +}; +use tower::{Layer, Service}; +use tower_http::compression::{Compression, CompressionLayer as TowerCompressionLayer}; + +/// This layer is a wrapper around [`tower_http::compression::CompressionLayer`] that integrates +/// with jsonrpsee's HTTP types. It automatically compresses responses based on the client's +/// Accept-Encoding header. +#[allow(missing_debug_implementations)] +#[derive(Clone)] +pub struct CompressionLayer { + inner_layer: TowerCompressionLayer, +} + +impl CompressionLayer { + /// Creates a new compression layer with zstd, gzip, brotli and deflate enabled. + pub fn new() -> Self { + Self { + inner_layer: TowerCompressionLayer::new().gzip(true).br(true).deflate(true).zstd(true), + } + } +} + +impl Default for CompressionLayer { + /// Creates a new compression layer with default settings. + /// See [`CompressionLayer::new`] for details. + fn default() -> Self { + Self::new() + } +} + +impl Layer for CompressionLayer { + type Service = CompressionService; + + fn layer(&self, inner: S) -> Self::Service { + CompressionService { compression: self.inner_layer.layer(inner) } + } +} + +/// Service that performs response compression. +/// +/// Created by [`CompressionLayer`]. +#[allow(missing_debug_implementations)] +#[derive(Clone)] +pub struct CompressionService { + compression: Compression, +} + +impl Service for CompressionService +where + S: Service, + S::Future: Send + 'static, +{ + type Response = HttpResponse; + type Error = S::Error; + type Future = Pin> + Send>>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.compression.poll_ready(cx) + } + + fn call(&mut self, req: HttpRequest) -> Self::Future { + let fut = self.compression.call(req); + + Box::pin(async move { + let resp = fut.await?; + let (parts, compressed_body) = resp.into_parts(); + let http_body = HttpBody::new(compressed_body); + + Ok(Self::Response::from_parts(parts, http_body)) + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use http::header::{ACCEPT_ENCODING, CONTENT_ENCODING}; + use http_body_util::BodyExt; + use jsonrpsee_http_client::{HttpRequest, HttpResponse}; + use std::{convert::Infallible, future::ready}; + + const TEST_DATA: &str = "compress test data "; + const REPEAT_COUNT: usize = 1000; + + #[derive(Clone)] + struct MockRequestService; + + impl Service for MockRequestService { + type Response = HttpResponse; + type Error = Infallible; + type Future = std::future::Ready>; + + fn poll_ready( + &mut self, + _: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + std::task::Poll::Ready(Ok(())) + } + + fn call(&mut self, _: HttpRequest) -> Self::Future { + let body = HttpBody::from(TEST_DATA.repeat(REPEAT_COUNT)); + let response = HttpResponse::builder().body(body).unwrap(); + ready(Ok(response)) + } + } + + fn setup_compression_service( + ) -> impl Service { + CompressionLayer::new().layer(MockRequestService) + } + + async fn get_response_size(response: HttpResponse) -> usize { + // Get the total size of the response body + response.into_body().collect().await.unwrap().to_bytes().len() + } + + #[tokio::test] + async fn test_gzip_compression() { + let mut service = setup_compression_service(); + let request = + HttpRequest::builder().header(ACCEPT_ENCODING, "gzip").body(HttpBody::empty()).unwrap(); + + let uncompressed_len = TEST_DATA.repeat(REPEAT_COUNT).len(); + + // Make the request + let response = service.call(request).await.unwrap(); + + // Verify the response has gzip content-encoding + assert_eq!( + response.headers().get(CONTENT_ENCODING).unwrap(), + "gzip", + "Response should be gzip encoded" + ); + + // Verify the response body is actually compressed (should be smaller than original) + let compressed_size = get_response_size(response).await; + assert!( + compressed_size < uncompressed_len, + "Compressed size ({compressed_size}) should be smaller than original size ({uncompressed_len})" + ); + } + + #[tokio::test] + async fn test_no_compression_when_not_requested() { + // Create a service with compression + let mut service = setup_compression_service(); + let request = HttpRequest::builder().body(HttpBody::empty()).unwrap(); + + let response = service.call(request).await.unwrap(); + assert!( + response.headers().get(CONTENT_ENCODING).is_none(), + "Response should not be compressed when not requested" + ); + + let uncompressed_len = TEST_DATA.repeat(REPEAT_COUNT).len(); + + // Verify the response body matches the original size + let response_size = get_response_size(response).await; + assert!( + response_size == uncompressed_len, + "Response size ({response_size}) should equal original size ({uncompressed_len})" + ); + } +} diff --git a/crates/rpc/rpc-layer/src/lib.rs b/crates/rpc/rpc-layer/src/lib.rs index 8387bb160e8..540daf5592b 100644 --- a/crates/rpc/rpc-layer/src/lib.rs +++ b/crates/rpc/rpc-layer/src/lib.rs @@ -13,9 +13,11 @@ use jsonrpsee_http_client::HttpResponse; mod auth_client_layer; mod auth_layer; +mod compression_layer; mod jwt_validator; pub use auth_layer::{AuthService, ResponseFuture}; +pub use compression_layer::CompressionLayer; // Export alloy JWT types pub use alloy_rpc_types_engine::{Claims, JwtError, JwtSecret}; From 115a20ea6a6f42fd6abcf23d2cdaebb3cf25b51e Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 13 Nov 2024 00:12:59 +0100 Subject: [PATCH 134/211] fix: deposit tx gasPrice must be 0 (#12486) --- crates/optimism/rpc/src/eth/transaction.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/crates/optimism/rpc/src/eth/transaction.rs b/crates/optimism/rpc/src/eth/transaction.rs index 20aa379a0c1..39fa288feed 100644 --- a/crates/optimism/rpc/src/eth/transaction.rs +++ b/crates/optimism/rpc/src/eth/transaction.rs @@ -122,11 +122,18 @@ where block_hash, block_number, index: transaction_index, base_fee, .. } = tx_info; - let effective_gas_price = base_fee - .map(|base_fee| { - inner.effective_tip_per_gas(base_fee as u64).unwrap_or_default() + base_fee - }) - .unwrap_or_else(|| inner.max_fee_per_gas()); + let effective_gas_price = if inner.is_deposit() { + // For deposits, we must always set the `gasPrice` field to 0 in rpc + // deposit tx don't have a gas price field, but serde of `Transaction` will take care of + // it + 0 + } else { + base_fee + .map(|base_fee| { + inner.effective_tip_per_gas(base_fee as u64).unwrap_or_default() + base_fee + }) + .unwrap_or_else(|| inner.max_fee_per_gas()) + }; Ok(Transaction { inner: alloy_rpc_types_eth::Transaction { From a71dd9c91f1f27b40bf289fbac332ad495c97fb6 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 13 Nov 2024 00:13:11 +0100 Subject: [PATCH 135/211] chore: introduce tuple type for pruned info (#12484) --- crates/prune/prune/src/event.rs | 8 ++------ crates/prune/prune/src/pruner.rs | 18 +++++++++++------- crates/prune/types/src/lib.rs | 3 ++- crates/prune/types/src/pruner.rs | 14 ++++++++++++-- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/crates/prune/prune/src/event.rs b/crates/prune/prune/src/event.rs index 95a90d7628c..4f5806e592e 100644 --- a/crates/prune/prune/src/event.rs +++ b/crates/prune/prune/src/event.rs @@ -1,5 +1,5 @@ use alloy_primitives::BlockNumber; -use reth_prune_types::{PruneProgress, PruneSegment}; +use reth_prune_types::PrunedSegmentInfo; use std::time::Duration; /// An event emitted by a [Pruner][crate::Pruner]. @@ -8,9 +8,5 @@ pub enum PrunerEvent { /// Emitted when pruner started running. Started { tip_block_number: BlockNumber }, /// Emitted when pruner finished running. - Finished { - tip_block_number: BlockNumber, - elapsed: Duration, - stats: Vec<(PruneSegment, usize, PruneProgress)>, - }, + Finished { tip_block_number: BlockNumber, elapsed: Duration, stats: Vec }, } diff --git a/crates/prune/prune/src/pruner.rs b/crates/prune/prune/src/pruner.rs index d21560cae60..0ad149bb654 100644 --- a/crates/prune/prune/src/pruner.rs +++ b/crates/prune/prune/src/pruner.rs @@ -9,7 +9,7 @@ use reth_exex_types::FinishedExExHeight; use reth_provider::{ DBProvider, DatabaseProviderFactory, PruneCheckpointReader, PruneCheckpointWriter, }; -use reth_prune_types::{PruneLimiter, PruneProgress, PruneSegment, PrunerOutput}; +use reth_prune_types::{PruneLimiter, PruneProgress, PrunedSegmentInfo, PrunerOutput}; use reth_tokio_util::{EventSender, EventStream}; use std::time::{Duration, Instant}; use tokio::sync::watch; @@ -21,8 +21,6 @@ pub type PrunerResult = Result; /// The pruner type itself with the result of [`Pruner::run`] pub type PrunerWithResult = (Pruner, PrunerResult); -type PrunerStats = Vec<(PruneSegment, usize, PruneProgress)>; - /// Pruner with preset provider factory. pub type PrunerWithFactory = Pruner<::ProviderRW, PF>; @@ -174,14 +172,15 @@ where /// be pruned according to the highest `static_files`. Segments are parts of the database that /// represent one or more tables. /// - /// Returns [`PrunerStats`], total number of entries pruned, and [`PruneProgress`]. + /// Returns a list of stats per pruned segment, total number of entries pruned, and + /// [`PruneProgress`]. fn prune_segments( &mut self, provider: &Provider, tip_block_number: BlockNumber, limiter: &mut PruneLimiter, - ) -> Result<(PrunerStats, usize, PrunerOutput), PrunerError> { - let mut stats = PrunerStats::new(); + ) -> Result<(Vec, usize, PrunerOutput), PrunerError> { + let mut stats = Vec::with_capacity(self.segments.len()); let mut pruned = 0; let mut output = PrunerOutput { progress: PruneProgress::Finished, @@ -249,7 +248,12 @@ where if segment_output.pruned > 0 { limiter.increment_deleted_entries_count_by(segment_output.pruned); pruned += segment_output.pruned; - stats.push((segment.segment(), segment_output.pruned, segment_output.progress)); + let info = PrunedSegmentInfo { + segment: segment.segment(), + pruned: segment_output.pruned, + progress: segment_output.progress, + }; + stats.push(info); } } else { debug!(target: "pruner", segment = ?segment.segment(), purpose = ?segment.purpose(), "Nothing to prune for the segment"); diff --git a/crates/prune/types/src/lib.rs b/crates/prune/types/src/lib.rs index 8483b7b7370..0722e760faf 100644 --- a/crates/prune/types/src/lib.rs +++ b/crates/prune/types/src/lib.rs @@ -19,7 +19,8 @@ pub use checkpoint::PruneCheckpoint; pub use limiter::PruneLimiter; pub use mode::PruneMode; pub use pruner::{ - PruneInterruptReason, PruneProgress, PrunerOutput, SegmentOutput, SegmentOutputCheckpoint, + PruneInterruptReason, PruneProgress, PrunedSegmentInfo, PrunerOutput, SegmentOutput, + SegmentOutputCheckpoint, }; pub use segment::{PrunePurpose, PruneSegment, PruneSegmentError}; use serde::{Deserialize, Serialize}; diff --git a/crates/prune/types/src/pruner.rs b/crates/prune/types/src/pruner.rs index dbfafff639e..3046dda0679 100644 --- a/crates/prune/types/src/pruner.rs +++ b/crates/prune/types/src/pruner.rs @@ -1,6 +1,5 @@ -use alloy_primitives::{BlockNumber, TxNumber}; - use crate::{PruneCheckpoint, PruneLimiter, PruneMode, PruneSegment}; +use alloy_primitives::{BlockNumber, TxNumber}; /// Pruner run output. #[derive(Debug)] @@ -17,6 +16,17 @@ impl From for PrunerOutput { } } +/// Represents information of a pruner run for a segment. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct PrunedSegmentInfo { + /// The pruned segment + pub segment: PruneSegment, + /// Number of pruned entries + pub pruned: usize, + /// Prune progress + pub progress: PruneProgress, +} + /// Segment pruning output. #[derive(Debug, Clone, Copy, Eq, PartialEq)] pub struct SegmentOutput { From ce50370ba5855bb1c2b925e2df63496c849a6972 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Wed, 13 Nov 2024 00:15:50 +0100 Subject: [PATCH 136/211] primitives: rm alloy `Withdrawal` reexport (#12487) --- crates/primitives-traits/src/lib.rs | 1 - crates/primitives-traits/src/withdrawal.rs | 6 +----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index afcc74a894d..6848da45814 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -41,7 +41,6 @@ pub use block::{ }; mod withdrawal; -pub use withdrawal::Withdrawal; mod error; pub use error::{GotExpected, GotExpectedBoxed}; diff --git a/crates/primitives-traits/src/withdrawal.rs b/crates/primitives-traits/src/withdrawal.rs index 699229684ec..0849ab6202e 100644 --- a/crates/primitives-traits/src/withdrawal.rs +++ b/crates/primitives-traits/src/withdrawal.rs @@ -1,12 +1,8 @@ //! [EIP-4895](https://eips.ethereum.org/EIPS/eip-4895) Withdrawal types. -/// Re-export from `alloy_eips`. -#[doc(inline)] -pub use alloy_eips::eip4895::Withdrawal; - #[cfg(test)] mod tests { - use super::*; + use alloy_eips::eip4895::Withdrawal; use alloy_primitives::Address; use alloy_rlp::{RlpDecodable, RlpEncodable}; use proptest::proptest; From a96dee17f595c9d8d704f008a64f57ce9c8a2e84 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 13 Nov 2024 01:06:25 +0100 Subject: [PATCH 137/211] chore: bump alloy 064 (#12488) --- Cargo.lock | 168 +++++++++--------- Cargo.toml | 64 +++---- crates/optimism/cli/src/ovm_file_codec.rs | 2 +- crates/optimism/rpc/src/eth/transaction.rs | 31 ++-- crates/primitives/src/transaction/mod.rs | 63 +++---- .../primitives/src/transaction/signature.rs | 2 +- 6 files changed, 170 insertions(+), 160 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab53c0862ee..9748712e245 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -112,9 +112,9 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef11c6b2dfbf77dca7bafc6759860391395f07c04d5486f2a2e2563d2961639b" +checksum = "ae09ffd7c29062431dd86061deefe4e3c6f07fa0d674930095f8dcedb0baf02c" dependencies = [ "alloy-eips", "alloy-primitives", @@ -131,9 +131,9 @@ dependencies = [ [[package]] name = "alloy-contract" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8faa407ef916bfe0677c52c9b2258ce0698c53e9e15a837d1501e3ae9e57421a" +checksum = "66430a72d5bf5edead101c8c2f0a24bada5ec9f3cf9909b3e08b6d6899b4803e" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", @@ -198,9 +198,9 @@ dependencies = [ [[package]] name = "alloy-eips" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d6c0c1744a7af7d325dca6b5c5bb431a6307c0961088f7a236ca2694c4a87e" +checksum = "5b6aa3961694b30ba53d41006131a2fca3bdab22e4c344e46db2c639e7c2dfdd" dependencies = [ "alloy-eip2930", "alloy-eip7702", @@ -219,9 +219,9 @@ dependencies = [ [[package]] name = "alloy-genesis" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a5a0a01ef6ec3cd3ebd52a7b3bc7f8a92b23e478e69c07abd94abf05e6b48e" +checksum = "e53f7877ded3921d18a0a9556d55bedf84535567198c9edab2aa23106da91855" dependencies = [ "alloy-primitives", "alloy-serde", @@ -230,9 +230,9 @@ dependencies = [ [[package]] name = "alloy-json-abi" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded610181f3dad5810f6ff12d1a99994cf9b42d2fcb7709029352398a5da5ae6" +checksum = "b84c506bf264110fa7e90d9924f742f40ef53c6572ea56a0b0bd714a567ed389" dependencies = [ "alloy-primitives", "alloy-sol-type-parser", @@ -242,9 +242,9 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fd0e2cff5ab68defc5050ff9e81cb053c5b52cf4809fc8786664898e29ae75" +checksum = "3694b7e480728c0b3e228384f223937f14c10caef5a4c766021190fc8f283d35" dependencies = [ "alloy-primitives", "alloy-sol-types", @@ -256,9 +256,9 @@ dependencies = [ [[package]] name = "alloy-network" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c9eca0c04ca8a663966ce7f5b19c03927f2b4d82910cb76cb4008490cfa838" +checksum = "ea94b8ceb5c75d7df0a93ba0acc53b55a22b47b532b600a800a87ef04eb5b0b4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -279,9 +279,9 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c3050f19dc93a7f09fef670c8db04a15e7e2901494ca40decbce323be69643" +checksum = "df9f3e281005943944d15ee8491534a1c7b3cbf7a7de26f8c433b842b93eb5f9" dependencies = [ "alloy-consensus", "alloy-eips", @@ -292,9 +292,9 @@ dependencies = [ [[package]] name = "alloy-node-bindings" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5ebd44d0ab30f1018dc1ff01686ea1a3ae732601841a4fb277c9d0b3a34bf50" +checksum = "c9805d126f24be459b958973c0569c73e1aadd27d4535eee82b2b6764aa03616" dependencies = [ "alloy-genesis", "alloy-primitives", @@ -309,9 +309,9 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd58d377699e6cfeab52c4a9d28bdc4ef37e2bd235ff2db525071fe37a2e9af5" +checksum = "9fce5dbd6a4f118eecc4719eaa9c7ffc31c315e6c5ccde3642db927802312425" dependencies = [ "alloy-rlp", "arbitrary", @@ -341,9 +341,9 @@ dependencies = [ [[package]] name = "alloy-provider" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8e5a28e7c4c04afc0f20b2aecf6f9214d6cfd5009187c0b8616a8f8918739c" +checksum = "40c1f9eede27bf4c13c099e8e64d54efd7ce80ef6ea47478aa75d5d74e2dba3b" dependencies = [ "alloy-chains", "alloy-consensus", @@ -382,9 +382,9 @@ dependencies = [ [[package]] name = "alloy-pubsub" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "365dd813ec271a14febc31ea8ed64185856534f5644511f0c7a2961db060d878" +checksum = "90f1f34232f77341076541c405482e4ae12f0ee7153d8f9969fc1691201b2247" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -423,9 +423,9 @@ dependencies = [ [[package]] name = "alloy-rpc-client" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336362936bb9fef88f27d51f2ede8c15cdfdb7f81b042e74257770052547101" +checksum = "374dbe0dc3abdc2c964f36b3d3edf9cdb3db29d16bda34aa123f03d810bec1dd" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -448,9 +448,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac9a46bc01bc27dbf4dd27d46986eda661ffe99e78aea3078a77b8c064072b01" +checksum = "c74832aa474b670309c20fffc2a869fa141edab7c79ff7963fad0a08de60bae1" dependencies = [ "alloy-primitives", "alloy-rpc-types-engine", @@ -461,9 +461,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-admin" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82845a6f1ed33ef4edf79aa7cb091df31a532675921fb85041fbd8d6e029093d" +checksum = "6bfd9b2cc3a1985f1f6da5afc41120256f9f9316fcd89e054cea99dbb10172f6" dependencies = [ "alloy-genesis", "alloy-primitives", @@ -473,9 +473,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-anvil" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e73c06c3e44866d304fe28e8cebc8354f99fe405cc7c9bd23ed92eaebca3c07" +checksum = "5ca97963132f78ddfc60e43a017348e6d52eea983925c23652f5b330e8e02291" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -485,9 +485,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-beacon" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f9f6f071674c62424b62e22307aa83a35a0b1b84820649cc82034a50389ddc6" +checksum = "922fa76678d2f9f07ea1b19309b5cfbf244c6029dcba3515227b515fdd6ed4a7" dependencies = [ "alloy-eips", "alloy-primitives", @@ -499,9 +499,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-debug" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63a857818fe47dacaa7cc7a9cdcfee212cf1ebf119ab7bd157065d434671892d" +checksum = "ba2253bee958658ebd614c07a61c40580e09dd1fad3f017684314442332ab753" dependencies = [ "alloy-primitives", "serde", @@ -509,9 +509,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-engine" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee44332315ef1adde384e44db3b5724d74d0cd0e0856a681c4db2b4da3a423e" +checksum = "3f56294dce86af23ad6ee8df46cf8b0d292eb5d1ff67dc88a0886051e32b1faf" dependencies = [ "alloy-consensus", "alloy-eips", @@ -530,9 +530,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d58fa055e02d04bc70443ecce984951fb5be02d2c843c640ca48237cdec66af1" +checksum = "a8a477281940d82d29315846c7216db45b15e90bcd52309da9f54bcf7ad94a11" dependencies = [ "alloy-consensus", "alloy-eips", @@ -551,9 +551,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-mev" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "debf779b847b058b7c9cdef576f5ef539bc3032c5f6e5c1c2f51820b4f74e6d9" +checksum = "8647f8135ee3d5de1cf196706c905c05728a4e38bb4a5b61a7214bd1ba8f60a6" dependencies = [ "alloy-eips", "alloy-primitives", @@ -564,9 +564,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-trace" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1319edeae0e5f453424d658f8f450a5b1090b9ee6c0c014dc216b42f11c9dc57" +checksum = "ecd8b4877ef520c138af702097477cdd19504a8e1e4675ba37e92ba40f2d3c6f" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -578,9 +578,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-txpool" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fcb4b823dcd7228a89be1be85a4fa8008ad6d91b169b61f75f36b6e7386f37b" +checksum = "1d4ab49acf90a71f7fb894dc5fd485f1f07a1e348966c714c4d1e0b7478850a8" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -590,9 +590,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feafd71e0e252b063fe4b07962beedf0445e66b07b4b44af178863d21e75b0fa" +checksum = "4dfa4a7ccf15b2492bb68088692481fd6b2604ccbee1d0d6c44c21427ae4df83" dependencies = [ "alloy-primitives", "arbitrary", @@ -602,9 +602,9 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebad84d52550351438ec7f151dbc551f870c31eecf23b473df5b779a91eee8ca" +checksum = "2e10aec39d60dc27edcac447302c7803d2371946fb737245320a05b78eb2fafd" dependencies = [ "alloy-primitives", "async-trait", @@ -616,9 +616,9 @@ dependencies = [ [[package]] name = "alloy-signer-local" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed742d76943b5ebaabfdf3d0d8b69a4377fc2981c7955a807e33a3469aed0cdc" +checksum = "d8396f6dff60700bc1d215ee03d86ff56de268af96e2bf833a14d0bafcab9882" dependencies = [ "alloy-consensus", "alloy-network", @@ -634,9 +634,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a1b42ac8f45e2f49f4bcdd72cbfde0bb148f5481d403774ffa546e48b83efc1" +checksum = "9343289b4a7461ed8bab8618504c995c049c082b70c7332efd7b32125633dc05" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", @@ -648,9 +648,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-expander" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06318f1778e57f36333e850aa71bd1bb5e560c10279e236622faae0470c50412" +checksum = "4222d70bec485ceccc5d8fd4f2909edd65b5d5e43d4aca0b5dcee65d519ae98f" dependencies = [ "alloy-sol-macro-input", "const-hex", @@ -666,9 +666,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-input" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaebb9b0ad61a41345a22c9279975c0cdd231b97947b10d7aad1cf0a7181e4a5" +checksum = "2e17f2677369571b976e51ea1430eb41c3690d344fef567b840bfc0b01b6f83a" dependencies = [ "const-hex", "dunce", @@ -681,9 +681,9 @@ dependencies = [ [[package]] name = "alloy-sol-type-parser" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12c71028bfbfec210e24106a542aad3def7caf1a70e2c05710e92a98481980d3" +checksum = "aa64d80ae58ffaafdff9d5d84f58d03775f66c84433916dc9a64ed16af5755da" dependencies = [ "serde", "winnow", @@ -691,9 +691,9 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374d7fb042d68ddfe79ccb23359de3007f6d4d53c13f703b64fb0db422132111" +checksum = "6520d427d4a8eb7aa803d852d7a52ceb0c519e784c292f64bb339e636918cf27" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -704,9 +704,9 @@ dependencies = [ [[package]] name = "alloy-transport" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da63700a2b3176b3009a6d3672d0c657280a517dcec7659c991c55e863a83165" +checksum = "f99acddb34000d104961897dbb0240298e8b775a7efffb9fda2a1a3efedd65b3" dependencies = [ "alloy-json-rpc", "base64 0.22.1", @@ -724,9 +724,9 @@ dependencies = [ [[package]] name = "alloy-transport-http" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6613c3abc567b710217d241650ef73cfb8df9bcdc2ef23fdedabf363637e2a00" +checksum = "5dc013132e34eeadaa0add7e74164c1503988bfba8bae885b32e0918ba85a8a6" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -739,9 +739,9 @@ dependencies = [ [[package]] name = "alloy-transport-ipc" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7087a28734aac88a606884cdde8c89ad053bd1c0580c787e31f917a8e4a7cbdd" +checksum = "063edc0660e81260653cc6a95777c29d54c2543a668aa5da2359fb450d25a1ba" dependencies = [ "alloy-json-rpc", "alloy-pubsub", @@ -758,9 +758,9 @@ dependencies = [ [[package]] name = "alloy-transport-ws" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "672797b3f7bcbe67f712f9e8e5703b22f24594bd2b248a90916bdb58811b8b6e" +checksum = "abd170e600801116d5efe64f74a4fc073dbbb35c807013a7d0a388742aeebba0" dependencies = [ "alloy-pubsub", "alloy-transport", @@ -5297,9 +5297,9 @@ checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "op-alloy-consensus" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b5745eca869a0b476fbd34025ac40c06a15c46ffc10d6b1c40d21475b05f835" +checksum = "bff54d1d790eca1f3aedbd666162e9c42eceff90b9f9d24b352ed9c2df1e901a" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5315,9 +5315,9 @@ dependencies = [ [[package]] name = "op-alloy-genesis" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa6b2f26a84984213bc12649dfd8466a46ddeede3b8d2d936583000a8362b117" +checksum = "ae84fd64fbc53b3e958ea5a96d7f5633e4a111092e41c51672c2d91835c09efb" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5329,9 +5329,9 @@ dependencies = [ [[package]] name = "op-alloy-network" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67085a07a35e71db0a95ac923a2de2c186a37c5f376a1e4dee19b5ef8a6ffcaa" +checksum = "d71e777450ee3e9c5177e00865e9b4496472b623c50f146fc907b667c6b4ab37" dependencies = [ "alloy-consensus", "alloy-network", @@ -5344,9 +5344,9 @@ dependencies = [ [[package]] name = "op-alloy-protocol" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "880331b1b7718236a016eb7ac5530abcf7d5ca8b7ad78ac6c3dc8f73826ce9ee" +checksum = "1e854d2d4958d0a213731560172e8455536329ee9574473ff79fa953da91eb6a" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5364,9 +5364,9 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b75a52c8659756cfe1119f7711e94749c8dec6ad82408f3c55641ae413fb83" +checksum = "981b7f8ab11fe85ba3c1723702f000429b8d0c16b5883c93d577895f262cbac6" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5383,9 +5383,9 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types-engine" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622eabdff1739ef163aeb8e8385d5936fa54c14cfa55b06f72f1c8faa987f715" +checksum = "a227b16c9c5df68b112c8db9d268ebf46b3e26c744b4d59d4949575cd603a292" dependencies = [ "alloy-eips", "alloy-primitives", @@ -10452,9 +10452,9 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edf42e81491fb8871b74df3d222c64ae8cbc1269ea509fa768a3ed3e1b0ac8cb" +checksum = "f76fe0a3e1476bdaa0775b9aec5b869ed9520c2b2fedfe9c6df3618f8ea6290b" dependencies = [ "paste", "proc-macro2", diff --git a/Cargo.toml b/Cargo.toml index 9f46533014a..3f65bceb4bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -431,46 +431,46 @@ alloy-rlp = "0.3.4" alloy-sol-types = "0.8.11" alloy-trie = { version = "0.7", default-features = false } -alloy-consensus = { version = "0.6.3", default-features = false } -alloy-contract = { version = "0.6.3", default-features = false } -alloy-eips = { version = "0.6.3", default-features = false } -alloy-genesis = { version = "0.6.3", default-features = false } -alloy-json-rpc = { version = "0.6.3", default-features = false } -alloy-network = { version = "0.6.3", default-features = false } -alloy-network-primitives = { version = "0.6.3", default-features = false } -alloy-node-bindings = { version = "0.6.3", default-features = false } -alloy-provider = { version = "0.6.3", features = [ +alloy-consensus = { version = "0.6.4", default-features = false } +alloy-contract = { version = "0.6.4", default-features = false } +alloy-eips = { version = "0.6.4", default-features = false } +alloy-genesis = { version = "0.6.4", default-features = false } +alloy-json-rpc = { version = "0.6.4", default-features = false } +alloy-network = { version = "0.6.4", default-features = false } +alloy-network-primitives = { version = "0.6.4", default-features = false } +alloy-node-bindings = { version = "0.6.4", default-features = false } +alloy-provider = { version = "0.6.4", features = [ "reqwest", ], default-features = false } -alloy-pubsub = { version = "0.6.3", default-features = false } -alloy-rpc-client = { version = "0.6.3", default-features = false } -alloy-rpc-types = { version = "0.6.3", features = [ +alloy-pubsub = { version = "0.6.4", default-features = false } +alloy-rpc-client = { version = "0.6.4", default-features = false } +alloy-rpc-types = { version = "0.6.4", features = [ "eth", ], default-features = false } -alloy-rpc-types-admin = { version = "0.6.3", default-features = false } -alloy-rpc-types-anvil = { version = "0.6.3", default-features = false } -alloy-rpc-types-beacon = { version = "0.6.3", default-features = false } -alloy-rpc-types-debug = { version = "0.6.3", default-features = false } -alloy-rpc-types-engine = { version = "0.6.3", default-features = false } -alloy-rpc-types-eth = { version = "0.6.3", default-features = false } -alloy-rpc-types-mev = { version = "0.6.3", default-features = false } -alloy-rpc-types-trace = { version = "0.6.3", default-features = false } -alloy-rpc-types-txpool = { version = "0.6.3", default-features = false } -alloy-serde = { version = "0.6.3", default-features = false } -alloy-signer = { version = "0.6.3", default-features = false } -alloy-signer-local = { version = "0.6.3", default-features = false } -alloy-transport = { version = "0.6.3" } -alloy-transport-http = { version = "0.6.3", features = [ +alloy-rpc-types-admin = { version = "0.6.4", default-features = false } +alloy-rpc-types-anvil = { version = "0.6.4", default-features = false } +alloy-rpc-types-beacon = { version = "0.6.4", default-features = false } +alloy-rpc-types-debug = { version = "0.6.4", default-features = false } +alloy-rpc-types-engine = { version = "0.6.4", default-features = false } +alloy-rpc-types-eth = { version = "0.6.4", default-features = false } +alloy-rpc-types-mev = { version = "0.6.4", default-features = false } +alloy-rpc-types-trace = { version = "0.6.4", default-features = false } +alloy-rpc-types-txpool = { version = "0.6.4", default-features = false } +alloy-serde = { version = "0.6.4", default-features = false } +alloy-signer = { version = "0.6.4", default-features = false } +alloy-signer-local = { version = "0.6.4", default-features = false } +alloy-transport = { version = "0.6.4" } +alloy-transport-http = { version = "0.6.4", features = [ "reqwest-rustls-tls", ], default-features = false } -alloy-transport-ipc = { version = "0.6.3", default-features = false } -alloy-transport-ws = { version = "0.6.3", default-features = false } +alloy-transport-ipc = { version = "0.6.4", default-features = false } +alloy-transport-ws = { version = "0.6.4", default-features = false } # op -op-alloy-rpc-types = "0.6.4" -op-alloy-rpc-types-engine = "0.6.4" -op-alloy-network = "0.6.4" -op-alloy-consensus = "0.6.4" +op-alloy-rpc-types = "0.6.5" +op-alloy-rpc-types-engine = "0.6.5" +op-alloy-network = "0.6.5" +op-alloy-consensus = "0.6.5" # misc aquamarine = "0.6" diff --git a/crates/optimism/cli/src/ovm_file_codec.rs b/crates/optimism/cli/src/ovm_file_codec.rs index 624305c4b6e..b29d30093ec 100644 --- a/crates/optimism/cli/src/ovm_file_codec.rs +++ b/crates/optimism/cli/src/ovm_file_codec.rs @@ -149,7 +149,7 @@ impl TransactionSigned { chain_id: None, }; - let v: u64 = Decodable::decode(data)?; + let v = Decodable::decode(data)?; let r: U256 = Decodable::decode(data)?; let s: U256 = Decodable::decode(data)?; diff --git a/crates/optimism/rpc/src/eth/transaction.rs b/crates/optimism/rpc/src/eth/transaction.rs index 39fa288feed..11e33817229 100644 --- a/crates/optimism/rpc/src/eth/transaction.rs +++ b/crates/optimism/rpc/src/eth/transaction.rs @@ -1,7 +1,7 @@ //! Loads and formats OP transaction RPC response. use alloy_consensus::{Signed, Transaction as _}; -use alloy_primitives::{Bytes, B256}; +use alloy_primitives::{Bytes, Sealable, Sealed, B256}; use alloy_rpc_types_eth::TransactionInfo; use op_alloy_consensus::OpTxEnvelope; use op_alloy_rpc_types::Transaction; @@ -86,6 +86,7 @@ where let from = tx.signer(); let TransactionSigned { transaction, signature, hash } = tx.into_signed(); let mut deposit_receipt_version = None; + let mut deposit_nonce = None; let inner = match transaction { reth_primitives::Transaction::Legacy(tx) => { @@ -102,19 +103,16 @@ where Signed::new_unchecked(tx, signature, hash).into() } reth_primitives::Transaction::Deposit(tx) => { - let deposit_info = self - .inner + self.inner .provider() .receipt_by_hash(hash) .map_err(Self::Error::from_eth_err)? - .and_then(|receipt| receipt.deposit_receipt_version.zip(receipt.deposit_nonce)); + .inspect(|receipt| { + deposit_receipt_version = receipt.deposit_receipt_version; + deposit_nonce = receipt.deposit_nonce; + }); - if let Some((version, _)) = deposit_info { - deposit_receipt_version = Some(version); - // TODO: set nonce - } - - OpTxEnvelope::Deposit(tx) + OpTxEnvelope::Deposit(tx.seal_unchecked(hash)) } }; @@ -144,6 +142,7 @@ where from, effective_gas_price: Some(effective_gas_price), }, + deposit_nonce, deposit_receipt_version, }) } @@ -154,7 +153,17 @@ where OpTxEnvelope::Eip2930(tx) => &mut tx.tx_mut().input, OpTxEnvelope::Legacy(tx) => &mut tx.tx_mut().input, OpTxEnvelope::Eip7702(tx) => &mut tx.tx_mut().input, - OpTxEnvelope::Deposit(tx) => &mut tx.input, + OpTxEnvelope::Deposit(tx) => { + let (mut deposit, hash) = std::mem::replace( + tx, + Sealed::new_unchecked(Default::default(), Default::default()), + ) + .split(); + deposit.input = deposit.input.slice(..4); + let mut deposit = deposit.seal_unchecked(hash); + std::mem::swap(tx, &mut deposit); + return + } _ => return, }; *input = input.slice(..4); diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index 26815fc38de..f0caa2863aa 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -330,21 +330,6 @@ impl Transaction { self.as_eip4844().map(TxEip4844::blob_gas) } - /// Returns the effective gas price for the given base fee. - /// - /// If the transaction is a legacy or EIP2930 transaction, the gas price is returned. - pub const fn effective_gas_price(&self, base_fee: Option) -> u128 { - match self { - Self::Legacy(tx) => tx.gas_price, - Self::Eip2930(tx) => tx.gas_price, - Self::Eip1559(dynamic_tx) => dynamic_tx.effective_gas_price(base_fee), - Self::Eip4844(dynamic_tx) => dynamic_tx.effective_gas_price(base_fee), - Self::Eip7702(dynamic_tx) => dynamic_tx.effective_gas_price(base_fee), - #[cfg(feature = "optimism")] - Self::Deposit(_) => 0, - } - } - /// Returns the effective miner gas tip cap (`gasTipCap`) for the given base fee: /// `min(maxFeePerGas - baseFee, maxPriorityFeePerGas)` /// @@ -755,6 +740,18 @@ impl alloy_consensus::Transaction for Transaction { } } + fn effective_gas_price(&self, base_fee: Option) -> u128 { + match self { + Self::Legacy(tx) => tx.effective_gas_price(base_fee), + Self::Eip2930(tx) => tx.effective_gas_price(base_fee), + Self::Eip1559(tx) => tx.effective_gas_price(base_fee), + Self::Eip4844(tx) => tx.effective_gas_price(base_fee), + Self::Eip7702(tx) => tx.effective_gas_price(base_fee), + #[cfg(feature = "optimism")] + Self::Deposit(tx) => tx.effective_gas_price(base_fee), + } + } + fn is_dynamic_fee(&self) -> bool { match self { Self::Legacy(_) | Self::Eip2930(_) => false, @@ -764,6 +761,18 @@ impl alloy_consensus::Transaction for Transaction { } } + fn kind(&self) -> TxKind { + match self { + Self::Legacy(tx) => tx.kind(), + Self::Eip2930(tx) => tx.kind(), + Self::Eip1559(tx) => tx.kind(), + Self::Eip4844(tx) => tx.kind(), + Self::Eip7702(tx) => tx.kind(), + #[cfg(feature = "optimism")] + Self::Deposit(tx) => tx.kind(), + } + } + fn value(&self) -> U256 { match self { Self::Legacy(tx) => tx.value(), @@ -835,18 +844,6 @@ impl alloy_consensus::Transaction for Transaction { Self::Deposit(tx) => tx.authorization_list(), } } - - fn kind(&self) -> TxKind { - match self { - Self::Legacy(tx) => tx.kind(), - Self::Eip2930(tx) => tx.kind(), - Self::Eip1559(tx) => tx.kind(), - Self::Eip4844(tx) => tx.kind(), - Self::Eip7702(tx) => tx.kind(), - #[cfg(feature = "optimism")] - Self::Deposit(tx) => tx.kind(), - } - } } /// Signed transaction without its Hash. Used type for inserting into the DB. @@ -1457,10 +1454,18 @@ impl alloy_consensus::Transaction for TransactionSigned { self.deref().priority_fee_or_price() } + fn effective_gas_price(&self, base_fee: Option) -> u128 { + self.deref().effective_gas_price(base_fee) + } + fn is_dynamic_fee(&self) -> bool { self.deref().is_dynamic_fee() } + fn kind(&self) -> TxKind { + self.deref().kind() + } + fn value(&self) -> U256 { self.deref().value() } @@ -1484,10 +1489,6 @@ impl alloy_consensus::Transaction for TransactionSigned { fn authorization_list(&self) -> Option<&[SignedAuthorization]> { self.deref().authorization_list() } - - fn kind(&self) -> TxKind { - self.deref().kind() - } } impl From for TransactionSigned { diff --git a/crates/primitives/src/transaction/signature.rs b/crates/primitives/src/transaction/signature.rs index ef4fab0fccb..8fab719947a 100644 --- a/crates/primitives/src/transaction/signature.rs +++ b/crates/primitives/src/transaction/signature.rs @@ -15,7 +15,7 @@ const SECP256K1N_HALF: U256 = U256::from_be_bytes([ pub(crate) fn decode_with_eip155_chain_id( buf: &mut &[u8], ) -> alloy_rlp::Result<(Signature, Option)> { - let v: u64 = Decodable::decode(buf)?; + let v = Decodable::decode(buf)?; let r: U256 = Decodable::decode(buf)?; let s: U256 = Decodable::decode(buf)?; From b0a39e8abcb9a117510d1dd281fa308253b92c3a Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 13 Nov 2024 01:06:33 +0100 Subject: [PATCH 138/211] chore: import static file types directly (#12490) --- Cargo.lock | 3 +-- crates/node/events/Cargo.toml | 3 +-- crates/node/events/src/node.rs | 5 ++--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9748712e245..b6744e1f1ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8089,13 +8089,12 @@ dependencies = [ "humantime", "pin-project", "reth-beacon-consensus", - "reth-network", "reth-network-api", "reth-primitives-traits", "reth-provider", "reth-prune", "reth-stages", - "reth-static-file", + "reth-static-file-types", "tokio", "tracing", ] diff --git a/crates/node/events/Cargo.toml b/crates/node/events/Cargo.toml index 6af3d8cbeb4..cc754d58320 100644 --- a/crates/node/events/Cargo.toml +++ b/crates/node/events/Cargo.toml @@ -14,11 +14,10 @@ workspace = true # reth reth-provider.workspace = true reth-beacon-consensus.workspace = true -reth-network = { workspace = true, features = ["serde"] } reth-network-api.workspace = true reth-stages.workspace = true reth-prune.workspace = true -reth-static-file.workspace = true +reth-static-file-types.workspace = true reth-primitives-traits.workspace = true # ethereum diff --git a/crates/node/events/src/node.rs b/crates/node/events/src/node.rs index fb0f4d48d77..39c6355e36e 100644 --- a/crates/node/events/src/node.rs +++ b/crates/node/events/src/node.rs @@ -8,12 +8,11 @@ use futures::Stream; use reth_beacon_consensus::{ BeaconConsensusEngineEvent, ConsensusEngineLiveSyncProgress, ForkchoiceStatus, }; -use reth_network::NetworkEvent; -use reth_network_api::PeersInfo; +use reth_network_api::{NetworkEvent, PeersInfo}; use reth_primitives_traits::{format_gas, format_gas_throughput}; use reth_prune::PrunerEvent; use reth_stages::{EntitiesCheckpoint, ExecOutput, PipelineEvent, StageCheckpoint, StageId}; -use reth_static_file::StaticFileProducerEvent; +use reth_static_file_types::StaticFileProducerEvent; use std::{ fmt::{Display, Formatter}, future::Future, From cef7ec80c13acac11ac4c2b93bf6bd19f4298d8c Mon Sep 17 00:00:00 2001 From: Steven <112043913+stevencartavia@users.noreply.github.com> Date: Tue, 12 Nov 2024 19:00:07 -0600 Subject: [PATCH 139/211] Move CanonChainTracker to storage-api (#12491) --- Cargo.lock | 1 + crates/storage/provider/src/traits/mod.rs | 3 --- crates/storage/storage-api/Cargo.toml | 1 + .../{provider/src/traits => storage-api/src}/chain_info.rs | 0 crates/storage/storage-api/src/lib.rs | 3 +++ 5 files changed, 5 insertions(+), 3 deletions(-) rename crates/storage/{provider/src/traits => storage-api/src}/chain_info.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index b6744e1f1ec..1525d53b8ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9121,6 +9121,7 @@ dependencies = [ "alloy-consensus", "alloy-eips", "alloy-primitives", + "alloy-rpc-types-engine", "auto_impl", "reth-chainspec", "reth-db", diff --git a/crates/storage/provider/src/traits/mod.rs b/crates/storage/provider/src/traits/mod.rs index 3034eda8044..5542ea168ab 100644 --- a/crates/storage/provider/src/traits/mod.rs +++ b/crates/storage/provider/src/traits/mod.rs @@ -9,9 +9,6 @@ pub use reth_evm::provider::EvmEnvProvider; mod block; pub use block::*; -mod chain_info; -pub use chain_info::CanonChainTracker; - mod header_sync_gap; pub use header_sync_gap::{HeaderSyncGap, HeaderSyncGapProvider}; diff --git a/crates/storage/storage-api/Cargo.toml b/crates/storage/storage-api/Cargo.toml index 32aadc1922d..2b13f6332f8 100644 --- a/crates/storage/storage-api/Cargo.toml +++ b/crates/storage/storage-api/Cargo.toml @@ -28,5 +28,6 @@ reth-db.workspace = true alloy-eips.workspace = true alloy-primitives.workspace = true alloy-consensus.workspace = true +alloy-rpc-types-engine.workspace = true auto_impl.workspace = true diff --git a/crates/storage/provider/src/traits/chain_info.rs b/crates/storage/storage-api/src/chain_info.rs similarity index 100% rename from crates/storage/provider/src/traits/chain_info.rs rename to crates/storage/storage-api/src/chain_info.rs diff --git a/crates/storage/storage-api/src/lib.rs b/crates/storage/storage-api/src/lib.rs index 4980335066f..13a44b482a6 100644 --- a/crates/storage/storage-api/src/lib.rs +++ b/crates/storage/storage-api/src/lib.rs @@ -46,6 +46,9 @@ pub use transactions::*; mod trie; pub use trie::*; +mod chain_info; +pub use chain_info::*; + mod withdrawals; pub use withdrawals::*; From 1ce067b77bd5a1c2ec7a03c0bdde363afc602bcc Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 13 Nov 2024 02:42:47 +0100 Subject: [PATCH 140/211] chore: rm direct reth-provider dep (#12492) --- Cargo.lock | 2 +- crates/node/events/Cargo.toml | 2 +- crates/node/events/src/cl.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1525d53b8ec..15c627e8437 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8091,10 +8091,10 @@ dependencies = [ "reth-beacon-consensus", "reth-network-api", "reth-primitives-traits", - "reth-provider", "reth-prune", "reth-stages", "reth-static-file-types", + "reth-storage-api", "tokio", "tracing", ] diff --git a/crates/node/events/Cargo.toml b/crates/node/events/Cargo.toml index cc754d58320..7a5b1cf3b02 100644 --- a/crates/node/events/Cargo.toml +++ b/crates/node/events/Cargo.toml @@ -12,7 +12,7 @@ workspace = true [dependencies] # reth -reth-provider.workspace = true +reth-storage-api.workspace = true reth-beacon-consensus.workspace = true reth-network-api.workspace = true reth-stages.workspace = true diff --git a/crates/node/events/src/cl.rs b/crates/node/events/src/cl.rs index 6d29c9bbfa2..bf0d4a59b21 100644 --- a/crates/node/events/src/cl.rs +++ b/crates/node/events/src/cl.rs @@ -1,7 +1,7 @@ //! Events related to Consensus Layer health. use futures::Stream; -use reth_provider::CanonChainTracker; +use reth_storage_api::CanonChainTracker; use std::{ fmt, pin::Pin, From 2f794b6b990d58f500d614ddcdbaebb622bcb063 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 13 Nov 2024 03:06:13 +0100 Subject: [PATCH 141/211] chore: rm unhinged attributes ordering (#12498) --- crates/net/p2p/src/error.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/net/p2p/src/error.rs b/crates/net/p2p/src/error.rs index 181a0b96b3c..45d34fc04ec 100644 --- a/crates/net/p2p/src/error.rs +++ b/crates/net/p2p/src/error.rs @@ -80,24 +80,24 @@ impl EthResponseValidator for RequestResult> { #[derive(Clone, Debug, Eq, PartialEq, Display, Error)] pub enum RequestError { /// Closed channel to the peer. - #[display("closed channel to the peer")] /// Indicates the channel to the peer is closed. + #[display("closed channel to the peer")] ChannelClosed, /// Connection to a peer dropped while handling the request. - #[display("connection to a peer dropped while handling the request")] /// Represents a dropped connection while handling the request. + #[display("connection to a peer dropped while handling the request")] ConnectionDropped, /// Capability message is not supported by the remote peer. - #[display("capability message is not supported by remote peer")] /// Indicates an unsupported capability message from the remote peer. + #[display("capability message is not supported by remote peer")] UnsupportedCapability, /// Request timed out while awaiting response. - #[display("request timed out while awaiting response")] /// Represents a timeout while waiting for a response. + #[display("request timed out while awaiting response")] Timeout, /// Received bad response. - #[display("received bad response")] /// Indicates a bad response was received. + #[display("received bad response")] BadResponse, } From b7e8d5aa3e81cfadd92f2c816732d4ad1a7b011c Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 13 Nov 2024 09:34:20 +0100 Subject: [PATCH 142/211] chore: add SealedHeader::seal (#12497) --- crates/primitives-traits/src/header/sealed.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crates/primitives-traits/src/header/sealed.rs b/crates/primitives-traits/src/header/sealed.rs index b0fe4434298..145e2722bfa 100644 --- a/crates/primitives-traits/src/header/sealed.rs +++ b/crates/primitives-traits/src/header/sealed.rs @@ -56,6 +56,14 @@ impl SealedHeader { } } +impl SealedHeader { + /// Hashes the header and creates a sealed header. + pub fn seal(header: H) -> Self { + let hash = header.hash_slow(); + Self::new(header, hash) + } +} + impl SealedHeader { /// Return the number hash tuple. pub fn num_hash(&self) -> BlockNumHash { From 5c62d68dd8a5107a9fde7f8c809090d3da8aeb59 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 13 Nov 2024 10:14:55 +0100 Subject: [PATCH 143/211] chore: rm unused error variants (#12499) --- crates/payload/primitives/src/error.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/crates/payload/primitives/src/error.rs b/crates/payload/primitives/src/error.rs index 16446255c35..ab222f5f6ef 100644 --- a/crates/payload/primitives/src/error.rs +++ b/crates/payload/primitives/src/error.rs @@ -21,9 +21,6 @@ pub enum PayloadBuilderError { /// If there's no payload to resolve. #[error("missing payload")] MissingPayload, - /// Build cancelled - #[error("build outcome cancelled")] - BuildOutcomeCancelled, /// Error occurring in the blob store. #[error(transparent)] BlobStore(#[from] BlobStoreError), @@ -33,9 +30,6 @@ pub enum PayloadBuilderError { /// Unrecoverable error during evm execution. #[error("evm execution error: {0}")] EvmExecutionError(EVMError), - /// Thrown if the payload requests withdrawals before Shanghai activation. - #[error("withdrawals set before Shanghai activation")] - WithdrawalsBeforeShanghai, /// Any other payload building errors. #[error(transparent)] Other(Box), From 39392e95f1675f09adce68b21af499b33f539fd3 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 13 Nov 2024 10:15:14 +0100 Subject: [PATCH 144/211] chore: only issue single header request (#12496) --- crates/node/core/src/utils.rs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/crates/node/core/src/utils.rs b/crates/node/core/src/utils.rs index 7aeb14c4c0e..3ea8fba2668 100644 --- a/crates/node/core/src/utils.rs +++ b/crates/node/core/src/utils.rs @@ -8,9 +8,7 @@ use alloy_rpc_types_engine::{JwtError, JwtSecret}; use eyre::Result; use reth_consensus::Consensus; use reth_network_p2p::{ - bodies::client::BodiesClient, - headers::client::{HeadersClient, HeadersDirection, HeadersRequest}, - priority::Priority, + bodies::client::BodiesClient, headers::client::HeadersClient, priority::Priority, }; use reth_primitives::{SealedBlock, SealedHeader}; use std::{ @@ -44,17 +42,13 @@ pub async fn get_single_header( where Client: HeadersClient, { - let request = HeadersRequest { direction: HeadersDirection::Rising, limit: 1, start: id }; + let (peer_id, response) = client.get_header_with_priority(id, Priority::High).await?.split(); - let (peer_id, response) = - client.get_headers_with_priority(request, Priority::High).await?.split(); - - if response.len() != 1 { + let Some(sealed_header) = response.map(|block| block.seal_slow()) else { client.report_bad_message(peer_id); - eyre::bail!("Invalid number of headers received. Expected: 1. Received: {}", response.len()) - } + eyre::bail!("Invalid number of headers received. Expected: 1. Received: 0") + }; - let sealed_header = response.into_iter().next().unwrap().seal_slow(); let (header, seal) = sealed_header.into_parts(); let header = SealedHeader::new(header, seal); From 03f3646355529554e2a38f2a821881425bc04531 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 13 Nov 2024 10:15:34 +0100 Subject: [PATCH 145/211] chore: use let some notation (#12494) --- crates/node/core/src/utils.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/node/core/src/utils.rs b/crates/node/core/src/utils.rs index 3ea8fba2668..45281dff0bd 100644 --- a/crates/node/core/src/utils.rs +++ b/crates/node/core/src/utils.rs @@ -80,14 +80,12 @@ where { let (peer_id, response) = client.get_block_body(header.hash()).await?.split(); - if response.is_none() { + let Some(body) = response else { client.report_bad_message(peer_id); eyre::bail!("Invalid number of bodies received. Expected: 1. Received: 0") - } + }; - let body = response.unwrap(); let block = SealedBlock { header, body }; - consensus.validate_block_pre_execution(&block)?; Ok(block) From bf44c9724f68d4aabc9ff1e27d278f36328b8d8f Mon Sep 17 00:00:00 2001 From: Ashutosh Varma Date: Wed, 13 Nov 2024 16:45:32 +0700 Subject: [PATCH 146/211] feat: add support for `eth_signTransaction` (#12500) --- crates/rpc/rpc-builder/tests/it/http.rs | 14 ++++----- crates/rpc/rpc-eth-api/src/core.rs | 5 ++-- .../rpc-eth-api/src/helpers/transaction.rs | 30 ++++++++++++------- 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/crates/rpc/rpc-builder/tests/it/http.rs b/crates/rpc/rpc-builder/tests/it/http.rs index b5faa71cc5e..8393d9427a6 100644 --- a/crates/rpc/rpc-builder/tests/it/http.rs +++ b/crates/rpc/rpc-builder/tests/it/http.rs @@ -278,7 +278,13 @@ where .await .unwrap(); EthApiClient::::syncing(client).await.unwrap(); - EthApiClient::::send_transaction(client, transaction_request) + EthApiClient::::send_transaction( + client, + transaction_request.clone(), + ) + .await + .unwrap_err(); + EthApiClient::::sign_transaction(client, transaction_request) .await .unwrap_err(); EthApiClient::::hashrate(client).await.unwrap(); @@ -318,12 +324,6 @@ where .err() .unwrap() )); - assert!(is_unimplemented( - EthApiClient::::sign_transaction(client, call_request.clone()) - .await - .err() - .unwrap() - )); } async fn test_basic_debug_calls(client: &C) diff --git a/crates/rpc/rpc-eth-api/src/core.rs b/crates/rpc/rpc-eth-api/src/core.rs index 8072021d990..9cd9ba2921a 100644 --- a/crates/rpc/rpc-eth-api/src/core.rs +++ b/crates/rpc/rpc-eth-api/src/core.rs @@ -780,8 +780,9 @@ where } /// Handler for: `eth_signTransaction` - async fn sign_transaction(&self, _transaction: TransactionRequest) -> RpcResult { - Err(internal_rpc_err("unimplemented")) + async fn sign_transaction(&self, request: TransactionRequest) -> RpcResult { + trace!(target: "rpc::eth", ?request, "Serving eth_signTransaction"); + Ok(EthTransactions::sign_transaction(self, request).await?) } /// Handler for: `eth_signTypedData` diff --git a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs index ca4b0322e72..e041b8c4605 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs @@ -400,16 +400,10 @@ pub trait EthTransactions: LoadTransaction { txn: TransactionRequest, ) -> impl Future> + Send { async move { - let signers: Vec<_> = self.signers().read().iter().cloned().collect(); - for signer in signers { - if signer.is_signer_for(from) { - return match signer.sign_transaction(txn, from).await { - Ok(tx) => Ok(tx), - Err(e) => Err(e.into_eth_err()), - } - } - } - Err(EthApiError::InvalidTransactionSignature.into()) + self.find_signer(from)? + .sign_transaction(txn, from) + .await + .map_err(Self::Error::from_eth_err) } } @@ -430,6 +424,22 @@ pub trait EthTransactions: LoadTransaction { } } + /// Signs a transaction request using the given account in request + /// Returns the EIP-2718 encoded signed transaction. + fn sign_transaction( + &self, + request: TransactionRequest, + ) -> impl Future> + Send { + async move { + let from = match request.from { + Some(from) => from, + None => return Err(SignError::NoAccount.into_eth_err()), + }; + + Ok(self.sign_request(&from, request).await?.encoded_2718().into()) + } + } + /// Encodes and signs the typed data according EIP-712. Payload must implement Eip712 trait. fn sign_typed_data(&self, data: &TypedData, account: Address) -> Result { Ok(self From 281c415cb02ea661b2d20ac64f2d4cb1a325347d Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 13 Nov 2024 11:28:28 +0100 Subject: [PATCH 147/211] chore: reorder validation items (#12503) --- crates/rpc/rpc/src/validation.rs | 109 ++++++++++++++++--------------- 1 file changed, 55 insertions(+), 54 deletions(-) diff --git a/crates/rpc/rpc/src/validation.rs b/crates/rpc/rpc/src/validation.rs index c3f2aab70bb..b997dec1e01 100644 --- a/crates/rpc/rpc/src/validation.rs +++ b/crates/rpc/rpc/src/validation.rs @@ -30,60 +30,6 @@ use serde::{Deserialize, Serialize}; use std::{collections::HashSet, sync::Arc}; use tokio::sync::RwLock; -/// Configuration for validation API. -#[derive(Debug, Clone, Default, Eq, PartialEq, Serialize, Deserialize)] -pub struct ValidationApiConfig { - /// Disallowed addresses. - pub disallow: HashSet
, -} - -#[derive(Debug, thiserror::Error)] -pub enum ValidationApiError { - #[error("block gas limit mismatch: {_0}")] - GasLimitMismatch(GotExpected), - #[error("block gas used mismatch: {_0}")] - GasUsedMismatch(GotExpected), - #[error("block parent hash mismatch: {_0}")] - ParentHashMismatch(GotExpected), - #[error("block hash mismatch: {_0}")] - BlockHashMismatch(GotExpected), - #[error("missing latest block in database")] - MissingLatestBlock, - #[error("could not verify proposer payment")] - ProposerPayment, - #[error("invalid blobs bundle")] - InvalidBlobsBundle, - #[error("block accesses blacklisted address: {_0}")] - Blacklist(Address), - #[error(transparent)] - Blob(#[from] BlobTransactionValidationError), - #[error(transparent)] - Consensus(#[from] ConsensusError), - #[error(transparent)] - Provider(#[from] ProviderError), - #[error(transparent)] - Execution(#[from] BlockExecutionError), -} - -#[derive(Debug)] -pub struct ValidationApiInner { - /// The provider that can interact with the chain. - provider: Provider, - /// Consensus implementation. - consensus: Arc, - /// Execution payload validator. - payload_validator: ExecutionPayloadValidator, - /// Block executor factory. - executor_provider: E, - /// Set of disallowed addresses - disallow: HashSet
, - /// Cached state reads to avoid redundant disk I/O across multiple validation attempts - /// targeting the same state. Stores a tuple of (`block_hash`, `cached_reads`) for the - /// latest head block state. Uses async `RwLock` to safely handle concurrent validation - /// requests. - cached_state: RwLock<(B256, CachedReads)>, -} - /// The type that implements the `validation` rpc namespace trait #[derive(Debug, derive_more::Deref)] pub struct ValidationApi { @@ -486,3 +432,58 @@ where .to_rpc_result() } } + +#[derive(Debug)] +pub struct ValidationApiInner { + /// The provider that can interact with the chain. + provider: Provider, + /// Consensus implementation. + consensus: Arc, + /// Execution payload validator. + payload_validator: ExecutionPayloadValidator, + /// Block executor factory. + executor_provider: E, + /// Set of disallowed addresses + disallow: HashSet
, + /// Cached state reads to avoid redundant disk I/O across multiple validation attempts + /// targeting the same state. Stores a tuple of (`block_hash`, `cached_reads`) for the + /// latest head block state. Uses async `RwLock` to safely handle concurrent validation + /// requests. + cached_state: RwLock<(B256, CachedReads)>, +} + +/// Configuration for validation API. +#[derive(Debug, Clone, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct ValidationApiConfig { + /// Disallowed addresses. + pub disallow: HashSet
, +} + +/// Errors thrown by the validation API. +#[derive(Debug, thiserror::Error)] +pub enum ValidationApiError { + #[error("block gas limit mismatch: {_0}")] + GasLimitMismatch(GotExpected), + #[error("block gas used mismatch: {_0}")] + GasUsedMismatch(GotExpected), + #[error("block parent hash mismatch: {_0}")] + ParentHashMismatch(GotExpected), + #[error("block hash mismatch: {_0}")] + BlockHashMismatch(GotExpected), + #[error("missing latest block in database")] + MissingLatestBlock, + #[error("could not verify proposer payment")] + ProposerPayment, + #[error("invalid blobs bundle")] + InvalidBlobsBundle, + #[error("block accesses blacklisted address: {_0}")] + Blacklist(Address), + #[error(transparent)] + Blob(#[from] BlobTransactionValidationError), + #[error(transparent)] + Consensus(#[from] ConsensusError), + #[error(transparent)] + Provider(#[from] ProviderError), + #[error(transparent)] + Execution(#[from] BlockExecutionError), +} From 68e7ad6fe595a98564d2b2d51ec836d4939ec869 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Wed, 13 Nov 2024 12:21:58 +0100 Subject: [PATCH 148/211] chore(dep): bump alloy-trie (#12511) --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 15c627e8437..9e1d2330091 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -776,9 +776,9 @@ dependencies = [ [[package]] name = "alloy-trie" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40d8e28db02c006f7abb20f345ffb3cc99c465e36f676ba262534e654ae76042" +checksum = "b6b2e366c0debf0af77766c23694a3f863b02633050e71e096e257ffbd395e50" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -4601,7 +4601,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] @@ -11086,7 +11086,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3637e734239e12ab152cd269302500bd063f37624ee210cd04b4936ed671f3b1" dependencies = [ "cc", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] @@ -11561,7 +11561,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] From 527767cc34f4ebac19281fe6ed7b73c360168c12 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 13 Nov 2024 13:15:42 +0100 Subject: [PATCH 149/211] chore: remove unused trait bound for evmenv (#12505) --- crates/rpc/rpc/src/eth/filter.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/rpc/rpc/src/eth/filter.rs b/crates/rpc/rpc/src/eth/filter.rs index 3782780f5a6..132d99a5c1a 100644 --- a/crates/rpc/rpc/src/eth/filter.rs +++ b/crates/rpc/rpc/src/eth/filter.rs @@ -18,7 +18,7 @@ use async_trait::async_trait; use jsonrpsee::{core::RpcResult, server::IdProvider}; use reth_chainspec::ChainInfo; use reth_primitives::{Receipt, SealedBlockWithSenders, TransactionSignedEcRecovered}; -use reth_provider::{BlockIdReader, BlockReader, EvmEnvProvider, ProviderError}; +use reth_provider::{BlockIdReader, BlockReader, ProviderError}; use reth_rpc_eth_api::{ EthApiTypes, EthFilterApiServer, FullEthApiTypes, RpcTransaction, TransactionCompat, }; @@ -144,7 +144,7 @@ where impl EthFilter where - Provider: BlockReader + BlockIdReader + EvmEnvProvider + 'static, + Provider: BlockReader + BlockIdReader + 'static, Pool: TransactionPool + 'static, Eth: FullEthApiTypes, { @@ -244,7 +244,7 @@ where impl EthFilterApiServer> for EthFilter where - Provider: BlockReader + BlockIdReader + EvmEnvProvider + 'static, + Provider: BlockReader + BlockIdReader + 'static, Pool: TransactionPool + 'static, Eth: FullEthApiTypes + 'static, { @@ -367,7 +367,7 @@ struct EthFilterInner { impl EthFilterInner where - Provider: BlockReader + BlockIdReader + EvmEnvProvider + 'static, + Provider: BlockReader + BlockIdReader + 'static, Pool: TransactionPool + 'static, { /// Returns logs matching given filter object. From 9313737dbbf0f46fa497e63d452b427c7dafe498 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Wed, 13 Nov 2024 13:41:56 +0100 Subject: [PATCH 150/211] primitives: use `SealedHeader::seal` (#12507) --- crates/blockchain-tree/src/blockchain_tree.rs | 10 +++---- crates/chain-state/src/test_utils.rs | 7 ++--- .../beacon/src/engine/invalid_headers.rs | 6 ++-- crates/consensus/beacon/src/engine/sync.rs | 13 +++----- .../consensus/beacon/src/engine/test_utils.rs | 7 ++--- crates/consensus/common/src/validation.rs | 23 +++++--------- crates/engine/tree/src/backfill.rs | 10 +++---- crates/engine/tree/src/download.rs | 9 ++---- crates/engine/tree/src/test_utils.rs | 6 ++-- crates/engine/tree/src/tree/mod.rs | 7 ++--- crates/ethereum/consensus/src/lib.rs | 10 +++---- crates/net/downloaders/src/file_client.rs | 8 ++--- .../src/headers/reverse_headers.rs | 17 +++-------- .../net/downloaders/src/headers/test_utils.rs | 5 +--- crates/net/p2p/src/full_block.rs | 28 ++++------------- crates/net/p2p/src/test_utils/headers.rs | 13 ++------ crates/node/core/src/utils.rs | 6 ++-- crates/primitives-traits/src/header/sealed.rs | 4 +-- crates/primitives/src/block.rs | 6 ++-- crates/rpc/rpc-engine-api/tests/it/payload.rs | 6 ++-- crates/stages/stages/benches/setup/mod.rs | 10 ++----- crates/stages/stages/src/stages/execution.rs | 7 ++--- crates/stages/stages/src/stages/headers.rs | 6 ++-- crates/stages/stages/src/stages/merkle.rs | 16 +++------- .../provider/src/providers/consistent.rs | 30 +++++-------------- crates/storage/provider/src/providers/mod.rs | 30 +++++-------------- .../storage/provider/src/test_utils/blocks.rs | 23 ++++---------- .../storage/provider/src/test_utils/mock.rs | 24 +++------------ crates/storage/storage-api/src/block.rs | 11 ++----- crates/transaction-pool/src/maintain.rs | 6 ++-- examples/db-access/src/main.rs | 6 ++-- testing/testing-utils/src/generators.rs | 15 ++++------ 32 files changed, 108 insertions(+), 277 deletions(-) diff --git a/crates/blockchain-tree/src/blockchain_tree.rs b/crates/blockchain-tree/src/blockchain_tree.rs index 20d1cfe9f1d..0a7dd2a1178 100644 --- a/crates/blockchain-tree/src/blockchain_tree.rs +++ b/crates/blockchain-tree/src/blockchain_tree.rs @@ -1377,7 +1377,7 @@ mod tests { use alloy_consensus::{TxEip1559, EMPTY_ROOT_HASH}; use alloy_eips::{eip1559::INITIAL_BASE_FEE, eip4895::Withdrawals}; use alloy_genesis::{Genesis, GenesisAccount}; - use alloy_primitives::{keccak256, Address, PrimitiveSignature as Signature, Sealable, B256}; + use alloy_primitives::{keccak256, Address, PrimitiveSignature as Signature, B256}; use assert_matches::assert_matches; use linked_hash_set::LinkedHashSet; use reth_chainspec::{ChainSpecBuilder, MAINNET, MIN_TRANSACTION_GAS}; @@ -1598,7 +1598,7 @@ mod tests { // receipts root computation is different for OP let receipts_root = calculate_receipt_root(&receipts); - let sealed = Header { + let header = Header { number, parent_hash: parent.unwrap_or_default(), gas_used: body.len() as u64 * MIN_TRANSACTION_GAS, @@ -1620,13 +1620,11 @@ mod tests { ), )])), ..Default::default() - } - .seal_slow(); - let (header, seal) = sealed.into_parts(); + }; SealedBlockWithSenders::new( SealedBlock { - header: SealedHeader::new(header, seal), + header: SealedHeader::seal(header), body: BlockBody { transactions: body.clone().into_iter().map(|tx| tx.into_signed()).collect(), ommers: Vec::new(), diff --git a/crates/chain-state/src/test_utils.rs b/crates/chain-state/src/test_utils.rs index 564df9fe341..650fcc3bbce 100644 --- a/crates/chain-state/src/test_utils.rs +++ b/crates/chain-state/src/test_utils.rs @@ -4,7 +4,7 @@ use crate::{ }; use alloy_consensus::{Transaction as _, TxEip1559, EMPTY_ROOT_HASH}; use alloy_eips::{eip1559::INITIAL_BASE_FEE, eip7685::Requests}; -use alloy_primitives::{Address, BlockNumber, Sealable, B256, U256}; +use alloy_primitives::{Address, BlockNumber, B256, U256}; use alloy_signer::SignerSync; use alloy_signer_local::PrivateKeySigner; use rand::{thread_rng, Rng}; @@ -160,11 +160,8 @@ impl TestBlockBuilder { ..Default::default() }; - let sealed = header.seal_slow(); - let (header, seal) = sealed.into_parts(); - let block = SealedBlock { - header: SealedHeader::new(header, seal), + header: SealedHeader::seal(header), body: BlockBody { transactions: transactions.into_iter().map(|tx| tx.into_signed()).collect(), ommers: Vec::new(), diff --git a/crates/consensus/beacon/src/engine/invalid_headers.rs b/crates/consensus/beacon/src/engine/invalid_headers.rs index 8a1c95d73ce..5bcf0cae7e9 100644 --- a/crates/consensus/beacon/src/engine/invalid_headers.rs +++ b/crates/consensus/beacon/src/engine/invalid_headers.rs @@ -106,14 +106,12 @@ struct InvalidHeaderCacheMetrics { #[cfg(test)] mod tests { use super::*; - use alloy_primitives::Sealable; #[test] fn test_hit_eviction() { let mut cache = InvalidHeaderCache::new(10); - let sealed = Header::default().seal_slow(); - let (header, seal) = sealed.into_parts(); - let header = SealedHeader::new(header, seal); + let header = Header::default(); + let header = SealedHeader::seal(header); cache.insert(header.clone()); assert_eq!(cache.headers.get(&header.hash()).unwrap().hit_count, 0); diff --git a/crates/consensus/beacon/src/engine/sync.rs b/crates/consensus/beacon/src/engine/sync.rs index 17d5d2281a3..d91280eac88 100644 --- a/crates/consensus/beacon/src/engine/sync.rs +++ b/crates/consensus/beacon/src/engine/sync.rs @@ -410,7 +410,6 @@ impl PipelineState { #[cfg(test)] mod tests { use super::*; - use alloy_primitives::Sealable; use assert_matches::assert_matches; use futures::poll; use reth_chainspec::{ChainSpec, ChainSpecBuilder, MAINNET}; @@ -599,9 +598,7 @@ mod tests { header.parent_hash = hash; header.number += 1; header.timestamp += 1; - let sealed = header.seal_slow(); - let (header, seal) = sealed.into_parts(); - sealed_header = SealedHeader::new(header, seal); + sealed_header = SealedHeader::seal(header); client.insert(sealed_header.clone(), body.clone()); } } @@ -617,14 +614,12 @@ mod tests { ); let client = TestFullBlockClient::default(); - let sealed = Header { + let header = Header { base_fee_per_gas: Some(7), gas_limit: chain_spec.max_gas_limit, ..Default::default() - } - .seal_slow(); - let (header, seal) = sealed.into_parts(); - let header = SealedHeader::new(header, seal); + }; + let header = SealedHeader::seal(header); insert_headers_into_client(&client, header, 0..10); // set up a pipeline diff --git a/crates/consensus/beacon/src/engine/test_utils.rs b/crates/consensus/beacon/src/engine/test_utils.rs index 3c69e7f55c3..0ad4c595f1b 100644 --- a/crates/consensus/beacon/src/engine/test_utils.rs +++ b/crates/consensus/beacon/src/engine/test_utils.rs @@ -4,7 +4,7 @@ use crate::{ BeaconConsensusEngineError, BeaconConsensusEngineHandle, BeaconForkChoiceUpdateError, BeaconOnNewPayloadError, EthBeaconConsensus, MIN_BLOCKS_FOR_PIPELINE_RUN, }; -use alloy_primitives::{BlockNumber, Sealable, B256}; +use alloy_primitives::{BlockNumber, B256}; use alloy_rpc_types_engine::{ ExecutionPayload, ExecutionPayloadSidecar, ForkchoiceState, ForkchoiceUpdated, PayloadStatus, }; @@ -402,9 +402,8 @@ where BlockchainTree::new(externals, BlockchainTreeConfig::new(1, 2, 3, 2)) .expect("failed to create tree"), )); - let sealed = self.base_config.chain_spec.genesis_header().clone().seal_slow(); - let (header, seal) = sealed.into_parts(); - let genesis_block = SealedHeader::new(header, seal); + let header = self.base_config.chain_spec.genesis_header().clone(); + let genesis_block = SealedHeader::seal(header); let blockchain_provider = BlockchainProvider::with_blocks( provider_factory.clone(), diff --git a/crates/consensus/common/src/validation.rs b/crates/consensus/common/src/validation.rs index c10116f2276..af1bbfdbdd3 100644 --- a/crates/consensus/common/src/validation.rs +++ b/crates/consensus/common/src/validation.rs @@ -326,7 +326,7 @@ mod tests { }; use alloy_primitives::{ hex_literal::hex, Address, BlockHash, BlockNumber, Bytes, PrimitiveSignature as Signature, - Sealable, U256, + U256, }; use mockall::mock; use rand::Rng; @@ -495,12 +495,9 @@ mod tests { let ommers = Vec::new(); let transactions = Vec::new(); - let sealed = header.seal_slow(); - let (header, seal) = sealed.into_parts(); - ( SealedBlock { - header: SealedHeader::new(header, seal), + header: SealedHeader::seal(header), body: BlockBody { transactions, ommers, withdrawals: None }, }, parent, @@ -519,15 +516,13 @@ mod tests { .collect(), ); - let sealed = Header { + let header = Header { withdrawals_root: Some(proofs::calculate_withdrawals_root(&withdrawals)), ..Default::default() - } - .seal_slow(); - let (header, seal) = sealed.into_parts(); + }; SealedBlock { - header: SealedHeader::new(header, seal), + header: SealedHeader::seal(header), body: BlockBody { withdrawals: Some(withdrawals), ..Default::default() }, } }; @@ -558,16 +553,14 @@ mod tests { // create a tx with 10 blobs let transaction = mock_blob_tx(1, 10); - let sealed = Header { + let header = Header { base_fee_per_gas: Some(1337), withdrawals_root: Some(proofs::calculate_withdrawals_root(&[])), blob_gas_used: Some(1), transactions_root: proofs::calculate_transaction_root(&[transaction.clone()]), ..Default::default() - } - .seal_slow(); - let (header, seal) = sealed.into_parts(); - let header = SealedHeader::new(header, seal); + }; + let header = SealedHeader::seal(header); let body = BlockBody { transactions: vec![transaction], diff --git a/crates/engine/tree/src/backfill.rs b/crates/engine/tree/src/backfill.rs index 78e21a7b5ef..c267203d851 100644 --- a/crates/engine/tree/src/backfill.rs +++ b/crates/engine/tree/src/backfill.rs @@ -230,7 +230,7 @@ impl PipelineState { mod tests { use super::*; use crate::test_utils::{insert_headers_into_client, TestPipelineBuilder}; - use alloy_primitives::{BlockNumber, Sealable, B256}; + use alloy_primitives::{BlockNumber, B256}; use assert_matches::assert_matches; use futures::poll; use reth_chainspec::{ChainSpecBuilder, MAINNET}; @@ -267,14 +267,12 @@ mod tests { let pipeline_sync = PipelineSync::new(pipeline, Box::::default()); let client = TestFullBlockClient::default(); - let sealed = Header { + let header = Header { base_fee_per_gas: Some(7), gas_limit: chain_spec.max_gas_limit, ..Default::default() - } - .seal_slow(); - let (header, seal) = sealed.into_parts(); - let header = SealedHeader::new(header, seal); + }; + let header = SealedHeader::seal(header); insert_headers_into_client(&client, header, 0..total_blocks); let tip = client.highest_block().expect("there should be blocks here").hash(); diff --git a/crates/engine/tree/src/download.rs b/crates/engine/tree/src/download.rs index 667808a4d62..cb43be3c4de 100644 --- a/crates/engine/tree/src/download.rs +++ b/crates/engine/tree/src/download.rs @@ -309,7 +309,6 @@ impl BlockDownloader for NoopBlockDownloader { mod tests { use super::*; use crate::test_utils::insert_headers_into_client; - use alloy_primitives::Sealable; use assert_matches::assert_matches; use reth_beacon_consensus::EthBeaconConsensus; use reth_chainspec::{ChainSpecBuilder, MAINNET}; @@ -333,14 +332,12 @@ mod tests { ); let client = TestFullBlockClient::default(); - let sealed = Header { + let header = Header { base_fee_per_gas: Some(7), gas_limit: chain_spec.max_gas_limit, ..Default::default() - } - .seal_slow(); - let (header, seal) = sealed.into_parts(); - let header = SealedHeader::new(header, seal); + }; + let header = SealedHeader::seal(header); insert_headers_into_client(&client, header, 0..total_blocks); let consensus = Arc::new(EthBeaconConsensus::new(chain_spec)); diff --git a/crates/engine/tree/src/test_utils.rs b/crates/engine/tree/src/test_utils.rs index f17766a43ed..c1b534ebf5e 100644 --- a/crates/engine/tree/src/test_utils.rs +++ b/crates/engine/tree/src/test_utils.rs @@ -1,4 +1,4 @@ -use alloy_primitives::{Sealable, B256}; +use alloy_primitives::B256; use reth_chainspec::ChainSpec; use reth_network_p2p::test_utils::TestFullBlockClient; use reth_primitives::{BlockBody, SealedHeader}; @@ -76,9 +76,7 @@ pub fn insert_headers_into_client( header.parent_hash = hash; header.number += 1; header.timestamp += 1; - let sealed = header.seal_slow(); - let (header, seal) = sealed.into_parts(); - sealed_header = SealedHeader::new(header, seal); + sealed_header = SealedHeader::seal(header); client.insert(sealed_header.clone(), body.clone()); } } diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index e89960d9870..755ee1106a6 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -2597,7 +2597,7 @@ pub enum AdvancePersistenceError { mod tests { use super::*; use crate::persistence::PersistenceAction; - use alloy_primitives::{Bytes, Sealable}; + use alloy_primitives::Bytes; use alloy_rlp::Decodable; use alloy_rpc_types_engine::{CancunPayloadFields, ExecutionPayloadSidecar}; use assert_matches::assert_matches; @@ -2709,9 +2709,8 @@ mod tests { let (from_tree_tx, from_tree_rx) = unbounded_channel(); - let sealed = chain_spec.genesis_header().clone().seal_slow(); - let (header, seal) = sealed.into_parts(); - let header = SealedHeader::new(header, seal); + let header = chain_spec.genesis_header().clone(); + let header = SealedHeader::seal(header); let engine_api_tree_state = EngineApiTreeState::new(10, 10, header.num_hash()); let canonical_in_memory_state = CanonicalInMemoryState::with_head(header, None, None); diff --git a/crates/ethereum/consensus/src/lib.rs b/crates/ethereum/consensus/src/lib.rs index d5cf692928f..3dab9849f6c 100644 --- a/crates/ethereum/consensus/src/lib.rs +++ b/crates/ethereum/consensus/src/lib.rs @@ -236,7 +236,7 @@ impl Consensu #[cfg(test)] mod tests { use super::*; - use alloy_primitives::{Sealable, B256}; + use alloy_primitives::B256; use reth_chainspec::{ChainSpec, ChainSpecBuilder}; use reth_primitives::proofs; @@ -321,16 +321,14 @@ mod tests { // that the header is valid let chain_spec = Arc::new(ChainSpecBuilder::mainnet().shanghai_activated().build()); - let sealed = Header { + let header = Header { base_fee_per_gas: Some(1337), withdrawals_root: Some(proofs::calculate_withdrawals_root(&[])), ..Default::default() - } - .seal_slow(); - let (header, seal) = sealed.into_parts(); + }; assert_eq!( - EthBeaconConsensus::new(chain_spec).validate_header(&SealedHeader::new(header, seal)), + EthBeaconConsensus::new(chain_spec).validate_header(&SealedHeader::seal(header,)), Ok(()) ); } diff --git a/crates/net/downloaders/src/file_client.rs b/crates/net/downloaders/src/file_client.rs index 9f539a5774d..f0104032aa0 100644 --- a/crates/net/downloaders/src/file_client.rs +++ b/crates/net/downloaders/src/file_client.rs @@ -1,7 +1,7 @@ use std::{collections::HashMap, io, path::Path}; use alloy_eips::BlockHashOrNumber; -use alloy_primitives::{BlockHash, BlockNumber, Sealable, B256}; +use alloy_primitives::{BlockHash, BlockNumber, B256}; use futures::Future; use itertools::Either; use reth_network_p2p::{ @@ -114,11 +114,7 @@ impl FileClient { /// Clones and returns the highest header of this client has or `None` if empty. Seals header /// before returning. pub fn tip_header(&self) -> Option { - self.headers.get(&self.max_block()?).map(|h| { - let sealed = h.clone().seal_slow(); - let (header, seal) = sealed.into_parts(); - SealedHeader::new(header, seal) - }) + self.headers.get(&self.max_block()?).map(|h| SealedHeader::seal(h.clone())) } /// Returns true if all blocks are canonical (no gaps) diff --git a/crates/net/downloaders/src/headers/reverse_headers.rs b/crates/net/downloaders/src/headers/reverse_headers.rs index 9532b4b3a35..125eef6d3eb 100644 --- a/crates/net/downloaders/src/headers/reverse_headers.rs +++ b/crates/net/downloaders/src/headers/reverse_headers.rs @@ -4,7 +4,7 @@ use super::task::TaskDownloader; use crate::metrics::HeaderDownloaderMetrics; use alloy_consensus::BlockHeader; use alloy_eips::BlockHashOrNumber; -use alloy_primitives::{BlockNumber, Sealable, B256}; +use alloy_primitives::{BlockNumber, B256}; use futures::{stream::Stream, FutureExt}; use futures_util::{stream::FuturesUnordered, StreamExt}; use rayon::prelude::*; @@ -250,15 +250,7 @@ where ) -> Result<(), ReverseHeadersDownloaderError> { let mut validated = Vec::with_capacity(headers.len()); - let sealed_headers = headers - .into_par_iter() - .map(|h| { - let sealed = h.seal_slow(); - let (header, seal) = sealed.into_parts(); - - SealedHeader::new(header, seal) - }) - .collect::>(); + let sealed_headers = headers.into_par_iter().map(SealedHeader::seal).collect::>(); for parent in sealed_headers { // Validate that the header is the parent header of the last validated header. if let Some(validated_header) = @@ -384,9 +376,8 @@ where .into()) } - let sealed_target = headers.swap_remove(0).seal_slow(); - let (header, seal) = sealed_target.into_parts(); - let target = SealedHeader::new(header, seal); + let header = headers.swap_remove(0); + let target = SealedHeader::seal(header); match sync_target { SyncTargetBlock::Hash(hash) | SyncTargetBlock::HashAndNumber { hash, .. } => { diff --git a/crates/net/downloaders/src/headers/test_utils.rs b/crates/net/downloaders/src/headers/test_utils.rs index 923ad996937..baea409f20e 100644 --- a/crates/net/downloaders/src/headers/test_utils.rs +++ b/crates/net/downloaders/src/headers/test_utils.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] -use alloy_primitives::Sealable; use reth_primitives::SealedHeader; /// Returns a new [`SealedHeader`] that's the child header of the given `parent`. @@ -10,7 +9,5 @@ pub(crate) fn child_header(parent: &SealedHeader) -> SealedHeader { let mut child = parent.as_ref().clone(); child.number += 1; child.parent_hash = parent.hash_slow(); - let sealed = child.seal_slow(); - let (header, seal) = sealed.into_parts(); - SealedHeader::new(header, seal) + SealedHeader::seal(child) } diff --git a/crates/net/p2p/src/full_block.rs b/crates/net/p2p/src/full_block.rs index 8f176f8da8a..8fcacd140b0 100644 --- a/crates/net/p2p/src/full_block.rs +++ b/crates/net/p2p/src/full_block.rs @@ -199,15 +199,8 @@ where ResponseResult::Header(res) => { match res { Ok(maybe_header) => { - let (peer, maybe_header) = maybe_header - .map(|h| { - h.map(|h| { - let sealed = h.seal_slow(); - let (header, seal) = sealed.into_parts(); - SealedHeader::new(header, seal) - }) - }) - .split(); + let (peer, maybe_header) = + maybe_header.map(|h| h.map(SealedHeader::seal)).split(); if let Some(header) = maybe_header { if header.hash() == this.hash { this.header = Some(header); @@ -457,17 +450,8 @@ where } fn on_headers_response(&mut self, headers: WithPeerId>) { - let (peer, mut headers_falling) = headers - .map(|h| { - h.into_iter() - .map(|h| { - let sealed = h.seal_slow(); - let (header, seal) = sealed.into_parts(); - SealedHeader::new(header, seal) - }) - .collect::>() - }) - .split(); + let (peer, mut headers_falling) = + headers.map(|h| h.into_iter().map(SealedHeader::seal).collect::>()).split(); // fill in the response if it's the correct length if headers_falling.len() == self.count as usize { @@ -707,9 +691,7 @@ mod tests { header.parent_hash = hash; header.number += 1; - let sealed = header.seal_slow(); - let (header, seal) = sealed.into_parts(); - sealed_header = SealedHeader::new(header, seal); + sealed_header = SealedHeader::seal(header); client.insert(sealed_header.clone(), body.clone()); } diff --git a/crates/net/p2p/src/test_utils/headers.rs b/crates/net/p2p/src/test_utils/headers.rs index d8d4bbc6b7a..8892a010b43 100644 --- a/crates/net/p2p/src/test_utils/headers.rs +++ b/crates/net/p2p/src/test_utils/headers.rs @@ -10,7 +10,6 @@ use crate::{ }, priority::Priority, }; -use alloy_primitives::Sealable; use futures::{Future, FutureExt, Stream, StreamExt}; use reth_consensus::{test_utils::TestConsensus, Consensus}; use reth_eth_wire_types::HeadersDirection; @@ -160,16 +159,8 @@ impl Stream for TestDownload { match ready!(this.get_or_init_fut().poll_unpin(cx)) { Ok(resp) => { // Skip head and seal headers - let mut headers = resp - .1 - .into_iter() - .skip(1) - .map(|header| { - let sealed = header.seal_slow(); - let (header, seal) = sealed.into_parts(); - SealedHeader::new(header, seal) - }) - .collect::>(); + let mut headers = + resp.1.into_iter().skip(1).map(SealedHeader::seal).collect::>(); headers.sort_unstable_by_key(|h| h.number); headers.into_iter().for_each(|h| this.buffer.push(h)); this.done = true; diff --git a/crates/node/core/src/utils.rs b/crates/node/core/src/utils.rs index 45281dff0bd..e52af4b46fe 100644 --- a/crates/node/core/src/utils.rs +++ b/crates/node/core/src/utils.rs @@ -3,7 +3,6 @@ use alloy_consensus::BlockHeader; use alloy_eips::BlockHashOrNumber; -use alloy_primitives::Sealable; use alloy_rpc_types_engine::{JwtError, JwtSecret}; use eyre::Result; use reth_consensus::Consensus; @@ -44,13 +43,12 @@ where { let (peer_id, response) = client.get_header_with_priority(id, Priority::High).await?.split(); - let Some(sealed_header) = response.map(|block| block.seal_slow()) else { + let Some(header) = response else { client.report_bad_message(peer_id); eyre::bail!("Invalid number of headers received. Expected: 1. Received: 0") }; - let (header, seal) = sealed_header.into_parts(); - let header = SealedHeader::new(header, seal); + let header = SealedHeader::seal(header); let valid = match id { BlockHashOrNumber::Hash(hash) => header.hash() == hash, diff --git a/crates/primitives-traits/src/header/sealed.rs b/crates/primitives-traits/src/header/sealed.rs index 145e2722bfa..8364b85b3aa 100644 --- a/crates/primitives-traits/src/header/sealed.rs +++ b/crates/primitives-traits/src/header/sealed.rs @@ -156,9 +156,7 @@ impl<'a> arbitrary::Arbitrary<'a> for SealedHeader { fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { let header = Header::arbitrary(u)?; - let sealed = header.seal_slow(); - let (header, seal) = sealed.into_parts(); - Ok(Self::new(header, seal)) + Ok(Self::seal(header)) } } diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index 6743cab3dc3..3ce4947ccc2 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -1,7 +1,7 @@ use crate::{GotExpected, Header, SealedHeader, TransactionSigned, TransactionSignedEcRecovered}; use alloc::vec::Vec; use alloy_eips::{eip2718::Encodable2718, eip4895::Withdrawals}; -use alloy_primitives::{Address, Bytes, Sealable, B256}; +use alloy_primitives::{Address, Bytes, B256}; use alloy_rlp::{Decodable, Encodable, RlpDecodable, RlpEncodable}; use derive_more::{Deref, DerefMut}; #[cfg(any(test, feature = "arbitrary"))] @@ -25,9 +25,7 @@ pub struct Block { impl Block { /// Calculate the header hash and seal the block so that it can't be changed. pub fn seal_slow(self) -> SealedBlock { - let sealed = self.header.seal_slow(); - let (header, seal) = sealed.into_parts(); - SealedBlock { header: SealedHeader::new(header, seal), body: self.body } + SealedBlock { header: SealedHeader::seal(self.header), body: self.body } } /// Seal the block with a known hash. diff --git a/crates/rpc/rpc-engine-api/tests/it/payload.rs b/crates/rpc/rpc-engine-api/tests/it/payload.rs index f341fd0474c..78b0351d4a5 100644 --- a/crates/rpc/rpc-engine-api/tests/it/payload.rs +++ b/crates/rpc/rpc-engine-api/tests/it/payload.rs @@ -1,7 +1,7 @@ //! Some payload tests use alloy_eips::eip4895::Withdrawals; -use alloy_primitives::{Bytes, Sealable, U256}; +use alloy_primitives::{Bytes, U256}; use alloy_rlp::{Decodable, Error as RlpError}; use alloy_rpc_types_engine::{ ExecutionPayload, ExecutionPayloadBodyV1, ExecutionPayloadSidecar, ExecutionPayloadV1, @@ -24,10 +24,8 @@ fn transform_block Block>(src: SealedBlock, f: F) -> Executi transformed.header.transactions_root = proofs::calculate_transaction_root(&transformed.body.transactions); transformed.header.ommers_hash = proofs::calculate_ommers_root(&transformed.body.ommers); - let sealed = transformed.header.seal_slow(); - let (header, seal) = sealed.into_parts(); block_to_payload(SealedBlock { - header: SealedHeader::new(header, seal), + header: SealedHeader::seal(transformed.header), body: transformed.body, }) } diff --git a/crates/stages/stages/benches/setup/mod.rs b/crates/stages/stages/benches/setup/mod.rs index e6ae33f9c29..c1c3ff89d72 100644 --- a/crates/stages/stages/benches/setup/mod.rs +++ b/crates/stages/stages/benches/setup/mod.rs @@ -1,5 +1,5 @@ #![allow(unreachable_pub)] -use alloy_primitives::{Address, Sealable, B256, U256}; +use alloy_primitives::{Address, B256, U256}; use itertools::concat; use reth_db::{tables, test_utils::TempDatabase, Database, DatabaseEnv}; use reth_db_api::{ @@ -147,9 +147,7 @@ pub(crate) fn txs_testdata(num_blocks: u64) -> TestStageDB { let cloned_second = second_block.clone(); let mut updated_header = cloned_second.header.unseal(); updated_header.state_root = root; - let sealed = updated_header.seal_slow(); - let (header, seal) = sealed.into_parts(); - *second_block = SealedBlock { header: SealedHeader::new(header, seal), ..cloned_second }; + *second_block = SealedBlock { header: SealedHeader::seal(updated_header), ..cloned_second }; let offset = transitions.len() as u64; @@ -182,9 +180,7 @@ pub(crate) fn txs_testdata(num_blocks: u64) -> TestStageDB { let cloned_last = last_block.clone(); let mut updated_header = cloned_last.header.unseal(); updated_header.state_root = root; - let sealed = updated_header.seal_slow(); - let (header, seal) = sealed.into_parts(); - *last_block = SealedBlock { header: SealedHeader::new(header, seal), ..cloned_last }; + *last_block = SealedBlock { header: SealedHeader::seal(updated_header), ..cloned_last }; db.insert_blocks(blocks.iter(), StorageKind::Static).unwrap(); diff --git a/crates/stages/stages/src/stages/execution.rs b/crates/stages/stages/src/stages/execution.rs index 88d5f830378..d49a2975ad0 100644 --- a/crates/stages/stages/src/stages/execution.rs +++ b/crates/stages/stages/src/stages/execution.rs @@ -1,5 +1,5 @@ use crate::stages::MERKLE_STAGE_DEFAULT_CLEAN_THRESHOLD; -use alloy_primitives::{BlockNumber, Sealable}; +use alloy_primitives::BlockNumber; use num_traits::Zero; use reth_config::config::ExecutionConfig; use reth_db::{static_file::HeaderMask, tables}; @@ -276,11 +276,8 @@ where let execute_start = Instant::now(); self.metrics.metered_one((&block, td).into(), |input| { - let sealed = block.header.clone().seal_slow(); - let (header, seal) = sealed.into_parts(); - executor.execute_and_verify_one(input).map_err(|error| StageError::Block { - block: Box::new(SealedHeader::new(header, seal)), + block: Box::new(SealedHeader::seal(block.header.clone())), error: BlockErrorKind::Execution(error), }) })?; diff --git a/crates/stages/stages/src/stages/headers.rs b/crates/stages/stages/src/stages/headers.rs index 2be78b88169..613e73194f4 100644 --- a/crates/stages/stages/src/stages/headers.rs +++ b/crates/stages/stages/src/stages/headers.rs @@ -392,7 +392,7 @@ mod tests { use crate::test_utils::{ stage_test_suite, ExecuteStageTestRunner, StageTestRunner, UnwindStageTestRunner, }; - use alloy_primitives::{Sealable, B256}; + use alloy_primitives::B256; use assert_matches::assert_matches; use reth_execution_types::ExecutionOutcome; use reth_primitives::{BlockBody, SealedBlock, SealedBlockWithSenders}; @@ -509,9 +509,7 @@ mod tests { // validate the header let header = provider.header_by_number(block_num)?; assert!(header.is_some()); - let sealed = header.unwrap().seal_slow(); - let (header, seal) = sealed.into_parts(); - let header = SealedHeader::new(header, seal); + let header = SealedHeader::seal(header.unwrap()); assert_eq!(header.hash(), hash); // validate the header total difficulty diff --git a/crates/stages/stages/src/stages/merkle.rs b/crates/stages/stages/src/stages/merkle.rs index d1d3496d917..2d2503b5391 100644 --- a/crates/stages/stages/src/stages/merkle.rs +++ b/crates/stages/stages/src/stages/merkle.rs @@ -1,4 +1,4 @@ -use alloy_primitives::{BlockNumber, Sealable, B256}; +use alloy_primitives::{BlockNumber, B256}; use reth_codecs::Compact; use reth_consensus::ConsensusError; use reth_db::tables; @@ -276,10 +276,7 @@ where // Reset the checkpoint self.save_execution_checkpoint(provider, None)?; - let sealed = target_block.seal_slow(); - let (header, seal) = sealed.into_parts(); - - validate_state_root(trie_root, SealedHeader::new(header, seal), to_block)?; + validate_state_root(trie_root, SealedHeader::seal(target_block), to_block)?; Ok(ExecOutput { checkpoint: StageCheckpoint::new(to_block) @@ -332,10 +329,7 @@ where .header_by_number(input.unwind_to)? .ok_or_else(|| ProviderError::HeaderNotFound(input.unwind_to.into()))?; - let sealed = target.seal_slow(); - let (header, seal) = sealed.into_parts(); - - validate_state_root(block_root, SealedHeader::new(header, seal), input.unwind_to)?; + validate_state_root(block_root, SealedHeader::seal(target), input.unwind_to)?; // Validation passed, apply unwind changes to the database. provider.write_trie_updates(&updates)?; @@ -538,9 +532,7 @@ mod tests { .into_iter() .map(|(address, account)| (address, (account, std::iter::empty()))), ); - let sealed = header.seal_slow(); - let (header, seal) = sealed.into_parts(); - let sealed_head = SealedBlock { header: SealedHeader::new(header, seal), body }; + let sealed_head = SealedBlock { header: SealedHeader::seal(header), body }; let head_hash = sealed_head.hash(); let mut blocks = vec![sealed_head]; diff --git a/crates/storage/provider/src/providers/consistent.rs b/crates/storage/provider/src/providers/consistent.rs index 98f7820e34a..0eb88c1f9ef 100644 --- a/crates/storage/provider/src/providers/consistent.rs +++ b/crates/storage/provider/src/providers/consistent.rs @@ -10,7 +10,7 @@ use alloy_eips::{ eip4895::{Withdrawal, Withdrawals}, BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, HashOrNumber, }; -use alloy_primitives::{Address, BlockHash, BlockNumber, Sealable, TxHash, TxNumber, B256, U256}; +use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256}; use reth_chain_state::{BlockState, CanonicalInMemoryState, MemoryOverlayStateProviderRef}; use reth_chainspec::{ChainInfo, EthereumHardforks}; use reth_db::models::BlockNumberAddress; @@ -1324,34 +1324,20 @@ impl BlockReaderIdExt for ConsistentProvider { Ok(self.canonical_in_memory_state.get_finalized_header()) } BlockNumberOrTag::Safe => Ok(self.canonical_in_memory_state.get_safe_header()), - BlockNumberOrTag::Earliest => self.header_by_number(0)?.map_or_else( - || Ok(None), - |h| { - let sealed = h.seal_slow(); - let (header, seal) = sealed.into_parts(); - Ok(Some(SealedHeader::new(header, seal))) - }, - ), + BlockNumberOrTag::Earliest => self + .header_by_number(0)? + .map_or_else(|| Ok(None), |h| Ok(Some(SealedHeader::seal(h)))), BlockNumberOrTag::Pending => Ok(self.canonical_in_memory_state.pending_sealed_header()), - BlockNumberOrTag::Number(num) => self.header_by_number(num)?.map_or_else( - || Ok(None), - |h| { - let sealed = h.seal_slow(); - let (header, seal) = sealed.into_parts(); - Ok(Some(SealedHeader::new(header, seal))) - }, - ), + BlockNumberOrTag::Number(num) => self + .header_by_number(num)? + .map_or_else(|| Ok(None), |h| Ok(Some(SealedHeader::seal(h)))), } } fn sealed_header_by_id(&self, id: BlockId) -> ProviderResult> { Ok(match id { BlockId::Number(num) => self.sealed_header_by_number_or_tag(num)?, - BlockId::Hash(hash) => self.header(&hash.block_hash)?.map(|h| { - let sealed = h.seal_slow(); - let (header, seal) = sealed.into_parts(); - SealedHeader::new(header, seal) - }), + BlockId::Hash(hash) => self.header(&hash.block_hash)?.map(SealedHeader::seal), }) } diff --git a/crates/storage/provider/src/providers/mod.rs b/crates/storage/provider/src/providers/mod.rs index c859ddba8a5..d3dde5b0d3b 100644 --- a/crates/storage/provider/src/providers/mod.rs +++ b/crates/storage/provider/src/providers/mod.rs @@ -11,7 +11,7 @@ use alloy_eips::{ eip4895::{Withdrawal, Withdrawals}, BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, }; -use alloy_primitives::{Address, BlockHash, BlockNumber, Sealable, TxHash, TxNumber, B256, U256}; +use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256}; use reth_blockchain_tree_api::{ error::{CanonicalError, InsertBlockError}, BlockValidationKind, BlockchainTreeEngine, BlockchainTreeViewer, CanonicalOutcome, @@ -847,34 +847,20 @@ where BlockNumberOrTag::Latest => Ok(Some(self.chain_info.get_canonical_head())), BlockNumberOrTag::Finalized => Ok(self.chain_info.get_finalized_header()), BlockNumberOrTag::Safe => Ok(self.chain_info.get_safe_header()), - BlockNumberOrTag::Earliest => self.header_by_number(0)?.map_or_else( - || Ok(None), - |h| { - let sealed = h.seal_slow(); - let (header, seal) = sealed.into_parts(); - Ok(Some(SealedHeader::new(header, seal))) - }, - ), + BlockNumberOrTag::Earliest => self + .header_by_number(0)? + .map_or_else(|| Ok(None), |h| Ok(Some(SealedHeader::seal(h)))), BlockNumberOrTag::Pending => Ok(self.tree.pending_header()), - BlockNumberOrTag::Number(num) => self.header_by_number(num)?.map_or_else( - || Ok(None), - |h| { - let sealed = h.seal_slow(); - let (header, seal) = sealed.into_parts(); - Ok(Some(SealedHeader::new(header, seal))) - }, - ), + BlockNumberOrTag::Number(num) => self + .header_by_number(num)? + .map_or_else(|| Ok(None), |h| Ok(Some(SealedHeader::seal(h)))), } } fn sealed_header_by_id(&self, id: BlockId) -> ProviderResult> { Ok(match id { BlockId::Number(num) => self.sealed_header_by_number_or_tag(num)?, - BlockId::Hash(hash) => self.header(&hash.block_hash)?.map(|h| { - let sealed = h.seal_slow(); - let (header, seal) = sealed.into_parts(); - SealedHeader::new(header, seal) - }), + BlockId::Hash(hash) => self.header(&hash.block_hash)?.map(SealedHeader::seal), }) } diff --git a/crates/storage/provider/src/test_utils/blocks.rs b/crates/storage/provider/src/test_utils/blocks.rs index 19a6cbf6a5c..9afc77ef701 100644 --- a/crates/storage/provider/src/test_utils/blocks.rs +++ b/crates/storage/provider/src/test_utils/blocks.rs @@ -2,8 +2,7 @@ use crate::{DBProvider, DatabaseProviderRW, ExecutionOutcome}; use alloy_consensus::{TxLegacy, EMPTY_OMMER_ROOT_HASH}; use alloy_primitives::{ - b256, hex_literal::hex, map::HashMap, Address, BlockNumber, Bytes, Log, Sealable, TxKind, B256, - U256, + b256, hex_literal::hex, map::HashMap, Address, BlockNumber, Bytes, Log, TxKind, B256, U256, }; use alloy_eips::eip4895::{Withdrawal, Withdrawals}; @@ -233,9 +232,7 @@ fn block1(number: BlockNumber) -> (SealedBlockWithSenders, ExecutionOutcome) { header.number = number; header.state_root = state_root; header.parent_hash = B256::ZERO; - let sealed = header.seal_slow(); - let (header, seal) = sealed.into_parts(); - block.header = SealedHeader::new(header, seal); + block.header = SealedHeader::seal(header); (SealedBlockWithSenders { block, senders: vec![Address::new([0x30; 20])] }, execution_outcome) } @@ -299,9 +296,7 @@ fn block2( header.state_root = state_root; // parent_hash points to block1 hash header.parent_hash = parent_hash; - let sealed = header.seal_slow(); - let (header, seal) = sealed.into_parts(); - block.header = SealedHeader::new(header, seal); + block.header = SealedHeader::seal(header); (SealedBlockWithSenders { block, senders: vec![Address::new([0x31; 20])] }, execution_outcome) } @@ -365,9 +360,7 @@ fn block3( header.state_root = state_root; // parent_hash points to block1 hash header.parent_hash = parent_hash; - let sealed = header.seal_slow(); - let (header, seal) = sealed.into_parts(); - block.header = SealedHeader::new(header, seal); + block.header = SealedHeader::seal(header); (SealedBlockWithSenders { block, senders: vec![Address::new([0x31; 20])] }, execution_outcome) } @@ -456,9 +449,7 @@ fn block4( header.state_root = state_root; // parent_hash points to block1 hash header.parent_hash = parent_hash; - let sealed = header.seal_slow(); - let (header, seal) = sealed.into_parts(); - block.header = SealedHeader::new(header, seal); + block.header = SealedHeader::seal(header); (SealedBlockWithSenders { block, senders: vec![Address::new([0x31; 20])] }, execution_outcome) } @@ -544,9 +535,7 @@ fn block5( header.state_root = state_root; // parent_hash points to block1 hash header.parent_hash = parent_hash; - let sealed = header.seal_slow(); - let (header, seal) = sealed.into_parts(); - block.header = SealedHeader::new(header, seal); + block.header = SealedHeader::seal(header); (SealedBlockWithSenders { block, senders: vec![Address::new([0x31; 20])] }, execution_outcome) } diff --git a/crates/storage/provider/src/test_utils/mock.rs b/crates/storage/provider/src/test_utils/mock.rs index 6e4331566db..9bc75f53d18 100644 --- a/crates/storage/provider/src/test_utils/mock.rs +++ b/crates/storage/provider/src/test_utils/mock.rs @@ -13,8 +13,7 @@ use alloy_eips::{ use alloy_primitives::{ keccak256, map::{HashMap, HashSet}, - Address, BlockHash, BlockNumber, Bytes, Sealable, StorageKey, StorageValue, TxHash, TxNumber, - B256, U256, + Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, TxHash, TxNumber, B256, U256, }; use parking_lot::Mutex; use reth_chainspec::{ChainInfo, ChainSpec}; @@ -218,11 +217,7 @@ impl HeaderProvider for MockEthProvider { } fn sealed_header(&self, number: BlockNumber) -> ProviderResult> { - Ok(self.header_by_number(number)?.map(|h| { - let sealed = h.seal_slow(); - let (header, seal) = sealed.into_parts(); - SealedHeader::new(header, seal) - })) + Ok(self.header_by_number(number)?.map(SealedHeader::seal)) } fn sealed_headers_while( @@ -233,11 +228,7 @@ impl HeaderProvider for MockEthProvider { Ok(self .headers_range(range)? .into_iter() - .map(|h| { - let sealed = h.seal_slow(); - let (header, seal) = sealed.into_parts(); - SealedHeader::new(header, seal) - }) + .map(SealedHeader::seal) .take_while(|h| predicate(h)) .collect()) } @@ -566,14 +557,7 @@ impl BlockReaderIdExt for MockEthProvider { } fn sealed_header_by_id(&self, id: BlockId) -> ProviderResult> { - self.header_by_id(id)?.map_or_else( - || Ok(None), - |h| { - let sealed = h.seal_slow(); - let (header, seal) = sealed.into_parts(); - Ok(Some(SealedHeader::new(header, seal))) - }, - ) + self.header_by_id(id)?.map_or_else(|| Ok(None), |h| Ok(Some(SealedHeader::seal(h)))) } fn header_by_id(&self, id: BlockId) -> ProviderResult> { diff --git a/crates/storage/storage-api/src/block.rs b/crates/storage/storage-api/src/block.rs index 01238be745e..c78ec5f8b80 100644 --- a/crates/storage/storage-api/src/block.rs +++ b/crates/storage/storage-api/src/block.rs @@ -3,7 +3,7 @@ use crate::{ TransactionsProvider, WithdrawalsProvider, }; use alloy_eips::{BlockHashOrNumber, BlockId, BlockNumberOrTag}; -use alloy_primitives::{BlockNumber, Sealable, B256}; +use alloy_primitives::{BlockNumber, B256}; use reth_db_models::StoredBlockBodyIndices; use reth_primitives::{ Block, BlockWithSenders, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, @@ -243,14 +243,7 @@ pub trait BlockReaderIdExt: BlockReader + ReceiptProviderIdExt { ) -> ProviderResult> { self.convert_block_number(id)? .map_or_else(|| Ok(None), |num| self.header_by_hash_or_number(num.into()))? - .map_or_else( - || Ok(None), - |h| { - let sealed = h.seal_slow(); - let (header, seal) = sealed.into_parts(); - Ok(Some(SealedHeader::new(header, seal))) - }, - ) + .map_or_else(|| Ok(None), |h| Ok(Some(SealedHeader::seal(h)))) } /// Returns the sealed header with the matching `BlockId` from the database. diff --git a/crates/transaction-pool/src/maintain.rs b/crates/transaction-pool/src/maintain.rs index 608f8d5745a..91b91fe8157 100644 --- a/crates/transaction-pool/src/maintain.rs +++ b/crates/transaction-pool/src/maintain.rs @@ -8,7 +8,7 @@ use crate::{ BlockInfo, PoolTransaction, }; use alloy_eips::BlockNumberOrTag; -use alloy_primitives::{Address, BlockHash, BlockNumber, Sealable}; +use alloy_primitives::{Address, BlockHash, BlockNumber}; use futures_util::{ future::{BoxFuture, Fuse, FusedFuture}, FutureExt, Stream, StreamExt, @@ -106,9 +106,7 @@ pub async fn maintain_transaction_pool( let MaintainPoolConfig { max_update_depth, max_reload_accounts, .. } = config; // ensure the pool points to latest state if let Ok(Some(latest)) = client.header_by_number_or_tag(BlockNumberOrTag::Latest) { - let sealed = latest.seal_slow(); - let (header, seal) = sealed.into_parts(); - let latest = SealedHeader::new(header, seal); + let latest = SealedHeader::seal(latest); let chain_spec = client.chain_spec(); let info = BlockInfo { block_gas_limit: latest.gas_limit, diff --git a/examples/db-access/src/main.rs b/examples/db-access/src/main.rs index c3e30fa1cee..0f7d1a269f3 100644 --- a/examples/db-access/src/main.rs +++ b/examples/db-access/src/main.rs @@ -1,4 +1,4 @@ -use alloy_primitives::{Address, Sealable, B256}; +use alloy_primitives::{Address, B256}; use alloy_rpc_types_eth::{Filter, FilteredParams}; use reth_chainspec::ChainSpecBuilder; use reth_db::{open_db_read_only, DatabaseEnv}; @@ -63,9 +63,7 @@ fn header_provider_example(provider: T, number: u64) -> eyre: // We can convert a header to a sealed header which contains the hash w/o needing to re-compute // it every time. - let sealed = header.seal_slow(); - let (header, seal) = sealed.into_parts(); - let sealed_header = SealedHeader::new(header, seal); + let sealed_header = SealedHeader::seal(header); // Can also query the header by hash! let header_by_hash = diff --git a/testing/testing-utils/src/generators.rs b/testing/testing-utils/src/generators.rs index c24840a2633..3457eb5f203 100644 --- a/testing/testing-utils/src/generators.rs +++ b/testing/testing-utils/src/generators.rs @@ -2,7 +2,7 @@ use alloy_consensus::{Transaction as _, TxLegacy}; use alloy_eips::eip4895::{Withdrawal, Withdrawals}; -use alloy_primitives::{Address, BlockNumber, Bytes, Sealable, TxKind, B256, U256}; +use alloy_primitives::{Address, BlockNumber, Bytes, TxKind, B256, U256}; pub use rand::Rng; use rand::{ distributions::uniform::SampleRange, rngs::StdRng, seq::SliceRandom, thread_rng, SeedableRng, @@ -106,9 +106,7 @@ pub fn random_header(rng: &mut R, number: u64, parent: Option) -> parent_hash: parent.unwrap_or_default(), ..Default::default() }; - let sealed = header.seal_slow(); - let (header, seal) = sealed.into_parts(); - SealedHeader::new(header, seal) + SealedHeader::seal(header) } /// Generates a random legacy [Transaction]. @@ -203,7 +201,7 @@ pub fn random_block(rng: &mut R, number: u64, block_params: BlockParams) }); let withdrawals_root = withdrawals.as_ref().map(|w| proofs::calculate_withdrawals_root(w)); - let sealed = Header { + let header = Header { parent_hash: block_params.parent.unwrap_or_default(), number, gas_used: total_gas, @@ -215,13 +213,10 @@ pub fn random_block(rng: &mut R, number: u64, block_params: BlockParams) requests_hash: None, withdrawals_root, ..Default::default() - } - .seal_slow(); - - let (header, seal) = sealed.into_parts(); + }; SealedBlock { - header: SealedHeader::new(header, seal), + header: SealedHeader::seal(header), body: BlockBody { transactions, ommers, withdrawals: withdrawals.map(Withdrawals::new) }, } } From 9e77d916e1b6758313d33ac0d6874476e1cbf7eb Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Wed, 13 Nov 2024 14:35:59 +0100 Subject: [PATCH 151/211] chore(sdk): improve usability tx primitive traits (#12437) --- crates/primitives-traits/src/lib.rs | 14 +++- .../primitives-traits/src/transaction/mod.rs | 72 ++++++++++--------- .../src/transaction/signed.rs | 29 +++++--- crates/primitives-traits/src/tx_type.rs | 18 +++-- crates/primitives/Cargo.toml | 1 + crates/primitives/src/transaction/mod.rs | 18 ++++- crates/primitives/src/transaction/tx_type.rs | 21 +++++- 7 files changed, 118 insertions(+), 55 deletions(-) diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index 6848da45814..ab3985158d8 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -27,7 +27,7 @@ pub use receipt::{FullReceipt, Receipt}; pub mod transaction; pub use transaction::{ signed::{FullSignedTx, SignedTransaction}, - FullTransaction, Transaction, + FullTransaction, Transaction, TransactionExt, }; mod integer_list; @@ -80,3 +80,15 @@ pub use size::InMemorySize; /// Node traits pub mod node; pub use node::{FullNodePrimitives, NodePrimitives}; + +/// Helper trait that requires arbitrary implementation if the feature is enabled. +#[cfg(any(feature = "test-utils", feature = "arbitrary"))] +pub trait MaybeArbitrary: for<'a> arbitrary::Arbitrary<'a> {} +/// Helper trait that requires arbitrary implementation if the feature is enabled. +#[cfg(not(any(feature = "test-utils", feature = "arbitrary")))] +pub trait MaybeArbitrary {} + +#[cfg(any(feature = "test-utils", feature = "arbitrary"))] +impl MaybeArbitrary for T where T: for<'a> arbitrary::Arbitrary<'a> {} +#[cfg(not(any(feature = "test-utils", feature = "arbitrary")))] +impl MaybeArbitrary for T {} diff --git a/crates/primitives-traits/src/transaction/mod.rs b/crates/primitives-traits/src/transaction/mod.rs index d5061ca3909..bb6f6a711e3 100644 --- a/crates/primitives-traits/src/transaction/mod.rs +++ b/crates/primitives-traits/src/transaction/mod.rs @@ -1,17 +1,20 @@ //! Transaction abstraction -use core::{fmt, hash::Hash}; +pub mod signed; -use alloy_primitives::{TxKind, B256}; +use core::{fmt, hash::Hash}; +use alloy_primitives::B256; use reth_codecs::Compact; use serde::{Deserialize, Serialize}; -use crate::InMemorySize; +use crate::{InMemorySize, MaybeArbitrary, TxType}; -pub mod signed; +/// Helper trait that unifies all behaviour required by transaction to support full node operations. +pub trait FullTransaction: Transaction + Compact {} + +impl FullTransaction for T where T: Transaction + Compact {} -#[allow(dead_code)] /// Abstraction of a transaction. pub trait Transaction: Send @@ -24,41 +27,42 @@ pub trait Transaction: + PartialEq + Hash + Serialize - + alloy_rlp::Encodable - + alloy_rlp::Decodable + for<'de> Deserialize<'de> - + alloy_consensus::Transaction + + TransactionExt + InMemorySize + MaybeArbitrary { - /// Heavy operation that return signature hash over rlp encoded transaction. - /// It is only for signature signing or signer recovery. - fn signature_hash(&self) -> B256; - - /// Gets 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; - - /// Returns true if the tx supports dynamic fees - fn is_dynamic_fee(&self) -> bool; - - /// Returns the effective gas price for the given base fee. - fn effective_gas_price(&self, base_fee: Option) -> u128; - - /// This encodes the transaction _without_ the signature, and is only suitable for creating a - /// hash intended for signing. - fn encode_without_signature(&self, out: &mut dyn bytes::BufMut); } -#[cfg(not(feature = "arbitrary"))] -/// Helper trait that requires arbitrary implementation if the feature is enabled. -pub trait MaybeArbitrary {} +impl Transaction for T where + T: Send + + Sync + + Unpin + + Clone + + Default + + fmt::Debug + + Eq + + PartialEq + + Hash + + Serialize + + for<'de> Deserialize<'de> + + TransactionExt + + InMemorySize + + MaybeArbitrary +{ +} -#[cfg(feature = "arbitrary")] -/// Helper trait that requires arbitrary implementation if the feature is enabled. -pub trait MaybeArbitrary: for<'a> arbitrary::Arbitrary<'a> {} +/// Extension trait of [`alloy_consensus::Transaction`]. +pub trait TransactionExt: alloy_consensus::Transaction { + /// Transaction envelope type ID. + type Type: TxType; -/// Helper trait that unifies all behaviour required by transaction to support full node operations. -pub trait FullTransaction: Transaction + Compact {} + /// Heavy operation that return signature hash over rlp encoded transaction. + /// It is only for signature signing or signer recovery. + fn signature_hash(&self) -> B256; -impl FullTransaction for T where T: Transaction + Compact {} + /// Returns the transaction type. + fn tx_type(&self) -> Self::Type { + Self::Type::try_from(self.ty()).expect("should decode tx type id") + } +} diff --git a/crates/primitives-traits/src/transaction/signed.rs b/crates/primitives-traits/src/transaction/signed.rs index 02e908aec6c..455a9886eb8 100644 --- a/crates/primitives-traits/src/transaction/signed.rs +++ b/crates/primitives-traits/src/transaction/signed.rs @@ -2,17 +2,18 @@ use alloc::fmt; use core::hash::Hash; -use reth_codecs::Compact; -use alloy_consensus::Transaction; use alloy_eips::eip2718::{Decodable2718, Encodable2718}; -use alloy_primitives::{keccak256, Address, PrimitiveSignature as Signature, TxHash, B256}; +use alloy_primitives::{keccak256, Address, PrimitiveSignature, TxHash, B256}; +use reth_codecs::Compact; use revm_primitives::TxEnv; +use crate::{transaction::TransactionExt, FullTransaction, MaybeArbitrary, Transaction}; + /// Helper trait that unifies all behaviour required by block to support full node operations. -pub trait FullSignedTx: SignedTransaction + Compact {} +pub trait FullSignedTx: SignedTransaction + Compact {} -impl FullSignedTx for T where T: SignedTransaction + Compact {} +impl FullSignedTx for T where T: SignedTransaction + Compact {} /// A signed transaction. pub trait SignedTransaction: @@ -31,6 +32,8 @@ pub trait SignedTransaction: + alloy_rlp::Decodable + Encodable2718 + Decodable2718 + + TransactionExt + + MaybeArbitrary { /// Transaction type that is signed. type Transaction: Transaction; @@ -42,7 +45,7 @@ pub trait SignedTransaction: fn transaction(&self) -> &Self::Transaction; /// Returns reference to signature. - fn signature(&self) -> &Signature; + fn signature(&self) -> &PrimitiveSignature; /// Recover signer from signature and hash. /// @@ -65,8 +68,10 @@ pub trait SignedTransaction: /// Create a new signed transaction from a transaction and its signature. /// /// This will also calculate the transaction hash using its encoding. - fn from_transaction_and_signature(transaction: Self::Transaction, signature: Signature) - -> Self; + fn from_transaction_and_signature( + transaction: Self::Transaction, + signature: PrimitiveSignature, + ) -> Self; /// Calculate transaction hash, eip2728 transaction does not contain rlp header and start with /// tx type. @@ -77,3 +82,11 @@ pub trait SignedTransaction: /// Fills [`TxEnv`] with an [`Address`] and transaction. fn fill_tx_env(&self, tx_env: &mut TxEnv, sender: Address); } + +impl TransactionExt for T { + type Type = ::Type; + + fn signature_hash(&self) -> B256 { + self.transaction().signature_hash() + } +} diff --git a/crates/primitives-traits/src/tx_type.rs b/crates/primitives-traits/src/tx_type.rs index e0bf28d2a99..078d8ac947b 100644 --- a/crates/primitives-traits/src/tx_type.rs +++ b/crates/primitives-traits/src/tx_type.rs @@ -1,8 +1,6 @@ use core::fmt; -use alloy_eips::eip2718::Eip2718Error; use alloy_primitives::{U64, U8}; -use alloy_rlp::{Decodable, Encodable}; use reth_codecs::Compact; /// Helper trait that unifies all behaviour required by transaction type ID to support full node @@ -26,11 +24,11 @@ pub trait TxType: + PartialEq + Into + Into - + TryFrom - + TryFrom + + TryFrom + + TryFrom + TryFrom - + Encodable - + Decodable + + alloy_rlp::Encodable + + alloy_rlp::Decodable { } @@ -48,10 +46,10 @@ impl TxType for T where + PartialEq + Into + Into - + TryFrom - + TryFrom + + TryFrom + + TryFrom + TryFrom - + Encodable - + Decodable + + alloy_rlp::Encodable + + alloy_rlp::Decodable { } diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index 1a4c33c7180..34d04c94edc 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -150,6 +150,7 @@ test-utils = [ "reth-chainspec/test-utils", "reth-codecs?/test-utils", "reth-trie-common/test-utils", + "arbitrary", ] serde-bincode-compat = [ "alloy-consensus/serde-bincode-compat", diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index f0caa2863aa..d1a95b09be2 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -68,7 +68,7 @@ use tx_type::{ }; use alloc::vec::Vec; -use reth_primitives_traits::SignedTransaction; +use reth_primitives_traits::{transaction::TransactionExt, SignedTransaction}; use revm_primitives::{AuthorizationList, TxEnv}; /// Either a transaction hash or number. @@ -846,6 +846,22 @@ impl alloy_consensus::Transaction for Transaction { } } +impl TransactionExt for Transaction { + type Type = TxType; + + fn signature_hash(&self) -> B256 { + match self { + Self::Legacy(tx) => tx.signature_hash(), + Self::Eip2930(tx) => tx.signature_hash(), + Self::Eip1559(tx) => tx.signature_hash(), + Self::Eip4844(tx) => tx.signature_hash(), + Self::Eip7702(tx) => tx.signature_hash(), + #[cfg(feature = "optimism")] + _ => todo!("use op type for op"), + } + } +} + /// Signed transaction without its Hash. Used type for inserting into the DB. /// /// This can by converted to [`TransactionSigned`] by calling [`TransactionSignedNoHash::hash`]. diff --git a/crates/primitives/src/transaction/tx_type.rs b/crates/primitives/src/transaction/tx_type.rs index 0cfb2ff9d67..46e37086113 100644 --- a/crates/primitives/src/transaction/tx_type.rs +++ b/crates/primitives/src/transaction/tx_type.rs @@ -4,6 +4,7 @@ use alloy_consensus::constants::{ }; use alloy_primitives::{U64, U8}; use alloy_rlp::{Decodable, Encodable}; +use derive_more::Display; use serde::{Deserialize, Serialize}; /// Identifier parameter for legacy transaction @@ -36,24 +37,42 @@ pub const DEPOSIT_TX_TYPE_ID: u8 = 126; /// /// Other required changes when adding a new type can be seen on [PR#3953](https://github.com/paradigmxyz/reth/pull/3953/files). #[derive( - Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Default, Serialize, Deserialize, Hash, + Clone, + Copy, + Debug, + PartialEq, + Eq, + PartialOrd, + Ord, + Default, + Serialize, + Deserialize, + Hash, + Display, )] #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] #[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(compact))] +#[display("tx type: {_variant}")] pub enum TxType { /// Legacy transaction pre EIP-2929 #[default] + #[display("legacy (0)")] Legacy = 0_isize, /// AccessList transaction + #[display("eip2930 (1)")] Eip2930 = 1_isize, /// Transaction with Priority fee + #[display("eip1559 (2)")] Eip1559 = 2_isize, /// Shard Blob Transactions - EIP-4844 + #[display("eip4844 (3)")] Eip4844 = 3_isize, /// EOA Contract Code Transactions - EIP-7702 + #[display("eip7702 (4)")] Eip7702 = 4_isize, /// Optimism Deposit transaction. #[cfg(feature = "optimism")] + #[display("deposit (126)")] Deposit = 126_isize, } From e6f3191c62cf92339dd682f1654ba2b450a115be Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 13 Nov 2024 15:16:16 +0100 Subject: [PATCH 152/211] chore: rm cfg imports (#12518) --- crates/primitives-traits/src/header/sealed.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/crates/primitives-traits/src/header/sealed.rs b/crates/primitives-traits/src/header/sealed.rs index 8364b85b3aa..5dd9fcf0d5f 100644 --- a/crates/primitives-traits/src/header/sealed.rs +++ b/crates/primitives-traits/src/header/sealed.rs @@ -1,11 +1,8 @@ -use crate::InMemorySize; - use super::Header; +use crate::InMemorySize; use alloy_consensus::Sealed; use alloy_eips::BlockNumHash; use alloy_primitives::{keccak256, BlockHash, Sealable}; -#[cfg(any(test, feature = "test-utils"))] -use alloy_primitives::{BlockNumber, B256, U256}; use alloy_rlp::{Decodable, Encodable}; use bytes::BufMut; use core::mem; @@ -130,17 +127,17 @@ impl SealedHeader { } /// Updates the block number. - pub fn set_block_number(&mut self, number: BlockNumber) { + pub fn set_block_number(&mut self, number: alloy_primitives::BlockNumber) { self.header.number = number; } /// Updates the block state root. - pub fn set_state_root(&mut self, state_root: B256) { + pub fn set_state_root(&mut self, state_root: alloy_primitives::B256) { self.header.state_root = state_root; } /// Updates the block difficulty. - pub fn set_difficulty(&mut self, difficulty: U256) { + pub fn set_difficulty(&mut self, difficulty: alloy_primitives::U256) { self.header.difficulty = difficulty; } } From 001f3899fdeaa01bb3acf9bb7258dffbbc89f050 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Wed, 13 Nov 2024 17:41:25 +0100 Subject: [PATCH 153/211] primitives: rm alloy `Header` reexport (#12515) --- Cargo.lock | 28 +++++-- crates/blockchain-tree/src/block_indices.rs | 3 +- crates/blockchain-tree/src/blockchain_tree.rs | 4 +- crates/chain-state/Cargo.toml | 19 +++-- crates/chain-state/src/in_memory.rs | 3 +- crates/chain-state/src/test_utils.rs | 6 +- crates/chainspec/src/api.rs | 2 +- crates/chainspec/src/spec.rs | 7 +- crates/cli/commands/Cargo.toml | 38 +++++----- crates/cli/commands/src/db/get.rs | 2 +- .../commands/src/init_state/without_evm.rs | 3 +- .../cli/commands/src/test_vectors/tables.rs | 3 +- crates/consensus/beacon/Cargo.toml | 19 ++--- .../beacon/src/engine/invalid_headers.rs | 3 +- crates/consensus/beacon/src/engine/mod.rs | 3 +- crates/consensus/beacon/src/engine/sync.rs | 3 +- crates/consensus/common/src/validation.rs | 6 +- crates/consensus/consensus/Cargo.toml | 12 +-- crates/consensus/consensus/src/lib.rs | 3 +- crates/engine/invalid-block-hooks/Cargo.toml | 1 + .../engine/invalid-block-hooks/src/witness.rs | 3 +- crates/engine/tree/Cargo.toml | 37 +++++----- crates/engine/tree/src/backfill.rs | 3 +- crates/engine/tree/src/download.rs | 3 +- crates/engine/tree/src/tree/mod.rs | 5 +- crates/engine/util/src/reorg.rs | 4 +- crates/ethereum/consensus/src/lib.rs | 4 +- crates/ethereum/evm/src/lib.rs | 10 +-- crates/ethereum/node/Cargo.toml | 28 +++---- crates/ethereum/node/src/node.rs | 3 +- crates/ethereum/payload/src/lib.rs | 4 +- crates/evm/src/provider.rs | 2 +- crates/evm/src/system_calls/eip2935.rs | 2 +- crates/evm/src/system_calls/eip4788.rs | 2 +- crates/evm/src/system_calls/eip7002.rs | 2 +- crates/evm/src/system_calls/eip7251.rs | 2 +- crates/evm/src/system_calls/mod.rs | 3 +- crates/exex/exex/src/backfill/test_utils.rs | 4 +- crates/net/downloaders/src/bodies/bodies.rs | 4 +- crates/net/downloaders/src/bodies/queue.rs | 2 +- crates/net/downloaders/src/bodies/request.rs | 6 +- crates/net/downloaders/src/bodies/task.rs | 2 +- crates/net/downloaders/src/file_client.rs | 3 +- crates/net/eth-wire-types/Cargo.toml | 34 ++++----- crates/net/eth-wire-types/src/blocks.rs | 8 +- crates/net/eth-wire-types/src/header.rs | 3 +- crates/net/eth-wire-types/src/primitives.rs | 2 +- crates/net/network/src/eth_requests.rs | 3 +- crates/net/network/src/state.rs | 3 +- crates/net/network/tests/it/requests.rs | 4 +- crates/net/p2p/src/bodies/response.rs | 2 +- crates/net/p2p/src/headers/client.rs | 2 +- crates/net/p2p/src/lib.rs | 4 +- crates/net/p2p/src/test_utils/full_block.rs | 3 +- crates/net/p2p/src/test_utils/headers.rs | 3 +- crates/node/api/Cargo.toml | 4 +- crates/node/api/src/node.rs | 2 +- crates/node/builder/Cargo.toml | 33 +++++---- crates/node/builder/src/components/builder.rs | 2 +- crates/node/builder/src/components/execute.rs | 2 +- crates/node/builder/src/components/mod.rs | 2 +- crates/node/builder/src/launch/common.rs | 2 +- crates/node/builder/src/setup.rs | 2 +- crates/optimism/chainspec/src/lib.rs | 2 +- crates/optimism/consensus/src/lib.rs | 6 +- crates/optimism/evm/src/execute.rs | 4 +- crates/optimism/evm/src/l1.rs | 3 +- crates/optimism/evm/src/lib.rs | 7 +- crates/optimism/node/Cargo.toml | 69 +++++++++--------- crates/optimism/node/src/node.rs | 3 +- crates/optimism/payload/src/builder.rs | 4 +- crates/optimism/primitives/Cargo.toml | 2 - crates/optimism/primitives/src/bedrock.rs | 3 +- crates/optimism/rpc/src/eth/call.rs | 6 +- crates/optimism/rpc/src/eth/mod.rs | 2 +- crates/optimism/rpc/src/eth/pending_block.rs | 3 +- crates/payload/builder/Cargo.toml | 9 ++- crates/payload/builder/src/lib.rs | 3 +- crates/primitives-traits/src/header/mod.rs | 3 +- .../src/header/test_utils.rs | 2 +- crates/primitives-traits/src/lib.rs | 2 +- crates/primitives/src/block.rs | 3 +- crates/primitives/src/lib.rs | 4 +- crates/primitives/src/proofs.rs | 4 +- crates/rpc/rpc-builder/Cargo.toml | 4 +- crates/rpc/rpc-builder/src/eth.rs | 2 +- crates/rpc/rpc-builder/src/lib.rs | 10 +-- crates/rpc/rpc-eth-api/src/helpers/block.rs | 2 +- crates/rpc/rpc-eth-api/src/helpers/call.rs | 4 +- .../rpc-eth-api/src/helpers/pending_block.rs | 5 +- crates/rpc/rpc-eth-api/src/helpers/state.rs | 3 +- crates/rpc/rpc-eth-api/src/helpers/trace.rs | 3 +- crates/rpc/rpc-eth-types/src/cache/mod.rs | 3 +- crates/rpc/rpc-eth-types/src/simulate.rs | 2 +- .../rpc-types-compat/src/engine/payload.rs | 4 +- crates/rpc/rpc/src/eth/core.rs | 3 +- crates/rpc/rpc/src/eth/helpers/call.rs | 2 +- .../rpc/rpc/src/eth/helpers/pending_block.rs | 2 +- crates/rpc/rpc/src/eth/helpers/trace.rs | 2 +- crates/rpc/rpc/src/trace.rs | 2 +- crates/stages/stages/Cargo.toml | 39 +++++----- crates/stages/stages/src/stages/bodies.rs | 3 +- crates/stages/stages/src/stages/execution.rs | 3 +- crates/stages/stages/src/stages/headers.rs | 8 +- crates/storage/db-api/Cargo.toml | 45 ++++++------ crates/storage/db-api/src/models/blocks.rs | 2 +- crates/storage/db-api/src/models/mod.rs | 5 +- crates/storage/db/Cargo.toml | 41 +++++------ .../storage/db/src/implementation/mdbx/mod.rs | 3 +- crates/storage/db/src/static_file/masks.rs | 2 +- crates/storage/db/src/tables/mod.rs | 3 +- crates/storage/provider/Cargo.toml | 73 +++++++++---------- .../src/providers/blockchain_provider.rs | 5 +- .../provider/src/providers/consistent.rs | 5 +- .../provider/src/providers/database/mod.rs | 3 +- .../src/providers/database/provider.rs | 7 +- crates/storage/provider/src/providers/mod.rs | 5 +- .../provider/src/providers/static_file/jar.rs | 3 +- .../src/providers/static_file/manager.rs | 3 +- .../provider/src/providers/static_file/mod.rs | 4 +- .../src/providers/static_file/writer.rs | 3 +- .../storage/provider/src/test_utils/blocks.rs | 5 +- .../storage/provider/src/test_utils/mock.rs | 4 +- .../storage/provider/src/test_utils/noop.rs | 6 +- crates/storage/provider/src/writer/mod.rs | 3 +- crates/storage/storage-api/src/block.rs | 3 +- crates/storage/storage-api/src/header.rs | 3 +- examples/custom-evm/Cargo.toml | 1 + examples/custom-evm/src/main.rs | 3 +- examples/stateful-precompile/Cargo.toml | 1 + examples/stateful-precompile/src/main.rs | 3 +- testing/ef-tests/Cargo.toml | 1 + testing/ef-tests/src/models.rs | 5 +- testing/testing-utils/src/generators.rs | 6 +- 134 files changed, 493 insertions(+), 439 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9e1d2330091..ca5465d37bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -776,9 +776,9 @@ dependencies = [ [[package]] name = "alloy-trie" -version = "0.7.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6b2e366c0debf0af77766c23694a3f863b02633050e71e096e257ffbd395e50" +checksum = "40d8e28db02c006f7abb20f345ffb3cc99c465e36f676ba262534e654ae76042" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -2611,6 +2611,7 @@ dependencies = [ name = "ef-tests" version = "1.1.1" dependencies = [ + "alloy-consensus", "alloy-eips", "alloy-primitives", "alloy-rlp", @@ -2878,6 +2879,7 @@ dependencies = [ name = "example-custom-evm" version = "0.0.0" dependencies = [ + "alloy-consensus", "alloy-genesis", "alloy-primitives", "eyre", @@ -3063,6 +3065,7 @@ dependencies = [ name = "example-stateful-precompile" version = "0.0.0" dependencies = [ + "alloy-consensus", "alloy-genesis", "alloy-primitives", "eyre", @@ -4601,7 +4604,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -6445,6 +6448,7 @@ dependencies = [ name = "reth-beacon-consensus" version = "1.1.1" dependencies = [ + "alloy-consensus", "alloy-eips", "alloy-genesis", "alloy-primitives", @@ -6647,6 +6651,7 @@ name = "reth-cli-commands" version = "1.1.1" dependencies = [ "ahash", + "alloy-consensus", "alloy-eips", "alloy-primitives", "alloy-rlp", @@ -6788,6 +6793,7 @@ dependencies = [ name = "reth-consensus" version = "1.1.1" dependencies = [ + "alloy-consensus", "alloy-eips", "alloy-primitives", "auto_impl", @@ -6838,6 +6844,7 @@ dependencies = [ name = "reth-db" version = "1.1.1" dependencies = [ + "alloy-consensus", "alloy-primitives", "arbitrary", "assert_matches", @@ -6878,6 +6885,7 @@ dependencies = [ name = "reth-db-api" version = "1.1.1" dependencies = [ + "alloy-consensus", "alloy-genesis", "alloy-primitives", "arbitrary", @@ -7206,6 +7214,7 @@ dependencies = [ name = "reth-engine-tree" version = "1.1.1" dependencies = [ + "alloy-consensus", "alloy-eips", "alloy-primitives", "alloy-rlp", @@ -7643,6 +7652,7 @@ dependencies = [ name = "reth-invalid-block-hooks" version = "1.1.1" dependencies = [ + "alloy-consensus", "alloy-primitives", "alloy-rlp", "alloy-rpc-types-debug", @@ -7902,6 +7912,7 @@ dependencies = [ name = "reth-node-api" version = "1.1.1" dependencies = [ + "alloy-consensus", "alloy-rpc-types-engine", "eyre", "reth-beacon-consensus", @@ -7912,7 +7923,6 @@ dependencies = [ "reth-node-core", "reth-node-types", "reth-payload-primitives", - "reth-primitives", "reth-provider", "reth-tasks", "reth-transaction-pool", @@ -7922,6 +7932,7 @@ dependencies = [ name = "reth-node-builder" version = "1.1.1" dependencies = [ + "alloy-consensus", "alloy-primitives", "alloy-rpc-types", "aquamarine", @@ -8354,8 +8365,6 @@ dependencies = [ "bytes", "derive_more 1.0.0", "op-alloy-consensus", - "reth-primitives", - "reth-primitives-traits", ] [[package]] @@ -8412,6 +8421,7 @@ dependencies = [ name = "reth-payload-builder" version = "1.1.1" dependencies = [ + "alloy-consensus", "alloy-primitives", "alloy-rpc-types", "async-trait", @@ -8770,6 +8780,7 @@ dependencies = [ name = "reth-rpc-builder" version = "1.1.1" dependencies = [ + "alloy-consensus", "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", @@ -8991,6 +9002,7 @@ dependencies = [ name = "reth-stages" version = "1.1.1" dependencies = [ + "alloy-consensus", "alloy-primitives", "alloy-rlp", "assert_matches", @@ -11086,7 +11098,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3637e734239e12ab152cd269302500bd063f37624ee210cd04b4936ed671f3b1" dependencies = [ "cc", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -11561,7 +11573,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/crates/blockchain-tree/src/block_indices.rs b/crates/blockchain-tree/src/block_indices.rs index 0c48b3b9ce8..7778fb9262c 100644 --- a/crates/blockchain-tree/src/block_indices.rs +++ b/crates/blockchain-tree/src/block_indices.rs @@ -377,8 +377,9 @@ impl BlockIndices { #[cfg(test)] mod tests { use super::*; + use alloy_consensus::Header; use alloy_primitives::B256; - use reth_primitives::{Header, SealedBlock, SealedHeader}; + use reth_primitives::{SealedBlock, SealedHeader}; #[test] fn pending_block_num_hash_returns_none_if_no_fork() { diff --git a/crates/blockchain-tree/src/blockchain_tree.rs b/crates/blockchain-tree/src/blockchain_tree.rs index 0a7dd2a1178..c48e1548434 100644 --- a/crates/blockchain-tree/src/blockchain_tree.rs +++ b/crates/blockchain-tree/src/blockchain_tree.rs @@ -1374,7 +1374,7 @@ where #[cfg(test)] mod tests { use super::*; - use alloy_consensus::{TxEip1559, EMPTY_ROOT_HASH}; + use alloy_consensus::{Header, TxEip1559, EMPTY_ROOT_HASH}; use alloy_eips::{eip1559::INITIAL_BASE_FEE, eip4895::Withdrawals}; use alloy_genesis::{Genesis, GenesisAccount}; use alloy_primitives::{keccak256, Address, PrimitiveSignature as Signature, B256}; @@ -1389,7 +1389,7 @@ mod tests { use reth_primitives::{ proofs::{calculate_receipt_root, calculate_transaction_root}, revm_primitives::AccountInfo, - Account, BlockBody, Header, Transaction, TransactionSigned, TransactionSignedEcRecovered, + Account, BlockBody, Transaction, TransactionSigned, TransactionSignedEcRecovered, }; use reth_provider::{ test_utils::{ diff --git a/crates/chain-state/Cargo.toml b/crates/chain-state/Cargo.toml index 9a88a3c54bc..0a2f53715ff 100644 --- a/crates/chain-state/Cargo.toml +++ b/crates/chain-state/Cargo.toml @@ -24,6 +24,7 @@ reth-trie.workspace = true # ethereum alloy-eips.workspace = true alloy-primitives.workspace = true +alloy-consensus.workspace = true # async tokio = { workspace = true, features = ["sync", "macros", "rt-multi-thread"] } @@ -42,7 +43,6 @@ pin-project.workspace = true # optional deps for test-utils alloy-signer = { workspace = true, optional = true } alloy-signer-local = { workspace = true, optional = true } -alloy-consensus = { workspace = true, optional = true } rand = { workspace = true, optional = true } revm = { workspace = true, optional = true } @@ -56,13 +56,12 @@ revm.workspace = true [features] test-utils = [ - "alloy-signer", - "alloy-signer-local", - "alloy-consensus", - "rand", - "revm", - "reth-chainspec/test-utils", - "reth-primitives/test-utils", - "reth-trie/test-utils", - "revm?/test-utils" + "alloy-signer", + "alloy-signer-local", + "rand", + "revm", + "reth-chainspec/test-utils", + "reth-primitives/test-utils", + "reth-trie/test-utils", + "revm?/test-utils", ] diff --git a/crates/chain-state/src/in_memory.rs b/crates/chain-state/src/in_memory.rs index 8794bb393ca..47443b36c67 100644 --- a/crates/chain-state/src/in_memory.rs +++ b/crates/chain-state/src/in_memory.rs @@ -4,6 +4,7 @@ use crate::{ CanonStateNotification, CanonStateNotificationSender, CanonStateNotifications, ChainInfoTracker, MemoryOverlayStateProvider, }; +use alloy_consensus::Header; use alloy_eips::{BlockHashOrNumber, BlockNumHash}; use alloy_primitives::{map::HashMap, Address, TxHash, B256}; use parking_lot::RwLock; @@ -11,7 +12,7 @@ use reth_chainspec::ChainInfo; use reth_execution_types::{Chain, ExecutionOutcome}; use reth_metrics::{metrics::Gauge, Metrics}; use reth_primitives::{ - BlockWithSenders, Header, Receipt, Receipts, SealedBlock, SealedBlockWithSenders, SealedHeader, + BlockWithSenders, Receipt, Receipts, SealedBlock, SealedBlockWithSenders, SealedHeader, TransactionMeta, TransactionSigned, }; use reth_storage_api::StateProviderBox; diff --git a/crates/chain-state/src/test_utils.rs b/crates/chain-state/src/test_utils.rs index 650fcc3bbce..60a90e43fee 100644 --- a/crates/chain-state/src/test_utils.rs +++ b/crates/chain-state/src/test_utils.rs @@ -2,7 +2,7 @@ use crate::{ in_memory::ExecutedBlock, CanonStateNotification, CanonStateNotifications, CanonStateSubscriptions, }; -use alloy_consensus::{Transaction as _, TxEip1559, EMPTY_ROOT_HASH}; +use alloy_consensus::{Header, Transaction as _, TxEip1559, EMPTY_ROOT_HASH}; use alloy_eips::{eip1559::INITIAL_BASE_FEE, eip7685::Requests}; use alloy_primitives::{Address, BlockNumber, B256, U256}; use alloy_signer::SignerSync; @@ -12,8 +12,8 @@ use reth_chainspec::{ChainSpec, EthereumHardfork, MIN_TRANSACTION_GAS}; use reth_execution_types::{Chain, ExecutionOutcome}; use reth_primitives::{ proofs::{calculate_receipt_root, calculate_transaction_root, calculate_withdrawals_root}, - BlockBody, Header, Receipt, Receipts, SealedBlock, SealedBlockWithSenders, SealedHeader, - Transaction, TransactionSigned, TransactionSignedEcRecovered, + BlockBody, Receipt, Receipts, SealedBlock, SealedBlockWithSenders, SealedHeader, Transaction, + TransactionSigned, TransactionSignedEcRecovered, }; use reth_trie::{root::state_root_unhashed, updates::TrieUpdates, HashedPostState}; use revm::{db::BundleState, primitives::AccountInfo}; diff --git a/crates/chainspec/src/api.rs b/crates/chainspec/src/api.rs index ee25f72bae8..f0cc31bb44d 100644 --- a/crates/chainspec/src/api.rs +++ b/crates/chainspec/src/api.rs @@ -1,12 +1,12 @@ use crate::{ChainSpec, DepositContract}; use alloc::{boxed::Box, vec::Vec}; use alloy_chains::Chain; +use alloy_consensus::Header; use alloy_eips::eip1559::BaseFeeParams; use alloy_genesis::Genesis; use alloy_primitives::B256; use core::fmt::{Debug, Display}; use reth_network_peers::NodeRecord; -use reth_primitives_traits::Header; /// Trait representing type configuring a chain spec. #[auto_impl::auto_impl(&, Arc)] diff --git a/crates/chainspec/src/spec.rs b/crates/chainspec/src/spec.rs index 779eb8a3757..fdaad948f26 100644 --- a/crates/chainspec/src/spec.rs +++ b/crates/chainspec/src/spec.rs @@ -11,7 +11,10 @@ use alloy_genesis::Genesis; use alloy_primitives::{address, b256, Address, BlockNumber, B256, U256}; use derive_more::From; -use alloy_consensus::constants::{DEV_GENESIS_HASH, MAINNET_GENESIS_HASH, SEPOLIA_GENESIS_HASH}; +use alloy_consensus::{ + constants::{DEV_GENESIS_HASH, MAINNET_GENESIS_HASH, SEPOLIA_GENESIS_HASH}, + Header, +}; use alloy_eips::eip1559::ETHEREUM_BLOCK_GAS_LIMIT; use reth_ethereum_forks::{ ChainHardforks, DisplayHardforks, EthereumHardfork, EthereumHardforks, ForkCondition, @@ -21,7 +24,7 @@ use reth_network_peers::{ base_nodes, base_testnet_nodes, holesky_nodes, mainnet_nodes, op_nodes, op_testnet_nodes, sepolia_nodes, NodeRecord, }; -use reth_primitives_traits::{constants::HOLESKY_GENESIS_HASH, Header, SealedHeader}; +use reth_primitives_traits::{constants::HOLESKY_GENESIS_HASH, SealedHeader}; use reth_trie_common::root::state_root_ref_unhashed; use crate::{constants::MAINNET_DEPOSIT_CONTRACT, once_cell_set, EthChainSpec, LazyLock, OnceLock}; diff --git a/crates/cli/commands/Cargo.toml b/crates/cli/commands/Cargo.toml index a0bc5147700..7e27d9b4e2e 100644 --- a/crates/cli/commands/Cargo.toml +++ b/crates/cli/commands/Cargo.toml @@ -52,6 +52,7 @@ reth-trie-common = { workspace = true, optional = true } alloy-eips.workspace = true alloy-primitives.workspace = true alloy-rlp.workspace = true +alloy-consensus.workspace = true itertools.workspace = true futures.workspace = true @@ -94,22 +95,23 @@ reth-discv4.workspace = true [features] default = [] arbitrary = [ - "dep:proptest", - "dep:arbitrary", - "dep:proptest-arbitrary-interop", - "reth-primitives/arbitrary", - "reth-db-api/arbitrary", - "reth-eth-wire/arbitrary", - "reth-db/arbitrary", - "reth-chainspec/arbitrary", - "alloy-eips/arbitrary", - "alloy-primitives/arbitrary", - "reth-codecs/test-utils", - "reth-prune-types/test-utils", - "reth-stages-types/test-utils", - "reth-trie-common/test-utils", - "reth-codecs?/arbitrary", - "reth-prune-types?/arbitrary", - "reth-stages-types?/arbitrary", - "reth-trie-common?/arbitrary" + "dep:proptest", + "dep:arbitrary", + "dep:proptest-arbitrary-interop", + "reth-primitives/arbitrary", + "reth-db-api/arbitrary", + "reth-eth-wire/arbitrary", + "reth-db/arbitrary", + "reth-chainspec/arbitrary", + "alloy-eips/arbitrary", + "alloy-primitives/arbitrary", + "reth-codecs/test-utils", + "reth-prune-types/test-utils", + "reth-stages-types/test-utils", + "reth-trie-common/test-utils", + "reth-codecs?/arbitrary", + "reth-prune-types?/arbitrary", + "reth-stages-types?/arbitrary", + "reth-trie-common?/arbitrary", + "alloy-consensus/arbitrary", ] diff --git a/crates/cli/commands/src/db/get.rs b/crates/cli/commands/src/db/get.rs index 4006d1660aa..94c0f63dd30 100644 --- a/crates/cli/commands/src/db/get.rs +++ b/crates/cli/commands/src/db/get.rs @@ -1,3 +1,4 @@ +use alloy_consensus::Header; use alloy_primitives::{hex, BlockHash}; use clap::Parser; use reth_db::{ @@ -7,7 +8,6 @@ use reth_db::{ use reth_db_api::table::{Decompress, DupSort, Table}; use reth_db_common::DbTool; use reth_node_builder::NodeTypesWithDB; -use reth_primitives::Header; use reth_provider::{providers::ProviderNodeTypes, StaticFileProviderFactory}; use reth_static_file_types::StaticFileSegment; use tracing::error; diff --git a/crates/cli/commands/src/init_state/without_evm.rs b/crates/cli/commands/src/init_state/without_evm.rs index 187996653c3..29fc2aec60e 100644 --- a/crates/cli/commands/src/init_state/without_evm.rs +++ b/crates/cli/commands/src/init_state/without_evm.rs @@ -1,8 +1,9 @@ use alloy_primitives::{BlockNumber, B256, U256}; use alloy_rlp::Decodable; +use alloy_consensus::Header; use reth_primitives::{ - BlockBody, Header, SealedBlock, SealedBlockWithSenders, SealedHeader, StaticFileSegment, + BlockBody, SealedBlock, SealedBlockWithSenders, SealedHeader, StaticFileSegment, }; use reth_provider::{ providers::StaticFileProvider, BlockWriter, StageCheckpointWriter, StaticFileWriter, diff --git a/crates/cli/commands/src/test_vectors/tables.rs b/crates/cli/commands/src/test_vectors/tables.rs index 6b523c6edd1..fd7d3b3799d 100644 --- a/crates/cli/commands/src/test_vectors/tables.rs +++ b/crates/cli/commands/src/test_vectors/tables.rs @@ -1,3 +1,4 @@ +use alloy_consensus::Header; use alloy_primitives::{hex, private::getrandom::getrandom}; use arbitrary::Arbitrary; use eyre::Result; @@ -10,7 +11,7 @@ use proptest_arbitrary_interop::arb; use reth_db::tables; use reth_db_api::table::{DupSort, Table, TableRow}; use reth_fs_util as fs; -use reth_primitives::{Header, TransactionSignedNoHash}; +use reth_primitives::TransactionSignedNoHash; use std::collections::HashSet; use tracing::error; diff --git a/crates/consensus/beacon/Cargo.toml b/crates/consensus/beacon/Cargo.toml index 0139be2f680..d926fc09c35 100644 --- a/crates/consensus/beacon/Cargo.toml +++ b/crates/consensus/beacon/Cargo.toml @@ -34,6 +34,7 @@ reth-chainspec = { workspace = true, optional = true } alloy-primitives.workspace = true alloy-rpc-types-engine = { workspace = true, features = ["std"] } alloy-eips.workspace = true +alloy-consensus.workspace = true # async tokio = { workspace = true, features = ["sync"] } @@ -77,12 +78,12 @@ assert_matches.workspace = true [features] optimism = [ - "reth-blockchain-tree/optimism", - "reth-chainspec", - "reth-db-api/optimism", - "reth-db/optimism", - "reth-downloaders/optimism", - "reth-primitives/optimism", - "reth-provider/optimism", - "reth-downloaders/optimism" -] \ No newline at end of file + "reth-blockchain-tree/optimism", + "reth-chainspec", + "reth-db-api/optimism", + "reth-db/optimism", + "reth-downloaders/optimism", + "reth-primitives/optimism", + "reth-provider/optimism", + "reth-downloaders/optimism", +] diff --git a/crates/consensus/beacon/src/engine/invalid_headers.rs b/crates/consensus/beacon/src/engine/invalid_headers.rs index 5bcf0cae7e9..b8d80b0ceea 100644 --- a/crates/consensus/beacon/src/engine/invalid_headers.rs +++ b/crates/consensus/beacon/src/engine/invalid_headers.rs @@ -1,9 +1,10 @@ +use alloy_consensus::Header; use alloy_primitives::B256; use reth_metrics::{ metrics::{Counter, Gauge}, Metrics, }; -use reth_primitives::{Header, SealedHeader}; +use reth_primitives::SealedHeader; use schnellru::{ByLength, LruMap}; use std::sync::Arc; use tracing::warn; diff --git a/crates/consensus/beacon/src/engine/mod.rs b/crates/consensus/beacon/src/engine/mod.rs index 8d385a64b8e..03f7bf08b1e 100644 --- a/crates/consensus/beacon/src/engine/mod.rs +++ b/crates/consensus/beacon/src/engine/mod.rs @@ -1,3 +1,4 @@ +use alloy_consensus::Header; use alloy_eips::{merge::EPOCH_SLOTS, BlockNumHash}; use alloy_primitives::{BlockNumber, B256}; use alloy_rpc_types_engine::{ @@ -20,7 +21,7 @@ use reth_node_types::NodeTypesWithEngine; use reth_payload_builder::PayloadBuilderHandle; use reth_payload_primitives::{PayloadAttributes, PayloadBuilder, PayloadBuilderAttributes}; use reth_payload_validator::ExecutionPayloadValidator; -use reth_primitives::{Head, Header, SealedBlock, SealedHeader}; +use reth_primitives::{Head, SealedBlock, SealedHeader}; use reth_provider::{ providers::ProviderNodeTypes, BlockIdReader, BlockReader, BlockSource, CanonChainTracker, ChainSpecProvider, ProviderError, StageCheckpointReader, diff --git a/crates/consensus/beacon/src/engine/sync.rs b/crates/consensus/beacon/src/engine/sync.rs index d91280eac88..b6e75f802e3 100644 --- a/crates/consensus/beacon/src/engine/sync.rs +++ b/crates/consensus/beacon/src/engine/sync.rs @@ -410,11 +410,12 @@ impl PipelineState { #[cfg(test)] mod tests { use super::*; + use alloy_consensus::Header; use assert_matches::assert_matches; use futures::poll; use reth_chainspec::{ChainSpec, ChainSpecBuilder, MAINNET}; use reth_network_p2p::{either::Either, test_utils::TestFullBlockClient}; - use reth_primitives::{BlockBody, Header, SealedHeader}; + use reth_primitives::{BlockBody, SealedHeader}; use reth_provider::{ test_utils::{create_test_provider_factory_with_chain_spec, MockNodeTypesWithDB}, ExecutionOutcome, diff --git a/crates/consensus/common/src/validation.rs b/crates/consensus/common/src/validation.rs index af1bbfdbdd3..62357b4b9b1 100644 --- a/crates/consensus/common/src/validation.rs +++ b/crates/consensus/common/src/validation.rs @@ -1,12 +1,10 @@ //! Collection of methods for block validation. -use alloy_consensus::constants::MAXIMUM_EXTRA_DATA_SIZE; +use alloy_consensus::{constants::MAXIMUM_EXTRA_DATA_SIZE, Header}; use alloy_eips::eip4844::{DATA_GAS_PER_BLOB, MAX_DATA_GAS_PER_BLOCK}; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_consensus::ConsensusError; -use reth_primitives::{ - BlockBody, EthereumHardfork, GotExpected, Header, SealedBlock, SealedHeader, -}; +use reth_primitives::{BlockBody, EthereumHardfork, GotExpected, SealedBlock, SealedHeader}; use revm_primitives::calc_excess_blob_gas; /// Gas used needs to be less than gas limit. Gas used is going to be checked after execution. diff --git a/crates/consensus/consensus/Cargo.toml b/crates/consensus/consensus/Cargo.toml index 2faf3f2ac71..d120d268bd9 100644 --- a/crates/consensus/consensus/Cargo.toml +++ b/crates/consensus/consensus/Cargo.toml @@ -17,6 +17,7 @@ reth-primitives.workspace = true # ethereum alloy-eips.workspace = true alloy-primitives.workspace = true +alloy-consensus.workspace = true # misc auto_impl.workspace = true @@ -25,10 +26,9 @@ derive_more.workspace = true [features] default = ["std"] std = [ - "reth-primitives/std", - "alloy-primitives/std", - "alloy-eips/std" -] -test-utils = [ - "reth-primitives/test-utils" + "reth-primitives/std", + "alloy-primitives/std", + "alloy-eips/std", + "alloy-consensus/std", ] +test-utils = ["reth-primitives/test-utils"] diff --git a/crates/consensus/consensus/src/lib.rs b/crates/consensus/consensus/src/lib.rs index 91ec42608c1..a8f0a01f22b 100644 --- a/crates/consensus/consensus/src/lib.rs +++ b/crates/consensus/consensus/src/lib.rs @@ -12,11 +12,12 @@ extern crate alloc; use alloc::{fmt::Debug, vec::Vec}; +use alloy_consensus::Header; use alloy_eips::eip7685::Requests; use alloy_primitives::{BlockHash, BlockNumber, Bloom, B256, U256}; use reth_primitives::{ constants::MINIMUM_GAS_LIMIT, BlockBody, BlockWithSenders, GotExpected, GotExpectedBoxed, - Header, InvalidTransactionError, Receipt, SealedBlock, SealedHeader, + InvalidTransactionError, Receipt, SealedBlock, SealedHeader, }; /// A consensus implementation that does nothing. diff --git a/crates/engine/invalid-block-hooks/Cargo.toml b/crates/engine/invalid-block-hooks/Cargo.toml index b33b8c00a1c..462f0762a9e 100644 --- a/crates/engine/invalid-block-hooks/Cargo.toml +++ b/crates/engine/invalid-block-hooks/Cargo.toml @@ -26,6 +26,7 @@ reth-trie = { workspace = true, features = ["serde"] } alloy-primitives.workspace = true alloy-rlp.workspace = true alloy-rpc-types-debug.workspace = true +alloy-consensus.workspace = true # async futures.workspace = true diff --git a/crates/engine/invalid-block-hooks/src/witness.rs b/crates/engine/invalid-block-hooks/src/witness.rs index 416c4adb40f..4e92411ea12 100644 --- a/crates/engine/invalid-block-hooks/src/witness.rs +++ b/crates/engine/invalid-block-hooks/src/witness.rs @@ -1,5 +1,6 @@ use std::{collections::HashMap, fmt::Debug, fs::File, io::Write, path::PathBuf}; +use alloy_consensus::Header; use alloy_primitives::{keccak256, B256, U256}; use alloy_rpc_types_debug::ExecutionWitness; use eyre::OptionExt; @@ -9,7 +10,7 @@ use reth_engine_primitives::InvalidBlockHook; use reth_evm::{ state_change::post_block_balance_increments, system_calls::SystemCaller, ConfigureEvm, }; -use reth_primitives::{Header, Receipt, SealedBlockWithSenders, SealedHeader}; +use reth_primitives::{Receipt, SealedBlockWithSenders, SealedHeader}; use reth_provider::{BlockExecutionOutput, ChainSpecProvider, StateProviderFactory}; use reth_revm::{ database::StateProviderDatabase, diff --git a/crates/engine/tree/Cargo.toml b/crates/engine/tree/Cargo.toml index 2ce18aa0e7d..fb259d08560 100644 --- a/crates/engine/tree/Cargo.toml +++ b/crates/engine/tree/Cargo.toml @@ -38,6 +38,7 @@ reth-trie-parallel.workspace = true alloy-primitives.workspace = true alloy-eips.workspace = true alloy-rpc-types-engine.workspace = true +alloy-consensus.workspace = true revm-primitives.workspace = true @@ -83,22 +84,22 @@ assert_matches.workspace = true [features] test-utils = [ - "reth-db/test-utils", - "reth-chain-state/test-utils", - "reth-network-p2p/test-utils", - "reth-prune-types", - "reth-stages/test-utils", - "reth-static-file", - "reth-tracing", - "reth-blockchain-tree/test-utils", - "reth-chainspec/test-utils", - "reth-consensus/test-utils", - "reth-evm/test-utils", - "reth-payload-builder/test-utils", - "reth-primitives/test-utils", - "reth-revm/test-utils", - "reth-stages-api/test-utils", - "reth-provider/test-utils", - "reth-trie/test-utils", - "reth-prune-types?/test-utils" + "reth-db/test-utils", + "reth-chain-state/test-utils", + "reth-network-p2p/test-utils", + "reth-prune-types", + "reth-stages/test-utils", + "reth-static-file", + "reth-tracing", + "reth-blockchain-tree/test-utils", + "reth-chainspec/test-utils", + "reth-consensus/test-utils", + "reth-evm/test-utils", + "reth-payload-builder/test-utils", + "reth-primitives/test-utils", + "reth-revm/test-utils", + "reth-stages-api/test-utils", + "reth-provider/test-utils", + "reth-trie/test-utils", + "reth-prune-types?/test-utils", ] diff --git a/crates/engine/tree/src/backfill.rs b/crates/engine/tree/src/backfill.rs index c267203d851..2ed0e758d50 100644 --- a/crates/engine/tree/src/backfill.rs +++ b/crates/engine/tree/src/backfill.rs @@ -230,12 +230,13 @@ impl PipelineState { mod tests { use super::*; use crate::test_utils::{insert_headers_into_client, TestPipelineBuilder}; + use alloy_consensus::Header; use alloy_primitives::{BlockNumber, B256}; use assert_matches::assert_matches; use futures::poll; use reth_chainspec::{ChainSpecBuilder, MAINNET}; use reth_network_p2p::test_utils::TestFullBlockClient; - use reth_primitives::{Header, SealedHeader}; + use reth_primitives::SealedHeader; use reth_provider::test_utils::MockNodeTypesWithDB; use reth_stages::ExecOutput; use reth_stages_api::StageCheckpoint; diff --git a/crates/engine/tree/src/download.rs b/crates/engine/tree/src/download.rs index cb43be3c4de..8a7ea583f0f 100644 --- a/crates/engine/tree/src/download.rs +++ b/crates/engine/tree/src/download.rs @@ -309,11 +309,12 @@ impl BlockDownloader for NoopBlockDownloader { mod tests { use super::*; use crate::test_utils::insert_headers_into_client; + use alloy_consensus::Header; use assert_matches::assert_matches; use reth_beacon_consensus::EthBeaconConsensus; use reth_chainspec::{ChainSpecBuilder, MAINNET}; use reth_network_p2p::test_utils::TestFullBlockClient; - use reth_primitives::{Header, SealedHeader}; + use reth_primitives::SealedHeader; use std::{future::poll_fn, sync::Arc}; struct TestHarness { diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index 755ee1106a6..adc9230af34 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -4,6 +4,7 @@ use crate::{ engine::{DownloadRequest, EngineApiEvent, FromEngine}, persistence::PersistenceHandle, }; +use alloy_consensus::Header; use alloy_eips::BlockNumHash; use alloy_primitives::{ map::{HashMap, HashSet}, @@ -32,9 +33,7 @@ use reth_evm::execute::BlockExecutorProvider; use reth_payload_builder::PayloadBuilderHandle; use reth_payload_primitives::{PayloadAttributes, PayloadBuilder, PayloadBuilderAttributes}; use reth_payload_validator::ExecutionPayloadValidator; -use reth_primitives::{ - Block, GotExpected, Header, SealedBlock, SealedBlockWithSenders, SealedHeader, -}; +use reth_primitives::{Block, GotExpected, SealedBlock, SealedBlockWithSenders, SealedHeader}; use reth_provider::{ providers::ConsistentDbView, BlockReader, DatabaseProviderFactory, ExecutionOutcome, ProviderError, StateProviderBox, StateProviderFactory, StateReader, StateRootProvider, diff --git a/crates/engine/util/src/reorg.rs b/crates/engine/util/src/reorg.rs index 169b6f5ede7..0a4dd8d496f 100644 --- a/crates/engine/util/src/reorg.rs +++ b/crates/engine/util/src/reorg.rs @@ -1,6 +1,6 @@ //! Stream wrapper that simulates reorgs. -use alloy_consensus::Transaction; +use alloy_consensus::{Header, Transaction}; use alloy_primitives::U256; use alloy_rpc_types_engine::{ CancunPayloadFields, ExecutionPayload, ExecutionPayloadSidecar, ForkchoiceState, PayloadStatus, @@ -16,7 +16,7 @@ use reth_evm::{ ConfigureEvm, }; use reth_payload_validator::ExecutionPayloadValidator; -use reth_primitives::{proofs, Block, BlockBody, Header, Receipt, Receipts}; +use reth_primitives::{proofs, Block, BlockBody, Receipt, Receipts}; use reth_provider::{BlockReader, ExecutionOutcome, ProviderError, StateProviderFactory}; use reth_revm::{ database::StateProviderDatabase, diff --git a/crates/ethereum/consensus/src/lib.rs b/crates/ethereum/consensus/src/lib.rs index 3dab9849f6c..3dc7a02af8b 100644 --- a/crates/ethereum/consensus/src/lib.rs +++ b/crates/ethereum/consensus/src/lib.rs @@ -8,7 +8,7 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -use alloy_consensus::EMPTY_OMMER_ROOT_HASH; +use alloy_consensus::{Header, EMPTY_OMMER_ROOT_HASH}; use alloy_primitives::U256; use reth_chainspec::{EthChainSpec, EthereumHardfork, EthereumHardforks}; use reth_consensus::{Consensus, ConsensusError, PostExecutionInput}; @@ -19,7 +19,7 @@ use reth_consensus_common::validation::{ validate_header_base_fee, validate_header_extradata, validate_header_gas, }; use reth_primitives::{ - constants::MINIMUM_GAS_LIMIT, BlockBody, BlockWithSenders, Header, SealedBlock, SealedHeader, + constants::MINIMUM_GAS_LIMIT, BlockBody, BlockWithSenders, SealedBlock, SealedHeader, }; use std::{fmt::Debug, sync::Arc, time::SystemTime}; diff --git a/crates/ethereum/evm/src/lib.rs b/crates/ethereum/evm/src/lib.rs index 1c340c0927b..11e4acd4bfc 100644 --- a/crates/ethereum/evm/src/lib.rs +++ b/crates/ethereum/evm/src/lib.rs @@ -20,10 +20,11 @@ extern crate alloc; use core::convert::Infallible; use alloc::{sync::Arc, vec::Vec}; +use alloy_consensus::Header; use alloy_primitives::{Address, Bytes, TxKind, U256}; use reth_chainspec::{ChainSpec, Head}; use reth_evm::{ConfigureEvm, ConfigureEvmEnv, NextBlockEnvAttributes}; -use reth_primitives::{transaction::FillTxEnv, Header, TransactionSigned}; +use reth_primitives::{transaction::FillTxEnv, TransactionSigned}; use revm_primitives::{ AnalysisKind, BlobExcessGasAndPrice, BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, Env, SpecId, TxEnv, }; @@ -195,15 +196,12 @@ impl ConfigureEvm for EthEvmConfig { #[cfg(test)] mod tests { use super::*; - use alloy_consensus::constants::KECCAK_EMPTY; + use alloy_consensus::{constants::KECCAK_EMPTY, Header}; use alloy_genesis::Genesis; use alloy_primitives::{B256, U256}; use reth_chainspec::{Chain, ChainSpec, MAINNET}; use reth_evm::execute::ProviderError; - use reth_primitives::{ - revm_primitives::{BlockEnv, CfgEnv, SpecId}, - Header, - }; + use reth_primitives::revm_primitives::{BlockEnv, CfgEnv, SpecId}; use reth_revm::{ db::{CacheDB, EmptyDBTyped}, inspectors::NoOpInspector, diff --git a/crates/ethereum/node/Cargo.toml b/crates/ethereum/node/Cargo.toml index 69bbeeb5b43..6ecd5437bfb 100644 --- a/crates/ethereum/node/Cargo.toml +++ b/crates/ethereum/node/Cargo.toml @@ -32,6 +32,8 @@ reth-primitives.workspace = true reth-revm = { workspace = true, features = ["std"] } reth-trie-db.workspace = true +alloy-consensus.workspace = true + # revm with required ethereum features revm = { workspace = true, features = ["secp256k1", "blst", "c-kzg"] } @@ -63,17 +65,17 @@ alloy-rpc-types-beacon.workspace = true [features] default = [] test-utils = [ - "reth-node-builder/test-utils", - "reth-chainspec/test-utils", - "reth-consensus/test-utils", - "reth-network/test-utils", - "reth-payload-builder/test-utils", - "reth-primitives/test-utils", - "reth-revm/test-utils", - "reth-db/test-utils", - "reth-provider/test-utils", - "reth-transaction-pool/test-utils", - "reth-trie-db/test-utils", - "revm/test-utils", - "reth-evm/test-utils" + "reth-node-builder/test-utils", + "reth-chainspec/test-utils", + "reth-consensus/test-utils", + "reth-network/test-utils", + "reth-payload-builder/test-utils", + "reth-primitives/test-utils", + "reth-revm/test-utils", + "reth-db/test-utils", + "reth-provider/test-utils", + "reth-transaction-pool/test-utils", + "reth-trie-db/test-utils", + "revm/test-utils", + "reth-evm/test-utils", ] diff --git a/crates/ethereum/node/src/node.rs b/crates/ethereum/node/src/node.rs index b37d0227a78..5265329f19a 100644 --- a/crates/ethereum/node/src/node.rs +++ b/crates/ethereum/node/src/node.rs @@ -2,6 +2,7 @@ use std::sync::Arc; +use alloy_consensus::Header; use reth_basic_payload_builder::{BasicPayloadJobGenerator, BasicPayloadJobGeneratorConfig}; use reth_beacon_consensus::EthBeaconConsensus; use reth_chainspec::ChainSpec; @@ -25,7 +26,7 @@ use reth_node_builder::{ BuilderContext, Node, NodeAdapter, NodeComponentsBuilder, PayloadBuilderConfig, PayloadTypes, }; use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService}; -use reth_primitives::{Block, Header, Receipt, TransactionSigned, TxType}; +use reth_primitives::{Block, Receipt, TransactionSigned, TxType}; use reth_provider::CanonStateSubscriptions; use reth_rpc::EthApi; use reth_tracing::tracing::{debug, info}; diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index 87ceb4200b1..c94cd8bb728 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -9,7 +9,7 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![allow(clippy::useless_let_if_seq)] -use alloy_consensus::EMPTY_OMMER_ROOT_HASH; +use alloy_consensus::{Header, EMPTY_OMMER_ROOT_HASH}; use alloy_eips::{eip4844::MAX_DATA_GAS_PER_BLOCK, eip7685::Requests, merge::BEACON_NONCE}; use alloy_primitives::U256; use reth_basic_payload_builder::{ @@ -27,7 +27,7 @@ use reth_payload_primitives::{PayloadBuilderAttributes, PayloadBuilderError}; use reth_primitives::{ proofs::{self}, revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg}, - Block, BlockBody, EthereumHardforks, Header, Receipt, + Block, BlockBody, EthereumHardforks, Receipt, }; use reth_provider::{ChainSpecProvider, StateProviderFactory}; use reth_revm::database::StateProviderDatabase; diff --git a/crates/evm/src/provider.rs b/crates/evm/src/provider.rs index 84c38db0dc5..0d4f45c4d9d 100644 --- a/crates/evm/src/provider.rs +++ b/crates/evm/src/provider.rs @@ -1,8 +1,8 @@ //! Provider trait for populating the EVM environment. use crate::ConfigureEvmEnv; +use alloy_consensus::Header; use alloy_eips::BlockHashOrNumber; -use reth_primitives::Header; use reth_storage_errors::provider::ProviderResult; use revm::primitives::{BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, SpecId}; diff --git a/crates/evm/src/system_calls/eip2935.rs b/crates/evm/src/system_calls/eip2935.rs index edb71c8b4e0..4848feb7281 100644 --- a/crates/evm/src/system_calls/eip2935.rs +++ b/crates/evm/src/system_calls/eip2935.rs @@ -4,10 +4,10 @@ use alloc::{boxed::Box, string::ToString}; use alloy_eips::eip2935::HISTORY_STORAGE_ADDRESS; use crate::ConfigureEvm; +use alloy_consensus::Header; use alloy_primitives::B256; use reth_chainspec::EthereumHardforks; use reth_execution_errors::{BlockExecutionError, BlockValidationError}; -use reth_primitives::Header; use revm::{interpreter::Host, Database, Evm}; use revm_primitives::ResultAndState; diff --git a/crates/evm/src/system_calls/eip4788.rs b/crates/evm/src/system_calls/eip4788.rs index bc535809680..2ad02c26eb9 100644 --- a/crates/evm/src/system_calls/eip4788.rs +++ b/crates/evm/src/system_calls/eip4788.rs @@ -2,11 +2,11 @@ use alloc::{boxed::Box, string::ToString}; use crate::ConfigureEvm; +use alloy_consensus::Header; use alloy_eips::eip4788::BEACON_ROOTS_ADDRESS; use alloy_primitives::B256; use reth_chainspec::EthereumHardforks; use reth_execution_errors::{BlockExecutionError, BlockValidationError}; -use reth_primitives::Header; use revm::{interpreter::Host, Database, Evm}; use revm_primitives::ResultAndState; diff --git a/crates/evm/src/system_calls/eip7002.rs b/crates/evm/src/system_calls/eip7002.rs index 5e36f2bdeb9..f20b7a54c08 100644 --- a/crates/evm/src/system_calls/eip7002.rs +++ b/crates/evm/src/system_calls/eip7002.rs @@ -1,10 +1,10 @@ //! [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002) system call implementation. use crate::ConfigureEvm; use alloc::{boxed::Box, format}; +use alloy_consensus::Header; use alloy_eips::eip7002::WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS; use alloy_primitives::Bytes; use reth_execution_errors::{BlockExecutionError, BlockValidationError}; -use reth_primitives::Header; use revm::{interpreter::Host, Database, Evm}; use revm_primitives::{ExecutionResult, ResultAndState}; diff --git a/crates/evm/src/system_calls/eip7251.rs b/crates/evm/src/system_calls/eip7251.rs index 7a55c7a5aea..112f724df76 100644 --- a/crates/evm/src/system_calls/eip7251.rs +++ b/crates/evm/src/system_calls/eip7251.rs @@ -1,10 +1,10 @@ //! [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251) system call implementation. use crate::ConfigureEvm; use alloc::{boxed::Box, format}; +use alloy_consensus::Header; use alloy_eips::eip7251::CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS; use alloy_primitives::Bytes; use reth_execution_errors::{BlockExecutionError, BlockValidationError}; -use reth_primitives::Header; use revm::{interpreter::Host, Database, Evm}; use revm_primitives::{ExecutionResult, ResultAndState}; diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index 7fdb31d967d..47fd59d735f 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -2,12 +2,13 @@ use crate::ConfigureEvm; use alloc::{boxed::Box, sync::Arc, vec}; +use alloy_consensus::Header; use alloy_eips::eip7685::Requests; use alloy_primitives::Bytes; use core::fmt::Display; use reth_chainspec::EthereumHardforks; use reth_execution_errors::BlockExecutionError; -use reth_primitives::{Block, Header}; +use reth_primitives::Block; use revm::{Database, DatabaseCommit, Evm}; use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ResultAndState, B256}; diff --git a/crates/exex/exex/src/backfill/test_utils.rs b/crates/exex/exex/src/backfill/test_utils.rs index 0a8bde24245..a1e88c7f428 100644 --- a/crates/exex/exex/src/backfill/test_utils.rs +++ b/crates/exex/exex/src/backfill/test_utils.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use alloy_consensus::{constants::ETH_TO_WEI, TxEip2930}; +use alloy_consensus::{constants::ETH_TO_WEI, Header, TxEip2930}; use alloy_genesis::{Genesis, GenesisAccount}; use alloy_primitives::{b256, Address, TxKind, U256}; use eyre::OptionExt; @@ -10,7 +10,7 @@ use reth_evm::execute::{ }; use reth_evm_ethereum::execute::EthExecutorProvider; use reth_primitives::{ - Block, BlockBody, BlockWithSenders, Header, Receipt, SealedBlockWithSenders, Transaction, + Block, BlockBody, BlockWithSenders, Receipt, SealedBlockWithSenders, Transaction, }; use reth_provider::{ providers::ProviderNodeTypes, BlockWriter as _, ExecutionOutcome, LatestStateProviderRef, diff --git a/crates/net/downloaders/src/bodies/bodies.rs b/crates/net/downloaders/src/bodies/bodies.rs index 02a36c8e8cd..bebc51ad772 100644 --- a/crates/net/downloaders/src/bodies/bodies.rs +++ b/crates/net/downloaders/src/bodies/bodies.rs @@ -37,7 +37,7 @@ pub struct BodiesDownloader { /// The bodies client client: Arc, /// The consensus client - consensus: Arc>, + consensus: Arc>, /// The database handle provider: Provider, /// The maximum number of non-empty blocks per one request @@ -564,7 +564,7 @@ impl BodiesDownloaderBuilder { pub fn build( self, client: B, - consensus: Arc>, + consensus: Arc>, provider: Provider, ) -> BodiesDownloader where diff --git a/crates/net/downloaders/src/bodies/queue.rs b/crates/net/downloaders/src/bodies/queue.rs index 54404d0da38..aa6ec9e4af0 100644 --- a/crates/net/downloaders/src/bodies/queue.rs +++ b/crates/net/downloaders/src/bodies/queue.rs @@ -58,7 +58,7 @@ where pub(crate) fn push_new_request( &mut self, client: Arc, - consensus: Arc>, + consensus: Arc>, request: Vec, ) { // Set last max requested block number diff --git a/crates/net/downloaders/src/bodies/request.rs b/crates/net/downloaders/src/bodies/request.rs index 7b99c81d89e..66287624f89 100644 --- a/crates/net/downloaders/src/bodies/request.rs +++ b/crates/net/downloaders/src/bodies/request.rs @@ -27,7 +27,7 @@ use std::{ /// It then proceeds to verify the downloaded bodies. In case of an validation error, /// the future will start over. /// -/// The future will filter out any empty headers (see [`reth_primitives::Header::is_empty`]) from +/// The future will filter out any empty headers (see [`alloy_consensus::Header::is_empty`]) from /// the request. If [`BodiesRequestFuture`] was initialized with all empty headers, no request will /// be dispatched and they will be immediately returned upon polling. /// @@ -39,7 +39,7 @@ use std::{ /// and eventually disconnected. pub(crate) struct BodiesRequestFuture { client: Arc, - consensus: Arc>, + consensus: Arc>, metrics: BodyDownloaderMetrics, /// Metrics for individual responses. This can be used to observe how the size (in bytes) of /// responses change while bodies are being downloaded. @@ -60,7 +60,7 @@ where /// Returns an empty future. Use [`BodiesRequestFuture::with_headers`] to set the request. pub(crate) fn new( client: Arc, - consensus: Arc>, + consensus: Arc>, metrics: BodyDownloaderMetrics, ) -> Self { Self { diff --git a/crates/net/downloaders/src/bodies/task.rs b/crates/net/downloaders/src/bodies/task.rs index 2caf3199188..de1638f3e66 100644 --- a/crates/net/downloaders/src/bodies/task.rs +++ b/crates/net/downloaders/src/bodies/task.rs @@ -54,7 +54,7 @@ impl TaskDownloader { /// Provider: HeaderProvider + Unpin + 'static, /// >( /// client: Arc, - /// consensus: Arc>, + /// consensus: Arc>, /// provider: Provider, /// ) { /// let downloader = BodiesDownloaderBuilder::default().build(client, consensus, provider); diff --git a/crates/net/downloaders/src/file_client.rs b/crates/net/downloaders/src/file_client.rs index f0104032aa0..486d4a05127 100644 --- a/crates/net/downloaders/src/file_client.rs +++ b/crates/net/downloaders/src/file_client.rs @@ -1,5 +1,6 @@ use std::{collections::HashMap, io, path::Path}; +use alloy_consensus::Header; use alloy_eips::BlockHashOrNumber; use alloy_primitives::{BlockHash, BlockNumber, B256}; use futures::Future; @@ -12,7 +13,7 @@ use reth_network_p2p::{ priority::Priority, }; use reth_network_peers::PeerId; -use reth_primitives::{BlockBody, Header, SealedHeader}; +use reth_primitives::{BlockBody, SealedHeader}; use thiserror::Error; use tokio::{fs::File, io::AsyncReadExt}; use tokio_stream::StreamExt; diff --git a/crates/net/eth-wire-types/Cargo.toml b/crates/net/eth-wire-types/Cargo.toml index 9ce712bf87a..f9759ffc25a 100644 --- a/crates/net/eth-wire-types/Cargo.toml +++ b/crates/net/eth-wire-types/Cargo.toml @@ -23,6 +23,7 @@ alloy-chains = { workspace = true, features = ["rlp"] } alloy-eips.workspace = true alloy-primitives.workspace = true alloy-rlp = { workspace = true, features = ["derive"] } +alloy-consensus.workspace = true bytes.workspace = true derive_more.workspace = true @@ -42,27 +43,26 @@ arbitrary = { workspace = true, features = ["derive"] } proptest.workspace = true proptest-arbitrary-interop.workspace = true rand.workspace = true -alloy-consensus.workspace = true [features] arbitrary = [ - "reth-primitives/arbitrary", - "alloy-chains/arbitrary", - "dep:arbitrary", - "dep:proptest", - "dep:proptest-arbitrary-interop", - "reth-chainspec/arbitrary", - "alloy-consensus/arbitrary", - "alloy-eips/arbitrary", - "alloy-primitives/arbitrary", + "reth-primitives/arbitrary", + "alloy-chains/arbitrary", + "dep:arbitrary", + "dep:proptest", + "dep:proptest-arbitrary-interop", + "reth-chainspec/arbitrary", + "alloy-consensus/arbitrary", + "alloy-eips/arbitrary", + "alloy-primitives/arbitrary", "reth-primitives-traits/arbitrary", ] serde = [ - "dep:serde", - "alloy-chains/serde", - "alloy-consensus/serde", - "alloy-eips/serde", - "alloy-primitives/serde", - "bytes/serde", - "rand/serde" + "dep:serde", + "alloy-chains/serde", + "alloy-consensus/serde", + "alloy-eips/serde", + "alloy-primitives/serde", + "bytes/serde", + "rand/serde", ] diff --git a/crates/net/eth-wire-types/src/blocks.rs b/crates/net/eth-wire-types/src/blocks.rs index a7835ae8641..1eb71082d81 100644 --- a/crates/net/eth-wire-types/src/blocks.rs +++ b/crates/net/eth-wire-types/src/blocks.rs @@ -41,12 +41,12 @@ pub struct GetBlockHeaders { #[derive(Clone, Debug, PartialEq, Eq, RlpEncodableWrapper, RlpDecodableWrapper, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] -pub struct BlockHeaders( +pub struct BlockHeaders( /// The requested headers. pub Vec, ); -generate_tests!(#[rlp, 10] BlockHeaders, EthBlockHeadersTests); +generate_tests!(#[rlp, 10] BlockHeaders, EthBlockHeadersTests); impl From> for BlockHeaders { fn from(headers: Vec) -> Self { @@ -94,11 +94,11 @@ mod tests { message::RequestPair, BlockBodies, BlockHeaders, GetBlockBodies, GetBlockHeaders, HeadersDirection, }; - use alloy_consensus::TxLegacy; + use alloy_consensus::{Header, TxLegacy}; use alloy_eips::BlockHashOrNumber; use alloy_primitives::{hex, PrimitiveSignature as Signature, TxKind, U256}; use alloy_rlp::{Decodable, Encodable}; - use reth_primitives::{BlockBody, Header, Transaction, TransactionSigned}; + use reth_primitives::{BlockBody, Transaction, TransactionSigned}; use std::str::FromStr; #[test] diff --git a/crates/net/eth-wire-types/src/header.rs b/crates/net/eth-wire-types/src/header.rs index 8c11bfa82bb..9fa3b150d9e 100644 --- a/crates/net/eth-wire-types/src/header.rs +++ b/crates/net/eth-wire-types/src/header.rs @@ -87,10 +87,9 @@ impl From for bool { #[cfg(test)] mod tests { use super::*; - use alloy_consensus::{EMPTY_OMMER_ROOT_HASH, EMPTY_ROOT_HASH}; + use alloy_consensus::{Header, EMPTY_OMMER_ROOT_HASH, EMPTY_ROOT_HASH}; use alloy_primitives::{address, b256, bloom, bytes, hex, Address, Bytes, B256, U256}; use alloy_rlp::{Decodable, Encodable}; - use reth_primitives::Header; use std::str::FromStr; // Test vector from: https://eips.ethereum.org/EIPS/eip-2481 diff --git a/crates/net/eth-wire-types/src/primitives.rs b/crates/net/eth-wire-types/src/primitives.rs index 15cfaaff0a2..eab36c3b6a7 100644 --- a/crates/net/eth-wire-types/src/primitives.rs +++ b/crates/net/eth-wire-types/src/primitives.rs @@ -78,7 +78,7 @@ pub trait NetworkPrimitives: pub struct EthNetworkPrimitives; impl NetworkPrimitives for EthNetworkPrimitives { - type BlockHeader = reth_primitives::Header; + type BlockHeader = alloy_consensus::Header; type BlockBody = reth_primitives::BlockBody; type Block = reth_primitives::Block; type BroadcastedTransaction = reth_primitives::TransactionSigned; diff --git a/crates/net/network/src/eth_requests.rs b/crates/net/network/src/eth_requests.rs index f0c355b174a..1f20be53967 100644 --- a/crates/net/network/src/eth_requests.rs +++ b/crates/net/network/src/eth_requests.rs @@ -7,6 +7,7 @@ use std::{ time::Duration, }; +use alloy_consensus::Header; use alloy_eips::BlockHashOrNumber; use alloy_rlp::Encodable; use futures::StreamExt; @@ -17,7 +18,7 @@ use reth_eth_wire::{ use reth_network_api::test_utils::PeersHandle; use reth_network_p2p::error::RequestResult; use reth_network_peers::PeerId; -use reth_primitives::{BlockBody, Header}; +use reth_primitives::BlockBody; use reth_storage_api::{BlockReader, HeaderProvider, ReceiptProvider}; use tokio::sync::{mpsc::Receiver, oneshot}; use tokio_stream::wrappers::ReceiverStream; diff --git a/crates/net/network/src/state.rs b/crates/net/network/src/state.rs index 3bafbf25856..c51f115c52f 100644 --- a/crates/net/network/src/state.rs +++ b/crates/net/network/src/state.rs @@ -563,12 +563,13 @@ mod tests { sync::{atomic::AtomicU64, Arc}, }; + use alloy_consensus::Header; use alloy_primitives::B256; use reth_eth_wire::{BlockBodies, Capabilities, Capability, EthVersion}; use reth_network_api::PeerRequestSender; use reth_network_p2p::{bodies::client::BodiesClient, error::RequestError}; use reth_network_peers::PeerId; - use reth_primitives::{BlockBody, Header}; + use reth_primitives::BlockBody; use reth_provider::test_utils::NoopProvider; use tokio::sync::mpsc; use tokio_stream::{wrappers::ReceiverStream, StreamExt}; diff --git a/crates/net/network/tests/it/requests.rs b/crates/net/network/tests/it/requests.rs index 58e46e3fb09..54e1f4e12b4 100644 --- a/crates/net/network/tests/it/requests.rs +++ b/crates/net/network/tests/it/requests.rs @@ -3,7 +3,7 @@ use std::sync::Arc; -use alloy_consensus::TxEip2930; +use alloy_consensus::{Header, TxEip2930}; use alloy_primitives::{Bytes, PrimitiveSignature as Signature, TxKind, U256}; use rand::Rng; use reth_eth_wire::HeadersDirection; @@ -16,7 +16,7 @@ use reth_network_p2p::{ bodies::client::BodiesClient, headers::client::{HeadersClient, HeadersRequest}, }; -use reth_primitives::{Block, Header, Transaction, TransactionSigned}; +use reth_primitives::{Block, Transaction, TransactionSigned}; use reth_provider::test_utils::MockEthProvider; /// Returns a new [`TransactionSigned`] with some random parameters diff --git a/crates/net/p2p/src/bodies/response.rs b/crates/net/p2p/src/bodies/response.rs index 8737647bd79..153d7d39d4e 100644 --- a/crates/net/p2p/src/bodies/response.rs +++ b/crates/net/p2p/src/bodies/response.rs @@ -6,7 +6,7 @@ use reth_primitives_traits::InMemorySize; #[derive(PartialEq, Eq, Debug, Clone)] pub enum BlockResponse { /// Full block response (with transactions or ommers) - Full(SealedBlock), + Full(SealedBlock), /// The empty block response Empty(SealedHeader), } diff --git a/crates/net/p2p/src/headers/client.rs b/crates/net/p2p/src/headers/client.rs index 585f2ab18a0..bb879784499 100644 --- a/crates/net/p2p/src/headers/client.rs +++ b/crates/net/p2p/src/headers/client.rs @@ -1,8 +1,8 @@ use crate::{download::DownloadClient, error::PeerRequestResult, priority::Priority}; +use alloy_consensus::Header; use alloy_eips::BlockHashOrNumber; use futures::{Future, FutureExt}; pub use reth_eth_wire_types::{BlockHeaders, HeadersDirection}; -use reth_primitives::Header; use std::{ fmt::Debug, pin::Pin, diff --git a/crates/net/p2p/src/lib.rs b/crates/net/p2p/src/lib.rs index 98d83c2d1a8..7dcb77671d4 100644 --- a/crates/net/p2p/src/lib.rs +++ b/crates/net/p2p/src/lib.rs @@ -55,11 +55,11 @@ impl BlockClient for T where T: HeadersClient + BodiesClient + Unpin + Clone /// The [`BlockClient`] providing Ethereum block parts. pub trait EthBlockClient: - BlockClient
+ BlockClient
{ } impl EthBlockClient for T where - T: BlockClient
+ T: BlockClient
{ } diff --git a/crates/net/p2p/src/test_utils/full_block.rs b/crates/net/p2p/src/test_utils/full_block.rs index 97d867531ad..ee65bcb3f07 100644 --- a/crates/net/p2p/src/test_utils/full_block.rs +++ b/crates/net/p2p/src/test_utils/full_block.rs @@ -5,12 +5,13 @@ use crate::{ headers::client::{HeadersClient, HeadersRequest}, priority::Priority, }; +use alloy_consensus::Header; use alloy_eips::{BlockHashOrNumber, BlockNumHash}; use alloy_primitives::B256; use parking_lot::Mutex; use reth_eth_wire_types::HeadersDirection; use reth_network_peers::{PeerId, WithPeerId}; -use reth_primitives::{BlockBody, Header, SealedBlock, SealedHeader}; +use reth_primitives::{BlockBody, SealedBlock, SealedHeader}; use std::{collections::HashMap, sync::Arc}; /// A headers+bodies client implementation that does nothing. diff --git a/crates/net/p2p/src/test_utils/headers.rs b/crates/net/p2p/src/test_utils/headers.rs index 8892a010b43..bc5262abef4 100644 --- a/crates/net/p2p/src/test_utils/headers.rs +++ b/crates/net/p2p/src/test_utils/headers.rs @@ -10,11 +10,12 @@ use crate::{ }, priority::Priority, }; +use alloy_consensus::Header; use futures::{Future, FutureExt, Stream, StreamExt}; use reth_consensus::{test_utils::TestConsensus, Consensus}; use reth_eth_wire_types::HeadersDirection; use reth_network_peers::{PeerId, WithPeerId}; -use reth_primitives::{Header, SealedHeader}; +use reth_primitives::SealedHeader; use std::{ fmt, pin::Pin, diff --git a/crates/node/api/Cargo.toml b/crates/node/api/Cargo.toml index b2bf001862e..a4cc0eb7eb6 100644 --- a/crates/node/api/Cargo.toml +++ b/crates/node/api/Cargo.toml @@ -22,9 +22,9 @@ reth-payload-primitives.workspace = true reth-tasks.workspace = true reth-network-api.workspace = true reth-node-types.workspace = true -reth-primitives.workspace = true reth-node-core.workspace = true alloy-rpc-types-engine.workspace = true +alloy-consensus.workspace = true -eyre.workspace = true \ No newline at end of file +eyre.workspace = true diff --git a/crates/node/api/src/node.rs b/crates/node/api/src/node.rs index 253145ea9eb..90b9e2999bf 100644 --- a/crates/node/api/src/node.rs +++ b/crates/node/api/src/node.rs @@ -1,6 +1,7 @@ //! Traits for configuring a node. use crate::ConfigureEvm; +use alloy_consensus::Header; use alloy_rpc_types_engine::JwtSecret; use reth_beacon_consensus::BeaconConsensusEngineHandle; use reth_consensus::Consensus; @@ -9,7 +10,6 @@ use reth_network_api::FullNetwork; use reth_node_core::node_config::NodeConfig; use reth_node_types::{NodeTypes, NodeTypesWithDB, NodeTypesWithEngine}; use reth_payload_primitives::PayloadBuilder; -use reth_primitives::Header; use reth_provider::FullProvider; use reth_tasks::TaskExecutor; use reth_transaction_pool::TransactionPool; diff --git a/crates/node/builder/Cargo.toml b/crates/node/builder/Cargo.toml index 4ef2b0728e0..09bdd8b2269 100644 --- a/crates/node/builder/Cargo.toml +++ b/crates/node/builder/Cargo.toml @@ -62,6 +62,7 @@ reth-transaction-pool.workspace = true ## ethereum alloy-primitives.workspace = true alloy-rpc-types = { workspace = true, features = ["engine"] } +alloy-consensus.workspace = true ## async futures.workspace = true @@ -96,20 +97,20 @@ tempfile.workspace = true [features] default = [] test-utils = [ - "reth-db/test-utils", - "reth-blockchain-tree/test-utils", - "reth-chain-state/test-utils", - "reth-chainspec/test-utils", - "reth-consensus/test-utils", - "reth-engine-tree/test-utils", - "reth-evm/test-utils", - "reth-downloaders/test-utils", - "reth-network/test-utils", - "reth-network-p2p/test-utils", - "reth-payload-builder/test-utils", - "reth-primitives/test-utils", - "reth-stages/test-utils", - "reth-db-api/test-utils", - "reth-provider/test-utils", - "reth-transaction-pool/test-utils" + "reth-db/test-utils", + "reth-blockchain-tree/test-utils", + "reth-chain-state/test-utils", + "reth-chainspec/test-utils", + "reth-consensus/test-utils", + "reth-engine-tree/test-utils", + "reth-evm/test-utils", + "reth-downloaders/test-utils", + "reth-network/test-utils", + "reth-network-p2p/test-utils", + "reth-payload-builder/test-utils", + "reth-primitives/test-utils", + "reth-stages/test-utils", + "reth-db-api/test-utils", + "reth-provider/test-utils", + "reth-transaction-pool/test-utils", ] diff --git a/crates/node/builder/src/components/builder.rs b/crates/node/builder/src/components/builder.rs index 41ce36858d8..95c0c764b5c 100644 --- a/crates/node/builder/src/components/builder.rs +++ b/crates/node/builder/src/components/builder.rs @@ -7,11 +7,11 @@ use crate::{ }, BuilderContext, ConfigureEvm, FullNodeTypes, }; +use alloy_consensus::Header; use reth_consensus::Consensus; use reth_evm::execute::BlockExecutorProvider; use reth_node_api::NodeTypesWithEngine; use reth_payload_builder::PayloadBuilderHandle; -use reth_primitives::Header; use reth_transaction_pool::TransactionPool; use std::{future::Future, marker::PhantomData}; diff --git a/crates/node/builder/src/components/execute.rs b/crates/node/builder/src/components/execute.rs index 90cff588f7c..4e8f63f412b 100644 --- a/crates/node/builder/src/components/execute.rs +++ b/crates/node/builder/src/components/execute.rs @@ -1,8 +1,8 @@ //! EVM component for the node builder. use crate::{BuilderContext, FullNodeTypes}; +use alloy_consensus::Header; use reth_evm::execute::BlockExecutorProvider; use reth_node_api::ConfigureEvm; -use reth_primitives::Header; use std::future::Future; /// A type that knows how to build the executor types. diff --git a/crates/node/builder/src/components/mod.rs b/crates/node/builder/src/components/mod.rs index 29b667d5409..1fe35e554d5 100644 --- a/crates/node/builder/src/components/mod.rs +++ b/crates/node/builder/src/components/mod.rs @@ -22,13 +22,13 @@ pub use payload::*; pub use pool::*; use crate::{ConfigureEvm, FullNodeTypes}; +use alloy_consensus::Header; use reth_consensus::Consensus; use reth_evm::execute::BlockExecutorProvider; use reth_network::NetworkHandle; use reth_network_api::FullNetwork; use reth_node_api::NodeTypesWithEngine; use reth_payload_builder::PayloadBuilderHandle; -use reth_primitives::Header; use reth_transaction_pool::TransactionPool; /// An abstraction over the components of a node, consisting of: diff --git a/crates/node/builder/src/launch/common.rs b/crates/node/builder/src/launch/common.rs index ec4912fdd86..f9106296323 100644 --- a/crates/node/builder/src/launch/common.rs +++ b/crates/node/builder/src/launch/common.rs @@ -760,7 +760,7 @@ where /// necessary pub async fn max_block(&self, client: C) -> eyre::Result> where - C: HeadersClient
, + C: HeadersClient
, { self.node_config().max_block(client, self.provider_factory().clone()).await } diff --git a/crates/node/builder/src/setup.rs b/crates/node/builder/src/setup.rs index d8405dad77f..db188402ca8 100644 --- a/crates/node/builder/src/setup.rs +++ b/crates/node/builder/src/setup.rs @@ -84,7 +84,7 @@ pub fn build_pipeline( ) -> eyre::Result> where N: ProviderNodeTypes, - H: HeaderDownloader
+ 'static, + H: HeaderDownloader
+ 'static, B: BodyDownloader + 'static, Executor: BlockExecutorProvider, { diff --git a/crates/optimism/chainspec/src/lib.rs b/crates/optimism/chainspec/src/lib.rs index c110c4b0821..d552d08f18c 100644 --- a/crates/optimism/chainspec/src/lib.rs +++ b/crates/optimism/chainspec/src/lib.rs @@ -19,6 +19,7 @@ mod op_sepolia; use alloc::{boxed::Box, vec, vec::Vec}; use alloy_chains::Chain; +use alloy_consensus::Header; use alloy_genesis::Genesis; use alloy_primitives::{Bytes, B256, U256}; pub use base::BASE_MAINNET; @@ -36,7 +37,6 @@ use reth_chainspec::{ use reth_ethereum_forks::{ChainHardforks, EthereumHardfork, ForkCondition, Hardfork}; use reth_network_peers::NodeRecord; use reth_optimism_forks::OpHardforks; -use reth_primitives_traits::Header; #[cfg(feature = "std")] pub(crate) use std::sync::LazyLock; diff --git a/crates/optimism/consensus/src/lib.rs b/crates/optimism/consensus/src/lib.rs index 476b259529e..72f67dcb450 100644 --- a/crates/optimism/consensus/src/lib.rs +++ b/crates/optimism/consensus/src/lib.rs @@ -9,7 +9,7 @@ // The `optimism` feature must be enabled to use this crate. #![cfg(feature = "optimism")] -use alloy_consensus::EMPTY_OMMER_ROOT_HASH; +use alloy_consensus::{Header, EMPTY_OMMER_ROOT_HASH}; use alloy_primitives::{B64, U256}; use reth_chainspec::EthereumHardforks; use reth_consensus::{Consensus, ConsensusError, PostExecutionInput}; @@ -21,9 +21,7 @@ use reth_consensus_common::validation::{ }; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_forks::OpHardforks; -use reth_primitives::{ - BlockBody, BlockWithSenders, GotExpected, Header, SealedBlock, SealedHeader, -}; +use reth_primitives::{BlockBody, BlockWithSenders, GotExpected, SealedBlock, SealedHeader}; use std::{sync::Arc, time::SystemTime}; mod proof; diff --git a/crates/optimism/evm/src/execute.rs b/crates/optimism/evm/src/execute.rs index 2b004e6eb9d..b4c2e16f593 100644 --- a/crates/optimism/evm/src/execute.rs +++ b/crates/optimism/evm/src/execute.rs @@ -2,7 +2,7 @@ use crate::{l1::ensure_create2_deployer, OpBlockExecutionError, OpEvmConfig}; use alloc::{boxed::Box, sync::Arc, vec::Vec}; -use alloy_consensus::Transaction as _; +use alloy_consensus::{Header, Transaction as _}; use alloy_eips::eip7685::Requests; use core::fmt::Display; use op_alloy_consensus::DepositTransaction; @@ -20,7 +20,7 @@ use reth_evm::{ use reth_optimism_chainspec::OpChainSpec; use reth_optimism_consensus::validate_block_post_execution; use reth_optimism_forks::OpHardfork; -use reth_primitives::{BlockWithSenders, Header, Receipt, TxType}; +use reth_primitives::{BlockWithSenders, Receipt, TxType}; use reth_revm::{Database, State}; use revm_primitives::{ db::DatabaseCommit, BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ResultAndState, U256, diff --git a/crates/optimism/evm/src/l1.rs b/crates/optimism/evm/src/l1.rs index 143399a5ab7..9d3e76fb442 100644 --- a/crates/optimism/evm/src/l1.rs +++ b/crates/optimism/evm/src/l1.rs @@ -304,8 +304,9 @@ mod tests { #[test] fn sanity_l1_block() { + use alloy_consensus::Header; use alloy_primitives::{hex_literal::hex, Bytes}; - use reth_primitives::{Header, TransactionSigned}; + use reth_primitives::TransactionSigned; let bytes = Bytes::from_static(&hex!("7ef9015aa044bae9d41b8380d781187b426c6fe43df5fb2fb57bd4466ef6a701e1f01e015694deaddeaddeaddeaddeaddeaddeaddeaddead000194420000000000000000000000000000000000001580808408f0d18001b90104015d8eb900000000000000000000000000000000000000000000000000000000008057650000000000000000000000000000000000000000000000000000000063d96d10000000000000000000000000000000000000000000000000000000000009f35273d89754a1e0387b89520d989d3be9c37c1f32495a88faf1ea05c61121ab0d1900000000000000000000000000000000000000000000000000000000000000010000000000000000000000002d679b567db6187c0c8323fa982cfb88b74dbcc7000000000000000000000000000000000000000000000000000000000000083400000000000000000000000000000000000000000000000000000000000f4240")); let l1_info_tx = TransactionSigned::decode_2718(&mut bytes.as_ref()).unwrap(); diff --git a/crates/optimism/evm/src/lib.rs b/crates/optimism/evm/src/lib.rs index cfa7dfa5849..dafb1676ebd 100644 --- a/crates/optimism/evm/src/lib.rs +++ b/crates/optimism/evm/src/lib.rs @@ -13,13 +13,14 @@ extern crate alloc; use alloc::{sync::Arc, vec::Vec}; +use alloy_consensus::Header; use alloy_primitives::{Address, U256}; use reth_evm::{ConfigureEvm, ConfigureEvmEnv, NextBlockEnvAttributes}; use reth_optimism_chainspec::{DecodeError, OpChainSpec}; use reth_primitives::{ revm_primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv}, transaction::FillTxEnv, - Head, Header, TransactionSigned, + Head, TransactionSigned, }; use reth_revm::{inspector_handle_register, Database, Evm, EvmBuilder, GetInspector}; @@ -200,7 +201,7 @@ impl ConfigureEvm for OpEvmConfig { #[cfg(test)] mod tests { use super::*; - use alloy_consensus::constants::KECCAK_EMPTY; + use alloy_consensus::{constants::KECCAK_EMPTY, Header}; use alloy_eips::eip7685::Requests; use alloy_genesis::Genesis; use alloy_primitives::{bytes, Address, LogData, B256, U256}; @@ -212,7 +213,7 @@ mod tests { use reth_optimism_chainspec::BASE_MAINNET; use reth_primitives::{ revm_primitives::{AccountInfo, BlockEnv, CfgEnv, SpecId}, - Account, Header, Log, Receipt, Receipts, SealedBlockWithSenders, TxType, + Account, Log, Receipt, Receipts, SealedBlockWithSenders, TxType, }; use reth_revm::{ diff --git a/crates/optimism/node/Cargo.toml b/crates/optimism/node/Cargo.toml index c1e23e3d571..fb8cc27787e 100644 --- a/crates/optimism/node/Cargo.toml +++ b/crates/optimism/node/Cargo.toml @@ -45,6 +45,7 @@ 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 clap.workspace = true @@ -76,42 +77,42 @@ futures.workspace = true [features] optimism = [ - "reth-primitives/optimism", - "reth-provider/optimism", - "reth-optimism-evm/optimism", - "reth-optimism-payload-builder/optimism", - "reth-beacon-consensus/optimism", - "revm/optimism", - "reth-optimism-rpc/optimism", - "reth-engine-local/optimism", - "reth-optimism-consensus/optimism", - "reth-db/optimism", - "reth-optimism-node/optimism" + "reth-primitives/optimism", + "reth-provider/optimism", + "reth-optimism-evm/optimism", + "reth-optimism-payload-builder/optimism", + "reth-beacon-consensus/optimism", + "revm/optimism", + "reth-optimism-rpc/optimism", + "reth-engine-local/optimism", + "reth-optimism-consensus/optimism", + "reth-db/optimism", + "reth-optimism-node/optimism", ] asm-keccak = [ - "reth-primitives/asm-keccak", - "reth/asm-keccak", - "alloy-primitives/asm-keccak", - "revm/asm-keccak", - "reth-optimism-node/asm-keccak" + "reth-primitives/asm-keccak", + "reth/asm-keccak", + "alloy-primitives/asm-keccak", + "revm/asm-keccak", + "reth-optimism-node/asm-keccak", ] test-utils = [ - "reth", - "reth-e2e-test-utils", - "alloy-genesis", - "tokio", - "reth-node-builder/test-utils", - "reth-chainspec/test-utils", - "reth-consensus/test-utils", - "reth-evm/test-utils", - "reth-network/test-utils", - "reth-payload-builder/test-utils", - "reth-primitives/test-utils", - "reth-revm/test-utils", - "reth-db/test-utils", - "reth-provider/test-utils", - "reth-transaction-pool/test-utils", - "reth-trie-db/test-utils", - "revm/test-utils", - "reth-optimism-node/test-utils" + "reth", + "reth-e2e-test-utils", + "alloy-genesis", + "tokio", + "reth-node-builder/test-utils", + "reth-chainspec/test-utils", + "reth-consensus/test-utils", + "reth-evm/test-utils", + "reth-network/test-utils", + "reth-payload-builder/test-utils", + "reth-primitives/test-utils", + "reth-revm/test-utils", + "reth-db/test-utils", + "reth-provider/test-utils", + "reth-transaction-pool/test-utils", + "reth-trie-db/test-utils", + "revm/test-utils", + "reth-optimism-node/test-utils", ] diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index efc8964ffab..0c2186c7268 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -2,6 +2,7 @@ use std::sync::Arc; +use alloy_consensus::Header; use reth_basic_payload_builder::{BasicPayloadJobGenerator, BasicPayloadJobGeneratorConfig}; use reth_chainspec::{EthChainSpec, Hardforks}; use reth_evm::{execute::BasicBlockExecutorProvider, ConfigureEvm}; @@ -24,7 +25,7 @@ use reth_optimism_evm::{OpEvmConfig, OpExecutionStrategyFactory}; use reth_optimism_payload_builder::builder::OpPayloadTransactions; use reth_optimism_rpc::OpEthApi; use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService}; -use reth_primitives::{Block, Header, Receipt, TransactionSigned, TxType}; +use reth_primitives::{Block, Receipt, TransactionSigned, TxType}; use reth_provider::CanonStateSubscriptions; use reth_tracing::tracing::{debug, info}; use reth_transaction_pool::{ diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index 47ef376b705..beb9a5c4ae2 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -2,7 +2,7 @@ use std::{fmt::Display, sync::Arc}; -use alloy_consensus::{Transaction, EMPTY_OMMER_ROOT_HASH}; +use alloy_consensus::{Header, Transaction, EMPTY_OMMER_ROOT_HASH}; use alloy_eips::merge::BEACON_NONCE; use alloy_primitives::{Address, Bytes, U256}; use alloy_rpc_types_engine::PayloadId; @@ -18,7 +18,7 @@ use reth_payload_primitives::{PayloadBuilderAttributes, PayloadBuilderError}; use reth_primitives::{ proofs, revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg}, - Block, BlockBody, Header, Receipt, SealedHeader, TransactionSigned, TxType, + Block, BlockBody, Receipt, SealedHeader, TransactionSigned, TxType, }; use reth_provider::{ProviderError, StateProviderFactory, StateRootProvider}; use reth_revm::database::StateProviderDatabase; diff --git a/crates/optimism/primitives/Cargo.toml b/crates/optimism/primitives/Cargo.toml index bc11c358504..a6f36732672 100644 --- a/crates/optimism/primitives/Cargo.toml +++ b/crates/optimism/primitives/Cargo.toml @@ -12,8 +12,6 @@ description = "OP primitive types" workspace = true [dependencies] -reth-primitives.workspace = true -reth-primitives-traits.workspace = true alloy-primitives.workspace = true alloy-consensus.workspace = true op-alloy-consensus.workspace = true diff --git a/crates/optimism/primitives/src/bedrock.rs b/crates/optimism/primitives/src/bedrock.rs index 7153ae3155c..204b34d3378 100644 --- a/crates/optimism/primitives/src/bedrock.rs +++ b/crates/optimism/primitives/src/bedrock.rs @@ -1,8 +1,7 @@ //! OP mainnet bedrock related data. -use alloy_consensus::{EMPTY_OMMER_ROOT_HASH, EMPTY_ROOT_HASH}; +use alloy_consensus::{Header, EMPTY_OMMER_ROOT_HASH, EMPTY_ROOT_HASH}; use alloy_primitives::{address, b256, bloom, bytes, B256, B64, U256}; -use reth_primitives::Header; /// Transaction 0x9ed8f713b2cc6439657db52dcd2fdb9cc944915428f3c6e2a7703e242b259cb9 in block 985, /// replayed in blocks: diff --git a/crates/optimism/rpc/src/eth/call.rs b/crates/optimism/rpc/src/eth/call.rs index 9ddf7b3855b..a76c25916f3 100644 --- a/crates/optimism/rpc/src/eth/call.rs +++ b/crates/optimism/rpc/src/eth/call.rs @@ -1,10 +1,8 @@ +use alloy_consensus::Header; use alloy_primitives::{Bytes, TxKind, U256}; use alloy_rpc_types_eth::transaction::TransactionRequest; use reth_evm::ConfigureEvm; -use reth_primitives::{ - revm_primitives::{BlockEnv, OptimismFields, TxEnv}, - Header, -}; +use reth_primitives::revm_primitives::{BlockEnv, OptimismFields, TxEnv}; use reth_rpc_eth_api::{ helpers::{Call, EthCall, LoadPendingBlock, LoadState, SpawnBlocking}, FromEthApiError, IntoEthApiError, RpcNodeCore, diff --git a/crates/optimism/rpc/src/eth/mod.rs b/crates/optimism/rpc/src/eth/mod.rs index 624602bba38..60af6542e28 100644 --- a/crates/optimism/rpc/src/eth/mod.rs +++ b/crates/optimism/rpc/src/eth/mod.rs @@ -11,6 +11,7 @@ pub use receipt::{OpReceiptBuilder, OpReceiptFieldsBuilder}; use std::{fmt, sync::Arc}; +use alloy_consensus::Header; use alloy_primitives::U256; use derive_more::Deref; use op_alloy_network::Optimism; @@ -18,7 +19,6 @@ use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_evm::ConfigureEvm; use reth_network_api::NetworkInfo; use reth_node_builder::EthApiBuilderCtx; -use reth_primitives::Header; use reth_provider::{ BlockNumReader, BlockReaderIdExt, CanonStateSubscriptions, ChainSpecProvider, EvmEnvProvider, StageCheckpointReader, StateProviderFactory, diff --git a/crates/optimism/rpc/src/eth/pending_block.rs b/crates/optimism/rpc/src/eth/pending_block.rs index c90b3f7b794..8356d72dbdc 100644 --- a/crates/optimism/rpc/src/eth/pending_block.rs +++ b/crates/optimism/rpc/src/eth/pending_block.rs @@ -1,11 +1,12 @@ //! Loads OP pending block for a RPC response. +use alloy_consensus::Header; use alloy_eips::BlockNumberOrTag; use alloy_primitives::{BlockNumber, B256}; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_evm::ConfigureEvm; use reth_optimism_consensus::calculate_receipt_root_no_memo_optimism; -use reth_primitives::{revm_primitives::BlockEnv, Header, Receipt, SealedBlockWithSenders}; +use reth_primitives::{revm_primitives::BlockEnv, Receipt, SealedBlockWithSenders}; use reth_provider::{ BlockReader, BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, ExecutionOutcome, ReceiptProvider, StateProviderFactory, diff --git a/crates/payload/builder/Cargo.toml b/crates/payload/builder/Cargo.toml index 7a536cdbcfa..8b2fef7b878 100644 --- a/crates/payload/builder/Cargo.toml +++ b/crates/payload/builder/Cargo.toml @@ -39,11 +39,12 @@ tracing.workspace = true reth-primitives.workspace = true alloy-primitives.workspace = true revm.workspace = true +alloy-consensus.workspace = true [features] test-utils = [ - "alloy-primitives", - "reth-chain-state/test-utils", - "reth-primitives/test-utils", - "revm/test-utils" + "alloy-primitives", + "reth-chain-state/test-utils", + "reth-primitives/test-utils", + "revm/test-utils", ] diff --git a/crates/payload/builder/src/lib.rs b/crates/payload/builder/src/lib.rs index 57a040a4bb4..da44072c99d 100644 --- a/crates/payload/builder/src/lib.rs +++ b/crates/payload/builder/src/lib.rs @@ -28,9 +28,10 @@ //! use std::pin::Pin; //! use std::sync::Arc; //! use std::task::{Context, Poll}; +//! use alloy_consensus::Header; //! use alloy_primitives::U256; //! use reth_payload_builder::{EthBuiltPayload, PayloadBuilderError, KeepPayloadJobAlive, EthPayloadBuilderAttributes, PayloadJob, PayloadJobGenerator, PayloadKind}; -//! use reth_primitives::{Block, Header}; +//! use reth_primitives::Block; //! //! /// The generator type that creates new jobs that builds empty blocks. //! pub struct EmptyBlockPayloadJobGenerator; diff --git a/crates/primitives-traits/src/header/mod.rs b/crates/primitives-traits/src/header/mod.rs index fa9c3324535..760abf33720 100644 --- a/crates/primitives-traits/src/header/mod.rs +++ b/crates/primitives-traits/src/header/mod.rs @@ -7,8 +7,7 @@ pub use error::HeaderError; #[cfg(any(test, feature = "test-utils", feature = "arbitrary"))] pub mod test_utils; -pub use alloy_consensus::Header; - +use alloy_consensus::Header; use alloy_primitives::{Address, BlockNumber, B256, U256}; /// Bincode-compatible header type serde implementations. diff --git a/crates/primitives-traits/src/header/test_utils.rs b/crates/primitives-traits/src/header/test_utils.rs index c5f6e86b9db..0e79f6cb462 100644 --- a/crates/primitives-traits/src/header/test_utils.rs +++ b/crates/primitives-traits/src/header/test_utils.rs @@ -1,6 +1,6 @@ //! Test utilities to generate random valid headers. -use crate::Header; +use alloy_consensus::Header; use alloy_primitives::B256; use proptest::{arbitrary::any, prop_compose}; use proptest_arbitrary_interop::arb; diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index ab3985158d8..b8f0aa4c8a8 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -59,7 +59,7 @@ pub use tx_type::{FullTxType, TxType}; pub mod header; #[cfg(any(test, feature = "arbitrary", feature = "test-utils"))] pub use header::test_utils; -pub use header::{Header, HeaderError, SealedHeader}; +pub use header::{HeaderError, SealedHeader}; /// Bincode-compatible serde implementations for common abstracted types in Reth. /// diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index 3ce4947ccc2..703f9d33169 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -1,5 +1,6 @@ -use crate::{GotExpected, Header, SealedHeader, TransactionSigned, TransactionSignedEcRecovered}; +use crate::{GotExpected, SealedHeader, TransactionSigned, TransactionSignedEcRecovered}; use alloc::vec::Vec; +use alloy_consensus::Header; use alloy_eips::{eip2718::Encodable2718, eip4895::Withdrawals}; use alloy_primitives::{Address, Bytes, B256}; use alloy_rlp::{Decodable, Encodable, RlpDecodable, RlpEncodable}; diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index f44e1ee6a09..534b525f086 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -41,8 +41,8 @@ pub use receipt::{ gas_spent_by_transactions, Receipt, ReceiptWithBloom, ReceiptWithBloomRef, Receipts, }; pub use reth_primitives_traits::{ - logs_bloom, Account, Bytecode, GotExpected, GotExpectedBoxed, Header, HeaderError, Log, - LogData, SealedHeader, StorageEntry, + logs_bloom, Account, Bytecode, GotExpected, GotExpectedBoxed, HeaderError, Log, LogData, + SealedHeader, StorageEntry, }; pub use static_file::StaticFileSegment; diff --git a/crates/primitives/src/proofs.rs b/crates/primitives/src/proofs.rs index 10b7bc2530b..1712112281f 100644 --- a/crates/primitives/src/proofs.rs +++ b/crates/primitives/src/proofs.rs @@ -1,8 +1,8 @@ //! Helper function for calculating Merkle proofs and hashes. -use crate::{Header, Receipt, ReceiptWithBloom, ReceiptWithBloomRef, TransactionSigned}; +use crate::{Receipt, ReceiptWithBloom, ReceiptWithBloomRef, TransactionSigned}; use alloc::vec::Vec; -use alloy_consensus::EMPTY_OMMER_ROOT_HASH; +use alloy_consensus::{Header, EMPTY_OMMER_ROOT_HASH}; use alloy_eips::{eip2718::Encodable2718, eip4895::Withdrawal}; use alloy_primitives::{keccak256, B256}; use alloy_trie::root::{ordered_trie_root, ordered_trie_root_with_encoder}; diff --git a/crates/rpc/rpc-builder/Cargo.toml b/crates/rpc/rpc-builder/Cargo.toml index b6ae86c7408..04e97f99e34 100644 --- a/crates/rpc/rpc-builder/Cargo.toml +++ b/crates/rpc/rpc-builder/Cargo.toml @@ -29,7 +29,8 @@ reth-tasks = { workspace = true, features = ["rayon"] } reth-transaction-pool.workspace = true reth-evm.workspace = true reth-engine-primitives.workspace = true -reth-primitives.workspace = true + +alloy-consensus.workspace = true # rpc/net jsonrpsee = { workspace = true, features = ["server"] } @@ -63,6 +64,7 @@ reth-rpc-engine-api.workspace = true reth-tracing.workspace = true reth-transaction-pool = { workspace = true, features = ["test-utils"] } reth-rpc-types-compat.workspace = true +reth-primitives.workspace = true alloy-primitives.workspace = true alloy-rpc-types-eth.workspace = true diff --git a/crates/rpc/rpc-builder/src/eth.rs b/crates/rpc/rpc-builder/src/eth.rs index 40acecfedf3..e88f6aa86bb 100644 --- a/crates/rpc/rpc-builder/src/eth.rs +++ b/crates/rpc/rpc-builder/src/eth.rs @@ -1,5 +1,5 @@ +use alloy_consensus::Header; use reth_evm::ConfigureEvm; -use reth_primitives::Header; use reth_provider::{BlockReader, CanonStateSubscriptions, EvmEnvProvider, StateProviderFactory}; use reth_rpc::{EthFilter, EthPubSub}; use reth_rpc_eth_api::EthApiTypes; diff --git a/crates/rpc/rpc-builder/src/lib.rs b/crates/rpc/rpc-builder/src/lib.rs index 40e40962349..27eceed98cb 100644 --- a/crates/rpc/rpc-builder/src/lib.rs +++ b/crates/rpc/rpc-builder/src/lib.rs @@ -16,9 +16,9 @@ //! Configure only an http server with a selection of [`RethRpcModule`]s //! //! ``` +//! use alloy_consensus::Header; //! use reth_evm::{execute::BlockExecutorProvider, ConfigureEvm}; //! use reth_network_api::{NetworkInfo, Peers}; -//! use reth_primitives::Header; //! use reth_provider::{AccountReader, CanonStateSubscriptions, ChangeSetReader, FullRpcProvider}; //! use reth_rpc::EthApi; //! use reth_rpc_builder::{ @@ -73,10 +73,10 @@ //! //! //! ``` +//! use alloy_consensus::Header; //! use reth_engine_primitives::EngineTypes; //! use reth_evm::{execute::BlockExecutorProvider, ConfigureEvm}; //! use reth_network_api::{NetworkInfo, Peers}; -//! use reth_primitives::Header; //! use reth_provider::{AccountReader, CanonStateSubscriptions, ChangeSetReader, FullRpcProvider}; //! use reth_rpc::EthApi; //! use reth_rpc_api::EngineApiServer; @@ -167,6 +167,7 @@ use std::{ }; use crate::{auth::AuthRpcModule, error::WsHttpSamePortError, metrics::RpcRequestMetrics}; +use alloy_consensus::Header; use error::{ConflictingModules, RpcError, ServerKind}; use eth::DynEthApiBuilder; use http::{header::AUTHORIZATION, HeaderMap}; @@ -183,7 +184,6 @@ use reth_consensus::Consensus; use reth_engine_primitives::EngineTypes; use reth_evm::{execute::BlockExecutorProvider, ConfigureEvm}; use reth_network_api::{noop::NoopNetwork, NetworkInfo, Peers}; -use reth_primitives::Header; use reth_provider::{ AccountReader, BlockReader, CanonStateSubscriptions, ChainSpecProvider, ChangeSetReader, EvmEnvProvider, FullRpcProvider, StateProviderFactory, @@ -259,7 +259,7 @@ where Network: NetworkInfo + Peers + Clone + 'static, Tasks: TaskSpawner + Clone + 'static, Events: CanonStateSubscriptions + Clone + 'static, - EvmConfig: ConfigureEvm
, + EvmConfig: ConfigureEvm
, EthApi: FullEthApiServer, BlockExecutor: BlockExecutorProvider, { @@ -679,11 +679,11 @@ where /// # Example /// /// ```no_run + /// use alloy_consensus::Header; /// use reth_consensus::noop::NoopConsensus; /// use reth_evm::ConfigureEvm; /// use reth_evm_ethereum::execute::EthExecutorProvider; /// use reth_network_api::noop::NoopNetwork; - /// use reth_primitives::Header; /// use reth_provider::test_utils::{NoopProvider, TestCanonStateSubscriptions}; /// use reth_rpc::EthApi; /// use reth_rpc_builder::RpcModuleBuilder; diff --git a/crates/rpc/rpc-eth-api/src/helpers/block.rs b/crates/rpc/rpc-eth-api/src/helpers/block.rs index 7125857b898..251ca225eb1 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/block.rs @@ -163,7 +163,7 @@ pub trait EthBlocks: LoadBlock { fn ommers( &self, block_id: BlockId, - ) -> Result>, Self::Error> { + ) -> Result>, Self::Error> { self.provider().ommers_by_id(block_id).map_err(Self::Error::from_eth_err) } diff --git a/crates/rpc/rpc-eth-api/src/helpers/call.rs b/crates/rpc/rpc-eth-api/src/helpers/call.rs index ef29f807026..6a5506ad2ad 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/call.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/call.rs @@ -5,7 +5,7 @@ use crate::{ AsEthApiError, FromEthApiError, FromEvmError, FullEthApiTypes, IntoEthApiError, RpcBlock, RpcNodeCore, }; -use alloy_consensus::BlockHeader; +use alloy_consensus::{BlockHeader, Header}; use alloy_eips::{eip1559::calc_next_block_base_fee, eip2930::AccessListResult}; use alloy_primitives::{Address, Bytes, TxKind, B256, U256}; use alloy_rpc_types_eth::{ @@ -22,7 +22,7 @@ use reth_primitives::{ BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ExecutionResult, HaltReason, ResultAndState, TransactTo, TxEnv, }, - Header, TransactionSigned, + TransactionSigned, }; use reth_provider::{BlockIdReader, ChainSpecProvider, HeaderProvider, StateProvider}; use reth_revm::{database::StateProviderDatabase, db::CacheDB, DatabaseRef}; diff --git a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs index 0173485aef5..490447d6152 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs @@ -5,7 +5,7 @@ use std::time::{Duration, Instant}; use crate::{EthApiTypes, FromEthApiError, FromEvmError, RpcNodeCore}; -use alloy_consensus::EMPTY_OMMER_ROOT_HASH; +use alloy_consensus::{Header, EMPTY_OMMER_ROOT_HASH}; use alloy_eips::{ eip4844::MAX_DATA_GAS_PER_BLOCK, eip7685::EMPTY_REQUESTS_HASH, merge::BEACON_NONCE, }; @@ -24,8 +24,7 @@ use reth_primitives::{ BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, EVMError, Env, ExecutionResult, InvalidTransaction, ResultAndState, SpecId, }, - Block, BlockBody, Header, Receipt, SealedBlockWithSenders, SealedHeader, - TransactionSignedEcRecovered, + Block, BlockBody, Receipt, SealedBlockWithSenders, SealedHeader, TransactionSignedEcRecovered, }; use reth_provider::{ BlockReader, BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, ProviderError, diff --git a/crates/rpc/rpc-eth-api/src/helpers/state.rs b/crates/rpc/rpc-eth-api/src/helpers/state.rs index 7bc365d91c4..7ff9fa4deff 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/state.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/state.rs @@ -1,7 +1,7 @@ //! Loads a pending block from database. Helper trait for `eth_` block, transaction, call and trace //! RPC methods. -use alloy_consensus::constants::KECCAK_EMPTY; +use alloy_consensus::{constants::KECCAK_EMPTY, Header}; use alloy_eips::BlockId; use alloy_primitives::{Address, Bytes, B256, U256}; use alloy_rpc_types_eth::{Account, EIP1186AccountProofResponse}; @@ -10,7 +10,6 @@ use futures::Future; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_errors::RethError; use reth_evm::ConfigureEvmEnv; -use reth_primitives::Header; use reth_provider::{ BlockIdReader, BlockNumReader, ChainSpecProvider, StateProvider, StateProviderBox, StateProviderFactory, diff --git a/crates/rpc/rpc-eth-api/src/helpers/trace.rs b/crates/rpc/rpc-eth-api/src/helpers/trace.rs index 36d901fda5f..104042d17a2 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/trace.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/trace.rs @@ -3,12 +3,13 @@ use std::{fmt::Display, sync::Arc}; use crate::{FromEvmError, RpcNodeCore}; +use alloy_consensus::Header; use alloy_primitives::B256; use alloy_rpc_types_eth::{BlockId, TransactionInfo}; use futures::Future; use reth_chainspec::ChainSpecProvider; use reth_evm::{system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv}; -use reth_primitives::{Header, SealedBlockWithSenders}; +use reth_primitives::SealedBlockWithSenders; use reth_revm::database::StateProviderDatabase; use reth_rpc_eth_types::{ cache::db::{StateCacheDb, StateCacheDbRefMutWrapper, StateProviderTraitObjWrapper}, diff --git a/crates/rpc/rpc-eth-types/src/cache/mod.rs b/crates/rpc/rpc-eth-types/src/cache/mod.rs index b6b0364c477..b4a110e96af 100644 --- a/crates/rpc/rpc-eth-types/src/cache/mod.rs +++ b/crates/rpc/rpc-eth-types/src/cache/mod.rs @@ -1,5 +1,6 @@ //! Async caching support for eth RPC +use alloy_consensus::Header; use alloy_eips::BlockHashOrNumber; use alloy_primitives::B256; use futures::{future::Either, Stream, StreamExt}; @@ -7,7 +8,7 @@ use reth_chain_state::CanonStateNotification; use reth_errors::{ProviderError, ProviderResult}; use reth_evm::{provider::EvmEnvProvider, ConfigureEvm}; use reth_execution_types::Chain; -use reth_primitives::{Header, Receipt, SealedBlockWithSenders, TransactionSigned}; +use reth_primitives::{Receipt, SealedBlockWithSenders, TransactionSigned}; use reth_storage_api::{BlockReader, StateProviderFactory, TransactionVariant}; use reth_tasks::{TaskSpawner, TokioTaskExecutor}; use revm::primitives::{BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, SpecId}; diff --git a/crates/rpc/rpc-eth-types/src/simulate.rs b/crates/rpc/rpc-eth-types/src/simulate.rs index 91aaa25430e..9807010c0cf 100644 --- a/crates/rpc/rpc-eth-types/src/simulate.rs +++ b/crates/rpc/rpc-eth-types/src/simulate.rs @@ -275,7 +275,7 @@ pub fn build_block>( let state_root = db.db.state_root(hashed_state).map_err(T::Error::from_eth_err)?; - let header = reth_primitives::Header { + let header = alloy_consensus::Header { beneficiary: block_env.coinbase, difficulty: block_env.difficulty, number: block_env.number.to(), diff --git a/crates/rpc/rpc-types-compat/src/engine/payload.rs b/crates/rpc/rpc-types-compat/src/engine/payload.rs index 9050b0cced1..7f260a7693c 100644 --- a/crates/rpc/rpc-types-compat/src/engine/payload.rs +++ b/crates/rpc/rpc-types-compat/src/engine/payload.rs @@ -1,7 +1,7 @@ //! Standalone Conversion Functions for Handling Different Versions of Execution Payloads in //! Ethereum's Engine -use alloy_consensus::{constants::MAXIMUM_EXTRA_DATA_SIZE, EMPTY_OMMER_ROOT_HASH}; +use alloy_consensus::{constants::MAXIMUM_EXTRA_DATA_SIZE, Header, EMPTY_OMMER_ROOT_HASH}; use alloy_eips::{ eip2718::{Decodable2718, Encodable2718}, eip4895::Withdrawals, @@ -15,7 +15,7 @@ use alloy_rpc_types_engine::{ }; use reth_primitives::{ proofs::{self}, - Block, BlockBody, Header, SealedBlock, TransactionSigned, + Block, BlockBody, SealedBlock, TransactionSigned, }; /// Converts [`ExecutionPayloadV1`] to [`Block`] diff --git a/crates/rpc/rpc/src/eth/core.rs b/crates/rpc/rpc/src/eth/core.rs index f945aa446b5..d6c8f522cda 100644 --- a/crates/rpc/rpc/src/eth/core.rs +++ b/crates/rpc/rpc/src/eth/core.rs @@ -405,6 +405,7 @@ impl EthApiInner Stage for HeaderStage where P: HeaderSyncGapProvider, - D: HeaderDownloader
, + D: HeaderDownloader
, Provider: DBProvider + StaticFileProviderFactory, { /// Return the id of the stage @@ -441,7 +441,7 @@ mod tests { } } - impl + 'static> StageTestRunner + impl + 'static> StageTestRunner for HeadersTestRunner { type S = HeaderStage, D>; @@ -461,7 +461,7 @@ mod tests { } } - impl + 'static> ExecuteStageTestRunner + impl + 'static> ExecuteStageTestRunner for HeadersTestRunner { type Seed = Vec; @@ -539,7 +539,7 @@ mod tests { } } - impl + 'static> UnwindStageTestRunner + impl + 'static> UnwindStageTestRunner for HeadersTestRunner { fn validate_unwind(&self, input: UnwindInput) -> Result<(), TestRunnerError> { diff --git a/crates/storage/db-api/Cargo.toml b/crates/storage/db-api/Cargo.toml index f827e48c8c3..9b8589cb6aa 100644 --- a/crates/storage/db-api/Cargo.toml +++ b/crates/storage/db-api/Cargo.toml @@ -25,6 +25,7 @@ reth-trie-common.workspace = true # ethereum alloy-primitives.workspace = true alloy-genesis.workspace = true +alloy-consensus.workspace = true # codecs modular-bitfield.workspace = true @@ -57,29 +58,27 @@ proptest-arbitrary-interop.workspace = true [features] test-utils = [ - "arbitrary", - "reth-primitives/test-utils", - "reth-primitives-traits/test-utils", - "reth-codecs/test-utils", - "reth-db-models/test-utils", - "reth-trie-common/test-utils", - "reth-prune-types/test-utils", - "reth-stages-types/test-utils" + "arbitrary", + "reth-primitives/test-utils", + "reth-primitives-traits/test-utils", + "reth-codecs/test-utils", + "reth-db-models/test-utils", + "reth-trie-common/test-utils", + "reth-prune-types/test-utils", + "reth-stages-types/test-utils", ] arbitrary = [ - "reth-primitives/arbitrary", - "reth-db-models/arbitrary", - "dep:arbitrary", - "dep:proptest", - "reth-primitives-traits/arbitrary", - "reth-trie-common/arbitrary", - "alloy-primitives/arbitrary", - "parity-scale-codec/arbitrary", - "reth-codecs/arbitrary", - "reth-prune-types/arbitrary", - "reth-stages-types/arbitrary" -] -optimism = [ - "reth-primitives/optimism", - "reth-codecs/optimism" + "reth-primitives/arbitrary", + "reth-db-models/arbitrary", + "dep:arbitrary", + "dep:proptest", + "reth-primitives-traits/arbitrary", + "reth-trie-common/arbitrary", + "alloy-primitives/arbitrary", + "parity-scale-codec/arbitrary", + "reth-codecs/arbitrary", + "reth-prune-types/arbitrary", + "reth-stages-types/arbitrary", + "alloy-consensus/arbitrary", ] +optimism = ["reth-primitives/optimism", "reth-codecs/optimism"] diff --git a/crates/storage/db-api/src/models/blocks.rs b/crates/storage/db-api/src/models/blocks.rs index 7268d82dd3c..0145ceb52b5 100644 --- a/crates/storage/db-api/src/models/blocks.rs +++ b/crates/storage/db-api/src/models/blocks.rs @@ -1,8 +1,8 @@ //! Block related models and types. +use alloy_consensus::Header; use alloy_primitives::B256; use reth_codecs::{add_arbitrary_tests, Compact}; -use reth_primitives::Header; use serde::{Deserialize, Serialize}; /// The storage representation of a block's ommers. diff --git a/crates/storage/db-api/src/models/mod.rs b/crates/storage/db-api/src/models/mod.rs index fc3351b73b6..00787194c71 100644 --- a/crates/storage/db-api/src/models/mod.rs +++ b/crates/storage/db-api/src/models/mod.rs @@ -4,12 +4,11 @@ use crate::{ table::{Compress, Decode, Decompress, Encode}, DatabaseError, }; +use alloy_consensus::Header; use alloy_genesis::GenesisAccount; use alloy_primitives::{Address, Bytes, Log, B256, U256}; use reth_codecs::{add_arbitrary_tests, Compact}; -use reth_primitives::{ - Account, Bytecode, Header, Receipt, StorageEntry, TransactionSignedNoHash, TxType, -}; +use reth_primitives::{Account, Bytecode, Receipt, StorageEntry, TransactionSignedNoHash, TxType}; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::StageCheckpoint; use reth_trie_common::{StoredNibbles, StoredNibblesSubKey, *}; diff --git a/crates/storage/db/Cargo.toml b/crates/storage/db/Cargo.toml index 324411613fc..6042b5faa81 100644 --- a/crates/storage/db/Cargo.toml +++ b/crates/storage/db/Cargo.toml @@ -26,6 +26,7 @@ reth-trie-common.workspace = true # ethereum alloy-primitives.workspace = true +alloy-consensus.workspace = true # mdbx reth-libmdbx = { workspace = true, optional = true, features = [ @@ -90,31 +91,29 @@ mdbx = [ "dep:rustc-hash", ] test-utils = [ - "dep:tempfile", - "arbitrary", - "parking_lot", - "reth-primitives/test-utils", - "reth-primitives-traits/test-utils", - "reth-db-api/test-utils", - "reth-nippy-jar/test-utils", - "reth-trie-common/test-utils", - "reth-prune-types/test-utils", - "reth-stages-types/test-utils" + "dep:tempfile", + "arbitrary", + "parking_lot", + "reth-primitives/test-utils", + "reth-primitives-traits/test-utils", + "reth-db-api/test-utils", + "reth-nippy-jar/test-utils", + "reth-trie-common/test-utils", + "reth-prune-types/test-utils", + "reth-stages-types/test-utils", ] bench = [] arbitrary = [ - "reth-primitives/arbitrary", - "reth-db-api/arbitrary", - "reth-primitives-traits/arbitrary", - "reth-trie-common/arbitrary", - "alloy-primitives/arbitrary", - "reth-prune-types/arbitrary", - "reth-stages-types/arbitrary" -] -optimism = [ - "reth-primitives/optimism", - "reth-db-api/optimism" + "reth-primitives/arbitrary", + "reth-db-api/arbitrary", + "reth-primitives-traits/arbitrary", + "reth-trie-common/arbitrary", + "alloy-primitives/arbitrary", + "reth-prune-types/arbitrary", + "reth-stages-types/arbitrary", + "alloy-consensus/arbitrary", ] +optimism = ["reth-primitives/optimism", "reth-db-api/optimism"] disable-lock = [] [[bench]] diff --git a/crates/storage/db/src/implementation/mdbx/mod.rs b/crates/storage/db/src/implementation/mdbx/mod.rs index 78a3f7971da..10f3b228230 100644 --- a/crates/storage/db/src/implementation/mdbx/mod.rs +++ b/crates/storage/db/src/implementation/mdbx/mod.rs @@ -497,6 +497,7 @@ mod tests { test_utils::*, AccountChangeSets, }; + use alloy_consensus::Header; use alloy_primitives::{Address, B256, U256}; use reth_db_api::{ cursor::{DbDupCursorRO, DbDupCursorRW, ReverseWalker, Walker}, @@ -504,7 +505,7 @@ mod tests { table::{Encode, Table}, }; use reth_libmdbx::Error; - use reth_primitives::{Account, Header, StorageEntry}; + use reth_primitives::{Account, StorageEntry}; use reth_primitives_traits::IntegerList; use reth_storage_errors::db::{DatabaseWriteError, DatabaseWriteOperation}; use std::str::FromStr; diff --git a/crates/storage/db/src/static_file/masks.rs b/crates/storage/db/src/static_file/masks.rs index ac2811a44d7..405606389ba 100644 --- a/crates/storage/db/src/static_file/masks.rs +++ b/crates/storage/db/src/static_file/masks.rs @@ -4,9 +4,9 @@ use crate::{ static_file::mask::{ColumnSelectorOne, ColumnSelectorTwo, HeaderMask}, HeaderTerminalDifficulties, RawValue, Receipts, Transactions, }; +use alloy_consensus::Header; use alloy_primitives::BlockHash; use reth_db_api::table::Table; -use reth_primitives::Header; // HEADER MASKS add_static_file_mask!(HeaderMask, Header, 0b001); diff --git a/crates/storage/db/src/tables/mod.rs b/crates/storage/db/src/tables/mod.rs index cf7d23a1272..aafdf606bb3 100644 --- a/crates/storage/db/src/tables/mod.rs +++ b/crates/storage/db/src/tables/mod.rs @@ -19,6 +19,7 @@ pub use raw::{RawDupSort, RawKey, RawTable, RawValue, TableRawRow}; #[cfg(feature = "mdbx")] pub(crate) mod utils; +use alloy_consensus::Header; use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash, TxNumber, B256}; use reth_db_api::{ models::{ @@ -30,7 +31,7 @@ use reth_db_api::{ }, table::{Decode, DupSort, Encode, Table}, }; -use reth_primitives::{Account, Bytecode, Header, Receipt, StorageEntry, TransactionSignedNoHash}; +use reth_primitives::{Account, Bytecode, Receipt, StorageEntry, TransactionSignedNoHash}; use reth_primitives_traits::IntegerList; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::StageCheckpoint; diff --git a/crates/storage/provider/Cargo.toml b/crates/storage/provider/Cargo.toml index 04a0bf42908..399e3e000b9 100644 --- a/crates/storage/provider/Cargo.toml +++ b/crates/storage/provider/Cargo.toml @@ -38,6 +38,7 @@ reth-node-types.workspace = true alloy-eips.workspace = true alloy-primitives.workspace = true alloy-rpc-types-engine.workspace = true +alloy-consensus.workspace = true revm.workspace = true # optimism @@ -65,7 +66,6 @@ strum.workspace = true # test-utils reth-ethereum-engine-primitives = { workspace = true, optional = true } -alloy-consensus = { workspace = true, optional = true } # parallel utils rayon.workspace = true @@ -88,44 +88,43 @@ alloy-consensus.workspace = true [features] optimism = [ - "reth-primitives/optimism", - "reth-execution-types/optimism", - "reth-optimism-primitives", - "reth-codecs/optimism", - "reth-db/optimism", - "reth-db-api/optimism", - "revm/optimism" + "reth-primitives/optimism", + "reth-execution-types/optimism", + "reth-optimism-primitives", + "reth-codecs/optimism", + "reth-db/optimism", + "reth-db-api/optimism", + "revm/optimism", ] serde = [ - "reth-execution-types/serde", - "reth-trie-db/serde", - "reth-trie/serde", - "alloy-consensus?/serde", - "alloy-eips/serde", - "alloy-primitives/serde", - "alloy-rpc-types-engine/serde", - "dashmap/serde", - "notify/serde", - "parking_lot/serde", - "rand/serde", - "revm/serde", - "reth-codecs/serde" + "reth-execution-types/serde", + "reth-trie-db/serde", + "reth-trie/serde", + "alloy-consensus/serde", + "alloy-eips/serde", + "alloy-primitives/serde", + "alloy-rpc-types-engine/serde", + "dashmap/serde", + "notify/serde", + "parking_lot/serde", + "rand/serde", + "revm/serde", + "reth-codecs/serde", ] test-utils = [ - "reth-db/test-utils", - "reth-nippy-jar/test-utils", - "reth-trie/test-utils", - "reth-chain-state/test-utils", - "reth-ethereum-engine-primitives", - "alloy-consensus", - "reth-chainspec/test-utils", - "reth-evm/test-utils", - "reth-network-p2p/test-utils", - "reth-primitives/test-utils", - "reth-codecs/test-utils", - "reth-db-api/test-utils", - "reth-trie-db/test-utils", - "revm/test-utils", - "reth-prune-types/test-utils", - "reth-stages-types/test-utils" + "reth-db/test-utils", + "reth-nippy-jar/test-utils", + "reth-trie/test-utils", + "reth-chain-state/test-utils", + "reth-ethereum-engine-primitives", + "reth-chainspec/test-utils", + "reth-evm/test-utils", + "reth-network-p2p/test-utils", + "reth-primitives/test-utils", + "reth-codecs/test-utils", + "reth-db-api/test-utils", + "reth-trie-db/test-utils", + "revm/test-utils", + "reth-prune-types/test-utils", + "reth-stages-types/test-utils", ] diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index dbfb4f7b872..0f0693471b0 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -9,6 +9,7 @@ use crate::{ StageCheckpointReader, StateProviderBox, StateProviderFactory, StateReader, StaticFileProviderFactory, TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; +use alloy_consensus::Header; use alloy_eips::{ eip4895::{Withdrawal, Withdrawals}, BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, @@ -26,8 +27,8 @@ use reth_evm::ConfigureEvmEnv; use reth_execution_types::ExecutionOutcome; use reth_node_types::NodeTypesWithDB; use reth_primitives::{ - Account, Block, BlockWithSenders, Header, Receipt, SealedBlock, SealedBlockWithSenders, - SealedHeader, StorageEntry, TransactionMeta, TransactionSigned, TransactionSignedNoHash, + Account, Block, BlockWithSenders, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, + StorageEntry, TransactionMeta, TransactionSigned, TransactionSignedNoHash, }; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; diff --git a/crates/storage/provider/src/providers/consistent.rs b/crates/storage/provider/src/providers/consistent.rs index 0eb88c1f9ef..37c00be23be 100644 --- a/crates/storage/provider/src/providers/consistent.rs +++ b/crates/storage/provider/src/providers/consistent.rs @@ -6,6 +6,7 @@ use crate::{ StageCheckpointReader, StateReader, StaticFileProviderFactory, TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; +use alloy_consensus::Header; use alloy_eips::{ eip4895::{Withdrawal, Withdrawals}, BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, HashOrNumber, @@ -18,8 +19,8 @@ use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices}; use reth_evm::ConfigureEvmEnv; use reth_execution_types::{BundleStateInit, ExecutionOutcome, RevertsInit}; use reth_primitives::{ - Account, Block, BlockWithSenders, Header, Receipt, SealedBlock, SealedBlockWithSenders, - SealedHeader, StorageEntry, TransactionMeta, TransactionSigned, TransactionSignedNoHash, + Account, Block, BlockWithSenders, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, + StorageEntry, TransactionMeta, TransactionSigned, TransactionSignedNoHash, }; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; diff --git a/crates/storage/provider/src/providers/database/mod.rs b/crates/storage/provider/src/providers/database/mod.rs index bb532329ee3..b4d2e5e48b8 100644 --- a/crates/storage/provider/src/providers/database/mod.rs +++ b/crates/storage/provider/src/providers/database/mod.rs @@ -7,6 +7,7 @@ use crate::{ PruneCheckpointReader, StageCheckpointReader, StateProviderBox, StaticFileProviderFactory, TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; +use alloy_consensus::Header; use alloy_eips::{ eip4895::{Withdrawal, Withdrawals}, BlockHashOrNumber, @@ -20,7 +21,7 @@ use reth_errors::{RethError, RethResult}; use reth_evm::ConfigureEvmEnv; use reth_node_types::NodeTypesWithDB; use reth_primitives::{ - Block, BlockWithSenders, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, + Block, BlockWithSenders, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, StaticFileSegment, TransactionMeta, TransactionSigned, TransactionSignedNoHash, }; use reth_prune_types::{PruneCheckpoint, PruneModes, PruneSegment}; diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index 9ba20306f37..eef0ff5b668 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -15,6 +15,7 @@ use crate::{ StaticFileProviderFactory, StatsReader, StorageReader, StorageTrieWriter, TransactionVariant, TransactionsProvider, TransactionsProviderExt, TrieWriter, WithdrawalsProvider, }; +use alloy_consensus::Header; use alloy_eips::{ eip4895::{Withdrawal, Withdrawals}, BlockHashOrNumber, @@ -42,9 +43,9 @@ use reth_execution_types::{Chain, ExecutionOutcome}; use reth_network_p2p::headers::downloader::SyncTarget; use reth_node_types::NodeTypes; use reth_primitives::{ - Account, Block, BlockBody, BlockWithSenders, Bytecode, GotExpected, Header, Receipt, - SealedBlock, SealedBlockWithSenders, SealedHeader, StaticFileSegment, StorageEntry, - TransactionMeta, TransactionSigned, TransactionSignedEcRecovered, TransactionSignedNoHash, + Account, Block, BlockBody, BlockWithSenders, Bytecode, GotExpected, Receipt, SealedBlock, + SealedBlockWithSenders, SealedHeader, StaticFileSegment, StorageEntry, TransactionMeta, + TransactionSigned, TransactionSignedEcRecovered, TransactionSignedNoHash, }; use reth_prune_types::{PruneCheckpoint, PruneModes, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; diff --git a/crates/storage/provider/src/providers/mod.rs b/crates/storage/provider/src/providers/mod.rs index d3dde5b0d3b..d1e1822d8c9 100644 --- a/crates/storage/provider/src/providers/mod.rs +++ b/crates/storage/provider/src/providers/mod.rs @@ -7,6 +7,7 @@ use crate::{ StageCheckpointReader, StateProviderBox, StateProviderFactory, StaticFileProviderFactory, TransactionVariant, TransactionsProvider, TreeViewer, WithdrawalsProvider, }; +use alloy_consensus::Header; use alloy_eips::{ eip4895::{Withdrawal, Withdrawals}, BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, @@ -23,8 +24,8 @@ use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices}; use reth_evm::ConfigureEvmEnv; use reth_node_types::NodeTypesWithDB; use reth_primitives::{ - Account, Block, BlockWithSenders, Header, Receipt, SealedBlock, SealedBlockWithSenders, - SealedHeader, TransactionMeta, TransactionSigned, TransactionSignedNoHash, + Account, Block, BlockWithSenders, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, + TransactionMeta, TransactionSigned, TransactionSignedNoHash, }; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; diff --git a/crates/storage/provider/src/providers/static_file/jar.rs b/crates/storage/provider/src/providers/static_file/jar.rs index 8d1dbd117cf..9c303394ed2 100644 --- a/crates/storage/provider/src/providers/static_file/jar.rs +++ b/crates/storage/provider/src/providers/static_file/jar.rs @@ -6,13 +6,14 @@ use crate::{ to_range, BlockHashReader, BlockNumReader, HeaderProvider, ReceiptProvider, TransactionsProvider, }; +use alloy_consensus::Header; use alloy_eips::BlockHashOrNumber; use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256}; use reth_chainspec::ChainInfo; use reth_db::static_file::{HeaderMask, ReceiptMask, StaticFileCursor, TransactionMask}; use reth_db_api::models::CompactU256; use reth_primitives::{ - Header, Receipt, SealedHeader, TransactionMeta, TransactionSigned, TransactionSignedNoHash, + Receipt, SealedHeader, TransactionMeta, TransactionSigned, TransactionSignedNoHash, }; use reth_storage_errors::provider::{ProviderError, ProviderResult}; use std::{ diff --git a/crates/storage/provider/src/providers/static_file/manager.rs b/crates/storage/provider/src/providers/static_file/manager.rs index cb270a6da46..a5d4537245d 100644 --- a/crates/storage/provider/src/providers/static_file/manager.rs +++ b/crates/storage/provider/src/providers/static_file/manager.rs @@ -7,6 +7,7 @@ use crate::{ ReceiptProvider, StageCheckpointReader, StatsReader, TransactionVariant, TransactionsProvider, TransactionsProviderExt, WithdrawalsProvider, }; +use alloy_consensus::Header; use alloy_eips::{ eip4895::{Withdrawal, Withdrawals}, BlockHashOrNumber, @@ -33,7 +34,7 @@ use reth_primitives::{ find_fixed_range, HighestStaticFiles, SegmentHeader, SegmentRangeInclusive, DEFAULT_BLOCKS_PER_STATIC_FILE, }, - Block, BlockWithSenders, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, + Block, BlockWithSenders, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, StaticFileSegment, TransactionMeta, TransactionSigned, TransactionSignedNoHash, }; use reth_stages_types::{PipelineTarget, StageId}; diff --git a/crates/storage/provider/src/providers/static_file/mod.rs b/crates/storage/provider/src/providers/static_file/mod.rs index 52eb6ed666e..dd52adf52f8 100644 --- a/crates/storage/provider/src/providers/static_file/mod.rs +++ b/crates/storage/provider/src/providers/static_file/mod.rs @@ -56,7 +56,7 @@ impl Deref for LoadedJar { mod tests { use super::*; use crate::{test_utils::create_test_provider_factory, HeaderProvider}; - use alloy_consensus::Transaction; + use alloy_consensus::{Header, Transaction}; use alloy_primitives::{BlockHash, TxNumber, B256, U256}; use rand::seq::SliceRandom; use reth_db::{ @@ -66,7 +66,7 @@ mod tests { use reth_db_api::transaction::DbTxMut; use reth_primitives::{ static_file::{find_fixed_range, SegmentRangeInclusive, DEFAULT_BLOCKS_PER_STATIC_FILE}, - Header, Receipt, TransactionSignedNoHash, + Receipt, TransactionSignedNoHash, }; use reth_storage_api::{ReceiptProvider, TransactionsProvider}; use reth_testing_utils::generators::{self, random_header_range}; diff --git a/crates/storage/provider/src/providers/static_file/writer.rs b/crates/storage/provider/src/providers/static_file/writer.rs index 8c31c021f21..ed1a51068c3 100644 --- a/crates/storage/provider/src/providers/static_file/writer.rs +++ b/crates/storage/provider/src/providers/static_file/writer.rs @@ -2,6 +2,7 @@ use super::{ manager::StaticFileProviderInner, metrics::StaticFileProviderMetrics, StaticFileProvider, }; use crate::providers::static_file::metrics::StaticFileProviderOperation; +use alloy_consensus::Header; use alloy_primitives::{BlockHash, BlockNumber, TxNumber, U256}; use parking_lot::{lock_api::RwLockWriteGuard, RawRwLock, RwLock}; use reth_codecs::Compact; @@ -9,7 +10,7 @@ use reth_db_api::models::CompactU256; use reth_nippy_jar::{NippyJar, NippyJarError, NippyJarWriter}; use reth_primitives::{ static_file::{SegmentHeader, SegmentRangeInclusive}, - Header, Receipt, StaticFileSegment, TransactionSignedNoHash, + Receipt, StaticFileSegment, TransactionSignedNoHash, }; use reth_storage_errors::provider::{ProviderError, ProviderResult}; use std::{ diff --git a/crates/storage/provider/src/test_utils/blocks.rs b/crates/storage/provider/src/test_utils/blocks.rs index 9afc77ef701..3259eee2bfb 100644 --- a/crates/storage/provider/src/test_utils/blocks.rs +++ b/crates/storage/provider/src/test_utils/blocks.rs @@ -5,14 +5,15 @@ use alloy_primitives::{ b256, hex_literal::hex, map::HashMap, Address, BlockNumber, Bytes, Log, TxKind, B256, U256, }; +use alloy_consensus::Header; use alloy_eips::eip4895::{Withdrawal, Withdrawals}; use alloy_primitives::PrimitiveSignature as Signature; use reth_db::tables; use reth_db_api::{database::Database, models::StoredBlockBodyIndices}; use reth_node_types::NodeTypes; use reth_primitives::{ - Account, BlockBody, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, - Transaction, TransactionSigned, TxType, + Account, BlockBody, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, Transaction, + TransactionSigned, TxType, }; use reth_trie::root::{state_root_unhashed, storage_root_unhashed}; use revm::{db::BundleState, primitives::AccountInfo}; diff --git a/crates/storage/provider/src/test_utils/mock.rs b/crates/storage/provider/src/test_utils/mock.rs index 9bc75f53d18..9661ab2057c 100644 --- a/crates/storage/provider/src/test_utils/mock.rs +++ b/crates/storage/provider/src/test_utils/mock.rs @@ -5,7 +5,7 @@ use crate::{ ReceiptProviderIdExt, StateProvider, StateProviderBox, StateProviderFactory, StateReader, StateRootProvider, TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; -use alloy_consensus::constants::EMPTY_ROOT_HASH; +use alloy_consensus::{constants::EMPTY_ROOT_HASH, Header}; use alloy_eips::{ eip4895::{Withdrawal, Withdrawals}, BlockHashOrNumber, BlockId, BlockNumberOrTag, @@ -23,7 +23,7 @@ use reth_evm::ConfigureEvmEnv; use reth_execution_types::ExecutionOutcome; use reth_node_types::NodeTypes; use reth_primitives::{ - Account, Block, BlockWithSenders, Bytecode, GotExpected, Header, Receipt, SealedBlock, + Account, Block, BlockWithSenders, Bytecode, GotExpected, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, TransactionMeta, TransactionSigned, TransactionSignedNoHash, }; diff --git a/crates/storage/provider/src/test_utils/noop.rs b/crates/storage/provider/src/test_utils/noop.rs index 7c3848b4a53..38fab0dc311 100644 --- a/crates/storage/provider/src/test_utils/noop.rs +++ b/crates/storage/provider/src/test_utils/noop.rs @@ -4,6 +4,7 @@ use std::{ sync::Arc, }; +use alloy_consensus::Header; use alloy_eips::{ eip4895::{Withdrawal, Withdrawals}, BlockHashOrNumber, BlockId, BlockNumberOrTag, @@ -21,9 +22,8 @@ use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices}; use reth_errors::ProviderError; use reth_evm::ConfigureEvmEnv; use reth_primitives::{ - Account, Block, BlockWithSenders, Bytecode, Header, Receipt, SealedBlock, - SealedBlockWithSenders, SealedHeader, TransactionMeta, TransactionSigned, - TransactionSignedNoHash, + Account, Block, BlockWithSenders, Bytecode, Receipt, SealedBlock, SealedBlockWithSenders, + SealedHeader, TransactionMeta, TransactionSigned, TransactionSignedNoHash, }; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; diff --git a/crates/storage/provider/src/writer/mod.rs b/crates/storage/provider/src/writer/mod.rs index 6ca024b0a9f..0fbec6c1b88 100644 --- a/crates/storage/provider/src/writer/mod.rs +++ b/crates/storage/provider/src/writer/mod.rs @@ -3,6 +3,7 @@ use crate::{ writer::static_file::StaticFileWriter, BlockExecutionWriter, BlockWriter, HistoryWriter, StateChangeWriter, StateWriter, TrieWriter, }; +use alloy_consensus::Header; use alloy_primitives::{BlockNumber, B256, U256}; use reth_chain_state::ExecutedBlock; use reth_db::{ @@ -13,7 +14,7 @@ use reth_db::{ }; use reth_errors::{ProviderError, ProviderResult}; use reth_execution_types::ExecutionOutcome; -use reth_primitives::{Header, SealedBlock, StaticFileSegment, TransactionSignedNoHash}; +use reth_primitives::{SealedBlock, StaticFileSegment, TransactionSignedNoHash}; use reth_stages_types::{StageCheckpoint, StageId}; use reth_storage_api::{ DBProvider, HeaderProvider, ReceiptWriter, StageCheckpointWriter, TransactionsProviderExt, diff --git a/crates/storage/storage-api/src/block.rs b/crates/storage/storage-api/src/block.rs index c78ec5f8b80..929f7ecca43 100644 --- a/crates/storage/storage-api/src/block.rs +++ b/crates/storage/storage-api/src/block.rs @@ -2,11 +2,12 @@ use crate::{ BlockNumReader, HeaderProvider, ReceiptProvider, ReceiptProviderIdExt, TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; +use alloy_consensus::Header; use alloy_eips::{BlockHashOrNumber, BlockId, BlockNumberOrTag}; use alloy_primitives::{BlockNumber, B256}; use reth_db_models::StoredBlockBodyIndices; use reth_primitives::{ - Block, BlockWithSenders, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, + Block, BlockWithSenders, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, }; use reth_storage_errors::provider::ProviderResult; use std::ops::RangeInclusive; diff --git a/crates/storage/storage-api/src/header.rs b/crates/storage/storage-api/src/header.rs index 7202f51ddf1..c068f7c1d29 100644 --- a/crates/storage/storage-api/src/header.rs +++ b/crates/storage/storage-api/src/header.rs @@ -1,6 +1,7 @@ +use alloy_consensus::Header; use alloy_eips::BlockHashOrNumber; use alloy_primitives::{BlockHash, BlockNumber, U256}; -use reth_primitives::{Header, SealedHeader}; +use reth_primitives::SealedHeader; use reth_storage_errors::provider::ProviderResult; use std::ops::RangeBounds; diff --git a/examples/custom-evm/Cargo.toml b/examples/custom-evm/Cargo.toml index 53563ab9575..e763a932eab 100644 --- a/examples/custom-evm/Cargo.toml +++ b/examples/custom-evm/Cargo.toml @@ -16,6 +16,7 @@ reth-node-ethereum = { workspace = true, features = ["test-utils"] } reth-tracing.workspace = true alloy-genesis.workspace = true alloy-primitives.workspace = true +alloy-consensus.workspace = true eyre.workspace = true tokio.workspace = true diff --git a/examples/custom-evm/src/main.rs b/examples/custom-evm/src/main.rs index 16aad63c093..c564c5b28b6 100644 --- a/examples/custom-evm/src/main.rs +++ b/examples/custom-evm/src/main.rs @@ -2,6 +2,7 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] +use alloy_consensus::Header; use alloy_genesis::Genesis; use alloy_primitives::{address, Address, Bytes, U256}; use reth::{ @@ -35,7 +36,7 @@ use reth_node_ethereum::{ }; use reth_primitives::{ revm_primitives::{CfgEnvWithHandlerCfg, TxEnv}, - Header, TransactionSigned, + TransactionSigned, }; use reth_tracing::{RethTracer, Tracer}; use std::{convert::Infallible, sync::Arc}; diff --git a/examples/stateful-precompile/Cargo.toml b/examples/stateful-precompile/Cargo.toml index 47a784c36e1..478886d061f 100644 --- a/examples/stateful-precompile/Cargo.toml +++ b/examples/stateful-precompile/Cargo.toml @@ -15,6 +15,7 @@ reth-node-ethereum = { workspace = true, features = ["test-utils"] } reth-tracing.workspace = true alloy-genesis.workspace = true alloy-primitives.workspace = true +alloy-consensus.workspace = true eyre.workspace = true parking_lot.workspace = true diff --git a/examples/stateful-precompile/src/main.rs b/examples/stateful-precompile/src/main.rs index 371fbf4f78b..5be45ad7674 100644 --- a/examples/stateful-precompile/src/main.rs +++ b/examples/stateful-precompile/src/main.rs @@ -2,6 +2,7 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] +use alloy_consensus::Header; use alloy_genesis::Genesis; use alloy_primitives::{Address, Bytes, U256}; use parking_lot::RwLock; @@ -26,7 +27,7 @@ use reth_node_ethereum::{ }; use reth_primitives::{ revm_primitives::{SpecId, StatefulPrecompileMut}, - Header, TransactionSigned, + TransactionSigned, }; use reth_tracing::{RethTracer, Tracer}; use schnellru::{ByLength, LruMap}; diff --git a/testing/ef-tests/Cargo.toml b/testing/ef-tests/Cargo.toml index de46f62675c..2fc0c751244 100644 --- a/testing/ef-tests/Cargo.toml +++ b/testing/ef-tests/Cargo.toml @@ -38,6 +38,7 @@ revm = { workspace = true, features = ["secp256k1", "blst", "c-kzg"] } alloy-rlp.workspace = true alloy-primitives.workspace = true alloy-eips.workspace = true +alloy-consensus.workspace = true walkdir = "2.3.3" serde.workspace = true diff --git a/testing/ef-tests/src/models.rs b/testing/ef-tests/src/models.rs index 2b6b3baa81e..292b32e8ce0 100644 --- a/testing/ef-tests/src/models.rs +++ b/testing/ef-tests/src/models.rs @@ -1,6 +1,7 @@ //! Shared models for use crate::{assert::assert_equal, Error}; +use alloy_consensus::Header as RethHeader; use alloy_eips::eip4895::Withdrawals; use alloy_primitives::{keccak256, Address, Bloom, Bytes, B256, B64, U256}; use reth_chainspec::{ChainSpec, ChainSpecBuilder}; @@ -9,9 +10,7 @@ use reth_db_api::{ cursor::DbDupCursorRO, transaction::{DbTx, DbTxMut}, }; -use reth_primitives::{ - Account as RethAccount, Bytecode, Header as RethHeader, SealedHeader, StorageEntry, -}; +use reth_primitives::{Account as RethAccount, Bytecode, SealedHeader, StorageEntry}; use serde::Deserialize; use std::{collections::BTreeMap, ops::Deref}; diff --git a/testing/testing-utils/src/generators.rs b/testing/testing-utils/src/generators.rs index 3457eb5f203..582298feab9 100644 --- a/testing/testing-utils/src/generators.rs +++ b/testing/testing-utils/src/generators.rs @@ -1,6 +1,6 @@ //! Generators for different data structures like block headers, block bodies and ranges of those. -use alloy_consensus::{Transaction as _, TxLegacy}; +use alloy_consensus::{Header, Transaction as _, TxLegacy}; use alloy_eips::eip4895::{Withdrawal, Withdrawals}; use alloy_primitives::{Address, BlockNumber, Bytes, TxKind, B256, U256}; pub use rand::Rng; @@ -8,7 +8,7 @@ use rand::{ distributions::uniform::SampleRange, rngs::StdRng, seq::SliceRandom, thread_rng, SeedableRng, }; use reth_primitives::{ - proofs, sign_message, Account, BlockBody, Header, Log, Receipt, SealedBlock, SealedHeader, + proofs, sign_message, Account, BlockBody, Log, Receipt, SealedBlock, SealedHeader, StorageEntry, Transaction, TransactionSigned, }; use secp256k1::{Keypair, Secp256k1}; @@ -99,7 +99,7 @@ pub fn random_header_range( /// /// The header is assumed to not be correct if validated. pub fn random_header(rng: &mut R, number: u64, parent: Option) -> SealedHeader { - let header = reth_primitives::Header { + let header = alloy_consensus::Header { number, nonce: rng.gen(), difficulty: U256::from(rng.gen::()), From 7a1698c504c4ee6f5d06e74ae087730dbec0a3b0 Mon Sep 17 00:00:00 2001 From: Ayodeji Akinola Date: Wed, 13 Nov 2024 18:07:59 +0100 Subject: [PATCH 154/211] chore(utils): Util function for headers request (#12501) --- .../src/headers/reverse_headers.rs | 13 +++---- crates/net/p2p/src/full_block.rs | 6 +--- crates/net/p2p/src/headers/client.rs | 35 +++++++++++++++---- 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/crates/net/downloaders/src/headers/reverse_headers.rs b/crates/net/downloaders/src/headers/reverse_headers.rs index 125eef6d3eb..3960ae6e812 100644 --- a/crates/net/downloaders/src/headers/reverse_headers.rs +++ b/crates/net/downloaders/src/headers/reverse_headers.rs @@ -13,7 +13,7 @@ use reth_consensus::Consensus; use reth_network_p2p::{ error::{DownloadError, DownloadResult, PeerRequestResult}, headers::{ - client::{HeadersClient, HeadersDirection, HeadersRequest}, + client::{HeadersClient, HeadersRequest}, downloader::{validate_header_download, HeaderDownloader, SyncTarget}, error::{HeadersDownloaderError, HeadersDownloaderResult}, }, @@ -60,9 +60,10 @@ impl From for ReverseHeadersDownloaderError { /// tries to fill the gap between the local head of the node and the chain tip by issuing multiple /// requests at a time but yielding them in batches on [`Stream::poll_next`]. /// -/// **Note:** This downloader downloads in reverse, see also [`HeadersDirection::Falling`], this -/// means the batches of headers that this downloader yields will start at the chain tip and move -/// towards the local head: falling block numbers. +/// **Note:** This downloader downloads in reverse, see also +/// [`reth_network_p2p::headers::client::HeadersDirection`], this means the batches of headers that +/// this downloader yields will start at the chain tip and move towards the local head: falling +/// block numbers. #[must_use = "Stream does nothing unless polled"] #[derive(Debug)] pub struct ReverseHeadersDownloader { @@ -567,7 +568,7 @@ where /// Returns the request for the `sync_target` header. const fn get_sync_target_request(&self, start: BlockHashOrNumber) -> HeadersRequest { - HeadersRequest { start, limit: 1, direction: HeadersDirection::Falling } + HeadersRequest::falling(start, 1) } /// Starts a request future @@ -1216,7 +1217,7 @@ fn calc_next_request( let diff = next_request_block_number - local_head; let limit = diff.min(request_limit); let start = next_request_block_number; - HeadersRequest { start: start.into(), limit, direction: HeadersDirection::Falling } + HeadersRequest::falling(start.into(), limit) } #[cfg(test)] diff --git a/crates/net/p2p/src/full_block.rs b/crates/net/p2p/src/full_block.rs index 8fcacd140b0..151a5bdd2a3 100644 --- a/crates/net/p2p/src/full_block.rs +++ b/crates/net/p2p/src/full_block.rs @@ -96,11 +96,7 @@ where start_hash: hash, count, request: FullBlockRangeRequest { - headers: Some(client.get_headers(HeadersRequest { - start: hash.into(), - limit: count, - direction: HeadersDirection::Falling, - })), + headers: Some(client.get_headers(HeadersRequest::falling(hash.into(), count))), bodies: None, }, client, diff --git a/crates/net/p2p/src/headers/client.rs b/crates/net/p2p/src/headers/client.rs index bb879784499..3e8f9296e07 100644 --- a/crates/net/p2p/src/headers/client.rs +++ b/crates/net/p2p/src/headers/client.rs @@ -21,6 +21,34 @@ pub struct HeadersRequest { pub direction: HeadersDirection, } +impl HeadersRequest { + /// Creates a request for a single header (direction doesn't matter). + /// + /// # Arguments + /// * `start` - The block hash or number to start from + pub const fn one(start: BlockHashOrNumber) -> Self { + Self { direction: HeadersDirection::Rising, limit: 1, start } + } + + /// Creates a request for headers in rising direction (ascending block numbers). + /// + /// # Arguments + /// * `start` - The block hash or number to start from + /// * `limit` - Maximum number of headers to retrieve + pub const fn rising(start: BlockHashOrNumber, limit: u64) -> Self { + Self { direction: HeadersDirection::Rising, limit, start } + } + + /// Creates a request for headers in falling direction (descending block numbers). + /// + /// # Arguments + /// * `start` - The block hash or number to start from + /// * `limit` - Maximum number of headers to retrieve + pub const fn falling(start: BlockHashOrNumber, limit: u64) -> Self { + Self { direction: HeadersDirection::Falling, limit, start } + } +} + /// The headers future type pub type HeadersFut = Pin>> + Send + Sync>>; @@ -57,12 +85,7 @@ pub trait HeadersClient: DownloadClient { start: BlockHashOrNumber, priority: Priority, ) -> SingleHeaderRequest { - let req = HeadersRequest { - start, - limit: 1, - // doesn't matter for a single header - direction: HeadersDirection::Rising, - }; + let req = HeadersRequest::one(start); let fut = self.get_headers_with_priority(req, priority); SingleHeaderRequest { fut } } From 413d65139181b36c5133b7e74be942eab9404a01 Mon Sep 17 00:00:00 2001 From: Tien Nguyen <116023870+htiennv@users.noreply.github.com> Date: Thu, 14 Nov 2024 00:11:32 +0700 Subject: [PATCH 155/211] chore: simplify import path (#12523) --- crates/storage/libmdbx-rs/src/txn_manager.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/storage/libmdbx-rs/src/txn_manager.rs b/crates/storage/libmdbx-rs/src/txn_manager.rs index 6afd4205a60..ae4a93724c4 100644 --- a/crates/storage/libmdbx-rs/src/txn_manager.rs +++ b/crates/storage/libmdbx-rs/src/txn_manager.rs @@ -5,7 +5,10 @@ use crate::{ }; use std::{ ptr, - sync::mpsc::{sync_channel, Receiver, SyncSender}, + sync::{ + mpsc::{sync_channel, Receiver, SyncSender}, + Arc, + }, }; #[derive(Copy, Clone, Debug)] @@ -28,7 +31,7 @@ pub(crate) enum TxnManagerMessage { pub(crate) struct TxnManager { sender: SyncSender, #[cfg(feature = "read-tx-timeouts")] - read_transactions: Option>, + read_transactions: Option>, } impl TxnManager { From 0d850e7f05ad7b68ced7035db43eee9128a6fc84 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 13 Nov 2024 18:13:00 +0100 Subject: [PATCH 156/211] fix: consume all payload variants (#12520) Co-authored-by: Arsenii Kulikov --- crates/payload/basic/src/lib.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index 6f2038ba4b4..9b36e44b1fc 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -616,7 +616,9 @@ where if let Some(fut) = Pin::new(&mut this.maybe_better).as_pin_mut() { if let Poll::Ready(res) = fut.poll(cx) { this.maybe_better = None; - if let Ok(BuildOutcome::Better { payload, .. }) = res { + if let Ok(Some(payload)) = res.map(|out| out.into_payload()) + .inspect_err(|err| warn!(target: "payload_builder", %err, "failed to resolve pending payload")) + { debug!(target: "payload_builder", "resolving better payload"); return Poll::Ready(Ok(payload)) } @@ -767,7 +769,7 @@ impl BuildOutcome { /// Consumes the type and returns the payload if the outcome is `Better`. pub fn into_payload(self) -> Option { match self { - Self::Better { payload, .. } => Some(payload), + Self::Better { payload, .. } | Self::Freeze(payload) => Some(payload), _ => None, } } From c326708ffc14f1dae63419521884b0a90b3e037d Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Wed, 13 Nov 2024 21:38:30 +0400 Subject: [PATCH 157/211] feat: add simple kurtosis test for OP stack (#12506) --- .../assets/kurtosis_op_network_params.yaml | 15 +++ .github/workflows/kurtosis-op.yml | 119 ++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 .github/assets/kurtosis_op_network_params.yaml create mode 100644 .github/workflows/kurtosis-op.yml diff --git a/.github/assets/kurtosis_op_network_params.yaml b/.github/assets/kurtosis_op_network_params.yaml new file mode 100644 index 00000000000..0e1516cc889 --- /dev/null +++ b/.github/assets/kurtosis_op_network_params.yaml @@ -0,0 +1,15 @@ +ethereum_package: + participants: + - el_type: reth + cl_type: lighthouse +optimism_package: + chains: + - participants: + - el_type: op-geth + cl_type: op-node + - el_type: op-reth + el_image: "ghcr.io/paradigmxyz/op-reth:kurtosis-ci" + cl_type: op-node + batcher_params: + extra_params: + - "--throttle-interval=0" diff --git a/.github/workflows/kurtosis-op.yml b/.github/workflows/kurtosis-op.yml new file mode 100644 index 00000000000..2652992fca9 --- /dev/null +++ b/.github/workflows/kurtosis-op.yml @@ -0,0 +1,119 @@ +# Runs simple OP stack setup in Kurtosis + +name: kurtosis-op + +on: + workflow_dispatch: + schedule: + # every day + - cron: "0 1 * * *" + +env: + CARGO_TERM_COLOR: always + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + prepare-reth: + if: github.repository == 'paradigmxyz/reth' + timeout-minutes: 45 + runs-on: + group: Reth + steps: + - uses: actions/checkout@v4 + - run: mkdir artifacts + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + with: + cache-on-failure: true + - name: Build reth + run: | + cargo build --features optimism,asm-keccak --profile hivetests --bin op-reth --manifest-path crates/optimism/bin/Cargo.toml --locked + mkdir dist && cp ./target/hivetests/op-reth ./dist/reth + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Build and export reth image + uses: docker/build-push-action@v6 + with: + context: . + file: .github/assets/hive/Dockerfile + tags: ghcr.io/paradigmxyz/op-reth:kurtosis-ci + outputs: type=docker,dest=./artifacts/reth_image.tar + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Upload reth image + uses: actions/upload-artifact@v4 + with: + name: artifacts + path: ./artifacts + + test: + timeout-minutes: 60 + strategy: + fail-fast: false + name: run kurtosis + runs-on: + group: Reth + needs: + - prepare-reth + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Download reth image + uses: actions/download-artifact@v4 + with: + name: artifacts + path: /tmp + + - name: Load Docker image + run: | + docker load -i /tmp/reth_image.tar & + wait + docker image ls -a + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + + - name: Run kurtosis + run: | + echo "deb [trusted=yes] https://apt.fury.io/kurtosis-tech/ /" | sudo tee /etc/apt/sources.list.d/kurtosis.list + sudo apt update + sudo apt install kurtosis-cli + kurtosis engine start + kurtosis run --enclave op-devnet github.com/ethpandaops/optimism-package --args-file .github/assets/kurtosis_op_network_params.yaml + ENCLAVE_ID=$(curl http://127.0.0.1:9779/api/enclaves | jq --raw-output 'keys[0]') + GETH_PORT=$(curl "http://127.0.0.1:9779/api/enclaves/$ENCLAVE_ID/services" | jq '."op-el-1-op-geth-op-node-op-kurtosis".public_ports.rpc.number') + RETH_PORT=$(curl "http://127.0.0.1:9779/api/enclaves/$ENCLAVE_ID/services" | jq '."op-el-2-op-reth-op-node-op-kurtosis".public_ports.rpc.number') + echo "GETH_RPC=http://127.0.0.1:$GETH_PORT" >> $GITHUB_ENV + echo "RETH_RPC=http://127.0.0.1:$RETH_PORT" >> $GITHUB_ENV + + - name: Assert that clients advance + run: | + for i in {1..100}; do + sleep 5 + BLOCK_GETH=$(cast bn --rpc-url $GETH_RPC) + BLOCK_RETH=$(cast bn --rpc-url $RETH_RPC) + + if [ $BLOCK_GETH -ge 100 ] && [ $BLOCK_RETH -ge 100 ] ; then exit 0; fi + echo "Waiting for clients to advance..., Reth: $BLOCK_RETH Geth: $BLOCK_GETH" + done + exit 1 + + + notify-on-error: + needs: test + if: failure() + runs-on: + group: Reth + steps: + - name: Slack Webhook Action + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_COLOR: ${{ job.status }} + SLACK_MESSAGE: "Failed run: https://github.com/paradigmxyz/reth/actions/runs/${{ github.run_id }}" + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} From d505089960c3ea2c65812db05a35f696f3f9d339 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Wed, 13 Nov 2024 22:53:00 +0100 Subject: [PATCH 158/211] tx-pool: rm useless allow deprecated (#12526) --- crates/transaction-pool/src/traits.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/transaction-pool/src/traits.rs b/crates/transaction-pool/src/traits.rs index 185c08c109a..0b3839a0436 100644 --- a/crates/transaction-pool/src/traits.rs +++ b/crates/transaction-pool/src/traits.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - use crate::{ blobstore::BlobStoreError, error::{InvalidPoolTransactionError, PoolResult}, From 457ac5f73fd29563a43f557542abcebf446a2ba3 Mon Sep 17 00:00:00 2001 From: leopardracer <136604165+leopardracer@users.noreply.github.com> Date: Thu, 14 Nov 2024 10:46:58 +0200 Subject: [PATCH 159/211] fix: typos in documentation files (#12528) --- book/run/pruning.md | 2 +- docs/crates/stages.md | 2 +- docs/repo/labels.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/book/run/pruning.md b/book/run/pruning.md index da3bb07e2cd..25d11b4e46e 100644 --- a/book/run/pruning.md +++ b/book/run/pruning.md @@ -18,7 +18,7 @@ the steps for running Reth as a full node, what caveats to expect and how to con - Full Node – Reth node that has the latest state and historical data for only the last 10064 blocks available for querying in the same way as an archive node. -The node type that was chosen when first [running a node](./run-a-node.md) **can not** be changed after +The node type that was chosen when first [running a node](./run-a-node.md) **cannot** be changed after the initial sync. Turning Archive into Pruned, or Pruned into Full is not supported. ## Modes diff --git a/docs/crates/stages.md b/docs/crates/stages.md index c7815b453b4..14666c1f44f 100644 --- a/docs/crates/stages.md +++ b/docs/crates/stages.md @@ -43,7 +43,7 @@ pub trait Stage: Send + Sync { } ``` -To get a better idea of what is happening at each part of the pipeline, lets walk through what is going on under the hood within the `execute()` function at each stage, starting with `HeaderStage`. +To get a better idea of what is happening at each part of the pipeline, let's walk through what is going on under the hood within the `execute()` function at each stage, starting with `HeaderStage`.
diff --git a/docs/repo/labels.md b/docs/repo/labels.md index 6b3dba97ee6..6772b828ffc 100644 --- a/docs/repo/labels.md +++ b/docs/repo/labels.md @@ -30,7 +30,7 @@ For easier at-a-glance communication of the status of issues and PRs the followi - https://github.com/paradigmxyz/reth/labels/S-duplicate - https://github.com/paradigmxyz/reth/labels/S-wontfix -**Misc.** +**Miscellaneous** - https://github.com/paradigmxyz/reth/labels/S-needs-triage - https://github.com/paradigmxyz/reth/labels/S-controversial From 68a6ada460c31c74f25d3b5418b8bc878edfe082 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Thu, 14 Nov 2024 09:47:56 +0100 Subject: [PATCH 160/211] tx-pool: add `PoolUpdateKind` for `CanonicalStateUpdate` (#12525) --- crates/transaction-pool/src/maintain.rs | 4 +++- crates/transaction-pool/src/pool/mod.rs | 5 ++++- crates/transaction-pool/src/pool/txpool.rs | 9 ++++++++- crates/transaction-pool/src/traits.rs | 13 ++++++++++++- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/crates/transaction-pool/src/maintain.rs b/crates/transaction-pool/src/maintain.rs index 91b91fe8157..271c63a388a 100644 --- a/crates/transaction-pool/src/maintain.rs +++ b/crates/transaction-pool/src/maintain.rs @@ -5,7 +5,7 @@ use crate::{ error::PoolError, metrics::MaintainPoolMetrics, traits::{CanonicalStateUpdate, TransactionPool, TransactionPoolExt}, - BlockInfo, PoolTransaction, + BlockInfo, PoolTransaction, PoolUpdateKind, }; use alloy_eips::BlockNumberOrTag; use alloy_primitives::{Address, BlockHash, BlockNumber}; @@ -352,6 +352,7 @@ pub async fn maintain_transaction_pool( changed_accounts, // all transactions mined in the new chain need to be removed from the pool mined_transactions: new_blocks.transaction_hashes().collect(), + update_kind: PoolUpdateKind::Reorg, }; pool.on_canonical_state_change(update); @@ -434,6 +435,7 @@ pub async fn maintain_transaction_pool( pending_block_blob_fee, changed_accounts, mined_transactions, + update_kind: PoolUpdateKind::Commit, }; pool.on_canonical_state_change(update); diff --git a/crates/transaction-pool/src/pool/mod.rs b/crates/transaction-pool/src/pool/mod.rs index 76b2490b12f..78cc790e942 100644 --- a/crates/transaction-pool/src/pool/mod.rs +++ b/crates/transaction-pool/src/pool/mod.rs @@ -394,7 +394,9 @@ where trace!(target: "txpool", ?update, "updating pool on canonical state change"); let block_info = update.block_info(); - let CanonicalStateUpdate { new_tip, changed_accounts, mined_transactions, .. } = update; + let CanonicalStateUpdate { + new_tip, changed_accounts, mined_transactions, update_kind, .. + } = update; self.validator.on_new_head_block(new_tip); let changed_senders = self.changed_senders(changed_accounts.into_iter()); @@ -404,6 +406,7 @@ where block_info, mined_transactions, changed_senders, + update_kind, ); // This will discard outdated transactions based on the account's nonce diff --git a/crates/transaction-pool/src/pool/txpool.rs b/crates/transaction-pool/src/pool/txpool.rs index 1d35f742ab6..3d72d6a9f15 100644 --- a/crates/transaction-pool/src/pool/txpool.rs +++ b/crates/transaction-pool/src/pool/txpool.rs @@ -15,7 +15,7 @@ use crate::{ AddedPendingTransaction, AddedTransaction, OnNewCanonicalStateOutcome, }, traits::{BestTransactionsAttributes, BlockInfo, PoolSize}, - PoolConfig, PoolResult, PoolTransaction, PriceBumpConfig, TransactionOrdering, + PoolConfig, PoolResult, PoolTransaction, PoolUpdateKind, PriceBumpConfig, TransactionOrdering, ValidPoolTransaction, U256, }; use alloy_consensus::constants::{ @@ -76,6 +76,8 @@ pub struct TxPool { all_transactions: AllTransactions, /// Transaction pool metrics metrics: TxPoolMetrics, + /// The last update kind that was applied to the pool. + latest_update_kind: Option, } // === impl TxPool === @@ -92,6 +94,7 @@ impl TxPool { all_transactions: AllTransactions::new(&config), config, metrics: Default::default(), + latest_update_kind: None, } } @@ -479,6 +482,7 @@ impl TxPool { block_info: BlockInfo, mined_transactions: Vec, changed_senders: HashMap, + update_kind: PoolUpdateKind, ) -> OnNewCanonicalStateOutcome { // update block info let block_hash = block_info.last_seen_block_hash; @@ -497,6 +501,9 @@ impl TxPool { self.update_transaction_type_metrics(); self.metrics.performed_state_updates.increment(1); + // Update the latest update kind + self.latest_update_kind = Some(update_kind); + OnNewCanonicalStateOutcome { block_hash, mined: mined_transactions, promoted, discarded } } diff --git a/crates/transaction-pool/src/traits.rs b/crates/transaction-pool/src/traits.rs index 0b3839a0436..9b4cccfb9d1 100644 --- a/crates/transaction-pool/src/traits.rs +++ b/crates/transaction-pool/src/traits.rs @@ -483,7 +483,7 @@ pub trait TransactionPoolExt: TransactionPool { /// /// ## Fee changes /// - /// The [CanonicalStateUpdate] includes the base and blob fee of the pending block, which + /// The [`CanonicalStateUpdate`] includes the base and blob fee of the pending block, which /// affects the dynamic fee requirement of pending transactions in the pool. /// /// ## EIP-4844 Blob transactions @@ -669,6 +669,15 @@ impl TransactionOrigin { } } +/// Represents the kind of update to the canonical state. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum PoolUpdateKind { + /// The update was due to a block commit. + Commit, + /// The update was due to a reorganization. + Reorg, +} + /// Represents changes after a new canonical block or range of canonical blocks was added to the /// chain. /// @@ -693,6 +702,8 @@ pub struct CanonicalStateUpdate<'a> { pub changed_accounts: Vec, /// All mined transactions in the block range. pub mined_transactions: Vec, + /// The kind of update to the canonical state. + pub update_kind: PoolUpdateKind, } impl CanonicalStateUpdate<'_> { From 7bd7c37b13960cb5c04b46ec678234596db299d6 Mon Sep 17 00:00:00 2001 From: Steven <112043913+stevencartavia@users.noreply.github.com> Date: Thu, 14 Nov 2024 05:01:23 -0600 Subject: [PATCH 161/211] feat: display warning for op-mainnet launch without pre-Bedrock state (#11765) Co-authored-by: Matthias Seitz --- crates/node/builder/src/launch/common.rs | 25 +++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/crates/node/builder/src/launch/common.rs b/crates/node/builder/src/launch/common.rs index f9106296323..7fafa9e5eac 100644 --- a/crates/node/builder/src/launch/common.rs +++ b/crates/node/builder/src/launch/common.rs @@ -40,9 +40,9 @@ use reth_node_metrics::{ use reth_primitives::Head; use reth_provider::{ providers::{BlockchainProvider, BlockchainProvider2, ProviderNodeTypes, StaticFileProvider}, - BlockHashReader, CanonStateNotificationSender, ChainSpecProvider, ProviderFactory, - ProviderResult, StageCheckpointReader, StateProviderFactory, StaticFileProviderFactory, - TreeViewer, + BlockHashReader, BlockNumReader, CanonStateNotificationSender, ChainSpecProvider, + ProviderError, ProviderFactory, ProviderResult, StageCheckpointReader, StateProviderFactory, + StaticFileProviderFactory, TreeViewer, }; use reth_prune::{PruneModes, PrunerBuilder}; use reth_rpc_api::clients::EthApiClient; @@ -814,6 +814,23 @@ where self.node_config().debug.terminate || self.node_config().debug.max_block.is_some() } + /// Ensures that the database matches chain-specific requirements. + /// + /// This checks for OP-Mainnet and ensures we have all the necessary data to progress (past + /// bedrock height) + fn ensure_chain_specific_db_checks(&self) -> ProviderResult<()> { + if self.chain_id() == Chain::optimism_mainnet() { + let latest = self.blockchain_db().last_block_number()?; + // bedrock height + if latest < 105235063 { + error!("Op-mainnet has been launched without importing the pre-Bedrock state. The chain can't progress without this. See also https://reth.rs/run/sync-op-mainnet.html?minimal-bootstrap-recommended"); + return Err(ProviderError::BestBlockNotFound) + } + } + + Ok(()) + } + /// Check if the pipeline is consistent (all stages have the checkpoint block numbers no less /// than the checkpoint of the first stage). /// @@ -857,6 +874,8 @@ where } } + self.ensure_chain_specific_db_checks()?; + Ok(None) } From 5c655e44f658db8662fb5c75ce4d7ccbaf5172e7 Mon Sep 17 00:00:00 2001 From: Steven <112043913+stevencartavia@users.noreply.github.com> Date: Thu, 14 Nov 2024 06:32:29 -0600 Subject: [PATCH 162/211] introduce standalone estimate gas type (#12344) Co-authored-by: Matthias Seitz --- crates/optimism/rpc/src/eth/call.rs | 12 +- crates/rpc/rpc-eth-api/src/helpers/call.rs | 345 +---------------- .../rpc/rpc-eth-api/src/helpers/estimate.rs | 356 ++++++++++++++++++ crates/rpc/rpc-eth-api/src/helpers/mod.rs | 1 + .../rpc-eth-api/src/helpers/transaction.rs | 13 +- crates/rpc/rpc/src/eth/helpers/call.rs | 14 +- 6 files changed, 391 insertions(+), 350 deletions(-) create mode 100644 crates/rpc/rpc-eth-api/src/helpers/estimate.rs diff --git a/crates/optimism/rpc/src/eth/call.rs b/crates/optimism/rpc/src/eth/call.rs index a76c25916f3..9b19c488889 100644 --- a/crates/optimism/rpc/src/eth/call.rs +++ b/crates/optimism/rpc/src/eth/call.rs @@ -4,7 +4,7 @@ use alloy_rpc_types_eth::transaction::TransactionRequest; use reth_evm::ConfigureEvm; use reth_primitives::revm_primitives::{BlockEnv, OptimismFields, TxEnv}; use reth_rpc_eth_api::{ - helpers::{Call, EthCall, LoadPendingBlock, LoadState, SpawnBlocking}, + helpers::{estimate::EstimateCall, Call, EthCall, LoadPendingBlock, LoadState, SpawnBlocking}, FromEthApiError, IntoEthApiError, RpcNodeCore, }; use reth_rpc_eth_types::{revm_utils::CallFees, RpcInvalidTransactionError}; @@ -13,7 +13,15 @@ use crate::{OpEthApi, OpEthApiError}; impl EthCall for OpEthApi where - Self: Call + LoadPendingBlock, + Self: EstimateCall + LoadPendingBlock, + N: RpcNodeCore, +{ +} + +impl EstimateCall for OpEthApi +where + Self: Call, + Self::Error: From, N: RpcNodeCore, { } diff --git a/crates/rpc/rpc-eth-api/src/helpers/call.rs b/crates/rpc/rpc-eth-api/src/helpers/call.rs index 6a5506ad2ad..e45590d4264 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/call.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/call.rs @@ -1,9 +1,10 @@ //! Loads a pending block from database. Helper trait for `eth_` transaction, call and trace RPC //! methods. +use super::{LoadBlock, LoadPendingBlock, LoadState, LoadTransaction, SpawnBlocking, Trace}; use crate::{ - AsEthApiError, FromEthApiError, FromEvmError, FullEthApiTypes, IntoEthApiError, RpcBlock, - RpcNodeCore, + helpers::estimate::EstimateCall, FromEthApiError, FromEvmError, FullEthApiTypes, + IntoEthApiError, RpcBlock, RpcNodeCore, }; use alloy_consensus::{BlockHeader, Header}; use alloy_eips::{eip1559::calc_next_block_base_fee, eip2930::AccessListResult}; @@ -15,16 +16,15 @@ use alloy_rpc_types_eth::{ BlockId, Bundle, EthCallResponse, StateContext, TransactionInfo, }; use futures::Future; -use reth_chainspec::{EthChainSpec, MIN_TRANSACTION_GAS}; +use reth_chainspec::EthChainSpec; use reth_evm::{ConfigureEvm, ConfigureEvmEnv}; use reth_primitives::{ revm_primitives::{ - BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ExecutionResult, HaltReason, - ResultAndState, TransactTo, TxEnv, + BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ExecutionResult, ResultAndState, TxEnv, }, TransactionSigned, }; -use reth_provider::{BlockIdReader, ChainSpecProvider, HeaderProvider, StateProvider}; +use reth_provider::{BlockIdReader, ChainSpecProvider, HeaderProvider}; use reth_revm::{database::StateProviderDatabase, db::CacheDB, DatabaseRef}; use reth_rpc_eth_types::{ cache::db::{StateCacheDbRefMutWrapper, StateProviderTraitObjWrapper}, @@ -36,19 +36,16 @@ use reth_rpc_eth_types::{ simulate::{self, EthSimulateError}, EthApiError, RevertError, RpcInvalidTransactionError, StateCacheDb, }; -use reth_rpc_server_types::constants::gas_oracle::{CALL_STIPEND_GAS, ESTIMATE_GAS_ERROR_RATIO}; use revm::{Database, DatabaseCommit, GetInspector}; use revm_inspectors::{access_list::AccessListInspector, transfer::TransferInspector}; use tracing::trace; -use super::{LoadBlock, LoadPendingBlock, LoadState, LoadTransaction, SpawnBlocking, Trace}; - /// Result type for `eth_simulateV1` RPC method. pub type SimulatedBlocksResult = Result>>, E>; /// Execution related functions for the [`EthApiServer`](crate::EthApiServer) trait in /// the `eth_` namespace. -pub trait EthCall: Call + LoadPendingBlock { +pub trait EthCall: EstimateCall + Call + LoadPendingBlock { /// Estimate gas needed for execution of the `request` at the [`BlockId`]. fn estimate_gas_at( &self, @@ -56,7 +53,7 @@ pub trait EthCall: Call + LoadPendingBlock { at: BlockId, state_override: Option, ) -> impl Future> + Send { - Call::estimate_gas_at(self, request, at, state_override) + EstimateCall::estimate_gas_at(self, request, at, state_override) } /// `eth_simulateV1` executes an arbitrary number of transactions on top of the requested state. @@ -683,284 +680,6 @@ pub trait Call: LoadState> + SpawnBlocking { Ok(index) } - /// Estimate gas needed for execution of the `request` at the [`BlockId`]. - fn estimate_gas_at( - &self, - request: TransactionRequest, - at: BlockId, - state_override: Option, - ) -> impl Future> + Send - where - Self: LoadPendingBlock, - { - async move { - let (cfg, block_env, at) = self.evm_env_at(at).await?; - - self.spawn_blocking_io(move |this| { - let state = this.state_at_block_id(at)?; - this.estimate_gas_with(cfg, block_env, request, state, state_override) - }) - .await - } - } - - /// Estimates the gas usage of the `request` with the state. - /// - /// This will execute the [`TransactionRequest`] and find the best gas limit via binary search. - /// - /// ## EVM settings - /// - /// This modifies certain EVM settings to mirror geth's `SkipAccountChecks` when transacting requests, see also: : - /// - /// - `disable_eip3607` is set to `true` - /// - `disable_base_fee` is set to `true` - /// - `nonce` is set to `None` - fn estimate_gas_with( - &self, - mut cfg: CfgEnvWithHandlerCfg, - block: BlockEnv, - mut request: TransactionRequest, - state: S, - state_override: Option, - ) -> Result - where - S: StateProvider, - { - // Disabled because eth_estimateGas is sometimes used with eoa senders - // See - cfg.disable_eip3607 = true; - - // The basefee should be ignored for eth_estimateGas and similar - // See: - // - cfg.disable_base_fee = true; - - // set nonce to None so that the correct nonce is chosen by the EVM - request.nonce = None; - - // Keep a copy of gas related request values - let tx_request_gas_limit = request.gas; - let tx_request_gas_price = request.gas_price; - // the gas limit of the corresponding block - let block_env_gas_limit = block.gas_limit; - - // Determine the highest possible gas limit, considering both the request's specified limit - // and the block's limit. - let mut highest_gas_limit = tx_request_gas_limit - .map(|tx_gas_limit| U256::from(tx_gas_limit).max(block_env_gas_limit)) - .unwrap_or(block_env_gas_limit); - - // Configure the evm env - let mut env = self.build_call_evm_env(cfg, block, request)?; - let mut db = CacheDB::new(StateProviderDatabase::new(state)); - - // Apply any state overrides if specified. - if let Some(state_override) = state_override { - apply_state_overrides(state_override, &mut db).map_err(Self::Error::from_eth_err)?; - } - - // Optimize for simple transfer transactions, potentially reducing the gas estimate. - if env.tx.data.is_empty() { - if let TransactTo::Call(to) = env.tx.transact_to { - if let Ok(code) = db.db.account_code(to) { - let no_code_callee = code.map(|code| code.is_empty()).unwrap_or(true); - if no_code_callee { - // If the tx is a simple transfer (call to an account with no code) we can - // shortcircuit. But simply returning - // `MIN_TRANSACTION_GAS` is dangerous because there might be additional - // field combos that bump the price up, so we try executing the function - // with the minimum gas limit to make sure. - let mut env = env.clone(); - env.tx.gas_limit = MIN_TRANSACTION_GAS; - if let Ok((res, _)) = self.transact(&mut db, env) { - if res.result.is_success() { - return Ok(U256::from(MIN_TRANSACTION_GAS)) - } - } - } - } - } - } - - // Check funds of the sender (only useful to check if transaction gas price is more than 0). - // - // The caller allowance is check by doing `(account.balance - tx.value) / tx.gas_price` - if env.tx.gas_price > U256::ZERO { - // cap the highest gas limit by max gas caller can afford with given gas price - highest_gas_limit = highest_gas_limit - .min(caller_gas_allowance(&mut db, &env.tx).map_err(Self::Error::from_eth_err)?); - } - - // We can now normalize the highest gas limit to a u64 - let mut highest_gas_limit: u64 = highest_gas_limit - .try_into() - .unwrap_or_else(|_| self.provider().chain_spec().max_gas_limit()); - - // If the provided gas limit is less than computed cap, use that - env.tx.gas_limit = env.tx.gas_limit.min(highest_gas_limit); - - trace!(target: "rpc::eth::estimate", ?env, "Starting gas estimation"); - - // Execute the transaction with the highest possible gas limit. - let (mut res, mut env) = match self.transact(&mut db, env.clone()) { - // Handle the exceptional case where the transaction initialization uses too much gas. - // If the gas price or gas limit was specified in the request, retry the transaction - // with the block's gas limit to determine if the failure was due to - // insufficient gas. - Err(err) - if err.is_gas_too_high() && - (tx_request_gas_limit.is_some() || tx_request_gas_price.is_some()) => - { - return Err(self.map_out_of_gas_err(block_env_gas_limit, env, &mut db)) - } - // Propagate other results (successful or other errors). - ethres => ethres?, - }; - - let gas_refund = match res.result { - ExecutionResult::Success { gas_refunded, .. } => gas_refunded, - ExecutionResult::Halt { reason, gas_used } => { - // here we don't check for invalid opcode because already executed with highest gas - // limit - return Err(RpcInvalidTransactionError::halt(reason, gas_used).into_eth_err()) - } - ExecutionResult::Revert { output, .. } => { - // if price or limit was included in the request then we can execute the request - // again with the block's gas limit to check if revert is gas related or not - return if tx_request_gas_limit.is_some() || tx_request_gas_price.is_some() { - Err(self.map_out_of_gas_err(block_env_gas_limit, env, &mut db)) - } else { - // the transaction did revert - Err(RpcInvalidTransactionError::Revert(RevertError::new(output)).into_eth_err()) - } - } - }; - - // At this point we know the call succeeded but want to find the _best_ (lowest) gas the - // transaction succeeds with. We find this by doing a binary search over the possible range. - - // we know the tx succeeded with the configured gas limit, so we can use that as the - // highest, in case we applied a gas cap due to caller allowance above - highest_gas_limit = env.tx.gas_limit; - - // NOTE: this is the gas the transaction used, which is less than the - // transaction requires to succeed. - let mut gas_used = res.result.gas_used(); - // the lowest value is capped by the gas used by the unconstrained transaction - let mut lowest_gas_limit = gas_used.saturating_sub(1); - - // As stated in Geth, there is a good chance that the transaction will pass if we set the - // gas limit to the execution gas used plus the gas refund, so we check this first - // 1 { - // An estimation error is allowed once the current gas limit range used in the binary - // search is small enough (less than 1.5% of the highest gas limit) - // { - // Decrease the highest gas limit if gas is too high - highest_gas_limit = mid_gas_limit; - } - Err(err) if err.is_gas_too_low() => { - // Increase the lowest gas limit if gas is too low - lowest_gas_limit = mid_gas_limit; - } - // Handle other cases, including successful transactions. - ethres => { - // Unpack the result and environment if the transaction was successful. - (res, env) = ethres?; - // Update the estimated gas range based on the transaction result. - update_estimated_gas_range( - res.result, - mid_gas_limit, - &mut highest_gas_limit, - &mut lowest_gas_limit, - )?; - } - } - - // New midpoint - mid_gas_limit = ((highest_gas_limit as u128 + lowest_gas_limit as u128) / 2) as u64; - } - - Ok(U256::from(highest_gas_limit)) - } - - /// Executes the requests again after an out of gas error to check if the error is gas related - /// or not - #[inline] - fn map_out_of_gas_err( - &self, - env_gas_limit: U256, - mut env: EnvWithHandlerCfg, - db: &mut DB, - ) -> Self::Error - where - DB: Database, - EthApiError: From, - { - let req_gas_limit = env.tx.gas_limit; - env.tx.gas_limit = env_gas_limit.try_into().unwrap_or(u64::MAX); - let (res, _) = match self.transact(db, env) { - Ok(res) => res, - Err(err) => return err, - }; - match res.result { - ExecutionResult::Success { .. } => { - // transaction succeeded by manually increasing the gas limit to - // highest, which means the caller lacks funds to pay for the tx - RpcInvalidTransactionError::BasicOutOfGas(req_gas_limit).into_eth_err() - } - ExecutionResult::Revert { output, .. } => { - // reverted again after bumping the limit - RpcInvalidTransactionError::Revert(RevertError::new(output)).into_eth_err() - } - ExecutionResult::Halt { reason, .. } => { - RpcInvalidTransactionError::EvmHalt(reason).into_eth_err() - } - } - } - /// Configures a new [`TxEnv`] for the [`TransactionRequest`] /// /// All [`TxEnv`] fields are derived from the given [`TransactionRequest`], if fields are @@ -1125,51 +844,3 @@ pub trait Call: LoadState> + SpawnBlocking { Ok(env) } } - -/// Updates the highest and lowest gas limits for binary search based on the execution result. -/// -/// This function refines the gas limit estimates used in a binary search to find the optimal -/// gas limit for a transaction. It adjusts the highest or lowest gas limits depending on -/// whether the execution succeeded, reverted, or halted due to specific reasons. -#[inline] -fn update_estimated_gas_range( - result: ExecutionResult, - tx_gas_limit: u64, - highest_gas_limit: &mut u64, - lowest_gas_limit: &mut u64, -) -> Result<(), EthApiError> { - match result { - ExecutionResult::Success { .. } => { - // Cap the highest gas limit with the succeeding gas limit. - *highest_gas_limit = tx_gas_limit; - } - ExecutionResult::Revert { .. } => { - // Increase the lowest gas limit. - *lowest_gas_limit = tx_gas_limit; - } - ExecutionResult::Halt { reason, .. } => { - match reason { - HaltReason::OutOfGas(_) | HaltReason::InvalidFEOpcode => { - // Both `OutOfGas` and `InvalidEFOpcode` can occur dynamically if the gas - // left is too low. Treat this as an out of gas - // condition, knowing that the call succeeds with a - // higher gas limit. - // - // Common usage of invalid opcode in OpenZeppelin: - // - - // Increase the lowest gas limit. - *lowest_gas_limit = tx_gas_limit; - } - err => { - // These cases should be unreachable because we know the transaction - // succeeds, but if they occur, treat them as an - // error. - return Err(RpcInvalidTransactionError::EvmHalt(err).into_eth_err()) - } - } - } - }; - - Ok(()) -} diff --git a/crates/rpc/rpc-eth-api/src/helpers/estimate.rs b/crates/rpc/rpc-eth-api/src/helpers/estimate.rs new file mode 100644 index 00000000000..37a68577fb0 --- /dev/null +++ b/crates/rpc/rpc-eth-api/src/helpers/estimate.rs @@ -0,0 +1,356 @@ +//! Estimate gas needed implementation + +use super::{Call, LoadPendingBlock}; +use crate::{AsEthApiError, FromEthApiError, IntoEthApiError}; +use alloy_primitives::U256; +use alloy_rpc_types_eth::{state::StateOverride, transaction::TransactionRequest, BlockId}; +use futures::Future; +use reth_chainspec::{EthChainSpec, MIN_TRANSACTION_GAS}; +use reth_primitives::revm_primitives::{ + BlockEnv, CfgEnvWithHandlerCfg, ExecutionResult, HaltReason, TransactTo, +}; +use reth_provider::{ChainSpecProvider, StateProvider}; +use reth_revm::{database::StateProviderDatabase, db::CacheDB}; +use reth_rpc_eth_types::{ + revm_utils::{apply_state_overrides, caller_gas_allowance}, + EthApiError, RevertError, RpcInvalidTransactionError, +}; +use reth_rpc_server_types::constants::gas_oracle::{CALL_STIPEND_GAS, ESTIMATE_GAS_ERROR_RATIO}; +use revm_primitives::{db::Database, EnvWithHandlerCfg}; +use tracing::trace; + +/// Gas execution estimates +pub trait EstimateCall: Call { + /// Estimates the gas usage of the `request` with the state. + /// + /// This will execute the [`TransactionRequest`] and find the best gas limit via binary search. + /// + /// ## EVM settings + /// + /// This modifies certain EVM settings to mirror geth's `SkipAccountChecks` when transacting requests, see also: : + /// + /// - `disable_eip3607` is set to `true` + /// - `disable_base_fee` is set to `true` + /// - `nonce` is set to `None` + fn estimate_gas_with( + &self, + mut cfg: CfgEnvWithHandlerCfg, + block: BlockEnv, + mut request: TransactionRequest, + state: S, + state_override: Option, + ) -> Result + where + S: StateProvider, + { + // Disabled because eth_estimateGas is sometimes used with eoa senders + // See + cfg.disable_eip3607 = true; + + // The basefee should be ignored for eth_estimateGas and similar + // See: + // + cfg.disable_base_fee = true; + + // set nonce to None so that the correct nonce is chosen by the EVM + request.nonce = None; + + // Keep a copy of gas related request values + let tx_request_gas_limit = request.gas; + let tx_request_gas_price = request.gas_price; + // the gas limit of the corresponding block + let block_env_gas_limit = block.gas_limit; + + // Determine the highest possible gas limit, considering both the request's specified limit + // and the block's limit. + let mut highest_gas_limit = tx_request_gas_limit + .map(|tx_gas_limit| U256::from(tx_gas_limit).max(block_env_gas_limit)) + .unwrap_or(block_env_gas_limit); + + // Configure the evm env + let mut env = self.build_call_evm_env(cfg, block, request)?; + let mut db = CacheDB::new(StateProviderDatabase::new(state)); + + // Apply any state overrides if specified. + if let Some(state_override) = state_override { + apply_state_overrides(state_override, &mut db).map_err(Self::Error::from_eth_err)?; + } + + // Optimize for simple transfer transactions, potentially reducing the gas estimate. + if env.tx.data.is_empty() { + if let TransactTo::Call(to) = env.tx.transact_to { + if let Ok(code) = db.db.account_code(to) { + let no_code_callee = code.map(|code| code.is_empty()).unwrap_or(true); + if no_code_callee { + // If the tx is a simple transfer (call to an account with no code) we can + // shortcircuit. But simply returning + // `MIN_TRANSACTION_GAS` is dangerous because there might be additional + // field combos that bump the price up, so we try executing the function + // with the minimum gas limit to make sure. + let mut env = env.clone(); + env.tx.gas_limit = MIN_TRANSACTION_GAS; + if let Ok((res, _)) = self.transact(&mut db, env) { + if res.result.is_success() { + return Ok(U256::from(MIN_TRANSACTION_GAS)) + } + } + } + } + } + } + + // Check funds of the sender (only useful to check if transaction gas price is more than 0). + // + // The caller allowance is check by doing `(account.balance - tx.value) / tx.gas_price` + if env.tx.gas_price > U256::ZERO { + // cap the highest gas limit by max gas caller can afford with given gas price + highest_gas_limit = highest_gas_limit + .min(caller_gas_allowance(&mut db, &env.tx).map_err(Self::Error::from_eth_err)?); + } + + // We can now normalize the highest gas limit to a u64 + let mut highest_gas_limit: u64 = highest_gas_limit + .try_into() + .unwrap_or_else(|_| self.provider().chain_spec().max_gas_limit()); + + // If the provided gas limit is less than computed cap, use that + env.tx.gas_limit = env.tx.gas_limit.min(highest_gas_limit); + + trace!(target: "rpc::eth::estimate", ?env, "Starting gas estimation"); + + // Execute the transaction with the highest possible gas limit. + let (mut res, mut env) = match self.transact(&mut db, env.clone()) { + // Handle the exceptional case where the transaction initialization uses too much gas. + // If the gas price or gas limit was specified in the request, retry the transaction + // with the block's gas limit to determine if the failure was due to + // insufficient gas. + Err(err) + if err.is_gas_too_high() && + (tx_request_gas_limit.is_some() || tx_request_gas_price.is_some()) => + { + return Err(self.map_out_of_gas_err(block_env_gas_limit, env, &mut db)) + } + // Propagate other results (successful or other errors). + ethres => ethres?, + }; + + let gas_refund = match res.result { + ExecutionResult::Success { gas_refunded, .. } => gas_refunded, + ExecutionResult::Halt { reason, gas_used } => { + // here we don't check for invalid opcode because already executed with highest gas + // limit + return Err(RpcInvalidTransactionError::halt(reason, gas_used).into_eth_err()) + } + ExecutionResult::Revert { output, .. } => { + // if price or limit was included in the request then we can execute the request + // again with the block's gas limit to check if revert is gas related or not + return if tx_request_gas_limit.is_some() || tx_request_gas_price.is_some() { + Err(self.map_out_of_gas_err(block_env_gas_limit, env, &mut db)) + } else { + // the transaction did revert + Err(RpcInvalidTransactionError::Revert(RevertError::new(output)).into_eth_err()) + } + } + }; + + // At this point we know the call succeeded but want to find the _best_ (lowest) gas the + // transaction succeeds with. We find this by doing a binary search over the possible range. + + // we know the tx succeeded with the configured gas limit, so we can use that as the + // highest, in case we applied a gas cap due to caller allowance above + highest_gas_limit = env.tx.gas_limit; + + // NOTE: this is the gas the transaction used, which is less than the + // transaction requires to succeed. + let mut gas_used = res.result.gas_used(); + // the lowest value is capped by the gas used by the unconstrained transaction + let mut lowest_gas_limit = gas_used.saturating_sub(1); + + // As stated in Geth, there is a good chance that the transaction will pass if we set the + // gas limit to the execution gas used plus the gas refund, so we check this first + // 1 { + // An estimation error is allowed once the current gas limit range used in the binary + // search is small enough (less than 1.5% of the highest gas limit) + // { + // Decrease the highest gas limit if gas is too high + highest_gas_limit = mid_gas_limit; + } + Err(err) if err.is_gas_too_low() => { + // Increase the lowest gas limit if gas is too low + lowest_gas_limit = mid_gas_limit; + } + // Handle other cases, including successful transactions. + ethres => { + // Unpack the result and environment if the transaction was successful. + (res, env) = ethres?; + // Update the estimated gas range based on the transaction result. + update_estimated_gas_range( + res.result, + mid_gas_limit, + &mut highest_gas_limit, + &mut lowest_gas_limit, + )?; + } + } + + // New midpoint + mid_gas_limit = ((highest_gas_limit as u128 + lowest_gas_limit as u128) / 2) as u64; + } + + Ok(U256::from(highest_gas_limit)) + } + + /// Estimate gas needed for execution of the `request` at the [`BlockId`]. + fn estimate_gas_at( + &self, + request: TransactionRequest, + at: BlockId, + state_override: Option, + ) -> impl Future> + Send + where + Self: LoadPendingBlock, + { + async move { + let (cfg, block_env, at) = self.evm_env_at(at).await?; + + self.spawn_blocking_io(move |this| { + let state = this.state_at_block_id(at)?; + EstimateCall::estimate_gas_with( + &this, + cfg, + block_env, + request, + state, + state_override, + ) + }) + .await + } + } + + /// Executes the requests again after an out of gas error to check if the error is gas related + /// or not + #[inline] + fn map_out_of_gas_err( + &self, + env_gas_limit: U256, + mut env: EnvWithHandlerCfg, + db: &mut DB, + ) -> Self::Error + where + DB: Database, + EthApiError: From, + { + let req_gas_limit = env.tx.gas_limit; + env.tx.gas_limit = env_gas_limit.try_into().unwrap_or(u64::MAX); + let (res, _) = match self.transact(db, env) { + Ok(res) => res, + Err(err) => return err, + }; + match res.result { + ExecutionResult::Success { .. } => { + // transaction succeeded by manually increasing the gas limit to + // highest, which means the caller lacks funds to pay for the tx + RpcInvalidTransactionError::BasicOutOfGas(req_gas_limit).into_eth_err() + } + ExecutionResult::Revert { output, .. } => { + // reverted again after bumping the limit + RpcInvalidTransactionError::Revert(RevertError::new(output)).into_eth_err() + } + ExecutionResult::Halt { reason, .. } => { + RpcInvalidTransactionError::EvmHalt(reason).into_eth_err() + } + } + } +} + +/// Updates the highest and lowest gas limits for binary search based on the execution result. +/// +/// This function refines the gas limit estimates used in a binary search to find the optimal +/// gas limit for a transaction. It adjusts the highest or lowest gas limits depending on +/// whether the execution succeeded, reverted, or halted due to specific reasons. +#[inline] +pub fn update_estimated_gas_range( + result: ExecutionResult, + tx_gas_limit: u64, + highest_gas_limit: &mut u64, + lowest_gas_limit: &mut u64, +) -> Result<(), EthApiError> { + match result { + ExecutionResult::Success { .. } => { + // Cap the highest gas limit with the succeeding gas limit. + *highest_gas_limit = tx_gas_limit; + } + ExecutionResult::Revert { .. } => { + // Increase the lowest gas limit. + *lowest_gas_limit = tx_gas_limit; + } + ExecutionResult::Halt { reason, .. } => { + match reason { + HaltReason::OutOfGas(_) | HaltReason::InvalidFEOpcode => { + // Both `OutOfGas` and `InvalidEFOpcode` can occur dynamically if the gas + // left is too low. Treat this as an out of gas + // condition, knowing that the call succeeds with a + // higher gas limit. + // + // Common usage of invalid opcode in OpenZeppelin: + // + + // Increase the lowest gas limit. + *lowest_gas_limit = tx_gas_limit; + } + err => { + // These cases should be unreachable because we know the transaction + // succeeds, but if they occur, treat them as an + // error. + return Err(RpcInvalidTransactionError::EvmHalt(err).into_eth_err()) + } + } + } + }; + + Ok(()) +} diff --git a/crates/rpc/rpc-eth-api/src/helpers/mod.rs b/crates/rpc/rpc-eth-api/src/helpers/mod.rs index a881330b045..174cb3bad04 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/mod.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/mod.rs @@ -17,6 +17,7 @@ pub mod block; pub mod blocking_task; pub mod call; +pub mod estimate; pub mod fee; pub mod pending_block; pub mod receipt; diff --git a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs index e041b8c4605..afe1c513b69 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs @@ -18,13 +18,12 @@ use reth_rpc_types_compat::transaction::{from_recovered, from_recovered_with_blo use reth_transaction_pool::{PoolTransaction, TransactionOrigin, TransactionPool}; use std::sync::Arc; -use crate::{ - FromEthApiError, FullEthApiTypes, IntoEthApiError, RpcNodeCore, RpcNodeCoreExt, RpcReceipt, - RpcTransaction, -}; - use super::{ - Call, EthApiSpec, EthSigner, LoadBlock, LoadPendingBlock, LoadReceipt, LoadState, SpawnBlocking, + EthApiSpec, EthSigner, LoadBlock, LoadPendingBlock, LoadReceipt, LoadState, SpawnBlocking, +}; +use crate::{ + helpers::estimate::EstimateCall, FromEthApiError, FullEthApiTypes, IntoEthApiError, + RpcNodeCore, RpcNodeCoreExt, RpcReceipt, RpcTransaction, }; /// Transaction related functions for the [`EthApiServer`](crate::EthApiServer) trait in @@ -348,7 +347,7 @@ pub trait EthTransactions: LoadTransaction { mut request: TransactionRequest, ) -> impl Future> + Send where - Self: EthApiSpec + LoadBlock + LoadPendingBlock + Call, + Self: EthApiSpec + LoadBlock + LoadPendingBlock + EstimateCall, { async move { let from = match request.from { diff --git a/crates/rpc/rpc/src/eth/helpers/call.rs b/crates/rpc/rpc/src/eth/helpers/call.rs index 1c1e35a5df8..c0594c023fa 100644 --- a/crates/rpc/rpc/src/eth/helpers/call.rs +++ b/crates/rpc/rpc/src/eth/helpers/call.rs @@ -1,13 +1,14 @@ //! Contains RPC handler implementations specific to endpoints that call/execute within evm. +use crate::EthApi; use alloy_consensus::Header; use reth_evm::ConfigureEvm; -use reth_rpc_eth_api::helpers::{Call, EthCall, LoadPendingBlock, LoadState, SpawnBlocking}; - -use crate::EthApi; +use reth_rpc_eth_api::helpers::{ + estimate::EstimateCall, Call, EthCall, LoadPendingBlock, LoadState, SpawnBlocking, +}; impl EthCall for EthApi where - Self: Call + LoadPendingBlock + Self: EstimateCall + LoadPendingBlock { } @@ -26,3 +27,8 @@ where self.inner.max_simulate_blocks() } } + +impl EstimateCall for EthApi where + Self: Call +{ +} From ff6b78a3627a0fb03da5ab2093672618cd3b70b1 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Thu, 14 Nov 2024 17:50:32 +0400 Subject: [PATCH 163/211] feat: move body writing to `BlockWriter` trait (#12538) --- crates/net/p2p/src/bodies/response.rs | 8 +++ crates/stages/stages/src/stages/bodies.rs | 72 +++++++------------ crates/storage/db-models/src/blocks.rs | 2 +- .../src/providers/database/provider.rs | 46 +++++++++++- crates/storage/provider/src/traits/block.rs | 12 +++- 5 files changed, 89 insertions(+), 51 deletions(-) diff --git a/crates/net/p2p/src/bodies/response.rs b/crates/net/p2p/src/bodies/response.rs index 153d7d39d4e..11aaab17a30 100644 --- a/crates/net/p2p/src/bodies/response.rs +++ b/crates/net/p2p/src/bodies/response.rs @@ -32,6 +32,14 @@ impl BlockResponse { Self::Empty(header) => header.difficulty, } } + + /// Return the reference to the response body + pub fn into_body(self) -> Option { + match self { + Self::Full(block) => Some(block.body), + Self::Empty(_) => None, + } + } } impl InMemorySize for BlockResponse { diff --git a/crates/stages/stages/src/stages/bodies.rs b/crates/stages/stages/src/stages/bodies.rs index eae61b088fd..c4676b2728c 100644 --- a/crates/stages/stages/src/stages/bodies.rs +++ b/crates/stages/stages/src/stages/bodies.rs @@ -7,17 +7,16 @@ use futures_util::TryStreamExt; use tracing::*; use alloy_primitives::TxNumber; -use reth_db::tables; +use reth_db::{tables, transaction::DbTx}; use reth_db_api::{ cursor::{DbCursorRO, DbCursorRW}, - models::{StoredBlockBodyIndices, StoredBlockOmmers, StoredBlockWithdrawals}, transaction::DbTxMut, }; use reth_network_p2p::bodies::{downloader::BodyDownloader, response::BlockResponse}; use reth_primitives::StaticFileSegment; use reth_provider::{ providers::{StaticFileProvider, StaticFileWriter}, - BlockReader, DBProvider, ProviderError, StaticFileProviderFactory, StatsReader, + BlockReader, BlockWriter, DBProvider, ProviderError, StaticFileProviderFactory, StatsReader, }; use reth_stages_api::{ EntitiesCheckpoint, ExecInput, ExecOutput, Stage, StageCheckpoint, StageError, StageId, @@ -72,7 +71,11 @@ impl BodyStage { impl Stage for BodyStage where - Provider: DBProvider + StaticFileProviderFactory + StatsReader + BlockReader, + Provider: DBProvider + + StaticFileProviderFactory + + StatsReader + + BlockReader + + BlockWriter, D: BodyDownloader, { /// Return the id of the stage @@ -116,15 +119,13 @@ where } let (from_block, to_block) = input.next_block_range().into_inner(); - // Cursors used to write bodies, ommers and transactions - let tx = provider.tx_ref(); - let mut block_indices_cursor = tx.cursor_write::()?; - let mut tx_block_cursor = tx.cursor_write::()?; - let mut ommers_cursor = tx.cursor_write::()?; - let mut withdrawals_cursor = tx.cursor_write::()?; - // Get id for the next tx_num of zero if there are no transactions. - let mut next_tx_num = tx_block_cursor.last()?.map(|(id, _)| id + 1).unwrap_or_default(); + let mut next_tx_num = provider + .tx_ref() + .cursor_read::()? + .last()? + .map(|(id, _)| id + 1) + .unwrap_or_default(); let static_file_provider = provider.static_file_provider(); let mut static_file_producer = @@ -166,17 +167,10 @@ where let buffer = self.buffer.take().ok_or(StageError::MissingDownloadBuffer)?; trace!(target: "sync::stages::bodies", bodies_len = buffer.len(), "Writing blocks"); let mut highest_block = from_block; - for response in buffer { - // Write block - let block_number = response.block_number(); - let block_indices = StoredBlockBodyIndices { - first_tx_num: next_tx_num, - tx_count: match &response { - BlockResponse::Full(block) => block.body.transactions.len() as u64, - BlockResponse::Empty(_) => 0, - }, - }; + // Firstly, write transactions to static files + for response in &buffer { + let block_number = response.block_number(); // Increment block on static file header. if block_number > 0 { @@ -195,15 +189,10 @@ where match response { BlockResponse::Full(block) => { - // write transaction block index - if !block.body.transactions.is_empty() { - tx_block_cursor.append(block_indices.last_tx_num(), block.number)?; - } - // Write transactions - for transaction in block.body.transactions { + for transaction in &block.body.transactions { let appended_tx_number = static_file_producer - .append_transaction(next_tx_num, &transaction.into())?; + .append_transaction(next_tx_num, &transaction.clone().into())?; if appended_tx_number != next_tx_num { // This scenario indicates a critical error in the logic of adding new @@ -218,32 +207,19 @@ where // Increment transaction id for each transaction. next_tx_num += 1; } - - // Write ommers if any - if !block.body.ommers.is_empty() { - ommers_cursor.append( - block_number, - StoredBlockOmmers { ommers: block.body.ommers }, - )?; - } - - // Write withdrawals if any - if let Some(withdrawals) = block.body.withdrawals { - if !withdrawals.is_empty() { - withdrawals_cursor - .append(block_number, StoredBlockWithdrawals { withdrawals })?; - } - } } BlockResponse::Empty(_) => {} }; - // insert block meta - block_indices_cursor.append(block_number, block_indices)?; - highest_block = block_number; } + // Write bodies to database. This will NOT write transactions to database as we've already + // written them directly to static files. + provider.append_block_bodies( + buffer.into_iter().map(|response| (response.block_number(), response.into_body())), + )?; + // The stage is "done" if: // - We got fewer blocks than our target // - We reached our target and the target was not limited by the batch size of the stage diff --git a/crates/storage/db-models/src/blocks.rs b/crates/storage/db-models/src/blocks.rs index ed1d7fb6772..be7661c8b12 100644 --- a/crates/storage/db-models/src/blocks.rs +++ b/crates/storage/db-models/src/blocks.rs @@ -12,7 +12,7 @@ pub type NumTransactions = u64; /// /// It has the pointer to the transaction Number of the first /// transaction in the block and the total number of transactions. -#[derive(Debug, Default, Eq, PartialEq, Clone, Serialize, Deserialize, Compact)] +#[derive(Debug, Default, Eq, PartialEq, Clone, Copy, Serialize, Deserialize, Compact)] #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] #[add_arbitrary_tests(compact)] pub struct StoredBlockBodyIndices { diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index eef0ff5b668..20d01932a15 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -3250,7 +3250,7 @@ impl + } let block_indices = StoredBlockBodyIndices { first_tx_num, tx_count }; - self.tx.put::(block_number, block_indices.clone())?; + self.tx.put::(block_number, block_indices)?; durations_recorder.record_relative(metrics::Action::InsertBlockBodyIndices); if !block_indices.is_empty() { @@ -3268,6 +3268,50 @@ impl + Ok(block_indices) } + fn append_block_bodies( + &self, + bodies: impl Iterator)>, + ) -> ProviderResult<()> { + let mut block_indices_cursor = self.tx.cursor_write::()?; + let mut tx_block_cursor = self.tx.cursor_write::()?; + let mut ommers_cursor = self.tx.cursor_write::()?; + let mut withdrawals_cursor = self.tx.cursor_write::()?; + + // Get id for the next tx_num of zero if there are no transactions. + let mut next_tx_num = tx_block_cursor.last()?.map(|(id, _)| id + 1).unwrap_or_default(); + + for (block_number, body) in bodies { + let tx_count = body.as_ref().map(|b| b.transactions.len() as u64).unwrap_or_default(); + let block_indices = StoredBlockBodyIndices { first_tx_num: next_tx_num, tx_count }; + + // insert block meta + block_indices_cursor.append(block_number, block_indices)?; + + next_tx_num += tx_count; + let Some(body) = body else { continue }; + + // write transaction block index + if !body.transactions.is_empty() { + tx_block_cursor.append(block_indices.last_tx_num(), block_number)?; + } + + // Write ommers if any + if !body.ommers.is_empty() { + ommers_cursor.append(block_number, StoredBlockOmmers { ommers: body.ommers })?; + } + + // Write withdrawals if any + if let Some(withdrawals) = body.withdrawals { + if !withdrawals.is_empty() { + withdrawals_cursor + .append(block_number, StoredBlockWithdrawals { withdrawals })?; + } + } + } + + Ok(()) + } + /// TODO(joshie): this fn should be moved to `UnifiedStorageWriter` eventually fn append_blocks_with_state( &self, diff --git a/crates/storage/provider/src/traits/block.rs b/crates/storage/provider/src/traits/block.rs index 7202c405f06..5cb60c2f42a 100644 --- a/crates/storage/provider/src/traits/block.rs +++ b/crates/storage/provider/src/traits/block.rs @@ -1,7 +1,7 @@ use alloy_primitives::BlockNumber; use reth_db_api::models::StoredBlockBodyIndices; use reth_execution_types::{Chain, ExecutionOutcome}; -use reth_primitives::SealedBlockWithSenders; +use reth_primitives::{BlockBody, SealedBlockWithSenders}; use reth_storage_errors::provider::ProviderResult; use reth_trie::{updates::TrieUpdates, HashedPostStateSorted}; use std::ops::RangeInclusive; @@ -40,6 +40,16 @@ pub trait BlockWriter: Send + Sync { fn insert_block(&self, block: SealedBlockWithSenders) -> ProviderResult; + /// Appends a batch of block bodies extending the canonical chain. This is invoked during + /// `Bodies` stage and does not write to `TransactionHashNumbers` and `TransactionSenders` + /// tables which are populated on later stages. + /// + /// Bodies are passed as [`Option`]s, if body is `None` the corresponding block is empty. + fn append_block_bodies( + &self, + bodies: impl Iterator)>, + ) -> ProviderResult<()>; + /// Appends a batch of sealed blocks to the blockchain, including sender information, and /// updates the post-state. /// From 3154a4f66c0f31c5cb9e6e28d58130bef219eb30 Mon Sep 17 00:00:00 2001 From: Noisy <125606576+donatik27@users.noreply.github.com> Date: Thu, 14 Nov 2024 16:35:04 +0100 Subject: [PATCH 164/211] Documentation Improvements: Grammar Corrections and Clarity Enhancements (#12545) --- docs/crates/db.md | 6 +++--- docs/repo/layout.md | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/crates/db.md b/docs/crates/db.md index 79eeae5ee4f..688f7ea76cc 100644 --- a/docs/crates/db.md +++ b/docs/crates/db.md @@ -212,7 +212,7 @@ pub trait DbTxMut: Send + Sync { Let's take a look at the `DbTx` and `DbTxMut` traits in action. -Revisiting the `DatabaseProvider` struct as an exampl, the `DatabaseProvider::header_by_number()` function uses the `DbTx::get()` function to get a header from the `Headers` table. +Revisiting the `DatabaseProvider` struct as an example, the `DatabaseProvider::header_by_number()` function uses the `DbTx::get()` function to get a header from the `Headers` table. [File: crates/storage/provider/src/providers/database/provider.rs](https://github.com/paradigmxyz/reth/blob/bf9cac7571f018fec581fe3647862dab527aeafb/crates/storage/provider/src/providers/database/provider.rs#L1319-L1336) @@ -267,7 +267,7 @@ let mut headers_cursor = provider.tx_ref().cursor_read::()?; let headers_walker = headers_cursor.walk_range(block_range.clone())?; ``` -Lets look at an examples of how cursors are used. The code snippet below contains the `unwind` method from the `BodyStage` defined in the `stages` crate. This function is responsible for unwinding any changes to the database if there is an error when executing the body stage within the Reth pipeline. +Let's look at an examples of how cursors are used. The code snippet below contains the `unwind` method from the `BodyStage` defined in the `stages` crate. This function is responsible for unwinding any changes to the database if there is an error when executing the body stage within the Reth pipeline. [File: crates/stages/stages/src/stages/bodies.rs](https://github.com/paradigmxyz/reth/blob/bf9cac7571f018fec581fe3647862dab527aeafb/crates/stages/stages/src/stages/bodies.rs#L267-L345) @@ -330,7 +330,7 @@ While this is a brief look at how cursors work in the context of database tables ## Summary -This chapter was packed with information, so lets do a quick review. The database is comprised of tables, with each table being a collection of key-value pairs representing various pieces of data in the blockchain. Any struct that implements the `Database` trait can view, update or delete entries in the various tables. The database design leverages nested traits and generic associated types to provide methods to interact with each table in the database. +This chapter was packed with information, so let's do a quick review. The database is comprised of tables, with each table being a collection of key-value pairs representing various pieces of data in the blockchain. Any struct that implements the `Database` trait can view, update or delete entries in the various tables. The database design leverages nested traits and generic associated types to provide methods to interact with each table in the database.
diff --git a/docs/repo/layout.md b/docs/repo/layout.md index f78abe96122..dcb475e020e 100644 --- a/docs/repo/layout.md +++ b/docs/repo/layout.md @@ -132,7 +132,7 @@ The IPC transport lives in [`rpc/ipc`](../../crates/rpc/ipc). - Supported transports: HTTP, WS, IPC - Supported namespaces: `eth_`, `engine_`, `debug_` - [`rpc/rpc-eth-api`](../../crates/rpc/rpc-eth-api/): Reth RPC 'eth' namespace API (including interface and implementation), this crate is re-exported by `rpc/rpc-api` -- [`rpc/rpc-eth-types`](../../crates/rpc/rpc-eth-types/): Types `supporting implementation` of 'eth' namespace RPC server API +- [`rpc/rpc-eth-types`](../../crates/rpc/rpc-eth-types/): Types `supporting the implementation` of 'eth' namespace RPC server API - [`rpc/rpc-server-types`](../../crates/rpc/rpc-server-types/): RPC server types and constants #### Utilities Crates @@ -159,7 +159,7 @@ These crates define primitive types or algorithms. ### Optimism -Crates related to the Optimism rollup are lives in [optimism](../../crates/optimism/). +Crates related to the Optimism rollup live in [optimism](../../crates/optimism/). ### Misc From 77e687c28c9f4b6b9eb38e7e684622163536ea6c Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Thu, 14 Nov 2024 19:23:15 +0400 Subject: [PATCH 165/211] feat: relax `BodyStage` bounds (#12539) --- crates/primitives-traits/src/block/body.rs | 69 ++----------------- crates/primitives-traits/src/node.rs | 2 +- crates/primitives/src/block.rs | 8 +++ crates/primitives/src/transaction/mod.rs | 16 +++++ crates/stages/stages/src/stages/bodies.rs | 16 ++--- .../stages/stages/src/test_utils/test_db.rs | 2 +- .../src/providers/database/provider.rs | 2 + .../src/providers/static_file/writer.rs | 4 +- crates/storage/provider/src/traits/block.rs | 7 +- 9 files changed, 47 insertions(+), 79 deletions(-) diff --git a/crates/primitives-traits/src/block/body.rs b/crates/primitives-traits/src/block/body.rs index 6ec184a2154..c5f15aefea6 100644 --- a/crates/primitives-traits/src/block/body.rs +++ b/crates/primitives-traits/src/block/body.rs @@ -1,10 +1,8 @@ //! Block body abstraction. -use alloc::{fmt, vec::Vec}; +use alloc::fmt; -use alloy_consensus::{BlockHeader, Transaction, TxType}; -use alloy_eips::{eip4895::Withdrawal, eip7685::Requests}; -use alloy_primitives::{Address, B256}; +use alloy_consensus::Transaction; use crate::InMemorySize; @@ -26,67 +24,8 @@ pub trait BlockBody: { /// Ordered list of signed transactions as committed in block. // todo: requires trait for signed transaction - type SignedTransaction: Transaction; - - /// Header type (uncle blocks). - type Header: BlockHeader; - - /// Withdrawals in block. - type Withdrawals: Iterator; + type Transaction: Transaction; /// Returns reference to transactions in block. - fn transactions(&self) -> &[Self::SignedTransaction]; - - /// Returns `Withdrawals` in the block, if any. - // todo: branch out into extension trait - fn withdrawals(&self) -> Option<&Self::Withdrawals>; - - /// Returns reference to uncle block headers. - fn ommers(&self) -> &[Self::Header]; - - /// Returns [`Requests`] in block, if any. - fn requests(&self) -> Option<&Requests>; - - /// Calculate the transaction root for the block body. - fn calculate_tx_root(&self) -> B256; - - /// Calculate the ommers root for the block body. - fn calculate_ommers_root(&self) -> B256; - - /// Calculate the withdrawals root for the block body, if withdrawals exist. If there are no - /// withdrawals, this will return `None`. - // todo: can be default impl if `calculate_withdrawals_root` made into a method on - // `Withdrawals` and `Withdrawals` moved to alloy - fn calculate_withdrawals_root(&self) -> Option; - - /// Recover signer addresses for all transactions in the block body. - fn recover_signers(&self) -> Option>; - - /// Returns whether or not the block body contains any blob transactions. - fn has_blob_transactions(&self) -> bool { - self.transactions().iter().any(|tx| tx.ty() == TxType::Eip4844 as u8) - } - - /// Returns whether or not the block body contains any EIP-7702 transactions. - fn has_eip7702_transactions(&self) -> bool { - self.transactions().iter().any(|tx| tx.ty() == TxType::Eip7702 as u8) - } - - /// Returns an iterator over all blob transactions of the block - fn blob_transactions_iter(&self) -> impl Iterator + '_ { - self.transactions().iter().filter(|tx| tx.ty() == TxType::Eip4844 as u8) - } - - /// Returns only the blob transactions, if any, from the block body. - fn blob_transactions(&self) -> Vec<&Self::SignedTransaction> { - self.blob_transactions_iter().collect() - } - - /// Returns an iterator over all blob versioned hashes from the block body. - fn blob_versioned_hashes_iter(&self) -> impl Iterator + '_; - - /// Returns all blob versioned hashes from the block body. - fn blob_versioned_hashes(&self) -> Vec<&B256> { - self.blob_versioned_hashes_iter().collect() - } + fn transactions(&self) -> &[Self::Transaction]; } diff --git a/crates/primitives-traits/src/node.rs b/crates/primitives-traits/src/node.rs index cebbbe202e8..9ca69274831 100644 --- a/crates/primitives-traits/src/node.rs +++ b/crates/primitives-traits/src/node.rs @@ -24,7 +24,7 @@ impl NodePrimitives for () { /// Helper trait that sets trait bounds on [`NodePrimitives`]. pub trait FullNodePrimitives: Send + Sync + Unpin + Clone + Default + fmt::Debug { /// Block primitive. - type Block: FullBlock>; + type Block: FullBlock>; /// Signed version of the transaction type. type SignedTx: FullSignedTx; /// Transaction envelope type ID. diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index 703f9d33169..0f96a9d5842 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -657,6 +657,14 @@ impl InMemorySize for BlockBody { } } +impl reth_primitives_traits::BlockBody for BlockBody { + type Transaction = TransactionSigned; + + fn transactions(&self) -> &[Self::Transaction] { + &self.transactions + } +} + impl From for BlockBody { fn from(block: Block) -> Self { Self { diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index d1a95b09be2..e5e4517d9dd 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -1058,6 +1058,22 @@ impl reth_codecs::Compact for TransactionSignedNoHash { } } +#[cfg(any(test, feature = "reth-codec"))] +impl reth_codecs::Compact for TransactionSigned { + fn to_compact(&self, buf: &mut B) -> usize + where + B: bytes::BufMut + AsMut<[u8]>, + { + let tx: TransactionSignedNoHash = self.clone().into(); + tx.to_compact(buf) + } + + fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) { + let (tx, buf) = TransactionSignedNoHash::from_compact(buf, len); + (tx.into(), buf) + } +} + impl From for TransactionSigned { fn from(tx: TransactionSignedNoHash) -> Self { tx.with_hash() diff --git a/crates/stages/stages/src/stages/bodies.rs b/crates/stages/stages/src/stages/bodies.rs index c4676b2728c..640bae86659 100644 --- a/crates/stages/stages/src/stages/bodies.rs +++ b/crates/stages/stages/src/stages/bodies.rs @@ -4,6 +4,8 @@ use std::{ }; use futures_util::TryStreamExt; +use reth_codecs::Compact; +use reth_primitives_traits::BlockBody; use tracing::*; use alloy_primitives::TxNumber; @@ -75,8 +77,8 @@ where + StaticFileProviderFactory + StatsReader + BlockReader - + BlockWriter, - D: BodyDownloader, + + BlockWriter, + D: BodyDownloader>, { /// Return the id of the stage fn id(&self) -> StageId { @@ -190,9 +192,9 @@ where match response { BlockResponse::Full(block) => { // Write transactions - for transaction in &block.body.transactions { - let appended_tx_number = static_file_producer - .append_transaction(next_tx_num, &transaction.clone().into())?; + for transaction in block.body.transactions() { + let appended_tx_number = + static_file_producer.append_transaction(next_tx_num, transaction)?; if appended_tx_number != next_tx_num { // This scenario indicates a critical error in the logic of adding new @@ -702,9 +704,7 @@ mod tests { body.tx_num_range().try_for_each(|tx_num| { let transaction = random_signed_tx(&mut rng); - static_file_producer - .append_transaction(tx_num, &transaction.into()) - .map(drop) + static_file_producer.append_transaction(tx_num, &transaction).map(drop) })?; if body.tx_count != 0 { diff --git a/crates/stages/stages/src/test_utils/test_db.rs b/crates/stages/stages/src/test_utils/test_db.rs index 4c43d4cdcd1..52983cb6f69 100644 --- a/crates/stages/stages/src/test_utils/test_db.rs +++ b/crates/stages/stages/src/test_utils/test_db.rs @@ -265,7 +265,7 @@ impl TestStageDB { let res = block.body.transactions.iter().try_for_each(|body_tx| { if let Some(txs_writer) = &mut txs_writer { - txs_writer.append_transaction(next_tx_num, &body_tx.clone().into())?; + txs_writer.append_transaction(next_tx_num, body_tx)?; } else { tx.put::(next_tx_num, body_tx.clone().into())? } diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index 20d01932a15..62a44c175b0 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -3110,6 +3110,8 @@ impl + impl + 'static> BlockWriter for DatabaseProvider { + type Body = BlockBody; + /// Inserts the block into the database, always modifying the following tables: /// * [`CanonicalHeaders`](tables::CanonicalHeaders) /// * [`Headers`](tables::Headers) diff --git a/crates/storage/provider/src/providers/static_file/writer.rs b/crates/storage/provider/src/providers/static_file/writer.rs index ed1a51068c3..2e54fb943a7 100644 --- a/crates/storage/provider/src/providers/static_file/writer.rs +++ b/crates/storage/provider/src/providers/static_file/writer.rs @@ -10,7 +10,7 @@ use reth_db_api::models::CompactU256; use reth_nippy_jar::{NippyJar, NippyJarError, NippyJarWriter}; use reth_primitives::{ static_file::{SegmentHeader, SegmentRangeInclusive}, - Receipt, StaticFileSegment, TransactionSignedNoHash, + Receipt, StaticFileSegment, }; use reth_storage_errors::provider::{ProviderError, ProviderResult}; use std::{ @@ -544,7 +544,7 @@ impl StaticFileProviderRW { pub fn append_transaction( &mut self, tx_num: TxNumber, - tx: &TransactionSignedNoHash, + tx: impl Compact, ) -> ProviderResult { let start = Instant::now(); self.ensure_no_queued_prune()?; diff --git a/crates/storage/provider/src/traits/block.rs b/crates/storage/provider/src/traits/block.rs index 5cb60c2f42a..50fb032923d 100644 --- a/crates/storage/provider/src/traits/block.rs +++ b/crates/storage/provider/src/traits/block.rs @@ -1,7 +1,7 @@ use alloy_primitives::BlockNumber; use reth_db_api::models::StoredBlockBodyIndices; use reth_execution_types::{Chain, ExecutionOutcome}; -use reth_primitives::{BlockBody, SealedBlockWithSenders}; +use reth_primitives::SealedBlockWithSenders; use reth_storage_errors::provider::ProviderResult; use reth_trie::{updates::TrieUpdates, HashedPostStateSorted}; use std::ops::RangeInclusive; @@ -32,6 +32,9 @@ pub trait StateReader: Send + Sync { /// Block Writer #[auto_impl::auto_impl(&, Arc, Box)] pub trait BlockWriter: Send + Sync { + /// The body this writer can write. + type Body: Send + Sync; + /// Insert full block and make it canonical. Parent tx num and transition id is taken from /// parent block in database. /// @@ -47,7 +50,7 @@ pub trait BlockWriter: Send + Sync { /// Bodies are passed as [`Option`]s, if body is `None` the corresponding block is empty. fn append_block_bodies( &self, - bodies: impl Iterator)>, + bodies: impl Iterator)>, ) -> ProviderResult<()>; /// Appends a batch of sealed blocks to the blockchain, including sender information, and From c5d1b813e4496244cfb673ae0e350035da4a6b4d Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 14 Nov 2024 17:03:28 +0100 Subject: [PATCH 166/211] chore: add missing debugs for pool types (#12546) --- crates/transaction-pool/src/pool/best.rs | 2 ++ crates/transaction-pool/src/validate/mod.rs | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/transaction-pool/src/pool/best.rs b/crates/transaction-pool/src/pool/best.rs index 17165611794..21bcc668b75 100644 --- a/crates/transaction-pool/src/pool/best.rs +++ b/crates/transaction-pool/src/pool/best.rs @@ -20,6 +20,7 @@ use tracing::debug; /// This is a wrapper around [`BestTransactions`] that also enforces a specific basefee. /// /// This iterator guarantees that all transaction it returns satisfy both the base fee and blob fee! +#[derive(Debug)] pub(crate) struct BestTransactionsWithFees { pub(crate) best: BestTransactions, pub(crate) base_fee: u64, @@ -72,6 +73,7 @@ impl Iterator for BestTransactionsWithFees { /// be executed on the current state, but only yields transactions that are ready to be executed /// now. While it contains all gapless transactions of a sender, it _always_ only returns the /// transaction with the current on chain nonce. +#[derive(Debug)] pub(crate) struct BestTransactions { /// Contains a copy of _all_ transactions of the pending pool at the point in time this /// iterator was created. diff --git a/crates/transaction-pool/src/validate/mod.rs b/crates/transaction-pool/src/validate/mod.rs index 6a3b0b96e97..8a5ecc9c419 100644 --- a/crates/transaction-pool/src/validate/mod.rs +++ b/crates/transaction-pool/src/validate/mod.rs @@ -453,9 +453,11 @@ impl Clone for ValidPoolTransaction { impl fmt::Debug for ValidPoolTransaction { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("ValidPoolTransaction") + .field("id", &self.transaction_id) + .field("pragate", &self.propagate) + .field("origin", &self.origin) .field("hash", self.transaction.hash()) - .field("provides", &self.transaction_id) - .field("raw_tx", &self.transaction) + .field("tx", &self.transaction) .finish() } } From 4a0bc37cbbbcd11e08100d2f677aef703196ca7a Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 14 Nov 2024 17:08:46 +0100 Subject: [PATCH 167/211] chore: rm reth testing utils dep from reth-primitives-traits (#12542) --- Cargo.lock | 1 - crates/primitives-traits/Cargo.toml | 2 -- crates/primitives-traits/src/header/sealed.rs | 4 +--- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca5465d37bc..33d50319339 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8536,7 +8536,6 @@ dependencies = [ "proptest-arbitrary-interop", "rand 0.8.5", "reth-codecs", - "reth-testing-utils", "revm-primitives", "roaring", "serde", diff --git a/crates/primitives-traits/Cargo.toml b/crates/primitives-traits/Cargo.toml index 6cafe8b8b1e..30f1c43c86a 100644 --- a/crates/primitives-traits/Cargo.toml +++ b/crates/primitives-traits/Cargo.toml @@ -39,8 +39,6 @@ proptest = { workspace = true, optional = true } proptest-arbitrary-interop = { workspace = true, optional = true } [dev-dependencies] -reth-testing-utils.workspace = true - alloy-primitives = { workspace = true, features = ["arbitrary"] } alloy-consensus = { workspace = true, features = ["arbitrary"] } diff --git a/crates/primitives-traits/src/header/sealed.rs b/crates/primitives-traits/src/header/sealed.rs index 5dd9fcf0d5f..e872eb9811d 100644 --- a/crates/primitives-traits/src/header/sealed.rs +++ b/crates/primitives-traits/src/header/sealed.rs @@ -219,10 +219,8 @@ pub(super) mod serde_bincode_compat { #[cfg(test)] mod tests { use super::super::{serde_bincode_compat, SealedHeader}; - use arbitrary::Arbitrary; use rand::Rng; - use reth_testing_utils::generators; use serde::{Deserialize, Serialize}; use serde_with::serde_as; @@ -236,7 +234,7 @@ pub(super) mod serde_bincode_compat { } let mut bytes = [0u8; 1024]; - generators::rng().fill(bytes.as_mut_slice()); + rand::thread_rng().fill(&mut bytes[..]); let data = Data { transaction: SealedHeader::arbitrary(&mut arbitrary::Unstructured::new(&bytes)) .unwrap(), From 217d9f7c12c151722f7e3b692df7d2ef020927d8 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Thu, 14 Nov 2024 16:58:04 +0100 Subject: [PATCH 168/211] chore(sdk): Add trait bound `Compact` on `::Type` (#12534) --- crates/primitives-traits/src/transaction/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/primitives-traits/src/transaction/mod.rs b/crates/primitives-traits/src/transaction/mod.rs index bb6f6a711e3..4d7ab78685f 100644 --- a/crates/primitives-traits/src/transaction/mod.rs +++ b/crates/primitives-traits/src/transaction/mod.rs @@ -8,12 +8,12 @@ use alloy_primitives::B256; use reth_codecs::Compact; use serde::{Deserialize, Serialize}; -use crate::{InMemorySize, MaybeArbitrary, TxType}; +use crate::{FullTxType, InMemorySize, MaybeArbitrary, TxType}; /// Helper trait that unifies all behaviour required by transaction to support full node operations. -pub trait FullTransaction: Transaction + Compact {} +pub trait FullTransaction: Transaction + Compact {} -impl FullTransaction for T where T: Transaction + Compact {} +impl FullTransaction for T where T: Transaction + Compact {} /// Abstraction of a transaction. pub trait Transaction: From b1635fcba2fdaa2f71747b231d4aeda6bf457b0c Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Thu, 14 Nov 2024 17:10:46 +0100 Subject: [PATCH 169/211] chore(sdk): make `BlockBatchRecord` generic over receipt (#12449) --- Cargo.lock | 217 +++++++++++++++++++++++---------------- crates/revm/Cargo.toml | 5 +- crates/revm/src/batch.rs | 39 ++++--- 3 files changed, 156 insertions(+), 105 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33d50319339..e37e52f0d94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -146,14 +146,14 @@ dependencies = [ "alloy-transport", "futures", "futures-util", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "alloy-dyn-abi" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85132f2698b520fab3f54beed55a44389f7006a7b557a0261e1e69439dcc1572" +checksum = "ef2364c782a245cf8725ea6dbfca5f530162702b5d685992ea03ce64529136cc" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -250,7 +250,7 @@ dependencies = [ "alloy-sol-types", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tracing", ] @@ -274,7 +274,7 @@ dependencies = [ "futures-utils-wasm", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -302,7 +302,7 @@ dependencies = [ "rand 0.8.5", "serde_json", "tempfile", - "thiserror", + "thiserror 1.0.69", "tracing", "url", ] @@ -373,7 +373,7 @@ dependencies = [ "schnellru", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", "url", @@ -494,7 +494,7 @@ dependencies = [ "alloy-rpc-types-engine", "serde", "serde_with", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -573,7 +573,7 @@ dependencies = [ "alloy-serde", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -611,7 +611,7 @@ dependencies = [ "auto_impl", "elliptic-curve", "k256", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -629,7 +629,7 @@ dependencies = [ "coins-bip39", "k256", "rand 0.8.5", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -714,7 +714,7 @@ dependencies = [ "futures-utils-wasm", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tower 0.5.1", "tracing", @@ -1400,7 +1400,7 @@ dependencies = [ "static_assertions", "tap", "thin-vec", - "thiserror", + "thiserror 1.0.69", "time", ] @@ -1625,7 +1625,7 @@ dependencies = [ "semver 1.0.23", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1803,7 +1803,7 @@ dependencies = [ "k256", "serde", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1819,7 +1819,7 @@ dependencies = [ "pbkdf2", "rand 0.8.5", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1838,7 +1838,7 @@ dependencies = [ "serde", "sha2 0.10.8", "sha3", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2627,7 +2627,7 @@ dependencies = [ "revm", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "walkdir", ] @@ -2782,7 +2782,7 @@ dependencies = [ "reth-node-ethereum", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2871,7 +2871,7 @@ dependencies = [ "reth-tracing", "reth-trie-db", "serde", - "thiserror", + "thiserror 1.0.69", "tokio", ] @@ -3142,7 +3142,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e182f7dbc2ef73d9ef67351c5fbbea084729c48362d3ce9dd44c28e32e277fe5" dependencies = [ "libc", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3455,7 +3455,7 @@ dependencies = [ "pin-project", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -4300,7 +4300,7 @@ dependencies = [ "combine", "jni-sys", "log", - "thiserror", + "thiserror 1.0.69", "walkdir", ] @@ -4363,7 +4363,7 @@ dependencies = [ "rustls-pki-types", "rustls-platform-verifier", "soketto", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-rustls", "tokio-util", @@ -4391,7 +4391,7 @@ dependencies = [ "rustc-hash 2.0.0", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tracing", @@ -4416,7 +4416,7 @@ dependencies = [ "rustls-platform-verifier", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tower 0.4.13", "tracing", @@ -4455,7 +4455,7 @@ dependencies = [ "serde", "serde_json", "soketto", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tokio-util", @@ -4472,7 +4472,7 @@ dependencies = [ "http", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -4627,7 +4627,7 @@ dependencies = [ "multihash", "quick-protobuf", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.69", "tracing", "zeroize", ] @@ -4865,7 +4865,7 @@ dependencies = [ "metrics", "metrics-util", "quanta", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -4915,7 +4915,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", ] @@ -5573,7 +5573,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", - "thiserror", + "thiserror 1.0.69", "ucd-trie", ] @@ -5763,7 +5763,7 @@ dependencies = [ "smallvec", "symbolic-demangle", "tempfile", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -6011,9 +6011,9 @@ 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", @@ -6022,26 +6022,29 @@ dependencies = [ "rustc-hash 2.0.0", "rustls", "socket2", - "thiserror", + "thiserror 2.0.3", "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 0.2.15", "rand 0.8.5", "ring", "rustc-hash 2.0.0", "rustls", + "rustls-pki-types", "slab", - "thiserror", + "thiserror 2.0.3", "tinyvec", "tracing", + "web-time", ] [[package]] @@ -6227,7 +6230,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom 0.2.15", "libredox", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -6491,7 +6494,7 @@ dependencies = [ "reth-tokio-util", "reth-tracing", "schnellru", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tracing", @@ -6526,7 +6529,7 @@ dependencies = [ "reth-rpc-types-compat", "reth-tracing", "serde", - "thiserror", + "thiserror 1.0.69", "tokio", "tower 0.4.13", "tracing", @@ -6580,7 +6583,7 @@ dependencies = [ "reth-execution-errors", "reth-primitives", "reth-storage-errors", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -6735,7 +6738,7 @@ dependencies = [ "reth-fs-util", "secp256k1", "serde", - "thiserror", + "thiserror 1.0.69", "tikv-jemallocator", "tracy-client", ] @@ -6878,7 +6881,7 @@ dependencies = [ "sysinfo", "tempfile", "test-fuzz", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -6934,7 +6937,7 @@ dependencies = [ "reth-trie-db", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tracing", ] @@ -6976,7 +6979,7 @@ dependencies = [ "schnellru", "secp256k1", "serde", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tracing", @@ -7001,7 +7004,7 @@ dependencies = [ "reth-network-peers", "reth-tracing", "secp256k1", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", ] @@ -7027,7 +7030,7 @@ dependencies = [ "secp256k1", "serde", "serde_with", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tracing", @@ -7066,7 +7069,7 @@ dependencies = [ "reth-testing-utils", "reth-tracing", "tempfile", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tokio-util", @@ -7132,7 +7135,7 @@ dependencies = [ "secp256k1", "sha2 0.10.8", "sha3", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tokio-util", @@ -7205,7 +7208,7 @@ dependencies = [ "reth-prune", "reth-stages-api", "reth-tasks", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", ] @@ -7254,7 +7257,7 @@ dependencies = [ "reth-trie", "reth-trie-parallel", "revm-primitives", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tracing", @@ -7301,7 +7304,7 @@ dependencies = [ "reth-execution-errors", "reth-fs-util", "reth-storage-errors", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -7332,7 +7335,7 @@ dependencies = [ "serde", "snap", "test-fuzz", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tokio-util", @@ -7360,7 +7363,7 @@ dependencies = [ "reth-primitives", "reth-primitives-traits", "serde", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -7619,7 +7622,7 @@ dependencies = [ "reth-transaction-pool", "reth-trie-db", "tempfile", - "thiserror", + "thiserror 1.0.69", "tokio", ] @@ -7645,7 +7648,7 @@ version = "1.1.1" dependencies = [ "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -7687,7 +7690,7 @@ dependencies = [ "rand 0.8.5", "reth-tracing", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tokio-util", @@ -7712,7 +7715,7 @@ dependencies = [ "reth-mdbx-sys", "smallvec", "tempfile", - "thiserror", + "thiserror 1.0.69", "tracing", ] @@ -7751,7 +7754,7 @@ dependencies = [ "reqwest", "reth-tracing", "serde_with", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", ] @@ -7809,7 +7812,7 @@ dependencies = [ "serial_test", "smallvec", "tempfile", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tokio-util", @@ -7834,7 +7837,7 @@ dependencies = [ "reth-network-types", "reth-tokio-util", "serde", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", ] @@ -7872,7 +7875,7 @@ dependencies = [ "secp256k1", "serde_json", "serde_with", - "thiserror", + "thiserror 1.0.69", "tokio", "url", ] @@ -7903,7 +7906,7 @@ dependencies = [ "reth-fs-util", "serde", "tempfile", - "thiserror", + "thiserror 1.0.69", "tracing", "zstd", ] @@ -8036,7 +8039,7 @@ dependencies = [ "serde", "shellexpand", "strum", - "thiserror", + "thiserror 1.0.69", "tokio", "toml", "tracing", @@ -8350,7 +8353,7 @@ dependencies = [ "reth-trie", "revm", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.69", "tracing", ] @@ -8401,7 +8404,7 @@ dependencies = [ "reth-transaction-pool", "revm", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", ] @@ -8454,7 +8457,7 @@ dependencies = [ "reth-primitives", "reth-transaction-pool", "serde", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tracing", @@ -8618,7 +8621,7 @@ dependencies = [ "reth-tokio-util", "reth-tracing", "rustc-hash 2.0.0", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", ] @@ -8639,7 +8642,7 @@ dependencies = [ "serde", "serde_json", "test-fuzz", - "thiserror", + "thiserror 1.0.69", "toml", ] @@ -8653,6 +8656,7 @@ dependencies = [ "reth-ethereum-forks", "reth-execution-errors", "reth-primitives", + "reth-primitives-traits", "reth-prune-types", "reth-storage-api", "reth-storage-errors", @@ -8724,7 +8728,7 @@ dependencies = [ "revm-primitives", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tower 0.4.13", @@ -8818,7 +8822,7 @@ dependencies = [ "reth-transaction-pool", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-util", "tower 0.4.13", @@ -8858,7 +8862,7 @@ dependencies = [ "reth-tokio-util", "reth-transaction-pool", "serde", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", ] @@ -8941,7 +8945,7 @@ dependencies = [ "schnellru", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tracing", @@ -9042,7 +9046,7 @@ dependencies = [ "reth-trie", "reth-trie-db", "tempfile", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", ] @@ -9069,7 +9073,7 @@ dependencies = [ "reth-static-file-types", "reth-testing-utils", "reth-tokio-util", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tracing", @@ -9169,7 +9173,7 @@ dependencies = [ "pin-project", "rayon", "reth-metrics", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", "tracing-futures", @@ -9251,7 +9255,7 @@ dependencies = [ "serde_json", "smallvec", "tempfile", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tracing", @@ -9362,7 +9366,7 @@ dependencies = [ "reth-trie", "reth-trie-common", "reth-trie-db", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", ] @@ -9384,7 +9388,7 @@ dependencies = [ "reth-trie", "reth-trie-common", "smallvec", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -9418,7 +9422,7 @@ dependencies = [ "colorchoice", "revm", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -9760,6 +9764,9 @@ name = "rustls-pki-types" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" +dependencies = [ + "web-time", +] [[package]] name = "rustls-platform-verifier" @@ -10023,7 +10030,7 @@ checksum = "c7715380eec75f029a4ef7de39a9200e0a63823176b759d055b613f5a87df6a6" dependencies = [ "percent-encoding", "serde", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -10259,7 +10266,7 @@ checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" dependencies = [ "num-bigint", "num-traits", - "thiserror", + "thiserror 1.0.69", "time", ] @@ -10601,7 +10608,16 @@ version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" +dependencies = [ + "thiserror-impl 2.0.3", ] [[package]] @@ -10615,6 +10631,17 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "thiserror-impl" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "thiserror-impl-no-std" version = "2.0.2" @@ -10977,7 +11004,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" dependencies = [ "crossbeam-channel", - "thiserror", + "thiserror 1.0.69", "time", "tracing-subscriber", ] @@ -11128,7 +11155,7 @@ dependencies = [ "once_cell", "rand 0.8.5", "smallvec", - "thiserror", + "thiserror 1.0.69", "tinyvec", "tokio", "tracing", @@ -11151,7 +11178,7 @@ dependencies = [ "resolv-conf", "serde", "smallvec", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", "trust-dns-proto", @@ -11179,7 +11206,7 @@ dependencies = [ "rustls", "rustls-pki-types", "sha1", - "thiserror", + "thiserror 1.0.69", "utf-8", ] @@ -11535,6 +11562,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "webpki-roots" version = "0.26.6" @@ -11910,7 +11947,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", diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index 3ee68010108..bd2251e0333 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -19,6 +19,7 @@ reth-execution-errors.workspace = true reth-prune-types.workspace = true reth-storage-api.workspace = true reth-trie = { workspace = true, optional = true } +reth-primitives-traits.workspace = true # alloy alloy-eips.workspace = true @@ -41,13 +42,15 @@ std = [ "revm/std", "alloy-eips/std", "alloy-consensus/std", + "reth-primitives-traits/std", ] test-utils = [ "dep:reth-trie", "reth-primitives/test-utils", "reth-trie?/test-utils", "revm/test-utils", - "reth-prune-types/test-utils" + "reth-prune-types/test-utils", + "reth-primitives-traits/test-utils", ] serde = [ "revm/serde", diff --git a/crates/revm/src/batch.rs b/crates/revm/src/batch.rs index be3ef0a3782..ddb88505b8d 100644 --- a/crates/revm/src/batch.rs +++ b/crates/revm/src/batch.rs @@ -1,10 +1,12 @@ //! Helper for handling execution of multiple blocks. use alloc::vec::Vec; + use alloy_eips::eip7685::Requests; use alloy_primitives::{map::HashSet, Address, BlockNumber}; use reth_execution_errors::{BlockExecutionError, InternalBlockExecutionError}; -use reth_primitives::{Receipt, Receipts}; +use reth_primitives::Receipts; +use reth_primitives_traits::Receipt; use reth_prune_types::{PruneMode, PruneModes, PruneSegmentError, MINIMUM_PRUNING_DISTANCE}; use revm::db::states::bundle_state::BundleRetention; @@ -13,7 +15,7 @@ use revm::db::states::bundle_state::BundleRetention; /// - pruning receipts according to the pruning configuration. /// - batch range if known #[derive(Debug, Default)] -pub struct BlockBatchRecord { +pub struct BlockBatchRecord { /// Pruning configuration. prune_modes: PruneModes, /// The collection of receipts. @@ -21,7 +23,7 @@ pub struct BlockBatchRecord { /// The inner vector stores receipts ordered by transaction number. /// /// If receipt is None it means it is pruned. - receipts: Receipts, + receipts: Receipts, /// The collection of EIP-7685 requests. /// Outer vector stores requests for each block sequentially. /// The inner vector stores requests ordered by transaction number. @@ -41,9 +43,12 @@ pub struct BlockBatchRecord { tip: Option, } -impl BlockBatchRecord { +impl BlockBatchRecord { /// Create a new receipts recorder with the given pruning configuration. - pub fn new(prune_modes: PruneModes) -> Self { + pub fn new(prune_modes: PruneModes) -> Self + where + T: Default, + { Self { prune_modes, ..Default::default() } } @@ -73,12 +78,15 @@ impl BlockBatchRecord { } /// Returns the recorded receipts. - pub const fn receipts(&self) -> &Receipts { + pub const fn receipts(&self) -> &Receipts { &self.receipts } /// Returns all recorded receipts. - pub fn take_receipts(&mut self) -> Receipts { + pub fn take_receipts(&mut self) -> Receipts + where + T: Default, + { core::mem::take(&mut self.receipts) } @@ -111,7 +119,10 @@ impl BlockBatchRecord { } /// Save receipts to the executor. - pub fn save_receipts(&mut self, receipts: Vec) -> Result<(), BlockExecutionError> { + pub fn save_receipts(&mut self, receipts: Vec) -> Result<(), BlockExecutionError> + where + T: Receipt, + { let mut receipts = receipts.into_iter().map(Some).collect(); // Prune receipts if necessary. self.prune_receipts(&mut receipts).map_err(InternalBlockExecutionError::from)?; @@ -121,10 +132,10 @@ impl BlockBatchRecord { } /// Prune receipts according to the pruning configuration. - fn prune_receipts( - &mut self, - receipts: &mut Vec>, - ) -> Result<(), PruneSegmentError> { + fn prune_receipts(&mut self, receipts: &mut Vec>) -> Result<(), PruneSegmentError> + where + T: Receipt, + { let (Some(first_block), Some(tip)) = (self.first_block, self.tip) else { return Ok(()) }; let block_number = first_block + self.receipts.len() as u64; @@ -161,7 +172,7 @@ impl BlockBatchRecord { // If there is an address_filter, it does not contain any of the // contract addresses, then remove this receipt. let inner_receipt = receipt.as_ref().expect("receipts have not been pruned"); - if !inner_receipt.logs.iter().any(|log| filter.contains(&log.address)) { + if !inner_receipt.logs().iter().any(|log| filter.contains(&log.address)) { receipt.take(); } } @@ -186,7 +197,7 @@ mod tests { #[test] fn test_save_receipts_empty() { - let mut recorder = BlockBatchRecord::default(); + let mut recorder: BlockBatchRecord = BlockBatchRecord::default(); // Create an empty vector of receipts let receipts = vec![]; From bd29f82567134537a6052d2b479e986a641a916b Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 14 Nov 2024 18:15:27 +0100 Subject: [PATCH 170/211] chore: replace reth-chainspec dep with alloy chains (#12550) --- Cargo.lock | 2 +- crates/net/eth-wire/Cargo.toml | 9 +++++---- crates/net/eth-wire/src/errors/eth.rs | 2 +- crates/net/eth-wire/src/ethstream.rs | 2 +- crates/net/eth-wire/src/test_utils.rs | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e37e52f0d94..216088877bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7311,6 +7311,7 @@ dependencies = [ name = "reth-eth-wire" version = "1.1.1" dependencies = [ + "alloy-chains", "alloy-eips", "alloy-primitives", "alloy-rlp", @@ -7323,7 +7324,6 @@ dependencies = [ "proptest", "proptest-arbitrary-interop", "rand 0.8.5", - "reth-chainspec", "reth-codecs", "reth-ecies", "reth-eth-wire-types", diff --git a/crates/net/eth-wire/Cargo.toml b/crates/net/eth-wire/Cargo.toml index 83a3e163ebc..791f05cc9ac 100644 --- a/crates/net/eth-wire/Cargo.toml +++ b/crates/net/eth-wire/Cargo.toml @@ -13,7 +13,6 @@ workspace = true [dependencies] # reth -reth-chainspec.workspace = true reth-codecs.workspace = true reth-primitives.workspace = true reth-ecies.workspace = true @@ -23,6 +22,7 @@ reth-network-peers.workspace = true # ethereum alloy-primitives.workspace = true +alloy-chains.workspace = true # metrics reth-metrics.workspace = true @@ -69,10 +69,10 @@ arbitrary = [ "reth-primitives/arbitrary", "reth-eth-wire-types/arbitrary", "dep:arbitrary", - "reth-chainspec/arbitrary", "alloy-eips/arbitrary", "alloy-primitives/arbitrary", - "reth-codecs/arbitrary" + "reth-codecs/arbitrary", + "alloy-chains/arbitrary" ] serde = [ "dep:serde", @@ -82,7 +82,8 @@ serde = [ "bytes/serde", "rand/serde", "secp256k1/serde", - "reth-codecs/serde" + "reth-codecs/serde", + "alloy-chains/serde" ] [[test]] diff --git a/crates/net/eth-wire/src/errors/eth.rs b/crates/net/eth-wire/src/errors/eth.rs index 1f8b995afda..e06d8230320 100644 --- a/crates/net/eth-wire/src/errors/eth.rs +++ b/crates/net/eth-wire/src/errors/eth.rs @@ -3,8 +3,8 @@ use crate::{ errors::P2PStreamError, message::MessageError, version::ParseVersionError, DisconnectReason, }; +use alloy_chains::Chain; use alloy_primitives::B256; -use reth_chainspec::Chain; use reth_eth_wire_types::EthVersion; use reth_primitives::{GotExpected, GotExpectedBoxed, ValidationError}; use std::io; diff --git a/crates/net/eth-wire/src/ethstream.rs b/crates/net/eth-wire/src/ethstream.rs index c971f6182ce..25b135d5637 100644 --- a/crates/net/eth-wire/src/ethstream.rs +++ b/crates/net/eth-wire/src/ethstream.rs @@ -365,9 +365,9 @@ mod tests { EthMessage, EthStream, EthVersion, HelloMessageWithProtocols, PassthroughCodec, ProtocolVersion, Status, }; + use alloy_chains::NamedChain; use alloy_primitives::{B256, U256}; use futures::{SinkExt, StreamExt}; - use reth_chainspec::NamedChain; use reth_ecies::stream::ECIESStream; use reth_eth_wire_types::EthNetworkPrimitives; use reth_network_peers::pk2id; diff --git a/crates/net/eth-wire/src/test_utils.rs b/crates/net/eth-wire/src/test_utils.rs index d7a3aa582b7..0ad83d5d944 100644 --- a/crates/net/eth-wire/src/test_utils.rs +++ b/crates/net/eth-wire/src/test_utils.rs @@ -6,8 +6,8 @@ use crate::{ hello::DEFAULT_TCP_PORT, EthVersion, HelloMessageWithProtocols, P2PStream, ProtocolVersion, Status, UnauthedP2PStream, }; +use alloy_chains::Chain; use alloy_primitives::{B256, U256}; -use reth_chainspec::Chain; use reth_network_peers::pk2id; use reth_primitives::{ForkFilter, Head}; use secp256k1::{SecretKey, SECP256K1}; From a7bb1d1fa33836533d8e3f1c07d64f4872cb1d5f Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 14 Nov 2024 18:36:31 +0100 Subject: [PATCH 171/211] chore: remove constants reexport (#12549) --- Cargo.lock | 5 +++++ bin/reth-bench/Cargo.toml | 1 + bin/reth-bench/src/bench/output.rs | 2 +- crates/consensus/consensus/Cargo.toml | 16 +++++++++++----- crates/consensus/consensus/src/lib.rs | 5 +++-- crates/ethereum/consensus/Cargo.toml | 1 + crates/ethereum/consensus/src/lib.rs | 5 ++--- crates/net/eth-wire/Cargo.toml | 4 +++- crates/net/eth-wire/src/hello.rs | 2 +- crates/payload/basic/Cargo.toml | 1 + crates/payload/basic/src/lib.rs | 3 ++- crates/primitives/src/constants/mod.rs | 3 --- crates/primitives/src/lib.rs | 2 -- crates/storage/db-common/src/init.rs | 5 +++-- 14 files changed, 34 insertions(+), 21 deletions(-) delete mode 100644 crates/primitives/src/constants/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 216088877bd..dbc1230f2c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6438,6 +6438,7 @@ dependencies = [ "reth-payload-builder", "reth-payload-primitives", "reth-primitives", + "reth-primitives-traits", "reth-provider", "reth-revm", "reth-tasks", @@ -6526,6 +6527,7 @@ dependencies = [ "reth-node-api", "reth-node-core", "reth-primitives", + "reth-primitives-traits", "reth-rpc-types-compat", "reth-tracing", "serde", @@ -6802,6 +6804,7 @@ dependencies = [ "auto_impl", "derive_more 1.0.0", "reth-primitives", + "reth-primitives-traits", ] [[package]] @@ -7330,6 +7333,7 @@ dependencies = [ "reth-metrics", "reth-network-peers", "reth-primitives", + "reth-primitives-traits", "reth-tracing", "secp256k1", "serde", @@ -7388,6 +7392,7 @@ dependencies = [ "reth-consensus", "reth-consensus-common", "reth-primitives", + "reth-primitives-traits", "tracing", ] diff --git a/bin/reth-bench/Cargo.toml b/bin/reth-bench/Cargo.toml index 03844633a92..0182076130c 100644 --- a/bin/reth-bench/Cargo.toml +++ b/bin/reth-bench/Cargo.toml @@ -20,6 +20,7 @@ reth-node-core.workspace = true reth-node-api.workspace = true reth-rpc-types-compat.workspace = true reth-primitives = { workspace = true, features = ["alloy-compat"] } +reth-primitives-traits.workspace = true reth-tracing.workspace = true # alloy diff --git a/bin/reth-bench/src/bench/output.rs b/bin/reth-bench/src/bench/output.rs index 8f68dac4533..56343c6af64 100644 --- a/bin/reth-bench/src/bench/output.rs +++ b/bin/reth-bench/src/bench/output.rs @@ -1,7 +1,7 @@ //! Contains various benchmark output formats, either for logging or for //! serialization to / from files. -use reth_primitives::constants::gas_units::GIGAGAS; +use reth_primitives_traits::constants::GIGAGAS; use serde::{ser::SerializeStruct, Serialize}; use std::time::Duration; diff --git a/crates/consensus/consensus/Cargo.toml b/crates/consensus/consensus/Cargo.toml index d120d268bd9..55188dd8472 100644 --- a/crates/consensus/consensus/Cargo.toml +++ b/crates/consensus/consensus/Cargo.toml @@ -13,6 +13,7 @@ workspace = true [dependencies] # reth reth-primitives.workspace = true +reth-primitives-traits.workspace = true # ethereum alloy-eips.workspace = true @@ -26,9 +27,14 @@ derive_more.workspace = true [features] default = ["std"] std = [ - "reth-primitives/std", - "alloy-primitives/std", - "alloy-eips/std", - "alloy-consensus/std", + "reth-primitives/std", + "reth-primitives-traits/std", + "alloy-primitives/std", + "alloy-eips/std", + "alloy-consensus/std", + "reth-primitives-traits/std" +] +test-utils = [ + "reth-primitives/test-utils", + "reth-primitives-traits/test-utils" ] -test-utils = ["reth-primitives/test-utils"] diff --git a/crates/consensus/consensus/src/lib.rs b/crates/consensus/consensus/src/lib.rs index a8f0a01f22b..ec296f3ed49 100644 --- a/crates/consensus/consensus/src/lib.rs +++ b/crates/consensus/consensus/src/lib.rs @@ -16,9 +16,10 @@ use alloy_consensus::Header; use alloy_eips::eip7685::Requests; use alloy_primitives::{BlockHash, BlockNumber, Bloom, B256, U256}; use reth_primitives::{ - constants::MINIMUM_GAS_LIMIT, BlockBody, BlockWithSenders, GotExpected, GotExpectedBoxed, - InvalidTransactionError, Receipt, SealedBlock, SealedHeader, + BlockBody, BlockWithSenders, GotExpected, GotExpectedBoxed, InvalidTransactionError, Receipt, + SealedBlock, SealedHeader, }; +use reth_primitives_traits::constants::MINIMUM_GAS_LIMIT; /// A consensus implementation that does nothing. pub mod noop; diff --git a/crates/ethereum/consensus/Cargo.toml b/crates/ethereum/consensus/Cargo.toml index bace4195ca6..8e6158ff46c 100644 --- a/crates/ethereum/consensus/Cargo.toml +++ b/crates/ethereum/consensus/Cargo.toml @@ -15,6 +15,7 @@ workspace = true reth-chainspec.workspace = true reth-consensus-common.workspace = true reth-primitives.workspace = true +reth-primitives-traits.workspace = true reth-consensus.workspace = true # alloy diff --git a/crates/ethereum/consensus/src/lib.rs b/crates/ethereum/consensus/src/lib.rs index 3dc7a02af8b..7198a703672 100644 --- a/crates/ethereum/consensus/src/lib.rs +++ b/crates/ethereum/consensus/src/lib.rs @@ -18,9 +18,8 @@ use reth_consensus_common::validation::{ validate_against_parent_timestamp, validate_block_pre_execution, validate_body_against_header, validate_header_base_fee, validate_header_extradata, validate_header_gas, }; -use reth_primitives::{ - constants::MINIMUM_GAS_LIMIT, BlockBody, BlockWithSenders, SealedBlock, SealedHeader, -}; +use reth_primitives::{BlockBody, BlockWithSenders, SealedBlock, SealedHeader}; +use reth_primitives_traits::constants::MINIMUM_GAS_LIMIT; use std::{fmt::Debug, sync::Arc, time::SystemTime}; /// The bound divisor of the gas limit, used in update calculations. diff --git a/crates/net/eth-wire/Cargo.toml b/crates/net/eth-wire/Cargo.toml index 791f05cc9ac..d4989ca3b29 100644 --- a/crates/net/eth-wire/Cargo.toml +++ b/crates/net/eth-wire/Cargo.toml @@ -15,6 +15,7 @@ workspace = true # reth reth-codecs.workspace = true reth-primitives.workspace = true +reth-primitives-traits.workspace = true reth-ecies.workspace = true alloy-rlp = { workspace = true, features = ["derive"] } reth-eth-wire-types.workspace = true @@ -72,7 +73,8 @@ arbitrary = [ "alloy-eips/arbitrary", "alloy-primitives/arbitrary", "reth-codecs/arbitrary", - "alloy-chains/arbitrary" + "alloy-chains/arbitrary", + "reth-primitives-traits/arbitrary" ] serde = [ "dep:serde", diff --git a/crates/net/eth-wire/src/hello.rs b/crates/net/eth-wire/src/hello.rs index 2eb42eaeb49..5d7650b4b7b 100644 --- a/crates/net/eth-wire/src/hello.rs +++ b/crates/net/eth-wire/src/hello.rs @@ -2,7 +2,7 @@ use crate::{Capability, EthVersion, ProtocolVersion}; use alloy_rlp::{RlpDecodable, RlpEncodable}; use reth_codecs::add_arbitrary_tests; use reth_network_peers::PeerId; -use reth_primitives::constants::RETH_CLIENT_VERSION; +use reth_primitives_traits::constants::RETH_CLIENT_VERSION; /// The default tcp port for p2p. /// diff --git a/crates/payload/basic/Cargo.toml b/crates/payload/basic/Cargo.toml index 74dea45d10d..5e9e524f79b 100644 --- a/crates/payload/basic/Cargo.toml +++ b/crates/payload/basic/Cargo.toml @@ -15,6 +15,7 @@ workspace = true # reth reth-chainspec.workspace = true reth-primitives.workspace = true +reth-primitives-traits.workspace = true reth-transaction-pool.workspace = true reth-provider.workspace = true reth-payload-builder.workspace = true diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index 9b36e44b1fc..a905f854448 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -20,7 +20,8 @@ use reth_payload_builder::{KeepPayloadJobAlive, PayloadId, PayloadJob, PayloadJo use reth_payload_primitives::{ BuiltPayload, PayloadBuilderAttributes, PayloadBuilderError, PayloadKind, }; -use reth_primitives::{constants::RETH_CLIENT_VERSION, proofs, SealedHeader}; +use reth_primitives::{proofs, SealedHeader}; +use reth_primitives_traits::constants::RETH_CLIENT_VERSION; use reth_provider::{BlockReaderIdExt, CanonStateNotification, StateProviderFactory}; use reth_revm::cached::CachedReads; use reth_tasks::TaskSpawner; diff --git a/crates/primitives/src/constants/mod.rs b/crates/primitives/src/constants/mod.rs deleted file mode 100644 index 09c488cc25a..00000000000 --- a/crates/primitives/src/constants/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -//! Ethereum protocol-related constants - -pub use reth_primitives_traits::constants::*; diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 534b525f086..2318b3c2455 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -26,7 +26,6 @@ mod alloy_compat; mod block; #[cfg(feature = "reth-codec")] mod compression; -pub mod constants; pub mod proofs; mod receipt; pub use reth_static_file_types as static_file; @@ -36,7 +35,6 @@ pub use block::{generate_valid_header, valid_header_strategy}; pub use block::{Block, BlockBody, BlockWithSenders, SealedBlock, SealedBlockWithSenders}; #[cfg(feature = "reth-codec")] pub use compression::*; -pub use constants::HOLESKY_GENESIS_HASH; pub use receipt::{ gas_spent_by_transactions, Receipt, ReceiptWithBloom, ReceiptWithBloomRef, Receipts, }; diff --git a/crates/storage/db-common/src/init.rs b/crates/storage/db-common/src/init.rs index 8c930b22ef8..45fb4b76b31 100644 --- a/crates/storage/db-common/src/init.rs +++ b/crates/storage/db-common/src/init.rs @@ -584,7 +584,9 @@ struct GenesisAccountWithAddress { #[cfg(test)] mod tests { use super::*; - use alloy_consensus::constants::{MAINNET_GENESIS_HASH, SEPOLIA_GENESIS_HASH}; + use alloy_consensus::constants::{ + HOLESKY_GENESIS_HASH, MAINNET_GENESIS_HASH, SEPOLIA_GENESIS_HASH, + }; use alloy_genesis::Genesis; use reth_chainspec::{Chain, ChainSpec, HOLESKY, MAINNET, SEPOLIA}; use reth_db::DatabaseEnv; @@ -595,7 +597,6 @@ mod tests { transaction::DbTx, Database, }; - use reth_primitives::HOLESKY_GENESIS_HASH; use reth_primitives_traits::IntegerList; use reth_provider::{ test_utils::{create_test_provider_factory_with_chain_spec, MockNodeTypesWithDB}, From 870ffae9094e411343781f7a1dc29d503740f168 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 14 Nov 2024 19:03:15 +0100 Subject: [PATCH 172/211] chore: use crates directly in eth-wire (#12554) --- Cargo.lock | 1 + crates/net/eth-wire/Cargo.toml | 8 +++++--- crates/net/eth-wire/src/errors/eth.rs | 3 ++- crates/net/eth-wire/src/errors/p2p.rs | 2 +- crates/net/eth-wire/src/ethstream.rs | 5 +++-- crates/net/eth-wire/src/multiplex.rs | 2 +- crates/net/eth-wire/src/p2pstream.rs | 2 +- crates/net/eth-wire/src/test_utils.rs | 2 +- 8 files changed, 15 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dbc1230f2c8..12e1a4a8cda 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7330,6 +7330,7 @@ dependencies = [ "reth-codecs", "reth-ecies", "reth-eth-wire-types", + "reth-ethereum-forks", "reth-metrics", "reth-network-peers", "reth-primitives", diff --git a/crates/net/eth-wire/Cargo.toml b/crates/net/eth-wire/Cargo.toml index d4989ca3b29..3999f658e0a 100644 --- a/crates/net/eth-wire/Cargo.toml +++ b/crates/net/eth-wire/Cargo.toml @@ -14,12 +14,12 @@ workspace = true [dependencies] # reth reth-codecs.workspace = true -reth-primitives.workspace = true reth-primitives-traits.workspace = true reth-ecies.workspace = true alloy-rlp = { workspace = true, features = ["derive"] } reth-eth-wire-types.workspace = true reth-network-peers.workspace = true +reth-ethereum-forks.workspace = true # ethereum alloy-primitives.workspace = true @@ -45,6 +45,7 @@ arbitrary = { workspace = true, features = ["derive"], optional = true } [dev-dependencies] reth-primitives = { workspace = true, features = ["arbitrary"] } +reth-primitives-traits = { workspace = true, features = ["arbitrary"] } reth-eth-wire-types = { workspace = true, features = ["arbitrary"] } reth-tracing.workspace = true @@ -67,14 +68,15 @@ alloy-eips.workspace = true [features] arbitrary = [ - "reth-primitives/arbitrary", "reth-eth-wire-types/arbitrary", "dep:arbitrary", "alloy-eips/arbitrary", "alloy-primitives/arbitrary", "reth-codecs/arbitrary", "alloy-chains/arbitrary", - "reth-primitives-traits/arbitrary" + "reth-primitives-traits/arbitrary", + "reth-ethereum-forks/arbitrary", + "reth-primitives/arbitrary" ] serde = [ "dep:serde", diff --git a/crates/net/eth-wire/src/errors/eth.rs b/crates/net/eth-wire/src/errors/eth.rs index e06d8230320..499ff8089bf 100644 --- a/crates/net/eth-wire/src/errors/eth.rs +++ b/crates/net/eth-wire/src/errors/eth.rs @@ -6,7 +6,8 @@ use crate::{ use alloy_chains::Chain; use alloy_primitives::B256; use reth_eth_wire_types::EthVersion; -use reth_primitives::{GotExpected, GotExpectedBoxed, ValidationError}; +use reth_ethereum_forks::ValidationError; +use reth_primitives_traits::{GotExpected, GotExpectedBoxed}; use std::io; /// Errors when sending/receiving messages diff --git a/crates/net/eth-wire/src/errors/p2p.rs b/crates/net/eth-wire/src/errors/p2p.rs index 2cfef926984..f24e2cebc78 100644 --- a/crates/net/eth-wire/src/errors/p2p.rs +++ b/crates/net/eth-wire/src/errors/p2p.rs @@ -3,7 +3,7 @@ use std::io; use reth_eth_wire_types::{DisconnectReason, UnknownDisconnectReason}; -use reth_primitives::GotExpected; +use reth_primitives_traits::GotExpected; use crate::{capability::SharedCapabilityError, ProtocolVersion}; diff --git a/crates/net/eth-wire/src/ethstream.rs b/crates/net/eth-wire/src/ethstream.rs index 25b135d5637..675ea19a5ce 100644 --- a/crates/net/eth-wire/src/ethstream.rs +++ b/crates/net/eth-wire/src/ethstream.rs @@ -9,7 +9,8 @@ use alloy_primitives::bytes::{Bytes, BytesMut}; use futures::{ready, Sink, SinkExt, StreamExt}; use pin_project::pin_project; use reth_eth_wire_types::NetworkPrimitives; -use reth_primitives::{ForkFilter, GotExpected}; +use reth_ethereum_forks::ForkFilter; +use reth_primitives_traits::GotExpected; use std::{ pin::Pin, task::{Context, Poll}, @@ -370,8 +371,8 @@ mod tests { use futures::{SinkExt, StreamExt}; use reth_ecies::stream::ECIESStream; use reth_eth_wire_types::EthNetworkPrimitives; + use reth_ethereum_forks::{ForkFilter, Head}; use reth_network_peers::pk2id; - use reth_primitives::{ForkFilter, Head}; use secp256k1::{SecretKey, SECP256K1}; use std::time::Duration; use tokio::net::{TcpListener, TcpStream}; diff --git a/crates/net/eth-wire/src/multiplex.rs b/crates/net/eth-wire/src/multiplex.rs index 6f882f40887..e46563cad48 100644 --- a/crates/net/eth-wire/src/multiplex.rs +++ b/crates/net/eth-wire/src/multiplex.rs @@ -25,7 +25,7 @@ use crate::{ use bytes::{Bytes, BytesMut}; use futures::{Sink, SinkExt, Stream, StreamExt, TryStream, TryStreamExt}; use reth_eth_wire_types::NetworkPrimitives; -use reth_primitives::ForkFilter; +use reth_ethereum_forks::ForkFilter; use tokio::sync::{mpsc, mpsc::UnboundedSender}; use tokio_stream::wrappers::UnboundedReceiverStream; diff --git a/crates/net/eth-wire/src/p2pstream.rs b/crates/net/eth-wire/src/p2pstream.rs index 76075838bc7..0ae546daafb 100644 --- a/crates/net/eth-wire/src/p2pstream.rs +++ b/crates/net/eth-wire/src/p2pstream.rs @@ -14,7 +14,7 @@ use futures::{Sink, SinkExt, StreamExt}; use pin_project::pin_project; use reth_codecs::add_arbitrary_tests; use reth_metrics::metrics::counter; -use reth_primitives::GotExpected; +use reth_primitives_traits::GotExpected; use std::{ collections::VecDeque, io, diff --git a/crates/net/eth-wire/src/test_utils.rs b/crates/net/eth-wire/src/test_utils.rs index 0ad83d5d944..56656d60e94 100644 --- a/crates/net/eth-wire/src/test_utils.rs +++ b/crates/net/eth-wire/src/test_utils.rs @@ -8,8 +8,8 @@ use crate::{ }; use alloy_chains::Chain; use alloy_primitives::{B256, U256}; +use reth_ethereum_forks::{ForkFilter, Head}; use reth_network_peers::pk2id; -use reth_primitives::{ForkFilter, Head}; use secp256k1::{SecretKey, SECP256K1}; use std::net::SocketAddr; use tokio::net::TcpStream; From 28a5b631d15b71463d1fe26d5910d26c5dc95613 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 14 Nov 2024 21:35:04 +0100 Subject: [PATCH 173/211] chore: move gas_spent_by_transactions to traits (#12541) --- crates/primitives-traits/src/receipt.rs | 17 +++++++++++++++-- crates/primitives/src/receipt.rs | 16 ++++------------ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/crates/primitives-traits/src/receipt.rs b/crates/primitives-traits/src/receipt.rs index 68917d62812..f3c9ef06356 100644 --- a/crates/primitives-traits/src/receipt.rs +++ b/crates/primitives-traits/src/receipt.rs @@ -1,9 +1,9 @@ //! Receipt abstraction -use core::fmt; - +use alloc::vec::Vec; use alloy_consensus::TxReceipt; use alloy_primitives::B256; +use core::fmt; use reth_codecs::Compact; use serde::{Deserialize, Serialize}; @@ -32,3 +32,16 @@ pub trait Receipt: /// Calculates the receipts root of the given receipts. fn receipts_root(receipts: &[&Self]) -> B256; } + +/// Retrieves gas spent by transactions as a vector of tuples (transaction index, gas used). +pub fn gas_spent_by_transactions(receipts: I) -> Vec<(u64, u64)> +where + I: IntoIterator, + T: TxReceipt, +{ + receipts + .into_iter() + .enumerate() + .map(|(id, receipt)| (id as u64, receipt.cumulative_gas_used() as u64)) + .collect() +} diff --git a/crates/primitives/src/receipt.rs b/crates/primitives/src/receipt.rs index 3258d4be6eb..41397181149 100644 --- a/crates/primitives/src/receipt.rs +++ b/crates/primitives/src/receipt.rs @@ -1,5 +1,5 @@ use alloc::{vec, vec::Vec}; -use core::{cmp::Ordering, ops::Deref}; +use core::cmp::Ordering; use alloy_consensus::{ constants::{EIP1559_TX_TYPE_ID, EIP2930_TX_TYPE_ID, EIP4844_TX_TYPE_ID, EIP7702_TX_TYPE_ID}, @@ -16,6 +16,9 @@ use serde::{Deserialize, Serialize}; use crate::compression::{RECEIPT_COMPRESSOR, RECEIPT_DECOMPRESSOR}; use crate::TxType; +/// Retrieves gas spent by transactions as a vector of tuples (transaction index, gas used). +pub use reth_primitives_traits::receipt::gas_spent_by_transactions; + /// Receipt containing result of transaction execution. #[derive( Clone, Debug, PartialEq, Eq, Default, RlpEncodable, RlpDecodable, Serialize, Deserialize, @@ -199,17 +202,6 @@ impl ReceiptWithBloom { } } -/// Retrieves gas spent by transactions as a vector of tuples (transaction index, gas used). -pub fn gas_spent_by_transactions>( - receipts: impl IntoIterator, -) -> Vec<(u64, u64)> { - receipts - .into_iter() - .enumerate() - .map(|(id, receipt)| (id as u64, receipt.deref().cumulative_gas_used)) - .collect() -} - #[cfg(any(test, feature = "arbitrary"))] impl<'a> arbitrary::Arbitrary<'a> for Receipt { fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { From a534db8714c71f398dfad307c1b7c88222e9a971 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Fri, 15 Nov 2024 00:57:31 +0400 Subject: [PATCH 174/211] refactor: use `DBProvider` in `HistoricalStateProvider` (#12556) --- .../src/providers/database/provider.rs | 9 +- .../src/providers/state/historical.rs | 249 +++++++----------- 2 files changed, 96 insertions(+), 162 deletions(-) diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index 62a44c175b0..53911b5d133 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -178,11 +178,7 @@ impl DatabaseProvider { let storage_history_prune_checkpoint = self.get_prune_checkpoint(PruneSegment::StorageHistory)?; - let mut state_provider = HistoricalStateProviderRef::new( - &self.tx, - block_number, - self.static_file_provider.clone(), - ); + let mut state_provider = HistoricalStateProviderRef::new(self, block_number); // If we pruned account or storage history, we can't return state on every historical block. // Instead, we should cap it at the latest prune checkpoint for corresponding prune segment. @@ -259,8 +255,7 @@ impl TryIntoHistoricalStateProvider for Databa let storage_history_prune_checkpoint = self.get_prune_checkpoint(PruneSegment::StorageHistory)?; - let mut state_provider = - HistoricalStateProvider::new(self.tx, block_number, self.static_file_provider); + let mut state_provider = HistoricalStateProvider::new(self, block_number); // If we pruned account or storage history, we can't return state on every historical block. // Instead, we should cap it at the latest prune checkpoint for corresponding prune segment. diff --git a/crates/storage/provider/src/providers/state/historical.rs b/crates/storage/provider/src/providers/state/historical.rs index 56a1d057e70..29ba70e2049 100644 --- a/crates/storage/provider/src/providers/state/historical.rs +++ b/crates/storage/provider/src/providers/state/historical.rs @@ -1,6 +1,6 @@ use crate::{ - providers::{state::macros::delegate_provider_impls, StaticFileProvider}, - AccountReader, BlockHashReader, ProviderError, StateProvider, StateRootProvider, + providers::state::macros::delegate_provider_impls, AccountReader, BlockHashReader, + ProviderError, StateProvider, StateRootProvider, }; use alloy_eips::merge::EPOCH_SLOTS; use alloy_primitives::{ @@ -14,8 +14,8 @@ use reth_db_api::{ table::Table, transaction::DbTx, }; -use reth_primitives::{Account, Bytecode, StaticFileSegment}; -use reth_storage_api::{StateProofProvider, StorageRootProvider}; +use reth_primitives::{Account, Bytecode}; +use reth_storage_api::{BlockNumReader, DBProvider, StateProofProvider, StorageRootProvider}; use reth_storage_errors::provider::ProviderResult; use reth_trie::{ proof::{Proof, StorageProof}, @@ -41,15 +41,13 @@ use std::fmt::Debug; /// - [`tables::AccountChangeSets`] /// - [`tables::StorageChangeSets`] #[derive(Debug)] -pub struct HistoricalStateProviderRef<'b, TX: DbTx> { - /// Transaction - tx: &'b TX, +pub struct HistoricalStateProviderRef<'b, Provider> { + /// Database provider + provider: &'b Provider, /// Block number is main index for the history state of accounts and storages. block_number: BlockNumber, /// Lowest blocks at which different parts of the state are available. lowest_available_blocks: LowestAvailableBlocks, - /// Static File provider - static_file_provider: StaticFileProvider, } #[derive(Debug, Eq, PartialEq)] @@ -60,25 +58,20 @@ pub enum HistoryInfo { MaybeInPlainState, } -impl<'b, TX: DbTx> HistoricalStateProviderRef<'b, TX> { +impl<'b, Provider: DBProvider + BlockNumReader> HistoricalStateProviderRef<'b, Provider> { /// Create new `StateProvider` for historical block number - pub fn new( - tx: &'b TX, - block_number: BlockNumber, - static_file_provider: StaticFileProvider, - ) -> Self { - Self { tx, block_number, lowest_available_blocks: Default::default(), static_file_provider } + pub fn new(provider: &'b Provider, block_number: BlockNumber) -> Self { + Self { provider, block_number, lowest_available_blocks: Default::default() } } /// Create new `StateProvider` for historical block number and lowest block numbers at which /// account & storage histories are available. pub const fn new_with_lowest_available_blocks( - tx: &'b TX, + provider: &'b Provider, block_number: BlockNumber, lowest_available_blocks: LowestAvailableBlocks, - static_file_provider: StaticFileProvider, ) -> Self { - Self { tx, block_number, lowest_available_blocks, static_file_provider } + Self { provider, block_number, lowest_available_blocks } } /// Lookup an account in the `AccountsHistory` table @@ -117,15 +110,7 @@ impl<'b, TX: DbTx> HistoricalStateProviderRef<'b, TX> { /// Checks and returns `true` if distance to historical block exceeds the provided limit. fn check_distance_against_limit(&self, limit: u64) -> ProviderResult { - let tip = self - .tx - .cursor_read::()? - .last()? - .map(|(tip, _)| tip) - .or_else(|| { - self.static_file_provider.get_highest_static_file_block(StaticFileSegment::Headers) - }) - .ok_or(ProviderError::BestBlockNotFound)?; + let tip = self.provider.last_block_number()?; Ok(tip.saturating_sub(self.block_number) > limit) } @@ -146,7 +131,7 @@ impl<'b, TX: DbTx> HistoricalStateProviderRef<'b, TX> { ); } - Ok(HashedPostState::from_reverts(self.tx, self.block_number)?) + Ok(HashedPostState::from_reverts(self.tx(), self.block_number)?) } /// Retrieve revert hashed storage for this history provider and target address. @@ -163,7 +148,7 @@ impl<'b, TX: DbTx> HistoricalStateProviderRef<'b, TX> { ); } - Ok(HashedStorage::from_reverts(self.tx, address, self.block_number)?) + Ok(HashedStorage::from_reverts(self.tx(), address, self.block_number)?) } fn history_info( @@ -175,7 +160,7 @@ impl<'b, TX: DbTx> HistoricalStateProviderRef<'b, TX> { where T: Table, { - let mut cursor = self.tx.cursor_read::()?; + let mut cursor = self.tx().cursor_read::()?; // Lookup the history chunk in the history index. If they key does not appear in the // index, the first chunk for the next key will be returned so we filter out chunks that @@ -248,13 +233,21 @@ impl<'b, TX: DbTx> HistoricalStateProviderRef<'b, TX> { } } -impl AccountReader for HistoricalStateProviderRef<'_, TX> { +impl HistoricalStateProviderRef<'_, Provider> { + fn tx(&self) -> &Provider::Tx { + self.provider.tx_ref() + } +} + +impl AccountReader + for HistoricalStateProviderRef<'_, Provider> +{ /// Get basic account information. fn basic_account(&self, address: Address) -> ProviderResult> { match self.account_history_lookup(address)? { HistoryInfo::NotYetWritten => Ok(None), HistoryInfo::InChangeset(changeset_block_number) => Ok(self - .tx + .tx() .cursor_dup_read::()? .seek_by_key_subkey(changeset_block_number, address)? .filter(|acc| acc.address == address) @@ -264,21 +257,18 @@ impl AccountReader for HistoricalStateProviderRef<'_, TX> { })? .info), HistoryInfo::InPlainState | HistoryInfo::MaybeInPlainState => { - Ok(self.tx.get::(address)?) + Ok(self.tx().get::(address)?) } } } } -impl BlockHashReader for HistoricalStateProviderRef<'_, TX> { +impl BlockHashReader + for HistoricalStateProviderRef<'_, Provider> +{ /// Get block hash by number. fn block_hash(&self, number: u64) -> ProviderResult> { - self.static_file_provider.get_with_static_file_or_database( - StaticFileSegment::Headers, - number, - |static_file| static_file.block_hash(number), - || Ok(self.tx.get::(number)?), - ) + self.provider.block_hash(number) } fn canonical_hashes_range( @@ -286,37 +276,23 @@ impl BlockHashReader for HistoricalStateProviderRef<'_, TX> { start: BlockNumber, end: BlockNumber, ) -> ProviderResult> { - self.static_file_provider.get_range_with_static_file_or_database( - StaticFileSegment::Headers, - start..end, - |static_file, range, _| static_file.canonical_hashes_range(range.start, range.end), - |range, _| { - self.tx - .cursor_read::() - .map(|mut cursor| { - cursor - .walk_range(range)? - .map(|result| result.map(|(_, hash)| hash).map_err(Into::into)) - .collect::>>() - })? - .map_err(Into::into) - }, - |_| true, - ) + self.provider.canonical_hashes_range(start, end) } } -impl StateRootProvider for HistoricalStateProviderRef<'_, TX> { +impl StateRootProvider + for HistoricalStateProviderRef<'_, Provider> +{ fn state_root(&self, hashed_state: HashedPostState) -> ProviderResult { let mut revert_state = self.revert_state()?; revert_state.extend(hashed_state); - StateRoot::overlay_root(self.tx, revert_state) + StateRoot::overlay_root(self.tx(), revert_state) .map_err(|err| ProviderError::Database(err.into())) } fn state_root_from_nodes(&self, mut input: TrieInput) -> ProviderResult { input.prepend(self.revert_state()?); - StateRoot::overlay_root_from_nodes(self.tx, input) + StateRoot::overlay_root_from_nodes(self.tx(), input) .map_err(|err| ProviderError::Database(err.into())) } @@ -326,7 +302,7 @@ impl StateRootProvider for HistoricalStateProviderRef<'_, TX> { ) -> ProviderResult<(B256, TrieUpdates)> { let mut revert_state = self.revert_state()?; revert_state.extend(hashed_state); - StateRoot::overlay_root_with_updates(self.tx, revert_state) + StateRoot::overlay_root_with_updates(self.tx(), revert_state) .map_err(|err| ProviderError::Database(err.into())) } @@ -335,12 +311,14 @@ impl StateRootProvider for HistoricalStateProviderRef<'_, TX> { mut input: TrieInput, ) -> ProviderResult<(B256, TrieUpdates)> { input.prepend(self.revert_state()?); - StateRoot::overlay_root_from_nodes_with_updates(self.tx, input) + StateRoot::overlay_root_from_nodes_with_updates(self.tx(), input) .map_err(|err| ProviderError::Database(err.into())) } } -impl StorageRootProvider for HistoricalStateProviderRef<'_, TX> { +impl StorageRootProvider + for HistoricalStateProviderRef<'_, Provider> +{ fn storage_root( &self, address: Address, @@ -348,7 +326,7 @@ impl StorageRootProvider for HistoricalStateProviderRef<'_, TX> { ) -> ProviderResult { let mut revert_storage = self.revert_storage(address)?; revert_storage.extend(&hashed_storage); - StorageRoot::overlay_root(self.tx, address, revert_storage) + StorageRoot::overlay_root(self.tx(), address, revert_storage) .map_err(|err| ProviderError::Database(err.into())) } @@ -360,12 +338,14 @@ impl StorageRootProvider for HistoricalStateProviderRef<'_, TX> { ) -> ProviderResult { let mut revert_storage = self.revert_storage(address)?; revert_storage.extend(&hashed_storage); - StorageProof::overlay_storage_proof(self.tx, address, slot, revert_storage) + StorageProof::overlay_storage_proof(self.tx(), address, slot, revert_storage) .map_err(Into::::into) } } -impl StateProofProvider for HistoricalStateProviderRef<'_, TX> { +impl StateProofProvider + for HistoricalStateProviderRef<'_, Provider> +{ /// Get account and storage proofs. fn proof( &self, @@ -374,7 +354,7 @@ impl StateProofProvider for HistoricalStateProviderRef<'_, TX> { slots: &[B256], ) -> ProviderResult { input.prepend(self.revert_state()?); - Proof::overlay_account_proof(self.tx, input, address, slots) + Proof::overlay_account_proof(self.tx(), input, address, slots) .map_err(Into::::into) } @@ -384,7 +364,7 @@ impl StateProofProvider for HistoricalStateProviderRef<'_, TX> { targets: HashMap>, ) -> ProviderResult { input.prepend(self.revert_state()?); - Proof::overlay_multiproof(self.tx, input, targets).map_err(Into::::into) + Proof::overlay_multiproof(self.tx(), input, targets).map_err(Into::::into) } fn witness( @@ -393,11 +373,13 @@ impl StateProofProvider for HistoricalStateProviderRef<'_, TX> { target: HashedPostState, ) -> ProviderResult> { input.prepend(self.revert_state()?); - TrieWitness::overlay_witness(self.tx, input, target).map_err(Into::::into) + TrieWitness::overlay_witness(self.tx(), input, target).map_err(Into::::into) } } -impl StateProvider for HistoricalStateProviderRef<'_, TX> { +impl StateProvider + for HistoricalStateProviderRef<'_, Provider> +{ /// Get storage. fn storage( &self, @@ -407,7 +389,7 @@ impl StateProvider for HistoricalStateProviderRef<'_, TX> { match self.storage_history_lookup(address, storage_key)? { HistoryInfo::NotYetWritten => Ok(None), HistoryInfo::InChangeset(changeset_block_number) => Ok(Some( - self.tx + self.tx() .cursor_dup_read::()? .seek_by_key_subkey((changeset_block_number, address).into(), storage_key)? .filter(|entry| entry.key == storage_key) @@ -419,7 +401,7 @@ impl StateProvider for HistoricalStateProviderRef<'_, TX> { .value, )), HistoryInfo::InPlainState | HistoryInfo::MaybeInPlainState => Ok(self - .tx + .tx() .cursor_dup_read::()? .seek_by_key_subkey(address, storage_key)? .filter(|entry| entry.key == storage_key) @@ -430,32 +412,26 @@ impl StateProvider for HistoricalStateProviderRef<'_, TX> { /// Get account code by its hash fn bytecode_by_hash(&self, code_hash: B256) -> ProviderResult> { - self.tx.get::(code_hash).map_err(Into::into) + self.tx().get::(code_hash).map_err(Into::into) } } /// State provider for a given block number. /// For more detailed description, see [`HistoricalStateProviderRef`]. #[derive(Debug)] -pub struct HistoricalStateProvider { - /// Database transaction - tx: TX, +pub struct HistoricalStateProvider { + /// Database provider. + provider: Provider, /// State at the block number is the main indexer of the state. block_number: BlockNumber, /// Lowest blocks at which different parts of the state are available. lowest_available_blocks: LowestAvailableBlocks, - /// Static File provider - static_file_provider: StaticFileProvider, } -impl HistoricalStateProvider { +impl HistoricalStateProvider { /// Create new `StateProvider` for historical block number - pub fn new( - tx: TX, - block_number: BlockNumber, - static_file_provider: StaticFileProvider, - ) -> Self { - Self { tx, block_number, lowest_available_blocks: Default::default(), static_file_provider } + pub fn new(provider: Provider, block_number: BlockNumber) -> Self { + Self { provider, block_number, lowest_available_blocks: Default::default() } } /// Set the lowest block number at which the account history is available. @@ -478,18 +454,17 @@ impl HistoricalStateProvider { /// Returns a new provider that takes the `TX` as reference #[inline(always)] - fn as_ref(&self) -> HistoricalStateProviderRef<'_, TX> { + const fn as_ref(&self) -> HistoricalStateProviderRef<'_, Provider> { HistoricalStateProviderRef::new_with_lowest_available_blocks( - &self.tx, + &self.provider, self.block_number, self.lowest_available_blocks, - self.static_file_provider.clone(), ) } } // Delegates all provider impls to [HistoricalStateProviderRef] -delegate_provider_impls!(HistoricalStateProvider where [TX: DbTx]); +delegate_provider_impls!(HistoricalStateProvider where [Provider: DBProvider + BlockNumReader + BlockHashReader]); /// Lowest blocks at which different parts of the state are available. /// They may be [Some] if pruning is enabled. @@ -525,7 +500,6 @@ mod tests { providers::state::historical::{HistoryInfo, LowestAvailableBlocks}, test_utils::create_test_provider_factory, AccountReader, HistoricalStateProvider, HistoricalStateProviderRef, StateProvider, - StaticFileProviderFactory, }; use alloy_primitives::{address, b256, Address, B256, U256}; use reth_db::{tables, BlockNumberList}; @@ -534,6 +508,7 @@ mod tests { transaction::{DbTx, DbTxMut}, }; use reth_primitives::{Account, StorageEntry}; + use reth_storage_api::{BlockHashReader, BlockNumReader, DBProvider, DatabaseProviderFactory}; use reth_storage_errors::provider::ProviderError; const ADDRESS: Address = address!("0000000000000000000000000000000000000001"); @@ -542,7 +517,7 @@ mod tests { const fn assert_state_provider() {} #[allow(dead_code)] - const fn assert_historical_state_provider() { + const fn assert_historical_state_provider() { assert_state_provider::>(); } @@ -550,7 +525,6 @@ mod tests { fn history_provider_get_account() { let factory = create_test_provider_factory(); let tx = factory.provider_rw().unwrap().into_tx(); - let static_file_provider = factory.static_file_provider(); tx.put::( ShardedKey { key: ADDRESS, highest_block_number: 7 }, @@ -610,63 +584,46 @@ mod tests { tx.put::(HIGHER_ADDRESS, higher_acc_plain).unwrap(); tx.commit().unwrap(); - let tx = factory.provider().unwrap().into_tx(); + let db = factory.provider().unwrap(); // run + assert_eq!(HistoricalStateProviderRef::new(&db, 1).basic_account(ADDRESS), Ok(None)); assert_eq!( - HistoricalStateProviderRef::new(&tx, 1, static_file_provider.clone()) - .basic_account(ADDRESS), - Ok(None) - ); - assert_eq!( - HistoricalStateProviderRef::new(&tx, 2, static_file_provider.clone()) - .basic_account(ADDRESS), + HistoricalStateProviderRef::new(&db, 2).basic_account(ADDRESS), Ok(Some(acc_at3)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 3, static_file_provider.clone()) - .basic_account(ADDRESS), + HistoricalStateProviderRef::new(&db, 3).basic_account(ADDRESS), Ok(Some(acc_at3)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 4, static_file_provider.clone()) - .basic_account(ADDRESS), + HistoricalStateProviderRef::new(&db, 4).basic_account(ADDRESS), Ok(Some(acc_at7)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 7, static_file_provider.clone()) - .basic_account(ADDRESS), + HistoricalStateProviderRef::new(&db, 7).basic_account(ADDRESS), Ok(Some(acc_at7)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 9, static_file_provider.clone()) - .basic_account(ADDRESS), + HistoricalStateProviderRef::new(&db, 9).basic_account(ADDRESS), Ok(Some(acc_at10)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 10, static_file_provider.clone()) - .basic_account(ADDRESS), + HistoricalStateProviderRef::new(&db, 10).basic_account(ADDRESS), Ok(Some(acc_at10)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 11, static_file_provider.clone()) - .basic_account(ADDRESS), + HistoricalStateProviderRef::new(&db, 11).basic_account(ADDRESS), Ok(Some(acc_at15)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 16, static_file_provider.clone()) - .basic_account(ADDRESS), + HistoricalStateProviderRef::new(&db, 16).basic_account(ADDRESS), Ok(Some(acc_plain)) ); + assert_eq!(HistoricalStateProviderRef::new(&db, 1).basic_account(HIGHER_ADDRESS), Ok(None)); assert_eq!( - HistoricalStateProviderRef::new(&tx, 1, static_file_provider.clone()) - .basic_account(HIGHER_ADDRESS), - Ok(None) - ); - assert_eq!( - HistoricalStateProviderRef::new(&tx, 1000, static_file_provider) - .basic_account(HIGHER_ADDRESS), + HistoricalStateProviderRef::new(&db, 1000).basic_account(HIGHER_ADDRESS), Ok(Some(higher_acc_plain)) ); } @@ -675,7 +632,6 @@ mod tests { fn history_provider_get_storage() { let factory = create_test_provider_factory(); let tx = factory.provider_rw().unwrap().into_tx(); - let static_file_provider = factory.static_file_provider(); tx.put::( StorageShardedKey { @@ -722,57 +678,44 @@ mod tests { tx.put::(HIGHER_ADDRESS, higher_entry_plain).unwrap(); tx.commit().unwrap(); - let tx = factory.provider().unwrap().into_tx(); + let db = factory.provider().unwrap(); // run + assert_eq!(HistoricalStateProviderRef::new(&db, 0).storage(ADDRESS, STORAGE), Ok(None)); assert_eq!( - HistoricalStateProviderRef::new(&tx, 0, static_file_provider.clone()) - .storage(ADDRESS, STORAGE), - Ok(None) - ); - assert_eq!( - HistoricalStateProviderRef::new(&tx, 3, static_file_provider.clone()) - .storage(ADDRESS, STORAGE), + HistoricalStateProviderRef::new(&db, 3).storage(ADDRESS, STORAGE), Ok(Some(U256::ZERO)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 4, static_file_provider.clone()) - .storage(ADDRESS, STORAGE), + HistoricalStateProviderRef::new(&db, 4).storage(ADDRESS, STORAGE), Ok(Some(entry_at7.value)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 7, static_file_provider.clone()) - .storage(ADDRESS, STORAGE), + HistoricalStateProviderRef::new(&db, 7).storage(ADDRESS, STORAGE), Ok(Some(entry_at7.value)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 9, static_file_provider.clone()) - .storage(ADDRESS, STORAGE), + HistoricalStateProviderRef::new(&db, 9).storage(ADDRESS, STORAGE), Ok(Some(entry_at10.value)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 10, static_file_provider.clone()) - .storage(ADDRESS, STORAGE), + HistoricalStateProviderRef::new(&db, 10).storage(ADDRESS, STORAGE), Ok(Some(entry_at10.value)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 11, static_file_provider.clone()) - .storage(ADDRESS, STORAGE), + HistoricalStateProviderRef::new(&db, 11).storage(ADDRESS, STORAGE), Ok(Some(entry_at15.value)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 16, static_file_provider.clone()) - .storage(ADDRESS, STORAGE), + HistoricalStateProviderRef::new(&db, 16).storage(ADDRESS, STORAGE), Ok(Some(entry_plain.value)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 1, static_file_provider.clone()) - .storage(HIGHER_ADDRESS, STORAGE), + HistoricalStateProviderRef::new(&db, 1).storage(HIGHER_ADDRESS, STORAGE), Ok(None) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 1000, static_file_provider) - .storage(HIGHER_ADDRESS, STORAGE), + HistoricalStateProviderRef::new(&db, 1000).storage(HIGHER_ADDRESS, STORAGE), Ok(Some(higher_entry_plain.value)) ); } @@ -780,19 +723,17 @@ mod tests { #[test] fn history_provider_unavailable() { let factory = create_test_provider_factory(); - let tx = factory.provider_rw().unwrap().into_tx(); - let static_file_provider = factory.static_file_provider(); + let db = factory.database_provider_rw().unwrap(); // provider block_number < lowest available block number, // i.e. state at provider block is pruned let provider = HistoricalStateProviderRef::new_with_lowest_available_blocks( - &tx, + &db, 2, LowestAvailableBlocks { account_history_block_number: Some(3), storage_history_block_number: Some(3), }, - static_file_provider.clone(), ); assert_eq!( provider.account_history_lookup(ADDRESS), @@ -806,13 +747,12 @@ mod tests { // provider block_number == lowest available block number, // i.e. state at provider block is available let provider = HistoricalStateProviderRef::new_with_lowest_available_blocks( - &tx, + &db, 2, LowestAvailableBlocks { account_history_block_number: Some(2), storage_history_block_number: Some(2), }, - static_file_provider.clone(), ); assert_eq!(provider.account_history_lookup(ADDRESS), Ok(HistoryInfo::MaybeInPlainState)); assert_eq!( @@ -823,13 +763,12 @@ mod tests { // provider block_number == lowest available block number, // i.e. state at provider block is available let provider = HistoricalStateProviderRef::new_with_lowest_available_blocks( - &tx, + &db, 2, LowestAvailableBlocks { account_history_block_number: Some(1), storage_history_block_number: Some(1), }, - static_file_provider, ); assert_eq!(provider.account_history_lookup(ADDRESS), Ok(HistoryInfo::MaybeInPlainState)); assert_eq!( From b1729d22e40fa43382bc3dcc843674d3a319c71c Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 14 Nov 2024 23:03:09 +0100 Subject: [PATCH 175/211] feat: impl block for sealedblock (#12555) --- crates/primitives-traits/src/block/body.rs | 5 ++- crates/primitives-traits/src/block/header.rs | 8 ++--- crates/primitives/src/block.rs | 32 +++++++++++++++++--- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/crates/primitives-traits/src/block/body.rs b/crates/primitives-traits/src/block/body.rs index c5f15aefea6..bb52b89724b 100644 --- a/crates/primitives-traits/src/block/body.rs +++ b/crates/primitives-traits/src/block/body.rs @@ -1,11 +1,9 @@ //! Block body abstraction. +use crate::InMemorySize; use alloc::fmt; - use alloy_consensus::Transaction; -use crate::InMemorySize; - /// Abstraction for block's body. pub trait BlockBody: Send @@ -21,6 +19,7 @@ pub trait BlockBody: + alloy_rlp::Encodable + alloy_rlp::Decodable + InMemorySize + + 'static { /// Ordered list of signed transactions as committed in block. // todo: requires trait for signed transaction diff --git a/crates/primitives-traits/src/block/header.rs b/crates/primitives-traits/src/block/header.rs index 7ab76f24987..0c1fc3e57f2 100644 --- a/crates/primitives-traits/src/block/header.rs +++ b/crates/primitives-traits/src/block/header.rs @@ -1,12 +1,10 @@ //! Block header data primitive. -use core::fmt; - +use crate::InMemorySize; use alloy_primitives::Sealable; +use core::fmt; use reth_codecs::Compact; -use crate::InMemorySize; - /// Helper trait that unifies all behaviour required by block header to support full node /// operations. pub trait FullBlockHeader: BlockHeader + Compact {} @@ -28,6 +26,7 @@ pub trait BlockHeader: + alloy_consensus::BlockHeader + Sealable + InMemorySize + + 'static { } @@ -47,5 +46,6 @@ impl BlockHeader for T where + alloy_consensus::BlockHeader + Sealable + InMemorySize + + 'static { } diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index 0f96a9d5842..d6476c29b4c 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -90,13 +90,13 @@ impl reth_primitives_traits::Block for Block { type Header = Header; type Body = BlockBody; - fn body(&self) -> &Self::Body { - &self.body - } - fn header(&self) -> &Self::Header { &self.header } + + fn body(&self) -> &Self::Body { + &self.body + } } impl InMemorySize for Block { @@ -463,6 +463,24 @@ where } } +impl reth_primitives_traits::Block for SealedBlock +where + H: reth_primitives_traits::BlockHeader, + B: reth_primitives_traits::BlockBody, + Self: Serialize + for<'a> Deserialize<'a>, +{ + type Header = H; + type Body = B; + + fn header(&self) -> &Self::Header { + self.header.header() + } + + fn body(&self) -> &Self::Body { + &self.body + } +} + #[cfg(any(test, feature = "arbitrary"))] impl<'a, H, B> arbitrary::Arbitrary<'a> for SealedBlock where @@ -959,6 +977,12 @@ mod tests { use alloy_rlp::{Decodable, Encodable}; use std::str::FromStr; + const fn _traits() { + const fn assert_block() {} + assert_block::(); + assert_block::(); + } + /// Check parsing according to EIP-1898. #[test] fn can_parse_blockid_u64() { From d8af28bbfac5e10b4ffcdca59a57997bed1a3a9f Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Fri, 15 Nov 2024 02:05:07 +0400 Subject: [PATCH 176/211] refactor: use `DBProvider` in `LatestStateProvider` (#12557) --- .../commands/debug_cmd/in_memory_merkle.rs | 7 +- bin/reth/src/commands/debug_cmd/merkle.rs | 7 +- crates/exex/exex/src/backfill/test_utils.rs | 13 +- crates/stages/stages/src/stages/execution.rs | 19 +-- .../provider/src/providers/database/mod.rs | 2 +- .../src/providers/database/provider.rs | 9 +- .../provider/src/providers/state/latest.rs | 116 +++++++----------- 7 files changed, 67 insertions(+), 106 deletions(-) diff --git a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs index bc36578a327..d5bb8a87b22 100644 --- a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs +++ b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs @@ -24,7 +24,7 @@ use reth_node_ethereum::EthExecutorProvider; use reth_provider::{ writer::UnifiedStorageWriter, AccountExtReader, ChainSpecProvider, HashingWriter, HeaderProvider, LatestStateProviderRef, OriginalValuesKnown, ProviderFactory, - StageCheckpointReader, StateWriter, StaticFileProviderFactory, StorageReader, + StageCheckpointReader, StateWriter, StorageReader, }; use reth_revm::database::StateProviderDatabase; use reth_stages::StageId; @@ -133,10 +133,7 @@ impl> Command { ) .await?; - let db = StateProviderDatabase::new(LatestStateProviderRef::new( - provider.tx_ref(), - provider_factory.static_file_provider(), - )); + let db = StateProviderDatabase::new(LatestStateProviderRef::new(&provider)); let executor = EthExecutorProvider::ethereum(provider_factory.chain_spec()).executor(db); diff --git a/bin/reth/src/commands/debug_cmd/merkle.rs b/bin/reth/src/commands/debug_cmd/merkle.rs index 3c6e38512c9..9c77c70abc7 100644 --- a/bin/reth/src/commands/debug_cmd/merkle.rs +++ b/bin/reth/src/commands/debug_cmd/merkle.rs @@ -22,7 +22,7 @@ use reth_node_ethereum::EthExecutorProvider; use reth_provider::{ writer::UnifiedStorageWriter, BlockNumReader, BlockWriter, ChainSpecProvider, DatabaseProviderFactory, HeaderProvider, LatestStateProviderRef, OriginalValuesKnown, - ProviderError, ProviderFactory, StateWriter, StaticFileProviderFactory, + ProviderError, ProviderFactory, StateWriter, }; use reth_revm::database::StateProviderDatabase; use reth_stages::{ @@ -153,10 +153,7 @@ impl> Command { td += sealed_block.difficulty; let mut executor = executor_provider.batch_executor(StateProviderDatabase::new( - LatestStateProviderRef::new( - provider_rw.tx_ref(), - provider_rw.static_file_provider().clone(), - ), + LatestStateProviderRef::new(&provider_rw), )); executor.execute_and_verify_one((&sealed_block.clone().unseal(), td).into())?; let execution_outcome = executor.finalize(); diff --git a/crates/exex/exex/src/backfill/test_utils.rs b/crates/exex/exex/src/backfill/test_utils.rs index a1e88c7f428..80af408c5c8 100644 --- a/crates/exex/exex/src/backfill/test_utils.rs +++ b/crates/exex/exex/src/backfill/test_utils.rs @@ -14,7 +14,7 @@ use reth_primitives::{ }; use reth_provider::{ providers::ProviderNodeTypes, BlockWriter as _, ExecutionOutcome, LatestStateProviderRef, - ProviderFactory, StaticFileProviderFactory, + ProviderFactory, }; use reth_revm::database::StateProviderDatabase; use reth_testing_utils::generators::sign_tx_with_key_pair; @@ -63,10 +63,7 @@ where // Execute the block to produce a block execution output let mut block_execution_output = EthExecutorProvider::ethereum(chain_spec) - .executor(StateProviderDatabase::new(LatestStateProviderRef::new( - provider.tx_ref(), - provider.static_file_provider(), - ))) + .executor(StateProviderDatabase::new(LatestStateProviderRef::new(&provider))) .execute(BlockExecutionInput { block, total_difficulty: U256::ZERO })?; block_execution_output.state.reverts.sort(); @@ -191,10 +188,8 @@ where let provider = provider_factory.provider()?; - let executor = - EthExecutorProvider::ethereum(chain_spec).batch_executor(StateProviderDatabase::new( - LatestStateProviderRef::new(provider.tx_ref(), provider.static_file_provider()), - )); + let executor = EthExecutorProvider::ethereum(chain_spec) + .batch_executor(StateProviderDatabase::new(LatestStateProviderRef::new(&provider))); let mut execution_outcome = executor.execute_and_verify_batch(vec![ (&block1, U256::ZERO).into(), diff --git a/crates/stages/stages/src/stages/execution.rs b/crates/stages/stages/src/stages/execution.rs index 630cc6df03d..1750758a26a 100644 --- a/crates/stages/stages/src/stages/execution.rs +++ b/crates/stages/stages/src/stages/execution.rs @@ -16,9 +16,9 @@ use reth_primitives_traits::format_gas_throughput; use reth_provider::{ providers::{StaticFileProvider, StaticFileProviderRWRefMut, StaticFileWriter}, writer::UnifiedStorageWriter, - BlockReader, DBProvider, HeaderProvider, LatestStateProviderRef, OriginalValuesKnown, - ProviderError, StateChangeWriter, StateWriter, StaticFileProviderFactory, StatsReader, - TransactionVariant, + BlockHashReader, BlockReader, DBProvider, HeaderProvider, LatestStateProviderRef, + OriginalValuesKnown, ProviderError, StateChangeWriter, StateWriter, StaticFileProviderFactory, + StatsReader, TransactionVariant, }; use reth_prune_types::PruneModes; use reth_revm::database::StateProviderDatabase; @@ -175,8 +175,12 @@ impl ExecutionStage { impl Stage for ExecutionStage where E: BlockExecutorProvider, - Provider: - DBProvider + BlockReader + StaticFileProviderFactory + StatsReader + StateChangeWriter, + Provider: DBProvider + + BlockReader + + StaticFileProviderFactory + + StatsReader + + StateChangeWriter + + BlockHashReader, for<'a> UnifiedStorageWriter<'a, Provider, StaticFileProviderRWRefMut<'a>>: StateWriter, { /// Return the id of the stage @@ -220,10 +224,7 @@ where None }; - let db = StateProviderDatabase(LatestStateProviderRef::new( - provider.tx_ref(), - provider.static_file_provider(), - )); + let db = StateProviderDatabase(LatestStateProviderRef::new(provider)); let mut executor = self.executor_provider.batch_executor(db); executor.set_tip(max_block); executor.set_prune_modes(prune_modes); diff --git a/crates/storage/provider/src/providers/database/mod.rs b/crates/storage/provider/src/providers/database/mod.rs index b4d2e5e48b8..0e193f8cdef 100644 --- a/crates/storage/provider/src/providers/database/mod.rs +++ b/crates/storage/provider/src/providers/database/mod.rs @@ -160,7 +160,7 @@ impl ProviderFactory { #[track_caller] pub fn latest(&self) -> ProviderResult { trace!(target: "providers::db", "Returning latest state provider"); - Ok(Box::new(LatestStateProvider::new(self.db.tx()?, self.static_file_provider()))) + Ok(Box::new(LatestStateProvider::new(self.database_provider_ro()?))) } /// Storage provider for state at that given block diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index 53911b5d133..30a69fbfc77 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -151,7 +151,7 @@ impl DatabaseProvider { /// State provider for latest block pub fn latest<'a>(&'a self) -> ProviderResult> { trace!(target: "providers::db", "Returning latest state provider"); - Ok(Box::new(LatestStateProviderRef::new(&self.tx, self.static_file_provider.clone()))) + Ok(Box::new(LatestStateProviderRef::new(self))) } /// Storage provider for state at that given block hash @@ -164,10 +164,7 @@ impl DatabaseProvider { if block_number == self.best_block_number().unwrap_or_default() && block_number == self.last_block_number().unwrap_or_default() { - return Ok(Box::new(LatestStateProviderRef::new( - &self.tx, - self.static_file_provider.clone(), - ))) + return Ok(Box::new(LatestStateProviderRef::new(self))) } // +1 as the changeset that we want is the one that was applied after this block. @@ -244,7 +241,7 @@ impl TryIntoHistoricalStateProvider for Databa if block_number == self.best_block_number().unwrap_or_default() && block_number == self.last_block_number().unwrap_or_default() { - return Ok(Box::new(LatestStateProvider::new(self.tx, self.static_file_provider))) + return Ok(Box::new(LatestStateProvider::new(self))) } // +1 as the changeset that we want is the one that was applied after this block. diff --git a/crates/storage/provider/src/providers/state/latest.rs b/crates/storage/provider/src/providers/state/latest.rs index fdcbfc4937f..297217acece 100644 --- a/crates/storage/provider/src/providers/state/latest.rs +++ b/crates/storage/provider/src/providers/state/latest.rs @@ -1,18 +1,15 @@ use crate::{ - providers::{state::macros::delegate_provider_impls, StaticFileProvider}, - AccountReader, BlockHashReader, StateProvider, StateRootProvider, + providers::state::macros::delegate_provider_impls, AccountReader, BlockHashReader, + StateProvider, StateRootProvider, }; use alloy_primitives::{ map::{HashMap, HashSet}, Address, BlockNumber, Bytes, StorageKey, StorageValue, B256, }; use reth_db::tables; -use reth_db_api::{ - cursor::{DbCursorRO, DbDupCursorRO}, - transaction::DbTx, -}; -use reth_primitives::{Account, Bytecode, StaticFileSegment}; -use reth_storage_api::{StateProofProvider, StorageRootProvider}; +use reth_db_api::{cursor::DbDupCursorRO, transaction::DbTx}; +use reth_primitives::{Account, Bytecode}; +use reth_storage_api::{DBProvider, StateProofProvider, StorageRootProvider}; use reth_storage_errors::provider::{ProviderError, ProviderResult}; use reth_trie::{ proof::{Proof, StorageProof}, @@ -26,37 +23,33 @@ use reth_trie_db::{ }; /// State provider over latest state that takes tx reference. +/// +/// Wraps a [`DBProvider`] to get access to database. #[derive(Debug)] -pub struct LatestStateProviderRef<'b, TX: DbTx> { - /// database transaction - tx: &'b TX, - /// Static File provider - static_file_provider: StaticFileProvider, -} +pub struct LatestStateProviderRef<'b, Provider>(&'b Provider); -impl<'b, TX: DbTx> LatestStateProviderRef<'b, TX> { +impl<'b, Provider: DBProvider> LatestStateProviderRef<'b, Provider> { /// Create new state provider - pub const fn new(tx: &'b TX, static_file_provider: StaticFileProvider) -> Self { - Self { tx, static_file_provider } + pub const fn new(provider: &'b Provider) -> Self { + Self(provider) + } + + fn tx(&self) -> &Provider::Tx { + self.0.tx_ref() } } -impl AccountReader for LatestStateProviderRef<'_, TX> { +impl AccountReader for LatestStateProviderRef<'_, Provider> { /// Get basic account information. fn basic_account(&self, address: Address) -> ProviderResult> { - self.tx.get::(address).map_err(Into::into) + self.tx().get::(address).map_err(Into::into) } } -impl BlockHashReader for LatestStateProviderRef<'_, TX> { +impl BlockHashReader for LatestStateProviderRef<'_, Provider> { /// Get block hash by number. fn block_hash(&self, number: u64) -> ProviderResult> { - self.static_file_provider.get_with_static_file_or_database( - StaticFileSegment::Headers, - number, - |static_file| static_file.block_hash(number), - || Ok(self.tx.get::(number)?), - ) + self.0.block_hash(number) } fn canonical_hashes_range( @@ -64,34 +57,18 @@ impl BlockHashReader for LatestStateProviderRef<'_, TX> { start: BlockNumber, end: BlockNumber, ) -> ProviderResult> { - self.static_file_provider.get_range_with_static_file_or_database( - StaticFileSegment::Headers, - start..end, - |static_file, range, _| static_file.canonical_hashes_range(range.start, range.end), - |range, _| { - self.tx - .cursor_read::() - .map(|mut cursor| { - cursor - .walk_range(range)? - .map(|result| result.map(|(_, hash)| hash).map_err(Into::into)) - .collect::>>() - })? - .map_err(Into::into) - }, - |_| true, - ) + self.0.canonical_hashes_range(start, end) } } -impl StateRootProvider for LatestStateProviderRef<'_, TX> { +impl StateRootProvider for LatestStateProviderRef<'_, Provider> { fn state_root(&self, hashed_state: HashedPostState) -> ProviderResult { - StateRoot::overlay_root(self.tx, hashed_state) + StateRoot::overlay_root(self.tx(), hashed_state) .map_err(|err| ProviderError::Database(err.into())) } fn state_root_from_nodes(&self, input: TrieInput) -> ProviderResult { - StateRoot::overlay_root_from_nodes(self.tx, input) + StateRoot::overlay_root_from_nodes(self.tx(), input) .map_err(|err| ProviderError::Database(err.into())) } @@ -99,7 +76,7 @@ impl StateRootProvider for LatestStateProviderRef<'_, TX> { &self, hashed_state: HashedPostState, ) -> ProviderResult<(B256, TrieUpdates)> { - StateRoot::overlay_root_with_updates(self.tx, hashed_state) + StateRoot::overlay_root_with_updates(self.tx(), hashed_state) .map_err(|err| ProviderError::Database(err.into())) } @@ -107,18 +84,18 @@ impl StateRootProvider for LatestStateProviderRef<'_, TX> { &self, input: TrieInput, ) -> ProviderResult<(B256, TrieUpdates)> { - StateRoot::overlay_root_from_nodes_with_updates(self.tx, input) + StateRoot::overlay_root_from_nodes_with_updates(self.tx(), input) .map_err(|err| ProviderError::Database(err.into())) } } -impl StorageRootProvider for LatestStateProviderRef<'_, TX> { +impl StorageRootProvider for LatestStateProviderRef<'_, Provider> { fn storage_root( &self, address: Address, hashed_storage: HashedStorage, ) -> ProviderResult { - StorageRoot::overlay_root(self.tx, address, hashed_storage) + StorageRoot::overlay_root(self.tx(), address, hashed_storage) .map_err(|err| ProviderError::Database(err.into())) } @@ -128,19 +105,19 @@ impl StorageRootProvider for LatestStateProviderRef<'_, TX> { slot: B256, hashed_storage: HashedStorage, ) -> ProviderResult { - StorageProof::overlay_storage_proof(self.tx, address, slot, hashed_storage) + StorageProof::overlay_storage_proof(self.tx(), address, slot, hashed_storage) .map_err(Into::::into) } } -impl StateProofProvider for LatestStateProviderRef<'_, TX> { +impl StateProofProvider for LatestStateProviderRef<'_, Provider> { fn proof( &self, input: TrieInput, address: Address, slots: &[B256], ) -> ProviderResult { - Proof::overlay_account_proof(self.tx, input, address, slots) + Proof::overlay_account_proof(self.tx(), input, address, slots) .map_err(Into::::into) } @@ -149,7 +126,7 @@ impl StateProofProvider for LatestStateProviderRef<'_, TX> { input: TrieInput, targets: HashMap>, ) -> ProviderResult { - Proof::overlay_multiproof(self.tx, input, targets).map_err(Into::::into) + Proof::overlay_multiproof(self.tx(), input, targets).map_err(Into::::into) } fn witness( @@ -157,18 +134,20 @@ impl StateProofProvider for LatestStateProviderRef<'_, TX> { input: TrieInput, target: HashedPostState, ) -> ProviderResult> { - TrieWitness::overlay_witness(self.tx, input, target).map_err(Into::::into) + TrieWitness::overlay_witness(self.tx(), input, target).map_err(Into::::into) } } -impl StateProvider for LatestStateProviderRef<'_, TX> { +impl StateProvider + for LatestStateProviderRef<'_, Provider> +{ /// Get storage. fn storage( &self, account: Address, storage_key: StorageKey, ) -> ProviderResult> { - let mut cursor = self.tx.cursor_dup_read::()?; + let mut cursor = self.tx().cursor_dup_read::()?; if let Some(entry) = cursor.seek_by_key_subkey(account, storage_key)? { if entry.key == storage_key { return Ok(Some(entry.value)) @@ -179,34 +158,29 @@ impl StateProvider for LatestStateProviderRef<'_, TX> { /// Get account code by its hash fn bytecode_by_hash(&self, code_hash: B256) -> ProviderResult> { - self.tx.get::(code_hash).map_err(Into::into) + self.tx().get::(code_hash).map_err(Into::into) } } /// State provider for the latest state. #[derive(Debug)] -pub struct LatestStateProvider { - /// database transaction - db: TX, - /// Static File provider - static_file_provider: StaticFileProvider, -} +pub struct LatestStateProvider(Provider); -impl LatestStateProvider { +impl LatestStateProvider { /// Create new state provider - pub const fn new(db: TX, static_file_provider: StaticFileProvider) -> Self { - Self { db, static_file_provider } + pub const fn new(db: Provider) -> Self { + Self(db) } /// Returns a new provider that takes the `TX` as reference #[inline(always)] - fn as_ref(&self) -> LatestStateProviderRef<'_, TX> { - LatestStateProviderRef::new(&self.db, self.static_file_provider.clone()) + const fn as_ref(&self) -> LatestStateProviderRef<'_, Provider> { + LatestStateProviderRef::new(&self.0) } } // Delegates all provider impls to [LatestStateProviderRef] -delegate_provider_impls!(LatestStateProvider where [TX: DbTx]); +delegate_provider_impls!(LatestStateProvider where [Provider: DBProvider + BlockHashReader]); #[cfg(test)] mod tests { @@ -214,7 +188,7 @@ mod tests { const fn assert_state_provider() {} #[allow(dead_code)] - const fn assert_latest_state_provider() { + const fn assert_latest_state_provider() { assert_state_provider::>(); } } From d028c1cbb4ad0df449cedb283f50085ed9579e2d Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Fri, 15 Nov 2024 02:07:57 +0400 Subject: [PATCH 177/211] refactor: don't reference `StaticFileProvider` in `static_file::Segment` (#12558) --- .../beacon/src/engine/hooks/static_file.rs | 10 ++++++++-- crates/stages/stages/src/stages/headers.rs | 14 +++++++------- .../static-file/src/segments/headers.rs | 9 +++------ crates/static-file/static-file/src/segments/mod.rs | 8 ++++---- .../static-file/src/segments/receipts.rs | 9 +++++---- .../static-file/src/segments/transactions.rs | 9 +++++---- .../static-file/src/static_file_producer.rs | 6 ++++-- 7 files changed, 36 insertions(+), 29 deletions(-) diff --git a/crates/consensus/beacon/src/engine/hooks/static_file.rs b/crates/consensus/beacon/src/engine/hooks/static_file.rs index 89231ed5582..99854209cb3 100644 --- a/crates/consensus/beacon/src/engine/hooks/static_file.rs +++ b/crates/consensus/beacon/src/engine/hooks/static_file.rs @@ -33,7 +33,10 @@ impl StaticFileHook where Provider: StaticFileProviderFactory + DatabaseProviderFactory< - Provider: StageCheckpointReader + BlockReader + ChainStateBlockReader, + Provider: StaticFileProviderFactory + + StageCheckpointReader + + BlockReader + + ChainStateBlockReader, > + 'static, { /// Create a new instance @@ -145,7 +148,10 @@ impl EngineHook for StaticFileHook where Provider: StaticFileProviderFactory + DatabaseProviderFactory< - Provider: StageCheckpointReader + BlockReader + ChainStateBlockReader, + Provider: StaticFileProviderFactory + + StageCheckpointReader + + BlockReader + + ChainStateBlockReader, > + 'static, { fn name(&self) -> &'static str { diff --git a/crates/stages/stages/src/stages/headers.rs b/crates/stages/stages/src/stages/headers.rs index 133a0719d91..1ec55f7fd80 100644 --- a/crates/stages/stages/src/stages/headers.rs +++ b/crates/stages/stages/src/stages/headers.rs @@ -13,9 +13,8 @@ use reth_network_p2p::headers::{downloader::HeaderDownloader, error::HeadersDown use reth_primitives::{SealedHeader, StaticFileSegment}; use reth_primitives_traits::serde_bincode_compat; use reth_provider::{ - providers::{StaticFileProvider, StaticFileWriter}, - BlockHashReader, DBProvider, HeaderProvider, HeaderSyncGap, HeaderSyncGapProvider, - StaticFileProviderFactory, + providers::StaticFileWriter, BlockHashReader, DBProvider, HeaderProvider, HeaderSyncGap, + HeaderSyncGapProvider, StaticFileProviderFactory, }; use reth_stages_api::{ BlockErrorKind, CheckpointBlockRange, EntitiesCheckpoint, ExecInput, ExecOutput, @@ -90,15 +89,16 @@ where /// /// Writes to static files ( `Header | HeaderTD | HeaderHash` ) and [`tables::HeaderNumbers`] /// database table. - fn write_headers( + fn write_headers + StaticFileProviderFactory>( &mut self, - provider: &impl DBProvider, - static_file_provider: StaticFileProvider, + provider: &P, ) -> Result { let total_headers = self.header_collector.len(); info!(target: "sync::stages::headers", total = total_headers, "Writing headers"); + let static_file_provider = provider.static_file_provider(); + // Consistency check of expected headers in static files vs DB is done on provider::sync_gap // when poll_execute_ready is polled. let mut last_header_number = static_file_provider @@ -293,7 +293,7 @@ where // Write the headers and related tables to DB from ETL space let to_be_processed = self.hash_collector.len() as u64; - let last_header_number = self.write_headers(provider, provider.static_file_provider())?; + let last_header_number = self.write_headers(provider)?; // Clear ETL collectors self.hash_collector.clear(); diff --git a/crates/static-file/static-file/src/segments/headers.rs b/crates/static-file/static-file/src/segments/headers.rs index 54d5bee65cf..650f4998764 100644 --- a/crates/static-file/static-file/src/segments/headers.rs +++ b/crates/static-file/static-file/src/segments/headers.rs @@ -2,10 +2,7 @@ use crate::segments::Segment; use alloy_primitives::BlockNumber; use reth_db::tables; use reth_db_api::{cursor::DbCursorRO, transaction::DbTx}; -use reth_provider::{ - providers::{StaticFileProvider, StaticFileWriter}, - DBProvider, -}; +use reth_provider::{providers::StaticFileWriter, DBProvider, StaticFileProviderFactory}; use reth_static_file_types::StaticFileSegment; use reth_storage_errors::provider::ProviderResult; use std::ops::RangeInclusive; @@ -14,7 +11,7 @@ use std::ops::RangeInclusive; #[derive(Debug, Default)] pub struct Headers; -impl Segment for Headers { +impl Segment for Headers { fn segment(&self) -> StaticFileSegment { StaticFileSegment::Headers } @@ -22,9 +19,9 @@ impl Segment for Headers { fn copy_to_static_files( &self, provider: Provider, - static_file_provider: StaticFileProvider, block_range: RangeInclusive, ) -> ProviderResult<()> { + let static_file_provider = provider.static_file_provider(); let mut static_file_writer = static_file_provider.get_writer(*block_range.start(), StaticFileSegment::Headers)?; diff --git a/crates/static-file/static-file/src/segments/mod.rs b/crates/static-file/static-file/src/segments/mod.rs index 3d961c7b119..fc79effdd5a 100644 --- a/crates/static-file/static-file/src/segments/mod.rs +++ b/crates/static-file/static-file/src/segments/mod.rs @@ -10,22 +10,22 @@ mod receipts; pub use receipts::Receipts; use alloy_primitives::BlockNumber; -use reth_provider::providers::StaticFileProvider; +use reth_provider::StaticFileProviderFactory; use reth_static_file_types::StaticFileSegment; use reth_storage_errors::provider::ProviderResult; use std::ops::RangeInclusive; /// A segment represents moving some portion of the data to static files. -pub trait Segment: Send + Sync { +pub trait Segment: Send + Sync { /// Returns the [`StaticFileSegment`]. fn segment(&self) -> StaticFileSegment; - /// Move data to static files for the provided block range. [`StaticFileProvider`] will handle + /// Move data to static files for the provided block range. + /// [`StaticFileProvider`](reth_provider::providers::StaticFileProvider) will handle /// the management of and writing to files. fn copy_to_static_files( &self, provider: Provider, - static_file_provider: StaticFileProvider, block_range: RangeInclusive, ) -> ProviderResult<()>; } diff --git a/crates/static-file/static-file/src/segments/receipts.rs b/crates/static-file/static-file/src/segments/receipts.rs index 4e2185a598a..0442c360099 100644 --- a/crates/static-file/static-file/src/segments/receipts.rs +++ b/crates/static-file/static-file/src/segments/receipts.rs @@ -3,8 +3,7 @@ use alloy_primitives::BlockNumber; use reth_db::tables; use reth_db_api::{cursor::DbCursorRO, transaction::DbTx}; use reth_provider::{ - providers::{StaticFileProvider, StaticFileWriter}, - BlockReader, DBProvider, + providers::StaticFileWriter, BlockReader, DBProvider, StaticFileProviderFactory, }; use reth_static_file_types::StaticFileSegment; use reth_storage_errors::provider::{ProviderError, ProviderResult}; @@ -14,7 +13,9 @@ use std::ops::RangeInclusive; #[derive(Debug, Default)] pub struct Receipts; -impl Segment for Receipts { +impl Segment + for Receipts +{ fn segment(&self) -> StaticFileSegment { StaticFileSegment::Receipts } @@ -22,9 +23,9 @@ impl Segment for Receipts { fn copy_to_static_files( &self, provider: Provider, - static_file_provider: StaticFileProvider, block_range: RangeInclusive, ) -> ProviderResult<()> { + let static_file_provider = provider.static_file_provider(); let mut static_file_writer = static_file_provider.get_writer(*block_range.start(), StaticFileSegment::Receipts)?; diff --git a/crates/static-file/static-file/src/segments/transactions.rs b/crates/static-file/static-file/src/segments/transactions.rs index 52e0ca8b575..eba1987080c 100644 --- a/crates/static-file/static-file/src/segments/transactions.rs +++ b/crates/static-file/static-file/src/segments/transactions.rs @@ -3,8 +3,7 @@ use alloy_primitives::BlockNumber; use reth_db::tables; use reth_db_api::{cursor::DbCursorRO, transaction::DbTx}; use reth_provider::{ - providers::{StaticFileProvider, StaticFileWriter}, - BlockReader, DBProvider, + providers::StaticFileWriter, BlockReader, DBProvider, StaticFileProviderFactory, }; use reth_static_file_types::StaticFileSegment; use reth_storage_errors::provider::{ProviderError, ProviderResult}; @@ -14,7 +13,9 @@ use std::ops::RangeInclusive; #[derive(Debug, Default)] pub struct Transactions; -impl Segment for Transactions { +impl Segment + for Transactions +{ fn segment(&self) -> StaticFileSegment { StaticFileSegment::Transactions } @@ -24,9 +25,9 @@ impl Segment for Transactions { fn copy_to_static_files( &self, provider: Provider, - static_file_provider: StaticFileProvider, block_range: RangeInclusive, ) -> ProviderResult<()> { + let static_file_provider = provider.static_file_provider(); let mut static_file_writer = static_file_provider .get_writer(*block_range.start(), StaticFileSegment::Transactions)?; diff --git a/crates/static-file/static-file/src/static_file_producer.rs b/crates/static-file/static-file/src/static_file_producer.rs index 0f07ec32821..8959819e821 100644 --- a/crates/static-file/static-file/src/static_file_producer.rs +++ b/crates/static-file/static-file/src/static_file_producer.rs @@ -85,7 +85,9 @@ where impl StaticFileProducerInner where Provider: StaticFileProviderFactory - + DatabaseProviderFactory, + + DatabaseProviderFactory< + Provider: StaticFileProviderFactory + StageCheckpointReader + BlockReader, + >, { /// Listen for events on the `static_file_producer`. pub fn events(&self) -> EventStream { @@ -136,7 +138,7 @@ where // Create a new database transaction on every segment to prevent long-lived read-only // transactions let provider = self.provider.database_provider_ro()?.disable_long_read_transaction_safety(); - segment.copy_to_static_files(provider, self.provider.static_file_provider(), block_range.clone())?; + segment.copy_to_static_files(provider, block_range.clone())?; let elapsed = start.elapsed(); // TODO(alexey): track in metrics debug!(target: "static_file", segment = %segment.segment(), ?block_range, ?elapsed, "Finished StaticFileProducer segment"); From 61d32e9bfdfadbc1f8bbcaefbbc8d83bbd9bc5e6 Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Thu, 14 Nov 2024 17:37:39 -0500 Subject: [PATCH 178/211] fix(rpc): remove reference to preimage bool in debug_executionWitness (#12559) --- crates/rpc/rpc-api/src/debug.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/rpc/rpc-api/src/debug.rs b/crates/rpc/rpc-api/src/debug.rs index 1b857d4a11f..76316fa71f4 100644 --- a/crates/rpc/rpc-api/src/debug.rs +++ b/crates/rpc/rpc-api/src/debug.rs @@ -136,8 +136,7 @@ pub trait DebugApi { /// to their preimages that were required during the execution of the block, including during /// state root recomputation. /// - /// The first argument is the block number or block hash. The second argument is a boolean - /// indicating whether to include the preimages of keys in the response. + /// The first argument is the block number or block hash. #[method(name = "executionWitness")] async fn debug_execution_witness(&self, block: BlockNumberOrTag) -> RpcResult; From 7a7a6de2cd7db570b9e07eca58bf59cd3e5f7d9e Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Fri, 15 Nov 2024 09:35:00 +0100 Subject: [PATCH 179/211] primitive-traits: simplify `SealedHeader::default` (#12563) --- crates/primitives-traits/src/header/sealed.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/primitives-traits/src/header/sealed.rs b/crates/primitives-traits/src/header/sealed.rs index e872eb9811d..ef81891d552 100644 --- a/crates/primitives-traits/src/header/sealed.rs +++ b/crates/primitives-traits/src/header/sealed.rs @@ -78,9 +78,7 @@ impl InMemorySize for SealedHeader { impl Default for SealedHeader { fn default() -> Self { - let sealed = H::default().seal_slow(); - let (header, hash) = sealed.into_parts(); - Self { header, hash } + Self::seal(H::default()) } } From 28478a5144acbefa883056d9096e25837ab0cf60 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Fri, 15 Nov 2024 09:35:27 +0100 Subject: [PATCH 180/211] primitives: rm alloy `HOLESKY_GENESIS_HASH` reexport (#12562) --- crates/chainspec/src/spec.rs | 6 ++++-- crates/primitives-traits/src/constants/mod.rs | 6 ------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/crates/chainspec/src/spec.rs b/crates/chainspec/src/spec.rs index fdaad948f26..1f8ebd45f45 100644 --- a/crates/chainspec/src/spec.rs +++ b/crates/chainspec/src/spec.rs @@ -12,7 +12,9 @@ use alloy_primitives::{address, b256, Address, BlockNumber, B256, U256}; use derive_more::From; use alloy_consensus::{ - constants::{DEV_GENESIS_HASH, MAINNET_GENESIS_HASH, SEPOLIA_GENESIS_HASH}, + constants::{ + DEV_GENESIS_HASH, HOLESKY_GENESIS_HASH, MAINNET_GENESIS_HASH, SEPOLIA_GENESIS_HASH, + }, Header, }; use alloy_eips::eip1559::ETHEREUM_BLOCK_GAS_LIMIT; @@ -24,7 +26,7 @@ use reth_network_peers::{ base_nodes, base_testnet_nodes, holesky_nodes, mainnet_nodes, op_nodes, op_testnet_nodes, sepolia_nodes, NodeRecord, }; -use reth_primitives_traits::{constants::HOLESKY_GENESIS_HASH, SealedHeader}; +use reth_primitives_traits::SealedHeader; use reth_trie_common::root::state_root_ref_unhashed; use crate::{constants::MAINNET_DEPOSIT_CONTRACT, once_cell_set, EthChainSpec, LazyLock, OnceLock}; diff --git a/crates/primitives-traits/src/constants/mod.rs b/crates/primitives-traits/src/constants/mod.rs index 94eaf95c269..e927ed3a7df 100644 --- a/crates/primitives-traits/src/constants/mod.rs +++ b/crates/primitives-traits/src/constants/mod.rs @@ -1,7 +1,5 @@ //! Ethereum protocol-related constants -use alloy_primitives::{b256, B256}; - /// Gas units, for example [`GIGAGAS`]. pub mod gas_units; pub use gas_units::{GIGAGAS, KILOGAS, MEGAGAS}; @@ -12,10 +10,6 @@ pub const RETH_CLIENT_VERSION: &str = concat!("reth/v", env!("CARGO_PKG_VERSION" /// Minimum gas limit allowed for transactions. pub const MINIMUM_GAS_LIMIT: u64 = 5000; -/// Holesky genesis hash: `0xb5f7f912443c940f21fd611f12828d75b534364ed9e95ca4e307729a4661bde4` -pub const HOLESKY_GENESIS_HASH: B256 = - b256!("b5f7f912443c940f21fd611f12828d75b534364ed9e95ca4e307729a4661bde4"); - /// The number of blocks to unwind during a reorg that already became a part of canonical chain. /// /// In reality, the node can end up in this particular situation very rarely. It would happen only From 1aa316e4bcca4277f8e39847a60eca26f13f6115 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Fri, 15 Nov 2024 09:41:37 +0100 Subject: [PATCH 181/211] fmt(primitives): group pub use transaction (#12561) --- crates/primitives/src/lib.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 2318b3c2455..87bf254edab 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -44,13 +44,10 @@ pub use reth_primitives_traits::{ }; pub use static_file::StaticFileSegment; -pub use transaction::{ - BlobTransaction, PooledTransactionsElement, PooledTransactionsElementEcRecovered, -}; - pub use transaction::{ util::secp256k1::{public_key_to_address, recover_signer_unchecked, sign_message}, - InvalidTransactionError, Transaction, TransactionMeta, TransactionSigned, + BlobTransaction, InvalidTransactionError, PooledTransactionsElement, + PooledTransactionsElementEcRecovered, Transaction, TransactionMeta, TransactionSigned, TransactionSignedEcRecovered, TransactionSignedNoHash, TxHashOrNumber, TxType, }; From 93ec6d48fe58f9352955f17131e92690e6562741 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Fri, 15 Nov 2024 09:43:21 +0100 Subject: [PATCH 182/211] net: use `BlockWithParent` in `SyncTarget::Gap` (#12514) --- crates/net/downloaders/src/headers/reverse_headers.rs | 11 ++++++++--- crates/net/p2p/src/headers/downloader.rs | 5 +++-- crates/primitives-traits/src/header/mod.rs | 2 +- crates/primitives-traits/src/header/sealed.rs | 11 ++++++++++- crates/primitives-traits/src/lib.rs | 2 +- 5 files changed, 23 insertions(+), 8 deletions(-) diff --git a/crates/net/downloaders/src/headers/reverse_headers.rs b/crates/net/downloaders/src/headers/reverse_headers.rs index 3960ae6e812..0f8111e4395 100644 --- a/crates/net/downloaders/src/headers/reverse_headers.rs +++ b/crates/net/downloaders/src/headers/reverse_headers.rs @@ -707,13 +707,13 @@ where } } SyncTarget::Gap(existing) => { - let target = existing.parent_hash; + let target = existing.parent; if Some(target) != current_tip { // there could be a sync target request in progress self.sync_target_request.take(); // If the target has changed, update the request pointers based on the new // targeted block number - let parent_block_number = existing.number.saturating_sub(1); + let parent_block_number = existing.block.number.saturating_sub(1); trace!(target: "downloaders::headers", current=?current_tip, new=?target, %parent_block_number, "Updated sync target"); @@ -1225,9 +1225,11 @@ mod tests { use super::*; use crate::headers::test_utils::child_header; use alloy_consensus::Header; + use alloy_eips::BlockNumHash; use assert_matches::assert_matches; use reth_consensus::test_utils::TestConsensus; use reth_network_p2p::test_utils::TestHeadersClient; + use reth_primitives_traits::BlockWithParent; /// Tests that `replace_number` works the same way as `Option::replace` #[test] @@ -1307,7 +1309,10 @@ mod tests { assert!(downloader.sync_target_request.is_some()); downloader.sync_target_request.take(); - let target = SyncTarget::Gap(SealedHeader::new(Default::default(), B256::random())); + let target = SyncTarget::Gap(BlockWithParent { + block: BlockNumHash::new(0, B256::random()), + parent: Default::default(), + }); downloader.update_sync_target(target); assert!(downloader.sync_target_request.is_none()); assert_matches!( diff --git a/crates/net/p2p/src/headers/downloader.rs b/crates/net/p2p/src/headers/downloader.rs index 59ecb58b84d..f02d9461fc1 100644 --- a/crates/net/p2p/src/headers/downloader.rs +++ b/crates/net/p2p/src/headers/downloader.rs @@ -6,6 +6,7 @@ use alloy_primitives::B256; use futures::Stream; use reth_consensus::Consensus; use reth_primitives::SealedHeader; +use reth_primitives_traits::BlockWithParent; /// A downloader capable of fetching and yielding block headers. /// /// A downloader represents a distinct strategy for submitting requests to download block headers, @@ -57,7 +58,7 @@ pub enum SyncTarget { /// /// The benefit of this variant is, that this already provides the block number of the highest /// missing block. - Gap(SealedHeader), + Gap(BlockWithParent), /// This represents a tip by block number TipNum(u64), } @@ -72,7 +73,7 @@ impl SyncTarget { pub fn tip(&self) -> BlockHashOrNumber { match self { Self::Tip(tip) => (*tip).into(), - Self::Gap(gap) => gap.parent_hash.into(), + Self::Gap(gap) => gap.parent.into(), Self::TipNum(num) => (*num).into(), } } diff --git a/crates/primitives-traits/src/header/mod.rs b/crates/primitives-traits/src/header/mod.rs index 760abf33720..ecd5725838e 100644 --- a/crates/primitives-traits/src/header/mod.rs +++ b/crates/primitives-traits/src/header/mod.rs @@ -1,5 +1,5 @@ mod sealed; -pub use sealed::SealedHeader; +pub use sealed::{BlockWithParent, SealedHeader}; mod error; pub use error::HeaderError; diff --git a/crates/primitives-traits/src/header/sealed.rs b/crates/primitives-traits/src/header/sealed.rs index ef81891d552..dab54977c51 100644 --- a/crates/primitives-traits/src/header/sealed.rs +++ b/crates/primitives-traits/src/header/sealed.rs @@ -2,7 +2,7 @@ use super::Header; use crate::InMemorySize; use alloy_consensus::Sealed; use alloy_eips::BlockNumHash; -use alloy_primitives::{keccak256, BlockHash, Sealable}; +use alloy_primitives::{keccak256, BlockHash, Sealable, B256}; use alloy_rlp::{Decodable, Encodable}; use bytes::BufMut; use core::mem; @@ -10,6 +10,15 @@ use derive_more::{AsRef, Deref}; use reth_codecs::add_arbitrary_tests; use serde::{Deserialize, Serialize}; +/// A helper struct to store the block number/hash and its parent hash. +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct BlockWithParent { + /// Parent hash. + pub parent: B256, + /// Block number/hash. + pub block: BlockNumHash, +} + /// A [`Header`] that is sealed at a precalculated hash, use [`SealedHeader::unseal()`] if you want /// to modify header. #[derive(Debug, Clone, PartialEq, Eq, Hash, AsRef, Deref, Serialize, Deserialize)] diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index b8f0aa4c8a8..584181f2c95 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -59,7 +59,7 @@ pub use tx_type::{FullTxType, TxType}; pub mod header; #[cfg(any(test, feature = "arbitrary", feature = "test-utils"))] pub use header::test_utils; -pub use header::{HeaderError, SealedHeader}; +pub use header::{BlockWithParent, HeaderError, SealedHeader}; /// Bincode-compatible serde implementations for common abstracted types in Reth. /// From 44964ac17124643b8fc745565cdcf9e457492377 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Fri, 15 Nov 2024 09:56:46 +0100 Subject: [PATCH 183/211] engine-primitives: make engine-tree independent of beacon-consensus crate (#12560) --- Cargo.lock | 8 ++++++- crates/consensus/beacon/src/engine/error.rs | 21 ------------------- crates/consensus/beacon/src/engine/event.rs | 2 +- crates/consensus/beacon/src/engine/handle.rs | 10 ++++----- crates/consensus/beacon/src/engine/mod.rs | 17 ++++++--------- .../consensus/beacon/src/engine/test_utils.rs | 4 ++-- crates/engine/local/src/miner.rs | 3 +-- crates/engine/local/src/service.rs | 3 ++- crates/engine/primitives/Cargo.toml | 7 +++++++ crates/engine/primitives/src/error.rs | 20 ++++++++++++++++++ .../primitives/src}/forkchoice.rs | 8 +++---- crates/engine/primitives/src/lib.rs | 9 ++++++++ .../primitives/src}/message.rs | 3 +-- crates/engine/service/Cargo.toml | 1 + crates/engine/service/src/service.rs | 4 +++- crates/engine/tree/src/engine.rs | 4 ++-- crates/engine/tree/src/tree/mod.rs | 21 +++++++++++-------- crates/engine/util/Cargo.toml | 8 +++---- crates/engine/util/src/engine_store.rs | 3 +-- crates/engine/util/src/lib.rs | 3 +-- crates/engine/util/src/reorg.rs | 6 ++++-- crates/engine/util/src/skip_fcu.rs | 3 +-- crates/engine/util/src/skip_new_payload.rs | 3 +-- crates/node/events/Cargo.toml | 1 + crates/node/events/src/node.rs | 5 ++--- crates/rpc/rpc-engine-api/src/engine_api.rs | 3 ++- crates/rpc/rpc-engine-api/src/error.rs | 3 ++- 27 files changed, 101 insertions(+), 82 deletions(-) create mode 100644 crates/engine/primitives/src/error.rs rename crates/{consensus/beacon/src/engine => engine/primitives/src}/forkchoice.rs (98%) rename crates/{consensus/beacon/src/engine => engine/primitives/src}/message.rs (98%) diff --git a/Cargo.lock b/Cargo.lock index 12e1a4a8cda..d92f66e8a58 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7181,11 +7181,16 @@ name = "reth-engine-primitives" version = "1.1.1" dependencies = [ "alloy-primitives", + "alloy-rpc-types-engine", + "futures", + "reth-errors", "reth-execution-types", "reth-payload-primitives", "reth-primitives", "reth-trie", "serde", + "thiserror 1.0.69", + "tokio", ] [[package]] @@ -7197,6 +7202,7 @@ dependencies = [ "reth-beacon-consensus", "reth-chainspec", "reth-consensus", + "reth-engine-primitives", "reth-engine-tree", "reth-ethereum-engine-primitives", "reth-evm", @@ -7278,7 +7284,6 @@ dependencies = [ "futures", "itertools 0.13.0", "pin-project", - "reth-beacon-consensus", "reth-engine-primitives", "reth-errors", "reth-ethereum-forks", @@ -8109,6 +8114,7 @@ dependencies = [ "humantime", "pin-project", "reth-beacon-consensus", + "reth-engine-primitives", "reth-network-api", "reth-primitives-traits", "reth-prune", diff --git a/crates/consensus/beacon/src/engine/error.rs b/crates/consensus/beacon/src/engine/error.rs index 5fc6df2b884..2092ea49f77 100644 --- a/crates/consensus/beacon/src/engine/error.rs +++ b/crates/consensus/beacon/src/engine/error.rs @@ -77,24 +77,3 @@ impl From for BeaconForkChoiceUpdateError { Self::internal(e) } } - -/// Represents all error cases when handling a new payload. -/// -/// This represents all possible error cases that must be returned as JSON RCP errors back to the -/// beacon node. -#[derive(Debug, thiserror::Error)] -pub enum BeaconOnNewPayloadError { - /// Thrown when the engine task is unavailable/stopped. - #[error("beacon consensus engine task stopped")] - EngineUnavailable, - /// An internal error occurred, not necessarily related to the payload. - #[error(transparent)] - Internal(Box), -} - -impl BeaconOnNewPayloadError { - /// Create a new internal error. - pub fn internal(e: E) -> Self { - Self::Internal(Box::new(e)) - } -} diff --git a/crates/consensus/beacon/src/engine/event.rs b/crates/consensus/beacon/src/engine/event.rs index 975085a32f3..b76b85374cd 100644 --- a/crates/consensus/beacon/src/engine/event.rs +++ b/crates/consensus/beacon/src/engine/event.rs @@ -1,6 +1,6 @@ -use crate::engine::forkchoice::ForkchoiceStatus; use alloy_primitives::B256; use alloy_rpc_types_engine::ForkchoiceState; +use reth_engine_primitives::ForkchoiceStatus; use reth_primitives::{SealedBlock, SealedHeader}; use std::{ fmt::{Display, Formatter, Result}, diff --git a/crates/consensus/beacon/src/engine/handle.rs b/crates/consensus/beacon/src/engine/handle.rs index f8840cf78ab..339f2fb067f 100644 --- a/crates/consensus/beacon/src/engine/handle.rs +++ b/crates/consensus/beacon/src/engine/handle.rs @@ -1,14 +1,14 @@ //! `BeaconConsensusEngine` external API -use crate::{ - engine::message::OnForkChoiceUpdated, BeaconConsensusEngineEvent, BeaconEngineMessage, - BeaconForkChoiceUpdateError, BeaconOnNewPayloadError, -}; +use crate::{BeaconConsensusEngineEvent, BeaconForkChoiceUpdateError}; use alloy_rpc_types_engine::{ ExecutionPayload, ExecutionPayloadSidecar, ForkchoiceState, ForkchoiceUpdated, PayloadStatus, }; use futures::TryFutureExt; -use reth_engine_primitives::{EngineApiMessageVersion, EngineTypes}; +use reth_engine_primitives::{ + BeaconEngineMessage, BeaconOnNewPayloadError, EngineApiMessageVersion, EngineTypes, + OnForkChoiceUpdated, +}; use reth_errors::RethResult; use reth_tokio_util::{EventSender, EventStream}; use tokio::sync::{mpsc::UnboundedSender, oneshot}; diff --git a/crates/consensus/beacon/src/engine/mod.rs b/crates/consensus/beacon/src/engine/mod.rs index 03f7bf08b1e..bc6bd3bc4f4 100644 --- a/crates/consensus/beacon/src/engine/mod.rs +++ b/crates/consensus/beacon/src/engine/mod.rs @@ -11,7 +11,11 @@ use reth_blockchain_tree_api::{ error::{BlockchainTreeError, CanonicalError, InsertBlockError, InsertBlockErrorKind}, BlockStatus, BlockValidationKind, BlockchainTreeEngine, CanonicalOutcome, InsertPayloadOk, }; -use reth_engine_primitives::{EngineApiMessageVersion, EngineTypes, PayloadTypes}; +use reth_engine_primitives::{ + BeaconEngineMessage, BeaconOnNewPayloadError, EngineApiMessageVersion, EngineTypes, + ForkchoiceStateHash, ForkchoiceStateTracker, ForkchoiceStatus, OnForkChoiceUpdated, + PayloadTypes, +}; use reth_errors::{BlockValidationError, ProviderResult, RethError, RethResult}; use reth_network_p2p::{ sync::{NetworkSyncUpdater, SyncState}, @@ -42,14 +46,8 @@ use tokio::sync::{ use tokio_stream::wrappers::UnboundedReceiverStream; use tracing::*; -mod message; -pub use message::{BeaconEngineMessage, OnForkChoiceUpdated}; - mod error; -pub use error::{ - BeaconConsensusEngineError, BeaconEngineResult, BeaconForkChoiceUpdateError, - BeaconOnNewPayloadError, -}; +pub use error::{BeaconConsensusEngineError, BeaconEngineResult, BeaconForkChoiceUpdateError}; mod invalid_headers; pub use invalid_headers::InvalidHeaderCache; @@ -60,9 +58,6 @@ pub use event::{BeaconConsensusEngineEvent, ConsensusEngineLiveSyncProgress}; mod handle; pub use handle::BeaconConsensusEngineHandle; -mod forkchoice; -pub use forkchoice::{ForkchoiceStateHash, ForkchoiceStateTracker, ForkchoiceStatus}; - mod metrics; use metrics::EngineMetrics; diff --git a/crates/consensus/beacon/src/engine/test_utils.rs b/crates/consensus/beacon/src/engine/test_utils.rs index 0ad4c595f1b..64daba2b453 100644 --- a/crates/consensus/beacon/src/engine/test_utils.rs +++ b/crates/consensus/beacon/src/engine/test_utils.rs @@ -2,7 +2,7 @@ use crate::{ engine::hooks::PruneHook, hooks::EngineHooks, BeaconConsensusEngine, BeaconConsensusEngineError, BeaconConsensusEngineHandle, BeaconForkChoiceUpdateError, - BeaconOnNewPayloadError, EthBeaconConsensus, MIN_BLOCKS_FOR_PIPELINE_RUN, + EthBeaconConsensus, MIN_BLOCKS_FOR_PIPELINE_RUN, }; use alloy_primitives::{BlockNumber, B256}; use alloy_rpc_types_engine::{ @@ -19,7 +19,7 @@ use reth_downloaders::{ bodies::bodies::BodiesDownloaderBuilder, headers::reverse_headers::ReverseHeadersDownloaderBuilder, }; -use reth_engine_primitives::EngineApiMessageVersion; +use reth_engine_primitives::{BeaconOnNewPayloadError, EngineApiMessageVersion}; use reth_ethereum_engine_primitives::EthEngineTypes; use reth_evm::{either::Either, test_utils::MockExecutorProvider}; use reth_evm_ethereum::execute::EthExecutorProvider; diff --git a/crates/engine/local/src/miner.rs b/crates/engine/local/src/miner.rs index 7cebd306309..2085aa81f9b 100644 --- a/crates/engine/local/src/miner.rs +++ b/crates/engine/local/src/miner.rs @@ -4,9 +4,8 @@ use alloy_primitives::{TxHash, B256}; use alloy_rpc_types_engine::{CancunPayloadFields, ExecutionPayloadSidecar, ForkchoiceState}; use eyre::OptionExt; use futures_util::{stream::Fuse, StreamExt}; -use reth_beacon_consensus::BeaconEngineMessage; use reth_chainspec::EthereumHardforks; -use reth_engine_primitives::{EngineApiMessageVersion, EngineTypes}; +use reth_engine_primitives::{BeaconEngineMessage, EngineApiMessageVersion, EngineTypes}; use reth_payload_builder::PayloadBuilderHandle; use reth_payload_primitives::{ BuiltPayload, PayloadAttributesBuilder, PayloadBuilder, PayloadKind, PayloadTypes, diff --git a/crates/engine/local/src/service.rs b/crates/engine/local/src/service.rs index 93a9cf11ecc..4e4826be31d 100644 --- a/crates/engine/local/src/service.rs +++ b/crates/engine/local/src/service.rs @@ -16,9 +16,10 @@ use std::{ use crate::miner::{LocalMiner, MiningMode}; use futures_util::{Stream, StreamExt}; -use reth_beacon_consensus::{BeaconConsensusEngineEvent, BeaconEngineMessage, EngineNodeTypes}; +use reth_beacon_consensus::{BeaconConsensusEngineEvent, EngineNodeTypes}; use reth_chainspec::EthChainSpec; use reth_consensus::Consensus; +use reth_engine_primitives::BeaconEngineMessage; use reth_engine_service::service::EngineMessageStream; use reth_engine_tree::{ chain::{ChainEvent, HandlerEvent}, diff --git a/crates/engine/primitives/Cargo.toml b/crates/engine/primitives/Cargo.toml index 008af450332..de4786553d3 100644 --- a/crates/engine/primitives/Cargo.toml +++ b/crates/engine/primitives/Cargo.toml @@ -16,9 +16,16 @@ reth-execution-types.workspace = true reth-payload-primitives.workspace = true reth-primitives.workspace = true reth-trie.workspace = true +reth-errors.workspace = true # alloy alloy-primitives.workspace = true +alloy-rpc-types-engine.workspace = true + +# async +tokio = { workspace = true, features = ["sync"] } +futures.workspace = true # misc serde.workspace = true +thiserror.workspace = true diff --git a/crates/engine/primitives/src/error.rs b/crates/engine/primitives/src/error.rs new file mode 100644 index 00000000000..b7deb607bcf --- /dev/null +++ b/crates/engine/primitives/src/error.rs @@ -0,0 +1,20 @@ +/// Represents all error cases when handling a new payload. +/// +/// This represents all possible error cases that must be returned as JSON RCP errors back to the +/// beacon node. +#[derive(Debug, thiserror::Error)] +pub enum BeaconOnNewPayloadError { + /// Thrown when the engine task is unavailable/stopped. + #[error("beacon consensus engine task stopped")] + EngineUnavailable, + /// An internal error occurred, not necessarily related to the payload. + #[error(transparent)] + Internal(Box), +} + +impl BeaconOnNewPayloadError { + /// Create a new internal error. + pub fn internal(e: E) -> Self { + Self::Internal(Box::new(e)) + } +} diff --git a/crates/consensus/beacon/src/engine/forkchoice.rs b/crates/engine/primitives/src/forkchoice.rs similarity index 98% rename from crates/consensus/beacon/src/engine/forkchoice.rs rename to crates/engine/primitives/src/forkchoice.rs index a9d9301738f..3c70b78ecdd 100644 --- a/crates/consensus/beacon/src/engine/forkchoice.rs +++ b/crates/engine/primitives/src/forkchoice.rs @@ -58,13 +58,13 @@ impl ForkchoiceStateTracker { /// Returns whether the latest received FCU is syncing: [`ForkchoiceStatus::Invalid`] #[allow(dead_code)] - pub(crate) fn is_latest_invalid(&self) -> bool { + pub fn is_latest_invalid(&self) -> bool { self.latest_status().map_or(false, |s| s.is_invalid()) } /// Returns the last valid head hash. #[allow(dead_code)] - pub(crate) fn last_valid_head(&self) -> Option { + pub fn last_valid_head(&self) -> Option { self.last_valid.as_ref().map(|s| s.head_block_hash) } @@ -188,7 +188,7 @@ pub enum ForkchoiceStateHash { impl ForkchoiceStateHash { /// Tries to find a matching hash in the given [`ForkchoiceState`]. - pub(crate) fn find(state: &ForkchoiceState, hash: B256) -> Option { + pub fn find(state: &ForkchoiceState, hash: B256) -> Option { if state.head_block_hash == hash { Some(Self::Head(hash)) } else if state.safe_block_hash == hash { @@ -201,7 +201,7 @@ impl ForkchoiceStateHash { } /// Returns true if this is the head hash of the [`ForkchoiceState`] - pub(crate) const fn is_head(&self) -> bool { + pub const fn is_head(&self) -> bool { matches!(self, Self::Head(_)) } } diff --git a/crates/engine/primitives/src/lib.rs b/crates/engine/primitives/src/lib.rs index 949ebf0155c..3429edc2867 100644 --- a/crates/engine/primitives/src/lib.rs +++ b/crates/engine/primitives/src/lib.rs @@ -8,6 +8,15 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +mod error; +pub use error::BeaconOnNewPayloadError; + +mod forkchoice; +pub use forkchoice::{ForkchoiceStateHash, ForkchoiceStateTracker, ForkchoiceStatus}; + +mod message; +pub use message::{BeaconEngineMessage, OnForkChoiceUpdated}; + mod invalid_block_hook; pub use invalid_block_hook::InvalidBlockHook; diff --git a/crates/consensus/beacon/src/engine/message.rs b/crates/engine/primitives/src/message.rs similarity index 98% rename from crates/consensus/beacon/src/engine/message.rs rename to crates/engine/primitives/src/message.rs index fa7457c1225..11fd383a1e2 100644 --- a/crates/consensus/beacon/src/engine/message.rs +++ b/crates/engine/primitives/src/message.rs @@ -1,10 +1,9 @@ -use crate::engine::{error::BeaconOnNewPayloadError, forkchoice::ForkchoiceStatus}; +use crate::{BeaconOnNewPayloadError, EngineApiMessageVersion, EngineTypes, ForkchoiceStatus}; use alloy_rpc_types_engine::{ ExecutionPayload, ExecutionPayloadSidecar, ForkChoiceUpdateResult, ForkchoiceState, ForkchoiceUpdateError, ForkchoiceUpdated, PayloadId, PayloadStatus, PayloadStatusEnum, }; use futures::{future::Either, FutureExt}; -use reth_engine_primitives::{EngineApiMessageVersion, EngineTypes}; use reth_errors::RethResult; use reth_payload_primitives::PayloadBuilderError; use std::{ diff --git a/crates/engine/service/Cargo.toml b/crates/engine/service/Cargo.toml index c6098bfe667..8359c453dcc 100644 --- a/crates/engine/service/Cargo.toml +++ b/crates/engine/service/Cargo.toml @@ -25,6 +25,7 @@ reth-stages-api.workspace = true reth-tasks.workspace = true reth-node-types.workspace = true reth-chainspec.workspace = true +reth-engine-primitives.workspace = true # async futures.workspace = true diff --git a/crates/engine/service/src/service.rs b/crates/engine/service/src/service.rs index d383af6caa6..cec9d981f1b 100644 --- a/crates/engine/service/src/service.rs +++ b/crates/engine/service/src/service.rs @@ -1,8 +1,9 @@ use futures::{Stream, StreamExt}; use pin_project::pin_project; -use reth_beacon_consensus::{BeaconConsensusEngineEvent, BeaconEngineMessage, EngineNodeTypes}; +use reth_beacon_consensus::{BeaconConsensusEngineEvent, EngineNodeTypes}; use reth_chainspec::EthChainSpec; use reth_consensus::Consensus; +use reth_engine_primitives::BeaconEngineMessage; use reth_engine_tree::{ backfill::PipelineSync, download::BasicBlockDownloader, @@ -145,6 +146,7 @@ mod tests { use super::*; use reth_beacon_consensus::EthBeaconConsensus; use reth_chainspec::{ChainSpecBuilder, MAINNET}; + use reth_engine_primitives::BeaconEngineMessage; use reth_engine_tree::{test_utils::TestPipelineBuilder, tree::NoopInvalidBlockHook}; use reth_ethereum_engine_primitives::EthEngineTypes; use reth_evm_ethereum::execute::EthExecutorProvider; diff --git a/crates/engine/tree/src/engine.rs b/crates/engine/tree/src/engine.rs index 914121adce5..005d4e54399 100644 --- a/crates/engine/tree/src/engine.rs +++ b/crates/engine/tree/src/engine.rs @@ -7,9 +7,9 @@ use crate::{ }; use alloy_primitives::B256; use futures::{Stream, StreamExt}; -use reth_beacon_consensus::{BeaconConsensusEngineEvent, BeaconEngineMessage}; +use reth_beacon_consensus::BeaconConsensusEngineEvent; use reth_chain_state::ExecutedBlock; -use reth_engine_primitives::EngineTypes; +use reth_engine_primitives::{BeaconEngineMessage, EngineTypes}; use reth_primitives::SealedBlockWithSenders; use std::{ collections::HashSet, diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index adc9230af34..67e692b5c6c 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -15,8 +15,7 @@ use alloy_rpc_types_engine::{ PayloadValidationError, }; use reth_beacon_consensus::{ - BeaconConsensusEngineEvent, BeaconEngineMessage, ForkchoiceStateTracker, InvalidHeaderCache, - OnForkChoiceUpdated, MIN_BLOCKS_FOR_PIPELINE_RUN, + BeaconConsensusEngineEvent, InvalidHeaderCache, MIN_BLOCKS_FOR_PIPELINE_RUN, }; use reth_blockchain_tree::{ error::{InsertBlockErrorKindTwo, InsertBlockErrorTwo, InsertBlockFatalError}, @@ -27,7 +26,10 @@ use reth_chain_state::{ }; use reth_chainspec::EthereumHardforks; use reth_consensus::{Consensus, PostExecutionInput}; -use reth_engine_primitives::{EngineApiMessageVersion, EngineTypes}; +use reth_engine_primitives::{ + BeaconEngineMessage, BeaconOnNewPayloadError, EngineApiMessageVersion, EngineTypes, + ForkchoiceStateTracker, OnForkChoiceUpdated, +}; use reth_errors::{ConsensusError, ProviderResult}; use reth_evm::execute::BlockExecutorProvider; use reth_payload_builder::PayloadBuilderHandle; @@ -1246,11 +1248,11 @@ where } BeaconEngineMessage::NewPayload { payload, sidecar, tx } => { let output = self.on_new_payload(payload, sidecar); - if let Err(err) = tx.send(output.map(|o| o.outcome).map_err(|e| { - reth_beacon_consensus::BeaconOnNewPayloadError::Internal( - Box::new(e), - ) - })) { + if let Err(err) = + tx.send(output.map(|o| o.outcome).map_err(|e| { + BeaconOnNewPayloadError::Internal(Box::new(e)) + })) + { error!(target: "engine::tree", "Failed to send event: {err:?}"); self.metrics .engine @@ -2600,9 +2602,10 @@ mod tests { use alloy_rlp::Decodable; use alloy_rpc_types_engine::{CancunPayloadFields, ExecutionPayloadSidecar}; use assert_matches::assert_matches; - use reth_beacon_consensus::{EthBeaconConsensus, ForkchoiceStatus}; + use reth_beacon_consensus::EthBeaconConsensus; use reth_chain_state::{test_utils::TestBlockBuilder, BlockState}; use reth_chainspec::{ChainSpec, HOLESKY, MAINNET}; + use reth_engine_primitives::ForkchoiceStatus; use reth_ethereum_engine_primitives::EthEngineTypes; use reth_evm::test_utils::MockExecutorProvider; use reth_provider::test_utils::MockEthProvider; diff --git a/crates/engine/util/Cargo.toml b/crates/engine/util/Cargo.toml index 07aa40165e2..6eb22340ec1 100644 --- a/crates/engine/util/Cargo.toml +++ b/crates/engine/util/Cargo.toml @@ -17,7 +17,6 @@ reth-errors.workspace = true reth-fs-util.workspace = true reth-rpc-types-compat.workspace = true reth-engine-primitives.workspace = true -reth-beacon-consensus.workspace = true reth-payload-validator.workspace = true reth-evm.workspace = true reth-revm.workspace = true @@ -51,8 +50,7 @@ tracing.workspace = true [features] optimism = [ - "reth-beacon-consensus/optimism", - "reth-primitives/optimism", - "reth-provider/optimism", - "revm-primitives/optimism" + "reth-primitives/optimism", + "reth-provider/optimism", + "revm-primitives/optimism", ] diff --git a/crates/engine/util/src/engine_store.rs b/crates/engine/util/src/engine_store.rs index 6b584f0c1f5..efed83159b3 100644 --- a/crates/engine/util/src/engine_store.rs +++ b/crates/engine/util/src/engine_store.rs @@ -2,8 +2,7 @@ use alloy_rpc_types_engine::{ExecutionPayload, ExecutionPayloadSidecar, ForkchoiceState}; use futures::{Stream, StreamExt}; -use reth_beacon_consensus::BeaconEngineMessage; -use reth_engine_primitives::EngineTypes; +use reth_engine_primitives::{BeaconEngineMessage, EngineTypes}; use reth_fs_util as fs; use serde::{Deserialize, Serialize}; use std::{ diff --git a/crates/engine/util/src/lib.rs b/crates/engine/util/src/lib.rs index 26dc817fc95..42746c376cf 100644 --- a/crates/engine/util/src/lib.rs +++ b/crates/engine/util/src/lib.rs @@ -1,8 +1,7 @@ //! Collection of various stream utilities for consensus engine. use futures::Stream; -use reth_beacon_consensus::BeaconEngineMessage; -use reth_engine_primitives::EngineTypes; +use reth_engine_primitives::{BeaconEngineMessage, EngineTypes}; use reth_payload_validator::ExecutionPayloadValidator; use std::path::PathBuf; use tokio_util::either::Either; diff --git a/crates/engine/util/src/reorg.rs b/crates/engine/util/src/reorg.rs index 0a4dd8d496f..ec69bbd0024 100644 --- a/crates/engine/util/src/reorg.rs +++ b/crates/engine/util/src/reorg.rs @@ -7,8 +7,10 @@ use alloy_rpc_types_engine::{ }; use futures::{stream::FuturesUnordered, Stream, StreamExt, TryFutureExt}; use itertools::Either; -use reth_beacon_consensus::{BeaconEngineMessage, BeaconOnNewPayloadError, OnForkChoiceUpdated}; -use reth_engine_primitives::{EngineApiMessageVersion, EngineTypes}; +use reth_engine_primitives::{ + BeaconEngineMessage, BeaconOnNewPayloadError, EngineApiMessageVersion, EngineTypes, + OnForkChoiceUpdated, +}; use reth_errors::{BlockExecutionError, BlockValidationError, RethError, RethResult}; use reth_ethereum_forks::EthereumHardforks; use reth_evm::{ diff --git a/crates/engine/util/src/skip_fcu.rs b/crates/engine/util/src/skip_fcu.rs index adadfb595f8..daa39ad572d 100644 --- a/crates/engine/util/src/skip_fcu.rs +++ b/crates/engine/util/src/skip_fcu.rs @@ -1,8 +1,7 @@ //! Stream wrapper that skips specified number of FCUs. use futures::{Stream, StreamExt}; -use reth_beacon_consensus::{BeaconEngineMessage, OnForkChoiceUpdated}; -use reth_engine_primitives::EngineTypes; +use reth_engine_primitives::{BeaconEngineMessage, EngineTypes, OnForkChoiceUpdated}; use std::{ pin::Pin, task::{ready, Context, Poll}, diff --git a/crates/engine/util/src/skip_new_payload.rs b/crates/engine/util/src/skip_new_payload.rs index 16f2e98197c..ea89bdf6d10 100644 --- a/crates/engine/util/src/skip_new_payload.rs +++ b/crates/engine/util/src/skip_new_payload.rs @@ -2,8 +2,7 @@ use alloy_rpc_types_engine::{PayloadStatus, PayloadStatusEnum}; use futures::{Stream, StreamExt}; -use reth_beacon_consensus::BeaconEngineMessage; -use reth_engine_primitives::EngineTypes; +use reth_engine_primitives::{BeaconEngineMessage, EngineTypes}; use std::{ pin::Pin, task::{ready, Context, Poll}, diff --git a/crates/node/events/Cargo.toml b/crates/node/events/Cargo.toml index 7a5b1cf3b02..4b4d912a27b 100644 --- a/crates/node/events/Cargo.toml +++ b/crates/node/events/Cargo.toml @@ -19,6 +19,7 @@ reth-stages.workspace = true reth-prune.workspace = true reth-static-file-types.workspace = true reth-primitives-traits.workspace = true +reth-engine-primitives.workspace = true # ethereum alloy-primitives.workspace = true diff --git a/crates/node/events/src/node.rs b/crates/node/events/src/node.rs index 39c6355e36e..285e28d0f2e 100644 --- a/crates/node/events/src/node.rs +++ b/crates/node/events/src/node.rs @@ -5,9 +5,8 @@ use alloy_consensus::constants::GWEI_TO_WEI; use alloy_primitives::{BlockNumber, B256}; use alloy_rpc_types_engine::ForkchoiceState; use futures::Stream; -use reth_beacon_consensus::{ - BeaconConsensusEngineEvent, ConsensusEngineLiveSyncProgress, ForkchoiceStatus, -}; +use reth_beacon_consensus::{BeaconConsensusEngineEvent, ConsensusEngineLiveSyncProgress}; +use reth_engine_primitives::ForkchoiceStatus; use reth_network_api::{NetworkEvent, PeersInfo}; use reth_primitives_traits::{format_gas, format_gas_throughput}; use reth_prune::PrunerEvent; diff --git a/crates/rpc/rpc-engine-api/src/engine_api.rs b/crates/rpc/rpc-engine-api/src/engine_api.rs index 666154f3b22..7773b5084c9 100644 --- a/crates/rpc/rpc-engine-api/src/engine_api.rs +++ b/crates/rpc/rpc-engine-api/src/engine_api.rs @@ -1023,8 +1023,9 @@ mod tests { use super::*; use alloy_rpc_types_engine::{ClientCode, ClientVersionV1}; use assert_matches::assert_matches; - use reth_beacon_consensus::{BeaconConsensusEngineEvent, BeaconEngineMessage}; + use reth_beacon_consensus::BeaconConsensusEngineEvent; use reth_chainspec::{ChainSpec, MAINNET}; + use reth_engine_primitives::BeaconEngineMessage; use reth_ethereum_engine_primitives::{EthEngineTypes, EthereumEngineValidator}; use reth_payload_builder::test_utils::spawn_test_payload_service; use reth_primitives::SealedBlock; diff --git a/crates/rpc/rpc-engine-api/src/error.rs b/crates/rpc/rpc-engine-api/src/error.rs index 677bd2fb246..82665ca35fd 100644 --- a/crates/rpc/rpc-engine-api/src/error.rs +++ b/crates/rpc/rpc-engine-api/src/error.rs @@ -2,7 +2,8 @@ use alloy_primitives::{B256, U256}; use jsonrpsee_types::error::{ INTERNAL_ERROR_CODE, INVALID_PARAMS_CODE, INVALID_PARAMS_MSG, SERVER_ERROR_MSG, }; -use reth_beacon_consensus::{BeaconForkChoiceUpdateError, BeaconOnNewPayloadError}; +use reth_beacon_consensus::BeaconForkChoiceUpdateError; +use reth_engine_primitives::BeaconOnNewPayloadError; use reth_payload_primitives::{EngineObjectValidationError, PayloadBuilderError}; use thiserror::Error; From cd9da550da5be4607966ca615f0ed7d9a73824c1 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 15 Nov 2024 11:31:14 +0100 Subject: [PATCH 184/211] chore: extract witness recorder helper type (#12566) --- crates/revm/Cargo.toml | 1 + crates/revm/src/lib.rs | 4 ++ crates/revm/src/witness.rs | 76 +++++++++++++++++++++++++++++++++++++ crates/rpc/rpc/Cargo.toml | 2 +- crates/rpc/rpc/src/debug.rs | 53 +++----------------------- 5 files changed, 87 insertions(+), 49 deletions(-) create mode 100644 crates/revm/src/witness.rs diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index bd2251e0333..d1202cd8b2c 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -44,6 +44,7 @@ std = [ "alloy-consensus/std", "reth-primitives-traits/std", ] +witness = ["dep:reth-trie"] test-utils = [ "dep:reth-trie", "reth-primitives/test-utils", diff --git a/crates/revm/src/lib.rs b/crates/revm/src/lib.rs index b06ee816f8d..5f18a0fe616 100644 --- a/crates/revm/src/lib.rs +++ b/crates/revm/src/lib.rs @@ -29,3 +29,7 @@ pub use revm::{self, *}; /// Either type for flexible usage of different database types in the same context. pub mod either; + +/// Helper types for execution witness generation. +#[cfg(feature = "witness")] +pub mod witness; diff --git a/crates/revm/src/witness.rs b/crates/revm/src/witness.rs new file mode 100644 index 00000000000..c40c87d324b --- /dev/null +++ b/crates/revm/src/witness.rs @@ -0,0 +1,76 @@ +use alloy_primitives::{keccak256, map::B256HashMap, Bytes, B256}; +use reth_trie::{HashedPostState, HashedStorage}; +use revm::State; + +/// Tracks state changes during execution. +#[derive(Debug, Clone, Default)] +pub struct ExecutionWitnessRecord { + /// Records all state changes + pub hashed_state: HashedPostState, + /// Map of all contract codes (created / accessed) to their preimages that were required during + /// the execution of the block, including during state root recomputation. + /// + /// `keccak(bytecodes) => bytecodes` + pub codes: B256HashMap, + /// Map of all hashed account and storage keys (addresses and slots) to their preimages + /// (unhashed account addresses and storage slots, respectively) that were required during + /// the execution of the block. during the execution of the block. + /// + /// `keccak(address|slot) => address|slot` + pub keys: B256HashMap, +} + +impl ExecutionWitnessRecord { + /// Records the state after execution. + pub fn record_executed_state(&mut self, statedb: &State) { + self.codes = statedb + .cache + .contracts + .iter() + .map(|(hash, code)| (*hash, code.original_bytes())) + .chain( + // cache state does not have all the contracts, especially when + // a contract is created within the block + // the contract only exists in bundle state, therefore we need + // to include them as well + statedb + .bundle_state + .contracts + .iter() + .map(|(hash, code)| (*hash, code.original_bytes())), + ) + .collect(); + + for (address, account) in &statedb.cache.accounts { + let hashed_address = keccak256(address); + self.hashed_state + .accounts + .insert(hashed_address, account.account.as_ref().map(|a| a.info.clone().into())); + + let storage = self + .hashed_state + .storages + .entry(hashed_address) + .or_insert_with(|| HashedStorage::new(account.status.was_destroyed())); + + if let Some(account) = &account.account { + self.keys.insert(hashed_address, address.to_vec().into()); + + for (slot, value) in &account.storage { + let slot = B256::from(*slot); + let hashed_slot = keccak256(slot); + storage.storage.insert(hashed_slot, *value); + + self.keys.insert(hashed_slot, slot.into()); + } + } + } + } + + /// Creates the record from the state after execution. + pub fn from_executed_state(state: &State) -> Self { + let mut record = Self::default(); + record.record_executed_state(state); + record + } +} diff --git a/crates/rpc/rpc/Cargo.toml b/crates/rpc/rpc/Cargo.toml index ac3a548f9b5..5418cd1eb3a 100644 --- a/crates/rpc/rpc/Cargo.toml +++ b/crates/rpc/rpc/Cargo.toml @@ -23,7 +23,7 @@ reth-provider.workspace = true reth-transaction-pool.workspace = true reth-network-api.workspace = true reth-rpc-engine-api.workspace = true -reth-revm.workspace = true +reth-revm = { workspace = true, features = ["witness"] } reth-tasks = { workspace = true, features = ["rayon"] } reth-consensus-common.workspace = true reth-rpc-types-compat.workspace = true diff --git a/crates/rpc/rpc/src/debug.rs b/crates/rpc/rpc/src/debug.rs index a74d1b5a155..78040b48c5f 100644 --- a/crates/rpc/rpc/src/debug.rs +++ b/crates/rpc/rpc/src/debug.rs @@ -23,7 +23,7 @@ use reth_provider::{ BlockReaderIdExt, ChainSpecProvider, HeaderProvider, StateProofProvider, StateProviderFactory, TransactionVariant, }; -use reth_revm::database::StateProviderDatabase; +use reth_revm::{database::StateProviderDatabase, witness::ExecutionWitnessRecord}; use reth_rpc_api::DebugApiServer; use reth_rpc_eth_api::{ helpers::{EthApiSpec, EthTransactions, TraceExt}, @@ -32,7 +32,6 @@ use reth_rpc_eth_api::{ use reth_rpc_eth_types::{EthApiError, StateCacheDb}; use reth_rpc_server_types::{result::internal_rpc_err, ToRpcResult}; use reth_tasks::pool::BlockingTaskGuard; -use reth_trie::{HashedPostState, HashedStorage}; use revm::{ db::{CacheDB, State}, primitives::{db::DatabaseCommit, BlockEnv, CfgEnvWithHandlerCfg, Env, EnvWithHandlerCfg}, @@ -40,7 +39,6 @@ use revm::{ use revm_inspectors::tracing::{ FourByteInspector, MuxInspector, TracingInspector, TracingInspectorConfig, TransactionContext, }; -use revm_primitives::{keccak256, HashMap}; use std::sync::Arc; use tokio::sync::{AcquireError, OwnedSemaphorePermit}; @@ -613,60 +611,19 @@ where let db = StateProviderDatabase::new(&state_provider); let block_executor = this.inner.block_executor.executor(db); - let mut hashed_state = HashedPostState::default(); - let mut keys = HashMap::default(); - let mut codes = HashMap::default(); + let mut witness_record = ExecutionWitnessRecord::default(); let _ = block_executor .execute_with_state_closure( (&(*block).clone().unseal(), block.difficulty).into(), |statedb: &State<_>| { - codes = statedb - .cache - .contracts - .iter() - .map(|(hash, code)| (*hash, code.original_bytes())) - .chain( - // cache state does not have all the contracts, especially when - // a contract is created within the block - // the contract only exists in bundle state, therefore we need - // to include them as well - statedb - .bundle_state - .contracts - .iter() - .map(|(hash, code)| (*hash, code.original_bytes())), - ) - .collect(); - - for (address, account) in &statedb.cache.accounts { - let hashed_address = keccak256(address); - hashed_state.accounts.insert( - hashed_address, - account.account.as_ref().map(|a| a.info.clone().into()), - ); - - let storage = - hashed_state.storages.entry(hashed_address).or_insert_with( - || HashedStorage::new(account.status.was_destroyed()), - ); - - if let Some(account) = &account.account { - keys.insert(hashed_address, address.to_vec().into()); - - for (slot, value) in &account.storage { - let slot = B256::from(*slot); - let hashed_slot = keccak256(slot); - storage.storage.insert(hashed_slot, *value); - - keys.insert(hashed_slot, slot.into()); - } - } - } + witness_record.record_executed_state(statedb); }, ) .map_err(|err| EthApiError::Internal(err.into()))?; + let ExecutionWitnessRecord { hashed_state, codes, keys } = witness_record; + let state = state_provider.witness(Default::default(), hashed_state).map_err(Into::into)?; Ok(ExecutionWitness { state: state.into_iter().collect(), codes, keys }) From 72a52d5ea59f40c07f30a03f360508ea433d1255 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Fri, 15 Nov 2024 14:42:58 +0400 Subject: [PATCH 185/211] feat: make `StaticFileProvider` generic over `NodePrimitives` (#12565) --- Cargo.lock | 1 + crates/cli/commands/src/common.rs | 2 +- crates/cli/commands/src/db/stats.rs | 11 ++- crates/cli/commands/src/init_state/mod.rs | 1 - .../commands/src/init_state/without_evm.rs | 28 ++++--- crates/cli/commands/src/stage/drop.rs | 20 ++--- crates/cli/commands/src/stage/run.rs | 7 +- crates/engine/tree/src/persistence.rs | 4 +- crates/node/builder/src/launch/common.rs | 4 +- crates/node/metrics/Cargo.toml | 1 + crates/node/metrics/src/hooks.rs | 16 ++-- .../cli/src/commands/import_receipts.rs | 4 +- .../optimism/cli/src/commands/init_state.rs | 1 - crates/primitives-traits/src/node.rs | 4 +- crates/prune/prune/src/builder.rs | 19 +++-- crates/prune/prune/src/segments/set.rs | 10 ++- .../prune/src/segments/static_file/headers.rs | 14 ++-- .../src/segments/static_file/receipts.rs | 18 +++-- .../src/segments/static_file/transactions.rs | 18 +++-- crates/stages/api/src/pipeline/mod.rs | 14 +--- crates/stages/stages/src/stages/bodies.rs | 4 +- crates/stages/stages/src/stages/execution.rs | 19 ++--- crates/stages/stages/src/stages/mod.rs | 9 ++- .../stages/stages/src/test_utils/test_db.rs | 4 +- crates/storage/db-common/src/init.rs | 35 +++++---- .../src/providers/blockchain_provider.rs | 9 ++- .../provider/src/providers/consistent.rs | 4 +- .../provider/src/providers/database/mod.rs | 10 ++- .../src/providers/database/provider.rs | 10 ++- crates/storage/provider/src/providers/mod.rs | 4 +- .../provider/src/providers/static_file/jar.rs | 30 +++++--- .../src/providers/static_file/manager.rs | 76 ++++++++++++------- .../provider/src/providers/static_file/mod.rs | 22 +++--- .../src/providers/static_file/writer.rs | 54 ++++++++----- .../storage/provider/src/test_utils/noop.rs | 4 +- .../src/traits/static_file_provider.rs | 7 +- crates/storage/provider/src/writer/mod.rs | 45 ++++++----- .../provider/src/writer/static_file.rs | 3 +- 38 files changed, 324 insertions(+), 222 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d92f66e8a58..927e653a609 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8140,6 +8140,7 @@ dependencies = [ "reqwest", "reth-db-api", "reth-metrics", + "reth-primitives-traits", "reth-provider", "reth-tasks", "socket2", diff --git a/crates/cli/commands/src/common.rs b/crates/cli/commands/src/common.rs index 49fee347ed4..3a9cbaa7fbb 100644 --- a/crates/cli/commands/src/common.rs +++ b/crates/cli/commands/src/common.rs @@ -109,7 +109,7 @@ impl> Environmen &self, config: &Config, db: Arc, - static_file_provider: StaticFileProvider, + static_file_provider: StaticFileProvider, ) -> eyre::Result>>> { let has_receipt_pruning = config.prune.as_ref().map_or(false, |a| a.has_receipts_pruning()); let prune_modes = diff --git a/crates/cli/commands/src/db/stats.rs b/crates/cli/commands/src/db/stats.rs index ac36b866b07..6865f01345e 100644 --- a/crates/cli/commands/src/db/stats.rs +++ b/crates/cli/commands/src/db/stats.rs @@ -9,7 +9,9 @@ use reth_db::{mdbx, static_file::iter_static_files, DatabaseEnv, TableViewer, Ta use reth_db_api::database::Database; use reth_db_common::DbTool; use reth_fs_util as fs; -use reth_node_builder::{NodeTypesWithDB, NodeTypesWithDBAdapter, NodeTypesWithEngine}; +use reth_node_builder::{ + NodePrimitives, NodeTypesWithDB, NodeTypesWithDBAdapter, NodeTypesWithEngine, +}; use reth_node_core::dirs::{ChainPath, DataDirPath}; use reth_provider::providers::{ProviderNodeTypes, StaticFileProvider}; use reth_static_file_types::SegmentRangeInclusive; @@ -49,7 +51,7 @@ impl Command { println!("\n"); } - let static_files_stats_table = self.static_files_stats_table(data_dir)?; + let static_files_stats_table = self.static_files_stats_table::(data_dir)?; println!("{static_files_stats_table}"); println!("\n"); @@ -143,7 +145,7 @@ impl Command { Ok(table) } - fn static_files_stats_table( + fn static_files_stats_table( &self, data_dir: ChainPath, ) -> eyre::Result { @@ -173,7 +175,8 @@ impl Command { } let static_files = iter_static_files(data_dir.static_files())?; - let static_file_provider = StaticFileProvider::read_only(data_dir.static_files(), false)?; + let static_file_provider = + StaticFileProvider::::read_only(data_dir.static_files(), false)?; let mut total_data_size = 0; let mut total_index_size = 0; diff --git a/crates/cli/commands/src/init_state/mod.rs b/crates/cli/commands/src/init_state/mod.rs index adaec3e8be3..adde88870fe 100644 --- a/crates/cli/commands/src/init_state/mod.rs +++ b/crates/cli/commands/src/init_state/mod.rs @@ -97,7 +97,6 @@ impl> InitStateC if last_block_number == 0 { without_evm::setup_without_evm( &provider_rw, - &static_file_provider, // &header, // header_hash, SealedHeader::new(header, header_hash), diff --git a/crates/cli/commands/src/init_state/without_evm.rs b/crates/cli/commands/src/init_state/without_evm.rs index 29fc2aec60e..c6e1f9a51dd 100644 --- a/crates/cli/commands/src/init_state/without_evm.rs +++ b/crates/cli/commands/src/init_state/without_evm.rs @@ -2,11 +2,13 @@ use alloy_primitives::{BlockNumber, B256, U256}; use alloy_rlp::Decodable; use alloy_consensus::Header; +use reth_node_builder::NodePrimitives; use reth_primitives::{ BlockBody, SealedBlock, SealedBlockWithSenders, SealedHeader, StaticFileSegment, }; use reth_provider::{ - providers::StaticFileProvider, BlockWriter, StageCheckpointWriter, StaticFileWriter, + providers::StaticFileProvider, BlockWriter, StageCheckpointWriter, StaticFileProviderFactory, + StaticFileWriter, }; use reth_stages::{StageCheckpoint, StageId}; @@ -27,21 +29,21 @@ pub(crate) fn read_header_from_file(path: PathBuf) -> Result( provider_rw: &Provider, - static_file_provider: &StaticFileProvider, header: SealedHeader, total_difficulty: U256, ) -> Result<(), eyre::Error> where - Provider: StageCheckpointWriter + BlockWriter, + Provider: StaticFileProviderFactory + StageCheckpointWriter + BlockWriter, { info!(target: "reth::cli", "Setting up dummy EVM chain before importing state."); + let static_file_provider = provider_rw.static_file_provider(); // Write EVM dummy data up to `header - 1` block - append_dummy_chain(static_file_provider, header.number - 1)?; + append_dummy_chain(&static_file_provider, header.number - 1)?; info!(target: "reth::cli", "Appending first valid block."); - append_first_block(provider_rw, static_file_provider, &header, total_difficulty)?; + append_first_block(provider_rw, &header, total_difficulty)?; for stage in StageId::ALL { provider_rw.save_stage_checkpoint(stage, StageCheckpoint::new(header.number))?; @@ -56,17 +58,21 @@ where /// /// By appending it, static file writer also verifies that all segments are at the same /// height. -fn append_first_block( - provider_rw: impl BlockWriter, - sf_provider: &StaticFileProvider, +fn append_first_block( + provider_rw: &Provider, header: &SealedHeader, total_difficulty: U256, -) -> Result<(), eyre::Error> { +) -> Result<(), eyre::Error> +where + Provider: BlockWriter + StaticFileProviderFactory, +{ provider_rw.insert_block( SealedBlockWithSenders::new(SealedBlock::new(header.clone(), BlockBody::default()), vec![]) .expect("no senders or txes"), )?; + let sf_provider = provider_rw.static_file_provider(); + sf_provider.latest_writer(StaticFileSegment::Headers)?.append_header( header, total_difficulty, @@ -85,8 +91,8 @@ fn append_first_block( /// * Headers: It will push an empty block. /// * Transactions: It will not push any tx, only increments the end block range. /// * Receipts: It will not push any receipt, only increments the end block range. -fn append_dummy_chain( - sf_provider: &StaticFileProvider, +fn append_dummy_chain( + sf_provider: &StaticFileProvider, target_height: BlockNumber, ) -> Result<(), eyre::Error> { let (tx, rx) = std::sync::mpsc::channel(); diff --git a/crates/cli/commands/src/stage/drop.rs b/crates/cli/commands/src/stage/drop.rs index 3a277cabd18..70b2caa8d16 100644 --- a/crates/cli/commands/src/stage/drop.rs +++ b/crates/cli/commands/src/stage/drop.rs @@ -12,7 +12,9 @@ use reth_db_common::{ }; use reth_node_builder::NodeTypesWithEngine; use reth_node_core::args::StageEnum; -use reth_provider::{writer::UnifiedStorageWriter, StaticFileProviderFactory}; +use reth_provider::{ + writer::UnifiedStorageWriter, DatabaseProviderFactory, StaticFileProviderFactory, +}; use reth_prune::PruneSegment; use reth_stages::StageId; use reth_static_file_types::StaticFileSegment; @@ -33,8 +35,6 @@ impl> Command ) -> eyre::Result<()> { let Environment { provider_factory, .. } = self.env.init::(AccessRights::RW)?; - let static_file_provider = provider_factory.static_file_provider(); - let tool = DbTool::new(provider_factory)?; let static_file_segment = match self.stage { @@ -60,7 +60,7 @@ impl> Command } } - let provider_rw = tool.provider_factory.provider_rw()?; + let provider_rw = tool.provider_factory.database_provider_rw()?; let tx = provider_rw.tx_ref(); match self.stage { @@ -71,7 +71,7 @@ impl> Command tx.clear::()?; reset_stage_checkpoint(tx, StageId::Headers)?; - insert_genesis_header(&provider_rw.0, &static_file_provider, &self.env.chain)?; + insert_genesis_header(&provider_rw, &self.env.chain)?; } StageEnum::Bodies => { tx.clear::()?; @@ -83,7 +83,7 @@ impl> Command tx.clear::()?; reset_stage_checkpoint(tx, StageId::Bodies)?; - insert_genesis_header(&provider_rw.0, &static_file_provider, &self.env.chain)?; + insert_genesis_header(&provider_rw, &self.env.chain)?; } StageEnum::Senders => { tx.clear::()?; @@ -104,7 +104,7 @@ impl> Command reset_stage_checkpoint(tx, StageId::Execution)?; let alloc = &self.env.chain.genesis().alloc; - insert_genesis_state(&provider_rw.0, alloc.iter())?; + insert_genesis_state(&provider_rw, alloc.iter())?; } StageEnum::AccountHashing => { tx.clear::()?; @@ -142,20 +142,20 @@ impl> Command reset_stage_checkpoint(tx, StageId::IndexAccountHistory)?; reset_stage_checkpoint(tx, StageId::IndexStorageHistory)?; - insert_genesis_history(&provider_rw.0, self.env.chain.genesis().alloc.iter())?; + insert_genesis_history(&provider_rw, self.env.chain.genesis().alloc.iter())?; } StageEnum::TxLookup => { tx.clear::()?; reset_prune_checkpoint(tx, PruneSegment::TransactionLookup)?; reset_stage_checkpoint(tx, StageId::TransactionLookup)?; - insert_genesis_header(&provider_rw.0, &static_file_provider, &self.env.chain)?; + insert_genesis_header(&provider_rw, &self.env.chain)?; } } tx.put::(StageId::Finish.to_string(), Default::default())?; - UnifiedStorageWriter::commit_unwind(provider_rw, static_file_provider)?; + UnifiedStorageWriter::commit_unwind(provider_rw)?; Ok(()) } diff --git a/crates/cli/commands/src/stage/run.rs b/crates/cli/commands/src/stage/run.rs index 23d6f6f28ac..1ac2a12d6fa 100644 --- a/crates/cli/commands/src/stage/run.rs +++ b/crates/cli/commands/src/stage/run.rs @@ -329,10 +329,7 @@ impl> Command } if self.commit { - UnifiedStorageWriter::commit_unwind( - provider_rw, - provider_factory.static_file_provider(), - )?; + UnifiedStorageWriter::commit_unwind(provider_rw)?; provider_rw = provider_factory.database_provider_rw()?; } } @@ -355,7 +352,7 @@ impl> Command provider_rw.save_stage_checkpoint(exec_stage.id(), checkpoint)?; } if self.commit { - UnifiedStorageWriter::commit(provider_rw, provider_factory.static_file_provider())?; + UnifiedStorageWriter::commit(provider_rw)?; provider_rw = provider_factory.database_provider_rw()?; } diff --git a/crates/engine/tree/src/persistence.rs b/crates/engine/tree/src/persistence.rs index f4650a047b4..e0c9e0362d0 100644 --- a/crates/engine/tree/src/persistence.rs +++ b/crates/engine/tree/src/persistence.rs @@ -120,7 +120,7 @@ impl PersistenceService { let new_tip_hash = provider_rw.block_hash(new_tip_num)?; UnifiedStorageWriter::from(&provider_rw, &sf_provider).remove_blocks_above(new_tip_num)?; - UnifiedStorageWriter::commit_unwind(provider_rw, sf_provider)?; + UnifiedStorageWriter::commit_unwind(provider_rw)?; debug!(target: "engine::persistence", ?new_tip_num, ?new_tip_hash, "Removed blocks from disk"); self.metrics.remove_blocks_above_duration_seconds.record(start_time.elapsed()); @@ -142,7 +142,7 @@ impl PersistenceService { let static_file_provider = self.provider.static_file_provider(); UnifiedStorageWriter::from(&provider_rw, &static_file_provider).save_blocks(&blocks)?; - UnifiedStorageWriter::commit(provider_rw, static_file_provider)?; + UnifiedStorageWriter::commit(provider_rw)?; } self.metrics.save_blocks_duration_seconds.record(start_time.elapsed()); Ok(last_block_hash_num) diff --git a/crates/node/builder/src/launch/common.rs b/crates/node/builder/src/launch/common.rs index 7fafa9e5eac..7e6571135f0 100644 --- a/crates/node/builder/src/launch/common.rs +++ b/crates/node/builder/src/launch/common.rs @@ -495,7 +495,7 @@ where } /// Returns the static file provider to interact with the static files. - pub fn static_file_provider(&self) -> StaticFileProvider { + pub fn static_file_provider(&self) -> StaticFileProvider { self.right().static_file_provider() } @@ -766,7 +766,7 @@ where } /// Returns the static file provider to interact with the static files. - pub fn static_file_provider(&self) -> StaticFileProvider { + pub fn static_file_provider(&self) -> StaticFileProvider<::Primitives> { self.provider_factory().static_file_provider() } diff --git a/crates/node/metrics/Cargo.toml b/crates/node/metrics/Cargo.toml index 9efdbd4959d..a823db9b467 100644 --- a/crates/node/metrics/Cargo.toml +++ b/crates/node/metrics/Cargo.toml @@ -9,6 +9,7 @@ repository.workspace = true [dependencies] reth-db-api.workspace = true +reth-primitives-traits.workspace = true reth-provider.workspace = true reth-metrics.workspace = true reth-tasks.workspace = true diff --git a/crates/node/metrics/src/hooks.rs b/crates/node/metrics/src/hooks.rs index 18755717667..21d12614f62 100644 --- a/crates/node/metrics/src/hooks.rs +++ b/crates/node/metrics/src/hooks.rs @@ -1,7 +1,12 @@ use metrics_process::Collector; use reth_db_api::database_metrics::DatabaseMetrics; +use reth_primitives_traits::NodePrimitives; use reth_provider::providers::StaticFileProvider; -use std::{fmt, sync::Arc}; +use std::{ + fmt::{self}, + sync::Arc, +}; + pub(crate) trait Hook: Fn() + Send + Sync {} impl Hook for T {} @@ -22,10 +27,11 @@ pub struct Hooks { impl Hooks { /// Create a new set of hooks - pub fn new( - db: Metrics, - static_file_provider: StaticFileProvider, - ) -> Self { + pub fn new(db: Metrics, static_file_provider: StaticFileProvider) -> Self + where + Metrics: DatabaseMetrics + 'static + Send + Sync, + N: NodePrimitives, + { let hooks: Vec>> = vec![ Box::new(move || db.report_metrics()), Box::new(move || { diff --git a/crates/optimism/cli/src/commands/import_receipts.rs b/crates/optimism/cli/src/commands/import_receipts.rs index 838a99818e9..ca82cf73ea4 100644 --- a/crates/optimism/cli/src/commands/import_receipts.rs +++ b/crates/optimism/cli/src/commands/import_receipts.rs @@ -150,7 +150,7 @@ where } } - let provider = provider_factory.provider_rw()?; + let provider = provider_factory.database_provider_rw()?; let mut total_decoded_receipts = 0; let mut total_receipts = 0; let mut total_filtered_out_dup_txns = 0; @@ -247,7 +247,7 @@ where provider .save_stage_checkpoint(StageId::Execution, StageCheckpoint::new(highest_block_receipts))?; - UnifiedStorageWriter::commit(provider, static_file_provider)?; + UnifiedStorageWriter::commit(provider)?; Ok(ImportReceiptsResult { total_decoded_receipts, total_filtered_out_dup_txns }) } diff --git a/crates/optimism/cli/src/commands/init_state.rs b/crates/optimism/cli/src/commands/init_state.rs index 68f5d9a585f..6be9b73c765 100644 --- a/crates/optimism/cli/src/commands/init_state.rs +++ b/crates/optimism/cli/src/commands/init_state.rs @@ -54,7 +54,6 @@ impl> InitStateCommandOp { if last_block_number == 0 { reth_cli_commands::init_state::without_evm::setup_without_evm( &provider_rw, - &static_file_provider, SealedHeader::new(BEDROCK_HEADER, BEDROCK_HEADER_HASH), BEDROCK_HEADER_TTD, )?; diff --git a/crates/primitives-traits/src/node.rs b/crates/primitives-traits/src/node.rs index 9ca69274831..ca490ac15aa 100644 --- a/crates/primitives-traits/src/node.rs +++ b/crates/primitives-traits/src/node.rs @@ -3,7 +3,7 @@ use core::fmt; use crate::{BlockBody, FullBlock, FullReceipt, FullSignedTx, FullTxType}; /// Configures all the primitive types of the node. -pub trait NodePrimitives: Send + Sync + Unpin + Clone + Default + fmt::Debug { +pub trait NodePrimitives: Send + Sync + Unpin + Clone + Default + fmt::Debug + 'static { /// Block primitive. type Block: Send + Sync + Unpin + Clone + Default + fmt::Debug + 'static; /// Signed version of the transaction type. @@ -22,7 +22,7 @@ impl NodePrimitives for () { } /// Helper trait that sets trait bounds on [`NodePrimitives`]. -pub trait FullNodePrimitives: Send + Sync + Unpin + Clone + Default + fmt::Debug { +pub trait FullNodePrimitives: Send + Sync + Unpin + Clone + Default + fmt::Debug + 'static { /// Block primitive. type Block: FullBlock>; /// Signed version of the transaction type. diff --git a/crates/prune/prune/src/builder.rs b/crates/prune/prune/src/builder.rs index 71d73c41610..85697160115 100644 --- a/crates/prune/prune/src/builder.rs +++ b/crates/prune/prune/src/builder.rs @@ -76,8 +76,11 @@ impl PrunerBuilder { /// Builds a [Pruner] from the current configuration with the given provider factory. pub fn build_with_provider_factory(self, provider_factory: PF) -> Pruner where - PF: DatabaseProviderFactory - + StaticFileProviderFactory, + PF: DatabaseProviderFactory< + ProviderRW: PruneCheckpointWriter + BlockReader + StaticFileProviderFactory, + > + StaticFileProviderFactory< + Primitives = ::Primitives, + >, { let segments = SegmentSet::from_components(provider_factory.static_file_provider(), self.segments); @@ -93,10 +96,16 @@ impl PrunerBuilder { } /// Builds a [Pruner] from the current configuration with the given static file provider. - pub fn build(self, static_file_provider: StaticFileProvider) -> Pruner + pub fn build( + self, + static_file_provider: StaticFileProvider, + ) -> Pruner where - Provider: - DBProvider + BlockReader + PruneCheckpointWriter + TransactionsProvider, + Provider: StaticFileProviderFactory + + DBProvider + + BlockReader + + PruneCheckpointWriter + + TransactionsProvider, { let segments = SegmentSet::::from_components(static_file_provider, self.segments); diff --git a/crates/prune/prune/src/segments/set.rs b/crates/prune/prune/src/segments/set.rs index 23d03345b09..62c252fc54b 100644 --- a/crates/prune/prune/src/segments/set.rs +++ b/crates/prune/prune/src/segments/set.rs @@ -5,7 +5,7 @@ use crate::segments::{ use reth_db::transaction::DbTxMut; use reth_provider::{ providers::StaticFileProvider, BlockReader, DBProvider, PruneCheckpointWriter, - TransactionsProvider, + StaticFileProviderFactory, TransactionsProvider, }; use reth_prune_types::PruneModes; @@ -45,12 +45,16 @@ impl SegmentSet { impl SegmentSet where - Provider: DBProvider + TransactionsProvider + PruneCheckpointWriter + BlockReader, + Provider: StaticFileProviderFactory + + DBProvider + + TransactionsProvider + + PruneCheckpointWriter + + BlockReader, { /// Creates a [`SegmentSet`] from an existing components, such as [`StaticFileProvider`] and /// [`PruneModes`]. pub fn from_components( - static_file_provider: StaticFileProvider, + static_file_provider: StaticFileProvider, prune_modes: PruneModes, ) -> Self { let PruneModes { diff --git a/crates/prune/prune/src/segments/static_file/headers.rs b/crates/prune/prune/src/segments/static_file/headers.rs index 8700a653b11..ea0264261af 100644 --- a/crates/prune/prune/src/segments/static_file/headers.rs +++ b/crates/prune/prune/src/segments/static_file/headers.rs @@ -12,7 +12,7 @@ use reth_db::{ tables, transaction::DbTxMut, }; -use reth_provider::{providers::StaticFileProvider, DBProvider}; +use reth_provider::{providers::StaticFileProvider, DBProvider, StaticFileProviderFactory}; use reth_prune_types::{ PruneLimiter, PruneMode, PruneProgress, PrunePurpose, PruneSegment, SegmentOutput, SegmentOutputCheckpoint, @@ -24,17 +24,19 @@ use tracing::trace; const HEADER_TABLES_TO_PRUNE: usize = 3; #[derive(Debug)] -pub struct Headers { - static_file_provider: StaticFileProvider, +pub struct Headers { + static_file_provider: StaticFileProvider, } -impl Headers { - pub const fn new(static_file_provider: StaticFileProvider) -> Self { +impl Headers { + pub const fn new(static_file_provider: StaticFileProvider) -> Self { Self { static_file_provider } } } -impl> Segment for Headers { +impl> Segment + for Headers +{ fn segment(&self) -> PruneSegment { PruneSegment::Headers } diff --git a/crates/prune/prune/src/segments/static_file/receipts.rs b/crates/prune/prune/src/segments/static_file/receipts.rs index f766f7ea1d3..5221418674a 100644 --- a/crates/prune/prune/src/segments/static_file/receipts.rs +++ b/crates/prune/prune/src/segments/static_file/receipts.rs @@ -5,25 +5,29 @@ use crate::{ use reth_db::transaction::DbTxMut; use reth_provider::{ errors::provider::ProviderResult, providers::StaticFileProvider, BlockReader, DBProvider, - PruneCheckpointWriter, TransactionsProvider, + PruneCheckpointWriter, StaticFileProviderFactory, TransactionsProvider, }; use reth_prune_types::{PruneCheckpoint, PruneMode, PrunePurpose, PruneSegment, SegmentOutput}; use reth_static_file_types::StaticFileSegment; #[derive(Debug)] -pub struct Receipts { - static_file_provider: StaticFileProvider, +pub struct Receipts { + static_file_provider: StaticFileProvider, } -impl Receipts { - pub const fn new(static_file_provider: StaticFileProvider) -> Self { +impl Receipts { + pub const fn new(static_file_provider: StaticFileProvider) -> Self { Self { static_file_provider } } } -impl Segment for Receipts +impl Segment for Receipts where - Provider: DBProvider + PruneCheckpointWriter + TransactionsProvider + BlockReader, + Provider: StaticFileProviderFactory + + DBProvider + + PruneCheckpointWriter + + TransactionsProvider + + BlockReader, { fn segment(&self) -> PruneSegment { PruneSegment::Receipts diff --git a/crates/prune/prune/src/segments/static_file/transactions.rs b/crates/prune/prune/src/segments/static_file/transactions.rs index 12772af5f88..7dc7a23191a 100644 --- a/crates/prune/prune/src/segments/static_file/transactions.rs +++ b/crates/prune/prune/src/segments/static_file/transactions.rs @@ -4,7 +4,10 @@ use crate::{ PrunerError, }; use reth_db::{tables, transaction::DbTxMut}; -use reth_provider::{providers::StaticFileProvider, BlockReader, DBProvider, TransactionsProvider}; +use reth_provider::{ + providers::StaticFileProvider, BlockReader, DBProvider, StaticFileProviderFactory, + TransactionsProvider, +}; use reth_prune_types::{ PruneMode, PruneProgress, PrunePurpose, PruneSegment, SegmentOutput, SegmentOutputCheckpoint, }; @@ -12,19 +15,20 @@ use reth_static_file_types::StaticFileSegment; use tracing::trace; #[derive(Debug)] -pub struct Transactions { - static_file_provider: StaticFileProvider, +pub struct Transactions { + static_file_provider: StaticFileProvider, } -impl Transactions { - pub const fn new(static_file_provider: StaticFileProvider) -> Self { +impl Transactions { + pub const fn new(static_file_provider: StaticFileProvider) -> Self { Self { static_file_provider } } } -impl Segment for Transactions +impl Segment for Transactions where - Provider: DBProvider + TransactionsProvider + BlockReader, + Provider: + DBProvider + TransactionsProvider + BlockReader + StaticFileProviderFactory, { fn segment(&self) -> PruneSegment { PruneSegment::Transactions diff --git a/crates/stages/api/src/pipeline/mod.rs b/crates/stages/api/src/pipeline/mod.rs index 399a3ffb4b7..bcf857fbac8 100644 --- a/crates/stages/api/src/pipeline/mod.rs +++ b/crates/stages/api/src/pipeline/mod.rs @@ -9,7 +9,7 @@ use reth_primitives_traits::constants::BEACON_CONSENSUS_REORG_UNWIND_DEPTH; use reth_provider::{ providers::ProviderNodeTypes, writer::UnifiedStorageWriter, ChainStateBlockReader, ChainStateBlockWriter, DatabaseProviderFactory, ProviderFactory, StageCheckpointReader, - StageCheckpointWriter, StaticFileProviderFactory, + StageCheckpointWriter, }; use reth_prune::PrunerBuilder; use reth_static_file::StaticFileProducer; @@ -358,10 +358,7 @@ impl Pipeline { ))?; } - UnifiedStorageWriter::commit_unwind( - provider_rw, - self.provider_factory.static_file_provider(), - )?; + UnifiedStorageWriter::commit_unwind(provider_rw)?; stage.post_unwind_commit()?; @@ -469,10 +466,7 @@ impl Pipeline { result: out.clone(), }); - UnifiedStorageWriter::commit( - provider_rw, - self.provider_factory.static_file_provider(), - )?; + UnifiedStorageWriter::commit(provider_rw)?; stage.post_execute_commit()?; @@ -533,7 +527,7 @@ fn on_stage_error( prev_checkpoint.unwrap_or_default(), )?; - UnifiedStorageWriter::commit(provider_rw, factory.static_file_provider())?; + UnifiedStorageWriter::commit(provider_rw)?; // We unwind because of a validation error. If the unwind itself // fails, we bail entirely, diff --git a/crates/stages/stages/src/stages/bodies.rs b/crates/stages/stages/src/stages/bodies.rs index 640bae86659..78aeda6feff 100644 --- a/crates/stages/stages/src/stages/bodies.rs +++ b/crates/stages/stages/src/stages/bodies.rs @@ -311,11 +311,11 @@ where fn missing_static_data_error( last_tx_num: TxNumber, - static_file_provider: &StaticFileProvider, + static_file_provider: &StaticFileProvider, provider: &Provider, ) -> Result where - Provider: BlockReader, + Provider: BlockReader + StaticFileProviderFactory, { let mut last_block = static_file_provider .get_highest_static_file_block(StaticFileSegment::Transactions) diff --git a/crates/stages/stages/src/stages/execution.rs b/crates/stages/stages/src/stages/execution.rs index 1750758a26a..16234ad483f 100644 --- a/crates/stages/stages/src/stages/execution.rs +++ b/crates/stages/stages/src/stages/execution.rs @@ -12,7 +12,7 @@ use reth_evm::{ use reth_execution_types::Chain; use reth_exex::{ExExManagerHandle, ExExNotification, ExExNotificationSource}; use reth_primitives::{SealedHeader, StaticFileSegment}; -use reth_primitives_traits::format_gas_throughput; +use reth_primitives_traits::{format_gas_throughput, NodePrimitives}; use reth_provider::{ providers::{StaticFileProvider, StaticFileProviderRWRefMut, StaticFileWriter}, writer::UnifiedStorageWriter, @@ -181,7 +181,8 @@ where + StatsReader + StateChangeWriter + BlockHashReader, - for<'a> UnifiedStorageWriter<'a, Provider, StaticFileProviderRWRefMut<'a>>: StateWriter, + for<'a> UnifiedStorageWriter<'a, Provider, StaticFileProviderRWRefMut<'a, Provider::Primitives>>: + StateWriter, { /// Return the id of the stage fn id(&self) -> StageId { @@ -485,8 +486,8 @@ where } } -fn execution_checkpoint( - provider: &StaticFileProvider, +fn execution_checkpoint( + provider: &StaticFileProvider, start_block: BlockNumber, max_block: BlockNumber, checkpoint: StageCheckpoint, @@ -552,8 +553,8 @@ fn execution_checkpoint( }) } -fn calculate_gas_used_from_headers( - provider: &StaticFileProvider, +fn calculate_gas_used_from_headers( + provider: &StaticFileProvider, range: RangeInclusive, ) -> Result { debug!(target: "sync::stages::execution", ?range, "Calculating gas used from headers"); @@ -587,11 +588,11 @@ fn calculate_gas_used_from_headers( /// (by returning [`StageError`]) until the heights in both the database and static file match. fn prepare_static_file_producer<'a, 'b, Provider>( provider: &'b Provider, - static_file_provider: &'a StaticFileProvider, + static_file_provider: &'a StaticFileProvider, start_block: u64, -) -> Result, StageError> +) -> Result, StageError> where - Provider: DBProvider + BlockReader + HeaderProvider, + Provider: StaticFileProviderFactory + DBProvider + BlockReader + HeaderProvider, 'b: 'a, { // Get next expected receipt number diff --git a/crates/stages/stages/src/stages/mod.rs b/crates/stages/stages/src/stages/mod.rs index 4b9f9295103..9d7cc685a7e 100644 --- a/crates/stages/stages/src/stages/mod.rs +++ b/crates/stages/stages/src/stages/mod.rs @@ -296,8 +296,8 @@ mod tests { ) { // We recreate the static file provider, since consistency heals are done on fetching the // writer for the first time. - let static_file_provider = - StaticFileProvider::read_write(db.factory.static_file_provider().path()).unwrap(); + let mut static_file_provider = db.factory.static_file_provider(); + static_file_provider = StaticFileProvider::read_write(static_file_provider.path()).unwrap(); // Simulate corruption by removing `prune_count` rows from the data file without updating // its offset list and configuration. @@ -314,9 +314,10 @@ mod tests { // We recreate the static file provider, since consistency heals are done on fetching the // writer for the first time. + let mut static_file_provider = db.factory.static_file_provider(); + static_file_provider = StaticFileProvider::read_write(static_file_provider.path()).unwrap(); assert_eq!( - StaticFileProvider::read_write(db.factory.static_file_provider().path()) - .unwrap() + static_file_provider .check_consistency(&db.factory.database_provider_ro().unwrap(), is_full_node,), Ok(expected) ); diff --git a/crates/stages/stages/src/test_utils/test_db.rs b/crates/stages/stages/src/test_utils/test_db.rs index 52983cb6f69..772e9cb78d0 100644 --- a/crates/stages/stages/src/test_utils/test_db.rs +++ b/crates/stages/stages/src/test_utils/test_db.rs @@ -24,7 +24,7 @@ use reth_provider::{ }; use reth_storage_errors::provider::ProviderResult; use reth_testing_utils::generators::ChangeSet; -use std::{collections::BTreeMap, path::Path}; +use std::{collections::BTreeMap, fmt::Debug, path::Path}; use tempfile::TempDir; /// Test database that is used for testing stage implementations. @@ -142,7 +142,7 @@ impl TestStageDB { /// Insert header to static file if `writer` exists, otherwise to DB. pub fn insert_header( - writer: Option<&mut StaticFileProviderRWRefMut<'_>>, + writer: Option<&mut StaticFileProviderRWRefMut<'_, ()>>, tx: &TX, header: &SealedHeader, td: U256, diff --git a/crates/storage/db-common/src/init.rs b/crates/storage/db-common/src/init.rs index 45fb4b76b31..e14796d2686 100644 --- a/crates/storage/db-common/src/init.rs +++ b/crates/storage/db-common/src/init.rs @@ -10,9 +10,7 @@ use reth_db_api::{transaction::DbTxMut, DatabaseError}; use reth_etl::Collector; use reth_primitives::{Account, Bytecode, GotExpected, Receipts, StaticFileSegment, StorageEntry}; use reth_provider::{ - errors::provider::ProviderResult, - providers::{StaticFileProvider, StaticFileWriter}, - writer::UnifiedStorageWriter, + errors::provider::ProviderResult, providers::StaticFileWriter, writer::UnifiedStorageWriter, BlockHashReader, BlockNumReader, BundleStateInit, ChainSpecProvider, DBProvider, DatabaseProviderFactory, ExecutionOutcome, HashingWriter, HeaderProvider, HistoryWriter, OriginalValuesKnown, ProviderError, RevertsInit, StageCheckpointWriter, StateChangeWriter, @@ -72,7 +70,8 @@ impl From for InitDatabaseError { pub fn init_genesis(factory: &PF) -> Result where PF: DatabaseProviderFactory + StaticFileProviderFactory + ChainSpecProvider + BlockHashReader, - PF::ProviderRW: StageCheckpointWriter + PF::ProviderRW: StaticFileProviderFactory + + StageCheckpointWriter + HistoryWriter + HeaderProvider + HashingWriter @@ -114,8 +113,7 @@ where insert_genesis_history(&provider_rw, alloc.iter())?; // Insert header - let static_file_provider = factory.static_file_provider(); - insert_genesis_header(&provider_rw, &static_file_provider, &chain)?; + insert_genesis_header(&provider_rw, &chain)?; insert_genesis_state(&provider_rw, alloc.iter())?; @@ -124,6 +122,7 @@ where provider_rw.save_stage_checkpoint(stage, Default::default())?; } + let static_file_provider = provider_rw.static_file_provider(); // Static file segments start empty, so we need to initialize the genesis block. let segment = StaticFileSegment::Receipts; static_file_provider.latest_writer(segment)?.increment_block(0)?; @@ -133,7 +132,7 @@ where // `commit_unwind`` will first commit the DB and then the static file provider, which is // necessary on `init_genesis`. - UnifiedStorageWriter::commit_unwind(provider_rw, static_file_provider)?; + UnifiedStorageWriter::commit_unwind(provider_rw)?; Ok(hash) } @@ -144,7 +143,11 @@ pub fn insert_genesis_state<'a, 'b, Provider>( alloc: impl Iterator, ) -> ProviderResult<()> where - Provider: DBProvider + StateChangeWriter + HeaderProvider + AsRef, + Provider: StaticFileProviderFactory + + DBProvider + + StateChangeWriter + + HeaderProvider + + AsRef, { insert_state(provider, alloc, 0) } @@ -156,7 +159,11 @@ pub fn insert_state<'a, 'b, Provider>( block: u64, ) -> ProviderResult<()> where - Provider: DBProvider + StateChangeWriter + HeaderProvider + AsRef, + Provider: StaticFileProviderFactory + + DBProvider + + StateChangeWriter + + HeaderProvider + + AsRef, { let capacity = alloc.size_hint().1.unwrap_or(0); let mut state_init: BundleStateInit = HashMap::with_capacity(capacity); @@ -296,14 +303,14 @@ where /// Inserts header for the genesis state. pub fn insert_genesis_header( provider: &Provider, - static_file_provider: &StaticFileProvider, chain: &Spec, ) -> ProviderResult<()> where - Provider: DBProvider, + Provider: StaticFileProviderFactory + DBProvider, Spec: EthChainSpec, { let (header, block_hash) = (chain.genesis_header(), chain.genesis_hash()); + let static_file_provider = provider.static_file_provider(); match static_file_provider.block_hash(0) { Ok(None) | Err(ProviderError::MissingStaticFileBlock(StaticFileSegment::Headers, 0)) => { @@ -333,7 +340,8 @@ pub fn init_from_state_dump( etl_config: EtlConfig, ) -> eyre::Result where - Provider: DBProvider + Provider: StaticFileProviderFactory + + DBProvider + BlockNumReader + BlockHashReader + ChainSpecProvider @@ -457,7 +465,8 @@ fn dump_state( block: u64, ) -> Result<(), eyre::Error> where - Provider: DBProvider + Provider: StaticFileProviderFactory + + DBProvider + HeaderProvider + HashingWriter + HistoryWriter diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index 0f0693471b0..083e7fb596b 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -163,7 +163,9 @@ impl DatabaseProviderFactory for BlockchainProvider2 { } impl StaticFileProviderFactory for BlockchainProvider2 { - fn static_file_provider(&self) -> StaticFileProvider { + type Primitives = N::Primitives; + + fn static_file_provider(&self) -> StaticFileProvider { self.database.static_file_provider() } } @@ -911,7 +913,7 @@ mod tests { )?; // Commit to both storages: database and static files - UnifiedStorageWriter::commit(provider_rw, factory.static_file_provider())?; + UnifiedStorageWriter::commit(provider_rw)?; let provider = BlockchainProvider2::new(factory)?; @@ -999,8 +1001,7 @@ mod tests { UnifiedStorageWriter::from(&provider_rw, &hook_provider.static_file_provider()) .save_blocks(&[lowest_memory_block]) .unwrap(); - UnifiedStorageWriter::commit(provider_rw, hook_provider.static_file_provider()) - .unwrap(); + UnifiedStorageWriter::commit(provider_rw).unwrap(); // Remove from memory hook_provider.canonical_in_memory_state.remove_persisted_blocks(num_hash); diff --git a/crates/storage/provider/src/providers/consistent.rs b/crates/storage/provider/src/providers/consistent.rs index 37c00be23be..3b2599f4999 100644 --- a/crates/storage/provider/src/providers/consistent.rs +++ b/crates/storage/provider/src/providers/consistent.rs @@ -612,7 +612,9 @@ impl ConsistentProvider { } impl StaticFileProviderFactory for ConsistentProvider { - fn static_file_provider(&self) -> StaticFileProvider { + type Primitives = N::Primitives; + + fn static_file_provider(&self) -> StaticFileProvider { self.storage_provider.static_file_provider() } } diff --git a/crates/storage/provider/src/providers/database/mod.rs b/crates/storage/provider/src/providers/database/mod.rs index 0e193f8cdef..94c83bbb442 100644 --- a/crates/storage/provider/src/providers/database/mod.rs +++ b/crates/storage/provider/src/providers/database/mod.rs @@ -53,7 +53,7 @@ pub struct ProviderFactory { /// Chain spec chain_spec: Arc, /// Static File Provider - static_file_provider: StaticFileProvider, + static_file_provider: StaticFileProvider, /// Optional pruning configuration prune_modes: PruneModes, } @@ -78,7 +78,7 @@ impl ProviderFactory { pub fn new( db: N::DB, chain_spec: Arc, - static_file_provider: StaticFileProvider, + static_file_provider: StaticFileProvider, ) -> Self { Self { db, chain_spec, static_file_provider, prune_modes: PruneModes::none() } } @@ -114,7 +114,7 @@ impl>> ProviderFactory { path: P, chain_spec: Arc, args: DatabaseArguments, - static_file_provider: StaticFileProvider, + static_file_provider: StaticFileProvider, ) -> RethResult { Ok(Self { db: Arc::new(init_db(path, args).map_err(RethError::msg)?), @@ -202,8 +202,10 @@ impl DatabaseProviderFactory for ProviderFactory { } impl StaticFileProviderFactory for ProviderFactory { + type Primitives = N::Primitives; + /// Returns static file provider - fn static_file_provider(&self) -> StaticFileProvider { + fn static_file_provider(&self) -> StaticFileProvider { self.static_file_provider.clone() } } diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index 30a69fbfc77..b93112e7084 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -135,7 +135,7 @@ pub struct DatabaseProvider { /// Chain spec chain_spec: Arc, /// Static File provider - static_file_provider: StaticFileProvider, + static_file_provider: StaticFileProvider, /// Pruning configuration prune_modes: PruneModes, } @@ -199,8 +199,10 @@ impl DatabaseProvider { } impl StaticFileProviderFactory for DatabaseProvider { + type Primitives = N::Primitives; + /// Returns a static file provider - fn static_file_provider(&self) -> StaticFileProvider { + fn static_file_provider(&self) -> StaticFileProvider { self.static_file_provider.clone() } } @@ -220,7 +222,7 @@ impl DatabaseProvider { pub const fn new_rw( tx: TX, chain_spec: Arc, - static_file_provider: StaticFileProvider, + static_file_provider: StaticFileProvider, prune_modes: PruneModes, ) -> Self { Self { tx, chain_spec, static_file_provider, prune_modes } @@ -363,7 +365,7 @@ impl DatabaseProvider { pub const fn new( tx: TX, chain_spec: Arc, - static_file_provider: StaticFileProvider, + static_file_provider: StaticFileProvider, prune_modes: PruneModes, ) -> Self { Self { tx, chain_spec, static_file_provider, prune_modes } diff --git a/crates/storage/provider/src/providers/mod.rs b/crates/storage/provider/src/providers/mod.rs index d1e1822d8c9..3bf3e7b247f 100644 --- a/crates/storage/provider/src/providers/mod.rs +++ b/crates/storage/provider/src/providers/mod.rs @@ -204,7 +204,9 @@ impl DatabaseProviderFactory for BlockchainProvider { } impl StaticFileProviderFactory for BlockchainProvider { - fn static_file_provider(&self) -> StaticFileProvider { + type Primitives = N::Primitives; + + fn static_file_provider(&self) -> StaticFileProvider { self.database.static_file_provider() } } diff --git a/crates/storage/provider/src/providers/static_file/jar.rs b/crates/storage/provider/src/providers/static_file/jar.rs index 9c303394ed2..e87829b1133 100644 --- a/crates/storage/provider/src/providers/static_file/jar.rs +++ b/crates/storage/provider/src/providers/static_file/jar.rs @@ -12,39 +12,49 @@ use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, use reth_chainspec::ChainInfo; use reth_db::static_file::{HeaderMask, ReceiptMask, StaticFileCursor, TransactionMask}; use reth_db_api::models::CompactU256; +use reth_node_types::NodePrimitives; use reth_primitives::{ Receipt, SealedHeader, TransactionMeta, TransactionSigned, TransactionSignedNoHash, }; use reth_storage_errors::provider::{ProviderError, ProviderResult}; use std::{ + fmt::Debug, ops::{Deref, RangeBounds}, sync::Arc, }; /// Provider over a specific `NippyJar` and range. #[derive(Debug)] -pub struct StaticFileJarProvider<'a> { +pub struct StaticFileJarProvider<'a, N> { /// Main static file segment jar: LoadedJarRef<'a>, /// Another kind of static file segment to help query data from the main one. auxiliary_jar: Option>, + /// Metrics for the static files. metrics: Option>, + /// Node primitives + _pd: std::marker::PhantomData, } -impl<'a> Deref for StaticFileJarProvider<'a> { +impl<'a, N: NodePrimitives> Deref for StaticFileJarProvider<'a, N> { type Target = LoadedJarRef<'a>; fn deref(&self) -> &Self::Target { &self.jar } } -impl<'a> From> for StaticFileJarProvider<'a> { +impl<'a, N: NodePrimitives> From> for StaticFileJarProvider<'a, N> { fn from(value: LoadedJarRef<'a>) -> Self { - StaticFileJarProvider { jar: value, auxiliary_jar: None, metrics: None } + StaticFileJarProvider { + jar: value, + auxiliary_jar: None, + metrics: None, + _pd: Default::default(), + } } } -impl<'a> StaticFileJarProvider<'a> { +impl<'a, N: NodePrimitives> StaticFileJarProvider<'a, N> { /// Provides a cursor for more granular data access. pub fn cursor<'b>(&'b self) -> ProviderResult> where @@ -76,7 +86,7 @@ impl<'a> StaticFileJarProvider<'a> { } } -impl HeaderProvider for StaticFileJarProvider<'_> { +impl HeaderProvider for StaticFileJarProvider<'_, N> { fn header(&self, block_hash: &BlockHash) -> ProviderResult> { Ok(self .cursor()? @@ -148,7 +158,7 @@ impl HeaderProvider for StaticFileJarProvider<'_> { } } -impl BlockHashReader for StaticFileJarProvider<'_> { +impl BlockHashReader for StaticFileJarProvider<'_, N> { fn block_hash(&self, number: u64) -> ProviderResult> { self.cursor()?.get_one::>(number.into()) } @@ -170,7 +180,7 @@ impl BlockHashReader for StaticFileJarProvider<'_> { } } -impl BlockNumReader for StaticFileJarProvider<'_> { +impl BlockNumReader for StaticFileJarProvider<'_, N> { fn chain_info(&self) -> ProviderResult { // Information on live database Err(ProviderError::UnsupportedProvider) @@ -195,7 +205,7 @@ impl BlockNumReader for StaticFileJarProvider<'_> { } } -impl TransactionsProvider for StaticFileJarProvider<'_> { +impl TransactionsProvider for StaticFileJarProvider<'_, N> { fn transaction_id(&self, hash: TxHash) -> ProviderResult> { let mut cursor = self.cursor()?; @@ -291,7 +301,7 @@ impl TransactionsProvider for StaticFileJarProvider<'_> { } } -impl ReceiptProvider for StaticFileJarProvider<'_> { +impl ReceiptProvider for StaticFileJarProvider<'_, N> { fn receipt(&self, num: TxNumber) -> ProviderResult> { self.cursor()?.get_one::>(num.into()) } diff --git a/crates/storage/provider/src/providers/static_file/manager.rs b/crates/storage/provider/src/providers/static_file/manager.rs index a5d4537245d..8f6a6957502 100644 --- a/crates/storage/provider/src/providers/static_file/manager.rs +++ b/crates/storage/provider/src/providers/static_file/manager.rs @@ -29,6 +29,7 @@ use reth_db_api::{ transaction::DbTx, }; use reth_nippy_jar::{NippyJar, NippyJarChecker, CONFIG_FILE_EXTENSION}; +use reth_node_types::NodePrimitives; use reth_primitives::{ static_file::{ find_fixed_range, HighestStaticFiles, SegmentHeader, SegmentRangeInclusive, @@ -42,6 +43,8 @@ use reth_storage_api::DBProvider; use reth_storage_errors::provider::{ProviderError, ProviderResult}; use std::{ collections::{hash_map::Entry, BTreeMap, HashMap}, + fmt::Debug, + marker::PhantomData, ops::{Deref, Range, RangeBounds, RangeInclusive}, path::{Path, PathBuf}, sync::{mpsc, Arc}, @@ -77,10 +80,16 @@ impl StaticFileAccess { } /// [`StaticFileProvider`] manages all existing [`StaticFileJarProvider`]. -#[derive(Debug, Clone)] -pub struct StaticFileProvider(pub(crate) Arc); +#[derive(Debug)] +pub struct StaticFileProvider(pub(crate) Arc>); + +impl Clone for StaticFileProvider { + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} -impl StaticFileProvider { +impl StaticFileProvider { /// Creates a new [`StaticFileProvider`]. fn new(path: impl AsRef, access: StaticFileAccess) -> ProviderResult { let provider = Self(Arc::new(StaticFileProviderInner::new(path, access)?)); @@ -191,8 +200,8 @@ impl StaticFileProvider { } } -impl Deref for StaticFileProvider { - type Target = StaticFileProviderInner; +impl Deref for StaticFileProvider { + type Target = StaticFileProviderInner; fn deref(&self) -> &Self::Target { &self.0 @@ -201,7 +210,7 @@ impl Deref for StaticFileProvider { /// [`StaticFileProviderInner`] manages all existing [`StaticFileJarProvider`]. #[derive(Debug)] -pub struct StaticFileProviderInner { +pub struct StaticFileProviderInner { /// Maintains a map which allows for concurrent access to different `NippyJars`, over different /// segments and ranges. map: DashMap<(BlockNumber, StaticFileSegment), LoadedJar>, @@ -212,7 +221,8 @@ pub struct StaticFileProviderInner { /// Directory where `static_files` are located path: PathBuf, /// Maintains a writer set of [`StaticFileSegment`]. - writers: StaticFileWriters, + writers: StaticFileWriters, + /// Metrics for the static files. metrics: Option>, /// Access rights of the provider. access: StaticFileAccess, @@ -220,9 +230,11 @@ pub struct StaticFileProviderInner { blocks_per_file: u64, /// Write lock for when access is [`StaticFileAccess::RW`]. _lock_file: Option, + /// Node primitives + _pd: PhantomData, } -impl StaticFileProviderInner { +impl StaticFileProviderInner { /// Creates a new [`StaticFileProviderInner`]. fn new(path: impl AsRef, access: StaticFileAccess) -> ProviderResult { let _lock_file = if access.is_read_write() { @@ -241,6 +253,7 @@ impl StaticFileProviderInner { access, blocks_per_file: DEFAULT_BLOCKS_PER_STATIC_FILE, _lock_file, + _pd: Default::default(), }; Ok(provider) @@ -257,7 +270,7 @@ impl StaticFileProviderInner { } } -impl StaticFileProvider { +impl StaticFileProvider { /// Set a custom number of blocks per file. #[cfg(any(test, feature = "test-utils"))] pub fn with_custom_blocks_per_file(self, blocks_per_file: u64) -> Self { @@ -323,7 +336,7 @@ impl StaticFileProvider { segment: StaticFileSegment, block: BlockNumber, path: Option<&Path>, - ) -> ProviderResult> { + ) -> ProviderResult> { self.get_segment_provider( segment, || self.get_segment_ranges_from_block(segment, block), @@ -338,7 +351,7 @@ impl StaticFileProvider { segment: StaticFileSegment, tx: TxNumber, path: Option<&Path>, - ) -> ProviderResult> { + ) -> ProviderResult> { self.get_segment_provider( segment, || self.get_segment_ranges_from_transaction(segment, tx), @@ -355,7 +368,7 @@ impl StaticFileProvider { segment: StaticFileSegment, fn_range: impl Fn() -> Option, path: Option<&Path>, - ) -> ProviderResult>> { + ) -> ProviderResult>> { // If we have a path, then get the block range from its name. // Otherwise, check `self.available_static_files` let block_range = match path { @@ -426,12 +439,12 @@ impl StaticFileProvider { &self, segment: StaticFileSegment, fixed_block_range: &SegmentRangeInclusive, - ) -> ProviderResult> { + ) -> ProviderResult> { let key = (fixed_block_range.end(), segment); // Avoid using `entry` directly to avoid a write lock in the common case. trace!(target: "provider::static_file", ?segment, ?fixed_block_range, "Getting provider"); - let mut provider: StaticFileJarProvider<'_> = if let Some(jar) = self.map.get(&key) { + let mut provider: StaticFileJarProvider<'_, N> = if let Some(jar) = self.map.get(&key) { trace!(target: "provider::static_file", ?segment, ?fixed_block_range, "Jar found in cache"); jar.into() } else { @@ -924,7 +937,7 @@ impl StaticFileProvider { pub fn find_static_file( &self, segment: StaticFileSegment, - func: impl Fn(StaticFileJarProvider<'_>) -> ProviderResult>, + func: impl Fn(StaticFileJarProvider<'_, N>) -> ProviderResult>, ) -> ProviderResult> { if let Some(highest_block) = self.get_highest_static_file_block(segment) { let mut range = self.find_fixed_range(highest_block); @@ -1167,30 +1180,35 @@ impl StaticFileProvider { /// Helper trait to manage different [`StaticFileProviderRW`] of an `Arc ProviderResult>; + ) -> ProviderResult>; /// Returns a mutable reference to a [`StaticFileProviderRW`] of the latest /// [`StaticFileSegment`]. fn latest_writer( &self, segment: StaticFileSegment, - ) -> ProviderResult>; + ) -> ProviderResult>; /// Commits all changes of all [`StaticFileProviderRW`] of all [`StaticFileSegment`]. fn commit(&self) -> ProviderResult<()>; } -impl StaticFileWriter for StaticFileProvider { +impl StaticFileWriter for StaticFileProvider { + type Primitives = N; + fn get_writer( &self, block: BlockNumber, segment: StaticFileSegment, - ) -> ProviderResult> { + ) -> ProviderResult> { if self.access.is_read_only() { return Err(ProviderError::ReadOnlyStaticFileAccess) } @@ -1204,7 +1222,7 @@ impl StaticFileWriter for StaticFileProvider { fn latest_writer( &self, segment: StaticFileSegment, - ) -> ProviderResult> { + ) -> ProviderResult> { self.get_writer(self.get_highest_static_file_block(segment).unwrap_or_default(), segment) } @@ -1213,7 +1231,7 @@ impl StaticFileWriter for StaticFileProvider { } } -impl HeaderProvider for StaticFileProvider { +impl HeaderProvider for StaticFileProvider { fn header(&self, block_hash: &BlockHash) -> ProviderResult> { self.find_static_file(StaticFileSegment::Headers, |jar_provider| { Ok(jar_provider @@ -1300,7 +1318,7 @@ impl HeaderProvider for StaticFileProvider { } } -impl BlockHashReader for StaticFileProvider { +impl BlockHashReader for StaticFileProvider { fn block_hash(&self, num: u64) -> ProviderResult> { self.get_segment_provider_from_block(StaticFileSegment::Headers, num, None)?.block_hash(num) } @@ -1319,7 +1337,7 @@ impl BlockHashReader for StaticFileProvider { } } -impl ReceiptProvider for StaticFileProvider { +impl ReceiptProvider for StaticFileProvider { fn receipt(&self, num: TxNumber) -> ProviderResult> { self.get_segment_provider_from_transaction(StaticFileSegment::Receipts, num, None) .and_then(|provider| provider.receipt(num)) @@ -1356,7 +1374,7 @@ impl ReceiptProvider for StaticFileProvider { } } -impl TransactionsProviderExt for StaticFileProvider { +impl TransactionsProviderExt for StaticFileProvider { fn transaction_hashes_by_range( &self, tx_range: Range, @@ -1417,7 +1435,7 @@ impl TransactionsProviderExt for StaticFileProvider { } } -impl TransactionsProvider for StaticFileProvider { +impl TransactionsProvider for StaticFileProvider { fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult> { self.find_static_file(StaticFileSegment::Transactions, |jar_provider| { let mut cursor = jar_provider.cursor()?; @@ -1529,7 +1547,7 @@ impl TransactionsProvider for StaticFileProvider { /* Cannot be successfully implemented but must exist for trait requirements */ -impl BlockNumReader for StaticFileProvider { +impl BlockNumReader for StaticFileProvider { fn chain_info(&self) -> ProviderResult { // Required data not present in static_files Err(ProviderError::UnsupportedProvider) @@ -1551,7 +1569,7 @@ impl BlockNumReader for StaticFileProvider { } } -impl BlockReader for StaticFileProvider { +impl BlockReader for StaticFileProvider { fn find_block_by_hash( &self, _hash: B256, @@ -1629,7 +1647,7 @@ impl BlockReader for StaticFileProvider { } } -impl WithdrawalsProvider for StaticFileProvider { +impl WithdrawalsProvider for StaticFileProvider { fn withdrawals_by_block( &self, _id: BlockHashOrNumber, @@ -1645,7 +1663,7 @@ impl WithdrawalsProvider for StaticFileProvider { } } -impl StatsReader for StaticFileProvider { +impl StatsReader for StaticFileProvider { fn count_entries(&self) -> ProviderResult { match T::NAME { tables::CanonicalHeaders::NAME | diff --git a/crates/storage/provider/src/providers/static_file/mod.rs b/crates/storage/provider/src/providers/static_file/mod.rs index dd52adf52f8..30b8d0344da 100644 --- a/crates/storage/provider/src/providers/static_file/mod.rs +++ b/crates/storage/provider/src/providers/static_file/mod.rs @@ -55,7 +55,9 @@ impl Deref for LoadedJar { #[cfg(test)] mod tests { use super::*; - use crate::{test_utils::create_test_provider_factory, HeaderProvider}; + use crate::{ + test_utils::create_test_provider_factory, HeaderProvider, StaticFileProviderFactory, + }; use alloy_consensus::{Header, Transaction}; use alloy_primitives::{BlockHash, TxNumber, B256, U256}; use rand::seq::SliceRandom; @@ -116,7 +118,7 @@ mod tests { // Create StaticFile { - let manager = StaticFileProvider::read_write(static_files_path.path()).unwrap(); + let manager = factory.static_file_provider(); let mut writer = manager.latest_writer(StaticFileSegment::Headers).unwrap(); let mut td = U256::ZERO; @@ -131,7 +133,7 @@ mod tests { // Use providers to query Header data and compare if it matches { let db_provider = factory.provider().unwrap(); - let manager = StaticFileProvider::read_write(static_files_path.path()).unwrap(); + let manager = db_provider.static_file_provider(); let jar_provider = manager .get_segment_provider_from_block(StaticFileSegment::Headers, 0, Some(&static_file)) .unwrap(); @@ -170,7 +172,7 @@ mod tests { // [ Headers Creation and Commit ] { - let sf_rw = StaticFileProvider::read_write(&static_dir) + let sf_rw = StaticFileProvider::<()>::read_write(&static_dir) .expect("Failed to create static file provider") .with_custom_blocks_per_file(blocks_per_file); @@ -189,8 +191,8 @@ mod tests { // Helper function to prune headers and validate truncation results fn prune_and_validate( - writer: &mut StaticFileProviderRWRefMut<'_>, - sf_rw: &StaticFileProvider, + writer: &mut StaticFileProviderRWRefMut<'_, ()>, + sf_rw: &StaticFileProvider<()>, static_dir: impl AsRef, prune_count: u64, expected_tip: Option, @@ -302,13 +304,13 @@ mod tests { /// * `10..=19`: no txs/receipts /// * `20..=29`: only one tx/receipt fn setup_tx_based_scenario( - sf_rw: &StaticFileProvider, + sf_rw: &StaticFileProvider<()>, segment: StaticFileSegment, blocks_per_file: u64, ) { fn setup_block_ranges( - writer: &mut StaticFileProviderRWRefMut<'_>, - sf_rw: &StaticFileProvider, + writer: &mut StaticFileProviderRWRefMut<'_, ()>, + sf_rw: &StaticFileProvider<()>, segment: StaticFileSegment, block_range: &Range, mut tx_count: u64, @@ -413,7 +415,7 @@ mod tests { #[allow(clippy::too_many_arguments)] fn prune_and_validate( - sf_rw: &StaticFileProvider, + sf_rw: &StaticFileProvider<()>, static_dir: impl AsRef, segment: StaticFileSegment, prune_count: u64, diff --git a/crates/storage/provider/src/providers/static_file/writer.rs b/crates/storage/provider/src/providers/static_file/writer.rs index 2e54fb943a7..796e16c9a13 100644 --- a/crates/storage/provider/src/providers/static_file/writer.rs +++ b/crates/storage/provider/src/providers/static_file/writer.rs @@ -8,6 +8,7 @@ use parking_lot::{lock_api::RwLockWriteGuard, RawRwLock, RwLock}; use reth_codecs::Compact; use reth_db_api::models::CompactU256; use reth_nippy_jar::{NippyJar, NippyJarError, NippyJarWriter}; +use reth_node_types::NodePrimitives; use reth_primitives::{ static_file::{SegmentHeader, SegmentRangeInclusive}, Receipt, StaticFileSegment, @@ -15,6 +16,7 @@ use reth_primitives::{ use reth_storage_errors::provider::{ProviderError, ProviderResult}; use std::{ borrow::Borrow, + fmt::Debug, path::{Path, PathBuf}, sync::{Arc, Weak}, time::Instant, @@ -25,19 +27,29 @@ use tracing::debug; /// /// WARNING: Trying to use more than one writer for the same segment type **will result in a /// deadlock**. -#[derive(Debug, Default)] -pub(crate) struct StaticFileWriters { - headers: RwLock>, - transactions: RwLock>, - receipts: RwLock>, +#[derive(Debug)] +pub(crate) struct StaticFileWriters { + headers: RwLock>>, + transactions: RwLock>>, + receipts: RwLock>>, +} + +impl Default for StaticFileWriters { + fn default() -> Self { + Self { + headers: Default::default(), + transactions: Default::default(), + receipts: Default::default(), + } + } } -impl StaticFileWriters { +impl StaticFileWriters { pub(crate) fn get_or_create( &self, segment: StaticFileSegment, - create_fn: impl FnOnce() -> ProviderResult, - ) -> ProviderResult> { + create_fn: impl FnOnce() -> ProviderResult>, + ) -> ProviderResult> { let mut write_guard = match segment { StaticFileSegment::Headers => self.headers.write(), StaticFileSegment::Transactions => self.transactions.write(), @@ -64,19 +76,19 @@ impl StaticFileWriters { /// Mutable reference to a [`StaticFileProviderRW`] behind a [`RwLockWriteGuard`]. #[derive(Debug)] -pub struct StaticFileProviderRWRefMut<'a>( - pub(crate) RwLockWriteGuard<'a, RawRwLock, Option>, +pub struct StaticFileProviderRWRefMut<'a, N>( + pub(crate) RwLockWriteGuard<'a, RawRwLock, Option>>, ); -impl std::ops::DerefMut for StaticFileProviderRWRefMut<'_> { +impl std::ops::DerefMut for StaticFileProviderRWRefMut<'_, N> { fn deref_mut(&mut self) -> &mut Self::Target { // This is always created by [`StaticFileWriters::get_or_create`] self.0.as_mut().expect("static file writer provider should be init") } } -impl std::ops::Deref for StaticFileProviderRWRefMut<'_> { - type Target = StaticFileProviderRW; +impl std::ops::Deref for StaticFileProviderRWRefMut<'_, N> { + type Target = StaticFileProviderRW; fn deref(&self) -> &Self::Target { // This is always created by [`StaticFileWriters::get_or_create`] @@ -86,11 +98,11 @@ impl std::ops::Deref for StaticFileProviderRWRefMut<'_> { #[derive(Debug)] /// Extends `StaticFileProvider` with writing capabilities -pub struct StaticFileProviderRW { +pub struct StaticFileProviderRW { /// Reference back to the provider. We need [Weak] here because [`StaticFileProviderRW`] is /// stored in a [`dashmap::DashMap`] inside the parent [`StaticFileProvider`].which is an /// [Arc]. If we were to use an [Arc] here, we would create a reference cycle. - reader: Weak, + reader: Weak>, /// A [`NippyJarWriter`] instance. writer: NippyJarWriter, /// Path to opened file. @@ -104,7 +116,7 @@ pub struct StaticFileProviderRW { prune_on_commit: Option<(u64, Option)>, } -impl StaticFileProviderRW { +impl StaticFileProviderRW { /// Creates a new [`StaticFileProviderRW`] for a [`StaticFileSegment`]. /// /// Before use, transaction based segments should ensure the block end range is the expected @@ -112,7 +124,7 @@ impl StaticFileProviderRW { pub fn new( segment: StaticFileSegment, block: BlockNumber, - reader: Weak, + reader: Weak>, metrics: Option>, ) -> ProviderResult { let (writer, data_path) = Self::open(segment, block, reader.clone(), metrics.clone())?; @@ -133,7 +145,7 @@ impl StaticFileProviderRW { fn open( segment: StaticFileSegment, block: u64, - reader: Weak, + reader: Weak>, metrics: Option>, ) -> ProviderResult<(NippyJarWriter, PathBuf)> { let start = Instant::now(); @@ -751,7 +763,7 @@ impl StaticFileProviderRW { Ok(()) } - fn reader(&self) -> StaticFileProvider { + fn reader(&self) -> StaticFileProvider { Self::upgrade_provider_to_strong_reference(&self.reader) } @@ -764,8 +776,8 @@ impl StaticFileProviderRW { /// active. In reality, it's impossible to detach the [`StaticFileProviderRW`] from the /// [`StaticFileProvider`]. fn upgrade_provider_to_strong_reference( - provider: &Weak, - ) -> StaticFileProvider { + provider: &Weak>, + ) -> StaticFileProvider { provider.upgrade().map(StaticFileProvider).expect("StaticFileProvider is dropped") } diff --git a/crates/storage/provider/src/test_utils/noop.rs b/crates/storage/provider/src/test_utils/noop.rs index 38fab0dc311..d12539a2c27 100644 --- a/crates/storage/provider/src/test_utils/noop.rs +++ b/crates/storage/provider/src/test_utils/noop.rs @@ -556,7 +556,9 @@ impl PruneCheckpointReader for NoopProvider { } impl StaticFileProviderFactory for NoopProvider { - fn static_file_provider(&self) -> StaticFileProvider { + type Primitives = (); + + fn static_file_provider(&self) -> StaticFileProvider { StaticFileProvider::read_only(PathBuf::default(), false).unwrap() } } diff --git a/crates/storage/provider/src/traits/static_file_provider.rs b/crates/storage/provider/src/traits/static_file_provider.rs index 24d69569205..d465121fb46 100644 --- a/crates/storage/provider/src/traits/static_file_provider.rs +++ b/crates/storage/provider/src/traits/static_file_provider.rs @@ -1,7 +1,12 @@ +use reth_node_types::NodePrimitives; + use crate::providers::StaticFileProvider; /// Static file provider factory. pub trait StaticFileProviderFactory { + /// The network primitives type [`StaticFileProvider`] is using. + type Primitives: NodePrimitives; + /// Create new instance of static file provider. - fn static_file_provider(&self) -> StaticFileProvider; + fn static_file_provider(&self) -> StaticFileProvider; } diff --git a/crates/storage/provider/src/writer/mod.rs b/crates/storage/provider/src/writer/mod.rs index 0fbec6c1b88..1c3894e9cfd 100644 --- a/crates/storage/provider/src/writer/mod.rs +++ b/crates/storage/provider/src/writer/mod.rs @@ -1,7 +1,8 @@ use crate::{ providers::{StaticFileProvider, StaticFileProviderRWRefMut, StaticFileWriter as SfWriter}, writer::static_file::StaticFileWriter, - BlockExecutionWriter, BlockWriter, HistoryWriter, StateChangeWriter, StateWriter, TrieWriter, + BlockExecutionWriter, BlockWriter, HistoryWriter, StateChangeWriter, StateWriter, + StaticFileProviderFactory, TrieWriter, }; use alloy_consensus::Header; use alloy_primitives::{BlockNumber, B256, U256}; @@ -115,15 +116,13 @@ impl UnifiedStorageWriter<'_, (), ()> { /// start-up. /// /// NOTE: If unwinding data from storage, use `commit_unwind` instead! - pub fn commit

( - database: impl Into

+ AsRef

, - static_file: StaticFileProvider, - ) -> ProviderResult<()> + pub fn commit

(provider: P) -> ProviderResult<()> where - P: DBProvider, + P: DBProvider + StaticFileProviderFactory, { + let static_file = provider.static_file_provider(); static_file.commit()?; - database.into().into_tx().commit()?; + provider.commit()?; Ok(()) } @@ -135,20 +134,18 @@ impl UnifiedStorageWriter<'_, (), ()> { /// checkpoints on the next start-up. /// /// NOTE: Should only be used after unwinding data from storage! - pub fn commit_unwind

( - database: impl Into

+ AsRef

, - static_file: StaticFileProvider, - ) -> ProviderResult<()> + pub fn commit_unwind

(provider: P) -> ProviderResult<()> where - P: DBProvider, + P: DBProvider + StaticFileProviderFactory, { - database.into().into_tx().commit()?; + let static_file = provider.static_file_provider(); + provider.commit()?; static_file.commit()?; Ok(()) } } -impl UnifiedStorageWriter<'_, ProviderDB, &StaticFileProvider> +impl UnifiedStorageWriter<'_, ProviderDB, &StaticFileProvider> where ProviderDB: DBProvider + BlockWriter @@ -158,7 +155,8 @@ where + HistoryWriter + StageCheckpointWriter + BlockExecutionWriter - + AsRef, + + AsRef + + StaticFileProviderFactory, { /// Writes executed blocks and receipts to storage. pub fn save_blocks(&self, blocks: &[ExecutedBlock]) -> ProviderResult<()> { @@ -319,9 +317,10 @@ where } } -impl UnifiedStorageWriter<'_, ProviderDB, StaticFileProviderRWRefMut<'_>> +impl + UnifiedStorageWriter<'_, ProviderDB, StaticFileProviderRWRefMut<'_, ProviderDB::Primitives>> where - ProviderDB: DBProvider + HeaderProvider, + ProviderDB: DBProvider + HeaderProvider + StaticFileProviderFactory, { /// Ensures that the static file writer is set and of the right [`StaticFileSegment`] variant. /// @@ -430,9 +429,10 @@ where } } -impl UnifiedStorageWriter<'_, ProviderDB, StaticFileProviderRWRefMut<'_>> +impl + UnifiedStorageWriter<'_, ProviderDB, StaticFileProviderRWRefMut<'_, ProviderDB::Primitives>> where - ProviderDB: DBProvider + HeaderProvider, + ProviderDB: DBProvider + HeaderProvider + StaticFileProviderFactory, { /// Appends receipts block by block. /// @@ -512,9 +512,12 @@ where } impl StateWriter - for UnifiedStorageWriter<'_, ProviderDB, StaticFileProviderRWRefMut<'_>> + for UnifiedStorageWriter<'_, ProviderDB, StaticFileProviderRWRefMut<'_, ProviderDB::Primitives>> where - ProviderDB: DBProvider + StateChangeWriter + HeaderProvider, + ProviderDB: DBProvider + + StateChangeWriter + + HeaderProvider + + StaticFileProviderFactory, { /// Write the data and receipts to the database or static files if `static_file_producer` is /// `Some`. It should be `None` if there is any kind of pruning/filtering over the receipts. diff --git a/crates/storage/provider/src/writer/static_file.rs b/crates/storage/provider/src/writer/static_file.rs index 5514e211e58..f7227d21ef3 100644 --- a/crates/storage/provider/src/writer/static_file.rs +++ b/crates/storage/provider/src/writer/static_file.rs @@ -1,12 +1,13 @@ use crate::providers::StaticFileProviderRWRefMut; use alloy_primitives::{BlockNumber, TxNumber}; use reth_errors::ProviderResult; +use reth_node_types::NodePrimitives; use reth_primitives::Receipt; use reth_storage_api::ReceiptWriter; pub(crate) struct StaticFileWriter<'a, W>(pub(crate) &'a mut W); -impl ReceiptWriter for StaticFileWriter<'_, StaticFileProviderRWRefMut<'_>> { +impl ReceiptWriter for StaticFileWriter<'_, StaticFileProviderRWRefMut<'_, N>> { fn append_block_receipts( &mut self, first_tx_index: TxNumber, From 305a1cee0bf6660bea22b5d83189c84d78398b70 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 15 Nov 2024 11:54:02 +0100 Subject: [PATCH 186/211] feat: introduce debug witness api (#12567) Co-authored-by: Oliver --- crates/rpc/rpc-api/src/debug.rs | 23 +++++++++++++++++++++++ crates/rpc/rpc-api/src/lib.rs | 4 ++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/crates/rpc/rpc-api/src/debug.rs b/crates/rpc/rpc-api/src/debug.rs index 76316fa71f4..52b63fe3021 100644 --- a/crates/rpc/rpc-api/src/debug.rs +++ b/crates/rpc/rpc-api/src/debug.rs @@ -385,3 +385,26 @@ pub trait DebugApi { #[method(name = "writeMutexProfile")] async fn debug_write_mutex_profile(&self, file: String) -> RpcResult<()>; } + +/// An extension to the `debug_` namespace that provides additional methods for retrieving +/// witnesses. +/// +/// This is separate from the regular `debug_` api, because this depends on the network specific +/// params. For optimism this will expect the optimism specific payload attributes +#[cfg_attr(not(feature = "client"), rpc(server, namespace = "debug"))] +#[cfg_attr(feature = "client", rpc(server, client, namespace = "debug"))] +pub trait DebugExecutionWitnessApi { + /// The `debug_executePayload` method allows for re-execution of a group of transactions with + /// the purpose of generating an execution witness. The witness comprises of a map of all + /// hashed trie nodes to their preimages that were required during the execution of the block, + /// including during state root recomputation. + /// + /// The first argument is the block number or block hash. The second argument is the payload + /// attributes for the new block. The third argument is a list of transactions to be included. + #[method(name = "executePayload")] + async fn execute_payload( + &self, + parent_block_hash: B256, + attributes: Attributes, + ) -> RpcResult; +} diff --git a/crates/rpc/rpc-api/src/lib.rs b/crates/rpc/rpc-api/src/lib.rs index 73775112dcf..ac39b4802a8 100644 --- a/crates/rpc/rpc-api/src/lib.rs +++ b/crates/rpc/rpc-api/src/lib.rs @@ -37,7 +37,7 @@ pub use servers::*; pub mod servers { pub use crate::{ admin::AdminApiServer, - debug::DebugApiServer, + debug::{DebugApiServer, DebugExecutionWitnessApiServer}, engine::{EngineApiServer, EngineEthApiServer}, mev::{MevFullApiServer, MevSimApiServer}, net::NetApiServer, @@ -65,7 +65,7 @@ pub mod clients { pub use crate::{ admin::AdminApiClient, anvil::AnvilApiClient, - debug::DebugApiClient, + debug::{DebugApiClient, DebugExecutionWitnessApiClient}, engine::{EngineApiClient, EngineEthApiClient}, ganache::GanacheApiClient, hardhat::HardhatApiClient, From efa350d28df77630867762c4fbd6872193a0c388 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 15 Nov 2024 12:44:16 +0100 Subject: [PATCH 187/211] ci: exclude more crates for op tests (#12568) --- .github/workflows/unit.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml index defd9a6f535..e89ad903d80 100644 --- a/.github/workflows/unit.yml +++ b/.github/workflows/unit.yml @@ -35,11 +35,11 @@ jobs: partition: 2 total_partitions: 2 - type: optimism - args: --features "asm-keccak optimism" --locked + args: --features "asm-keccak optimism" --locked --exclude reth --exclude reth-bench --exclude "example-*" partition: 1 total_partitions: 2 - type: optimism - args: --features "asm-keccak optimism" --locked + args: --features "asm-keccak optimism" --locked --exclude reth --exclude reth-bench --exclude "example-*" partition: 2 total_partitions: 2 - type: book From 56826cbdbbf84ccbea41ff6ac049b27b024d5a48 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Fri, 15 Nov 2024 16:35:35 +0400 Subject: [PATCH 188/211] fix: remove redundant check in bodies stage (#12569) --- crates/stages/api/src/error.rs | 13 +------------ crates/stages/stages/src/stages/bodies.rs | 12 +----------- .../static-file/src/segments/headers.rs | 4 +--- .../static-file/src/segments/receipts.rs | 3 +-- .../static-file/src/segments/transactions.rs | 3 +-- .../provider/src/providers/static_file/writer.rs | 15 ++++++--------- 6 files changed, 11 insertions(+), 39 deletions(-) diff --git a/crates/stages/api/src/error.rs b/crates/stages/api/src/error.rs index 8562b10b6a5..b12f5186f3b 100644 --- a/crates/stages/api/src/error.rs +++ b/crates/stages/api/src/error.rs @@ -1,5 +1,5 @@ use crate::PipelineEvent; -use alloy_primitives::{BlockNumber, TxNumber}; +use alloy_primitives::TxNumber; use reth_consensus::ConsensusError; use reth_errors::{BlockExecutionError, DatabaseError, RethError}; use reth_network_p2p::error::DownloadError; @@ -112,16 +112,6 @@ pub enum StageError { /// Expected static file transaction number. static_file: TxNumber, }, - /// Unrecoverable inconsistency error related to a block number in a static file segment. - #[error("inconsistent block number for {segment}. db: {database}, static_file: {static_file}")] - InconsistentBlockNumber { - /// Static File segment where this error was encountered. - segment: StaticFileSegment, - /// Expected database block number. - database: BlockNumber, - /// Expected static file block number. - static_file: BlockNumber, - }, /// The prune checkpoint for the given segment is missing. #[error("missing prune checkpoint for {0}")] MissingPruneCheckpoint(PruneSegment), @@ -156,7 +146,6 @@ impl StageError { Self::MissingDownloadBuffer | Self::MissingSyncGap | Self::ChannelClosed | - Self::InconsistentBlockNumber { .. } | Self::InconsistentTxNumber { .. } | Self::Internal(_) | Self::Fatal(_) diff --git a/crates/stages/stages/src/stages/bodies.rs b/crates/stages/stages/src/stages/bodies.rs index 78aeda6feff..48bc679f5bd 100644 --- a/crates/stages/stages/src/stages/bodies.rs +++ b/crates/stages/stages/src/stages/bodies.rs @@ -176,17 +176,7 @@ where // Increment block on static file header. if block_number > 0 { - let appended_block_number = static_file_producer.increment_block(block_number)?; - - if appended_block_number != block_number { - // This scenario indicates a critical error in the logic of adding new - // items. It should be treated as an `expect()` failure. - return Err(StageError::InconsistentBlockNumber { - segment: StaticFileSegment::Transactions, - database: block_number, - static_file: appended_block_number, - }) - } + static_file_producer.increment_block(block_number)?; } match response { diff --git a/crates/static-file/static-file/src/segments/headers.rs b/crates/static-file/static-file/src/segments/headers.rs index 650f4998764..e06e1f09a17 100644 --- a/crates/static-file/static-file/src/segments/headers.rs +++ b/crates/static-file/static-file/src/segments/headers.rs @@ -46,9 +46,7 @@ impl Segment for Hea debug_assert_eq!(header_block, header_td_block); debug_assert_eq!(header_td_block, canonical_header_block); - let _static_file_block = - static_file_writer.append_header(&header, header_td.0, &canonical_header)?; - debug_assert_eq!(_static_file_block, header_block); + static_file_writer.append_header(&header, header_td.0, &canonical_header)?; } Ok(()) diff --git a/crates/static-file/static-file/src/segments/receipts.rs b/crates/static-file/static-file/src/segments/receipts.rs index 0442c360099..bd808b4d839 100644 --- a/crates/static-file/static-file/src/segments/receipts.rs +++ b/crates/static-file/static-file/src/segments/receipts.rs @@ -30,8 +30,7 @@ impl Segment Segment StaticFileProviderRW { /// and create the next one if we are past the end range. /// /// Returns the current [`BlockNumber`] as seen in the static file. - pub fn increment_block( - &mut self, - expected_block_number: BlockNumber, - ) -> ProviderResult { + pub fn increment_block(&mut self, expected_block_number: BlockNumber) -> ProviderResult<()> { let segment = self.writer.user_header().segment(); self.check_next_block_number(expected_block_number)?; @@ -350,7 +347,7 @@ impl StaticFileProviderRW { } } - let block = self.writer.user_header_mut().increment_block(); + self.writer.user_header_mut().increment_block(); if let Some(metrics) = &self.metrics { metrics.record_segment_operation( segment, @@ -359,7 +356,7 @@ impl StaticFileProviderRW { ); } - Ok(block) + Ok(()) } /// Verifies if the incoming block number matches the next expected block number @@ -524,13 +521,13 @@ impl StaticFileProviderRW { header: &Header, total_difficulty: U256, hash: &BlockHash, - ) -> ProviderResult { + ) -> ProviderResult<()> { let start = Instant::now(); self.ensure_no_queued_prune()?; debug_assert!(self.writer.user_header().segment() == StaticFileSegment::Headers); - let block_number = self.increment_block(header.number)?; + self.increment_block(header.number)?; self.append_column(header)?; self.append_column(CompactU256::from(total_difficulty))?; @@ -544,7 +541,7 @@ impl StaticFileProviderRW { ); } - Ok(block_number) + Ok(()) } /// Appends transaction to static file. From 5f66fa448ef5f19d1e9d122d140b61370d330a1c Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Fri, 15 Nov 2024 14:31:35 +0100 Subject: [PATCH 189/211] chore(sdk): improve usability `TxType` trait (#12548) --- Cargo.lock | 1 + crates/optimism/primitives/Cargo.toml | 1 + crates/optimism/primitives/src/lib.rs | 2 +- .../src/{op_tx_type.rs => tx_type.rs} | 33 ++++++++++++++++-- crates/primitives-traits/src/tx_type.rs | 34 +++++++------------ crates/primitives/src/transaction/tx_type.rs | 27 +++++++++++++++ 6 files changed, 74 insertions(+), 24 deletions(-) rename crates/optimism/primitives/src/{op_tx_type.rs => tx_type.rs} (90%) diff --git a/Cargo.lock b/Cargo.lock index 927e653a609..6ccf3cdabb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8381,6 +8381,7 @@ dependencies = [ "bytes", "derive_more 1.0.0", "op-alloy-consensus", + "reth-primitives-traits", ] [[package]] diff --git a/crates/optimism/primitives/Cargo.toml b/crates/optimism/primitives/Cargo.toml index a6f36732672..48f5877182f 100644 --- a/crates/optimism/primitives/Cargo.toml +++ b/crates/optimism/primitives/Cargo.toml @@ -19,3 +19,4 @@ alloy-eips.workspace = true alloy-rlp.workspace = true derive_more.workspace = true bytes.workspace = true +reth-primitives-traits.workspace = true \ No newline at end of file diff --git a/crates/optimism/primitives/src/lib.rs b/crates/optimism/primitives/src/lib.rs index f8d8e511498..a0745e7ac7d 100644 --- a/crates/optimism/primitives/src/lib.rs +++ b/crates/optimism/primitives/src/lib.rs @@ -8,4 +8,4 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] pub mod bedrock; -pub mod op_tx_type; +pub mod tx_type; diff --git a/crates/optimism/primitives/src/op_tx_type.rs b/crates/optimism/primitives/src/tx_type.rs similarity index 90% rename from crates/optimism/primitives/src/op_tx_type.rs rename to crates/optimism/primitives/src/tx_type.rs index b317bb05c9c..8536d352547 100644 --- a/crates/optimism/primitives/src/op_tx_type.rs +++ b/crates/optimism/primitives/src/tx_type.rs @@ -2,22 +2,51 @@ //! `OpTxType` implements `reth_primitives_traits::TxType`. //! This type is required because a `Compact` impl is needed on the deposit tx type. +use core::fmt::Debug; +use std::convert::TryFrom; + use alloy_primitives::{U64, U8}; use alloy_rlp::{Decodable, Encodable, Error}; use bytes::BufMut; -use core::fmt::Debug; use derive_more::{ derive::{From, Into}, Display, }; use op_alloy_consensus::OpTxType as AlloyOpTxType; -use std::convert::TryFrom; +use reth_primitives_traits::TxType; /// Wrapper type for `AlloyOpTxType` to implement `TxType` trait. #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Display, Ord, Hash, From, Into)] #[into(u8)] pub struct OpTxType(AlloyOpTxType); +impl TxType for OpTxType { + #[inline] + fn is_legacy(&self) -> bool { + matches!(self.0, AlloyOpTxType::Legacy) + } + + #[inline] + fn is_eip2930(&self) -> bool { + matches!(self.0, AlloyOpTxType::Eip2930) + } + + #[inline] + fn is_eip1559(&self) -> bool { + matches!(self.0, AlloyOpTxType::Eip1559) + } + + #[inline] + fn is_eip4844(&self) -> bool { + false + } + + #[inline] + fn is_eip7702(&self) -> bool { + matches!(self.0, AlloyOpTxType::Eip7702) + } +} + impl From for U8 { fn from(tx_type: OpTxType) -> Self { Self::from(u8::from(tx_type)) diff --git a/crates/primitives-traits/src/tx_type.rs b/crates/primitives-traits/src/tx_type.rs index 078d8ac947b..b1828ad57d9 100644 --- a/crates/primitives-traits/src/tx_type.rs +++ b/crates/primitives-traits/src/tx_type.rs @@ -30,26 +30,18 @@ pub trait TxType: + alloy_rlp::Encodable + alloy_rlp::Decodable { -} + /// Returns `true` if this is a legacy transaction. + fn is_legacy(&self) -> bool; -impl TxType for T where - T: Send - + Sync - + Unpin - + Clone - + Copy - + Default - + fmt::Debug - + fmt::Display - + PartialEq - + Eq - + PartialEq - + Into - + Into - + TryFrom - + TryFrom - + TryFrom - + alloy_rlp::Encodable - + alloy_rlp::Decodable -{ + /// Returns `true` if this is an eip-2930 transaction. + fn is_eip2930(&self) -> bool; + + /// Returns `true` if this is an eip-1559 transaction. + fn is_eip1559(&self) -> bool; + + /// Returns `true` if this is an eip-4844 transaction. + fn is_eip4844(&self) -> bool; + + /// Returns `true` if this is an eip-7702 transaction. + fn is_eip7702(&self) -> bool; } diff --git a/crates/primitives/src/transaction/tx_type.rs b/crates/primitives/src/transaction/tx_type.rs index 46e37086113..66fb7df5d64 100644 --- a/crates/primitives/src/transaction/tx_type.rs +++ b/crates/primitives/src/transaction/tx_type.rs @@ -91,6 +91,33 @@ impl TxType { } } +impl reth_primitives_traits::TxType for TxType { + #[inline] + fn is_legacy(&self) -> bool { + matches!(self, Self::Legacy) + } + + #[inline] + fn is_eip2930(&self) -> bool { + matches!(self, Self::Eip2930) + } + + #[inline] + fn is_eip1559(&self) -> bool { + matches!(self, Self::Eip1559) + } + + #[inline] + fn is_eip4844(&self) -> bool { + matches!(self, Self::Eip4844) + } + + #[inline] + fn is_eip7702(&self) -> bool { + matches!(self, Self::Eip7702) + } +} + impl From for u8 { fn from(value: TxType) -> Self { match value { From ac5976ff51251d59d726517278e7555c57a7c7d6 Mon Sep 17 00:00:00 2001 From: Krishang Shah <93703995+kamuik16@users.noreply.github.com> Date: Fri, 15 Nov 2024 21:35:19 +0530 Subject: [PATCH 190/211] feat: implement Compact for OpTxType (#12537) --- Cargo.lock | 3 + crates/optimism/primitives/Cargo.toml | 12 ++- crates/optimism/primitives/src/tx_type.rs | 93 ++++++++++++++++++++ crates/primitives/src/transaction/mod.rs | 2 +- crates/primitives/src/transaction/tx_type.rs | 8 +- 5 files changed, 112 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6ccf3cdabb1..ace45858d20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8381,7 +8381,10 @@ dependencies = [ "bytes", "derive_more 1.0.0", "op-alloy-consensus", + "reth-codecs", + "reth-primitives", "reth-primitives-traits", + "rstest", ] [[package]] diff --git a/crates/optimism/primitives/Cargo.toml b/crates/optimism/primitives/Cargo.toml index 48f5877182f..216e559a201 100644 --- a/crates/optimism/primitives/Cargo.toml +++ b/crates/optimism/primitives/Cargo.toml @@ -19,4 +19,14 @@ alloy-eips.workspace = true alloy-rlp.workspace = true derive_more.workspace = true bytes.workspace = true -reth-primitives-traits.workspace = true \ No newline at end of file +reth-primitives-traits.workspace = true +reth-codecs = { workspace = true, optional = true } +reth-primitives = { workspace = true, features = ["reth-codec"], optional = true } + +[features] +default = ["reth-codec"] +reth-codec = ["dep:reth-codecs", "dep:reth-primitives"] + +[dev-dependencies] +reth-codecs = { workspace = true, features = ["test-utils"] } +rstest.workspace = true \ No newline at end of file diff --git a/crates/optimism/primitives/src/tx_type.rs b/crates/optimism/primitives/src/tx_type.rs index 8536d352547..1b505920120 100644 --- a/crates/optimism/primitives/src/tx_type.rs +++ b/crates/optimism/primitives/src/tx_type.rs @@ -15,6 +15,16 @@ use derive_more::{ use op_alloy_consensus::OpTxType as AlloyOpTxType; use reth_primitives_traits::TxType; +#[cfg(feature = "reth-codec")] +use alloy_consensus::constants::EIP7702_TX_TYPE_ID; +#[cfg(feature = "reth-codec")] +use op_alloy_consensus::DEPOSIT_TX_TYPE_ID; +#[cfg(feature = "reth-codec")] +use reth_primitives::transaction::{ + COMPACT_EXTENDED_IDENTIFIER_FLAG, COMPACT_IDENTIFIER_EIP1559, COMPACT_IDENTIFIER_EIP2930, + COMPACT_IDENTIFIER_LEGACY, +}; + /// Wrapper type for `AlloyOpTxType` to implement `TxType` trait. #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Display, Ord, Hash, From, Into)] #[into(u8)] @@ -123,10 +133,55 @@ impl Decodable for OpTxType { } } +#[cfg(any(test, feature = "reth-codec"))] +impl reth_codecs::Compact for OpTxType { + fn to_compact(&self, buf: &mut B) -> usize + where + B: bytes::BufMut + AsMut<[u8]>, + { + match self.0 { + AlloyOpTxType::Legacy => COMPACT_IDENTIFIER_LEGACY, + AlloyOpTxType::Eip2930 => COMPACT_IDENTIFIER_EIP2930, + AlloyOpTxType::Eip1559 => COMPACT_IDENTIFIER_EIP1559, + AlloyOpTxType::Eip7702 => { + buf.put_u8(EIP7702_TX_TYPE_ID); + COMPACT_EXTENDED_IDENTIFIER_FLAG + } + AlloyOpTxType::Deposit => { + buf.put_u8(DEPOSIT_TX_TYPE_ID); + COMPACT_EXTENDED_IDENTIFIER_FLAG + } + } + } + + fn from_compact(mut buf: &[u8], identifier: usize) -> (Self, &[u8]) { + use bytes::Buf; + ( + match identifier { + COMPACT_IDENTIFIER_LEGACY => Self(AlloyOpTxType::Legacy), + COMPACT_IDENTIFIER_EIP2930 => Self(AlloyOpTxType::Eip2930), + COMPACT_IDENTIFIER_EIP1559 => Self(AlloyOpTxType::Eip1559), + COMPACT_EXTENDED_IDENTIFIER_FLAG => { + let extended_identifier = buf.get_u8(); + match extended_identifier { + EIP7702_TX_TYPE_ID => Self(AlloyOpTxType::Eip7702), + DEPOSIT_TX_TYPE_ID => Self(AlloyOpTxType::Deposit), + _ => panic!("Unsupported OpTxType identifier: {extended_identifier}"), + } + } + _ => panic!("Unknown identifier for OpTxType: {identifier}"), + }, + buf, + ) + } +} + #[cfg(test)] mod tests { use super::*; use bytes::BytesMut; + use reth_codecs::Compact; + use rstest::rstest; #[test] fn test_from_alloy_op_tx_type() { @@ -215,4 +270,42 @@ mod tests { let result = OpTxType::decode(&mut buf); assert!(result.is_err()); } + + #[rstest] + #[case(OpTxType(AlloyOpTxType::Legacy), COMPACT_IDENTIFIER_LEGACY, vec![])] + #[case(OpTxType(AlloyOpTxType::Eip2930), COMPACT_IDENTIFIER_EIP2930, vec![])] + #[case(OpTxType(AlloyOpTxType::Eip1559), COMPACT_IDENTIFIER_EIP1559, vec![])] + #[case(OpTxType(AlloyOpTxType::Eip7702), COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID])] + #[case(OpTxType(AlloyOpTxType::Deposit), COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![DEPOSIT_TX_TYPE_ID])] + fn test_txtype_to_compact( + #[case] tx_type: OpTxType, + #[case] expected_identifier: usize, + #[case] expected_buf: Vec, + ) { + let mut buf = vec![]; + let identifier = tx_type.to_compact(&mut buf); + + assert_eq!( + identifier, expected_identifier, + "Unexpected identifier for OpTxType {tx_type:?}", + ); + assert_eq!(buf, expected_buf, "Unexpected buffer for OpTxType {tx_type:?}",); + } + + #[rstest] + #[case(OpTxType(AlloyOpTxType::Legacy), COMPACT_IDENTIFIER_LEGACY, vec![])] + #[case(OpTxType(AlloyOpTxType::Eip2930), COMPACT_IDENTIFIER_EIP2930, vec![])] + #[case(OpTxType(AlloyOpTxType::Eip1559), COMPACT_IDENTIFIER_EIP1559, vec![])] + #[case(OpTxType(AlloyOpTxType::Eip7702), COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID])] + #[case(OpTxType(AlloyOpTxType::Deposit), COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![DEPOSIT_TX_TYPE_ID])] + fn test_txtype_from_compact( + #[case] expected_type: OpTxType, + #[case] identifier: usize, + #[case] buf: Vec, + ) { + let (actual_type, remaining_buf) = OpTxType::from_compact(&buf, identifier); + + assert_eq!(actual_type, expected_type, "Unexpected TxType for identifier {identifier}"); + assert!(remaining_buf.is_empty(), "Buffer not fully consumed for identifier {identifier}"); + } } diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index e5e4517d9dd..f325b72776f 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -62,7 +62,7 @@ use op_alloy_consensus::TxDeposit; #[cfg(feature = "optimism")] pub use tx_type::DEPOSIT_TX_TYPE_ID; #[cfg(any(test, feature = "reth-codec"))] -use tx_type::{ +pub use tx_type::{ COMPACT_EXTENDED_IDENTIFIER_FLAG, COMPACT_IDENTIFIER_EIP1559, COMPACT_IDENTIFIER_EIP2930, COMPACT_IDENTIFIER_LEGACY, }; diff --git a/crates/primitives/src/transaction/tx_type.rs b/crates/primitives/src/transaction/tx_type.rs index 66fb7df5d64..3445cb184c1 100644 --- a/crates/primitives/src/transaction/tx_type.rs +++ b/crates/primitives/src/transaction/tx_type.rs @@ -9,21 +9,21 @@ use serde::{Deserialize, Serialize}; /// Identifier parameter for legacy transaction #[cfg(any(test, feature = "reth-codec"))] -pub(crate) const COMPACT_IDENTIFIER_LEGACY: usize = 0; +pub const COMPACT_IDENTIFIER_LEGACY: usize = 0; /// Identifier parameter for EIP-2930 transaction #[cfg(any(test, feature = "reth-codec"))] -pub(crate) const COMPACT_IDENTIFIER_EIP2930: usize = 1; +pub const COMPACT_IDENTIFIER_EIP2930: usize = 1; /// Identifier parameter for EIP-1559 transaction #[cfg(any(test, feature = "reth-codec"))] -pub(crate) const COMPACT_IDENTIFIER_EIP1559: usize = 2; +pub const COMPACT_IDENTIFIER_EIP1559: usize = 2; /// For backwards compatibility purposes only 2 bits of the type are encoded in the identifier /// parameter. In the case of a [`COMPACT_EXTENDED_IDENTIFIER_FLAG`], the full transaction type is /// read from the buffer as a single byte. #[cfg(any(test, feature = "reth-codec"))] -pub(crate) const COMPACT_EXTENDED_IDENTIFIER_FLAG: usize = 3; +pub const COMPACT_EXTENDED_IDENTIFIER_FLAG: usize = 3; /// Identifier for [`TxDeposit`](op_alloy_consensus::TxDeposit) transaction. #[cfg(feature = "optimism")] From 841267d1b28e4f315012cdf8373212a7cde690ca Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 15 Nov 2024 17:16:55 +0100 Subject: [PATCH 191/211] feat: add helpers to obtain the execution witness for a payload (#12573) --- Cargo.lock | 1 + crates/optimism/payload/Cargo.toml | 3 +- crates/optimism/payload/src/builder.rs | 96 ++++++++++++++++++++------ 3 files changed, 76 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ace45858d20..650dc4607d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8344,6 +8344,7 @@ dependencies = [ "alloy-eips", "alloy-primitives", "alloy-rlp", + "alloy-rpc-types-debug", "alloy-rpc-types-engine", "op-alloy-consensus", "op-alloy-rpc-types-engine", diff --git a/crates/optimism/payload/Cargo.toml b/crates/optimism/payload/Cargo.toml index 839355b2158..646df040e19 100644 --- a/crates/optimism/payload/Cargo.toml +++ b/crates/optimism/payload/Cargo.toml @@ -15,7 +15,7 @@ workspace = true # reth reth-chainspec.workspace = true reth-primitives.workspace = true -reth-revm.workspace = true +reth-revm = { workspace = true, features = ["witness"] } reth-transaction-pool.workspace = true reth-provider.workspace = true reth-rpc-types-compat.workspace = true @@ -41,6 +41,7 @@ alloy-rlp.workspace = true op-alloy-rpc-types-engine.workspace = true op-alloy-consensus.workspace = true alloy-rpc-types-engine.workspace = true +alloy-rpc-types-debug.workspace = true alloy-consensus.workspace = true # misc diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index beb9a5c4ae2..2542ff527df 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -5,6 +5,7 @@ use std::{fmt::Display, sync::Arc}; use alloy_consensus::{Header, Transaction, EMPTY_OMMER_ROOT_HASH}; use alloy_eips::merge::BEACON_NONCE; use alloy_primitives::{Address, Bytes, U256}; +use alloy_rpc_types_debug::ExecutionWitness; use alloy_rpc_types_engine::PayloadId; use reth_basic_payload_builder::*; use reth_chain_state::ExecutedBlock; @@ -20,7 +21,7 @@ use reth_primitives::{ revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg}, Block, BlockBody, Receipt, SealedHeader, TransactionSigned, TxType, }; -use reth_provider::{ProviderError, StateProviderFactory, StateRootProvider}; +use reth_provider::{ProviderError, StateProofProvider, StateProviderFactory, StateRootProvider}; use reth_revm::database::StateProviderDatabase; use reth_transaction_pool::{ noop::NoopTransactionPool, BestTransactionsAttributes, PayloadTransactions, TransactionPool, @@ -38,6 +39,7 @@ use crate::{ payload::{OpBuiltPayload, OpPayloadBuilderAttributes}, }; use op_alloy_consensus::DepositTransaction; +use reth_revm::witness::ExecutionWitnessRecord; use reth_transaction_pool::pool::BestPayloadTransactions; /// Optimism's payload builder @@ -234,36 +236,33 @@ where Pool: TransactionPool, Txs: OpPayloadTransactions, { - /// Builds the payload on top of the state. - pub fn build( + /// Executes the payload and returns the outcome. + pub fn execute( self, - mut db: State, - ctx: OpPayloadBuilderCtx, - ) -> Result, PayloadBuilderError> + state: &mut State, + ctx: &OpPayloadBuilderCtx, + ) -> Result, PayloadBuilderError> where EvmConfig: ConfigureEvm

, - DB: Database + AsRef

, - P: StateRootProvider, + 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(&mut db)?; + ctx.apply_pre_beacon_root_contract_call(state)?; // 2. ensure create2deployer is force deployed - ctx.ensure_create2_deployer(&mut db)?; + ctx.ensure_create2_deployer(state)?; // 3. execute sequencer transactions - let mut info = ctx.execute_sequencer_transactions(&mut db)?; + let mut info = ctx.execute_sequencer_transactions(state)?; // 4. if mem pool transactions are requested we execute them if !ctx.attributes().no_tx_pool { let best_txs = best.best_transactions(pool, ctx.best_transaction_attributes()); - if let Some(cancelled) = - ctx.execute_best_transactions::<_, Pool>(&mut info, &mut db, best_txs)? - { - return Ok(cancelled) + 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 @@ -273,16 +272,38 @@ where } } - let WithdrawalsOutcome { withdrawals_root, withdrawals } = - ctx.commit_withdrawals(&mut db)?; + let withdrawals_outcome = ctx.commit_withdrawals(state)?; // merge all transitions into bundle state, this would apply the withdrawal balance changes // and 4788 contract call - db.merge_transitions(BundleRetention::Reverts); + state.merge_transitions(BundleRetention::Reverts); + + Ok(BuildOutcomeKind::Better { payload: ExecutedPayload { info, withdrawals_outcome } }) + } + + /// 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, + { + let ExecutedPayload { + info, + withdrawals_outcome: WithdrawalsOutcome { withdrawals, 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( - db.take_bundle(), + state.take_bundle(), vec![info.receipts.clone()].into(), block_number, Vec::new(), @@ -302,7 +323,7 @@ where // // calculate the state root let hashed_state = HashedPostState::from_bundle_state(&execution_outcome.state().state); let (state_root, trie_output) = { - db.database.as_ref().state_root_with_updates(hashed_state.clone()).inspect_err( + state.database.as_ref().state_root_with_updates(hashed_state.clone()).inspect_err( |err| { warn!(target: "payload_builder", parent_header=%ctx.parent().hash(), @@ -388,6 +409,24 @@ where 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 }) + } } /// A type that returns a the [`PayloadTransactions`] that should be included in the pool. @@ -411,6 +450,15 @@ impl OpPayloadTransactions for () { } } +/// Holds the state after execution +#[derive(Debug)] +pub struct ExecutedPayload { + /// Tracked execution info + pub info: ExecutionInfo, + /// Outcome after committing withdrawals. + pub withdrawals_outcome: WithdrawalsOutcome, +} + /// This acts as the container for executed transactions and its byproducts (receipts, gas used) #[derive(Default, Debug)] pub struct ExecutionInfo { @@ -725,13 +773,15 @@ where Ok(info) } - /// Executes the given best transactions and updates the execution 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> + ) -> Result, PayloadBuilderError> where DB: Database, Pool: TransactionPool, @@ -764,7 +814,7 @@ where // check if the job was cancelled, if so we can exit early if self.cancel.is_cancelled() { - return Ok(Some(BuildOutcomeKind::Cancelled)) + return Ok(Some(())) } // Configure the environment for the tx. From 6e00e5842669c98063d55931650c81d7a0ce3da1 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 15 Nov 2024 18:33:37 +0100 Subject: [PATCH 192/211] feat: add payload witness fn (#12579) --- crates/optimism/payload/src/builder.rs | 77 ++++++++++++++++++++------ 1 file changed, 61 insertions(+), 16 deletions(-) diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index 2542ff527df..8fb569f3dac 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -39,6 +39,7 @@ use crate::{ payload::{OpBuiltPayload, OpPayloadBuilderAttributes}, }; use op_alloy_consensus::DepositTransaction; +use op_alloy_rpc_types_engine::OpPayloadAttributes; use reth_revm::witness::ExecutionWitnessRecord; use reth_transaction_pool::pool::BestPayloadTransactions; @@ -94,21 +95,6 @@ where EvmConfig: ConfigureEvm

, Txs: OpPayloadTransactions, { - /// Returns the configured [`CfgEnvWithHandlerCfg`] and [`BlockEnv`] for the targeted payload - /// (that has the `parent` as its parent). - pub fn cfg_and_block_env( - &self, - config: &PayloadConfig, - parent: &Header, - ) -> Result<(CfgEnvWithHandlerCfg, BlockEnv), EvmConfig::Error> { - let next_attributes = NextBlockEnvAttributes { - timestamp: config.attributes.timestamp(), - suggested_fee_recipient: config.attributes.suggested_fee_recipient(), - prev_randao: config.attributes.prev_randao(), - }; - self.evm_config.next_cfg_and_block_env(parent, next_attributes) - } - /// 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 @@ -126,7 +112,7 @@ where Pool: TransactionPool, { let (initialized_cfg, initialized_block_env) = self - .cfg_and_block_env(&args.config, &args.config.parent_header) + .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; @@ -161,6 +147,65 @@ where } } +impl OpPayloadBuilder +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(), + }; + self.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.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 = OpBuilder { pool: NoopTransactionPool::default(), best: () }; + builder.witness(&mut state, &ctx) + } +} + /// Implementation of the [`PayloadBuilder`] trait for [`OpPayloadBuilder`]. impl PayloadBuilder for OpPayloadBuilder where From f0b8b9b221ad53d52f809daec5b76c6d11ea7ec3 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Fri, 15 Nov 2024 23:04:35 +0400 Subject: [PATCH 193/211] feat: add tx_number consistency check to StaticFileProviderRW (#12570) Co-authored-by: Matthias Seitz --- crates/stages/api/src/error.rs | 14 ------- crates/stages/stages/src/stages/bodies.rs | 13 +----- crates/storage/errors/src/provider.rs | 3 ++ .../src/providers/static_file/writer.rs | 41 ++++++++++--------- 4 files changed, 25 insertions(+), 46 deletions(-) diff --git a/crates/stages/api/src/error.rs b/crates/stages/api/src/error.rs index b12f5186f3b..9a4ef35aaf2 100644 --- a/crates/stages/api/src/error.rs +++ b/crates/stages/api/src/error.rs @@ -1,5 +1,4 @@ use crate::PipelineEvent; -use alloy_primitives::TxNumber; use reth_consensus::ConsensusError; use reth_errors::{BlockExecutionError, DatabaseError, RethError}; use reth_network_p2p::error::DownloadError; @@ -100,18 +99,6 @@ pub enum StageError { /// Static File segment segment: StaticFileSegment, }, - /// Unrecoverable inconsistency error related to a transaction number in a static file segment. - #[error( - "inconsistent transaction number for {segment}. db: {database}, static_file: {static_file}" - )] - InconsistentTxNumber { - /// Static File segment where this error was encountered. - segment: StaticFileSegment, - /// Expected database transaction number. - database: TxNumber, - /// Expected static file transaction number. - static_file: TxNumber, - }, /// The prune checkpoint for the given segment is missing. #[error("missing prune checkpoint for {0}")] MissingPruneCheckpoint(PruneSegment), @@ -146,7 +133,6 @@ impl StageError { Self::MissingDownloadBuffer | Self::MissingSyncGap | Self::ChannelClosed | - Self::InconsistentTxNumber { .. } | Self::Internal(_) | Self::Fatal(_) ) diff --git a/crates/stages/stages/src/stages/bodies.rs b/crates/stages/stages/src/stages/bodies.rs index 48bc679f5bd..07b97574972 100644 --- a/crates/stages/stages/src/stages/bodies.rs +++ b/crates/stages/stages/src/stages/bodies.rs @@ -183,18 +183,7 @@ where BlockResponse::Full(block) => { // Write transactions for transaction in block.body.transactions() { - let appended_tx_number = - static_file_producer.append_transaction(next_tx_num, transaction)?; - - if appended_tx_number != next_tx_num { - // This scenario indicates a critical error in the logic of adding new - // items. It should be treated as an `expect()` failure. - return Err(StageError::InconsistentTxNumber { - segment: StaticFileSegment::Transactions, - database: next_tx_num, - static_file: appended_tx_number, - }) - } + static_file_producer.append_transaction(next_tx_num, transaction)?; // Increment transaction id for each transaction. next_tx_num += 1; diff --git a/crates/storage/errors/src/provider.rs b/crates/storage/errors/src/provider.rs index d60a2adb92b..b6fcee545d5 100644 --- a/crates/storage/errors/src/provider.rs +++ b/crates/storage/errors/src/provider.rs @@ -133,6 +133,9 @@ pub enum ProviderError { /// Trying to insert data from an unexpected block number. #[display("trying to append data to {_0} as block #{_1} but expected block #{_2}")] UnexpectedStaticFileBlockNumber(StaticFileSegment, BlockNumber, BlockNumber), + /// Trying to insert data from an unexpected block number. + #[display("trying to append row to {_0} at index #{_1} but expected index #{_2}")] + UnexpectedStaticFileTxNumber(StaticFileSegment, TxNumber, TxNumber), /// Static File Provider was initialized as read-only. #[display("cannot get a writer on a read-only environment.")] ReadOnlyStaticFileAccess, diff --git a/crates/storage/provider/src/providers/static_file/writer.rs b/crates/storage/provider/src/providers/static_file/writer.rs index ef01bd773c8..5951dbb751f 100644 --- a/crates/storage/provider/src/providers/static_file/writer.rs +++ b/crates/storage/provider/src/providers/static_file/writer.rs @@ -498,16 +498,24 @@ impl StaticFileProviderRW { &mut self, tx_num: TxNumber, value: V, - ) -> ProviderResult { - if self.writer.user_header().tx_range().is_none() { - self.writer.user_header_mut().set_tx_range(tx_num, tx_num); - } else { + ) -> ProviderResult<()> { + if let Some(range) = self.writer.user_header().tx_range() { + let next_tx = range.end() + 1; + if next_tx != tx_num { + return Err(ProviderError::UnexpectedStaticFileTxNumber( + self.writer.user_header().segment(), + tx_num, + next_tx, + )) + } self.writer.user_header_mut().increment_tx(); + } else { + self.writer.user_header_mut().set_tx_range(tx_num, tx_num); } self.append_column(value)?; - Ok(self.writer.user_header().tx_end().expect("qed")) + Ok(()) } /// Appends header to static file. @@ -550,16 +558,12 @@ impl StaticFileProviderRW { /// empty blocks and this function wouldn't be called. /// /// Returns the current [`TxNumber`] as seen in the static file. - pub fn append_transaction( - &mut self, - tx_num: TxNumber, - tx: impl Compact, - ) -> ProviderResult { + pub fn append_transaction(&mut self, tx_num: TxNumber, tx: impl Compact) -> ProviderResult<()> { let start = Instant::now(); self.ensure_no_queued_prune()?; debug_assert!(self.writer.user_header().segment() == StaticFileSegment::Transactions); - let result = self.append_with_tx_number(tx_num, tx)?; + self.append_with_tx_number(tx_num, tx)?; if let Some(metrics) = &self.metrics { metrics.record_segment_operation( @@ -569,7 +573,7 @@ impl StaticFileProviderRW { ); } - Ok(result) + Ok(()) } /// Appends receipt to static file. @@ -578,16 +582,12 @@ impl StaticFileProviderRW { /// empty blocks and this function wouldn't be called. /// /// Returns the current [`TxNumber`] as seen in the static file. - pub fn append_receipt( - &mut self, - tx_num: TxNumber, - receipt: &Receipt, - ) -> ProviderResult { + pub fn append_receipt(&mut self, tx_num: TxNumber, receipt: &Receipt) -> ProviderResult<()> { let start = Instant::now(); self.ensure_no_queued_prune()?; debug_assert!(self.writer.user_header().segment() == StaticFileSegment::Receipts); - let result = self.append_with_tx_number(tx_num, receipt)?; + self.append_with_tx_number(tx_num, receipt)?; if let Some(metrics) = &self.metrics { metrics.record_segment_operation( @@ -597,7 +597,7 @@ impl StaticFileProviderRW { ); } - Ok(result) + Ok(()) } /// Appends multiple receipts to the static file. @@ -625,7 +625,8 @@ impl StaticFileProviderRW { for receipt_result in receipts_iter { let (tx_num, receipt) = receipt_result?; - tx_number = self.append_with_tx_number(tx_num, receipt.borrow())?; + self.append_with_tx_number(tx_num, receipt.borrow())?; + tx_number = tx_num; count += 1; } From b31b1ea288363de9010fa3608be130382625ed14 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 15 Nov 2024 20:44:53 +0100 Subject: [PATCH 194/211] feat: add op debug witness api (#12583) Co-authored-by: Federico Gimenez --- Cargo.lock | 5 ++ crates/optimism/rpc/Cargo.toml | 8 ++- crates/optimism/rpc/src/lib.rs | 1 + crates/optimism/rpc/src/witness.rs | 81 ++++++++++++++++++++++++++++++ crates/rpc/rpc-api/src/debug.rs | 8 +-- 5 files changed, 98 insertions(+), 5 deletions(-) create mode 100644 crates/optimism/rpc/src/witness.rs diff --git a/Cargo.lock b/Cargo.lock index 650dc4607d9..ac3dd4fa988 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8395,12 +8395,15 @@ dependencies = [ "alloy-consensus", "alloy-eips", "alloy-primitives", + "alloy-rpc-types-debug", "alloy-rpc-types-eth", "derive_more 1.0.0", + "jsonrpsee-core", "jsonrpsee-types", "op-alloy-consensus", "op-alloy-network", "op-alloy-rpc-types", + "op-alloy-rpc-types-engine", "parking_lot", "reqwest", "reth-chainspec", @@ -8412,9 +8415,11 @@ dependencies = [ "reth-optimism-consensus", "reth-optimism-evm", "reth-optimism-forks", + "reth-optimism-payload-builder", "reth-primitives", "reth-provider", "reth-rpc", + "reth-rpc-api", "reth-rpc-eth-api", "reth-rpc-eth-types", "reth-rpc-server-types", diff --git a/crates/optimism/rpc/Cargo.toml b/crates/optimism/rpc/Cargo.toml index 37b64b774a1..17fafef7096 100644 --- a/crates/optimism/rpc/Cargo.toml +++ b/crates/optimism/rpc/Cargo.toml @@ -22,6 +22,7 @@ reth-rpc-server-types.workspace = true reth-tasks = { workspace = true, features = ["rayon"] } reth-transaction-pool.workspace = true reth-rpc.workspace = true +reth-rpc-api.workspace = true reth-node-api.workspace = true reth-network-api.workspace = true reth-node-builder.workspace = true @@ -31,15 +32,18 @@ reth-chainspec.workspace = true reth-optimism-chainspec.workspace = true reth-optimism-consensus.workspace = true reth-optimism-evm.workspace = true +reth-optimism-payload-builder.workspace = true reth-optimism-forks.workspace = true # ethereum alloy-eips.workspace = true alloy-primitives.workspace = true alloy-rpc-types-eth.workspace = true +alloy-rpc-types-debug.workspace = true alloy-consensus.workspace = true op-alloy-network.workspace = true op-alloy-rpc-types.workspace = true +op-alloy-rpc-types-engine.workspace = true op-alloy-consensus.workspace = true revm.workspace = true @@ -49,6 +53,7 @@ tokio.workspace = true reqwest = { workspace = true, features = ["rustls-tls-native-roots"] } # rpc +jsonrpsee-core.workspace = true jsonrpsee-types.workspace = true serde_json.workspace = true @@ -66,5 +71,6 @@ optimism = [ "reth-primitives/optimism", "reth-provider/optimism", "revm/optimism", - "reth-optimism-consensus/optimism" + "reth-optimism-consensus/optimism", + "reth-optimism-payload-builder/optimism" ] diff --git a/crates/optimism/rpc/src/lib.rs b/crates/optimism/rpc/src/lib.rs index 44d0fa35389..0fa0debdf33 100644 --- a/crates/optimism/rpc/src/lib.rs +++ b/crates/optimism/rpc/src/lib.rs @@ -13,6 +13,7 @@ pub mod error; pub mod eth; pub mod sequencer; +pub mod witness; pub use error::{OpEthApiError, OpInvalidTransactionError, SequencerClientError}; pub use eth::{OpEthApi, OpReceiptBuilder}; diff --git a/crates/optimism/rpc/src/witness.rs b/crates/optimism/rpc/src/witness.rs new file mode 100644 index 00000000000..0521fa9025d --- /dev/null +++ b/crates/optimism/rpc/src/witness.rs @@ -0,0 +1,81 @@ +//! Support for optimism specific witness RPCs. + +use alloy_consensus::Header; +use alloy_primitives::B256; +use alloy_rpc_types_debug::ExecutionWitness; +use jsonrpsee_core::RpcResult; +use op_alloy_rpc_types_engine::OpPayloadAttributes; +use reth_chainspec::ChainSpecProvider; +use reth_evm::ConfigureEvm; +use reth_optimism_chainspec::OpChainSpec; +use reth_optimism_payload_builder::OpPayloadBuilder; +use reth_primitives::SealedHeader; +use reth_provider::{BlockReaderIdExt, ProviderError, ProviderResult, StateProviderFactory}; +use reth_rpc_api::DebugExecutionWitnessApiServer; +use reth_rpc_server_types::{result::internal_rpc_err, ToRpcResult}; +use std::{fmt::Debug, sync::Arc}; + +/// An extension to the `debug_` namespace of the RPC API. +pub struct OpDebugWitnessApi { + inner: Arc>, +} + +impl OpDebugWitnessApi { + /// Creates a new instance of the `OpDebugWitnessApi`. + pub fn new(provider: Provider, evm_config: EvmConfig) -> Self { + let builder = OpPayloadBuilder::new(evm_config); + let inner = OpDebugWitnessApiInner { provider, builder }; + Self { inner: Arc::new(inner) } + } +} + +impl OpDebugWitnessApi +where + Provider: BlockReaderIdExt, +{ + /// Fetches the parent header by hash. + fn parent_header(&self, parent_block_hash: B256) -> ProviderResult { + self.inner + .provider + .sealed_header_by_hash(parent_block_hash)? + .ok_or_else(|| ProviderError::HeaderNotFound(parent_block_hash.into())) + } +} + +impl DebugExecutionWitnessApiServer + for OpDebugWitnessApi +where + Provider: BlockReaderIdExt + + StateProviderFactory + + ChainSpecProvider + + 'static, + EvmConfig: ConfigureEvm
+ 'static, +{ + fn execute_payload( + &self, + parent_block_hash: B256, + attributes: OpPayloadAttributes, + ) -> RpcResult { + let parent_header = self.parent_header(parent_block_hash).to_rpc_result()?; + self.inner + .builder + .payload_witness(&self.inner.provider, parent_header, attributes) + .map_err(|err| internal_rpc_err(err.to_string())) + } +} + +impl Clone for OpDebugWitnessApi { + fn clone(&self) -> Self { + Self { inner: Arc::clone(&self.inner) } + } +} +impl Debug for OpDebugWitnessApi { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("OpDebugWitnessApi").finish_non_exhaustive() + } +} + +struct OpDebugWitnessApiInner { + provider: Provider, + builder: OpPayloadBuilder, +} diff --git a/crates/rpc/rpc-api/src/debug.rs b/crates/rpc/rpc-api/src/debug.rs index 52b63fe3021..28ed9af5c13 100644 --- a/crates/rpc/rpc-api/src/debug.rs +++ b/crates/rpc/rpc-api/src/debug.rs @@ -399,10 +399,10 @@ pub trait DebugExecutionWitnessApi { /// hashed trie nodes to their preimages that were required during the execution of the block, /// including during state root recomputation. /// - /// The first argument is the block number or block hash. The second argument is the payload - /// attributes for the new block. The third argument is a list of transactions to be included. - #[method(name = "executePayload")] - async fn execute_payload( + /// The first argument is the parent block hash. The second argument is the payload + /// attributes for the new block. + #[method(name = "executePayload", blocking)] + fn execute_payload( &self, parent_block_hash: B256, attributes: Attributes, From 02237bfa711ea6d1757a2569ac59639a6ed36e5a Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sat, 16 Nov 2024 05:19:40 +0100 Subject: [PATCH 195/211] feat: add contains fns to transport rpc modules (#12593) --- crates/rpc/rpc-builder/src/lib.rs | 20 ++++++++++++++++++++ crates/rpc/rpc-server-types/src/module.rs | 9 +++++++++ 2 files changed, 29 insertions(+) diff --git a/crates/rpc/rpc-builder/src/lib.rs b/crates/rpc/rpc-builder/src/lib.rs index 27eceed98cb..8af60bda187 100644 --- a/crates/rpc/rpc-builder/src/lib.rs +++ b/crates/rpc/rpc-builder/src/lib.rs @@ -1934,6 +1934,26 @@ impl TransportRpcModuleConfig { self.config.as_ref() } + /// Returns true if the given module is configured for any transport. + pub fn contains_any(&self, module: &RethRpcModule) -> bool { + self.contains_http(module) || self.contains_ws(module) || self.contains_ipc(module) + } + + /// Returns true if the given module is configured for the http transport. + pub fn contains_http(&self, module: &RethRpcModule) -> bool { + self.http.as_ref().map_or(false, |http| http.contains(module)) + } + + /// Returns true if the given module is configured for the ws transport. + pub fn contains_ws(&self, module: &RethRpcModule) -> bool { + self.ws.as_ref().map_or(false, |ws| ws.contains(module)) + } + + /// Returns true if the given module is configured for the ipc transport. + pub fn contains_ipc(&self, module: &RethRpcModule) -> bool { + self.ipc.as_ref().map_or(false, |ipc| ipc.contains(module)) + } + /// Ensures that both http and ws are configured and that they are configured to use the same /// port. fn ensure_ws_http_identical(&self) -> Result<(), WsHttpSamePortError> { diff --git a/crates/rpc/rpc-server-types/src/module.rs b/crates/rpc/rpc-server-types/src/module.rs index 9f96ff0cef3..43e4a937436 100644 --- a/crates/rpc/rpc-server-types/src/module.rs +++ b/crates/rpc/rpc-server-types/src/module.rs @@ -140,6 +140,15 @@ impl RpcModuleSelection { (None, None) => true, } } + + /// Returns true if the selection contains the given module. + pub fn contains(&self, module: &RethRpcModule) -> bool { + match self { + Self::All => true, + Self::Standard => Self::STANDARD_MODULES.contains(module), + Self::Selection(s) => s.contains(module), + } + } } impl From<&HashSet> for RpcModuleSelection { From 5276093e71ff48bfcc8c1cab00ae7c946eb4418f Mon Sep 17 00:00:00 2001 From: Ayodeji Akinola Date: Sat, 16 Nov 2024 05:39:34 +0100 Subject: [PATCH 196/211] chore(util): Add reth payload util (#12590) --- Cargo.lock | 12 ++ Cargo.toml | 2 + crates/optimism/node/Cargo.toml | 1 + crates/optimism/node/tests/it/priority.rs | 6 +- crates/optimism/payload/Cargo.toml | 1 + crates/optimism/payload/src/builder.rs | 3 +- crates/payload/util/Cargo.toml | 20 ++++ crates/payload/util/src/lib.rs | 15 +++ crates/payload/util/src/traits.rs | 20 ++++ crates/payload/util/src/transaction.rs | 128 +++++++++++++++++++++ crates/transaction-pool/Cargo.toml | 1 + crates/transaction-pool/src/pool/best.rs | 131 +--------------------- crates/transaction-pool/src/pool/mod.rs | 1 - crates/transaction-pool/src/traits.rs | 18 --- 14 files changed, 207 insertions(+), 152 deletions(-) create mode 100644 crates/payload/util/Cargo.toml create mode 100644 crates/payload/util/src/lib.rs create mode 100644 crates/payload/util/src/traits.rs create mode 100644 crates/payload/util/src/transaction.rs diff --git a/Cargo.lock b/Cargo.lock index ac3dd4fa988..9514d361fbf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8324,6 +8324,7 @@ dependencies = [ "reth-optimism-payload-builder", "reth-optimism-rpc", "reth-payload-builder", + "reth-payload-util", "reth-primitives", "reth-provider", "reth-revm", @@ -8359,6 +8360,7 @@ dependencies = [ "reth-optimism-forks", "reth-payload-builder", "reth-payload-primitives", + "reth-payload-util", "reth-primitives", "reth-provider", "reth-revm", @@ -8486,6 +8488,15 @@ dependencies = [ "tracing", ] +[[package]] +name = "reth-payload-util" +version = "1.1.1" +dependencies = [ + "alloy-consensus", + "alloy-primitives", + "reth-primitives", +] + [[package]] name = "reth-payload-validator" version = "1.1.1" @@ -9265,6 +9276,7 @@ dependencies = [ "reth-execution-types", "reth-fs-util", "reth-metrics", + "reth-payload-util", "reth-primitives", "reth-primitives-traits", "reth-provider", diff --git a/Cargo.toml b/Cargo.toml index 3f65bceb4bf..398be3e5faf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -82,6 +82,7 @@ members = [ "crates/payload/builder/", "crates/payload/primitives/", "crates/payload/validator/", + "crates/payload/util/", "crates/primitives-traits/", "crates/primitives/", "crates/prune/prune", @@ -381,6 +382,7 @@ reth-optimism-storage = { path = "crates/optimism/storage" } reth-payload-builder = { path = "crates/payload/builder" } reth-payload-primitives = { path = "crates/payload/primitives" } reth-payload-validator = { path = "crates/payload/validator" } +reth-payload-util = { path = "crates/payload/util" } reth-primitives = { path = "crates/primitives", default-features = false, features = [ "std", ] } diff --git a/crates/optimism/node/Cargo.toml b/crates/optimism/node/Cargo.toml index fb8cc27787e..9a80c83deec 100644 --- a/crates/optimism/node/Cargo.toml +++ b/crates/optimism/node/Cargo.toml @@ -16,6 +16,7 @@ reth-chainspec.workspace = true reth-engine-local.workspace = true reth-primitives.workspace = true reth-payload-builder.workspace = true +reth-payload-util.workspace = true reth-basic-payload-builder.workspace = true reth-consensus.workspace = true reth-node-api.workspace = true diff --git a/crates/optimism/node/tests/it/priority.rs b/crates/optimism/node/tests/it/priority.rs index 52e3bef3d91..f1260d2da01 100644 --- a/crates/optimism/node/tests/it/priority.rs +++ b/crates/optimism/node/tests/it/priority.rs @@ -25,12 +25,10 @@ use reth_optimism_node::{ OpEngineTypes, OpNode, }; use reth_optimism_payload_builder::builder::OpPayloadTransactions; +use reth_payload_util::{PayloadTransactions, PayloadTransactionsChain, PayloadTransactionsFixed}; use reth_primitives::{SealedBlock, Transaction, TransactionSigned, TransactionSignedEcRecovered}; use reth_provider::providers::BlockchainProvider2; -use reth_transaction_pool::{ - pool::{BestPayloadTransactions, PayloadTransactionsChain, PayloadTransactionsFixed}, - PayloadTransactions, -}; +use reth_transaction_pool::pool::BestPayloadTransactions; use std::sync::Arc; use tokio::sync::Mutex; diff --git a/crates/optimism/payload/Cargo.toml b/crates/optimism/payload/Cargo.toml index 646df040e19..19a47be4951 100644 --- a/crates/optimism/payload/Cargo.toml +++ b/crates/optimism/payload/Cargo.toml @@ -22,6 +22,7 @@ reth-rpc-types-compat.workspace = true reth-evm.workspace = true reth-execution-types.workspace = true reth-payload-builder.workspace = true +reth-payload-util.workspace = true reth-payload-primitives = { workspace = true, features = ["op"] } reth-basic-payload-builder.workspace = true reth-trie.workspace = true diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index 8fb569f3dac..d0eb464ae02 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -16,6 +16,7 @@ use reth_optimism_chainspec::OpChainSpec; use reth_optimism_consensus::calculate_receipt_root_no_memo_optimism; use reth_optimism_forks::OpHardforks; use reth_payload_primitives::{PayloadBuilderAttributes, PayloadBuilderError}; +use reth_payload_util::PayloadTransactions; use reth_primitives::{ proofs, revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg}, @@ -24,7 +25,7 @@ use reth_primitives::{ use reth_provider::{ProviderError, StateProofProvider, StateProviderFactory, StateRootProvider}; use reth_revm::database::StateProviderDatabase; use reth_transaction_pool::{ - noop::NoopTransactionPool, BestTransactionsAttributes, PayloadTransactions, TransactionPool, + noop::NoopTransactionPool, BestTransactionsAttributes, TransactionPool, }; use reth_trie::HashedPostState; use revm::{ diff --git a/crates/payload/util/Cargo.toml b/crates/payload/util/Cargo.toml new file mode 100644 index 00000000000..2da8dc66028 --- /dev/null +++ b/crates/payload/util/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "reth-payload-util" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true +description = "reth payload utilities" + +[lints] +workspace = true + +[dependencies] +# reth +reth-primitives.workspace = true + +# alloy +alloy-primitives.workspace = true +alloy-consensus.workspace = true \ No newline at end of file diff --git a/crates/payload/util/src/lib.rs b/crates/payload/util/src/lib.rs new file mode 100644 index 00000000000..5ad0e83507b --- /dev/null +++ b/crates/payload/util/src/lib.rs @@ -0,0 +1,15 @@ +//! payload utils. + +#![doc( + html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", + html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", + issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" +)] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] + +mod traits; +mod transaction; + +pub use traits::PayloadTransactions; +pub use transaction::{PayloadTransactionsChain, PayloadTransactionsFixed}; diff --git a/crates/payload/util/src/traits.rs b/crates/payload/util/src/traits.rs new file mode 100644 index 00000000000..52dad511169 --- /dev/null +++ b/crates/payload/util/src/traits.rs @@ -0,0 +1,20 @@ +use alloy_primitives::Address; +use reth_primitives::TransactionSignedEcRecovered; + +/// Iterator that returns transactions for the block building process in the order they should be +/// included in the block. +/// +/// Can include transactions from the pool and other sources (alternative pools, +/// sequencer-originated transactions, etc.). +pub trait PayloadTransactions { + /// Returns the next transaction to include in the block. + fn next( + &mut self, + // In the future, `ctx` can include access to state for block building purposes. + ctx: (), + ) -> Option; + + /// Exclude descendants of the transaction with given sender and nonce from the iterator, + /// because this transaction won't be included in the block. + fn mark_invalid(&mut self, sender: Address, nonce: u64); +} diff --git a/crates/payload/util/src/transaction.rs b/crates/payload/util/src/transaction.rs new file mode 100644 index 00000000000..a45e177d4d3 --- /dev/null +++ b/crates/payload/util/src/transaction.rs @@ -0,0 +1,128 @@ +use crate::PayloadTransactions; +use alloy_consensus::Transaction; +use alloy_primitives::Address; +use reth_primitives::TransactionSignedEcRecovered; + +/// An implementation of [`crate::traits::PayloadTransactions`] that yields +/// a pre-defined set of transactions. +/// +/// This is useful to put a sequencer-specified set of transactions into the block +/// and compose it with the rest of the transactions. +#[derive(Debug)] +pub struct PayloadTransactionsFixed { + transactions: Vec, + index: usize, +} + +impl PayloadTransactionsFixed { + /// Constructs a new [`PayloadTransactionsFixed`]. + pub fn new(transactions: Vec) -> Self { + Self { transactions, index: Default::default() } + } + + /// Constructs a new [`PayloadTransactionsFixed`] with a single transaction. + pub fn single(transaction: T) -> Self { + Self { transactions: vec![transaction], index: Default::default() } + } +} + +impl PayloadTransactions for PayloadTransactionsFixed { + fn next(&mut self, _ctx: ()) -> Option { + (self.index < self.transactions.len()).then(|| { + let tx = self.transactions[self.index].clone(); + self.index += 1; + tx + }) + } + + fn mark_invalid(&mut self, _sender: Address, _nonce: u64) {} +} + +/// Wrapper over [`crate::traits::PayloadTransactions`] that combines transactions from multiple +/// `PayloadTransactions` iterators and keeps track of the gas for both of iterators. +/// +/// We can't use [`Iterator::chain`], because: +/// (a) we need to propagate the `mark_invalid` and `no_updates` +/// (b) we need to keep track of the gas +/// +/// Notes that [`PayloadTransactionsChain`] fully drains the first iterator +/// before moving to the second one. +/// +/// If the `before` iterator has transactions that are not fitting into the block, +/// the after iterator will get propagated a `mark_invalid` call for each of them. +#[derive(Debug)] +pub struct PayloadTransactionsChain { + /// Iterator that will be used first + before: B, + /// Allowed gas for the transactions from `before` iterator. If `None`, no gas limit is + /// enforced. + before_max_gas: Option, + /// Gas used by the transactions from `before` iterator + before_gas: u64, + /// Iterator that will be used after `before` iterator + after: A, + /// Allowed gas for the transactions from `after` iterator. If `None`, no gas limit is + /// enforced. + after_max_gas: Option, + /// Gas used by the transactions from `after` iterator + after_gas: u64, +} + +impl PayloadTransactionsChain { + /// Constructs a new [`PayloadTransactionsChain`]. + pub fn new( + before: B, + before_max_gas: Option, + after: A, + after_max_gas: Option, + ) -> Self { + Self { + before, + before_max_gas, + before_gas: Default::default(), + after, + after_max_gas, + after_gas: Default::default(), + } + } +} + +impl PayloadTransactions for PayloadTransactionsChain +where + B: PayloadTransactions, + A: PayloadTransactions, +{ + fn next(&mut self, ctx: ()) -> Option { + while let Some(tx) = self.before.next(ctx) { + if let Some(before_max_gas) = self.before_max_gas { + if self.before_gas + tx.transaction.gas_limit() <= before_max_gas { + self.before_gas += tx.transaction.gas_limit(); + return Some(tx); + } + self.before.mark_invalid(tx.signer(), tx.transaction.nonce()); + self.after.mark_invalid(tx.signer(), tx.transaction.nonce()); + } else { + return Some(tx); + } + } + + while let Some(tx) = self.after.next(ctx) { + if let Some(after_max_gas) = self.after_max_gas { + if self.after_gas + tx.transaction.gas_limit() <= after_max_gas { + self.after_gas += tx.transaction.gas_limit(); + return Some(tx); + } + self.after.mark_invalid(tx.signer(), tx.transaction.nonce()); + } else { + return Some(tx); + } + } + + None + } + + fn mark_invalid(&mut self, sender: Address, nonce: u64) { + self.before.mark_invalid(sender, nonce); + self.after.mark_invalid(sender, nonce); + } +} diff --git a/crates/transaction-pool/Cargo.toml b/crates/transaction-pool/Cargo.toml index 7c760c81c54..22df8253682 100644 --- a/crates/transaction-pool/Cargo.toml +++ b/crates/transaction-pool/Cargo.toml @@ -18,6 +18,7 @@ reth-chainspec.workspace = true reth-eth-wire-types.workspace = true reth-primitives = { workspace = true, features = ["c-kzg", "secp256k1"] } reth-primitives-traits.workspace = true +reth-payload-util.workspace = true reth-execution-types.workspace = true reth-fs-util.workspace = true reth-storage-api.workspace = true diff --git a/crates/transaction-pool/src/pool/best.rs b/crates/transaction-pool/src/pool/best.rs index 21bcc668b75..7c2e5a025b7 100644 --- a/crates/transaction-pool/src/pool/best.rs +++ b/crates/transaction-pool/src/pool/best.rs @@ -1,11 +1,11 @@ use crate::{ identifier::{SenderId, TransactionId}, pool::pending::PendingTransaction, - PayloadTransactions, PoolTransaction, TransactionOrdering, ValidPoolTransaction, + PoolTransaction, TransactionOrdering, ValidPoolTransaction, }; -use alloy_consensus::Transaction; use alloy_primitives::Address; use core::fmt; +use reth_payload_util::PayloadTransactions; use reth_primitives::TransactionSignedEcRecovered; use std::{ collections::{BTreeMap, BTreeSet, HashSet, VecDeque}, @@ -20,7 +20,6 @@ use tracing::debug; /// This is a wrapper around [`BestTransactions`] that also enforces a specific basefee. /// /// This iterator guarantees that all transaction it returns satisfy both the base fee and blob fee! -#[derive(Debug)] pub(crate) struct BestTransactionsWithFees { pub(crate) best: BestTransactions, pub(crate) base_fee: u64, @@ -73,7 +72,6 @@ impl Iterator for BestTransactionsWithFees { /// be executed on the current state, but only yields transactions that are ready to be executed /// now. While it contains all gapless transactions of a sender, it _always_ only returns the /// transaction with the current on chain nonce. -#[derive(Debug)] pub(crate) struct BestTransactions { /// Contains a copy of _all_ transactions of the pending pool at the point in time this /// iterator was created. @@ -397,130 +395,6 @@ where } } -/// An implementation of [`crate::traits::PayloadTransactions`] that yields -/// a pre-defined set of transactions. -/// -/// This is useful to put a sequencer-specified set of transactions into the block -/// and compose it with the rest of the transactions. -#[derive(Debug)] -pub struct PayloadTransactionsFixed { - transactions: Vec, - index: usize, -} - -impl PayloadTransactionsFixed { - /// Constructs a new [`PayloadTransactionsFixed`]. - pub fn new(transactions: Vec) -> Self { - Self { transactions, index: Default::default() } - } - - /// Constructs a new [`PayloadTransactionsFixed`] with a single transaction. - pub fn single(transaction: T) -> Self { - Self { transactions: vec![transaction], index: Default::default() } - } -} - -impl PayloadTransactions for PayloadTransactionsFixed { - fn next(&mut self, _ctx: ()) -> Option { - (self.index < self.transactions.len()).then(|| { - let tx = self.transactions[self.index].clone(); - self.index += 1; - tx - }) - } - - fn mark_invalid(&mut self, _sender: Address, _nonce: u64) {} -} - -/// Wrapper over [`crate::traits::PayloadTransactions`] that combines transactions from multiple -/// `PayloadTransactions` iterators and keeps track of the gas for both of iterators. -/// -/// We can't use [`Iterator::chain`], because: -/// (a) we need to propagate the `mark_invalid` and `no_updates` -/// (b) we need to keep track of the gas -/// -/// Notes that [`PayloadTransactionsChain`] fully drains the first iterator -/// before moving to the second one. -/// -/// If the `before` iterator has transactions that are not fitting into the block, -/// the after iterator will get propagated a `mark_invalid` call for each of them. -#[derive(Debug)] -pub struct PayloadTransactionsChain { - /// Iterator that will be used first - before: B, - /// Allowed gas for the transactions from `before` iterator. If `None`, no gas limit is - /// enforced. - before_max_gas: Option, - /// Gas used by the transactions from `before` iterator - before_gas: u64, - /// Iterator that will be used after `before` iterator - after: A, - /// Allowed gas for the transactions from `after` iterator. If `None`, no gas limit is - /// enforced. - after_max_gas: Option, - /// Gas used by the transactions from `after` iterator - after_gas: u64, -} - -impl PayloadTransactionsChain { - /// Constructs a new [`PayloadTransactionsChain`]. - pub fn new( - before: B, - before_max_gas: Option, - after: A, - after_max_gas: Option, - ) -> Self { - Self { - before, - before_max_gas, - before_gas: Default::default(), - after, - after_max_gas, - after_gas: Default::default(), - } - } -} - -impl PayloadTransactions for PayloadTransactionsChain -where - B: PayloadTransactions, - A: PayloadTransactions, -{ - fn next(&mut self, ctx: ()) -> Option { - while let Some(tx) = self.before.next(ctx) { - if let Some(before_max_gas) = self.before_max_gas { - if self.before_gas + tx.transaction.gas_limit() <= before_max_gas { - self.before_gas += tx.transaction.gas_limit(); - return Some(tx); - } - self.before.mark_invalid(tx.signer(), tx.transaction.nonce()); - self.after.mark_invalid(tx.signer(), tx.transaction.nonce()); - } else { - return Some(tx); - } - } - - while let Some(tx) = self.after.next(ctx) { - if let Some(after_max_gas) = self.after_max_gas { - if self.after_gas + tx.transaction.gas_limit() <= after_max_gas { - self.after_gas += tx.transaction.gas_limit(); - return Some(tx); - } - self.after.mark_invalid(tx.signer(), tx.transaction.nonce()); - } else { - return Some(tx); - } - } - - None - } - - fn mark_invalid(&mut self, sender: Address, nonce: u64) { - self.before.mark_invalid(sender, nonce); - self.after.mark_invalid(sender, nonce); - } -} - #[cfg(test)] mod tests { use super::*; @@ -530,6 +404,7 @@ mod tests { Priority, }; use alloy_primitives::U256; + use reth_payload_util::{PayloadTransactionsChain, PayloadTransactionsFixed}; #[test] fn test_best_iter() { diff --git a/crates/transaction-pool/src/pool/mod.rs b/crates/transaction-pool/src/pool/mod.rs index 78cc790e942..6441ed687f2 100644 --- a/crates/transaction-pool/src/pool/mod.rs +++ b/crates/transaction-pool/src/pool/mod.rs @@ -108,7 +108,6 @@ use crate::{ }; pub use best::{ BestPayloadTransactions, BestTransactionFilter, BestTransactionsWithPrioritizedSenders, - PayloadTransactionsChain, PayloadTransactionsFixed, }; pub use blob::{blob_tx_priority, fee_delta}; pub use events::{FullTransactionEvent, TransactionEvent}; diff --git a/crates/transaction-pool/src/traits.rs b/crates/transaction-pool/src/traits.rs index 9b4cccfb9d1..6c247a84cdb 100644 --- a/crates/transaction-pool/src/traits.rs +++ b/crates/transaction-pool/src/traits.rs @@ -1510,24 +1510,6 @@ impl Stream for NewSubpoolTransactionStream { } } -/// Iterator that returns transactions for the block building process in the order they should be -/// included in the block. -/// -/// Can include transactions from the pool and other sources (alternative pools, -/// sequencer-originated transactions, etc.). -pub trait PayloadTransactions { - /// Returns the next transaction to include in the block. - fn next( - &mut self, - // In the future, `ctx` can include access to state for block building purposes. - ctx: (), - ) -> Option; - - /// Exclude descendants of the transaction with given sender and nonce from the iterator, - /// because this transaction won't be included in the block. - fn mark_invalid(&mut self, sender: Address, nonce: u64); -} - #[cfg(test)] mod tests { use super::*; From c160005531347c5745cb34b81f295e8b64a4d25a Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Sat, 16 Nov 2024 05:39:49 +0100 Subject: [PATCH 197/211] rm generics when useless (#12581) --- crates/cli/commands/src/db/checksum.rs | 8 ++++---- crates/cli/commands/src/db/get.rs | 4 ++-- crates/cli/commands/src/db/tui.rs | 2 +- crates/cli/commands/src/import.rs | 2 +- crates/cli/util/src/load_secret_key.rs | 5 +---- crates/cli/util/src/parsers.rs | 8 ++++---- 6 files changed, 13 insertions(+), 16 deletions(-) diff --git a/crates/cli/commands/src/db/checksum.rs b/crates/cli/commands/src/db/checksum.rs index 9aa48e0e865..4c986dc0332 100644 --- a/crates/cli/commands/src/db/checksum.rs +++ b/crates/cli/commands/src/db/checksum.rs @@ -79,17 +79,17 @@ impl TableViewer<(u64, Duration)> for ChecksumViewer<'_, N let mut cursor = tx.cursor_read::>()?; let walker = match (self.start_key.as_deref(), self.end_key.as_deref()) { (Some(start), Some(end)) => { - let start_key = table_key::(start).map(RawKey::::new)?; - let end_key = table_key::(end).map(RawKey::::new)?; + let start_key = table_key::(start).map(RawKey::new)?; + let end_key = table_key::(end).map(RawKey::new)?; cursor.walk_range(start_key..=end_key)? } (None, Some(end)) => { - let end_key = table_key::(end).map(RawKey::::new)?; + let end_key = table_key::(end).map(RawKey::new)?; cursor.walk_range(..=end_key)? } (Some(start), None) => { - let start_key = table_key::(start).map(RawKey::::new)?; + let start_key = table_key::(start).map(RawKey::new)?; cursor.walk_range(start_key..)? } (None, None) => cursor.walk_range(..)?, diff --git a/crates/cli/commands/src/db/get.rs b/crates/cli/commands/src/db/get.rs index 94c0f63dd30..e9fc034519f 100644 --- a/crates/cli/commands/src/db/get.rs +++ b/crates/cli/commands/src/db/get.rs @@ -128,12 +128,12 @@ impl Command { /// Get an instance of key for given table pub(crate) fn table_key(key: &str) -> Result { - serde_json::from_str::(key).map_err(|e| eyre::eyre!(e)) + serde_json::from_str(key).map_err(|e| eyre::eyre!(e)) } /// Get an instance of subkey for given dupsort table fn table_subkey(subkey: Option<&str>) -> Result { - serde_json::from_str::(subkey.unwrap_or_default()).map_err(|e| eyre::eyre!(e)) + serde_json::from_str(subkey.unwrap_or_default()).map_err(|e| eyre::eyre!(e)) } struct GetValueViewer<'a, N: NodeTypesWithDB> { diff --git a/crates/cli/commands/src/db/tui.rs b/crates/cli/commands/src/db/tui.rs index 240ca376970..1a9fae7f891 100644 --- a/crates/cli/commands/src/db/tui.rs +++ b/crates/cli/commands/src/db/tui.rs @@ -365,7 +365,7 @@ where .map(|(i, k)| { ListItem::new(format!("[{:0>width$}]: {k:?}", i + app.skip, width = key_length)) }) - .collect::>>(); + .collect::>(); let key_list = List::new(formatted_keys) .block(Block::default().borders(Borders::ALL).title(format!( diff --git a/crates/cli/commands/src/import.rs b/crates/cli/commands/src/import.rs index a7c81e53052..ebda2deafa6 100644 --- a/crates/cli/commands/src/import.rs +++ b/crates/cli/commands/src/import.rs @@ -203,7 +203,7 @@ where let max_block = file_client.max_block().unwrap_or(0); - let pipeline = Pipeline::::builder() + let pipeline = Pipeline::builder() .with_tip_sender(tip_tx) // we want to sync all blocks the file client provides or 0 if empty .with_max_block(max_block) diff --git a/crates/cli/util/src/load_secret_key.rs b/crates/cli/util/src/load_secret_key.rs index 25da0e06676..8b3bee09c8c 100644 --- a/crates/cli/util/src/load_secret_key.rs +++ b/crates/cli/util/src/load_secret_key.rs @@ -41,10 +41,7 @@ pub fn get_secret_key(secret_key_path: &Path) -> Result { let contents = fs::read_to_string(secret_key_path)?; - Ok(contents - .as_str() - .parse::() - .map_err(SecretKeyError::SecretKeyDecodeError)?) + Ok(contents.as_str().parse().map_err(SecretKeyError::SecretKeyDecodeError)?) } Ok(false) => { if let Some(dir) = secret_key_path.parent() { diff --git a/crates/cli/util/src/parsers.rs b/crates/cli/util/src/parsers.rs index 9bb803bcca8..fb27e1420c0 100644 --- a/crates/cli/util/src/parsers.rs +++ b/crates/cli/util/src/parsers.rs @@ -23,11 +23,11 @@ pub fn parse_duration_from_secs_or_ms( arg: &str, ) -> eyre::Result { if arg.ends_with("ms") { - arg.trim_end_matches("ms").parse::().map(Duration::from_millis) + arg.trim_end_matches("ms").parse().map(Duration::from_millis) } else if arg.ends_with('s') { - arg.trim_end_matches('s').parse::().map(Duration::from_secs) + arg.trim_end_matches('s').parse().map(Duration::from_secs) } else { - arg.parse::().map(Duration::from_secs) + arg.parse().map(Duration::from_secs) } } @@ -75,7 +75,7 @@ pub fn parse_socket_address(value: &str) -> eyre::Result() { + if let Ok(port) = value.parse() { return Ok(SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), port)) } value From 7745046b0b30cbce916606222aadd6de72beb9fa Mon Sep 17 00:00:00 2001 From: Hopium <135053852+Hopium21@users.noreply.github.com> Date: Sat, 16 Nov 2024 05:44:37 +0100 Subject: [PATCH 198/211] Fix grammar in MDBX documentation (#12580) Co-authored-by: Matthias Seitz --- crates/storage/libmdbx-rs/mdbx-sys/libmdbx/man1/mdbx_chk.1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/storage/libmdbx-rs/mdbx-sys/libmdbx/man1/mdbx_chk.1 b/crates/storage/libmdbx-rs/mdbx-sys/libmdbx/man1/mdbx_chk.1 index 7b182325b31..0934fea1c16 100644 --- a/crates/storage/libmdbx-rs/mdbx-sys/libmdbx/man1/mdbx_chk.1 +++ b/crates/storage/libmdbx-rs/mdbx-sys/libmdbx/man1/mdbx_chk.1 @@ -27,7 +27,7 @@ mdbx_chk \- MDBX checking tool .SH DESCRIPTION The .B mdbx_chk -utility intended to check an MDBX database file. +utility is intended to check an MDBX database file. .SH OPTIONS .TP .BR \-V @@ -55,7 +55,7 @@ check, including full check of all meta-pages and actual size of database file. .BR \-w Open environment in read-write mode and lock for writing while checking. This could be impossible if environment already used by another process(s) -in an incompatible read-write mode. This allow rollback to last steady commit +in an incompatible read-write mode. This allows rollback to last steady commit (in case environment was not closed properly) and then check transaction IDs of meta-pages. Otherwise, without \fB\-w\fP option environment will be opened in read-only mode. @@ -90,7 +90,7 @@ then forcibly loads ones by sequential access and tries to lock database pages i .TP .BR \-n Open MDBX environment(s) which do not use subdirectories. -This is legacy option. For now MDBX handles this automatically. +This is a legacy option. For now MDBX handles this automatically. .SH DIAGNOSTICS Exit status is zero if no errors occur. Errors result in a non-zero exit status From 2dc9a063219e7c6f1a61edcba4b0e2b9d97c4aef Mon Sep 17 00:00:00 2001 From: Darshan Kathiriya <8559992+lakshya-sky@users.noreply.github.com> Date: Fri, 15 Nov 2024 23:59:53 -0500 Subject: [PATCH 199/211] chore(sdk): add NetworkPrimitives for NetworkManager (#12530) Co-authored-by: dkathiriya --- Cargo.lock | 1 + crates/net/network/Cargo.toml | 4 +- crates/net/network/src/builder.rs | 5 +- crates/net/network/src/config.rs | 31 ++++++----- crates/net/network/src/eth_requests.rs | 22 ++++---- crates/net/network/src/lib.rs | 7 ++- crates/net/network/src/manager.rs | 51 +++++++++--------- crates/net/network/src/network.rs | 57 ++++++++++---------- crates/net/network/src/transactions/mod.rs | 13 ++--- crates/net/network/tests/it/connect.rs | 9 ++-- crates/net/network/tests/it/startup.rs | 15 +++--- examples/bsc-p2p/src/main.rs | 6 ++- examples/custom-rlpx-subprotocol/src/main.rs | 6 +-- examples/network/src/main.rs | 5 +- examples/polygon-p2p/src/main.rs | 5 +- 15 files changed, 130 insertions(+), 107 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9514d361fbf..973ad471872 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7800,6 +7800,7 @@ dependencies = [ "reth-dns-discovery", "reth-ecies", "reth-eth-wire", + "reth-eth-wire-types", "reth-fs-util", "reth-metrics", "reth-net-banlist", diff --git a/crates/net/network/Cargo.toml b/crates/net/network/Cargo.toml index 09f81e63e54..dde0b4a0b23 100644 --- a/crates/net/network/Cargo.toml +++ b/crates/net/network/Cargo.toml @@ -24,6 +24,7 @@ reth-discv4.workspace = true reth-discv5.workspace = true reth-dns-discovery.workspace = true reth-eth-wire.workspace = true +reth-eth-wire-types.workspace = true reth-ecies.workspace = true reth-tasks.workspace = true reth-transaction-pool.workspace = true @@ -111,6 +112,7 @@ serde = [ "reth-dns-discovery/serde", "reth-eth-wire/serde", "reth-provider?/serde", + "reth-eth-wire-types/serde", "alloy-consensus/serde", "alloy-eips/serde", "alloy-primitives/serde", @@ -118,7 +120,7 @@ serde = [ "parking_lot/serde", "rand/serde", "smallvec/serde", - "url/serde" + "url/serde", ] test-utils = [ "dep:reth-provider", diff --git a/crates/net/network/src/builder.rs b/crates/net/network/src/builder.rs index e6a5d956641..31038906b25 100644 --- a/crates/net/network/src/builder.rs +++ b/crates/net/network/src/builder.rs @@ -1,5 +1,6 @@ //! Builder support for configuring the entire setup. +use reth_eth_wire::{EthNetworkPrimitives, NetworkPrimitives}; use reth_network_api::test_utils::PeersHandleProvider; use reth_transaction_pool::TransactionPool; use tokio::sync::mpsc; @@ -16,8 +17,8 @@ pub(crate) const ETH_REQUEST_CHANNEL_CAPACITY: usize = 256; /// A builder that can configure all components of the network. #[allow(missing_debug_implementations)] -pub struct NetworkBuilder { - pub(crate) network: NetworkManager, +pub struct NetworkBuilder { + pub(crate) network: NetworkManager, pub(crate) transactions: Tx, pub(crate) request_handler: Eth, } diff --git a/crates/net/network/src/config.rs b/crates/net/network/src/config.rs index 96aef249d9f..db7b384c2b3 100644 --- a/crates/net/network/src/config.rs +++ b/crates/net/network/src/config.rs @@ -6,7 +6,9 @@ use reth_chainspec::{ChainSpecProvider, EthChainSpec, Hardforks}; use reth_discv4::{Discv4Config, Discv4ConfigBuilder, NatResolver, DEFAULT_DISCOVERY_ADDRESS}; use reth_discv5::NetworkStackId; use reth_dns_discovery::DnsDiscoveryConfig; -use reth_eth_wire::{HelloMessage, HelloMessageWithProtocols, Status}; +use reth_eth_wire::{ + EthNetworkPrimitives, HelloMessage, HelloMessageWithProtocols, NetworkPrimitives, Status, +}; use reth_network_peers::{mainnet_nodes, pk2id, sepolia_nodes, PeerId, TrustedPeer}; use reth_network_types::{PeersConfig, SessionsConfig}; use reth_primitives::{ForkFilter, Head}; @@ -32,7 +34,7 @@ pub fn rng_secret_key() -> SecretKey { /// All network related initialization settings. #[derive(Debug)] -pub struct NetworkConfig { +pub struct NetworkConfig { /// The client type that can interact with the chain. /// /// This type is used to fetch the block number after we established a session and received the @@ -66,7 +68,7 @@ pub struct NetworkConfig { /// first hardfork, `Frontier` for mainnet. pub fork_filter: ForkFilter, /// The block importer type. - pub block_import: Box, + pub block_import: Box>, /// The default mode of the network. pub network_mode: NetworkMode, /// The executor to use for spawning tasks. @@ -87,9 +89,9 @@ pub struct NetworkConfig { // === impl NetworkConfig === -impl NetworkConfig<()> { +impl NetworkConfig<(), N> { /// Convenience method for creating the corresponding builder type - pub fn builder(secret_key: SecretKey) -> NetworkConfigBuilder { + pub fn builder(secret_key: SecretKey) -> NetworkConfigBuilder { NetworkConfigBuilder::new(secret_key) } @@ -99,7 +101,7 @@ impl NetworkConfig<()> { } } -impl NetworkConfig { +impl NetworkConfig { /// Create a new instance with all mandatory fields set, rest is field with defaults. pub fn new(client: C, secret_key: SecretKey) -> Self where @@ -134,12 +136,13 @@ impl NetworkConfig { } } -impl NetworkConfig +impl NetworkConfig where C: BlockNumReader + 'static, + N: NetworkPrimitives, { /// Convenience method for calling [`NetworkManager::new`]. - pub async fn manager(self) -> Result { + pub async fn manager(self) -> Result, NetworkError> { NetworkManager::new(self).await } } @@ -164,7 +167,7 @@ where /// Builder for [`NetworkConfig`](struct.NetworkConfig.html). #[derive(Debug)] -pub struct NetworkConfigBuilder { +pub struct NetworkConfigBuilder { /// The node's secret key, from which the node's identity is derived. secret_key: SecretKey, /// How to configure discovery over DNS. @@ -196,7 +199,7 @@ pub struct NetworkConfigBuilder { /// Whether tx gossip is disabled tx_gossip_disabled: bool, /// The block importer type - block_import: Option>, + block_import: Option>>, /// How to instantiate transactions manager. transactions_manager_config: TransactionsManagerConfig, /// The NAT resolver for external IP @@ -206,7 +209,7 @@ pub struct NetworkConfigBuilder { // === impl NetworkConfigBuilder === #[allow(missing_docs)] -impl NetworkConfigBuilder { +impl NetworkConfigBuilder { /// Create a new builder instance with a random secret key. pub fn with_rng_secret_key() -> Self { Self::new(rng_secret_key()) @@ -480,7 +483,7 @@ impl NetworkConfigBuilder { } /// Sets the block import type. - pub fn block_import(mut self, block_import: Box) -> Self { + pub fn block_import(mut self, block_import: Box>) -> Self { self.block_import = Some(block_import); self } @@ -490,7 +493,7 @@ impl NetworkConfigBuilder { pub fn build_with_noop_provider( self, chain_spec: Arc, - ) -> NetworkConfig> + ) -> NetworkConfig, N> where ChainSpec: EthChainSpec + Hardforks + 'static, { @@ -509,7 +512,7 @@ impl NetworkConfigBuilder { /// The given client is to be used for interacting with the chain, for example fetching the /// corresponding block for a given block hash we receive from a peer in the status message when /// establishing a connection. - pub fn build(self, client: C) -> NetworkConfig + pub fn build(self, client: C) -> NetworkConfig where C: ChainSpecProvider, { diff --git a/crates/net/network/src/eth_requests.rs b/crates/net/network/src/eth_requests.rs index 1f20be53967..8121b9675ed 100644 --- a/crates/net/network/src/eth_requests.rs +++ b/crates/net/network/src/eth_requests.rs @@ -12,8 +12,8 @@ use alloy_eips::BlockHashOrNumber; use alloy_rlp::Encodable; use futures::StreamExt; use reth_eth_wire::{ - BlockBodies, BlockHeaders, GetBlockBodies, GetBlockHeaders, GetNodeData, GetReceipts, - HeadersDirection, NodeData, Receipts, + BlockBodies, BlockHeaders, EthNetworkPrimitives, GetBlockBodies, GetBlockHeaders, GetNodeData, + GetReceipts, HeadersDirection, NetworkPrimitives, NodeData, Receipts, }; use reth_network_api::test_utils::PeersHandle; use reth_network_p2p::error::RequestResult; @@ -54,7 +54,7 @@ const SOFT_RESPONSE_LIMIT: usize = 2 * 1024 * 1024; /// This can be spawned to another task and is supposed to be run as background service. #[derive(Debug)] #[must_use = "Manager does nothing unless polled."] -pub struct EthRequestHandler { +pub struct EthRequestHandler { /// The client type that can interact with the chain. client: C, /// Used for reporting peers. @@ -62,15 +62,15 @@ pub struct EthRequestHandler { #[allow(dead_code)] peers: PeersHandle, /// Incoming request from the [`NetworkManager`](crate::NetworkManager). - incoming_requests: ReceiverStream, + incoming_requests: ReceiverStream>, /// Metrics for the eth request handler. metrics: EthRequestHandlerMetrics, } // === impl EthRequestHandler === -impl EthRequestHandler { +impl EthRequestHandler { /// Create a new instance - pub fn new(client: C, peers: PeersHandle, incoming: Receiver) -> Self { + pub fn new(client: C, peers: PeersHandle, incoming: Receiver>) -> Self { Self { client, peers, @@ -148,7 +148,7 @@ where &self, _peer_id: PeerId, request: GetBlockHeaders, - response: oneshot::Sender>, + response: oneshot::Sender>>, ) { self.metrics.eth_headers_requests_received_total.increment(1); let headers = self.get_headers_response(request); @@ -159,7 +159,7 @@ where &self, _peer_id: PeerId, request: GetBlockBodies, - response: oneshot::Sender>, + response: oneshot::Sender>>, ) { self.metrics.eth_bodies_requests_received_total.increment(1); let mut bodies = Vec::new(); @@ -272,7 +272,7 @@ where /// All `eth` request related to blocks delegated by the network. #[derive(Debug)] -pub enum IncomingEthRequest { +pub enum IncomingEthRequest { /// Request Block headers from the peer. /// /// The response should be sent through the channel. @@ -282,7 +282,7 @@ pub enum IncomingEthRequest { /// The specific block headers requested. request: GetBlockHeaders, /// The channel sender for the response containing block headers. - response: oneshot::Sender>, + response: oneshot::Sender>>, }, /// Request Block bodies from the peer. /// @@ -293,7 +293,7 @@ pub enum IncomingEthRequest { /// The specific block bodies requested. request: GetBlockBodies, /// The channel sender for the response containing block bodies. - response: oneshot::Sender>, + response: oneshot::Sender>>, }, /// Request Node Data from the peer. /// diff --git a/crates/net/network/src/lib.rs b/crates/net/network/src/lib.rs index 0e433a38862..0eae99e7c50 100644 --- a/crates/net/network/src/lib.rs +++ b/crates/net/network/src/lib.rs @@ -46,7 +46,9 @@ //! //! ``` //! # async fn launch() { -//! use reth_network::{config::rng_secret_key, NetworkConfig, NetworkManager}; +//! use reth_network::{ +//! config::rng_secret_key, EthNetworkPrimitives, NetworkConfig, NetworkManager, +//! }; //! use reth_network_peers::mainnet_nodes; //! use reth_provider::test_utils::NoopProvider; //! @@ -59,7 +61,7 @@ //! let config = NetworkConfig::builder(local_key).boot_nodes(mainnet_nodes()).build(client); //! //! // create the network instance -//! let network = NetworkManager::new(config).await.unwrap(); +//! let network = NetworkManager::::new(config).await.unwrap(); //! //! // keep a handle to the network and spawn it //! let handle = network.handle().clone(); @@ -138,6 +140,7 @@ mod state; mod swarm; pub use reth_eth_wire::{DisconnectReason, HelloMessageWithProtocols}; +pub use reth_eth_wire_types::{EthNetworkPrimitives, NetworkPrimitives}; pub use reth_network_api::{ BlockDownloaderProvider, DiscoveredEvent, DiscoveryEvent, NetworkEvent, NetworkEventListenerProvider, NetworkInfo, PeerRequest, PeerRequestSender, Peers, PeersInfo, diff --git a/crates/net/network/src/manager.rs b/crates/net/network/src/manager.rs index 3a7f94985fc..0738be1bcac 100644 --- a/crates/net/network/src/manager.rs +++ b/crates/net/network/src/manager.rs @@ -29,7 +29,10 @@ use std::{ use futures::{Future, StreamExt}; use parking_lot::Mutex; -use reth_eth_wire::{capability::CapabilityMessage, Capabilities, DisconnectReason}; +use reth_eth_wire::{ + capability::CapabilityMessage, Capabilities, DisconnectReason, EthNetworkPrimitives, + NetworkPrimitives, +}; use reth_fs_util::{self as fs, FsPathError}; use reth_metrics::common::mpsc::UnboundedMeteredSender; use reth_network_api::{ @@ -76,17 +79,17 @@ use crate::{ /// include_mmd!("docs/mermaid/network-manager.mmd") #[derive(Debug)] #[must_use = "The NetworkManager does nothing unless polled"] -pub struct NetworkManager { +pub struct NetworkManager { /// The type that manages the actual network part, which includes connections. - swarm: Swarm, + swarm: Swarm, /// Underlying network handle that can be shared. - handle: NetworkHandle, + handle: NetworkHandle, /// Receiver half of the command channel set up between this type and the [`NetworkHandle`] - from_handle_rx: UnboundedReceiverStream, + from_handle_rx: UnboundedReceiverStream>, /// Handles block imports according to the `eth` protocol. - block_import: Box, + block_import: Box>, /// Sender for high level network events. - event_sender: EventSender, + event_sender: EventSender>>, /// Sender half to send events to the /// [`TransactionsManager`](crate::transactions::TransactionsManager) task, if configured. to_transactions_manager: Option>, @@ -103,7 +106,7 @@ pub struct NetworkManager { /// Thus, we use a bounded channel here to avoid unbounded build up if the node is flooded with /// requests. This channel size is set at /// [`ETH_REQUEST_CHANNEL_CAPACITY`](crate::builder::ETH_REQUEST_CHANNEL_CAPACITY) - to_eth_request_handler: Option>, + to_eth_request_handler: Option>>, /// Tracks the number of active session (connected peers). /// /// This is updated via internal events and shared via `Arc` with the [`NetworkHandle`] @@ -116,7 +119,7 @@ pub struct NetworkManager { } // === impl NetworkManager === -impl NetworkManager { +impl NetworkManager { /// Sets the dedicated channel for events indented for the /// [`TransactionsManager`](crate::transactions::TransactionsManager). pub fn set_transactions(&mut self, tx: mpsc::UnboundedSender) { @@ -126,7 +129,7 @@ impl NetworkManager { /// Sets the dedicated channel for events indented for the /// [`EthRequestHandler`](crate::eth_requests::EthRequestHandler). - pub fn set_eth_request_handler(&mut self, tx: mpsc::Sender) { + pub fn set_eth_request_handler(&mut self, tx: mpsc::Sender>) { self.to_eth_request_handler = Some(tx); } @@ -138,7 +141,7 @@ impl NetworkManager { /// Returns the [`NetworkHandle`] that can be cloned and shared. /// /// The [`NetworkHandle`] can be used to interact with this [`NetworkManager`] - pub const fn handle(&self) -> &NetworkHandle { + pub const fn handle(&self) -> &NetworkHandle { &self.handle } @@ -165,7 +168,7 @@ impl NetworkManager { /// The [`NetworkManager`] is an endless future that needs to be polled in order to advance the /// state of the entire network. pub async fn new( - config: NetworkConfig, + config: NetworkConfig, ) -> Result { let NetworkConfig { client, @@ -253,7 +256,7 @@ impl NetworkManager { let (to_manager_tx, from_handle_rx) = mpsc::unbounded_channel(); - let event_sender: EventSender = Default::default(); + let event_sender: EventSender>> = Default::default(); let handle = NetworkHandle::new( Arc::clone(&num_active_peers), @@ -314,14 +317,14 @@ impl NetworkManager { /// } /// ``` pub async fn builder( - config: NetworkConfig, - ) -> Result, NetworkError> { + config: NetworkConfig, + ) -> Result, NetworkError> { let network = Self::new(config).await?; Ok(network.into_builder()) } /// Create a [`NetworkBuilder`] to configure all components of the network - pub const fn into_builder(self) -> NetworkBuilder<(), ()> { + pub const fn into_builder(self) -> NetworkBuilder<(), (), N> { NetworkBuilder { network: self, transactions: (), request_handler: () } } @@ -369,7 +372,7 @@ impl NetworkManager { /// Returns a new [`FetchClient`] that can be cloned and shared. /// /// The [`FetchClient`] is the entrypoint for sending requests to the network. - pub fn fetch_client(&self) -> FetchClient { + pub fn fetch_client(&self) -> FetchClient { self.swarm.state().fetch_client() } @@ -416,7 +419,7 @@ impl NetworkManager { /// Sends an event to the [`EthRequestManager`](crate::eth_requests::EthRequestHandler) if /// configured. - fn delegate_eth_request(&self, event: IncomingEthRequest) { + fn delegate_eth_request(&self, event: IncomingEthRequest) { if let Some(ref reqs) = self.to_eth_request_handler { let _ = reqs.try_send(event).map_err(|e| { if let TrySendError::Full(_) = e { @@ -428,7 +431,7 @@ impl NetworkManager { } /// Handle an incoming request from the peer - fn on_eth_request(&self, peer_id: PeerId, req: PeerRequest) { + fn on_eth_request(&self, peer_id: PeerId, req: PeerRequest) { match req { PeerRequest::GetBlockHeaders { request, response } => { self.delegate_eth_request(IncomingEthRequest::GetBlockHeaders { @@ -469,7 +472,7 @@ impl NetworkManager { } /// Invoked after a `NewBlock` message from the peer was validated - fn on_block_import_result(&mut self, outcome: BlockImportOutcome) { + fn on_block_import_result(&mut self, outcome: BlockImportOutcome) { let BlockImportOutcome { peer, result } = outcome; match result { Ok(validated_block) => match validated_block { @@ -511,7 +514,7 @@ impl NetworkManager { } /// Handles a received Message from the peer's session. - fn on_peer_message(&mut self, peer_id: PeerId, msg: PeerMessage) { + fn on_peer_message(&mut self, peer_id: PeerId, msg: PeerMessage) { match msg { PeerMessage::NewBlockHashes(hashes) => { self.within_pow_or_disconnect(peer_id, |this| { @@ -551,7 +554,7 @@ impl NetworkManager { } /// Handler for received messages from a handle - fn on_handle_message(&mut self, msg: NetworkHandleMessage) { + fn on_handle_message(&mut self, msg: NetworkHandleMessage) { match msg { NetworkHandleMessage::DiscoveryListener(tx) => { self.swarm.state_mut().discovery_mut().add_listener(tx); @@ -646,7 +649,7 @@ impl NetworkManager { } } - fn on_swarm_event(&mut self, event: SwarmEvent) { + fn on_swarm_event(&mut self, event: SwarmEvent) { // handle event match event { SwarmEvent::ValidMessage { peer_id, message } => self.on_peer_message(peer_id, message), @@ -981,7 +984,7 @@ impl NetworkManager { } } -impl Future for NetworkManager { +impl Future for NetworkManager { type Output = (); fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { diff --git a/crates/net/network/src/network.rs b/crates/net/network/src/network.rs index 4175757e0cf..1715fa63e2f 100644 --- a/crates/net/network/src/network.rs +++ b/crates/net/network/src/network.rs @@ -11,7 +11,10 @@ use enr::Enr; use parking_lot::Mutex; use reth_discv4::{Discv4, NatResolver}; use reth_discv5::Discv5; -use reth_eth_wire::{DisconnectReason, NewBlock, NewPooledTransactionHashes, SharedTransactions}; +use reth_eth_wire::{ + DisconnectReason, EthNetworkPrimitives, NetworkPrimitives, NewBlock, + NewPooledTransactionHashes, SharedTransactions, +}; use reth_network_api::{ test_utils::{PeersHandle, PeersHandleProvider}, BlockDownloaderProvider, DiscoveryEvent, NetworkError, NetworkEvent, @@ -39,20 +42,20 @@ use crate::{ /// /// See also [`NetworkManager`](crate::NetworkManager). #[derive(Clone, Debug)] -pub struct NetworkHandle { +pub struct NetworkHandle { /// The Arc'ed delegate that contains the state. - inner: Arc, + inner: Arc>, } // === impl NetworkHandle === -impl NetworkHandle { +impl NetworkHandle { /// Creates a single new instance. #[allow(clippy::too_many_arguments)] pub(crate) fn new( num_active_peers: Arc, listener_address: Arc>, - to_manager_tx: UnboundedSender, + to_manager_tx: UnboundedSender>, secret_key: SecretKey, local_peer_id: PeerId, peers: PeersHandle, @@ -61,7 +64,7 @@ impl NetworkHandle { tx_gossip_disabled: bool, discv4: Option, discv5: Option, - event_sender: EventSender, + event_sender: EventSender>>, nat: Option, ) -> Self { let inner = NetworkInner { @@ -89,7 +92,7 @@ impl NetworkHandle { &self.inner.local_peer_id } - fn manager(&self) -> &UnboundedSender { + fn manager(&self) -> &UnboundedSender> { &self.inner.to_manager_tx } @@ -99,7 +102,7 @@ impl NetworkHandle { } /// Sends a [`NetworkHandleMessage`] to the manager - pub(crate) fn send_message(&self, msg: NetworkHandleMessage) { + pub(crate) fn send_message(&self, msg: NetworkHandleMessage) { let _ = self.inner.to_manager_tx.send(msg); } @@ -113,12 +116,12 @@ impl NetworkHandle { /// Caution: in `PoS` this is a noop because new blocks are no longer announced over devp2p. /// Instead they are sent to the node by CL and can be requested over devp2p. /// Broadcasting new blocks is considered a protocol violation. - pub fn announce_block(&self, block: NewBlock, hash: B256) { + pub fn announce_block(&self, block: NewBlock, hash: B256) { self.send_message(NetworkHandleMessage::AnnounceBlock(block, hash)) } /// Sends a [`PeerRequest`] to the given peer's session. - pub fn send_request(&self, peer_id: PeerId, request: PeerRequest) { + pub fn send_request(&self, peer_id: PeerId, request: PeerRequest) { self.send_message(NetworkHandleMessage::EthRequest { peer_id, request }) } @@ -186,8 +189,8 @@ impl NetworkHandle { // === API Implementations === -impl NetworkEventListenerProvider for NetworkHandle { - fn event_listener(&self) -> EventStream { +impl NetworkEventListenerProvider for NetworkHandle { + fn event_listener(&self) -> EventStream>> { self.inner.event_sender.new_listener() } @@ -198,13 +201,13 @@ impl NetworkEventListenerProvider for NetworkHandle { } } -impl NetworkProtocols for NetworkHandle { +impl NetworkProtocols for NetworkHandle { fn add_rlpx_sub_protocol(&self, protocol: RlpxSubProtocol) { self.send_message(NetworkHandleMessage::AddRlpxSubProtocol(protocol)) } } -impl PeersInfo for NetworkHandle { +impl PeersInfo for NetworkHandle { fn num_connected_peers(&self) -> usize { self.inner.num_active_peers.load(Ordering::Relaxed) } @@ -337,13 +340,13 @@ impl Peers for NetworkHandle { } } -impl PeersHandleProvider for NetworkHandle { +impl PeersHandleProvider for NetworkHandle { fn peers_handle(&self) -> &PeersHandle { &self.inner.peers } } -impl NetworkInfo for NetworkHandle { +impl NetworkInfo for NetworkHandle { fn local_addr(&self) -> SocketAddr { *self.inner.listener_address.lock() } @@ -367,7 +370,7 @@ impl NetworkInfo for NetworkHandle { } } -impl SyncStateProvider for NetworkHandle { +impl SyncStateProvider for NetworkHandle { fn is_syncing(&self) -> bool { self.inner.is_syncing.load(Ordering::Relaxed) } @@ -380,7 +383,7 @@ impl SyncStateProvider for NetworkHandle { } } -impl NetworkSyncUpdater for NetworkHandle { +impl NetworkSyncUpdater for NetworkHandle { fn update_sync_state(&self, state: SyncState) { let future_state = state.is_syncing(); let prev_state = self.inner.is_syncing.swap(future_state, Ordering::Relaxed); @@ -396,8 +399,8 @@ impl NetworkSyncUpdater for NetworkHandle { } } -impl BlockDownloaderProvider for NetworkHandle { - type Client = FetchClient; +impl BlockDownloaderProvider for NetworkHandle { + type Client = FetchClient; async fn fetch_client(&self) -> Result { let (tx, rx) = oneshot::channel(); @@ -407,11 +410,11 @@ impl BlockDownloaderProvider for NetworkHandle { } #[derive(Debug)] -struct NetworkInner { +struct NetworkInner { /// Number of active peer sessions the node's currently handling. num_active_peers: Arc, /// Sender half of the message channel to the [`crate::NetworkManager`]. - to_manager_tx: UnboundedSender, + to_manager_tx: UnboundedSender>, /// The local address that accepts incoming connections. listener_address: Arc>, /// The secret key used for authenticating sessions. @@ -435,7 +438,7 @@ struct NetworkInner { /// The instance of the discv5 service discv5: Option, /// Sender for high level network events. - event_sender: EventSender, + event_sender: EventSender>>, /// The NAT resolver nat: Option, } @@ -448,7 +451,7 @@ pub trait NetworkProtocols: Send + Sync { /// Internal messages that can be passed to the [`NetworkManager`](crate::NetworkManager). #[derive(Debug)] -pub(crate) enum NetworkHandleMessage { +pub(crate) enum NetworkHandleMessage { /// Marks a peer as trusted. AddTrustedPeerId(PeerId), /// Adds an address for a peer, including its ID, kind, and socket address. @@ -458,7 +461,7 @@ pub(crate) enum NetworkHandleMessage { /// Disconnects a connection to a peer if it exists, optionally providing a disconnect reason. DisconnectPeer(PeerId, Option), /// Broadcasts an event to announce a new block to all nodes. - AnnounceBlock(NewBlock, B256), + AnnounceBlock(NewBlock, B256), /// Sends a list of transactions to the given peer. SendTransaction { /// The ID of the peer to which the transactions are sent. @@ -478,12 +481,12 @@ pub(crate) enum NetworkHandleMessage { /// The peer to send the request to. peer_id: PeerId, /// The request to send to the peer's sessions. - request: PeerRequest, + request: PeerRequest, }, /// Applies a reputation change to the given peer. ReputationChange(PeerId, ReputationChangeKind), /// Returns the client that can be used to interact with the network. - FetchClient(oneshot::Sender), + FetchClient(oneshot::Sender>), /// Applies a status update. StatusUpdate { /// The head status to apply. diff --git a/crates/net/network/src/transactions/mod.rs b/crates/net/network/src/transactions/mod.rs index 4e23c8527b4..48ae61e0dd0 100644 --- a/crates/net/network/src/transactions/mod.rs +++ b/crates/net/network/src/transactions/mod.rs @@ -34,9 +34,10 @@ use std::{ use alloy_primitives::{TxHash, B256}; use futures::{stream::FuturesUnordered, Future, StreamExt}; use reth_eth_wire::{ - DedupPayload, EthVersion, GetPooledTransactions, HandleMempoolData, HandleVersionedMempoolData, - NewPooledTransactionHashes, NewPooledTransactionHashes66, NewPooledTransactionHashes68, - PooledTransactions, RequestTxHashes, Transactions, + DedupPayload, EthNetworkPrimitives, EthVersion, GetPooledTransactions, HandleMempoolData, + HandleVersionedMempoolData, NetworkPrimitives, NewPooledTransactionHashes, + NewPooledTransactionHashes66, NewPooledTransactionHashes68, PooledTransactions, + RequestTxHashes, Transactions, }; use reth_metrics::common::mpsc::UnboundedMeteredReceiver; use reth_network_api::{ @@ -200,15 +201,15 @@ impl TransactionsHandle { /// propagate new transactions over the network. #[derive(Debug)] #[must_use = "Manager does nothing unless polled."] -pub struct TransactionsManager { +pub struct TransactionsManager { /// Access to the transaction pool. pool: Pool, /// Network access. - network: NetworkHandle, + network: NetworkHandle, /// Subscriptions to all network related events. /// /// From which we get all new incoming transaction related messages. - network_events: EventStream, + network_events: EventStream>>, /// Transaction fetcher to handle inflight and missing transaction requests. transaction_fetcher: TransactionFetcher, /// All currently pending transactions grouped by peers. diff --git a/crates/net/network/tests/it/connect.rs b/crates/net/network/tests/it/connect.rs index ec891e5b39a..0a17cbd563e 100644 --- a/crates/net/network/tests/it/connect.rs +++ b/crates/net/network/tests/it/connect.rs @@ -8,7 +8,7 @@ use alloy_provider::{ext::AdminApi, ProviderBuilder}; use futures::StreamExt; use reth_chainspec::MAINNET; use reth_discv4::Discv4Config; -use reth_eth_wire::{DisconnectReason, HeadersDirection}; +use reth_eth_wire::{DisconnectReason, EthNetworkPrimitives, HeadersDirection}; use reth_net_banlist::BanList; use reth_network::{ test_utils::{enr_to_peer_id, NetworkEventStream, PeerConfig, Testnet, GETH_TIMEOUT}, @@ -204,8 +204,9 @@ async fn test_connect_with_boot_nodes() { let mut discv4 = Discv4Config::builder(); discv4.add_boot_nodes(mainnet_nodes()); - let config = - NetworkConfigBuilder::new(secret_key).discovery(discv4).build(NoopProvider::default()); + let config = NetworkConfigBuilder::::new(secret_key) + .discovery(discv4) + .build(NoopProvider::default()); let network = NetworkManager::new(config).await.unwrap(); let handle = network.handle().clone(); @@ -572,7 +573,7 @@ async fn test_disconnect_incoming_when_exceeded_incoming_connections() { let secret_key = SecretKey::new(&mut rand::thread_rng()); let peers_config = PeersConfig::default().with_max_inbound(0); - let config = NetworkConfigBuilder::new(secret_key) + let config = NetworkConfigBuilder::::new(secret_key) .listener_port(0) .disable_discovery() .peer_config(peers_config) diff --git a/crates/net/network/tests/it/startup.rs b/crates/net/network/tests/it/startup.rs index d84ff492e5e..862281ab1ff 100644 --- a/crates/net/network/tests/it/startup.rs +++ b/crates/net/network/tests/it/startup.rs @@ -5,6 +5,7 @@ use std::{ use reth_chainspec::MAINNET; use reth_discv4::{Discv4Config, NatResolver}; +use reth_eth_wire::EthNetworkPrimitives; use reth_network::{ error::{NetworkError, ServiceKind}, Discovery, NetworkConfigBuilder, NetworkManager, @@ -26,7 +27,7 @@ fn is_addr_in_use_kind(err: &NetworkError, kind: ServiceKind) -> bool { #[tokio::test(flavor = "multi_thread")] async fn test_is_default_syncing() { let secret_key = SecretKey::new(&mut rand::thread_rng()); - let config = NetworkConfigBuilder::new(secret_key) + let config = NetworkConfigBuilder::::new(secret_key) .disable_discovery() .listener_port(0) .build(NoopProvider::default()); @@ -37,13 +38,13 @@ async fn test_is_default_syncing() { #[tokio::test(flavor = "multi_thread")] async fn test_listener_addr_in_use() { let secret_key = SecretKey::new(&mut rand::thread_rng()); - let config = NetworkConfigBuilder::new(secret_key) + let config = NetworkConfigBuilder::::new(secret_key) .disable_discovery() .listener_port(0) .build(NoopProvider::default()); let network = NetworkManager::new(config).await.unwrap(); let listener_port = network.local_addr().port(); - let config = NetworkConfigBuilder::new(secret_key) + let config = NetworkConfigBuilder::::new(secret_key) .listener_port(listener_port) .disable_discovery() .build(NoopProvider::default()); @@ -72,7 +73,7 @@ async fn test_discovery_addr_in_use() { #[tokio::test(flavor = "multi_thread")] async fn test_tcp_port_node_record_no_discovery() { let secret_key = SecretKey::new(&mut rand::thread_rng()); - let config = NetworkConfigBuilder::new(secret_key) + let config = NetworkConfigBuilder::::new(secret_key) .listener_port(0) .disable_discovery() .build_with_noop_provider(MAINNET.clone()); @@ -90,7 +91,7 @@ async fn test_tcp_port_node_record_no_discovery() { #[tokio::test(flavor = "multi_thread")] async fn test_tcp_port_node_record_discovery() { let secret_key = SecretKey::new(&mut rand::thread_rng()); - let config = NetworkConfigBuilder::new(secret_key) + let config = NetworkConfigBuilder::::new(secret_key) .listener_port(0) .discovery_port(0) .disable_dns_discovery() @@ -109,7 +110,7 @@ async fn test_tcp_port_node_record_discovery() { #[tokio::test(flavor = "multi_thread")] async fn test_node_record_address_with_nat() { let secret_key = SecretKey::new(&mut rand::thread_rng()); - let config = NetworkConfigBuilder::new(secret_key) + let config = NetworkConfigBuilder::::new(secret_key) .add_nat(Some(NatResolver::ExternalIp("10.1.1.1".parse().unwrap()))) .disable_discv4_discovery() .disable_dns_discovery() @@ -125,7 +126,7 @@ async fn test_node_record_address_with_nat() { #[tokio::test(flavor = "multi_thread")] async fn test_node_record_address_with_nat_disable_discovery() { let secret_key = SecretKey::new(&mut rand::thread_rng()); - let config = NetworkConfigBuilder::new(secret_key) + let config = NetworkConfigBuilder::::new(secret_key) .add_nat(Some(NatResolver::ExternalIp("10.1.1.1".parse().unwrap()))) .disable_discovery() .listener_port(0) diff --git a/examples/bsc-p2p/src/main.rs b/examples/bsc-p2p/src/main.rs index e46ea4bec35..9e83f34e92f 100644 --- a/examples/bsc-p2p/src/main.rs +++ b/examples/bsc-p2p/src/main.rs @@ -14,7 +14,9 @@ use chainspec::{boot_nodes, bsc_chain_spec}; use reth_discv4::Discv4ConfigBuilder; -use reth_network::{NetworkConfig, NetworkEvent, NetworkEventListenerProvider, NetworkManager}; +use reth_network::{ + EthNetworkPrimitives, NetworkConfig, NetworkEvent, NetworkEventListenerProvider, NetworkManager, +}; use reth_network_api::PeersInfo; use reth_primitives::{ForkHash, ForkId}; use reth_tracing::{ @@ -62,7 +64,7 @@ async fn main() { // latest BSC forkId, we need to override this to allow connections from BSC nodes let fork_id = ForkId { hash: ForkHash([0x07, 0xb5, 0x43, 0x28]), next: 0 }; net_cfg.fork_filter.set_current_fork_id(fork_id); - let net_manager = NetworkManager::new(net_cfg).await.unwrap(); + let net_manager = NetworkManager::::new(net_cfg).await.unwrap(); // The network handle is our entrypoint into the network. let net_handle = net_manager.handle().clone(); diff --git a/examples/custom-rlpx-subprotocol/src/main.rs b/examples/custom-rlpx-subprotocol/src/main.rs index e16f71071c8..702d0e8cf5e 100644 --- a/examples/custom-rlpx-subprotocol/src/main.rs +++ b/examples/custom-rlpx-subprotocol/src/main.rs @@ -14,8 +14,8 @@ use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; use reth::builder::NodeHandle; use reth_network::{ - config::SecretKey, protocol::IntoRlpxSubProtocol, NetworkConfig, NetworkManager, - NetworkProtocols, + config::SecretKey, protocol::IntoRlpxSubProtocol, EthNetworkPrimitives, NetworkConfig, + NetworkManager, NetworkProtocols, }; use reth_network_api::{test_utils::PeersHandleProvider, NetworkInfo}; use reth_node_ethereum::EthereumNode; @@ -53,7 +53,7 @@ fn main() -> eyre::Result<()> { .build_with_noop_provider(node.chain_spec()); // spawn the second network instance - let subnetwork = NetworkManager::new(net_cfg).await?; + let subnetwork = NetworkManager::::new(net_cfg).await?; let subnetwork_peer_id = *subnetwork.peer_id(); let subnetwork_peer_addr = subnetwork.local_addr(); let subnetwork_handle = subnetwork.peers_handle(); diff --git a/examples/network/src/main.rs b/examples/network/src/main.rs index 1d8f436f318..bd4f232a754 100644 --- a/examples/network/src/main.rs +++ b/examples/network/src/main.rs @@ -8,7 +8,8 @@ use futures::StreamExt; use reth_network::{ - config::rng_secret_key, NetworkConfig, NetworkEventListenerProvider, NetworkManager, + config::rng_secret_key, EthNetworkPrimitives, NetworkConfig, NetworkEventListenerProvider, + NetworkManager, }; use reth_provider::test_utils::NoopProvider; @@ -24,7 +25,7 @@ async fn main() -> eyre::Result<()> { let config = NetworkConfig::builder(local_key).mainnet_boot_nodes().build(client); // create the network instance - let network = NetworkManager::new(config).await?; + let network = NetworkManager::::new(config).await?; // get a handle to the network to interact with it let handle = network.handle().clone(); diff --git a/examples/polygon-p2p/src/main.rs b/examples/polygon-p2p/src/main.rs index 6078ae14cb8..bcc17a24f8d 100644 --- a/examples/polygon-p2p/src/main.rs +++ b/examples/polygon-p2p/src/main.rs @@ -12,7 +12,8 @@ use chain_cfg::{boot_nodes, head, polygon_chain_spec}; use reth_discv4::Discv4ConfigBuilder; use reth_network::{ - config::NetworkMode, NetworkConfig, NetworkEvent, NetworkEventListenerProvider, NetworkManager, + config::NetworkMode, EthNetworkPrimitives, NetworkConfig, NetworkEvent, + NetworkEventListenerProvider, NetworkManager, }; use reth_tracing::{ tracing::info, tracing_subscriber::filter::LevelFilter, LayerInfo, LogFormat, RethTracer, @@ -57,7 +58,7 @@ async fn main() { discv4_cfg.add_boot_nodes(boot_nodes()).lookup_interval(interval); let net_cfg = net_cfg.set_discovery_v4(discv4_cfg.build()); - let net_manager = NetworkManager::new(net_cfg).await.unwrap(); + let net_manager = NetworkManager::::new(net_cfg).await.unwrap(); // The network handle is our entrypoint into the network. let net_handle = net_manager.handle(); From fc97a0cbaf8f4a2a1a864dc61f1b247c08c0dea4 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sat, 16 Nov 2024 06:04:39 +0100 Subject: [PATCH 200/211] chore: make clippy happy (#12594) --- crates/cli/commands/src/common.rs | 2 +- crates/engine/primitives/src/forkchoice.rs | 6 +++--- .../net/eth-wire/tests/pooled_transactions.rs | 5 +---- crates/node/builder/src/launch/common.rs | 2 +- crates/optimism/rpc/src/eth/call.rs | 2 +- .../prune/src/segments/static_file/headers.rs | 2 +- crates/prune/types/src/limiter.rs | 4 ++-- crates/revm/src/batch.rs | 6 +++--- crates/rpc/rpc-builder/src/lib.rs | 6 +++--- crates/rpc/rpc-eth-api/src/helpers/call.rs | 2 +- crates/stages/api/src/pipeline/mod.rs | 4 ++-- crates/storage/db/src/metrics.rs | 2 +- crates/storage/db/src/static_file/mod.rs | 2 +- .../src/providers/static_file/manager.rs | 2 +- crates/transaction-pool/src/pool/txpool.rs | 4 ++-- crates/trie/sparse/src/state.rs | 2 +- crates/trie/sparse/src/trie.rs | 6 +++--- crates/trie/trie/src/forward_cursor.rs | 2 +- .../trie/trie/src/hashed_cursor/post_state.rs | 16 +++++++------- crates/trie/trie/src/node_iter.rs | 2 +- crates/trie/trie/src/trie_cursor/in_memory.rs | 21 ++++++++++--------- crates/trie/trie/src/trie_cursor/subnode.rs | 2 +- crates/trie/trie/src/walker.rs | 4 ++-- crates/trie/trie/src/witness.rs | 4 ++-- 24 files changed, 54 insertions(+), 56 deletions(-) diff --git a/crates/cli/commands/src/common.rs b/crates/cli/commands/src/common.rs index 3a9cbaa7fbb..21d24a7ff7a 100644 --- a/crates/cli/commands/src/common.rs +++ b/crates/cli/commands/src/common.rs @@ -111,7 +111,7 @@ impl> Environmen db: Arc, static_file_provider: StaticFileProvider, ) -> eyre::Result>>> { - let has_receipt_pruning = config.prune.as_ref().map_or(false, |a| a.has_receipts_pruning()); + let has_receipt_pruning = config.prune.as_ref().is_some_and(|a| a.has_receipts_pruning()); let prune_modes = config.prune.as_ref().map(|prune| prune.segments.clone()).unwrap_or_default(); let factory = ProviderFactory::>>::new( diff --git a/crates/engine/primitives/src/forkchoice.rs b/crates/engine/primitives/src/forkchoice.rs index 3c70b78ecdd..9d680d5a124 100644 --- a/crates/engine/primitives/src/forkchoice.rs +++ b/crates/engine/primitives/src/forkchoice.rs @@ -47,19 +47,19 @@ impl ForkchoiceStateTracker { /// Returns whether the latest received FCU is valid: [`ForkchoiceStatus::Valid`] #[allow(dead_code)] pub(crate) fn is_latest_valid(&self) -> bool { - self.latest_status().map_or(false, |s| s.is_valid()) + self.latest_status().is_some_and(|s| s.is_valid()) } /// Returns whether the latest received FCU is syncing: [`ForkchoiceStatus::Syncing`] #[allow(dead_code)] pub(crate) fn is_latest_syncing(&self) -> bool { - self.latest_status().map_or(false, |s| s.is_syncing()) + self.latest_status().is_some_and(|s| s.is_syncing()) } /// Returns whether the latest received FCU is syncing: [`ForkchoiceStatus::Invalid`] #[allow(dead_code)] pub fn is_latest_invalid(&self) -> bool { - self.latest_status().map_or(false, |s| s.is_invalid()) + self.latest_status().is_some_and(|s| s.is_invalid()) } /// Returns the last valid head hash. diff --git a/crates/net/eth-wire/tests/pooled_transactions.rs b/crates/net/eth-wire/tests/pooled_transactions.rs index 22c5fcc3329..3b17d04cba5 100644 --- a/crates/net/eth-wire/tests/pooled_transactions.rs +++ b/crates/net/eth-wire/tests/pooled_transactions.rs @@ -12,10 +12,7 @@ use test_fuzz::test_fuzz; #[test_fuzz] fn roundtrip_pooled_transactions(hex_data: Vec) -> Result<(), alloy_rlp::Error> { let input_rlp = &mut &hex_data[..]; - let txs: PooledTransactions = match PooledTransactions::decode(input_rlp) { - Ok(txs) => txs, - Err(e) => return Err(e), - }; + let txs: PooledTransactions = PooledTransactions::decode(input_rlp)?; // get the amount of bytes decoded in `decode` by subtracting the length of the original buf, // from the length of the remaining bytes diff --git a/crates/node/builder/src/launch/common.rs b/crates/node/builder/src/launch/common.rs index 7e6571135f0..972fdc640df 100644 --- a/crates/node/builder/src/launch/common.rs +++ b/crates/node/builder/src/launch/common.rs @@ -416,7 +416,7 @@ where .with_static_files_metrics(); let has_receipt_pruning = - self.toml_config().prune.as_ref().map_or(false, |a| a.has_receipts_pruning()); + self.toml_config().prune.as_ref().is_some_and(|a| a.has_receipts_pruning()); // Check for consistency between database and static files. If it fails, it unwinds to // the first block that's consistent between database and static files. diff --git a/crates/optimism/rpc/src/eth/call.rs b/crates/optimism/rpc/src/eth/call.rs index 9b19c488889..ea0086aedfd 100644 --- a/crates/optimism/rpc/src/eth/call.rs +++ b/crates/optimism/rpc/src/eth/call.rs @@ -48,7 +48,7 @@ where request: TransactionRequest, ) -> Result { // Ensure that if versioned hashes are set, they're not empty - if request.blob_versioned_hashes.as_ref().map_or(false, |hashes| hashes.is_empty()) { + if request.blob_versioned_hashes.as_ref().is_some_and(|hashes| hashes.is_empty()) { return Err(RpcInvalidTransactionError::BlobTransactionMissingBlobHashes.into_eth_err()) } diff --git a/crates/prune/prune/src/segments/static_file/headers.rs b/crates/prune/prune/src/segments/static_file/headers.rs index ea0264261af..5cd6f62643a 100644 --- a/crates/prune/prune/src/segments/static_file/headers.rs +++ b/crates/prune/prune/src/segments/static_file/headers.rs @@ -91,7 +91,7 @@ impl> Segment bool { - self.deleted_entries_limit.as_ref().map_or(false, |limit| limit.is_limit_reached()) + self.deleted_entries_limit.as_ref().is_some_and(|limit| limit.is_limit_reached()) } /// Increments the number of deleted entries by the given number. @@ -112,7 +112,7 @@ impl PruneLimiter { /// Returns `true` if time limit is reached. pub fn is_time_limit_reached(&self) -> bool { - self.time_limit.as_ref().map_or(false, |limit| limit.is_limit_reached()) + self.time_limit.as_ref().is_some_and(|limit| limit.is_limit_reached()) } /// Returns `true` if any limit is reached. diff --git a/crates/revm/src/batch.rs b/crates/revm/src/batch.rs index ddb88505b8d..15ba049250f 100644 --- a/crates/revm/src/batch.rs +++ b/crates/revm/src/batch.rs @@ -106,11 +106,11 @@ impl BlockBatchRecord { !self .prune_modes .account_history - .map_or(false, |mode| mode.should_prune(block_number, tip)) && + .is_some_and(|mode| mode.should_prune(block_number, tip)) && !self .prune_modes .storage_history - .map_or(false, |mode| mode.should_prune(block_number, tip)) + .is_some_and(|mode| mode.should_prune(block_number, tip)) }) { BundleRetention::Reverts } else { @@ -143,7 +143,7 @@ impl BlockBatchRecord { // Block receipts should not be retained if self.prune_modes.receipts == Some(PruneMode::Full) || // [`PruneSegment::Receipts`] takes priority over [`PruneSegment::ContractLogs`] - self.prune_modes.receipts.map_or(false, |mode| mode.should_prune(block_number, tip)) + self.prune_modes.receipts.is_some_and(|mode| mode.should_prune(block_number, tip)) { receipts.clear(); return Ok(()) diff --git a/crates/rpc/rpc-builder/src/lib.rs b/crates/rpc/rpc-builder/src/lib.rs index 8af60bda187..ab68d3c88e4 100644 --- a/crates/rpc/rpc-builder/src/lib.rs +++ b/crates/rpc/rpc-builder/src/lib.rs @@ -1941,17 +1941,17 @@ impl TransportRpcModuleConfig { /// Returns true if the given module is configured for the http transport. pub fn contains_http(&self, module: &RethRpcModule) -> bool { - self.http.as_ref().map_or(false, |http| http.contains(module)) + self.http.as_ref().is_some_and(|http| http.contains(module)) } /// Returns true if the given module is configured for the ws transport. pub fn contains_ws(&self, module: &RethRpcModule) -> bool { - self.ws.as_ref().map_or(false, |ws| ws.contains(module)) + self.ws.as_ref().is_some_and(|ws| ws.contains(module)) } /// Returns true if the given module is configured for the ipc transport. pub fn contains_ipc(&self, module: &RethRpcModule) -> bool { - self.ipc.as_ref().map_or(false, |ipc| ipc.contains(module)) + self.ipc.as_ref().is_some_and(|ipc| ipc.contains(module)) } /// Ensures that both http and ws are configured and that they are configured to use the same diff --git a/crates/rpc/rpc-eth-api/src/helpers/call.rs b/crates/rpc/rpc-eth-api/src/helpers/call.rs index e45590d4264..d614018a407 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/call.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/call.rs @@ -690,7 +690,7 @@ pub trait Call: LoadState> + SpawnBlocking { request: TransactionRequest, ) -> Result { // Ensure that if versioned hashes are set, they're not empty - if request.blob_versioned_hashes.as_ref().map_or(false, |hashes| hashes.is_empty()) { + if request.blob_versioned_hashes.as_ref().is_some_and(|hashes| hashes.is_empty()) { return Err(RpcInvalidTransactionError::BlobTransactionMissingBlobHashes.into_eth_err()) } diff --git a/crates/stages/api/src/pipeline/mod.rs b/crates/stages/api/src/pipeline/mod.rs index bcf857fbac8..39d26cd8808 100644 --- a/crates/stages/api/src/pipeline/mod.rs +++ b/crates/stages/api/src/pipeline/mod.rs @@ -177,7 +177,7 @@ impl Pipeline { self.progress .minimum_block_number .zip(self.max_block) - .map_or(false, |(progress, target)| progress >= target) + .is_some_and(|(progress, target)| progress >= target) { trace!( target: "sync::pipeline", @@ -393,7 +393,7 @@ impl Pipeline { let stage_reached_max_block = prev_checkpoint .zip(self.max_block) - .map_or(false, |(prev_progress, target)| prev_progress.block_number >= target); + .is_some_and(|(prev_progress, target)| prev_progress.block_number >= target); if stage_reached_max_block { warn!( target: "sync::pipeline", diff --git a/crates/storage/db/src/metrics.rs b/crates/storage/db/src/metrics.rs index fecd691ee5d..2d908c68156 100644 --- a/crates/storage/db/src/metrics.rs +++ b/crates/storage/db/src/metrics.rs @@ -347,7 +347,7 @@ impl OperationMetrics { // Record duration only for large values to prevent the performance hit of clock syscall // on small operations - if value_size.map_or(false, |size| size > LARGE_VALUE_THRESHOLD_BYTES) { + if value_size.is_some_and(|size| size > LARGE_VALUE_THRESHOLD_BYTES) { let start = Instant::now(); let result = f(); self.large_value_duration_seconds.record(start.elapsed()); diff --git a/crates/storage/db/src/static_file/mod.rs b/crates/storage/db/src/static_file/mod.rs index f27a574f640..071835f566b 100644 --- a/crates/storage/db/src/static_file/mod.rs +++ b/crates/storage/db/src/static_file/mod.rs @@ -38,7 +38,7 @@ pub fn iter_static_files(path: impl AsRef) -> Result>(); for entry in entries { - if entry.metadata().map_or(false, |metadata| metadata.is_file()) { + if entry.metadata().is_ok_and(|metadata| metadata.is_file()) { if let Some((segment, _)) = StaticFileSegment::parse_filename(&entry.file_name().to_string_lossy()) { diff --git a/crates/storage/provider/src/providers/static_file/manager.rs b/crates/storage/provider/src/providers/static_file/manager.rs index 8f6a6957502..bee42fdac83 100644 --- a/crates/storage/provider/src/providers/static_file/manager.rs +++ b/crates/storage/provider/src/providers/static_file/manager.rs @@ -1107,7 +1107,7 @@ impl StaticFileProvider { }; if static_file_upper_bound - .map_or(false, |static_file_upper_bound| static_file_upper_bound >= number) + .is_some_and(|static_file_upper_bound| static_file_upper_bound >= number) { return fetch_from_static_file(self) } diff --git a/crates/transaction-pool/src/pool/txpool.rs b/crates/transaction-pool/src/pool/txpool.rs index 3d72d6a9f15..040deb15fcb 100644 --- a/crates/transaction-pool/src/pool/txpool.rs +++ b/crates/transaction-pool/src/pool/txpool.rs @@ -318,7 +318,7 @@ impl TxPool { // blob pool that are valid with the lower blob fee if best_transactions_attributes .blob_fee - .map_or(false, |fee| fee < self.all_transactions.pending_fees.blob_fee as u64) + .is_some_and(|fee| fee < self.all_transactions.pending_fees.blob_fee as u64) { let unlocked_by_blob_fee = self.blob_pool.satisfy_attributes(best_transactions_attributes); @@ -1446,7 +1446,7 @@ impl AllTransactions { fn contains_conflicting_transaction(&self, tx: &ValidPoolTransaction) -> bool { self.txs_iter(tx.transaction_id.sender) .next() - .map_or(false, |(_, existing)| tx.tx_type_conflicts_with(&existing.transaction)) + .is_some_and(|(_, existing)| tx.tx_type_conflicts_with(&existing.transaction)) } /// Additional checks for a new transaction. diff --git a/crates/trie/sparse/src/state.rs b/crates/trie/sparse/src/state.rs index 126e05e8582..d7557a7a365 100644 --- a/crates/trie/sparse/src/state.rs +++ b/crates/trie/sparse/src/state.rs @@ -32,7 +32,7 @@ impl SparseStateTrie { /// Returns `true` if storage slot for account was already revealed. pub fn is_storage_slot_revealed(&self, account: &B256, slot: &B256) -> bool { - self.revealed.get(account).map_or(false, |slots| slots.contains(slot)) + self.revealed.get(account).is_some_and(|slots| slots.contains(slot)) } /// Reveal unknown trie paths from provided leaf path and its proof for the account. diff --git a/crates/trie/sparse/src/trie.rs b/crates/trie/sparse/src/trie.rs index 9db1dff5313..696934d3edb 100644 --- a/crates/trie/sparse/src/trie.rs +++ b/crates/trie/sparse/src/trie.rs @@ -529,7 +529,7 @@ impl RevealedSparseTrie { let unset_branch_nibble = self .nodes .get(&child_path) - .map_or(false, move |node| match node { + .is_some_and(move |node| match node { SparseNode::Leaf { key, .. } => { // Get full path of the leaf node child_path.extend_from_slice_unchecked(key); @@ -665,7 +665,7 @@ impl RevealedSparseTrie { child_path.extend_from_slice_unchecked(key); if let Some(hash) = hash.filter(|_| !prefix_set_contains(&path)) { RlpNode::word_rlp(&hash) - } else if buffers.rlp_node_stack.last().map_or(false, |e| e.0 == child_path) { + } else if buffers.rlp_node_stack.last().is_some_and(|e| e.0 == child_path) { let (_, child) = buffers.rlp_node_stack.pop().unwrap(); self.rlp_buf.clear(); let rlp_node = ExtensionNodeRef::new(key, &child).rlp(&mut self.rlp_buf); @@ -699,7 +699,7 @@ impl RevealedSparseTrie { .resize(buffers.branch_child_buf.len(), Default::default()); let mut added_children = false; for (i, child_path) in buffers.branch_child_buf.iter().enumerate() { - if buffers.rlp_node_stack.last().map_or(false, |e| &e.0 == child_path) { + if buffers.rlp_node_stack.last().is_some_and(|e| &e.0 == child_path) { let (_, child) = buffers.rlp_node_stack.pop().unwrap(); // Insert children in the resulting buffer in a normal order, because // initially we iterated in reverse. diff --git a/crates/trie/trie/src/forward_cursor.rs b/crates/trie/trie/src/forward_cursor.rs index 6db214bb51a..745fc351b90 100644 --- a/crates/trie/trie/src/forward_cursor.rs +++ b/crates/trie/trie/src/forward_cursor.rs @@ -30,7 +30,7 @@ where /// exhausted. Returns the first entry for which `comparator` returns `false` or `None`. fn advance_while_false(&mut self, comparator: impl Fn(&K) -> bool) -> Option<(K, V)> { let mut entry = self.entries.get(self.index); - while entry.map_or(false, |entry| comparator(&entry.0)) { + while entry.is_some_and(|entry| comparator(&entry.0)) { self.index += 1; entry = self.entries.get(self.index); } diff --git a/crates/trie/trie/src/hashed_cursor/post_state.rs b/crates/trie/trie/src/hashed_cursor/post_state.rs index 67891419152..7521bb1b2bc 100644 --- a/crates/trie/trie/src/hashed_cursor/post_state.rs +++ b/crates/trie/trie/src/hashed_cursor/post_state.rs @@ -82,14 +82,14 @@ where // It's an exact match, return the account from post state without looking up in the // database. - if post_state_entry.map_or(false, |entry| entry.0 == key) { + if post_state_entry.is_some_and(|entry| entry.0 == key) { return Ok(post_state_entry) } // It's not an exact match, reposition to the first greater or equal account that wasn't // cleared. let mut db_entry = self.cursor.seek(key)?; - while db_entry.as_ref().map_or(false, |(address, _)| self.is_account_cleared(address)) { + while db_entry.as_ref().is_some_and(|(address, _)| self.is_account_cleared(address)) { db_entry = self.cursor.next()?; } @@ -103,7 +103,7 @@ where // If post state was given precedence or account was cleared, move the cursor forward. let mut db_entry = self.cursor.seek(last_account)?; - while db_entry.as_ref().map_or(false, |(address, _)| { + while db_entry.as_ref().is_some_and(|(address, _)| { address <= &last_account || self.is_account_cleared(address) }) { db_entry = self.cursor.next()?; @@ -200,14 +200,14 @@ where let post_state_cursor = post_state_storage.map(|s| ForwardInMemoryCursor::new(&s.non_zero_valued_slots)); let cleared_slots = post_state_storage.map(|s| &s.zero_valued_slots); - let storage_wiped = post_state_storage.map_or(false, |s| s.wiped); + let storage_wiped = post_state_storage.is_some_and(|s| s.wiped); Self { cursor, post_state_cursor, cleared_slots, storage_wiped, last_slot: None } } /// Check if the slot was zeroed out in the post state. /// The database is not checked since it already has no zero-valued slots. fn is_slot_zero_valued(&self, slot: &B256) -> bool { - self.cleared_slots.map_or(false, |s| s.contains(slot)) + self.cleared_slots.is_some_and(|s| s.contains(slot)) } /// Find the storage entry in post state or database that's greater or equal to provided subkey. @@ -217,14 +217,14 @@ where // If database storage was wiped or it's an exact match, // return the storage slot from post state without looking up in the database. - if self.storage_wiped || post_state_entry.map_or(false, |entry| entry.0 == subkey) { + if self.storage_wiped || post_state_entry.is_some_and(|entry| entry.0 == subkey) { return Ok(post_state_entry) } // It's not an exact match and storage was not wiped, // reposition to the first greater or equal account. let mut db_entry = self.cursor.seek(subkey)?; - while db_entry.as_ref().map_or(false, |entry| self.is_slot_zero_valued(&entry.0)) { + while db_entry.as_ref().is_some_and(|entry| self.is_slot_zero_valued(&entry.0)) { db_entry = self.cursor.next()?; } @@ -248,7 +248,7 @@ where let mut db_entry = self.cursor.seek(last_slot)?; while db_entry .as_ref() - .map_or(false, |entry| entry.0 == last_slot || self.is_slot_zero_valued(&entry.0)) + .is_some_and(|entry| entry.0 == last_slot || self.is_slot_zero_valued(&entry.0)) { db_entry = self.cursor.next()?; } diff --git a/crates/trie/trie/src/node_iter.rs b/crates/trie/trie/src/node_iter.rs index feebe36e16e..60219eedd7c 100644 --- a/crates/trie/trie/src/node_iter.rs +++ b/crates/trie/trie/src/node_iter.rs @@ -106,7 +106,7 @@ where if let Some((hashed_key, value)) = self.current_hashed_entry.take() { // If the walker's key is less than the unpacked hashed key, // reset the checked status and continue - if self.walker.key().map_or(false, |key| key < &Nibbles::unpack(hashed_key)) { + if self.walker.key().is_some_and(|key| key < &Nibbles::unpack(hashed_key)) { self.current_walker_key_checked = false; continue } diff --git a/crates/trie/trie/src/trie_cursor/in_memory.rs b/crates/trie/trie/src/trie_cursor/in_memory.rs index 851670f4267..4a34fd31ad1 100644 --- a/crates/trie/trie/src/trie_cursor/in_memory.rs +++ b/crates/trie/trie/src/trie_cursor/in_memory.rs @@ -79,13 +79,13 @@ impl<'a, C: TrieCursor> InMemoryAccountTrieCursor<'a, C> { exact: bool, ) -> Result, DatabaseError> { let in_memory = self.in_memory_cursor.seek(&key); - if exact && in_memory.as_ref().map_or(false, |entry| entry.0 == key) { + if exact && in_memory.as_ref().is_some_and(|entry| entry.0 == key) { return Ok(in_memory) } // Reposition the cursor to the first greater or equal node that wasn't removed. let mut db_entry = self.cursor.seek(key.clone())?; - while db_entry.as_ref().map_or(false, |entry| self.removed_nodes.contains(&entry.0)) { + while db_entry.as_ref().is_some_and(|entry| self.removed_nodes.contains(&entry.0)) { db_entry = self.cursor.next()?; } @@ -105,7 +105,7 @@ impl<'a, C: TrieCursor> InMemoryAccountTrieCursor<'a, C> { let mut db_entry = self.cursor.seek(last.clone())?; while db_entry .as_ref() - .map_or(false, |entry| entry.0 < last || self.removed_nodes.contains(&entry.0)) + .is_some_and(|entry| entry.0 < last || self.removed_nodes.contains(&entry.0)) { db_entry = self.cursor.next()?; } @@ -184,7 +184,7 @@ impl<'a, C> InMemoryStorageTrieCursor<'a, C> { ) -> Self { let in_memory_cursor = updates.map(|u| ForwardInMemoryCursor::new(&u.storage_nodes)); let removed_nodes = updates.map(|u| &u.removed_nodes); - let storage_trie_cleared = updates.map_or(false, |u| u.is_deleted); + let storage_trie_cleared = updates.is_some_and(|u| u.is_deleted); Self { hashed_address, cursor, @@ -204,16 +204,17 @@ impl InMemoryStorageTrieCursor<'_, C> { ) -> Result, DatabaseError> { let in_memory = self.in_memory_cursor.as_mut().and_then(|c| c.seek(&key)); if self.storage_trie_cleared || - (exact && in_memory.as_ref().map_or(false, |entry| entry.0 == key)) + (exact && in_memory.as_ref().is_some_and(|entry| entry.0 == key)) { return Ok(in_memory.filter(|(nibbles, _)| !exact || nibbles == &key)) } // Reposition the cursor to the first greater or equal node that wasn't removed. let mut db_entry = self.cursor.seek(key.clone())?; - while db_entry.as_ref().map_or(false, |entry| { - self.removed_nodes.as_ref().map_or(false, |r| r.contains(&entry.0)) - }) { + while db_entry + .as_ref() + .is_some_and(|entry| self.removed_nodes.as_ref().is_some_and(|r| r.contains(&entry.0))) + { db_entry = self.cursor.next()?; } @@ -234,8 +235,8 @@ impl InMemoryStorageTrieCursor<'_, C> { // Reposition the cursor to the first greater or equal node that wasn't removed. let mut db_entry = self.cursor.seek(last.clone())?; - while db_entry.as_ref().map_or(false, |entry| { - entry.0 < last || self.removed_nodes.as_ref().map_or(false, |r| r.contains(&entry.0)) + while db_entry.as_ref().is_some_and(|entry| { + entry.0 < last || self.removed_nodes.as_ref().is_some_and(|r| r.contains(&entry.0)) }) { db_entry = self.cursor.next()?; } diff --git a/crates/trie/trie/src/trie_cursor/subnode.rs b/crates/trie/trie/src/trie_cursor/subnode.rs index 9d5a2770b26..c928028eb15 100644 --- a/crates/trie/trie/src/trie_cursor/subnode.rs +++ b/crates/trie/trie/src/trie_cursor/subnode.rs @@ -89,7 +89,7 @@ impl CursorSubNode { /// Returns `true` if the current nibble has a root hash. pub fn hash_flag(&self) -> bool { - self.node.as_ref().map_or(false, |node| match self.nibble { + self.node.as_ref().is_some_and(|node| match self.nibble { // This guy has it -1 => node.root_hash.is_some(), // Or get it from the children diff --git a/crates/trie/trie/src/walker.rs b/crates/trie/trie/src/walker.rs index aaff293b379..774fa64a0ef 100644 --- a/crates/trie/trie/src/walker.rs +++ b/crates/trie/trie/src/walker.rs @@ -88,7 +88,7 @@ impl TrieWalker { /// Indicates whether the children of the current node are present in the trie. pub fn children_are_in_trie(&self) -> bool { - self.stack.last().map_or(false, |n| n.tree_flag()) + self.stack.last().is_some_and(|n| n.tree_flag()) } /// Returns the next unprocessed key in the trie. @@ -112,7 +112,7 @@ impl TrieWalker { self.can_skip_current_node = self .stack .last() - .map_or(false, |node| !self.changes.contains(node.full_key()) && node.hash_flag()); + .is_some_and(|node| !self.changes.contains(node.full_key()) && node.hash_flag()); } } diff --git a/crates/trie/trie/src/witness.rs b/crates/trie/trie/src/witness.rs index 39d82a7bda7..8290f158062 100644 --- a/crates/trie/trie/src/witness.rs +++ b/crates/trie/trie/src/witness.rs @@ -292,7 +292,7 @@ where let mut keys = trie_nodes.keys().peekable(); let mut ignored = HashSet::::default(); while let Some(key) = keys.next() { - if keys.peek().map_or(false, |next| next.starts_with(key)) { + if keys.peek().is_some_and(|next| next.starts_with(key)) { ignored.insert(key.clone()); } } @@ -306,7 +306,7 @@ where if hash_builder.key.starts_with(&parent_branch_path) || trie_nodes .peek() - .map_or(false, |next| next.0.starts_with(&parent_branch_path)) + .is_some_and(|next| next.0.starts_with(&parent_branch_path)) { hash_builder.add_branch(path, branch_hash, false); } else { From e182df71a1150231dc4e2ecf89395a68b644c748 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Sat, 16 Nov 2024 06:25:02 +0100 Subject: [PATCH 201/211] chore(sdk): Remove duplicate trait `BlockHeader` (#12584) --- crates/primitives-traits/src/header/mod.rs | 64 ------------------- crates/primitives-traits/src/header/sealed.rs | 9 +-- 2 files changed, 5 insertions(+), 68 deletions(-) diff --git a/crates/primitives-traits/src/header/mod.rs b/crates/primitives-traits/src/header/mod.rs index ecd5725838e..b36a74471ff 100644 --- a/crates/primitives-traits/src/header/mod.rs +++ b/crates/primitives-traits/src/header/mod.rs @@ -7,72 +7,8 @@ pub use error::HeaderError; #[cfg(any(test, feature = "test-utils", feature = "arbitrary"))] pub mod test_utils; -use alloy_consensus::Header; -use alloy_primitives::{Address, BlockNumber, B256, U256}; - /// Bincode-compatible header type serde implementations. #[cfg(feature = "serde-bincode-compat")] pub mod serde_bincode_compat { pub use super::sealed::serde_bincode_compat::SealedHeader; } - -/// Trait for extracting specific Ethereum block data from a header -pub trait BlockHeader { - /// Retrieves the beneficiary (miner) of the block - fn beneficiary(&self) -> Address; - - /// Retrieves the difficulty of the block - fn difficulty(&self) -> U256; - - /// Retrieves the block number - fn number(&self) -> BlockNumber; - - /// Retrieves the gas limit of the block - fn gas_limit(&self) -> u64; - - /// Retrieves the timestamp of the block - fn timestamp(&self) -> u64; - - /// Retrieves the mix hash of the block - fn mix_hash(&self) -> B256; - - /// Retrieves the base fee per gas of the block, if available - fn base_fee_per_gas(&self) -> Option; - - /// Retrieves the excess blob gas of the block, if available - fn excess_blob_gas(&self) -> Option; -} - -impl BlockHeader for Header { - fn beneficiary(&self) -> Address { - self.beneficiary - } - - fn difficulty(&self) -> U256 { - self.difficulty - } - - fn number(&self) -> BlockNumber { - self.number - } - - fn gas_limit(&self) -> u64 { - self.gas_limit - } - - fn timestamp(&self) -> u64 { - self.timestamp - } - - fn mix_hash(&self) -> B256 { - self.mix_hash - } - - fn base_fee_per_gas(&self) -> Option { - self.base_fee_per_gas - } - - fn excess_blob_gas(&self) -> Option { - self.excess_blob_gas - } -} diff --git a/crates/primitives-traits/src/header/sealed.rs b/crates/primitives-traits/src/header/sealed.rs index dab54977c51..f4a365e1512 100644 --- a/crates/primitives-traits/src/header/sealed.rs +++ b/crates/primitives-traits/src/header/sealed.rs @@ -1,15 +1,16 @@ -use super::Header; -use crate::InMemorySize; -use alloy_consensus::Sealed; +use core::mem; + +use alloy_consensus::{Header, Sealed}; use alloy_eips::BlockNumHash; use alloy_primitives::{keccak256, BlockHash, Sealable, B256}; use alloy_rlp::{Decodable, Encodable}; use bytes::BufMut; -use core::mem; use derive_more::{AsRef, Deref}; use reth_codecs::add_arbitrary_tests; use serde::{Deserialize, Serialize}; +use crate::InMemorySize; + /// A helper struct to store the block number/hash and its parent hash. #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct BlockWithParent { From 3614a37ff6e7cf08c5015f0af866d68618d05649 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Sat, 16 Nov 2024 10:08:25 +0100 Subject: [PATCH 202/211] test(tx-pool): add more unit tests for parked pool (#12591) --- crates/transaction-pool/src/pool/parked.rs | 142 +++++++++++++++++++++ 1 file changed, 142 insertions(+) diff --git a/crates/transaction-pool/src/pool/parked.rs b/crates/transaction-pool/src/pool/parked.rs index 407f04fd5be..29216af47d0 100644 --- a/crates/transaction-pool/src/pool/parked.rs +++ b/crates/transaction-pool/src/pool/parked.rs @@ -916,4 +916,146 @@ mod tests { SenderTransactionCount { count: 1, last_submission_id: 3 } ); } + + #[test] + fn test_pool_size() { + let mut f = MockTransactionFactory::default(); + let mut pool = ParkedPool::>::default(); + + // Create a transaction with a specific size and add it to the pool + let tx = f.validated_arc(MockTransaction::eip1559().set_size(1024).clone()); + pool.add_transaction(tx); + + // Assert that the reported size of the pool is correct + assert_eq!(pool.size(), 1024); + } + + #[test] + fn test_pool_len() { + let mut f = MockTransactionFactory::default(); + let mut pool = ParkedPool::>::default(); + + // Initially, the pool should have zero transactions + assert_eq!(pool.len(), 0); + + // Add a transaction to the pool and check the length + let tx = f.validated_arc(MockTransaction::eip1559()); + pool.add_transaction(tx); + assert_eq!(pool.len(), 1); + } + + #[test] + fn test_pool_contains() { + let mut f = MockTransactionFactory::default(); + let mut pool = ParkedPool::>::default(); + + // Create a transaction and get its ID + let tx = f.validated_arc(MockTransaction::eip1559()); + let tx_id = *tx.id(); + + // Before adding, the transaction should not be in the pool + assert!(!pool.contains(&tx_id)); + + // After adding, the transaction should be present in the pool + pool.add_transaction(tx); + assert!(pool.contains(&tx_id)); + } + + #[test] + fn test_get_transaction() { + let mut f = MockTransactionFactory::default(); + let mut pool = ParkedPool::>::default(); + + // Add a transaction to the pool and get its ID + let tx = f.validated_arc(MockTransaction::eip1559()); + let tx_id = *tx.id(); + pool.add_transaction(tx.clone()); + + // Retrieve the transaction using `get()` and assert it matches the added transaction + let retrieved = pool.get(&tx_id).expect("Transaction should exist in the pool"); + assert_eq!(retrieved.transaction.id(), tx.id()); + } + + #[test] + fn test_all_transactions() { + let mut f = MockTransactionFactory::default(); + let mut pool = ParkedPool::>::default(); + + // Add two transactions to the pool + let tx1 = f.validated_arc(MockTransaction::eip1559()); + let tx2 = f.validated_arc(MockTransaction::eip1559()); + pool.add_transaction(tx1.clone()); + pool.add_transaction(tx2.clone()); + + // Collect all transaction IDs from the pool + let all_txs: Vec<_> = pool.all().map(|tx| *tx.id()).collect(); + assert_eq!(all_txs.len(), 2); + + // Check that the IDs of both transactions are present + assert!(all_txs.contains(tx1.id())); + assert!(all_txs.contains(tx2.id())); + } + + #[test] + fn test_truncate_pool_edge_case() { + let mut f = MockTransactionFactory::default(); + let mut pool = ParkedPool::>::default(); + + // Add two transactions to the pool + let tx1 = f.validated_arc(MockTransaction::eip1559()); + let tx2 = f.validated_arc(MockTransaction::eip1559()); + pool.add_transaction(tx1); + pool.add_transaction(tx2); + + // Set a limit that matches the current number of transactions + let limit = SubPoolLimit { max_txs: 2, max_size: usize::MAX }; + let removed = pool.truncate_pool(limit); + + // No transactions should be removed + assert!(removed.is_empty()); + + // Set a stricter limit that requires truncating one transaction + let limit = SubPoolLimit { max_txs: 1, max_size: usize::MAX }; + let removed = pool.truncate_pool(limit); + + // One transaction should be removed, and the pool should have one left + assert_eq!(removed.len(), 1); + assert_eq!(pool.len(), 1); + } + + #[test] + fn test_satisfy_base_fee_transactions() { + let mut f = MockTransactionFactory::default(); + let mut pool = ParkedPool::>::default(); + + // Add two transactions with different max fees + let tx1 = f.validated_arc(MockTransaction::eip1559().set_max_fee(100).clone()); + let tx2 = f.validated_arc(MockTransaction::eip1559().set_max_fee(200).clone()); + pool.add_transaction(tx1); + pool.add_transaction(tx2.clone()); + + // Check that only the second transaction satisfies the base fee requirement + let satisfied = pool.satisfy_base_fee_transactions(150); + assert_eq!(satisfied.len(), 1); + assert_eq!(satisfied[0].id(), tx2.id()) + } + + #[test] + fn test_remove_transaction() { + let mut f = MockTransactionFactory::default(); + let mut pool = ParkedPool::>::default(); + + // Add a transaction to the pool and get its ID + let tx = f.validated_arc(MockTransaction::eip1559()); + let tx_id = *tx.id(); + pool.add_transaction(tx); + + // Ensure the transaction is in the pool before removal + assert!(pool.contains(&tx_id)); + + // Remove the transaction and check that it is no longer in the pool + let removed = pool.remove_transaction(&tx_id); + assert!(removed.is_some()); + assert!(!pool.contains(&tx_id)); + } } From 1945cd8b425c1a90f6be6cdeabdc0a1cfa250203 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sat, 16 Nov 2024 10:37:14 +0100 Subject: [PATCH 203/211] chore: move hashing writer trait (#12597) --- crates/storage/provider/src/traits/mod.rs | 3 --- .../{provider/src/traits => storage-api/src}/hashing.rs | 0 crates/storage/storage-api/src/lib.rs | 2 ++ 3 files changed, 2 insertions(+), 3 deletions(-) rename crates/storage/{provider/src/traits => storage-api/src}/hashing.rs (100%) diff --git a/crates/storage/provider/src/traits/mod.rs b/crates/storage/provider/src/traits/mod.rs index 5542ea168ab..dce9dd77bc2 100644 --- a/crates/storage/provider/src/traits/mod.rs +++ b/crates/storage/provider/src/traits/mod.rs @@ -17,9 +17,6 @@ pub use state::{StateChangeWriter, StateWriter}; pub use reth_chainspec::ChainSpecProvider; -mod hashing; -pub use hashing::HashingWriter; - mod trie; pub use trie::{StorageTrieWriter, TrieWriter}; diff --git a/crates/storage/provider/src/traits/hashing.rs b/crates/storage/storage-api/src/hashing.rs similarity index 100% rename from crates/storage/provider/src/traits/hashing.rs rename to crates/storage/storage-api/src/hashing.rs diff --git a/crates/storage/storage-api/src/lib.rs b/crates/storage/storage-api/src/lib.rs index 13a44b482a6..7b7ad761476 100644 --- a/crates/storage/storage-api/src/lib.rs +++ b/crates/storage/storage-api/src/lib.rs @@ -60,5 +60,7 @@ pub mod noop; mod history; pub use history::*; +mod hashing; +pub use hashing::*; mod stats; pub use stats::*; From d52c7194d122e5940692e6ff63dd01448bc70b0a Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sat, 16 Nov 2024 11:32:56 +0100 Subject: [PATCH 204/211] chore: move triewriter trait (#12598) --- crates/storage/provider/src/traits/mod.rs | 3 -- crates/storage/provider/src/traits/trie.rs | 36 ---------------------- crates/storage/storage-api/src/trie.rs | 34 ++++++++++++++++++-- 3 files changed, 32 insertions(+), 41 deletions(-) delete mode 100644 crates/storage/provider/src/traits/trie.rs diff --git a/crates/storage/provider/src/traits/mod.rs b/crates/storage/provider/src/traits/mod.rs index dce9dd77bc2..69f053936bb 100644 --- a/crates/storage/provider/src/traits/mod.rs +++ b/crates/storage/provider/src/traits/mod.rs @@ -17,9 +17,6 @@ pub use state::{StateChangeWriter, StateWriter}; pub use reth_chainspec::ChainSpecProvider; -mod trie; -pub use trie::{StorageTrieWriter, TrieWriter}; - mod static_file_provider; pub use static_file_provider::StaticFileProviderFactory; diff --git a/crates/storage/provider/src/traits/trie.rs b/crates/storage/provider/src/traits/trie.rs deleted file mode 100644 index 2edb4e072dd..00000000000 --- a/crates/storage/provider/src/traits/trie.rs +++ /dev/null @@ -1,36 +0,0 @@ -use std::collections::HashMap; - -use alloy_primitives::B256; -use auto_impl::auto_impl; -use reth_storage_errors::provider::ProviderResult; -use reth_trie::updates::{StorageTrieUpdates, TrieUpdates}; - -/// Trie Writer -#[auto_impl(&, Arc, Box)] -pub trait TrieWriter: Send + Sync { - /// Writes trie updates to the database. - /// - /// Returns the number of entries modified. - fn write_trie_updates(&self, trie_updates: &TrieUpdates) -> ProviderResult; -} - -/// Storage Trie Writer -#[auto_impl(&, Arc, Box)] -pub trait StorageTrieWriter: Send + Sync { - /// Writes storage trie updates from the given storage trie map. - /// - /// First sorts the storage trie updates by the hashed address key, writing in sorted order. - /// - /// Returns the number of entries modified. - fn write_storage_trie_updates( - &self, - storage_tries: &HashMap, - ) -> ProviderResult; - - /// Writes storage trie updates for the given hashed address. - fn write_individual_storage_trie_updates( - &self, - hashed_address: B256, - updates: &StorageTrieUpdates, - ) -> ProviderResult; -} diff --git a/crates/storage/storage-api/src/trie.rs b/crates/storage/storage-api/src/trie.rs index f7d41066d06..c8f12da0716 100644 --- a/crates/storage/storage-api/src/trie.rs +++ b/crates/storage/storage-api/src/trie.rs @@ -4,8 +4,8 @@ use alloy_primitives::{ }; use reth_storage_errors::provider::ProviderResult; use reth_trie::{ - updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, StorageProof, - TrieInput, + updates::{StorageTrieUpdates, TrieUpdates}, + AccountProof, HashedPostState, HashedStorage, MultiProof, StorageProof, TrieInput, }; /// A type that can compute the state root of a given post state. @@ -85,3 +85,33 @@ pub trait StateProofProvider: Send + Sync { target: HashedPostState, ) -> ProviderResult>; } + +/// Trie Writer +#[auto_impl::auto_impl(&, Arc, Box)] +pub trait TrieWriter: Send + Sync { + /// Writes trie updates to the database. + /// + /// Returns the number of entries modified. + fn write_trie_updates(&self, trie_updates: &TrieUpdates) -> ProviderResult; +} + +/// Storage Trie Writer +#[auto_impl::auto_impl(&, Arc, Box)] +pub trait StorageTrieWriter: Send + Sync { + /// Writes storage trie updates from the given storage trie map. + /// + /// First sorts the storage trie updates by the hashed address key, writing in sorted order. + /// + /// Returns the number of entries modified. + fn write_storage_trie_updates( + &self, + storage_tries: &std::collections::HashMap, + ) -> ProviderResult; + + /// Writes storage trie updates for the given hashed address. + fn write_individual_storage_trie_updates( + &self, + hashed_address: B256, + updates: &StorageTrieUpdates, + ) -> ProviderResult; +} From d9ed07a367f593605b76e9360c7e8711c6f7c041 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sat, 16 Nov 2024 11:33:09 +0100 Subject: [PATCH 205/211] chore: remove revm-primitives re-export (#12599) --- Cargo.lock | 3 ++- .../src/commands/debug_cmd/build_block.rs | 10 +++++--- crates/blockchain-tree/src/blockchain_tree.rs | 2 +- crates/ethereum/evm/src/lib.rs | 2 +- crates/ethereum/payload/Cargo.toml | 1 - crates/ethereum/payload/src/lib.rs | 7 +++--- crates/node/builder/Cargo.toml | 1 + crates/node/builder/src/builder/mod.rs | 15 ++++++------ crates/optimism/evm/src/lib.rs | 16 ++++++------- crates/optimism/payload/src/builder.rs | 11 ++++----- crates/optimism/rpc/src/error.rs | 2 +- crates/optimism/rpc/src/eth/call.rs | 5 ++-- crates/optimism/rpc/src/eth/pending_block.rs | 6 ++--- crates/payload/primitives/Cargo.toml | 2 ++ crates/payload/primitives/src/error.rs | 2 +- crates/primitives/src/lib.rs | 1 - crates/primitives/src/receipt.rs | 3 +-- crates/revm/src/cached.rs | 2 +- crates/rpc/rpc-eth-api/src/helpers/call.rs | 12 ++++++---- .../rpc/rpc-eth-api/src/helpers/estimate.rs | 9 ++++---- .../rpc-eth-api/src/helpers/pending_block.rs | 23 +++++++++---------- crates/rpc/rpc-eth-types/src/error/mod.rs | 2 +- crates/rpc/rpc/src/eth/bundle.rs | 23 ++++++++----------- crates/rpc/rpc/src/eth/sim_bundle.rs | 6 ++--- crates/trie/db/src/state.rs | 3 +-- .../custom-beacon-withdrawals/src/main.rs | 12 ++++------ examples/custom-evm/src/main.rs | 8 ++----- examples/stateful-precompile/src/main.rs | 10 ++++---- 28 files changed, 94 insertions(+), 105 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 973ad471872..2b6ea4f3431 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7463,7 +7463,6 @@ dependencies = [ "reth-transaction-pool", "reth-trie", "revm", - "revm-primitives", "tracing", ] @@ -8001,6 +8000,7 @@ dependencies = [ "reth-tokio-util", "reth-tracing", "reth-transaction-pool", + "revm-primitives", "secp256k1", "tempfile", "tokio", @@ -8482,6 +8482,7 @@ dependencies = [ "reth-errors", "reth-primitives", "reth-transaction-pool", + "revm-primitives", "serde", "thiserror 1.0.69", "tokio", diff --git a/bin/reth/src/commands/debug_cmd/build_block.rs b/bin/reth/src/commands/debug_cmd/build_block.rs index 30af4c61c53..89eca6b776f 100644 --- a/bin/reth/src/commands/debug_cmd/build_block.rs +++ b/bin/reth/src/commands/debug_cmd/build_block.rs @@ -27,14 +27,18 @@ use reth_node_api::{ }; use reth_node_ethereum::{EthEvmConfig, EthExecutorProvider}; use reth_primitives::{ - revm_primitives::KzgSettings, BlobTransaction, PooledTransactionsElement, SealedBlock, - SealedBlockWithSenders, SealedHeader, Transaction, TransactionSigned, + BlobTransaction, PooledTransactionsElement, SealedBlock, SealedBlockWithSenders, SealedHeader, + Transaction, TransactionSigned, }; use reth_provider::{ providers::BlockchainProvider, BlockHashReader, BlockReader, BlockWriter, ChainSpecProvider, ProviderFactory, StageCheckpointReader, StateProviderFactory, }; -use reth_revm::{cached::CachedReads, database::StateProviderDatabase, primitives::EnvKzgSettings}; +use reth_revm::{ + cached::CachedReads, + database::StateProviderDatabase, + primitives::{EnvKzgSettings, KzgSettings}, +}; use reth_stages::StageId; use reth_transaction_pool::{ blobstore::InMemoryBlobStore, BlobStore, EthPooledTransaction, PoolConfig, TransactionOrigin, diff --git a/crates/blockchain-tree/src/blockchain_tree.rs b/crates/blockchain-tree/src/blockchain_tree.rs index c48e1548434..1a8a390e99d 100644 --- a/crates/blockchain-tree/src/blockchain_tree.rs +++ b/crates/blockchain-tree/src/blockchain_tree.rs @@ -1388,7 +1388,6 @@ mod tests { use reth_evm_ethereum::execute::EthExecutorProvider; use reth_primitives::{ proofs::{calculate_receipt_root, calculate_transaction_root}, - revm_primitives::AccountInfo, Account, BlockBody, Transaction, TransactionSigned, TransactionSignedEcRecovered, }; use reth_provider::{ @@ -1398,6 +1397,7 @@ mod tests { }, ProviderFactory, }; + use reth_revm::primitives::AccountInfo; use reth_stages_api::StageCheckpoint; use reth_trie::{root::state_root_unhashed, StateRoot}; use std::collections::HashMap; diff --git a/crates/ethereum/evm/src/lib.rs b/crates/ethereum/evm/src/lib.rs index 11e4acd4bfc..c8ed58df03b 100644 --- a/crates/ethereum/evm/src/lib.rs +++ b/crates/ethereum/evm/src/lib.rs @@ -201,10 +201,10 @@ mod tests { use alloy_primitives::{B256, U256}; use reth_chainspec::{Chain, ChainSpec, MAINNET}; use reth_evm::execute::ProviderError; - use reth_primitives::revm_primitives::{BlockEnv, CfgEnv, SpecId}; use reth_revm::{ db::{CacheDB, EmptyDBTyped}, inspectors::NoOpInspector, + primitives::{BlockEnv, CfgEnv, SpecId}, JournaledState, }; use revm_primitives::{CfgEnvWithHandlerCfg, EnvWithHandlerCfg, HandlerCfg}; diff --git a/crates/ethereum/payload/Cargo.toml b/crates/ethereum/payload/Cargo.toml index 443e837b2ed..a29cc473362 100644 --- a/crates/ethereum/payload/Cargo.toml +++ b/crates/ethereum/payload/Cargo.toml @@ -30,7 +30,6 @@ reth-chainspec.workspace = true # ethereum revm.workspace = true -revm-primitives.workspace = true # alloy alloy-eips.workspace = true diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index c94cd8bb728..7d795c510e2 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -26,7 +26,6 @@ use reth_payload_builder::{EthBuiltPayload, EthPayloadBuilderAttributes}; use reth_payload_primitives::{PayloadBuilderAttributes, PayloadBuilderError}; use reth_primitives::{ proofs::{self}, - revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg}, Block, BlockBody, EthereumHardforks, Receipt, }; use reth_provider::{ChainSpecProvider, StateProviderFactory}; @@ -38,10 +37,12 @@ use reth_transaction_pool::{ use reth_trie::HashedPostState; use revm::{ db::{states::bundle_state::BundleRetention, State}, - primitives::{EVMError, EnvWithHandlerCfg, InvalidTransaction, ResultAndState}, + primitives::{ + calc_excess_blob_gas, BlockEnv, CfgEnvWithHandlerCfg, EVMError, EnvWithHandlerCfg, + InvalidTransaction, ResultAndState, TxEnv, + }, DatabaseCommit, }; -use revm_primitives::{calc_excess_blob_gas, TxEnv}; use std::sync::Arc; use tracing::{debug, trace, warn}; diff --git a/crates/node/builder/Cargo.toml b/crates/node/builder/Cargo.toml index 09bdd8b2269..b0b62d1b2ed 100644 --- a/crates/node/builder/Cargo.toml +++ b/crates/node/builder/Cargo.toml @@ -63,6 +63,7 @@ reth-transaction-pool.workspace = true alloy-primitives.workspace = true alloy-rpc-types = { workspace = true, features = ["engine"] } alloy-consensus.workspace = true +revm-primitives.workspace = true ## async futures.workspace = true diff --git a/crates/node/builder/src/builder/mod.rs b/crates/node/builder/src/builder/mod.rs index 2e00b08f8a5..89892ed5985 100644 --- a/crates/node/builder/src/builder/mod.rs +++ b/crates/node/builder/src/builder/mod.rs @@ -2,13 +2,6 @@ #![allow(clippy::type_complexity, missing_debug_implementations)] -pub mod add_ons; -mod states; - -pub use states::*; - -use std::sync::Arc; - use crate::{ common::WithConfigs, components::NodeComponentsBuilder, @@ -38,13 +31,19 @@ use reth_node_core::{ node_config::NodeConfig, primitives::Head, }; -use reth_primitives::revm_primitives::EnvKzgSettings; use reth_provider::{providers::BlockchainProvider, ChainSpecProvider, FullProvider}; use reth_tasks::TaskExecutor; use reth_transaction_pool::{PoolConfig, TransactionPool}; +use revm_primitives::EnvKzgSettings; use secp256k1::SecretKey; +use std::sync::Arc; use tracing::{info, trace, warn}; +pub mod add_ons; + +mod states; +pub use states::*; + /// The adapter type for a reth node with the builtin provider type // Note: we need to hardcode this because custom components might depend on it in associated types. pub type RethFullAdapter = FullNodeTypesAdapter< diff --git a/crates/optimism/evm/src/lib.rs b/crates/optimism/evm/src/lib.rs index dafb1676ebd..9569c1cb8b5 100644 --- a/crates/optimism/evm/src/lib.rs +++ b/crates/optimism/evm/src/lib.rs @@ -17,12 +17,12 @@ use alloy_consensus::Header; use alloy_primitives::{Address, U256}; use reth_evm::{ConfigureEvm, ConfigureEvmEnv, NextBlockEnvAttributes}; use reth_optimism_chainspec::{DecodeError, OpChainSpec}; -use reth_primitives::{ - revm_primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv}, - transaction::FillTxEnv, - Head, TransactionSigned, +use reth_primitives::{transaction::FillTxEnv, Head, TransactionSigned}; +use reth_revm::{ + inspector_handle_register, + primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv}, + Database, Evm, EvmBuilder, GetInspector, }; -use reth_revm::{inspector_handle_register, Database, Evm, EvmBuilder, GetInspector}; mod config; pub use config::{revm_spec, revm_spec_by_timestamp_after_bedrock}; @@ -211,14 +211,12 @@ mod tests { AccountRevertInit, BundleStateInit, Chain, ExecutionOutcome, RevertsInit, }; use reth_optimism_chainspec::BASE_MAINNET; - use reth_primitives::{ - revm_primitives::{AccountInfo, BlockEnv, CfgEnv, SpecId}, - Account, Log, Receipt, Receipts, SealedBlockWithSenders, TxType, - }; + use reth_primitives::{Account, Log, Receipt, Receipts, SealedBlockWithSenders, TxType}; use reth_revm::{ db::{BundleState, CacheDB, EmptyDBTyped}, inspectors::NoOpInspector, + primitives::{AccountInfo, BlockEnv, CfgEnv, SpecId}, JournaledState, }; use revm_primitives::{CfgEnvWithHandlerCfg, EnvWithHandlerCfg, HandlerCfg}; diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index d0eb464ae02..7047c587b0c 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -17,11 +17,7 @@ use reth_optimism_consensus::calculate_receipt_root_no_memo_optimism; use reth_optimism_forks::OpHardforks; use reth_payload_primitives::{PayloadBuilderAttributes, PayloadBuilderError}; use reth_payload_util::PayloadTransactions; -use reth_primitives::{ - proofs, - revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg}, - Block, BlockBody, Receipt, SealedHeader, TransactionSigned, TxType, -}; +use reth_primitives::{proofs, Block, BlockBody, Receipt, SealedHeader, TransactionSigned, TxType}; use reth_provider::{ProviderError, StateProofProvider, StateProviderFactory, StateRootProvider}; use reth_revm::database::StateProviderDatabase; use reth_transaction_pool::{ @@ -30,7 +26,10 @@ use reth_transaction_pool::{ use reth_trie::HashedPostState; use revm::{ db::{states::bundle_state::BundleRetention, State}, - primitives::{EVMError, EnvWithHandlerCfg, InvalidTransaction, ResultAndState, TxEnv}, + primitives::{ + BlockEnv, CfgEnvWithHandlerCfg, EVMError, EnvWithHandlerCfg, InvalidTransaction, + ResultAndState, TxEnv, + }, Database, DatabaseCommit, }; use tracing::{debug, trace, warn}; diff --git a/crates/optimism/rpc/src/error.rs b/crates/optimism/rpc/src/error.rs index 1dd7a639eac..caafe798c81 100644 --- a/crates/optimism/rpc/src/error.rs +++ b/crates/optimism/rpc/src/error.rs @@ -3,10 +3,10 @@ use alloy_rpc_types_eth::{error::EthRpcErrorCode, BlockError}; use jsonrpsee_types::error::INTERNAL_ERROR_CODE; use reth_optimism_evm::OpBlockExecutionError; -use reth_primitives::revm_primitives::{InvalidTransaction, OptimismInvalidTransaction}; use reth_rpc_eth_api::AsEthApiError; use reth_rpc_eth_types::EthApiError; use reth_rpc_server_types::result::{internal_rpc_err, rpc_err}; +use revm::primitives::{InvalidTransaction, OptimismInvalidTransaction}; /// Optimism specific errors, that extend [`EthApiError`]. #[derive(Debug, thiserror::Error)] diff --git a/crates/optimism/rpc/src/eth/call.rs b/crates/optimism/rpc/src/eth/call.rs index ea0086aedfd..9495a359e32 100644 --- a/crates/optimism/rpc/src/eth/call.rs +++ b/crates/optimism/rpc/src/eth/call.rs @@ -1,15 +1,14 @@ +use crate::{OpEthApi, OpEthApiError}; use alloy_consensus::Header; use alloy_primitives::{Bytes, TxKind, U256}; use alloy_rpc_types_eth::transaction::TransactionRequest; use reth_evm::ConfigureEvm; -use reth_primitives::revm_primitives::{BlockEnv, OptimismFields, TxEnv}; use reth_rpc_eth_api::{ helpers::{estimate::EstimateCall, Call, EthCall, LoadPendingBlock, LoadState, SpawnBlocking}, FromEthApiError, IntoEthApiError, RpcNodeCore, }; use reth_rpc_eth_types::{revm_utils::CallFees, RpcInvalidTransactionError}; - -use crate::{OpEthApi, OpEthApiError}; +use revm::primitives::{BlockEnv, OptimismFields, TxEnv}; impl EthCall for OpEthApi where diff --git a/crates/optimism/rpc/src/eth/pending_block.rs b/crates/optimism/rpc/src/eth/pending_block.rs index 8356d72dbdc..782f78dd4aa 100644 --- a/crates/optimism/rpc/src/eth/pending_block.rs +++ b/crates/optimism/rpc/src/eth/pending_block.rs @@ -1,12 +1,13 @@ //! Loads OP pending block for a RPC response. +use crate::OpEthApi; use alloy_consensus::Header; use alloy_eips::BlockNumberOrTag; use alloy_primitives::{BlockNumber, B256}; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_evm::ConfigureEvm; use reth_optimism_consensus::calculate_receipt_root_no_memo_optimism; -use reth_primitives::{revm_primitives::BlockEnv, Receipt, SealedBlockWithSenders}; +use reth_primitives::{Receipt, SealedBlockWithSenders}; use reth_provider::{ BlockReader, BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, ExecutionOutcome, ReceiptProvider, StateProviderFactory, @@ -17,8 +18,7 @@ use reth_rpc_eth_api::{ }; use reth_rpc_eth_types::{EthApiError, PendingBlock}; use reth_transaction_pool::TransactionPool; - -use crate::OpEthApi; +use revm::primitives::BlockEnv; impl LoadPendingBlock for OpEthApi where diff --git a/crates/payload/primitives/Cargo.toml b/crates/payload/primitives/Cargo.toml index 951108e7da3..b1a115f12c8 100644 --- a/crates/payload/primitives/Cargo.toml +++ b/crates/payload/primitives/Cargo.toml @@ -25,6 +25,8 @@ alloy-primitives.workspace = true alloy-rpc-types-engine = { workspace = true, features = ["serde"] } op-alloy-rpc-types-engine = { workspace = true, optional = true } +revm-primitives.workspace = true + # async async-trait.workspace = true tokio = { workspace = true, features = ["sync"] } diff --git a/crates/payload/primitives/src/error.rs b/crates/payload/primitives/src/error.rs index ab222f5f6ef..82891919feb 100644 --- a/crates/payload/primitives/src/error.rs +++ b/crates/payload/primitives/src/error.rs @@ -2,8 +2,8 @@ use alloy_primitives::B256; use reth_errors::{ProviderError, RethError}; -use reth_primitives::revm_primitives::EVMError; use reth_transaction_pool::BlobStoreError; +use revm_primitives::EVMError; use tokio::sync::oneshot; /// Possible error variants during payload building. diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 87bf254edab..45067d60079 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -53,7 +53,6 @@ pub use transaction::{ // Re-exports pub use reth_ethereum_forks::*; -pub use revm_primitives::{self, JumpTable}; #[cfg(any(test, feature = "arbitrary"))] pub use arbitrary; diff --git a/crates/primitives/src/receipt.rs b/crates/primitives/src/receipt.rs index 41397181149..b7138183d11 100644 --- a/crates/primitives/src/receipt.rs +++ b/crates/primitives/src/receipt.rs @@ -545,8 +545,7 @@ impl Encodable for ReceiptWithBloomEncoder<'_> { #[cfg(test)] mod tests { use super::*; - use crate::revm_primitives::Bytes; - use alloy_primitives::{address, b256, bytes, hex_literal::hex}; + use alloy_primitives::{address, b256, bytes, hex_literal::hex, Bytes}; use reth_codecs::Compact; #[test] diff --git a/crates/revm/src/cached.rs b/crates/revm/src/cached.rs index 88a41e1d895..5d5262adc5b 100644 --- a/crates/revm/src/cached.rs +++ b/crates/revm/src/cached.rs @@ -4,7 +4,7 @@ use alloy_primitives::{ Address, B256, U256, }; use core::cell::RefCell; -use reth_primitives::revm_primitives::{ +use revm::primitives::{ db::{Database, DatabaseRef}, AccountInfo, Bytecode, }; diff --git a/crates/rpc/rpc-eth-api/src/helpers/call.rs b/crates/rpc/rpc-eth-api/src/helpers/call.rs index d614018a407..1eade554fc1 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/call.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/call.rs @@ -18,14 +18,16 @@ use alloy_rpc_types_eth::{ use futures::Future; use reth_chainspec::EthChainSpec; use reth_evm::{ConfigureEvm, ConfigureEvmEnv}; -use reth_primitives::{ - revm_primitives::{ +use reth_primitives::TransactionSigned; +use reth_provider::{BlockIdReader, ChainSpecProvider, HeaderProvider}; +use reth_revm::{ + database::StateProviderDatabase, + db::CacheDB, + primitives::{ BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ExecutionResult, ResultAndState, TxEnv, }, - TransactionSigned, + DatabaseRef, }; -use reth_provider::{BlockIdReader, ChainSpecProvider, HeaderProvider}; -use reth_revm::{database::StateProviderDatabase, db::CacheDB, DatabaseRef}; use reth_rpc_eth_types::{ cache::db::{StateCacheDbRefMutWrapper, StateProviderTraitObjWrapper}, error::ensure_success, diff --git a/crates/rpc/rpc-eth-api/src/helpers/estimate.rs b/crates/rpc/rpc-eth-api/src/helpers/estimate.rs index 37a68577fb0..465c33ada38 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/estimate.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/estimate.rs @@ -6,11 +6,12 @@ use alloy_primitives::U256; use alloy_rpc_types_eth::{state::StateOverride, transaction::TransactionRequest, BlockId}; use futures::Future; use reth_chainspec::{EthChainSpec, MIN_TRANSACTION_GAS}; -use reth_primitives::revm_primitives::{ - BlockEnv, CfgEnvWithHandlerCfg, ExecutionResult, HaltReason, TransactTo, -}; use reth_provider::{ChainSpecProvider, StateProvider}; -use reth_revm::{database::StateProviderDatabase, db::CacheDB}; +use reth_revm::{ + database::StateProviderDatabase, + db::CacheDB, + primitives::{BlockEnv, CfgEnvWithHandlerCfg, ExecutionResult, HaltReason, TransactTo}, +}; use reth_rpc_eth_types::{ revm_utils::{apply_state_overrides, caller_gas_allowance}, EthApiError, RevertError, RpcInvalidTransactionError, diff --git a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs index 490447d6152..548f9101023 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs @@ -1,10 +1,8 @@ //! Loads a pending block from database. Helper trait for `eth_` block, transaction, call and trace //! RPC methods. -use std::time::{Duration, Instant}; - +use super::SpawnBlocking; use crate::{EthApiTypes, FromEthApiError, FromEvmError, RpcNodeCore}; - use alloy_consensus::{Header, EMPTY_OMMER_ROOT_HASH}; use alloy_eips::{ eip4844::MAX_DATA_GAS_PER_BLOCK, eip7685::EMPTY_REQUESTS_HASH, merge::BEACON_NONCE, @@ -19,27 +17,28 @@ use reth_evm::{ }; use reth_execution_types::ExecutionOutcome; use reth_primitives::{ - proofs::calculate_transaction_root, - revm_primitives::{ - BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, EVMError, Env, ExecutionResult, InvalidTransaction, - ResultAndState, SpecId, - }, - Block, BlockBody, Receipt, SealedBlockWithSenders, SealedHeader, TransactionSignedEcRecovered, + proofs::calculate_transaction_root, Block, BlockBody, Receipt, SealedBlockWithSenders, + SealedHeader, TransactionSignedEcRecovered, }; use reth_provider::{ BlockReader, BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, ProviderError, ReceiptProvider, StateProviderFactory, }; -use reth_revm::database::StateProviderDatabase; +use reth_revm::{ + database::StateProviderDatabase, + primitives::{ + BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, EVMError, Env, ExecutionResult, InvalidTransaction, + ResultAndState, SpecId, + }, +}; use reth_rpc_eth_types::{EthApiError, PendingBlock, PendingBlockEnv, PendingBlockEnvOrigin}; use reth_transaction_pool::{BestTransactionsAttributes, TransactionPool}; use reth_trie::HashedPostState; use revm::{db::states::bundle_state::BundleRetention, DatabaseCommit, State}; +use std::time::{Duration, Instant}; use tokio::sync::Mutex; use tracing::debug; -use super::SpawnBlocking; - /// Loads a pending block from database. /// /// Behaviour shared by several `eth_` RPC methods, not exclusive to `eth_` blocks RPC methods. diff --git a/crates/rpc/rpc-eth-types/src/error/mod.rs b/crates/rpc/rpc-eth-types/src/error/mod.rs index 99c41daea37..893bbdd6b9c 100644 --- a/crates/rpc/rpc-eth-types/src/error/mod.rs +++ b/crates/rpc/rpc-eth-types/src/error/mod.rs @@ -10,7 +10,6 @@ use alloy_primitives::{Address, Bytes, U256}; use alloy_rpc_types_eth::{error::EthRpcErrorCode, request::TransactionInputError, BlockError}; use alloy_sol_types::decode_revert_reason; use reth_errors::RethError; -use reth_primitives::revm_primitives::InvalidHeader; use reth_rpc_server_types::result::{ block_id_to_str, internal_rpc_err, invalid_params_rpc_err, rpc_err, rpc_error_with_code, }; @@ -20,6 +19,7 @@ use reth_transaction_pool::error::{ }; use revm::primitives::{EVMError, ExecutionResult, HaltReason, InvalidTransaction, OutOfGasError}; use revm_inspectors::tracing::MuxError; +use revm_primitives::InvalidHeader; use tracing::error; /// A trait to convert an error to an RPC error. diff --git a/crates/rpc/rpc/src/eth/bundle.rs b/crates/rpc/rpc/src/eth/bundle.rs index a2e0be30437..f92bd075a3b 100644 --- a/crates/rpc/rpc/src/eth/bundle.rs +++ b/crates/rpc/rpc/src/eth/bundle.rs @@ -1,31 +1,26 @@ //! `Eth` bundle implementation and helpers. -use std::sync::Arc; - use alloy_primitives::{Keccak256, U256}; use alloy_rpc_types_mev::{EthCallBundle, EthCallBundleResponse, EthCallBundleTransactionResult}; use jsonrpsee::core::RpcResult; use reth_chainspec::EthChainSpec; use reth_evm::{ConfigureEvm, ConfigureEvmEnv}; -use reth_primitives::{ - revm_primitives::db::{DatabaseCommit, DatabaseRef}, - PooledTransactionsElement, -}; +use reth_primitives::PooledTransactionsElement; +use reth_provider::{ChainSpecProvider, HeaderProvider}; use reth_revm::database::StateProviderDatabase; -use reth_rpc_eth_api::{FromEthApiError, FromEvmError, RpcNodeCore}; +use reth_rpc_eth_api::{ + helpers::{Call, EthTransactions, LoadPendingBlock}, + EthCallBundleApiServer, FromEthApiError, FromEvmError, RpcNodeCore, +}; +use reth_rpc_eth_types::{utils::recover_raw_transaction, EthApiError, RpcInvalidTransactionError}; use reth_tasks::pool::BlockingTaskGuard; use revm::{ - db::CacheDB, + db::{CacheDB, DatabaseCommit, DatabaseRef}, primitives::{ResultAndState, TxEnv}, }; use revm_primitives::{EnvKzgSettings, EnvWithHandlerCfg, SpecId, MAX_BLOB_GAS_PER_BLOCK}; +use std::sync::Arc; -use reth_provider::{ChainSpecProvider, HeaderProvider}; -use reth_rpc_eth_api::{ - helpers::{Call, EthTransactions, LoadPendingBlock}, - EthCallBundleApiServer, -}; -use reth_rpc_eth_types::{utils::recover_raw_transaction, EthApiError, RpcInvalidTransactionError}; /// `Eth` bundle implementation. pub struct EthBundle { /// All nested fields bundled together. diff --git a/crates/rpc/rpc/src/eth/sim_bundle.rs b/crates/rpc/rpc/src/eth/sim_bundle.rs index 40d951f755f..f77b7e79da0 100644 --- a/crates/rpc/rpc/src/eth/sim_bundle.rs +++ b/crates/rpc/rpc/src/eth/sim_bundle.rs @@ -10,10 +10,7 @@ use alloy_rpc_types_mev::{ use jsonrpsee::core::RpcResult; use reth_chainspec::EthChainSpec; use reth_evm::{ConfigureEvm, ConfigureEvmEnv}; -use reth_primitives::{ - revm_primitives::db::{DatabaseCommit, DatabaseRef}, - TransactionSigned, -}; +use reth_primitives::TransactionSigned; use reth_provider::{ChainSpecProvider, HeaderProvider}; use reth_revm::database::StateProviderDatabase; use reth_rpc_api::MevSimApiServer; @@ -26,6 +23,7 @@ use reth_tasks::pool::BlockingTaskGuard; use revm::{ db::CacheDB, primitives::{Address, EnvWithHandlerCfg, ResultAndState, SpecId, TxEnv}, + DatabaseCommit, DatabaseRef, }; use std::{sync::Arc, time::Duration}; use tracing::info; diff --git a/crates/trie/db/src/state.rs b/crates/trie/db/src/state.rs index 0d2171604d5..6e2cea5051d 100644 --- a/crates/trie/db/src/state.rs +++ b/crates/trie/db/src/state.rs @@ -265,8 +265,7 @@ mod tests { use alloy_primitives::{hex, map::HashMap, Address, U256}; use reth_db::test_utils::create_test_rw_db; use reth_db_api::database::Database; - use reth_primitives::revm_primitives::AccountInfo; - use revm::db::BundleState; + use revm::{db::BundleState, primitives::AccountInfo}; #[test] fn from_bundle_state_with_rayon() { diff --git a/examples/custom-beacon-withdrawals/src/main.rs b/examples/custom-beacon-withdrawals/src/main.rs index 43e5f7428f6..47adc64c004 100644 --- a/examples/custom-beacon-withdrawals/src/main.rs +++ b/examples/custom-beacon-withdrawals/src/main.rs @@ -15,7 +15,10 @@ use reth::{ providers::ProviderError, revm::{ interpreter::Host, - primitives::{Env, TransactTo, TxEnv}, + primitives::{ + address, Address, BlockEnv, Bytes, CfgEnvWithHandlerCfg, Env, EnvWithHandlerCfg, + TransactTo, TxEnv, U256, + }, Database, DatabaseCommit, Evm, State, }, }; @@ -26,12 +29,7 @@ use reth_evm::execute::{ }; use reth_evm_ethereum::EthEvmConfig; use reth_node_ethereum::{node::EthereumAddOns, BasicBlockExecutorProvider, EthereumNode}; -use reth_primitives::{ - revm_primitives::{ - address, Address, BlockEnv, Bytes, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, U256, - }, - BlockWithSenders, Receipt, -}; +use reth_primitives::{BlockWithSenders, Receipt}; use std::{fmt::Display, sync::Arc}; pub const SYSTEM_ADDRESS: Address = address!("fffffffffffffffffffffffffffffffffffffffe"); diff --git a/examples/custom-evm/src/main.rs b/examples/custom-evm/src/main.rs index c564c5b28b6..7a5278061f2 100644 --- a/examples/custom-evm/src/main.rs +++ b/examples/custom-evm/src/main.rs @@ -11,12 +11,11 @@ use reth::{ BuilderContext, NodeBuilder, }, payload::{EthBuiltPayload, EthPayloadBuilderAttributes}, - primitives::revm_primitives::{Env, PrecompileResult}, revm::{ handler::register::EvmHandler, inspector_handle_register, precompile::{Precompile, PrecompileOutput, PrecompileSpecId}, - primitives::BlockEnv, + primitives::{BlockEnv, CfgEnvWithHandlerCfg, Env, PrecompileResult, TxEnv}, ContextPrecompiles, Database, Evm, EvmBuilder, GetInspector, }, rpc::types::engine::PayloadAttributes, @@ -34,10 +33,7 @@ use reth_node_ethereum::{ node::{EthereumAddOns, EthereumPayloadBuilder}, BasicBlockExecutorProvider, EthExecutionStrategyFactory, EthereumNode, }; -use reth_primitives::{ - revm_primitives::{CfgEnvWithHandlerCfg, TxEnv}, - TransactionSigned, -}; +use reth_primitives::TransactionSigned; use reth_tracing::{RethTracer, Tracer}; use std::{convert::Infallible, sync::Arc}; diff --git a/examples/stateful-precompile/src/main.rs b/examples/stateful-precompile/src/main.rs index 5be45ad7674..f683af4e430 100644 --- a/examples/stateful-precompile/src/main.rs +++ b/examples/stateful-precompile/src/main.rs @@ -9,11 +9,14 @@ use parking_lot::RwLock; use reth::{ api::NextBlockEnvAttributes, builder::{components::ExecutorBuilder, BuilderContext, NodeBuilder}, - primitives::revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, Env, PrecompileResult, TxEnv}, revm::{ handler::register::EvmHandler, inspector_handle_register, precompile::{Precompile, PrecompileSpecId}, + primitives::{ + BlockEnv, CfgEnvWithHandlerCfg, Env, PrecompileResult, SpecId, StatefulPrecompileMut, + TxEnv, + }, ContextPrecompile, ContextPrecompiles, Database, Evm, EvmBuilder, GetInspector, }, tasks::TaskManager, @@ -25,10 +28,7 @@ use reth_node_ethereum::{ node::EthereumAddOns, BasicBlockExecutorProvider, EthEvmConfig, EthExecutionStrategyFactory, EthereumNode, }; -use reth_primitives::{ - revm_primitives::{SpecId, StatefulPrecompileMut}, - TransactionSigned, -}; +use reth_primitives::TransactionSigned; use reth_tracing::{RethTracer, Tracer}; use schnellru::{ByLength, LruMap}; use std::{collections::HashMap, convert::Infallible, sync::Arc}; From dda19065885c3b0f32594e737e76dac5713b1bdf Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Sat, 16 Nov 2024 17:06:57 +0100 Subject: [PATCH 206/211] rm more generics when useless (#12595) --- crates/exex/exex/src/wal/mod.rs | 14 +++---- crates/net/eth-wire-types/src/blocks.rs | 16 +++---- crates/net/eth-wire-types/src/broadcast.rs | 2 +- crates/net/eth-wire-types/src/message.rs | 42 +++++-------------- crates/net/eth-wire-types/src/receipts.rs | 8 ++-- crates/net/eth-wire-types/src/state.rs | 8 ++-- crates/net/eth-wire-types/src/status.rs | 2 +- crates/net/eth-wire-types/src/transactions.rs | 22 ++++------ crates/net/nat/src/lib.rs | 2 +- .../net/network/src/transactions/fetcher.rs | 22 ++++------ crates/net/network/src/transactions/mod.rs | 2 +- crates/net/p2p/src/full_block.rs | 2 +- crates/rpc/rpc-eth-types/src/simulate.rs | 4 +- .../stages/src/stages/sender_recovery.rs | 6 +-- crates/stages/stages/src/stages/tx_lookup.rs | 4 +- 15 files changed, 60 insertions(+), 96 deletions(-) diff --git a/crates/exex/exex/src/wal/mod.rs b/crates/exex/exex/src/wal/mod.rs index 00b0ea919ef..a2e8ee8e6c6 100644 --- a/crates/exex/exex/src/wal/mod.rs +++ b/crates/exex/exex/src/wal/mod.rs @@ -231,13 +231,13 @@ mod tests { use crate::wal::{cache::CachedBlock, Wal}; fn read_notifications(wal: &Wal) -> eyre::Result> { - let Some(files_range) = wal.inner.storage.files_range()? else { return Ok(Vec::new()) }; - - wal.inner - .storage - .iter_notifications(files_range) - .map(|entry| Ok(entry?.2)) - .collect::>() + wal.inner.storage.files_range()?.map_or(Ok(Vec::new()), |range| { + wal.inner + .storage + .iter_notifications(range) + .map(|entry| entry.map(|(_, _, n)| n)) + .collect() + }) } fn sort_committed_blocks( diff --git a/crates/net/eth-wire-types/src/blocks.rs b/crates/net/eth-wire-types/src/blocks.rs index 1eb71082d81..06549e769e6 100644 --- a/crates/net/eth-wire-types/src/blocks.rs +++ b/crates/net/eth-wire-types/src/blocks.rs @@ -198,7 +198,7 @@ mod tests { fn encode_get_block_header_number() { let expected = hex!("ca820457c682270f050580"); let mut data = vec![]; - RequestPair:: { + RequestPair { request_id: 1111, message: GetBlockHeaders { start_block: BlockHashOrNumber::Number(9999), @@ -215,7 +215,7 @@ mod tests { #[test] fn decode_get_block_header_number() { let data = hex!("ca820457c682270f050580"); - let expected = RequestPair:: { + let expected = RequestPair { request_id: 1111, message: GetBlockHeaders { start_block: BlockHashOrNumber::Number(9999), @@ -234,7 +234,7 @@ mod tests { // [ (f90202) 0x0457 = 1111, [ (f901fc) [ (f901f9) header ] ] ] let expected = hex!("f90202820457f901fcf901f9a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008208ae820d0582115c8215b3821a0a827788a00000000000000000000000000000000000000000000000000000000000000000880000000000000000"); let mut data = vec![]; - RequestPair::> { + RequestPair { request_id: 1111, message: BlockHeaders(vec![ Header { @@ -269,7 +269,7 @@ mod tests { #[test] fn decode_block_header() { let data = hex!("f90202820457f901fcf901f9a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008208ae820d0582115c8215b3821a0a827788a00000000000000000000000000000000000000000000000000000000000000000880000000000000000"); - let expected = RequestPair::> { + let expected = RequestPair { request_id: 1111, message: BlockHeaders(vec![ Header { @@ -306,7 +306,7 @@ mod tests { fn encode_get_block_bodies() { let expected = hex!("f847820457f842a000000000000000000000000000000000000000000000000000000000deadc0dea000000000000000000000000000000000000000000000000000000000feedbeef"); let mut data = vec![]; - RequestPair:: { + RequestPair { request_id: 1111, message: GetBlockBodies(vec![ hex!("00000000000000000000000000000000000000000000000000000000deadc0de").into(), @@ -321,7 +321,7 @@ mod tests { #[test] fn decode_get_block_bodies() { let data = hex!("f847820457f842a000000000000000000000000000000000000000000000000000000000deadc0dea000000000000000000000000000000000000000000000000000000000feedbeef"); - let expected = RequestPair:: { + let expected = RequestPair { request_id: 1111, message: GetBlockBodies(vec![ hex!("00000000000000000000000000000000000000000000000000000000deadc0de").into(), @@ -337,7 +337,7 @@ mod tests { fn encode_block_bodies() { let expected = hex!("f902dc820457f902d6f902d3f8d2f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afbf901fcf901f9a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008208ae820d0582115c8215b3821a0a827788a00000000000000000000000000000000000000000000000000000000000000000880000000000000000"); let mut data = vec![]; - let request = RequestPair::> { + let request = RequestPair { request_id: 1111, message: BlockBodies(vec![ BlockBody { @@ -408,7 +408,7 @@ mod tests { #[test] fn decode_block_bodies() { let data = hex!("f902dc820457f902d6f902d3f8d2f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afbf901fcf901f9a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008208ae820d0582115c8215b3821a0a827788a00000000000000000000000000000000000000000000000000000000000000000880000000000000000"); - let expected = RequestPair::> { + let expected = RequestPair { request_id: 1111, message: BlockBodies(vec![ BlockBody { diff --git a/crates/net/eth-wire-types/src/broadcast.rs b/crates/net/eth-wire-types/src/broadcast.rs index 03222706992..f37c5e74a04 100644 --- a/crates/net/eth-wire-types/src/broadcast.rs +++ b/crates/net/eth-wire-types/src/broadcast.rs @@ -733,7 +733,7 @@ impl RequestTxHashes { impl FromIterator<(TxHash, Eth68TxMetadata)> for RequestTxHashes { fn from_iter>(iter: I) -> Self { - Self::new(iter.into_iter().map(|(hash, _)| hash).collect::>()) + Self::new(iter.into_iter().map(|(hash, _)| hash).collect()) } } diff --git a/crates/net/eth-wire-types/src/message.rs b/crates/net/eth-wire-types/src/message.rs index 2a6d973ffc3..f83e21124e3 100644 --- a/crates/net/eth-wire-types/src/message.rs +++ b/crates/net/eth-wire-types/src/message.rs @@ -77,52 +77,30 @@ impl ProtocolMessage { )?) } } - EthMessageID::GetBlockHeaders => { - let request_pair = RequestPair::::decode(buf)?; - EthMessage::GetBlockHeaders(request_pair) - } - EthMessageID::BlockHeaders => { - let request_pair = RequestPair::>::decode(buf)?; - EthMessage::BlockHeaders(request_pair) - } - EthMessageID::GetBlockBodies => { - let request_pair = RequestPair::::decode(buf)?; - EthMessage::GetBlockBodies(request_pair) - } - EthMessageID::BlockBodies => { - let request_pair = RequestPair::>::decode(buf)?; - EthMessage::BlockBodies(request_pair) - } + EthMessageID::GetBlockHeaders => EthMessage::GetBlockHeaders(RequestPair::decode(buf)?), + EthMessageID::BlockHeaders => EthMessage::BlockHeaders(RequestPair::decode(buf)?), + EthMessageID::GetBlockBodies => EthMessage::GetBlockBodies(RequestPair::decode(buf)?), + EthMessageID::BlockBodies => EthMessage::BlockBodies(RequestPair::decode(buf)?), EthMessageID::GetPooledTransactions => { - let request_pair = RequestPair::::decode(buf)?; - EthMessage::GetPooledTransactions(request_pair) + EthMessage::GetPooledTransactions(RequestPair::decode(buf)?) } EthMessageID::PooledTransactions => { - let request_pair = RequestPair::::decode(buf)?; - EthMessage::PooledTransactions(request_pair) + EthMessage::PooledTransactions(RequestPair::decode(buf)?) } EthMessageID::GetNodeData => { if version >= EthVersion::Eth67 { return Err(MessageError::Invalid(version, EthMessageID::GetNodeData)) } - let request_pair = RequestPair::::decode(buf)?; - EthMessage::GetNodeData(request_pair) + EthMessage::GetNodeData(RequestPair::decode(buf)?) } EthMessageID::NodeData => { if version >= EthVersion::Eth67 { return Err(MessageError::Invalid(version, EthMessageID::GetNodeData)) } - let request_pair = RequestPair::::decode(buf)?; - EthMessage::NodeData(request_pair) - } - EthMessageID::GetReceipts => { - let request_pair = RequestPair::::decode(buf)?; - EthMessage::GetReceipts(request_pair) - } - EthMessageID::Receipts => { - let request_pair = RequestPair::::decode(buf)?; - EthMessage::Receipts(request_pair) + EthMessage::NodeData(RequestPair::decode(buf)?) } + EthMessageID::GetReceipts => EthMessage::GetReceipts(RequestPair::decode(buf)?), + EthMessageID::Receipts => EthMessage::Receipts(RequestPair::decode(buf)?), }; Ok(Self { message_type, message }) } diff --git a/crates/net/eth-wire-types/src/receipts.rs b/crates/net/eth-wire-types/src/receipts.rs index db9d6f871e4..ca5e85a146f 100644 --- a/crates/net/eth-wire-types/src/receipts.rs +++ b/crates/net/eth-wire-types/src/receipts.rs @@ -54,7 +54,7 @@ mod tests { fn encode_get_receipts() { let expected = hex!("f847820457f842a000000000000000000000000000000000000000000000000000000000deadc0dea000000000000000000000000000000000000000000000000000000000feedbeef"); let mut data = vec![]; - let request = RequestPair:: { + let request = RequestPair { request_id: 1111, message: GetReceipts(vec![ hex!("00000000000000000000000000000000000000000000000000000000deadc0de").into(), @@ -72,7 +72,7 @@ mod tests { let request = RequestPair::::decode(&mut &data[..]).unwrap(); assert_eq!( request, - RequestPair:: { + RequestPair { request_id: 1111, message: GetReceipts(vec![ hex!("00000000000000000000000000000000000000000000000000000000deadc0de").into(), @@ -88,7 +88,7 @@ mod tests { fn encode_receipts() { let expected = hex!("f90172820457f9016cf90169f901668001b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f85ff85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff"); let mut data = vec![]; - let request = RequestPair:: { + let request = RequestPair { request_id: 1111, message: Receipts(vec![vec![ ReceiptWithBloom { @@ -124,7 +124,7 @@ mod tests { let request = RequestPair::::decode(&mut &data[..]).unwrap(); assert_eq!( request, - RequestPair:: { + RequestPair { request_id: 1111, message: Receipts(vec![ vec![ diff --git a/crates/net/eth-wire-types/src/state.rs b/crates/net/eth-wire-types/src/state.rs index 16a2959b338..57273adc6b1 100644 --- a/crates/net/eth-wire-types/src/state.rs +++ b/crates/net/eth-wire-types/src/state.rs @@ -36,7 +36,7 @@ mod tests { fn encode_get_node_data() { let expected = hex!("f847820457f842a000000000000000000000000000000000000000000000000000000000deadc0dea000000000000000000000000000000000000000000000000000000000feedbeef"); let mut data = vec![]; - let request = RequestPair:: { + let request = RequestPair { request_id: 1111, message: GetNodeData(vec![ hex!("00000000000000000000000000000000000000000000000000000000deadc0de").into(), @@ -54,7 +54,7 @@ mod tests { let request = RequestPair::::decode(&mut &data[..]).unwrap(); assert_eq!( request, - RequestPair:: { + RequestPair { request_id: 1111, message: GetNodeData(vec![ hex!("00000000000000000000000000000000000000000000000000000000deadc0de").into(), @@ -69,7 +69,7 @@ mod tests { fn encode_node_data() { let expected = hex!("ce820457ca84deadc0de84feedbeef"); let mut data = vec![]; - let request = RequestPair:: { + let request = RequestPair { request_id: 1111, message: NodeData(vec![ hex!("deadc0de").as_slice().into(), @@ -87,7 +87,7 @@ mod tests { let request = RequestPair::::decode(&mut &data[..]).unwrap(); assert_eq!( request, - RequestPair:: { + RequestPair { request_id: 1111, message: NodeData(vec![ hex!("deadc0de").as_slice().into(), diff --git a/crates/net/eth-wire-types/src/status.rs b/crates/net/eth-wire-types/src/status.rs index d9e8d4319b5..fa73d0907fe 100644 --- a/crates/net/eth-wire-types/src/status.rs +++ b/crates/net/eth-wire-types/src/status.rs @@ -338,7 +338,7 @@ mod tests { let total_difficulty = U256::from(rng.gen::()); // create a genesis that has a random part, so we can check that the hash is preserved - let genesis = Genesis { nonce: rng.gen::(), ..Default::default() }; + let genesis = Genesis { nonce: rng.gen(), ..Default::default() }; // build head let head = Head { diff --git a/crates/net/eth-wire-types/src/transactions.rs b/crates/net/eth-wire-types/src/transactions.rs index dfedcb6f83e..8db96c10042 100644 --- a/crates/net/eth-wire-types/src/transactions.rs +++ b/crates/net/eth-wire-types/src/transactions.rs @@ -96,7 +96,7 @@ mod tests { fn encode_get_pooled_transactions() { let expected = hex!("f847820457f842a000000000000000000000000000000000000000000000000000000000deadc0dea000000000000000000000000000000000000000000000000000000000feedbeef"); let mut data = vec![]; - let request = RequestPair:: { + let request = RequestPair { request_id: 1111, message: GetPooledTransactions(vec![ hex!("00000000000000000000000000000000000000000000000000000000deadc0de").into(), @@ -114,7 +114,7 @@ mod tests { let request = RequestPair::::decode(&mut &data[..]).unwrap(); assert_eq!( request, - RequestPair:: { + RequestPair { request_id: 1111, message: GetPooledTransactions(vec![ hex!("00000000000000000000000000000000000000000000000000000000deadc0de").into(), @@ -182,7 +182,7 @@ mod tests { .expect("Failed to convert TransactionSigned to PooledTransactionsElement") }) .collect(); - let request = RequestPair:: { + let request = RequestPair { request_id: 1111, message: PooledTransactions(message), /* Assuming PooledTransactions wraps a * Vec */ @@ -248,10 +248,7 @@ mod tests { .expect("Failed to convert TransactionSigned to PooledTransactionsElement") }) .collect(); - let expected = RequestPair:: { - request_id: 1111, - message: PooledTransactions(message), - }; + let expected = RequestPair { request_id: 1111, message: PooledTransactions(message) }; let request = RequestPair::::decode(&mut &data[..]).unwrap(); assert_eq!(request, expected); @@ -383,10 +380,8 @@ mod tests { .expect("Failed to convert TransactionSigned to PooledTransactionsElement") }) .collect(); - let expected_transactions = RequestPair:: { - request_id: 0, - message: PooledTransactions(message), - }; + let expected_transactions = + RequestPair { request_id: 0, message: PooledTransactions(message) }; // checking tx by tx for easier debugging if there are any regressions for (decoded, expected) in @@ -522,10 +517,7 @@ mod tests { .expect("Failed to convert TransactionSigned to PooledTransactionsElement") }) .collect(); - let transactions = RequestPair:: { - request_id: 0, - message: PooledTransactions(message), - }; + let transactions = RequestPair { request_id: 0, message: PooledTransactions(message) }; let mut encoded = vec![]; transactions.encode(&mut encoded); diff --git a/crates/net/nat/src/lib.rs b/crates/net/nat/src/lib.rs index 600ba97cd2d..962f1e49efd 100644 --- a/crates/net/nat/src/lib.rs +++ b/crates/net/nat/src/lib.rs @@ -111,7 +111,7 @@ impl FromStr for NatResolver { "Unknown Nat Resolver: {s}" ))) }; - Self::ExternalIp(ip.parse::()?) + Self::ExternalIp(ip.parse()?) } }; Ok(r) diff --git a/crates/net/network/src/transactions/fetcher.rs b/crates/net/network/src/transactions/fetcher.rs index 00a9158233b..4c4119c85c0 100644 --- a/crates/net/network/src/transactions/fetcher.rs +++ b/crates/net/network/src/transactions/fetcher.rs @@ -289,7 +289,7 @@ impl TransactionFetcher { // tx is really big, pack request with single tx if size >= self.info.soft_limit_byte_size_pooled_transactions_response_on_pack_request { - return hashes_from_announcement_iter.collect::() + return hashes_from_announcement_iter.collect() } acc_size_response = size; } @@ -688,10 +688,8 @@ impl TransactionFetcher { } let (response, rx) = oneshot::channel(); - let req: PeerRequest = PeerRequest::GetPooledTransactions { - request: GetPooledTransactions( - new_announced_hashes.iter().copied().collect::>(), - ), + let req = PeerRequest::GetPooledTransactions { + request: GetPooledTransactions(new_announced_hashes.iter().copied().collect()), response, }; @@ -1012,8 +1010,7 @@ impl TransactionFetcher { // self.try_buffer_hashes_for_retry(requested_hashes, &peer_id); - let transactions = - valid_payload.into_data().into_values().collect::(); + let transactions = valid_payload.into_data().into_values().collect(); FetchEvent::TransactionsFetched { peer_id, transactions } } @@ -1202,13 +1199,10 @@ impl DedupPayload for VerifiedPooledTransactions { } fn dedup(self) -> PartiallyValidData { - let Self { txns } = self; - let unique_fetched = txns - .into_iter() - .map(|tx| (*tx.hash(), tx)) - .collect::>(); - - PartiallyValidData::from_raw_data(unique_fetched, None) + PartiallyValidData::from_raw_data( + self.txns.into_iter().map(|tx| (*tx.hash(), tx)).collect(), + None, + ) } } diff --git a/crates/net/network/src/transactions/mod.rs b/crates/net/network/src/transactions/mod.rs index 48ae61e0dd0..36abcd3d617 100644 --- a/crates/net/network/src/transactions/mod.rs +++ b/crates/net/network/src/transactions/mod.rs @@ -879,7 +879,7 @@ where .into_iter() .map(PooledTransactionsElement::try_from_broadcast) .filter_map(Result::ok) - .collect::(); + .collect(); self.import_transactions(peer_id, non_blob_txs, TransactionSource::Broadcast); diff --git a/crates/net/p2p/src/full_block.rs b/crates/net/p2p/src/full_block.rs index 151a5bdd2a3..a966c01c933 100644 --- a/crates/net/p2p/src/full_block.rs +++ b/crates/net/p2p/src/full_block.rs @@ -351,7 +351,7 @@ where { /// Returns the block hashes for the given range, if they are available. pub fn range_block_hashes(&self) -> Option> { - self.headers.as_ref().map(|h| h.iter().map(|h| h.hash()).collect::>()) + self.headers.as_ref().map(|h| h.iter().map(|h| h.hash()).collect()) } /// Returns whether or not the bodies map is fully populated with requested headers and bodies. diff --git a/crates/rpc/rpc-eth-types/src/simulate.rs b/crates/rpc/rpc-eth-types/src/simulate.rs index 9807010c0cf..b24ec9e86bc 100644 --- a/crates/rpc/rpc-eth-types/src/simulate.rs +++ b/crates/rpc/rpc-eth-types/src/simulate.rs @@ -282,7 +282,7 @@ pub fn build_block>( timestamp: block_env.timestamp.to(), base_fee_per_gas: Some(block_env.basefee.to()), gas_limit: block_env.gas_limit.to(), - gas_used: calls.iter().map(|c| c.gas_used).sum::(), + gas_used: calls.iter().map(|c| c.gas_used).sum(), blob_gas_used: Some(0), parent_hash, receipts_root: calculate_receipt_root(&receipts), @@ -306,6 +306,6 @@ pub fn build_block>( let txs_kind = if full_transactions { BlockTransactionsKind::Full } else { BlockTransactionsKind::Hashes }; - let block = from_block::(block, total_difficulty, txs_kind, None, tx_resp_builder)?; + let block = from_block(block, total_difficulty, txs_kind, None, tx_resp_builder)?; Ok(SimulatedBlock { inner: block, calls }) } diff --git a/crates/stages/stages/src/stages/sender_recovery.rs b/crates/stages/stages/src/stages/sender_recovery.rs index a4eda6394c0..178fceb262b 100644 --- a/crates/stages/stages/src/stages/sender_recovery.rs +++ b/crates/stages/stages/src/stages/sender_recovery.rs @@ -552,7 +552,7 @@ mod tests { blocks[..=max_pruned_block as usize] .iter() .map(|block| block.body.transactions.len() as u64) - .sum::(), + .sum(), ), prune_mode: PruneMode::Full, }, @@ -567,8 +567,8 @@ mod tests { processed: blocks[..=max_processed_block] .iter() .map(|block| block.body.transactions.len() as u64) - .sum::(), - total: blocks.iter().map(|block| block.body.transactions.len() as u64).sum::() + .sum(), + total: blocks.iter().map(|block| block.body.transactions.len() as u64).sum() } ); } diff --git a/crates/stages/stages/src/stages/tx_lookup.rs b/crates/stages/stages/src/stages/tx_lookup.rs index 60c958abf86..3fdcbd0da64 100644 --- a/crates/stages/stages/src/stages/tx_lookup.rs +++ b/crates/stages/stages/src/stages/tx_lookup.rs @@ -416,8 +416,8 @@ mod tests { processed: blocks[..=max_processed_block] .iter() .map(|block| block.body.transactions.len() as u64) - .sum::(), - total: blocks.iter().map(|block| block.body.transactions.len() as u64).sum::() + .sum(), + total: blocks.iter().map(|block| block.body.transactions.len() as u64).sum() } ); } From 735eb4b97cf3937886a2972647e0afb90c916a71 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Sat, 16 Nov 2024 21:22:17 +0400 Subject: [PATCH 207/211] chore(cli): unify trait bounds (#12604) Co-authored-by: Matthias Seitz --- bin/reth/src/commands/debug_cmd/build_block.rs | 15 +++++++-------- bin/reth/src/commands/debug_cmd/execution.rs | 13 +++++++------ .../src/commands/debug_cmd/in_memory_merkle.rs | 13 ++++++------- bin/reth/src/commands/debug_cmd/merkle.rs | 13 ++++++------- bin/reth/src/commands/debug_cmd/mod.rs | 6 ++---- bin/reth/src/commands/debug_cmd/replay_engine.rs | 15 ++++++--------- crates/cli/commands/src/common.rs | 9 +++++++-- crates/cli/commands/src/db/checksum.rs | 9 ++++++--- crates/cli/commands/src/db/mod.rs | 7 ++----- crates/cli/commands/src/db/stats.rs | 8 +++----- crates/cli/commands/src/import.rs | 5 ++--- crates/cli/commands/src/init_cmd.rs | 7 ++----- crates/cli/commands/src/init_state/mod.rs | 7 ++----- crates/cli/commands/src/prune.rs | 7 ++----- crates/cli/commands/src/recover/mod.rs | 4 ++-- crates/cli/commands/src/recover/storage_tries.rs | 5 ++--- crates/cli/commands/src/stage/drop.rs | 7 ++----- crates/cli/commands/src/stage/dump/execution.rs | 6 +++--- .../commands/src/stage/dump/hashing_account.rs | 5 ++--- .../commands/src/stage/dump/hashing_storage.rs | 5 ++--- crates/cli/commands/src/stage/dump/merkle.rs | 5 ++--- crates/cli/commands/src/stage/dump/mod.rs | 6 +++--- crates/cli/commands/src/stage/mod.rs | 4 ++-- crates/cli/commands/src/stage/run.rs | 5 ++--- crates/cli/commands/src/stage/unwind.rs | 9 +++------ .../optimism/cli/src/commands/build_pipeline.rs | 8 +++++--- crates/optimism/cli/src/commands/import.rs | 7 ++----- .../optimism/cli/src/commands/import_receipts.rs | 9 +++------ crates/optimism/cli/src/commands/init_state.rs | 7 ++----- 29 files changed, 97 insertions(+), 129 deletions(-) diff --git a/bin/reth/src/commands/debug_cmd/build_block.rs b/bin/reth/src/commands/debug_cmd/build_block.rs index 89eca6b776f..adb2c83b1b2 100644 --- a/bin/reth/src/commands/debug_cmd/build_block.rs +++ b/bin/reth/src/commands/debug_cmd/build_block.rs @@ -15,24 +15,23 @@ use reth_blockchain_tree::{ }; use reth_chainspec::ChainSpec; use reth_cli::chainspec::ChainSpecParser; -use reth_cli_commands::common::{AccessRights, Environment, EnvironmentArgs}; +use reth_cli_commands::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs}; use reth_cli_runner::CliContext; use reth_consensus::Consensus; use reth_errors::RethResult; use reth_evm::execute::{BlockExecutorProvider, Executor}; use reth_execution_types::ExecutionOutcome; use reth_fs_util as fs; -use reth_node_api::{ - EngineApiMessageVersion, NodeTypesWithDB, NodeTypesWithEngine, PayloadBuilderAttributes, -}; +use reth_node_api::{EngineApiMessageVersion, PayloadBuilderAttributes}; use reth_node_ethereum::{EthEvmConfig, EthExecutorProvider}; use reth_primitives::{ BlobTransaction, PooledTransactionsElement, SealedBlock, SealedBlockWithSenders, SealedHeader, Transaction, TransactionSigned, }; use reth_provider::{ - providers::BlockchainProvider, BlockHashReader, BlockReader, BlockWriter, ChainSpecProvider, - ProviderFactory, StageCheckpointReader, StateProviderFactory, + providers::{BlockchainProvider, ProviderNodeTypes}, + BlockHashReader, BlockReader, BlockWriter, ChainSpecProvider, ProviderFactory, + StageCheckpointReader, StateProviderFactory, }; use reth_revm::{ cached::CachedReads, @@ -88,7 +87,7 @@ impl> Command { /// Fetches the best block block from the database. /// /// If the database is empty, returns the genesis block. - fn lookup_best_block>( + fn lookup_best_block>( &self, factory: ProviderFactory, ) -> RethResult> { @@ -123,7 +122,7 @@ impl> Command { } /// Execute `debug in-memory-merkle` command - pub async fn execute>( + pub async fn execute>( self, ctx: CliContext, ) -> eyre::Result<()> { diff --git a/bin/reth/src/commands/debug_cmd/execution.rs b/bin/reth/src/commands/debug_cmd/execution.rs index 9056d3424c7..da928645b9f 100644 --- a/bin/reth/src/commands/debug_cmd/execution.rs +++ b/bin/reth/src/commands/debug_cmd/execution.rs @@ -8,7 +8,7 @@ use futures::{stream::select as stream_select, StreamExt}; use reth_beacon_consensus::EthBeaconConsensus; use reth_chainspec::ChainSpec; use reth_cli::chainspec::ChainSpecParser; -use reth_cli_commands::common::{AccessRights, Environment, EnvironmentArgs}; +use reth_cli_commands::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs}; use reth_cli_runner::CliContext; use reth_cli_util::get_secret_key; use reth_config::Config; @@ -22,10 +22,11 @@ use reth_exex::ExExManagerHandle; use reth_network::{BlockDownloaderProvider, NetworkEventListenerProvider, NetworkHandle}; use reth_network_api::NetworkInfo; use reth_network_p2p::{headers::client::HeadersClient, EthBlockClient}; -use reth_node_api::{NodeTypesWithDB, NodeTypesWithDBAdapter, NodeTypesWithEngine}; +use reth_node_api::NodeTypesWithDBAdapter; use reth_node_ethereum::EthExecutorProvider; use reth_provider::{ - BlockExecutionWriter, ChainSpecProvider, ProviderFactory, StageCheckpointReader, + providers::ProviderNodeTypes, BlockExecutionWriter, ChainSpecProvider, ProviderFactory, + StageCheckpointReader, }; use reth_prune::PruneModes; use reth_stages::{ @@ -58,7 +59,7 @@ pub struct Command { } impl> Command { - fn build_pipeline, Client>( + fn build_pipeline, Client>( &self, config: &Config, client: Client, @@ -116,7 +117,7 @@ impl> Command { Ok(pipeline) } - async fn build_network>( + async fn build_network>( &self, config: &Config, task_executor: TaskExecutor, @@ -160,7 +161,7 @@ impl> Command { } /// Execute `execution-debug` command - pub async fn execute>( + pub async fn execute>( self, ctx: CliContext, ) -> eyre::Result<()> { diff --git a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs index d5bb8a87b22..ce5f318632e 100644 --- a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs +++ b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs @@ -10,7 +10,7 @@ use clap::Parser; use reth_beacon_consensus::EthBeaconConsensus; use reth_chainspec::ChainSpec; use reth_cli::chainspec::ChainSpecParser; -use reth_cli_commands::common::{AccessRights, Environment, EnvironmentArgs}; +use reth_cli_commands::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs}; use reth_cli_runner::CliContext; use reth_cli_util::get_secret_key; use reth_config::Config; @@ -19,12 +19,11 @@ use reth_evm::execute::{BlockExecutorProvider, Executor}; use reth_execution_types::ExecutionOutcome; use reth_network::{BlockDownloaderProvider, NetworkHandle}; use reth_network_api::NetworkInfo; -use reth_node_api::{NodeTypesWithDB, NodeTypesWithEngine}; use reth_node_ethereum::EthExecutorProvider; use reth_provider::{ - writer::UnifiedStorageWriter, AccountExtReader, ChainSpecProvider, HashingWriter, - HeaderProvider, LatestStateProviderRef, OriginalValuesKnown, ProviderFactory, - StageCheckpointReader, StateWriter, StorageReader, + providers::ProviderNodeTypes, writer::UnifiedStorageWriter, AccountExtReader, + ChainSpecProvider, HashingWriter, HeaderProvider, LatestStateProviderRef, OriginalValuesKnown, + ProviderFactory, StageCheckpointReader, StateWriter, StorageReader, }; use reth_revm::database::StateProviderDatabase; use reth_stages::StageId; @@ -56,7 +55,7 @@ pub struct Command { } impl> Command { - async fn build_network>( + async fn build_network>( &self, config: &Config, task_executor: TaskExecutor, @@ -78,7 +77,7 @@ impl> Command { } /// Execute `debug in-memory-merkle` command - pub async fn execute>( + pub async fn execute>( self, ctx: CliContext, ) -> eyre::Result<()> { diff --git a/bin/reth/src/commands/debug_cmd/merkle.rs b/bin/reth/src/commands/debug_cmd/merkle.rs index 9c77c70abc7..db4cd952e8d 100644 --- a/bin/reth/src/commands/debug_cmd/merkle.rs +++ b/bin/reth/src/commands/debug_cmd/merkle.rs @@ -6,7 +6,7 @@ use clap::Parser; use reth_beacon_consensus::EthBeaconConsensus; use reth_chainspec::ChainSpec; use reth_cli::chainspec::ChainSpecParser; -use reth_cli_commands::common::{AccessRights, Environment, EnvironmentArgs}; +use reth_cli_commands::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs}; use reth_cli_runner::CliContext; use reth_cli_util::get_secret_key; use reth_config::Config; @@ -17,12 +17,11 @@ use reth_evm::execute::{BatchExecutor, BlockExecutorProvider}; use reth_network::{BlockDownloaderProvider, NetworkHandle}; use reth_network_api::NetworkInfo; use reth_network_p2p::full_block::FullBlockClient; -use reth_node_api::{NodeTypesWithDB, NodeTypesWithEngine}; use reth_node_ethereum::EthExecutorProvider; use reth_provider::{ - writer::UnifiedStorageWriter, BlockNumReader, BlockWriter, ChainSpecProvider, - DatabaseProviderFactory, HeaderProvider, LatestStateProviderRef, OriginalValuesKnown, - ProviderError, ProviderFactory, StateWriter, + providers::ProviderNodeTypes, writer::UnifiedStorageWriter, BlockNumReader, BlockWriter, + ChainSpecProvider, DatabaseProviderFactory, HeaderProvider, LatestStateProviderRef, + OriginalValuesKnown, ProviderError, ProviderFactory, StateWriter, }; use reth_revm::database::StateProviderDatabase; use reth_stages::{ @@ -56,7 +55,7 @@ pub struct Command { } impl> Command { - async fn build_network>( + async fn build_network>( &self, config: &Config, task_executor: TaskExecutor, @@ -78,7 +77,7 @@ impl> Command { } /// Execute `merkle-debug` command - pub async fn execute>( + pub async fn execute>( self, ctx: CliContext, ) -> eyre::Result<()> { diff --git a/bin/reth/src/commands/debug_cmd/mod.rs b/bin/reth/src/commands/debug_cmd/mod.rs index 51681e8c59e..65329f41400 100644 --- a/bin/reth/src/commands/debug_cmd/mod.rs +++ b/bin/reth/src/commands/debug_cmd/mod.rs @@ -3,8 +3,8 @@ use clap::{Parser, Subcommand}; use reth_chainspec::ChainSpec; use reth_cli::chainspec::ChainSpecParser; +use reth_cli_commands::common::CliNodeTypes; use reth_cli_runner::CliContext; -use reth_node_api::NodeTypesWithEngine; use reth_node_ethereum::EthEngineTypes; mod build_block; @@ -37,9 +37,7 @@ pub enum Subcommands { impl> Command { /// Execute `debug` command - pub async fn execute< - N: NodeTypesWithEngine, - >( + pub async fn execute>( self, ctx: CliContext, ) -> eyre::Result<()> { diff --git a/bin/reth/src/commands/debug_cmd/replay_engine.rs b/bin/reth/src/commands/debug_cmd/replay_engine.rs index 9314a439265..7daead83a84 100644 --- a/bin/reth/src/commands/debug_cmd/replay_engine.rs +++ b/bin/reth/src/commands/debug_cmd/replay_engine.rs @@ -8,7 +8,7 @@ use reth_blockchain_tree::{ }; use reth_chainspec::ChainSpec; use reth_cli::chainspec::ChainSpecParser; -use reth_cli_commands::common::{AccessRights, Environment, EnvironmentArgs}; +use reth_cli_commands::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs}; use reth_cli_runner::CliContext; use reth_cli_util::get_secret_key; use reth_config::Config; @@ -18,13 +18,12 @@ use reth_engine_util::engine_store::{EngineMessageStore, StoredEngineApiMessage} use reth_fs_util as fs; use reth_network::{BlockDownloaderProvider, NetworkHandle}; use reth_network_api::NetworkInfo; -use reth_node_api::{ - EngineApiMessageVersion, NodeTypesWithDB, NodeTypesWithDBAdapter, NodeTypesWithEngine, -}; +use reth_node_api::{EngineApiMessageVersion, NodeTypesWithDBAdapter}; use reth_node_ethereum::{EthEngineTypes, EthEvmConfig, EthExecutorProvider}; use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService}; use reth_provider::{ - providers::BlockchainProvider, CanonStateSubscriptions, ChainSpecProvider, ProviderFactory, + providers::{BlockchainProvider, ProviderNodeTypes}, + CanonStateSubscriptions, ChainSpecProvider, ProviderFactory, }; use reth_prune::PruneModes; use reth_stages::Pipeline; @@ -56,7 +55,7 @@ pub struct Command { } impl> Command { - async fn build_network>( + async fn build_network>( &self, config: &Config, task_executor: TaskExecutor, @@ -78,9 +77,7 @@ impl> Command { } /// Execute `debug replay-engine` command - pub async fn execute< - N: NodeTypesWithEngine, - >( + pub async fn execute>( self, ctx: CliContext, ) -> eyre::Result<()> { diff --git a/crates/cli/commands/src/common.rs b/crates/cli/commands/src/common.rs index 21d24a7ff7a..0e4eb2723c3 100644 --- a/crates/cli/commands/src/common.rs +++ b/crates/cli/commands/src/common.rs @@ -53,7 +53,7 @@ pub struct EnvironmentArgs { impl> EnvironmentArgs { /// Initializes environment according to [`AccessRights`] and returns an instance of /// [`Environment`]. - pub fn init>( + pub fn init>( &self, access: AccessRights, ) -> eyre::Result> { @@ -105,7 +105,7 @@ impl> Environmen /// If it's a read-write environment and an issue is found, it will attempt to heal (including a /// pipeline unwind). Otherwise, it will print out an warning, advising the user to restart the /// node to heal. - fn create_provider_factory>( + fn create_provider_factory>( &self, config: &Config, db: Arc, @@ -188,3 +188,8 @@ impl AccessRights { matches!(self, Self::RW) } } + +/// Helper trait with a common set of requirements for the +/// [`NodeTypes`](reth_node_builder::NodeTypes) in CLI. +pub trait CliNodeTypes: NodeTypesWithEngine {} +impl CliNodeTypes for N where N: NodeTypesWithEngine {} diff --git a/crates/cli/commands/src/db/checksum.rs b/crates/cli/commands/src/db/checksum.rs index 4c986dc0332..76d92962f72 100644 --- a/crates/cli/commands/src/db/checksum.rs +++ b/crates/cli/commands/src/db/checksum.rs @@ -1,11 +1,14 @@ -use crate::db::get::{maybe_json_value_parser, table_key}; +use crate::{ + common::CliNodeTypes, + db::get::{maybe_json_value_parser, table_key}, +}; use ahash::RandomState; use clap::Parser; use reth_chainspec::EthereumHardforks; use reth_db::{DatabaseEnv, RawKey, RawTable, RawValue, TableViewer, Tables}; use reth_db_api::{cursor::DbCursorRO, table::Table, transaction::DbTx}; use reth_db_common::DbTool; -use reth_node_builder::{NodeTypesWithDB, NodeTypesWithDBAdapter, NodeTypesWithEngine}; +use reth_node_builder::{NodeTypesWithDB, NodeTypesWithDBAdapter}; use reth_provider::{providers::ProviderNodeTypes, DBProvider}; use std::{ hash::{BuildHasher, Hasher}, @@ -36,7 +39,7 @@ pub struct Command { impl Command { /// Execute `db checksum` command - pub fn execute>( + pub fn execute>( self, tool: &DbTool>>, ) -> eyre::Result<()> { diff --git a/crates/cli/commands/src/db/mod.rs b/crates/cli/commands/src/db/mod.rs index e1a9a90bacc..e80b51160e2 100644 --- a/crates/cli/commands/src/db/mod.rs +++ b/crates/cli/commands/src/db/mod.rs @@ -1,10 +1,9 @@ -use crate::common::{AccessRights, Environment, EnvironmentArgs}; +use crate::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs}; use clap::{Parser, Subcommand}; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_cli::chainspec::ChainSpecParser; use reth_db::version::{get_db_version, DatabaseVersionError, DB_VERSION}; use reth_db_common::DbTool; -use reth_node_builder::NodeTypesWithEngine; use std::io::{self, Write}; mod checksum; @@ -65,9 +64,7 @@ macro_rules! db_ro_exec { impl> Command { /// Execute `db` command - pub async fn execute>( - self, - ) -> eyre::Result<()> { + pub async fn execute>(self) -> eyre::Result<()> { let data_dir = self.env.datadir.clone().resolve_datadir(self.env.chain.chain()); let db_path = data_dir.db(); let static_files_path = data_dir.static_files(); diff --git a/crates/cli/commands/src/db/stats.rs b/crates/cli/commands/src/db/stats.rs index 6865f01345e..71ea995800f 100644 --- a/crates/cli/commands/src/db/stats.rs +++ b/crates/cli/commands/src/db/stats.rs @@ -1,4 +1,4 @@ -use crate::db::checksum::ChecksumViewer; +use crate::{common::CliNodeTypes, db::checksum::ChecksumViewer}; use clap::Parser; use comfy_table::{Cell, Row, Table as ComfyTable}; use eyre::WrapErr; @@ -9,9 +9,7 @@ use reth_db::{mdbx, static_file::iter_static_files, DatabaseEnv, TableViewer, Ta use reth_db_api::database::Database; use reth_db_common::DbTool; use reth_fs_util as fs; -use reth_node_builder::{ - NodePrimitives, NodeTypesWithDB, NodeTypesWithDBAdapter, NodeTypesWithEngine, -}; +use reth_node_builder::{NodePrimitives, NodeTypesWithDB, NodeTypesWithDBAdapter}; use reth_node_core::dirs::{ChainPath, DataDirPath}; use reth_provider::providers::{ProviderNodeTypes, StaticFileProvider}; use reth_static_file_types::SegmentRangeInclusive; @@ -40,7 +38,7 @@ pub struct Command { impl Command { /// Execute `db stats` command - pub fn execute>( + pub fn execute>( self, data_dir: ChainPath, tool: &DbTool>>, diff --git a/crates/cli/commands/src/import.rs b/crates/cli/commands/src/import.rs index ebda2deafa6..539211a22f7 100644 --- a/crates/cli/commands/src/import.rs +++ b/crates/cli/commands/src/import.rs @@ -1,5 +1,5 @@ //! Command that initializes the node by importing a chain from a file. -use crate::common::{AccessRights, Environment, EnvironmentArgs}; +use crate::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs}; use alloy_primitives::B256; use clap::Parser; use futures::{Stream, StreamExt}; @@ -20,7 +20,6 @@ use reth_network_p2p::{ bodies::downloader::BodyDownloader, headers::downloader::{HeaderDownloader, SyncTarget}, }; -use reth_node_builder::NodeTypesWithEngine; use reth_node_core::version::SHORT_VERSION; use reth_node_events::node::NodeEvent; use reth_provider::{ @@ -60,7 +59,7 @@ impl> ImportComm /// Execute `import` command pub async fn execute(self, executor: F) -> eyre::Result<()> where - N: NodeTypesWithEngine, + N: CliNodeTypes, E: BlockExecutorProvider, F: FnOnce(Arc) -> E, { diff --git a/crates/cli/commands/src/init_cmd.rs b/crates/cli/commands/src/init_cmd.rs index 5fde9ac0d0b..83f471d629d 100644 --- a/crates/cli/commands/src/init_cmd.rs +++ b/crates/cli/commands/src/init_cmd.rs @@ -1,10 +1,9 @@ //! Command that initializes the node from a genesis file. -use crate::common::{AccessRights, Environment, EnvironmentArgs}; +use crate::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs}; use clap::Parser; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_cli::chainspec::ChainSpecParser; -use reth_node_builder::NodeTypesWithEngine; use reth_provider::BlockHashReader; use tracing::info; @@ -17,9 +16,7 @@ pub struct InitCommand { impl> InitCommand { /// Execute the `init` command - pub async fn execute>( - self, - ) -> eyre::Result<()> { + pub async fn execute>(self) -> eyre::Result<()> { info!(target: "reth::cli", "reth init starting"); let Environment { provider_factory, .. } = self.env.init::(AccessRights::RW)?; diff --git a/crates/cli/commands/src/init_state/mod.rs b/crates/cli/commands/src/init_state/mod.rs index adde88870fe..2aa2483fdda 100644 --- a/crates/cli/commands/src/init_state/mod.rs +++ b/crates/cli/commands/src/init_state/mod.rs @@ -1,12 +1,11 @@ //! Command that initializes the node from a genesis file. -use crate::common::{AccessRights, Environment, EnvironmentArgs}; +use crate::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs}; use alloy_primitives::{B256, U256}; use clap::Parser; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_cli::chainspec::ChainSpecParser; use reth_db_common::init::init_from_state_dump; -use reth_node_builder::NodeTypesWithEngine; use reth_primitives::SealedHeader; use reth_provider::{ BlockNumReader, DatabaseProviderFactory, StaticFileProviderFactory, StaticFileWriter, @@ -68,9 +67,7 @@ pub struct InitStateCommand { impl> InitStateCommand { /// Execute the `init` command - pub async fn execute>( - self, - ) -> eyre::Result<()> { + pub async fn execute>(self) -> eyre::Result<()> { info!(target: "reth::cli", "Reth init-state starting"); let Environment { config, provider_factory, .. } = self.env.init::(AccessRights::RW)?; diff --git a/crates/cli/commands/src/prune.rs b/crates/cli/commands/src/prune.rs index 7dbb66fc2fa..37f0637b0a5 100644 --- a/crates/cli/commands/src/prune.rs +++ b/crates/cli/commands/src/prune.rs @@ -1,9 +1,8 @@ //! Command that runs pruning without any limits. -use crate::common::{AccessRights, Environment, EnvironmentArgs}; +use crate::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs}; use clap::Parser; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_cli::chainspec::ChainSpecParser; -use reth_node_builder::NodeTypesWithEngine; use reth_prune::PrunerBuilder; use reth_static_file::StaticFileProducer; use tracing::info; @@ -17,9 +16,7 @@ pub struct PruneCommand { impl> PruneCommand { /// Execute the `prune` command - pub async fn execute>( - self, - ) -> eyre::Result<()> { + pub async fn execute>(self) -> eyre::Result<()> { let Environment { config, provider_factory, .. } = self.env.init::(AccessRights::RW)?; let prune_config = config.prune.unwrap_or_default(); diff --git a/crates/cli/commands/src/recover/mod.rs b/crates/cli/commands/src/recover/mod.rs index 3216449e49b..a2d94360227 100644 --- a/crates/cli/commands/src/recover/mod.rs +++ b/crates/cli/commands/src/recover/mod.rs @@ -1,10 +1,10 @@ //! `reth recover` command. +use crate::common::CliNodeTypes; use clap::{Parser, Subcommand}; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_cli::chainspec::ChainSpecParser; use reth_cli_runner::CliContext; -use reth_node_builder::NodeTypesWithEngine; mod storage_tries; @@ -24,7 +24,7 @@ pub enum Subcommands { impl> Command { /// Execute `recover` command - pub async fn execute>( + pub async fn execute>( self, ctx: CliContext, ) -> eyre::Result<()> { diff --git a/crates/cli/commands/src/recover/storage_tries.rs b/crates/cli/commands/src/recover/storage_tries.rs index 794058fac1d..f879c393c6b 100644 --- a/crates/cli/commands/src/recover/storage_tries.rs +++ b/crates/cli/commands/src/recover/storage_tries.rs @@ -1,4 +1,4 @@ -use crate::common::{AccessRights, Environment, EnvironmentArgs}; +use crate::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs}; use clap::Parser; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_cli::chainspec::ChainSpecParser; @@ -8,7 +8,6 @@ use reth_db_api::{ cursor::{DbCursorRO, DbDupCursorRW}, transaction::DbTx, }; -use reth_node_builder::NodeTypesWithEngine; use reth_provider::{BlockNumReader, HeaderProvider, ProviderError}; use reth_trie::StateRoot; use reth_trie_db::DatabaseStateRoot; @@ -23,7 +22,7 @@ pub struct Command { impl> Command { /// Execute `storage-tries` recovery command - pub async fn execute>( + pub async fn execute>( self, _ctx: CliContext, ) -> eyre::Result<()> { diff --git a/crates/cli/commands/src/stage/drop.rs b/crates/cli/commands/src/stage/drop.rs index 70b2caa8d16..49bbc55ec24 100644 --- a/crates/cli/commands/src/stage/drop.rs +++ b/crates/cli/commands/src/stage/drop.rs @@ -1,5 +1,5 @@ //! Database debugging tool -use crate::common::{AccessRights, Environment, EnvironmentArgs}; +use crate::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs}; use clap::Parser; use itertools::Itertools; use reth_chainspec::{EthChainSpec, EthereumHardforks}; @@ -10,7 +10,6 @@ use reth_db_common::{ init::{insert_genesis_header, insert_genesis_history, insert_genesis_state}, DbTool, }; -use reth_node_builder::NodeTypesWithEngine; use reth_node_core::args::StageEnum; use reth_provider::{ writer::UnifiedStorageWriter, DatabaseProviderFactory, StaticFileProviderFactory, @@ -30,9 +29,7 @@ pub struct Command { impl> Command { /// Execute `db` command - pub async fn execute>( - self, - ) -> eyre::Result<()> { + pub async fn execute>(self) -> eyre::Result<()> { let Environment { provider_factory, .. } = self.env.init::(AccessRights::RW)?; let tool = DbTool::new(provider_factory)?; diff --git a/crates/cli/commands/src/stage/dump/execution.rs b/crates/cli/commands/src/stage/dump/execution.rs index 709fc59190d..19704cb1c2f 100644 --- a/crates/cli/commands/src/stage/dump/execution.rs +++ b/crates/cli/commands/src/stage/dump/execution.rs @@ -7,7 +7,7 @@ use reth_db_api::{ }; use reth_db_common::DbTool; use reth_evm::{execute::BlockExecutorProvider, noop::NoopBlockExecutorProvider}; -use reth_node_builder::{NodeTypesWithDB, NodeTypesWithDBAdapter}; +use reth_node_builder::NodeTypesWithDB; use reth_node_core::dirs::{ChainPath, DataDirPath}; use reth_provider::{ providers::{ProviderNodeTypes, StaticFileProvider}, @@ -25,7 +25,7 @@ pub(crate) async fn dump_execution_stage( executor: E, ) -> eyre::Result<()> where - N: ProviderNodeTypes, + N: ProviderNodeTypes>, E: BlockExecutorProvider, { let (output_db, tip_block_number) = setup(from, to, &output_datadir.db(), db_tool)?; @@ -36,7 +36,7 @@ where if should_run { dry_run( - ProviderFactory::>>::new( + ProviderFactory::::new( Arc::new(output_db), db_tool.chain(), StaticFileProvider::read_write(output_datadir.static_files())?, diff --git a/crates/cli/commands/src/stage/dump/hashing_account.rs b/crates/cli/commands/src/stage/dump/hashing_account.rs index 738dcabafa7..97452cee892 100644 --- a/crates/cli/commands/src/stage/dump/hashing_account.rs +++ b/crates/cli/commands/src/stage/dump/hashing_account.rs @@ -6,7 +6,6 @@ use eyre::Result; use reth_db::{tables, DatabaseEnv}; use reth_db_api::{database::Database, table::TableImporter}; use reth_db_common::DbTool; -use reth_node_builder::NodeTypesWithDBAdapter; use reth_node_core::dirs::{ChainPath, DataDirPath}; use reth_provider::{ providers::{ProviderNodeTypes, StaticFileProvider}, @@ -15,7 +14,7 @@ use reth_provider::{ use reth_stages::{stages::AccountHashingStage, Stage, StageCheckpoint, UnwindInput}; use tracing::info; -pub(crate) async fn dump_hashing_account_stage( +pub(crate) async fn dump_hashing_account_stage>>( db_tool: &DbTool, from: BlockNumber, to: BlockNumber, @@ -37,7 +36,7 @@ pub(crate) async fn dump_hashing_account_stage( if should_run { dry_run( - ProviderFactory::>>::new( + ProviderFactory::::new( Arc::new(output_db), db_tool.chain(), StaticFileProvider::read_write(output_datadir.static_files())?, diff --git a/crates/cli/commands/src/stage/dump/hashing_storage.rs b/crates/cli/commands/src/stage/dump/hashing_storage.rs index 204c087a234..06b064bc02f 100644 --- a/crates/cli/commands/src/stage/dump/hashing_storage.rs +++ b/crates/cli/commands/src/stage/dump/hashing_storage.rs @@ -5,7 +5,6 @@ use eyre::Result; use reth_db::{tables, DatabaseEnv}; use reth_db_api::{database::Database, table::TableImporter}; use reth_db_common::DbTool; -use reth_node_builder::NodeTypesWithDBAdapter; use reth_node_core::dirs::{ChainPath, DataDirPath}; use reth_provider::{ providers::{ProviderNodeTypes, StaticFileProvider}, @@ -14,7 +13,7 @@ use reth_provider::{ use reth_stages::{stages::StorageHashingStage, Stage, StageCheckpoint, UnwindInput}; use tracing::info; -pub(crate) async fn dump_hashing_storage_stage( +pub(crate) async fn dump_hashing_storage_stage>>( db_tool: &DbTool, from: u64, to: u64, @@ -27,7 +26,7 @@ pub(crate) async fn dump_hashing_storage_stage( if should_run { dry_run( - ProviderFactory::>>::new( + ProviderFactory::::new( Arc::new(output_db), db_tool.chain(), StaticFileProvider::read_write(output_datadir.static_files())?, diff --git a/crates/cli/commands/src/stage/dump/merkle.rs b/crates/cli/commands/src/stage/dump/merkle.rs index f7e9e2fc1af..f2688c365e1 100644 --- a/crates/cli/commands/src/stage/dump/merkle.rs +++ b/crates/cli/commands/src/stage/dump/merkle.rs @@ -9,7 +9,6 @@ use reth_db_api::{database::Database, table::TableImporter}; use reth_db_common::DbTool; use reth_evm::noop::NoopBlockExecutorProvider; use reth_exex::ExExManagerHandle; -use reth_node_builder::NodeTypesWithDBAdapter; use reth_node_core::dirs::{ChainPath, DataDirPath}; use reth_provider::{ providers::{ProviderNodeTypes, StaticFileProvider}, @@ -25,7 +24,7 @@ use reth_stages::{ }; use tracing::info; -pub(crate) async fn dump_merkle_stage( +pub(crate) async fn dump_merkle_stage>>( db_tool: &DbTool, from: BlockNumber, to: BlockNumber, @@ -54,7 +53,7 @@ pub(crate) async fn dump_merkle_stage( if should_run { dry_run( - ProviderFactory::>>::new( + ProviderFactory::::new( Arc::new(output_db), db_tool.chain(), StaticFileProvider::read_write(output_datadir.static_files())?, diff --git a/crates/cli/commands/src/stage/dump/mod.rs b/crates/cli/commands/src/stage/dump/mod.rs index 6fd2f23aa0e..36b8fb12258 100644 --- a/crates/cli/commands/src/stage/dump/mod.rs +++ b/crates/cli/commands/src/stage/dump/mod.rs @@ -1,5 +1,5 @@ //! Database debugging tool -use crate::common::{AccessRights, Environment, EnvironmentArgs}; +use crate::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs}; use clap::Parser; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_cli::chainspec::ChainSpecParser; @@ -10,7 +10,7 @@ use reth_db_api::{ }; use reth_db_common::DbTool; use reth_evm::execute::BlockExecutorProvider; -use reth_node_builder::{NodeTypesWithDB, NodeTypesWithEngine}; +use reth_node_builder::NodeTypesWithDB; use reth_node_core::{ args::DatadirArgs, dirs::{DataDirPath, PlatformPath}, @@ -92,7 +92,7 @@ impl> Command /// Execute `dump-stage` command pub async fn execute(self, executor: F) -> eyre::Result<()> where - N: NodeTypesWithEngine, + N: CliNodeTypes, E: BlockExecutorProvider, F: FnOnce(Arc) -> E, { diff --git a/crates/cli/commands/src/stage/mod.rs b/crates/cli/commands/src/stage/mod.rs index 562bd73a28d..b9e0725428a 100644 --- a/crates/cli/commands/src/stage/mod.rs +++ b/crates/cli/commands/src/stage/mod.rs @@ -2,12 +2,12 @@ use std::sync::Arc; +use crate::common::CliNodeTypes; use clap::{Parser, Subcommand}; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_cli::chainspec::ChainSpecParser; use reth_cli_runner::CliContext; use reth_evm::execute::BlockExecutorProvider; -use reth_node_builder::NodeTypesWithEngine; pub mod drop; pub mod dump; @@ -43,7 +43,7 @@ impl> Command /// Execute `stage` command pub async fn execute(self, ctx: CliContext, executor: F) -> eyre::Result<()> where - N: NodeTypesWithEngine, + N: CliNodeTypes, E: BlockExecutorProvider, F: FnOnce(Arc) -> E, { diff --git a/crates/cli/commands/src/stage/run.rs b/crates/cli/commands/src/stage/run.rs index 1ac2a12d6fa..f3c3bbef965 100644 --- a/crates/cli/commands/src/stage/run.rs +++ b/crates/cli/commands/src/stage/run.rs @@ -2,7 +2,7 @@ //! //! Stage debugging tool -use crate::common::{AccessRights, Environment, EnvironmentArgs}; +use crate::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs}; use alloy_eips::BlockHashOrNumber; use clap::Parser; use reth_beacon_consensus::EthBeaconConsensus; @@ -19,7 +19,6 @@ use reth_evm::execute::BlockExecutorProvider; use reth_exex::ExExManagerHandle; use reth_network::BlockDownloaderProvider; use reth_network_p2p::HeadersClient; -use reth_node_builder::NodeTypesWithEngine; use reth_node_core::{ args::{NetworkArgs, StageEnum}, version::{ @@ -106,7 +105,7 @@ impl> Command /// Execute `stage` command pub async fn execute(self, ctx: CliContext, executor: F) -> eyre::Result<()> where - N: NodeTypesWithEngine, + N: CliNodeTypes, E: BlockExecutorProvider, F: FnOnce(Arc) -> E, { diff --git a/crates/cli/commands/src/stage/unwind.rs b/crates/cli/commands/src/stage/unwind.rs index a5c9956c95b..e71861a988d 100644 --- a/crates/cli/commands/src/stage/unwind.rs +++ b/crates/cli/commands/src/stage/unwind.rs @@ -1,6 +1,6 @@ //! Unwinding a certain block range -use crate::common::{AccessRights, Environment, EnvironmentArgs}; +use crate::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs}; use alloy_eips::BlockHashOrNumber; use alloy_primitives::{BlockNumber, B256}; use clap::{Parser, Subcommand}; @@ -13,7 +13,6 @@ use reth_db::DatabaseEnv; use reth_downloaders::{bodies::noop::NoopBodiesDownloader, headers::noop::NoopHeaderDownloader}; use reth_evm::noop::NoopBlockExecutorProvider; use reth_exex::ExExManagerHandle; -use reth_node_builder::{NodeTypesWithDB, NodeTypesWithEngine}; use reth_node_core::args::NetworkArgs; use reth_provider::{ providers::ProviderNodeTypes, BlockExecutionWriter, BlockNumReader, ChainSpecProvider, @@ -50,9 +49,7 @@ pub struct Command { impl> Command { /// Execute `db stage unwind` command - pub async fn execute>( - self, - ) -> eyre::Result<()> { + pub async fn execute>(self) -> eyre::Result<()> { let Environment { provider_factory, config, .. } = self.env.init::(AccessRights::RW)?; let range = self.command.unwind_range(provider_factory.clone())?; @@ -116,7 +113,7 @@ impl> Command Ok(()) } - fn build_pipeline>( + fn build_pipeline>( self, config: Config, provider_factory: ProviderFactory, diff --git a/crates/optimism/cli/src/commands/build_pipeline.rs b/crates/optimism/cli/src/commands/build_pipeline.rs index a197f93a8b4..88dc0989717 100644 --- a/crates/optimism/cli/src/commands/build_pipeline.rs +++ b/crates/optimism/cli/src/commands/build_pipeline.rs @@ -11,11 +11,13 @@ use reth_network_p2p::{ bodies::downloader::BodyDownloader, headers::downloader::{HeaderDownloader, SyncTarget}, }; -use reth_node_builder::NodeTypesWithDB; use reth_node_events::node::NodeEvent; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_evm::OpExecutorProvider; -use reth_provider::{BlockNumReader, ChainSpecProvider, HeaderProvider, ProviderFactory}; +use reth_provider::{ + providers::ProviderNodeTypes, BlockNumReader, ChainSpecProvider, HeaderProvider, + ProviderFactory, +}; use reth_prune::PruneModes; use reth_stages::{sets::DefaultStages, Pipeline, StageSet}; use reth_stages_types::StageId; @@ -36,7 +38,7 @@ pub(crate) async fn build_import_pipeline( disable_exec: bool, ) -> eyre::Result<(Pipeline, impl Stream)> where - N: NodeTypesWithDB, + N: ProviderNodeTypes, C: Consensus + 'static, { if !file_client.has_canonical_blocks() { diff --git a/crates/optimism/cli/src/commands/import.rs b/crates/optimism/cli/src/commands/import.rs index e5f037c3d5c..5e3de5a8671 100644 --- a/crates/optimism/cli/src/commands/import.rs +++ b/crates/optimism/cli/src/commands/import.rs @@ -2,14 +2,13 @@ //! file. use clap::Parser; use reth_cli::chainspec::ChainSpecParser; -use reth_cli_commands::common::{AccessRights, Environment, EnvironmentArgs}; +use reth_cli_commands::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs}; use reth_consensus::noop::NoopConsensus; use reth_db::tables; use reth_db_api::transaction::DbTx; use reth_downloaders::file_client::{ ChunkedFileReader, FileClient, DEFAULT_BYTE_LEN_CHUNK_CHAIN_FILE, }; -use reth_node_builder::NodeTypesWithEngine; use reth_node_core::version::SHORT_VERSION; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_primitives::bedrock::is_dup_tx; @@ -42,9 +41,7 @@ pub struct ImportOpCommand { impl> ImportOpCommand { /// Execute `import` command - pub async fn execute>( - self, - ) -> eyre::Result<()> { + pub async fn execute>(self) -> eyre::Result<()> { info!(target: "reth::cli", "reth {} starting", SHORT_VERSION); info!(target: "reth::cli", diff --git a/crates/optimism/cli/src/commands/import_receipts.rs b/crates/optimism/cli/src/commands/import_receipts.rs index ca82cf73ea4..049e160ae23 100644 --- a/crates/optimism/cli/src/commands/import_receipts.rs +++ b/crates/optimism/cli/src/commands/import_receipts.rs @@ -5,14 +5,13 @@ use std::path::{Path, PathBuf}; use clap::Parser; use reth_cli::chainspec::ChainSpecParser; -use reth_cli_commands::common::{AccessRights, Environment, EnvironmentArgs}; +use reth_cli_commands::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs}; use reth_db::tables; use reth_downloaders::{ file_client::{ChunkedFileReader, DEFAULT_BYTE_LEN_CHUNK_CHAIN_FILE}, receipt_file_client::ReceiptFileClient, }; use reth_execution_types::ExecutionOutcome; -use reth_node_builder::{NodeTypesWithDB, NodeTypesWithEngine}; use reth_node_core::version::SHORT_VERSION; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_primitives::bedrock::is_dup_tx; @@ -48,9 +47,7 @@ pub struct ImportReceiptsOpCommand { impl> ImportReceiptsOpCommand { /// Execute `import` command - pub async fn execute>( - self, - ) -> eyre::Result<()> { + pub async fn execute>(self) -> eyre::Result<()> { info!(target: "reth::cli", "reth {} starting", SHORT_VERSION); debug!(target: "reth::cli", @@ -88,7 +85,7 @@ pub async fn import_receipts_from_file( filter: F, ) -> eyre::Result<()> where - N: NodeTypesWithDB, + N: ProviderNodeTypes, P: AsRef, F: FnMut(u64, &mut Receipts) -> usize, { diff --git a/crates/optimism/cli/src/commands/init_state.rs b/crates/optimism/cli/src/commands/init_state.rs index 6be9b73c765..6a36f492c50 100644 --- a/crates/optimism/cli/src/commands/init_state.rs +++ b/crates/optimism/cli/src/commands/init_state.rs @@ -2,9 +2,8 @@ use clap::Parser; use reth_cli::chainspec::ChainSpecParser; -use reth_cli_commands::common::{AccessRights, Environment}; +use reth_cli_commands::common::{AccessRights, CliNodeTypes, Environment}; use reth_db_common::init::init_from_state_dump; -use reth_node_builder::NodeTypesWithEngine; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_primitives::bedrock::{BEDROCK_HEADER, BEDROCK_HEADER_HASH, BEDROCK_HEADER_TTD}; use reth_primitives::SealedHeader; @@ -36,9 +35,7 @@ pub struct InitStateCommandOp { impl> InitStateCommandOp { /// Execute the `init` command - pub async fn execute>( - self, - ) -> eyre::Result<()> { + pub async fn execute>(self) -> eyre::Result<()> { info!(target: "reth::cli", "Reth init-state starting"); let Environment { config, provider_factory, .. } = From bf92a5fb59861ccadc664c4b18f228a787f0e606 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Sat, 16 Nov 2024 18:36:57 +0100 Subject: [PATCH 208/211] feat: split reth-payload-primitives (#12600) --- .github/assets/check_wasm.sh | 1 + Cargo.lock | 37 ++++-- Cargo.toml | 2 + crates/consensus/beacon/Cargo.toml | 1 + crates/consensus/beacon/src/engine/mod.rs | 3 +- crates/e2e-test-utils/Cargo.toml | 1 + crates/e2e-test-utils/src/payload.rs | 5 +- crates/engine/local/Cargo.toml | 1 + crates/engine/local/src/miner.rs | 5 +- crates/engine/primitives/Cargo.toml | 1 + crates/engine/primitives/src/message.rs | 2 +- crates/engine/tree/Cargo.toml | 1 + crates/engine/tree/src/tree/mod.rs | 3 +- crates/ethereum/payload/Cargo.toml | 1 + crates/ethereum/payload/src/lib.rs | 3 +- crates/node/api/Cargo.toml | 1 + crates/node/api/src/lib.rs | 4 + crates/node/api/src/node.rs | 2 +- crates/node/builder/Cargo.toml | 1 - crates/node/builder/src/launch/engine.rs | 4 +- crates/node/builder/src/rpc.rs | 2 +- crates/optimism/payload/Cargo.toml | 1 + crates/optimism/payload/src/builder.rs | 3 +- crates/payload/basic/Cargo.toml | 1 + crates/payload/basic/src/lib.rs | 5 +- crates/payload/builder-primitives/Cargo.toml | 33 ++++++ .../payload/builder-primitives/src/error.rs | 58 +++++++++ .../src/events.rs | 2 +- crates/payload/builder-primitives/src/lib.rs | 19 +++ .../payload/builder-primitives/src/traits.rs | 111 ++++++++++++++++++ crates/payload/builder/Cargo.toml | 1 + crates/payload/builder/src/lib.rs | 3 +- crates/payload/builder/src/service.rs | 6 +- crates/payload/builder/src/test_utils.rs | 3 +- crates/payload/builder/src/traits.rs | 5 +- crates/payload/primitives/Cargo.toml | 11 -- crates/payload/primitives/src/error.rs | 57 --------- crates/payload/primitives/src/lib.rs | 9 +- crates/payload/primitives/src/traits.rs | 109 ----------------- crates/rpc/rpc-engine-api/Cargo.toml | 1 + crates/rpc/rpc-engine-api/src/error.rs | 3 +- examples/custom-engine-types/Cargo.toml | 1 - 42 files changed, 301 insertions(+), 222 deletions(-) create mode 100644 crates/payload/builder-primitives/Cargo.toml create mode 100644 crates/payload/builder-primitives/src/error.rs rename crates/payload/{primitives => builder-primitives}/src/events.rs (98%) create mode 100644 crates/payload/builder-primitives/src/lib.rs create mode 100644 crates/payload/builder-primitives/src/traits.rs diff --git a/.github/assets/check_wasm.sh b/.github/assets/check_wasm.sh index c34f82d2e31..0d9c9b34a03 100755 --- a/.github/assets/check_wasm.sh +++ b/.github/assets/check_wasm.sh @@ -52,6 +52,7 @@ exclude_crates=( reth-optimism-payload-builder reth-optimism-rpc reth-payload-builder + reth-payload-builder-primitives reth-payload-primitives reth-rpc reth-rpc-api diff --git a/Cargo.lock b/Cargo.lock index 2b6ea4f3431..fefa6fb5c1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2867,7 +2867,6 @@ dependencies = [ "reth-node-core", "reth-node-ethereum", "reth-payload-builder", - "reth-primitives", "reth-tracing", "reth-trie-db", "serde", @@ -6436,6 +6435,7 @@ dependencies = [ "reth-evm", "reth-metrics", "reth-payload-builder", + "reth-payload-builder-primitives", "reth-payload-primitives", "reth-primitives", "reth-primitives-traits", @@ -6480,6 +6480,7 @@ dependencies = [ "reth-network-p2p", "reth-node-types", "reth-payload-builder", + "reth-payload-builder-primitives", "reth-payload-primitives", "reth-payload-validator", "reth-primitives", @@ -7103,6 +7104,7 @@ dependencies = [ "reth-network-peers", "reth-node-builder", "reth-payload-builder", + "reth-payload-builder-primitives", "reth-payload-primitives", "reth-provider", "reth-rpc-layer", @@ -7164,6 +7166,7 @@ dependencies = [ "reth-ethereum-engine-primitives", "reth-evm", "reth-payload-builder", + "reth-payload-builder-primitives", "reth-payload-primitives", "reth-payload-validator", "reth-provider", @@ -7185,6 +7188,7 @@ dependencies = [ "futures", "reth-errors", "reth-execution-types", + "reth-payload-builder-primitives", "reth-payload-primitives", "reth-primitives", "reth-trie", @@ -7250,6 +7254,7 @@ dependencies = [ "reth-metrics", "reth-network-p2p", "reth-payload-builder", + "reth-payload-builder-primitives", "reth-payload-primitives", "reth-payload-validator", "reth-primitives", @@ -7456,6 +7461,7 @@ dependencies = [ "reth-evm-ethereum", "reth-execution-types", "reth-payload-builder", + "reth-payload-builder-primitives", "reth-payload-primitives", "reth-primitives", "reth-provider", @@ -7936,6 +7942,7 @@ dependencies = [ "reth-network-api", "reth-node-core", "reth-node-types", + "reth-payload-builder-primitives", "reth-payload-primitives", "reth-provider", "reth-tasks", @@ -7983,7 +7990,6 @@ dependencies = [ "reth-node-events", "reth-node-metrics", "reth-payload-builder", - "reth-payload-primitives", "reth-payload-validator", "reth-primitives", "reth-provider", @@ -8360,6 +8366,7 @@ dependencies = [ "reth-optimism-evm", "reth-optimism-forks", "reth-payload-builder", + "reth-payload-builder-primitives", "reth-payload-primitives", "reth-payload-util", "reth-primitives", @@ -8459,6 +8466,7 @@ dependencies = [ "reth-chain-state", "reth-ethereum-engine-primitives", "reth-metrics", + "reth-payload-builder-primitives", "reth-payload-primitives", "reth-primitives", "revm", @@ -8468,28 +8476,38 @@ dependencies = [ ] [[package]] -name = "reth-payload-primitives" +name = "reth-payload-builder-primitives" version = "1.1.1" dependencies = [ - "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", "async-trait", - "op-alloy-rpc-types-engine", "pin-project", - "reth-chain-state", - "reth-chainspec", "reth-errors", - "reth-primitives", + "reth-payload-primitives", "reth-transaction-pool", "revm-primitives", - "serde", "thiserror 1.0.69", "tokio", "tokio-stream", "tracing", ] +[[package]] +name = "reth-payload-primitives" +version = "1.1.1" +dependencies = [ + "alloy-eips", + "alloy-primitives", + "alloy-rpc-types-engine", + "op-alloy-rpc-types-engine", + "reth-chain-state", + "reth-chainspec", + "reth-primitives", + "serde", + "thiserror 1.0.69", +] + [[package]] name = "reth-payload-util" version = "1.1.1" @@ -8887,6 +8905,7 @@ dependencies = [ "reth-evm", "reth-metrics", "reth-payload-builder", + "reth-payload-builder-primitives", "reth-payload-primitives", "reth-primitives", "reth-provider", diff --git a/Cargo.toml b/Cargo.toml index 398be3e5faf..2f2f9aa884a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -80,6 +80,7 @@ members = [ "crates/optimism/storage", "crates/payload/basic/", "crates/payload/builder/", + "crates/payload/builder-primitives/", "crates/payload/primitives/", "crates/payload/validator/", "crates/payload/util/", @@ -380,6 +381,7 @@ reth-optimism-primitives = { path = "crates/optimism/primitives" } reth-optimism-rpc = { path = "crates/optimism/rpc" } reth-optimism-storage = { path = "crates/optimism/storage" } reth-payload-builder = { path = "crates/payload/builder" } +reth-payload-builder-primitives = { path = "crates/payload/builder-primitives" } reth-payload-primitives = { path = "crates/payload/primitives" } reth-payload-validator = { path = "crates/payload/validator" } reth-payload-util = { path = "crates/payload/util" } diff --git a/crates/consensus/beacon/Cargo.toml b/crates/consensus/beacon/Cargo.toml index d926fc09c35..245ebe8541e 100644 --- a/crates/consensus/beacon/Cargo.toml +++ b/crates/consensus/beacon/Cargo.toml @@ -20,6 +20,7 @@ reth-errors.workspace = true reth-provider.workspace = true reth-tasks.workspace = true reth-payload-builder.workspace = true +reth-payload-builder-primitives.workspace = true reth-payload-primitives.workspace = true reth-payload-validator.workspace = true reth-prune.workspace = true diff --git a/crates/consensus/beacon/src/engine/mod.rs b/crates/consensus/beacon/src/engine/mod.rs index bc6bd3bc4f4..0b93ae0f29a 100644 --- a/crates/consensus/beacon/src/engine/mod.rs +++ b/crates/consensus/beacon/src/engine/mod.rs @@ -23,7 +23,8 @@ use reth_network_p2p::{ }; use reth_node_types::NodeTypesWithEngine; use reth_payload_builder::PayloadBuilderHandle; -use reth_payload_primitives::{PayloadAttributes, PayloadBuilder, PayloadBuilderAttributes}; +use reth_payload_builder_primitives::PayloadBuilder; +use reth_payload_primitives::{PayloadAttributes, PayloadBuilderAttributes}; use reth_payload_validator::ExecutionPayloadValidator; use reth_primitives::{Head, SealedBlock, SealedHeader}; use reth_provider::{ diff --git a/crates/e2e-test-utils/Cargo.toml b/crates/e2e-test-utils/Cargo.toml index e56449551bb..c4c74ebcdf1 100644 --- a/crates/e2e-test-utils/Cargo.toml +++ b/crates/e2e-test-utils/Cargo.toml @@ -17,6 +17,7 @@ reth-tracing.workspace = true reth-db = { workspace = true, features = ["test-utils"] } reth-rpc-layer.workspace = true reth-payload-builder = { workspace = true, features = ["test-utils"] } +reth-payload-builder-primitives.workspace = true reth-payload-primitives.workspace = true reth-provider.workspace = true reth-node-builder = { workspace = true, features = ["test-utils"] } diff --git a/crates/e2e-test-utils/src/payload.rs b/crates/e2e-test-utils/src/payload.rs index 29aa11895b7..7828f61c2af 100644 --- a/crates/e2e-test-utils/src/payload.rs +++ b/crates/e2e-test-utils/src/payload.rs @@ -1,7 +1,8 @@ use futures_util::StreamExt; -use reth::api::{BuiltPayload, PayloadBuilderAttributes}; +use reth::api::BuiltPayload; use reth_payload_builder::{PayloadBuilderHandle, PayloadId}; -use reth_payload_primitives::{Events, PayloadBuilder, PayloadTypes}; +use reth_payload_builder_primitives::{Events, PayloadBuilder}; +use reth_payload_primitives::{PayloadBuilderAttributes, PayloadTypes}; use tokio_stream::wrappers::BroadcastStream; /// Helper for payload operations diff --git a/crates/engine/local/Cargo.toml b/crates/engine/local/Cargo.toml index 2ab448e3bbf..a1b74d13fee 100644 --- a/crates/engine/local/Cargo.toml +++ b/crates/engine/local/Cargo.toml @@ -19,6 +19,7 @@ reth-engine-tree.workspace = true reth-evm.workspace = true reth-ethereum-engine-primitives.workspace = true reth-payload-builder.workspace = true +reth-payload-builder-primitives.workspace = true reth-payload-primitives.workspace = true reth-payload-validator.workspace = true reth-provider.workspace = true diff --git a/crates/engine/local/src/miner.rs b/crates/engine/local/src/miner.rs index 2085aa81f9b..3a0f5a2f192 100644 --- a/crates/engine/local/src/miner.rs +++ b/crates/engine/local/src/miner.rs @@ -7,9 +7,8 @@ use futures_util::{stream::Fuse, StreamExt}; use reth_chainspec::EthereumHardforks; use reth_engine_primitives::{BeaconEngineMessage, EngineApiMessageVersion, EngineTypes}; use reth_payload_builder::PayloadBuilderHandle; -use reth_payload_primitives::{ - BuiltPayload, PayloadAttributesBuilder, PayloadBuilder, PayloadKind, PayloadTypes, -}; +use reth_payload_builder_primitives::PayloadBuilder; +use reth_payload_primitives::{BuiltPayload, PayloadAttributesBuilder, PayloadKind, PayloadTypes}; use reth_provider::{BlockReader, ChainSpecProvider}; use reth_rpc_types_compat::engine::payload::block_to_payload; use reth_transaction_pool::TransactionPool; diff --git a/crates/engine/primitives/Cargo.toml b/crates/engine/primitives/Cargo.toml index de4786553d3..42cbd932d45 100644 --- a/crates/engine/primitives/Cargo.toml +++ b/crates/engine/primitives/Cargo.toml @@ -14,6 +14,7 @@ workspace = true # reth reth-execution-types.workspace = true reth-payload-primitives.workspace = true +reth-payload-builder-primitives.workspace = true reth-primitives.workspace = true reth-trie.workspace = true reth-errors.workspace = true diff --git a/crates/engine/primitives/src/message.rs b/crates/engine/primitives/src/message.rs index 11fd383a1e2..d8a4c1322ad 100644 --- a/crates/engine/primitives/src/message.rs +++ b/crates/engine/primitives/src/message.rs @@ -5,7 +5,7 @@ use alloy_rpc_types_engine::{ }; use futures::{future::Either, FutureExt}; use reth_errors::RethResult; -use reth_payload_primitives::PayloadBuilderError; +use reth_payload_builder_primitives::PayloadBuilderError; use std::{ fmt::Display, future::Future, diff --git a/crates/engine/tree/Cargo.toml b/crates/engine/tree/Cargo.toml index fb259d08560..278457145e7 100644 --- a/crates/engine/tree/Cargo.toml +++ b/crates/engine/tree/Cargo.toml @@ -23,6 +23,7 @@ reth-errors.workspace = true reth-evm.workspace = true reth-network-p2p.workspace = true reth-payload-builder.workspace = true +reth-payload-builder-primitives.workspace = true reth-payload-primitives.workspace = true reth-payload-validator.workspace = true reth-primitives.workspace = true diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index 67e692b5c6c..39843377684 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -33,7 +33,8 @@ use reth_engine_primitives::{ use reth_errors::{ConsensusError, ProviderResult}; use reth_evm::execute::BlockExecutorProvider; use reth_payload_builder::PayloadBuilderHandle; -use reth_payload_primitives::{PayloadAttributes, PayloadBuilder, PayloadBuilderAttributes}; +use reth_payload_builder_primitives::PayloadBuilder; +use reth_payload_primitives::{PayloadAttributes, PayloadBuilderAttributes}; use reth_payload_validator::ExecutionPayloadValidator; use reth_primitives::{Block, GotExpected, SealedBlock, SealedBlockWithSenders, SealedHeader}; use reth_provider::{ diff --git a/crates/ethereum/payload/Cargo.toml b/crates/ethereum/payload/Cargo.toml index a29cc473362..4e0880d1d15 100644 --- a/crates/ethereum/payload/Cargo.toml +++ b/crates/ethereum/payload/Cargo.toml @@ -18,6 +18,7 @@ reth-revm.workspace = true reth-transaction-pool.workspace = true reth-provider.workspace = true reth-payload-builder.workspace = true +reth-payload-builder-primitives.workspace = true reth-payload-primitives.workspace = true reth-execution-types.workspace = true reth-basic-payload-builder.workspace = true diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index 7d795c510e2..2b55ea87dd0 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -23,7 +23,8 @@ use reth_evm::{system_calls::SystemCaller, ConfigureEvm, NextBlockEnvAttributes} use reth_evm_ethereum::{eip6110::parse_deposits_from_receipts, EthEvmConfig}; use reth_execution_types::ExecutionOutcome; use reth_payload_builder::{EthBuiltPayload, EthPayloadBuilderAttributes}; -use reth_payload_primitives::{PayloadBuilderAttributes, PayloadBuilderError}; +use reth_payload_builder_primitives::PayloadBuilderError; +use reth_payload_primitives::PayloadBuilderAttributes; use reth_primitives::{ proofs::{self}, Block, BlockBody, EthereumHardforks, Receipt, diff --git a/crates/node/api/Cargo.toml b/crates/node/api/Cargo.toml index a4cc0eb7eb6..ab4595d3362 100644 --- a/crates/node/api/Cargo.toml +++ b/crates/node/api/Cargo.toml @@ -18,6 +18,7 @@ reth-evm.workspace = true reth-provider.workspace = true reth-engine-primitives.workspace = true reth-transaction-pool.workspace = true +reth-payload-builder-primitives.workspace = true reth-payload-primitives.workspace = true reth-tasks.workspace = true reth-network-api.workspace = true diff --git a/crates/node/api/src/lib.rs b/crates/node/api/src/lib.rs index 099cf82b5fe..105cac47d94 100644 --- a/crates/node/api/src/lib.rs +++ b/crates/node/api/src/lib.rs @@ -16,6 +16,10 @@ pub use reth_engine_primitives::*; pub use reth_payload_primitives as payload; pub use reth_payload_primitives::*; +/// Traits and helper types used to abstract over payload builder types. +pub use reth_payload_builder_primitives as payload_builder; +pub use reth_payload_builder_primitives::*; + /// Traits and helper types used to abstract over EVM methods and types. pub use reth_evm::{ConfigureEvm, ConfigureEvmEnv, NextBlockEnvAttributes}; diff --git a/crates/node/api/src/node.rs b/crates/node/api/src/node.rs index 90b9e2999bf..5d25d8d592c 100644 --- a/crates/node/api/src/node.rs +++ b/crates/node/api/src/node.rs @@ -9,7 +9,7 @@ use reth_evm::execute::BlockExecutorProvider; use reth_network_api::FullNetwork; use reth_node_core::node_config::NodeConfig; use reth_node_types::{NodeTypes, NodeTypesWithDB, NodeTypesWithEngine}; -use reth_payload_primitives::PayloadBuilder; +use reth_payload_builder_primitives::PayloadBuilder; use reth_provider::FullProvider; use reth_tasks::TaskExecutor; use reth_transaction_pool::TransactionPool; diff --git a/crates/node/builder/Cargo.toml b/crates/node/builder/Cargo.toml index b0b62d1b2ed..781112d93c8 100644 --- a/crates/node/builder/Cargo.toml +++ b/crates/node/builder/Cargo.toml @@ -41,7 +41,6 @@ reth-node-core.workspace = true reth-node-events.workspace = true reth-node-metrics.workspace = true reth-payload-builder.workspace = true -reth-payload-primitives.workspace = true reth-payload-validator.workspace = true reth-primitives.workspace = true reth-provider.workspace = true diff --git a/crates/node/builder/src/launch/engine.rs b/crates/node/builder/src/launch/engine.rs index 65433176ba9..86ab0b9a3d7 100644 --- a/crates/node/builder/src/launch/engine.rs +++ b/crates/node/builder/src/launch/engine.rs @@ -19,7 +19,8 @@ use reth_exex::ExExManagerHandle; use reth_network::{NetworkSyncUpdater, SyncState}; use reth_network_api::{BlockDownloaderProvider, NetworkEventListenerProvider}; use reth_node_api::{ - BuiltPayload, FullNodeTypes, NodeTypesWithEngine, PayloadAttributesBuilder, PayloadTypes, + BuiltPayload, FullNodeTypes, NodeTypesWithEngine, PayloadAttributesBuilder, PayloadBuilder, + PayloadTypes, }; use reth_node_core::{ dirs::{ChainPath, DataDirPath}, @@ -27,7 +28,6 @@ use reth_node_core::{ primitives::Head, }; use reth_node_events::{cl::ConsensusLayerHealthEvents, node}; -use reth_payload_primitives::PayloadBuilder; use reth_primitives::EthereumHardforks; use reth_provider::providers::{BlockchainProvider2, ProviderNodeTypes}; use reth_tasks::TaskExecutor; diff --git a/crates/node/builder/src/rpc.rs b/crates/node/builder/src/rpc.rs index 9680c221d7c..adee942748c 100644 --- a/crates/node/builder/src/rpc.rs +++ b/crates/node/builder/src/rpc.rs @@ -11,13 +11,13 @@ use alloy_rpc_types::engine::ClientVersionV1; use futures::TryFutureExt; use reth_node_api::{ AddOnsContext, EngineValidator, FullNodeComponents, NodeAddOns, NodeTypes, NodeTypesWithEngine, + PayloadBuilder, }; use reth_node_core::{ node_config::NodeConfig, version::{CARGO_PKG_VERSION, CLIENT_CODE, NAME_CLIENT, VERGEN_GIT_SHA}, }; use reth_payload_builder::PayloadStore; -use reth_payload_primitives::PayloadBuilder; use reth_provider::providers::ProviderNodeTypes; use reth_rpc::{ eth::{EthApiTypes, FullEthApiServer}, diff --git a/crates/optimism/payload/Cargo.toml b/crates/optimism/payload/Cargo.toml index 19a47be4951..7f47da7e236 100644 --- a/crates/optimism/payload/Cargo.toml +++ b/crates/optimism/payload/Cargo.toml @@ -22,6 +22,7 @@ reth-rpc-types-compat.workspace = true reth-evm.workspace = true reth-execution-types.workspace = true reth-payload-builder.workspace = true +reth-payload-builder-primitives.workspace = true reth-payload-util.workspace = true reth-payload-primitives = { workspace = true, features = ["op"] } reth-basic-payload-builder.workspace = true diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index 7047c587b0c..3644d8f71a5 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -15,7 +15,8 @@ use reth_execution_types::ExecutionOutcome; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_consensus::calculate_receipt_root_no_memo_optimism; use reth_optimism_forks::OpHardforks; -use reth_payload_primitives::{PayloadBuilderAttributes, PayloadBuilderError}; +use reth_payload_builder_primitives::PayloadBuilderError; +use reth_payload_primitives::PayloadBuilderAttributes; use reth_payload_util::PayloadTransactions; use reth_primitives::{proofs, Block, BlockBody, Receipt, SealedHeader, TransactionSigned, TxType}; use reth_provider::{ProviderError, StateProofProvider, StateProviderFactory, StateRootProvider}; diff --git a/crates/payload/basic/Cargo.toml b/crates/payload/basic/Cargo.toml index 5e9e524f79b..0315f73cae4 100644 --- a/crates/payload/basic/Cargo.toml +++ b/crates/payload/basic/Cargo.toml @@ -19,6 +19,7 @@ reth-primitives-traits.workspace = true reth-transaction-pool.workspace = true reth-provider.workspace = true reth-payload-builder.workspace = true +reth-payload-builder-primitives.workspace = true reth-payload-primitives.workspace = true reth-tasks.workspace = true reth-evm.workspace = true diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index a905f854448..e3193ec6deb 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -17,9 +17,8 @@ use futures_util::FutureExt; use reth_chainspec::EthereumHardforks; use reth_evm::state_change::post_block_withdrawals_balance_increments; use reth_payload_builder::{KeepPayloadJobAlive, PayloadId, PayloadJob, PayloadJobGenerator}; -use reth_payload_primitives::{ - BuiltPayload, PayloadBuilderAttributes, PayloadBuilderError, PayloadKind, -}; +use reth_payload_builder_primitives::PayloadBuilderError; +use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes, PayloadKind}; use reth_primitives::{proofs, SealedHeader}; use reth_primitives_traits::constants::RETH_CLIENT_VERSION; use reth_provider::{BlockReaderIdExt, CanonStateNotification, StateProviderFactory}; diff --git a/crates/payload/builder-primitives/Cargo.toml b/crates/payload/builder-primitives/Cargo.toml new file mode 100644 index 00000000000..c3665dbc58e --- /dev/null +++ b/crates/payload/builder-primitives/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "reth-payload-builder-primitives" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true +exclude.workspace = true + +[lints] +workspace = true + +[dependencies] +# reth +reth-errors.workspace = true +reth-payload-primitives.workspace = true +reth-transaction-pool.workspace = true +revm-primitives.workspace = true + +# alloy +alloy-primitives.workspace = true +alloy-rpc-types-engine = { workspace = true, features = ["serde"] } + +# async +async-trait.workspace = true +pin-project.workspace = true +tokio = { workspace = true, features = ["sync"] } +tokio-stream.workspace = true + +# misc +thiserror.workspace = true +tracing.workspace = true diff --git a/crates/payload/builder-primitives/src/error.rs b/crates/payload/builder-primitives/src/error.rs new file mode 100644 index 00000000000..0d988c829e4 --- /dev/null +++ b/crates/payload/builder-primitives/src/error.rs @@ -0,0 +1,58 @@ +//! Error types emitted by types or implementations of this crate. + +use alloy_primitives::B256; +use reth_errors::{ProviderError, RethError}; +use reth_transaction_pool::BlobStoreError; +use revm_primitives::EVMError; +use tokio::sync::oneshot; + +/// Possible error variants during payload building. +#[derive(Debug, thiserror::Error)] +pub enum PayloadBuilderError { + /// Thrown when the parent header cannot be found + #[error("missing parent header: {0}")] + MissingParentHeader(B256), + /// Thrown when the parent block is missing. + #[error("missing parent block {0}")] + MissingParentBlock(B256), + /// An oneshot channels has been closed. + #[error("sender has been dropped")] + ChannelClosed, + /// If there's no payload to resolve. + #[error("missing payload")] + MissingPayload, + /// Error occurring in the blob store. + #[error(transparent)] + BlobStore(#[from] BlobStoreError), + /// Other internal error + #[error(transparent)] + Internal(#[from] RethError), + /// Unrecoverable error during evm execution. + #[error("evm execution error: {0}")] + EvmExecutionError(EVMError), + /// Any other payload building errors. + #[error(transparent)] + Other(Box), +} + +impl PayloadBuilderError { + /// Create a new error from a boxed error. + pub fn other(error: E) -> Self + where + E: core::error::Error + Send + Sync + 'static, + { + Self::Other(Box::new(error)) + } +} + +impl From for PayloadBuilderError { + fn from(error: ProviderError) -> Self { + Self::Internal(RethError::Provider(error)) + } +} + +impl From for PayloadBuilderError { + fn from(_: oneshot::error::RecvError) -> Self { + Self::ChannelClosed + } +} diff --git a/crates/payload/primitives/src/events.rs b/crates/payload/builder-primitives/src/events.rs similarity index 98% rename from crates/payload/primitives/src/events.rs rename to crates/payload/builder-primitives/src/events.rs index 3fb3813adb1..d51f13f7c4c 100644 --- a/crates/payload/primitives/src/events.rs +++ b/crates/payload/builder-primitives/src/events.rs @@ -1,4 +1,4 @@ -use crate::PayloadTypes; +use reth_payload_primitives::PayloadTypes; use std::{ pin::Pin, task::{ready, Context, Poll}, diff --git a/crates/payload/builder-primitives/src/lib.rs b/crates/payload/builder-primitives/src/lib.rs new file mode 100644 index 00000000000..003a385c6c0 --- /dev/null +++ b/crates/payload/builder-primitives/src/lib.rs @@ -0,0 +1,19 @@ +//! This crate defines abstractions to create and update payloads (blocks) + +#![doc( + html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", + html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", + issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" +)] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] + +mod error; +pub use error::PayloadBuilderError; + +mod events; +pub use crate::events::{Events, PayloadEvents}; + +/// Contains the payload builder trait to abstract over payload attributes. +mod traits; +pub use traits::{PayloadBuilder, PayloadStoreExt}; diff --git a/crates/payload/builder-primitives/src/traits.rs b/crates/payload/builder-primitives/src/traits.rs new file mode 100644 index 00000000000..b5e8910b6c2 --- /dev/null +++ b/crates/payload/builder-primitives/src/traits.rs @@ -0,0 +1,111 @@ +use crate::{PayloadBuilderError, PayloadEvents}; +use alloy_rpc_types_engine::PayloadId; +use reth_payload_primitives::{PayloadKind, PayloadTypes}; +use std::fmt::Debug; +use tokio::sync::oneshot; + +/// A helper trait for internal usage to retrieve and resolve payloads. +#[async_trait::async_trait] +pub trait PayloadStoreExt: Debug + Send + Sync + Unpin { + /// Resolves the payload job and returns the best payload that has been built so far. + async fn resolve_kind( + &self, + id: PayloadId, + kind: PayloadKind, + ) -> Option>; + + /// Resolves the payload job as fast and possible and returns the best payload that has been + /// built so far. + async fn resolve(&self, id: PayloadId) -> Option> { + self.resolve_kind(id, PayloadKind::Earliest).await + } + + /// Returns the best payload for the given identifier. + async fn best_payload( + &self, + id: PayloadId, + ) -> Option>; + + /// Returns the payload attributes associated with the given identifier. + async fn payload_attributes( + &self, + id: PayloadId, + ) -> Option>; +} + +#[async_trait::async_trait] +impl PayloadStoreExt for P +where + P: PayloadBuilder, +{ + async fn resolve_kind( + &self, + id: PayloadId, + kind: PayloadKind, + ) -> Option> { + Some(PayloadBuilder::resolve_kind(self, id, kind).await?.map_err(Into::into)) + } + + async fn best_payload( + &self, + id: PayloadId, + ) -> Option> { + Some(PayloadBuilder::best_payload(self, id).await?.map_err(Into::into)) + } + + async fn payload_attributes( + &self, + id: PayloadId, + ) -> Option> { + Some(PayloadBuilder::payload_attributes(self, id).await?.map_err(Into::into)) + } +} + +/// A type that can request, subscribe to and resolve payloads. +#[async_trait::async_trait] +pub trait PayloadBuilder: Debug + Send + Sync + Unpin { + /// The Payload type for the builder. + type PayloadType: PayloadTypes; + /// The error type returned by the builder. + type Error: Into; + + /// Sends a message to the service to start building a new payload for the given payload. + /// + /// Returns a receiver that will receive the payload id. + fn send_new_payload( + &self, + attr: ::PayloadBuilderAttributes, + ) -> oneshot::Receiver>; + + /// Returns the best payload for the given identifier. + async fn best_payload( + &self, + id: PayloadId, + ) -> Option::BuiltPayload, Self::Error>>; + + /// Resolves the payload job and returns the best payload that has been built so far. + async fn resolve_kind( + &self, + id: PayloadId, + kind: PayloadKind, + ) -> Option::BuiltPayload, Self::Error>>; + + /// Resolves the payload job as fast and possible and returns the best payload that has been + /// built so far. + async fn resolve( + &self, + id: PayloadId, + ) -> Option::BuiltPayload, Self::Error>> { + self.resolve_kind(id, PayloadKind::Earliest).await + } + + /// Sends a message to the service to subscribe to payload events. + /// Returns a receiver that will receive them. + async fn subscribe(&self) -> Result, Self::Error>; + + /// Returns the payload attributes associated with the given identifier. + async fn payload_attributes( + &self, + id: PayloadId, + ) -> Option::PayloadBuilderAttributes, Self::Error>>; +} diff --git a/crates/payload/builder/Cargo.toml b/crates/payload/builder/Cargo.toml index 8b2fef7b878..78814da5066 100644 --- a/crates/payload/builder/Cargo.toml +++ b/crates/payload/builder/Cargo.toml @@ -15,6 +15,7 @@ workspace = true # reth reth-primitives = { workspace = true, optional = true } reth-chain-state.workspace = true +reth-payload-builder-primitives.workspace = true reth-payload-primitives.workspace = true reth-ethereum-engine-primitives.workspace = true diff --git a/crates/payload/builder/src/lib.rs b/crates/payload/builder/src/lib.rs index da44072c99d..0887a5ca74a 100644 --- a/crates/payload/builder/src/lib.rs +++ b/crates/payload/builder/src/lib.rs @@ -113,7 +113,8 @@ pub mod noop; pub mod test_utils; pub use alloy_rpc_types::engine::PayloadId; -pub use reth_payload_primitives::{PayloadBuilderError, PayloadKind}; +pub use reth_payload_builder_primitives::PayloadBuilderError; +pub use reth_payload_primitives::PayloadKind; pub use service::{ PayloadBuilderHandle, PayloadBuilderService, PayloadServiceCommand, PayloadStore, }; diff --git a/crates/payload/builder/src/service.rs b/crates/payload/builder/src/service.rs index 267a1e355b0..af11ba75ce6 100644 --- a/crates/payload/builder/src/service.rs +++ b/crates/payload/builder/src/service.rs @@ -10,10 +10,10 @@ use crate::{ use alloy_rpc_types::engine::PayloadId; use futures_util::{future::FutureExt, Stream, StreamExt}; use reth_chain_state::CanonStateNotification; -use reth_payload_primitives::{ - BuiltPayload, Events, PayloadBuilder, PayloadBuilderAttributes, PayloadBuilderError, - PayloadEvents, PayloadKind, PayloadStoreExt, PayloadTypes, +use reth_payload_builder_primitives::{ + Events, PayloadBuilder, PayloadBuilderError, PayloadEvents, PayloadStoreExt, }; +use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes, PayloadKind, PayloadTypes}; use std::{ fmt, future::Future, diff --git a/crates/payload/builder/src/test_utils.rs b/crates/payload/builder/src/test_utils.rs index 780df5c8463..5025a12ed71 100644 --- a/crates/payload/builder/src/test_utils.rs +++ b/crates/payload/builder/src/test_utils.rs @@ -7,7 +7,8 @@ use crate::{ use alloy_primitives::U256; use reth_chain_state::{CanonStateNotification, ExecutedBlock}; -use reth_payload_primitives::{PayloadBuilderError, PayloadKind, PayloadTypes}; +use reth_payload_builder_primitives::PayloadBuilderError; +use reth_payload_primitives::{PayloadKind, PayloadTypes}; use reth_primitives::Block; use std::{ future::Future, diff --git a/crates/payload/builder/src/traits.rs b/crates/payload/builder/src/traits.rs index ba8486b6907..d9d54ccd0e4 100644 --- a/crates/payload/builder/src/traits.rs +++ b/crates/payload/builder/src/traits.rs @@ -1,9 +1,8 @@ //! Trait abstractions used by the payload crate. use reth_chain_state::CanonStateNotification; -use reth_payload_primitives::{ - BuiltPayload, PayloadBuilderAttributes, PayloadBuilderError, PayloadKind, -}; +use reth_payload_builder_primitives::PayloadBuilderError; +use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes, PayloadKind}; use std::future::Future; /// A type that can build a payload. diff --git a/crates/payload/primitives/Cargo.toml b/crates/payload/primitives/Cargo.toml index b1a115f12c8..332964de96b 100644 --- a/crates/payload/primitives/Cargo.toml +++ b/crates/payload/primitives/Cargo.toml @@ -14,9 +14,7 @@ workspace = true [dependencies] # reth reth-chainspec.workspace = true -reth-errors.workspace = true reth-primitives.workspace = true -reth-transaction-pool.workspace = true reth-chain-state.workspace = true # alloy @@ -25,18 +23,9 @@ alloy-primitives.workspace = true alloy-rpc-types-engine = { workspace = true, features = ["serde"] } op-alloy-rpc-types-engine = { workspace = true, optional = true } -revm-primitives.workspace = true - -# async -async-trait.workspace = true -tokio = { workspace = true, features = ["sync"] } -tokio-stream.workspace = true -pin-project.workspace = true - # misc serde.workspace = true thiserror.workspace = true -tracing.workspace = true [features] op = ["dep:op-alloy-rpc-types-engine"] \ No newline at end of file diff --git a/crates/payload/primitives/src/error.rs b/crates/payload/primitives/src/error.rs index 82891919feb..67b6dbe4b93 100644 --- a/crates/payload/primitives/src/error.rs +++ b/crates/payload/primitives/src/error.rs @@ -1,62 +1,5 @@ //! Error types emitted by types or implementations of this crate. -use alloy_primitives::B256; -use reth_errors::{ProviderError, RethError}; -use reth_transaction_pool::BlobStoreError; -use revm_primitives::EVMError; -use tokio::sync::oneshot; - -/// Possible error variants during payload building. -#[derive(Debug, thiserror::Error)] -pub enum PayloadBuilderError { - /// Thrown when the parent header cannot be found - #[error("missing parent header: {0}")] - MissingParentHeader(B256), - /// Thrown when the parent block is missing. - #[error("missing parent block {0}")] - MissingParentBlock(B256), - /// An oneshot channels has been closed. - #[error("sender has been dropped")] - ChannelClosed, - /// If there's no payload to resolve. - #[error("missing payload")] - MissingPayload, - /// Error occurring in the blob store. - #[error(transparent)] - BlobStore(#[from] BlobStoreError), - /// Other internal error - #[error(transparent)] - Internal(#[from] RethError), - /// Unrecoverable error during evm execution. - #[error("evm execution error: {0}")] - EvmExecutionError(EVMError), - /// Any other payload building errors. - #[error(transparent)] - Other(Box), -} - -impl PayloadBuilderError { - /// Create a new error from a boxed error. - pub fn other(error: E) -> Self - where - E: core::error::Error + Send + Sync + 'static, - { - Self::Other(Box::new(error)) - } -} - -impl From for PayloadBuilderError { - fn from(error: ProviderError) -> Self { - Self::Internal(RethError::Provider(error)) - } -} - -impl From for PayloadBuilderError { - fn from(_: oneshot::error::RecvError) -> Self { - Self::ChannelClosed - } -} - /// Thrown when the payload or attributes are known to be invalid before processing. /// /// This is used mainly for diff --git a/crates/payload/primitives/src/lib.rs b/crates/payload/primitives/src/lib.rs index 3604ff5d8d8..a2bdb58bc51 100644 --- a/crates/payload/primitives/src/lib.rs +++ b/crates/payload/primitives/src/lib.rs @@ -9,18 +9,13 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] mod error; - -pub use error::{EngineObjectValidationError, PayloadBuilderError, VersionSpecificValidationError}; - -mod events; -pub use crate::events::{Events, PayloadEvents}; +pub use error::{EngineObjectValidationError, VersionSpecificValidationError}; /// Contains traits to abstract over payload attributes types and default implementations of the /// [`PayloadAttributes`] trait for ethereum mainnet and optimism types. mod traits; pub use traits::{ - BuiltPayload, PayloadAttributes, PayloadAttributesBuilder, PayloadBuilder, - PayloadBuilderAttributes, PayloadStoreExt, + BuiltPayload, PayloadAttributes, PayloadAttributesBuilder, PayloadBuilderAttributes, }; mod payload; diff --git a/crates/payload/primitives/src/traits.rs b/crates/payload/primitives/src/traits.rs index 197a7fe3af9..8d5c429e6c6 100644 --- a/crates/payload/primitives/src/traits.rs +++ b/crates/payload/primitives/src/traits.rs @@ -1,4 +1,3 @@ -use crate::{PayloadBuilderError, PayloadEvents, PayloadKind, PayloadTypes}; use alloy_eips::{ eip4895::{Withdrawal, Withdrawals}, eip7685::Requests, @@ -7,114 +6,6 @@ use alloy_primitives::{Address, B256, U256}; use alloy_rpc_types_engine::{PayloadAttributes as EthPayloadAttributes, PayloadId}; use reth_chain_state::ExecutedBlock; use reth_primitives::SealedBlock; -use std::fmt::Debug; -use tokio::sync::oneshot; - -/// A type that can request, subscribe to and resolve payloads. -#[async_trait::async_trait] -pub trait PayloadBuilder: Debug + Send + Sync + Unpin { - /// The Payload type for the builder. - type PayloadType: PayloadTypes; - /// The error type returned by the builder. - type Error: Into; - - /// Sends a message to the service to start building a new payload for the given payload. - /// - /// Returns a receiver that will receive the payload id. - fn send_new_payload( - &self, - attr: ::PayloadBuilderAttributes, - ) -> oneshot::Receiver>; - - /// Returns the best payload for the given identifier. - async fn best_payload( - &self, - id: PayloadId, - ) -> Option::BuiltPayload, Self::Error>>; - - /// Resolves the payload job and returns the best payload that has been built so far. - async fn resolve_kind( - &self, - id: PayloadId, - kind: PayloadKind, - ) -> Option::BuiltPayload, Self::Error>>; - - /// Resolves the payload job as fast and possible and returns the best payload that has been - /// built so far. - async fn resolve( - &self, - id: PayloadId, - ) -> Option::BuiltPayload, Self::Error>> { - self.resolve_kind(id, PayloadKind::Earliest).await - } - - /// Sends a message to the service to subscribe to payload events. - /// Returns a receiver that will receive them. - async fn subscribe(&self) -> Result, Self::Error>; - - /// Returns the payload attributes associated with the given identifier. - async fn payload_attributes( - &self, - id: PayloadId, - ) -> Option::PayloadBuilderAttributes, Self::Error>>; -} - -/// A helper trait for internal usage to retrieve and resolve payloads. -#[async_trait::async_trait] -pub trait PayloadStoreExt: Debug + Send + Sync + Unpin { - /// Resolves the payload job and returns the best payload that has been built so far. - async fn resolve_kind( - &self, - id: PayloadId, - kind: PayloadKind, - ) -> Option>; - - /// Resolves the payload job as fast and possible and returns the best payload that has been - /// built so far. - async fn resolve(&self, id: PayloadId) -> Option> { - self.resolve_kind(id, PayloadKind::Earliest).await - } - - /// Returns the best payload for the given identifier. - async fn best_payload( - &self, - id: PayloadId, - ) -> Option>; - - /// Returns the payload attributes associated with the given identifier. - async fn payload_attributes( - &self, - id: PayloadId, - ) -> Option>; -} - -#[async_trait::async_trait] -impl PayloadStoreExt for P -where - P: PayloadBuilder, -{ - async fn resolve_kind( - &self, - id: PayloadId, - kind: PayloadKind, - ) -> Option> { - Some(PayloadBuilder::resolve_kind(self, id, kind).await?.map_err(Into::into)) - } - - async fn best_payload( - &self, - id: PayloadId, - ) -> Option> { - Some(PayloadBuilder::best_payload(self, id).await?.map_err(Into::into)) - } - - async fn payload_attributes( - &self, - id: PayloadId, - ) -> Option> { - Some(PayloadBuilder::payload_attributes(self, id).await?.map_err(Into::into)) - } -} /// Represents a built payload type that contains a built [`SealedBlock`] and can be converted into /// engine API execution payloads. diff --git a/crates/rpc/rpc-engine-api/Cargo.toml b/crates/rpc/rpc-engine-api/Cargo.toml index 62d1eea3225..4854ac44dc5 100644 --- a/crates/rpc/rpc-engine-api/Cargo.toml +++ b/crates/rpc/rpc-engine-api/Cargo.toml @@ -19,6 +19,7 @@ reth-rpc-api.workspace = true reth-storage-api.workspace = true reth-beacon-consensus.workspace = true reth-payload-builder.workspace = true +reth-payload-builder-primitives.workspace = true reth-payload-primitives.workspace = true reth-tasks.workspace = true reth-rpc-types-compat.workspace = true diff --git a/crates/rpc/rpc-engine-api/src/error.rs b/crates/rpc/rpc-engine-api/src/error.rs index 82665ca35fd..4210d415bfe 100644 --- a/crates/rpc/rpc-engine-api/src/error.rs +++ b/crates/rpc/rpc-engine-api/src/error.rs @@ -4,7 +4,8 @@ use jsonrpsee_types::error::{ }; use reth_beacon_consensus::BeaconForkChoiceUpdateError; use reth_engine_primitives::BeaconOnNewPayloadError; -use reth_payload_primitives::{EngineObjectValidationError, PayloadBuilderError}; +use reth_payload_builder_primitives::PayloadBuilderError; +use reth_payload_primitives::EngineObjectValidationError; use thiserror::Error; /// The Engine API result type diff --git a/examples/custom-engine-types/Cargo.toml b/examples/custom-engine-types/Cargo.toml index 9afd16bea16..d6642a8edfe 100644 --- a/examples/custom-engine-types/Cargo.toml +++ b/examples/custom-engine-types/Cargo.toml @@ -10,7 +10,6 @@ reth.workspace = true reth-chainspec.workspace = true reth-node-api.workspace = true reth-node-core.workspace = true -reth-primitives.workspace = true reth-payload-builder.workspace = true reth-basic-payload-builder.workspace = true reth-ethereum-payload-builder.workspace = true From 2f3fde8fb5f55b32efacb1824df1c88dd3021444 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Sun, 17 Nov 2024 11:26:15 +0100 Subject: [PATCH 209/211] feat: fix WASM build for crates dependent on reth-payload-primitives (#12610) --- .github/assets/check_wasm.sh | 7 --- Cargo.lock | 8 +-- crates/chain-state/Cargo.toml | 2 +- crates/ethereum/payload/src/lib.rs | 8 ++- crates/payload/builder-primitives/Cargo.toml | 5 -- .../payload/builder-primitives/src/error.rs | 58 ------------------- crates/payload/builder-primitives/src/lib.rs | 5 +- crates/payload/primitives/Cargo.toml | 4 ++ crates/payload/primitives/src/error.rs | 53 +++++++++++++++++ crates/payload/primitives/src/lib.rs | 2 +- 10 files changed, 69 insertions(+), 83 deletions(-) delete mode 100644 crates/payload/builder-primitives/src/error.rs diff --git a/.github/assets/check_wasm.sh b/.github/assets/check_wasm.sh index 0d9c9b34a03..0e704857edb 100755 --- a/.github/assets/check_wasm.sh +++ b/.github/assets/check_wasm.sh @@ -15,7 +15,6 @@ exclude_crates=( reth-beacon-consensus reth-bench reth-blockchain-tree - reth-chain-state reth-cli reth-cli-commands reth-cli-runner @@ -26,13 +25,11 @@ exclude_crates=( reth-dns-discovery reth-downloaders reth-e2e-test-utils - reth-engine-primitives reth-engine-service reth-engine-tree reth-engine-util reth-eth-wire reth-ethereum-cli - reth-ethereum-engine-primitives reth-ethereum-payload-builder reth-etl reth-exex @@ -41,7 +38,6 @@ exclude_crates=( reth-net-nat reth-network reth-node-api - reth-node-types reth-node-builder reth-node-core reth-node-ethereum @@ -51,9 +47,6 @@ exclude_crates=( reth-optimism-node reth-optimism-payload-builder reth-optimism-rpc - reth-payload-builder - reth-payload-builder-primitives - reth-payload-primitives reth-rpc reth-rpc-api reth-rpc-api-testing-util diff --git a/Cargo.lock b/Cargo.lock index fefa6fb5c1d..7ff1c650bda 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8479,15 +8479,10 @@ dependencies = [ name = "reth-payload-builder-primitives" version = "1.1.1" dependencies = [ - "alloy-primitives", "alloy-rpc-types-engine", "async-trait", "pin-project", - "reth-errors", "reth-payload-primitives", - "reth-transaction-pool", - "revm-primitives", - "thiserror 1.0.69", "tokio", "tokio-stream", "tracing", @@ -8503,9 +8498,12 @@ dependencies = [ "op-alloy-rpc-types-engine", "reth-chain-state", "reth-chainspec", + "reth-errors", "reth-primitives", + "revm-primitives", "serde", "thiserror 1.0.69", + "tokio", ] [[package]] diff --git a/crates/chain-state/Cargo.toml b/crates/chain-state/Cargo.toml index 0a2f53715ff..ff62b76e5df 100644 --- a/crates/chain-state/Cargo.toml +++ b/crates/chain-state/Cargo.toml @@ -27,7 +27,7 @@ alloy-primitives.workspace = true alloy-consensus.workspace = true # async -tokio = { workspace = true, features = ["sync", "macros", "rt-multi-thread"] } +tokio = { workspace = true, default-features = false, features = ["sync", "macros"] } tokio-stream = { workspace = true, features = ["sync"] } # tracing diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index 2b55ea87dd0..4ec1e212c8d 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -397,9 +397,11 @@ where // only determine cancun fields when active if chain_spec.is_cancun_active_at_timestamp(attributes.timestamp) { // grab the blob sidecars from the executed txs - blob_sidecars = pool.get_all_blobs_exact( - executed_txs.iter().filter(|tx| tx.is_eip4844()).map(|tx| tx.hash).collect(), - )?; + blob_sidecars = pool + .get_all_blobs_exact( + executed_txs.iter().filter(|tx| tx.is_eip4844()).map(|tx| tx.hash).collect(), + ) + .map_err(PayloadBuilderError::other)?; excess_blob_gas = if chain_spec.is_cancun_active_at_timestamp(parent_header.timestamp) { let parent_excess_blob_gas = parent_header.excess_blob_gas.unwrap_or_default(); diff --git a/crates/payload/builder-primitives/Cargo.toml b/crates/payload/builder-primitives/Cargo.toml index c3665dbc58e..6d89ea89d03 100644 --- a/crates/payload/builder-primitives/Cargo.toml +++ b/crates/payload/builder-primitives/Cargo.toml @@ -13,13 +13,9 @@ workspace = true [dependencies] # reth -reth-errors.workspace = true reth-payload-primitives.workspace = true -reth-transaction-pool.workspace = true -revm-primitives.workspace = true # alloy -alloy-primitives.workspace = true alloy-rpc-types-engine = { workspace = true, features = ["serde"] } # async @@ -29,5 +25,4 @@ tokio = { workspace = true, features = ["sync"] } tokio-stream.workspace = true # misc -thiserror.workspace = true tracing.workspace = true diff --git a/crates/payload/builder-primitives/src/error.rs b/crates/payload/builder-primitives/src/error.rs deleted file mode 100644 index 0d988c829e4..00000000000 --- a/crates/payload/builder-primitives/src/error.rs +++ /dev/null @@ -1,58 +0,0 @@ -//! Error types emitted by types or implementations of this crate. - -use alloy_primitives::B256; -use reth_errors::{ProviderError, RethError}; -use reth_transaction_pool::BlobStoreError; -use revm_primitives::EVMError; -use tokio::sync::oneshot; - -/// Possible error variants during payload building. -#[derive(Debug, thiserror::Error)] -pub enum PayloadBuilderError { - /// Thrown when the parent header cannot be found - #[error("missing parent header: {0}")] - MissingParentHeader(B256), - /// Thrown when the parent block is missing. - #[error("missing parent block {0}")] - MissingParentBlock(B256), - /// An oneshot channels has been closed. - #[error("sender has been dropped")] - ChannelClosed, - /// If there's no payload to resolve. - #[error("missing payload")] - MissingPayload, - /// Error occurring in the blob store. - #[error(transparent)] - BlobStore(#[from] BlobStoreError), - /// Other internal error - #[error(transparent)] - Internal(#[from] RethError), - /// Unrecoverable error during evm execution. - #[error("evm execution error: {0}")] - EvmExecutionError(EVMError), - /// Any other payload building errors. - #[error(transparent)] - Other(Box), -} - -impl PayloadBuilderError { - /// Create a new error from a boxed error. - pub fn other(error: E) -> Self - where - E: core::error::Error + Send + Sync + 'static, - { - Self::Other(Box::new(error)) - } -} - -impl From for PayloadBuilderError { - fn from(error: ProviderError) -> Self { - Self::Internal(RethError::Provider(error)) - } -} - -impl From for PayloadBuilderError { - fn from(_: oneshot::error::RecvError) -> Self { - Self::ChannelClosed - } -} diff --git a/crates/payload/builder-primitives/src/lib.rs b/crates/payload/builder-primitives/src/lib.rs index 003a385c6c0..af7ad736d44 100644 --- a/crates/payload/builder-primitives/src/lib.rs +++ b/crates/payload/builder-primitives/src/lib.rs @@ -8,12 +8,11 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -mod error; -pub use error::PayloadBuilderError; - mod events; pub use crate::events::{Events, PayloadEvents}; /// Contains the payload builder trait to abstract over payload attributes. mod traits; pub use traits::{PayloadBuilder, PayloadStoreExt}; + +pub use reth_payload_primitives::PayloadBuilderError; diff --git a/crates/payload/primitives/Cargo.toml b/crates/payload/primitives/Cargo.toml index 332964de96b..d4070b4688e 100644 --- a/crates/payload/primitives/Cargo.toml +++ b/crates/payload/primitives/Cargo.toml @@ -14,9 +14,12 @@ workspace = true [dependencies] # reth reth-chainspec.workspace = true +reth-errors.workspace = true reth-primitives.workspace = true reth-chain-state.workspace = true +revm-primitives.workspace = true + # alloy alloy-eips.workspace = true alloy-primitives.workspace = true @@ -26,6 +29,7 @@ op-alloy-rpc-types-engine = { workspace = true, optional = true } # misc serde.workspace = true thiserror.workspace = true +tokio = { workspace = true, default-features = false, features = ["sync"] } [features] op = ["dep:op-alloy-rpc-types-engine"] \ No newline at end of file diff --git a/crates/payload/primitives/src/error.rs b/crates/payload/primitives/src/error.rs index 67b6dbe4b93..d2e57da5791 100644 --- a/crates/payload/primitives/src/error.rs +++ b/crates/payload/primitives/src/error.rs @@ -1,5 +1,58 @@ //! Error types emitted by types or implementations of this crate. +use alloy_primitives::B256; +use reth_errors::{ProviderError, RethError}; +use revm_primitives::EVMError; +use tokio::sync::oneshot; + +/// Possible error variants during payload building. +#[derive(Debug, thiserror::Error)] +pub enum PayloadBuilderError { + /// Thrown when the parent header cannot be found + #[error("missing parent header: {0}")] + MissingParentHeader(B256), + /// Thrown when the parent block is missing. + #[error("missing parent block {0}")] + MissingParentBlock(B256), + /// An oneshot channels has been closed. + #[error("sender has been dropped")] + ChannelClosed, + /// If there's no payload to resolve. + #[error("missing payload")] + MissingPayload, + /// Other internal error + #[error(transparent)] + Internal(#[from] RethError), + /// Unrecoverable error during evm execution. + #[error("evm execution error: {0}")] + EvmExecutionError(EVMError), + /// Any other payload building errors. + #[error(transparent)] + Other(Box), +} + +impl PayloadBuilderError { + /// Create a new error from a boxed error. + pub fn other(error: E) -> Self + where + E: core::error::Error + Send + Sync + 'static, + { + Self::Other(Box::new(error)) + } +} + +impl From for PayloadBuilderError { + fn from(error: ProviderError) -> Self { + Self::Internal(RethError::Provider(error)) + } +} + +impl From for PayloadBuilderError { + fn from(_: oneshot::error::RecvError) -> Self { + Self::ChannelClosed + } +} + /// Thrown when the payload or attributes are known to be invalid before processing. /// /// This is used mainly for diff --git a/crates/payload/primitives/src/lib.rs b/crates/payload/primitives/src/lib.rs index a2bdb58bc51..0ff4810b864 100644 --- a/crates/payload/primitives/src/lib.rs +++ b/crates/payload/primitives/src/lib.rs @@ -9,7 +9,7 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] mod error; -pub use error::{EngineObjectValidationError, VersionSpecificValidationError}; +pub use error::{EngineObjectValidationError, PayloadBuilderError, VersionSpecificValidationError}; /// Contains traits to abstract over payload attributes types and default implementations of the /// [`PayloadAttributes`] trait for ethereum mainnet and optimism types. From 7ae8ce1d0096a32211cda406c1f1176cfc217b43 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Sun, 17 Nov 2024 17:48:27 +0100 Subject: [PATCH 210/211] chore(sdk): Add blanket impls for refs to prim traits (#12613) --- Cargo.lock | 1 + .../execution-types/src/execution_outcome.rs | 58 +++++++++---------- crates/primitives-traits/Cargo.toml | 1 + crates/primitives-traits/src/block/body.rs | 2 +- crates/primitives-traits/src/block/header.rs | 2 - crates/primitives-traits/src/block/mod.rs | 3 +- crates/primitives-traits/src/receipt.rs | 6 +- crates/primitives-traits/src/size.rs | 1 + .../primitives-traits/src/transaction/mod.rs | 1 + .../src/transaction/signed.rs | 29 +++++----- crates/primitives/src/block.rs | 4 +- crates/primitives/src/receipt.rs | 3 + crates/primitives/src/transaction/mod.rs | 6 -- 13 files changed, 57 insertions(+), 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7ff1c650bda..23503d90756 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8582,6 +8582,7 @@ dependencies = [ "alloy-primitives", "alloy-rlp", "arbitrary", + "auto_impl", "bincode", "byteorder", "bytes", diff --git a/crates/evm/execution-types/src/execution_outcome.rs b/crates/evm/execution-types/src/execution_outcome.rs index c1d9c701650..412269ace9c 100644 --- a/crates/evm/execution-types/src/execution_outcome.rs +++ b/crates/evm/execution-types/src/execution_outcome.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use alloy_eips::eip7685::Requests; use alloy_primitives::{Address, BlockNumber, Bloom, Log, B256, U256}; use reth_primitives::{logs_bloom, Account, Bytecode, Receipts, StorageEntry}; -use reth_primitives_traits::Receipt; +use reth_primitives_traits::{receipt::ReceiptExt, Receipt}; use reth_trie::HashedPostState; use revm::{ db::{states::BundleState, BundleAccount}, @@ -182,36 +182,6 @@ impl ExecutionOutcome { Some(index as usize) } - /// Returns an iterator over all block logs. - pub fn logs(&self, block_number: BlockNumber) -> Option> - where - T: Receipt, - { - let index = self.block_number_to_index(block_number)?; - Some(self.receipts[index].iter().filter_map(|r| Some(r.as_ref()?.logs().iter())).flatten()) - } - - /// Return blocks logs bloom - pub fn block_logs_bloom(&self, block_number: BlockNumber) -> Option - where - T: Receipt, - { - Some(logs_bloom(self.logs(block_number)?)) - } - - /// Returns the receipt root for all recorded receipts. - /// Note: this function calculated Bloom filters for every receipt and created merkle trees - /// of receipt. This is a expensive operation. - pub fn receipts_root_slow(&self, _block_number: BlockNumber) -> Option - where - T: Receipt, - { - #[cfg(feature = "optimism")] - panic!("This should not be called in optimism mode. Use `optimism_receipts_root_slow` instead."); - #[cfg(not(feature = "optimism"))] - self.receipts.root_slow(self.block_number_to_index(_block_number)?, T::receipts_root) - } - /// Returns the receipt root for all recorded receipts. /// Note: this function calculated Bloom filters for every receipt and created merkle trees /// of receipt. This is a expensive operation. @@ -364,6 +334,32 @@ impl ExecutionOutcome { } } +impl ExecutionOutcome { + /// Returns an iterator over all block logs. + pub fn logs(&self, block_number: BlockNumber) -> Option> { + let index = self.block_number_to_index(block_number)?; + Some(self.receipts[index].iter().filter_map(|r| Some(r.as_ref()?.logs().iter())).flatten()) + } + + /// Return blocks logs bloom + pub fn block_logs_bloom(&self, block_number: BlockNumber) -> Option { + Some(logs_bloom(self.logs(block_number)?)) + } + + /// Returns the receipt root for all recorded receipts. + /// Note: this function calculated Bloom filters for every receipt and created merkle trees + /// of receipt. This is a expensive operation. + pub fn receipts_root_slow(&self, _block_number: BlockNumber) -> Option + where + T: ReceiptExt, + { + #[cfg(feature = "optimism")] + panic!("This should not be called in optimism mode. Use `optimism_receipts_root_slow` instead."); + #[cfg(not(feature = "optimism"))] + self.receipts.root_slow(self.block_number_to_index(_block_number)?, T::receipts_root) + } +} + impl From<(BlockExecutionOutput, BlockNumber)> for ExecutionOutcome { fn from(value: (BlockExecutionOutput, BlockNumber)) -> Self { Self { diff --git a/crates/primitives-traits/Cargo.toml b/crates/primitives-traits/Cargo.toml index 30f1c43c86a..651583f8e4d 100644 --- a/crates/primitives-traits/Cargo.toml +++ b/crates/primitives-traits/Cargo.toml @@ -27,6 +27,7 @@ byteorder = "1" derive_more.workspace = true roaring = "0.10.2" serde_with = { workspace = true, optional = true } +auto_impl.workspace = true # required by reth-codecs bytes.workspace = true diff --git a/crates/primitives-traits/src/block/body.rs b/crates/primitives-traits/src/block/body.rs index bb52b89724b..e9aadf40957 100644 --- a/crates/primitives-traits/src/block/body.rs +++ b/crates/primitives-traits/src/block/body.rs @@ -5,6 +5,7 @@ use alloc::fmt; use alloy_consensus::Transaction; /// Abstraction for block's body. +#[auto_impl::auto_impl(&, Arc)] pub trait BlockBody: Send + Sync @@ -19,7 +20,6 @@ pub trait BlockBody: + alloy_rlp::Encodable + alloy_rlp::Decodable + InMemorySize - + 'static { /// Ordered list of signed transactions as committed in block. // todo: requires trait for signed transaction diff --git a/crates/primitives-traits/src/block/header.rs b/crates/primitives-traits/src/block/header.rs index 0c1fc3e57f2..779df442538 100644 --- a/crates/primitives-traits/src/block/header.rs +++ b/crates/primitives-traits/src/block/header.rs @@ -26,7 +26,6 @@ pub trait BlockHeader: + alloy_consensus::BlockHeader + Sealable + InMemorySize - + 'static { } @@ -46,6 +45,5 @@ impl BlockHeader for T where + alloy_consensus::BlockHeader + Sealable + InMemorySize - + 'static { } diff --git a/crates/primitives-traits/src/block/mod.rs b/crates/primitives-traits/src/block/mod.rs index 33008c4381d..6bef9ea167f 100644 --- a/crates/primitives-traits/src/block/mod.rs +++ b/crates/primitives-traits/src/block/mod.rs @@ -18,6 +18,7 @@ impl FullBlock for T where T: Block + Compact {} // todo: make sealable super-trait, depends on // todo: make with senders extension trait, so block can be impl by block type already containing // senders +#[auto_impl::auto_impl(&, Arc)] pub trait Block: Send + Sync @@ -32,7 +33,7 @@ pub trait Block: + InMemorySize { /// Header part of the block. - type Header: BlockHeader; + type Header: BlockHeader + 'static; /// The block's body contains the transactions in the block. type Body: Send + Sync + Unpin + 'static; diff --git a/crates/primitives-traits/src/receipt.rs b/crates/primitives-traits/src/receipt.rs index f3c9ef06356..31bded015d4 100644 --- a/crates/primitives-traits/src/receipt.rs +++ b/crates/primitives-traits/src/receipt.rs @@ -10,9 +10,10 @@ use serde::{Deserialize, Serialize}; /// Helper trait that unifies all behaviour required by receipt to support full node operations. pub trait FullReceipt: Receipt + Compact {} -impl FullReceipt for T where T: Receipt + Compact {} +impl FullReceipt for T where T: ReceiptExt + Compact {} /// Abstraction of a receipt. +#[auto_impl::auto_impl(&, Arc)] pub trait Receipt: Send + Sync @@ -28,7 +29,10 @@ pub trait Receipt: { /// Returns transaction type. fn tx_type(&self) -> u8; +} +/// Extension if [`Receipt`] used in block execution. +pub trait ReceiptExt: Receipt { /// Calculates the receipts root of the given receipts. fn receipts_root(receipts: &[&Self]) -> B256; } diff --git a/crates/primitives-traits/src/size.rs b/crates/primitives-traits/src/size.rs index 0c250688e05..7d83a8af8c4 100644 --- a/crates/primitives-traits/src/size.rs +++ b/crates/primitives-traits/src/size.rs @@ -1,4 +1,5 @@ /// Trait for calculating a heuristic for the in-memory size of a struct. +#[auto_impl::auto_impl(&, Arc, Box)] pub trait InMemorySize { /// Returns a heuristic for the in-memory size of a struct. fn size(&self) -> usize; diff --git a/crates/primitives-traits/src/transaction/mod.rs b/crates/primitives-traits/src/transaction/mod.rs index 4d7ab78685f..33ee36090ac 100644 --- a/crates/primitives-traits/src/transaction/mod.rs +++ b/crates/primitives-traits/src/transaction/mod.rs @@ -53,6 +53,7 @@ impl Transaction for T where } /// Extension trait of [`alloy_consensus::Transaction`]. +#[auto_impl::auto_impl(&, Arc)] pub trait TransactionExt: alloy_consensus::Transaction { /// Transaction envelope type ID. type Type: TxType; diff --git a/crates/primitives-traits/src/transaction/signed.rs b/crates/primitives-traits/src/transaction/signed.rs index 455a9886eb8..958d5cd6c77 100644 --- a/crates/primitives-traits/src/transaction/signed.rs +++ b/crates/primitives-traits/src/transaction/signed.rs @@ -8,7 +8,7 @@ use alloy_primitives::{keccak256, Address, PrimitiveSignature, TxHash, B256}; use reth_codecs::Compact; use revm_primitives::TxEnv; -use crate::{transaction::TransactionExt, FullTransaction, MaybeArbitrary, Transaction}; +use crate::{FullTransaction, MaybeArbitrary, Transaction}; /// Helper trait that unifies all behaviour required by block to support full node operations. pub trait FullSignedTx: SignedTransaction + Compact {} @@ -16,6 +16,7 @@ pub trait FullSignedTx: SignedTransaction + Compac impl FullSignedTx for T where T: SignedTransaction + Compact {} /// A signed transaction. +#[auto_impl::auto_impl(&, Arc)] pub trait SignedTransaction: Send + Sync @@ -32,7 +33,7 @@ pub trait SignedTransaction: + alloy_rlp::Decodable + Encodable2718 + Decodable2718 - + TransactionExt + + alloy_consensus::Transaction + MaybeArbitrary { /// Transaction type that is signed. @@ -65,14 +66,6 @@ pub trait SignedTransaction: /// `reth_primitives::transaction::recover_signer_unchecked`. fn recover_signer_unchecked(&self) -> Option
; - /// Create a new signed transaction from a transaction and its signature. - /// - /// This will also calculate the transaction hash using its encoding. - fn from_transaction_and_signature( - transaction: Self::Transaction, - signature: PrimitiveSignature, - ) -> Self; - /// Calculate transaction hash, eip2728 transaction does not contain rlp header and start with /// tx type. fn recalculate_hash(&self) -> B256 { @@ -83,10 +76,14 @@ pub trait SignedTransaction: fn fill_tx_env(&self, tx_env: &mut TxEnv, sender: Address); } -impl TransactionExt for T { - type Type = ::Type; - - fn signature_hash(&self) -> B256 { - self.transaction().signature_hash() - } +/// Helper trait used in testing. +#[cfg(feature = "test-utils")] +pub trait SignedTransactionTesting: SignedTransaction { + /// Create a new signed transaction from a transaction and its signature. + /// + /// This will also calculate the transaction hash using its encoding. + fn from_transaction_and_signature( + transaction: Self::Transaction, + signature: PrimitiveSignature, + ) -> Self; } diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index d6476c29b4c..94dd578493c 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -465,8 +465,8 @@ where impl reth_primitives_traits::Block for SealedBlock where - H: reth_primitives_traits::BlockHeader, - B: reth_primitives_traits::BlockBody, + H: reth_primitives_traits::BlockHeader + 'static, + B: reth_primitives_traits::BlockBody + 'static, Self: Serialize + for<'a> Deserialize<'a>, { type Header = H; diff --git a/crates/primitives/src/receipt.rs b/crates/primitives/src/receipt.rs index b7138183d11..b61ee7c14d2 100644 --- a/crates/primitives/src/receipt.rs +++ b/crates/primitives/src/receipt.rs @@ -10,6 +10,7 @@ use alloy_primitives::{Bloom, Log, B256}; use alloy_rlp::{length_of_length, Decodable, Encodable, RlpDecodable, RlpEncodable}; use bytes::{Buf, BufMut}; use derive_more::{DerefMut, From, IntoIterator}; +use reth_primitives_traits::receipt::ReceiptExt; use serde::{Deserialize, Serialize}; #[cfg(feature = "reth-codec")] @@ -97,7 +98,9 @@ impl reth_primitives_traits::Receipt for Receipt { fn tx_type(&self) -> u8 { self.tx_type as u8 } +} +impl ReceiptExt for Receipt { fn receipts_root(_receipts: &[&Self]) -> B256 { #[cfg(feature = "optimism")] panic!("This should not be called in optimism mode. Use `optimism_receipts_root_slow` instead."); diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index f325b72776f..015621cdcce 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -1367,12 +1367,6 @@ impl SignedTransaction for TransactionSigned { recover_signer_unchecked(&self.signature, signature_hash) } - fn from_transaction_and_signature(transaction: Transaction, signature: Signature) -> Self { - let mut initial_tx = Self { transaction, hash: Default::default(), signature }; - initial_tx.hash = initial_tx.recalculate_hash(); - initial_tx - } - fn fill_tx_env(&self, tx_env: &mut TxEnv, sender: Address) { tx_env.caller = sender; match self.as_ref() { From 3540a83427aa3f397a6b330446d791cfb2c5e771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Garamv=C3=B6lgyi?= Date: Sun, 17 Nov 2024 18:23:41 +0100 Subject: [PATCH 211/211] update fork base commit --- fork.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fork.yaml b/fork.yaml index e53dce7f9bf..ffc49c306e9 100644 --- a/fork.yaml +++ b/fork.yaml @@ -4,7 +4,7 @@ footer: | base: name: reth url: https://github.com/paradigmxyz/reth - hash: 21d911abb2cf594834c1818d2f723718b5109f8b + hash: 7ae8ce1d0096a32211cda406c1f1176cfc217b43 fork: name: scroll-reth url: https://github.com/scroll-tech/reth