diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs
index 7f94a4d501..2d820734d5 100644
--- a/crates/primitives/src/block.rs
+++ b/crates/primitives/src/block.rs
@@ -1,4 +1,7 @@
-use crate::{Address, Header, SealedHeader, TransactionSigned, Withdrawal, B256};
+use crate::{
+ Address, Header, SealedHeader, TransactionSigned, TransactionSignedEcRecovered, Withdrawal,
+ B256,
+};
use alloy_rlp::{RlpDecodable, RlpEncodable};
use reth_codecs::derive_arbitrary;
use serde::{Deserialize, Serialize};
@@ -252,9 +255,38 @@ impl SealedBlockWithSenders {
}
/// Split Structure to its components
+ #[inline]
pub fn into_components(self) -> (SealedBlock, Vec
) {
(self.block, self.senders)
}
+
+ /// Returns an iterator over all transactions in the block.
+ #[inline]
+ pub fn transactions(&self) -> impl Iterator- + '_ {
+ self.block.body.iter()
+ }
+
+ /// Returns an iterator over all transactions and their sender.
+ #[inline]
+ pub fn transactions_with_sender(
+ &self,
+ ) -> impl Iterator
- + '_ {
+ self.senders.iter().zip(self.block.body.iter())
+ }
+
+ /// Consumes the block and returns the transactions of the block.
+ #[inline]
+ pub fn into_transactions(self) -> Vec {
+ self.block.body
+ }
+
+ /// Returns an iterator over all transactions in the chain.
+ #[inline]
+ pub fn into_transactions_ecrecovered(
+ self,
+ ) -> impl Iterator
- {
+ self.block.body.into_iter().zip(self.senders).map(|(tx, sender)| tx.with_signer(sender))
+ }
}
impl Deref for SealedBlockWithSenders {
diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs
index 40b37085f6..2d539b1f36 100644
--- a/crates/primitives/src/transaction/mod.rs
+++ b/crates/primitives/src/transaction/mod.rs
@@ -1006,6 +1006,12 @@ impl TransactionSigned {
}
}
+ /// Returns the [TransactionSignedEcRecovered] transaction with the given sender.
+ #[inline]
+ pub const fn with_signer(self, signer: Address) -> TransactionSignedEcRecovered {
+ TransactionSignedEcRecovered::from_signed_transaction(self, signer)
+ }
+
/// Consumes the type, recover signer and return [`TransactionSignedEcRecovered`]
///
/// Returns `None` if the transaction's signature is invalid, see also [Self::recover_signer].
@@ -1424,7 +1430,11 @@ impl TransactionSignedEcRecovered {
/// Create [`TransactionSignedEcRecovered`] from [`TransactionSigned`] and [`Address`] of the
/// signer.
- pub fn from_signed_transaction(signed_transaction: TransactionSigned, signer: Address) -> Self {
+ #[inline]
+ pub const fn from_signed_transaction(
+ signed_transaction: TransactionSigned,
+ signer: Address,
+ ) -> Self {
Self { signed_transaction, signer }
}
}
diff --git a/crates/storage/provider/src/chain.rs b/crates/storage/provider/src/chain.rs
index ab269b680a..53bc31a941 100644
--- a/crates/storage/provider/src/chain.rs
+++ b/crates/storage/provider/src/chain.rs
@@ -3,8 +3,8 @@
use crate::bundle_state::BundleStateWithReceipts;
use reth_interfaces::{executor::BlockExecutionError, RethResult};
use reth_primitives::{
- BlockHash, BlockNumHash, BlockNumber, ForkBlock, Receipt, SealedBlock, SealedBlockWithSenders,
- SealedHeader, TransactionSigned, TxHash,
+ Address, BlockHash, BlockNumHash, BlockNumber, ForkBlock, Receipt, SealedBlock,
+ SealedBlockWithSenders, SealedHeader, TransactionSigned, TransactionSignedEcRecovered, TxHash,
};
use std::{borrow::Cow, collections::BTreeMap, fmt};
@@ -276,11 +276,13 @@ impl<'a> ChainBlocks<'a> {
/// Creates a consuming iterator over all blocks in the chain with increasing block number.
///
/// Note: this always yields at least one block.
+ #[inline]
pub fn into_blocks(self) -> impl Iterator
- {
self.blocks.into_owned().into_values()
}
/// Creates an iterator over all blocks in the chain with increasing block number.
+ #[inline]
pub fn iter(&self) -> impl Iterator
- {
self.blocks.iter()
}
@@ -290,6 +292,7 @@ impl<'a> ChainBlocks<'a> {
/// # Note
///
/// Chains always have at least one block.
+ #[inline]
pub fn tip(&self) -> &SealedBlockWithSenders {
self.blocks.last_key_value().expect("Chain should have at least one block").1
}
@@ -299,14 +302,40 @@ impl<'a> ChainBlocks<'a> {
/// # Note
///
/// Chains always have at least one block.
+ #[inline]
pub fn first(&self) -> &SealedBlockWithSenders {
self.blocks.first_key_value().expect("Chain should have at least one block").1
}
/// Returns an iterator over all transactions in the chain.
+ #[inline]
pub fn transactions(&self) -> impl Iterator
- + '_ {
self.blocks.values().flat_map(|block| block.body.iter())
}
+
+ /// Returns an iterator over all transactions and their senders.
+ #[inline]
+ pub fn transactions_with_sender(
+ &self,
+ ) -> impl Iterator
- + '_ {
+ self.blocks.values().flat_map(|block| block.transactions_with_sender())
+ }
+
+ /// Returns an iterator over all [TransactionSignedEcRecovered] in the blocks
+ ///
+ /// Note: This clones the transactions since it is assumed this is part of a shared [Chain].
+ #[inline]
+ pub fn transactions_ecrecovered(
+ &self,
+ ) -> impl Iterator
- + '_ {
+ self.transactions_with_sender().map(|(signer, tx)| tx.clone().with_signer(*signer))
+ }
+
+ /// Returns an iterator over all transaction hashes in the block
+ #[inline]
+ pub fn transaction_hashes(&self) -> impl Iterator
- + '_ {
+ self.blocks.values().flat_map(|block| block.transactions().map(|tx| tx.hash))
+ }
}
impl<'a> IntoIterator for ChainBlocks<'a> {
diff --git a/crates/transaction-pool/src/maintain.rs b/crates/transaction-pool/src/maintain.rs
index 8c48601c47..4da9987b72 100644
--- a/crates/transaction-pool/src/maintain.rs
+++ b/crates/transaction-pool/src/maintain.rs
@@ -279,15 +279,13 @@ pub async fn maintain_transaction_pool(
changed_accounts.extend(new_changed_accounts.into_iter().map(|entry| entry.0));
// all transactions mined in the new chain
- let new_mined_transactions: HashSet<_> =
- new_blocks.transactions().map(|tx| tx.hash).collect();
+ let new_mined_transactions: HashSet<_> = new_blocks.transaction_hashes().collect();
// update the pool then re-inject the pruned transactions
// find all transactions that were mined in the old chain but not in the new chain
let pruned_old_transactions = old_blocks
- .transactions()
+ .transactions_ecrecovered()
.filter(|tx| !new_mined_transactions.contains(&tx.hash))
- .filter_map(|tx| tx.clone().into_ecrecovered())
.map(
::Transaction::from_recovered_transaction)
.collect::>();
@@ -359,7 +357,7 @@ pub async fn maintain_transaction_pool(
changed_accounts.push(acc);
}
- let mined_transactions = blocks.transactions().map(|tx| tx.hash).collect();
+ let mined_transactions = blocks.transaction_hashes().collect();
// check if the range of the commit is canonical with the pool's block
if first_block.parent_hash != pool_info.last_seen_block_hash {