feat: add Transaction AT to TransactionsProvider (#12794)

This commit is contained in:
Arsenii Kulikov
2024-11-23 03:04:42 +04:00
committed by GitHub
parent 36db1c2407
commit 5db3ad1a67
33 changed files with 389 additions and 271 deletions

View File

@ -25,7 +25,7 @@ use reth_db::{models::BlockNumberAddress, transaction::DbTx, Database};
use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices};
use reth_evm::ConfigureEvmEnv;
use reth_execution_types::ExecutionOutcome;
use reth_node_types::NodeTypesWithDB;
use reth_node_types::{NodeTypesWithDB, TxTy};
use reth_primitives::{
Account, Block, BlockWithSenders, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader,
StorageEntry, TransactionMeta, TransactionSigned, TransactionSignedNoHash,
@ -331,29 +331,31 @@ impl<N: ProviderNodeTypes> BlockReader for BlockchainProvider2<N> {
}
impl<N: ProviderNodeTypes> TransactionsProvider for BlockchainProvider2<N> {
type Transaction = TxTy<N>;
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
self.consistent_provider()?.transaction_id(tx_hash)
}
fn transaction_by_id(&self, id: TxNumber) -> ProviderResult<Option<TransactionSigned>> {
fn transaction_by_id(&self, id: TxNumber) -> ProviderResult<Option<Self::Transaction>> {
self.consistent_provider()?.transaction_by_id(id)
}
fn transaction_by_id_unhashed(
&self,
id: TxNumber,
) -> ProviderResult<Option<TransactionSignedNoHash>> {
) -> ProviderResult<Option<Self::Transaction>> {
self.consistent_provider()?.transaction_by_id_unhashed(id)
}
fn transaction_by_hash(&self, hash: TxHash) -> ProviderResult<Option<TransactionSigned>> {
fn transaction_by_hash(&self, hash: TxHash) -> ProviderResult<Option<Self::Transaction>> {
self.consistent_provider()?.transaction_by_hash(hash)
}
fn transaction_by_hash_with_meta(
&self,
tx_hash: TxHash,
) -> ProviderResult<Option<(TransactionSigned, TransactionMeta)>> {
) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>> {
self.consistent_provider()?.transaction_by_hash_with_meta(tx_hash)
}
@ -364,21 +366,21 @@ impl<N: ProviderNodeTypes> TransactionsProvider for BlockchainProvider2<N> {
fn transactions_by_block(
&self,
id: BlockHashOrNumber,
) -> ProviderResult<Option<Vec<TransactionSigned>>> {
) -> ProviderResult<Option<Vec<Self::Transaction>>> {
self.consistent_provider()?.transactions_by_block(id)
}
fn transactions_by_block_range(
&self,
range: impl RangeBounds<BlockNumber>,
) -> ProviderResult<Vec<Vec<TransactionSigned>>> {
) -> ProviderResult<Vec<Vec<Self::Transaction>>> {
self.consistent_provider()?.transactions_by_block_range(range)
}
fn transactions_by_tx_range(
&self,
range: impl RangeBounds<TxNumber>,
) -> ProviderResult<Vec<TransactionSignedNoHash>> {
) -> ProviderResult<Vec<Self::Transaction>> {
self.consistent_provider()?.transactions_by_tx_range(range)
}
@ -2244,9 +2246,7 @@ mod tests {
(transactions_by_tx_range, |block: &SealedBlock, _: &Vec<Vec<Receipt>>| block
.body
.transactions
.iter()
.map(|tx| Into::<TransactionSignedNoHash>::into(tx.clone()))
.collect::<Vec<_>>()),
.clone()),
(receipts_by_tx_range, |block: &SealedBlock, receipts: &Vec<Vec<Receipt>>| receipts
[block.number as usize]
.clone())
@ -2591,9 +2591,7 @@ mod tests {
transaction_by_id_unhashed,
|block: &SealedBlock, tx_num: TxNumber, _: B256, _: &Vec<Vec<Receipt>>| (
tx_num,
Some(Into::<TransactionSignedNoHash>::into(
block.body.transactions[test_tx_index].clone()
))
Some(block.body.transactions[test_tx_index].clone())
),
u64::MAX
),

View File

@ -18,9 +18,10 @@ use reth_db::models::BlockNumberAddress;
use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices};
use reth_evm::ConfigureEvmEnv;
use reth_execution_types::{BundleStateInit, ExecutionOutcome, RevertsInit};
use reth_node_types::TxTy;
use reth_primitives::{
Account, Block, BlockWithSenders, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader,
StorageEntry, TransactionMeta, TransactionSigned, TransactionSignedNoHash,
StorageEntry, TransactionMeta,
};
use reth_prune_types::{PruneCheckpoint, PruneSegment};
use reth_stages_types::{StageCheckpoint, StageId};
@ -927,6 +928,8 @@ impl<N: ProviderNodeTypes> BlockReader for ConsistentProvider<N> {
}
impl<N: ProviderNodeTypes> TransactionsProvider for ConsistentProvider<N> {
type Transaction = TxTy<N>;
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
self.get_in_memory_or_storage_by_tx(
tx_hash.into(),
@ -935,12 +938,19 @@ impl<N: ProviderNodeTypes> TransactionsProvider for ConsistentProvider<N> {
)
}
fn transaction_by_id(&self, id: TxNumber) -> ProviderResult<Option<TransactionSigned>> {
fn transaction_by_id(&self, id: TxNumber) -> ProviderResult<Option<Self::Transaction>> {
self.get_in_memory_or_storage_by_tx(
id.into(),
|provider| provider.transaction_by_id(id),
|tx_index, _, block_state| {
Ok(block_state.block_ref().block().body.transactions.get(tx_index).cloned())
Ok(block_state
.block_ref()
.block()
.body
.transactions
.get(tx_index)
.cloned()
.map(Into::into))
},
)
}
@ -948,7 +958,7 @@ impl<N: ProviderNodeTypes> TransactionsProvider for ConsistentProvider<N> {
fn transaction_by_id_unhashed(
&self,
id: TxNumber,
) -> ProviderResult<Option<TransactionSignedNoHash>> {
) -> ProviderResult<Option<Self::Transaction>> {
self.get_in_memory_or_storage_by_tx(
id.into(),
|provider| provider.transaction_by_id_unhashed(id),
@ -965,9 +975,9 @@ impl<N: ProviderNodeTypes> TransactionsProvider for ConsistentProvider<N> {
)
}
fn transaction_by_hash(&self, hash: TxHash) -> ProviderResult<Option<TransactionSigned>> {
fn transaction_by_hash(&self, hash: TxHash) -> ProviderResult<Option<Self::Transaction>> {
if let Some(tx) = self.head_block.as_ref().and_then(|b| b.transaction_on_chain(hash)) {
return Ok(Some(tx))
return Ok(Some(tx.into()))
}
self.storage_provider.transaction_by_hash(hash)
@ -976,11 +986,11 @@ impl<N: ProviderNodeTypes> TransactionsProvider for ConsistentProvider<N> {
fn transaction_by_hash_with_meta(
&self,
tx_hash: TxHash,
) -> ProviderResult<Option<(TransactionSigned, TransactionMeta)>> {
) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>> {
if let Some((tx, meta)) =
self.head_block.as_ref().and_then(|b| b.transaction_meta_on_chain(tx_hash))
{
return Ok(Some((tx, meta)))
return Ok(Some((tx.into(), meta)))
}
self.storage_provider.transaction_by_hash_with_meta(tx_hash)
@ -997,22 +1007,44 @@ impl<N: ProviderNodeTypes> TransactionsProvider for ConsistentProvider<N> {
fn transactions_by_block(
&self,
id: BlockHashOrNumber,
) -> ProviderResult<Option<Vec<TransactionSigned>>> {
) -> ProviderResult<Option<Vec<Self::Transaction>>> {
self.get_in_memory_or_storage_by_block(
id,
|provider| provider.transactions_by_block(id),
|block_state| Ok(Some(block_state.block_ref().block().body.transactions.clone())),
|block_state| {
Ok(Some(
block_state
.block_ref()
.block()
.body
.transactions
.iter()
.map(|tx| tx.clone().into())
.collect(),
))
},
)
}
fn transactions_by_block_range(
&self,
range: impl RangeBounds<BlockNumber>,
) -> ProviderResult<Vec<Vec<TransactionSigned>>> {
) -> ProviderResult<Vec<Vec<Self::Transaction>>> {
self.get_in_memory_or_storage_by_block_range_while(
range,
|db_provider, range, _| db_provider.transactions_by_block_range(range),
|block_state, _| Some(block_state.block_ref().block().body.transactions.clone()),
|block_state, _| {
Some(
block_state
.block_ref()
.block()
.body
.transactions
.iter()
.map(|tx| tx.clone().into())
.collect(),
)
},
|_| true,
)
}
@ -1020,7 +1052,7 @@ impl<N: ProviderNodeTypes> TransactionsProvider for ConsistentProvider<N> {
fn transactions_by_tx_range(
&self,
range: impl RangeBounds<TxNumber>,
) -> ProviderResult<Vec<TransactionSignedNoHash>> {
) -> ProviderResult<Vec<Self::Transaction>> {
self.get_in_memory_or_storage_by_tx_range(
range,
|db_provider, db_range| db_provider.transactions_by_tx_range(db_range),

View File

@ -19,10 +19,10 @@ use reth_db::{init_db, mdbx::DatabaseArguments, DatabaseEnv};
use reth_db_api::{database::Database, models::StoredBlockBodyIndices};
use reth_errors::{RethError, RethResult};
use reth_evm::ConfigureEvmEnv;
use reth_node_types::NodeTypesWithDB;
use reth_node_types::{NodeTypesWithDB, TxTy};
use reth_primitives::{
Block, BlockWithSenders, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader,
StaticFileSegment, TransactionMeta, TransactionSigned, TransactionSignedNoHash,
StaticFileSegment, TransactionMeta,
};
use reth_prune_types::{PruneCheckpoint, PruneModes, PruneSegment};
use reth_stages_types::{StageCheckpoint, StageId};
@ -420,11 +420,13 @@ impl<N: ProviderNodeTypes> BlockReader for ProviderFactory<N> {
}
impl<N: ProviderNodeTypes> TransactionsProvider for ProviderFactory<N> {
type Transaction = TxTy<N>;
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
self.provider()?.transaction_id(tx_hash)
}
fn transaction_by_id(&self, id: TxNumber) -> ProviderResult<Option<TransactionSigned>> {
fn transaction_by_id(&self, id: TxNumber) -> ProviderResult<Option<Self::Transaction>> {
self.static_file_provider.get_with_static_file_or_database(
StaticFileSegment::Transactions,
id,
@ -436,7 +438,7 @@ impl<N: ProviderNodeTypes> TransactionsProvider for ProviderFactory<N> {
fn transaction_by_id_unhashed(
&self,
id: TxNumber,
) -> ProviderResult<Option<TransactionSignedNoHash>> {
) -> ProviderResult<Option<Self::Transaction>> {
self.static_file_provider.get_with_static_file_or_database(
StaticFileSegment::Transactions,
id,
@ -445,14 +447,14 @@ impl<N: ProviderNodeTypes> TransactionsProvider for ProviderFactory<N> {
)
}
fn transaction_by_hash(&self, hash: TxHash) -> ProviderResult<Option<TransactionSigned>> {
fn transaction_by_hash(&self, hash: TxHash) -> ProviderResult<Option<Self::Transaction>> {
self.provider()?.transaction_by_hash(hash)
}
fn transaction_by_hash_with_meta(
&self,
tx_hash: TxHash,
) -> ProviderResult<Option<(TransactionSigned, TransactionMeta)>> {
) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>> {
self.provider()?.transaction_by_hash_with_meta(tx_hash)
}
@ -463,21 +465,21 @@ impl<N: ProviderNodeTypes> TransactionsProvider for ProviderFactory<N> {
fn transactions_by_block(
&self,
id: BlockHashOrNumber,
) -> ProviderResult<Option<Vec<TransactionSigned>>> {
) -> ProviderResult<Option<Vec<Self::Transaction>>> {
self.provider()?.transactions_by_block(id)
}
fn transactions_by_block_range(
&self,
range: impl RangeBounds<BlockNumber>,
) -> ProviderResult<Vec<Vec<TransactionSigned>>> {
) -> ProviderResult<Vec<Vec<Self::Transaction>>> {
self.provider()?.transactions_by_block_range(range)
}
fn transactions_by_tx_range(
&self,
range: impl RangeBounds<TxNumber>,
) -> ProviderResult<Vec<TransactionSignedNoHash>> {
) -> ProviderResult<Vec<Self::Transaction>> {
self.provider()?.transactions_by_tx_range(range)
}

View File

@ -3,7 +3,7 @@ use crate::{
providers::{
database::{chain::ChainStorage, metrics},
static_file::StaticFileWriter,
ProviderNodeTypes, StaticFileProvider,
NodeTypesForProvider, StaticFileProvider,
},
to_range,
traits::{
@ -46,7 +46,7 @@ use reth_db_api::{
use reth_evm::ConfigureEvmEnv;
use reth_execution_types::{Chain, ExecutionOutcome};
use reth_network_p2p::headers::downloader::SyncTarget;
use reth_node_types::NodeTypes;
use reth_node_types::{NodeTypes, TxTy};
use reth_primitives::{
Account, Block, BlockBody, BlockWithSenders, Bytecode, GotExpected, NodePrimitives, Receipt,
SealedBlock, SealedBlockWithSenders, SealedHeader, StaticFileSegment, StorageEntry,
@ -243,7 +243,7 @@ impl<TX, N: NodeTypes> AsRef<Self> for DatabaseProvider<TX, N> {
}
}
impl<TX: DbTx + DbTxMut + 'static, N: ProviderNodeTypes> DatabaseProvider<TX, N> {
impl<TX: DbTx + DbTxMut + 'static, N: NodeTypesForProvider> DatabaseProvider<TX, N> {
/// Unwinds trie state for the given range.
///
/// This includes calculating the resulted state root and comparing it with the parent block
@ -374,7 +374,7 @@ impl<TX: DbTx + 'static, N: NodeTypes> TryIntoHistoricalStateProvider for Databa
}
}
impl<Tx: DbTx + DbTxMut + 'static, N: ProviderNodeTypes + 'static> DatabaseProvider<Tx, N> {
impl<Tx: DbTx + DbTxMut + 'static, N: NodeTypesForProvider + 'static> DatabaseProvider<Tx, N> {
// TODO: uncomment below, once `reth debug_cmd` has been feature gated with dev.
// #[cfg(any(test, feature = "test-utils"))]
/// Inserts an historical block. **Used for setting up test environments**
@ -486,14 +486,16 @@ impl<TX: DbTx + 'static, N: NodeTypes> DatabaseProvider<TX, N> {
pub fn chain_spec(&self) -> &N::ChainSpec {
&self.chain_spec
}
}
impl<TX: DbTx + 'static, N: NodeTypesForProvider> DatabaseProvider<TX, N> {
fn transactions_by_tx_range_with_cursor<C>(
&self,
range: impl RangeBounds<TxNumber>,
cursor: &mut C,
) -> ProviderResult<Vec<TransactionSignedNoHash>>
) -> ProviderResult<Vec<TxTy<N>>>
where
C: DbCursorRO<tables::Transactions>,
C: DbCursorRO<tables::Transactions<TxTy<N>>>,
{
self.static_file_provider.get_range_with_static_file_or_database(
StaticFileSegment::Transactions,
@ -507,7 +509,7 @@ impl<TX: DbTx + 'static, N: NodeTypes> DatabaseProvider<TX, N> {
fn block_with_senders<H, HF, B, BF>(
&self,
id: BlockHashOrNumber,
transaction_kind: TransactionVariant,
_transaction_kind: TransactionVariant,
header_by_number: HF,
construct_block: BF,
) -> ProviderResult<Option<B>>
@ -546,15 +548,7 @@ impl<TX: DbTx + 'static, N: NodeTypes> DatabaseProvider<TX, N> {
(self.transactions_by_tx_range(tx_range.clone())?, self.senders_by_tx_range(tx_range)?)
};
let body = transactions
.into_iter()
.map(|tx| match transaction_kind {
TransactionVariant::NoHash => {
TransactionSigned::new_unhashed(tx.transaction, tx.signature)
}
TransactionVariant::WithHash => tx.with_hash(),
})
.collect();
let body = transactions.into_iter().map(Into::into).collect();
construct_block(header, body, senders, ommers, withdrawals)
}
@ -663,7 +657,7 @@ impl<TX: DbTx + 'static, N: NodeTypes> DatabaseProvider<TX, N> {
Vec<Address>,
) -> ProviderResult<B>,
{
let mut tx_cursor = self.tx.cursor_read::<tables::Transactions>()?;
let mut tx_cursor = self.tx.cursor_read::<tables::Transactions<TxTy<N>>>()?;
let mut senders_cursor = self.tx.cursor_read::<tables::TransactionSenders>()?;
self.block_range(range, headers_range, |header, tx_range, ommers, withdrawals| {
@ -1219,9 +1213,7 @@ impl<TX: DbTx + 'static, N: NodeTypes> BlockNumReader for DatabaseProvider<TX, N
}
}
impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> BlockReader
for DatabaseProvider<TX, N>
{
impl<TX: DbTx + 'static, N: NodeTypesForProvider> BlockReader for DatabaseProvider<TX, N> {
fn find_block_by_hash(&self, hash: B256, source: BlockSource) -> ProviderResult<Option<Block>> {
if source.is_canonical() {
self.block(hash.into())
@ -1245,7 +1237,7 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> BlockReader
// If they exist but are not indexed, we don't have enough
// information to return the block anyways, so we return `None`.
let transactions = match self.transactions_by_block(number.into())? {
Some(transactions) => transactions,
Some(transactions) => transactions.into_iter().map(Into::into).collect(),
None => return Ok(None),
};
@ -1345,7 +1337,7 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> BlockReader
}
fn block_range(&self, range: RangeInclusive<BlockNumber>) -> ProviderResult<Vec<Block>> {
let mut tx_cursor = self.tx.cursor_read::<tables::Transactions>()?;
let mut tx_cursor = self.tx.cursor_read::<tables::Transactions<TxTy<N>>>()?;
self.block_range(
range,
|range| self.headers_range(range),
@ -1396,7 +1388,7 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> BlockReader
}
}
impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> TransactionsProviderExt
impl<TX: DbTx + 'static, N: NodeTypesForProvider> TransactionsProviderExt
for DatabaseProvider<TX, N>
{
/// Recovers transaction hashes by walking through `Transactions` table and
@ -1466,53 +1458,49 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> Transaction
}
// Calculates the hash of the given transaction
impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> TransactionsProvider
for DatabaseProvider<TX, N>
{
impl<TX: DbTx + 'static, N: NodeTypesForProvider> TransactionsProvider for DatabaseProvider<TX, N> {
type Transaction = TxTy<N>;
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
Ok(self.tx.get::<tables::TransactionHashNumbers>(tx_hash)?)
}
fn transaction_by_id(&self, id: TxNumber) -> ProviderResult<Option<TransactionSigned>> {
fn transaction_by_id(&self, id: TxNumber) -> ProviderResult<Option<Self::Transaction>> {
self.static_file_provider.get_with_static_file_or_database(
StaticFileSegment::Transactions,
id,
|static_file| static_file.transaction_by_id(id),
|| Ok(self.tx.get::<tables::Transactions>(id)?.map(Into::into)),
|| Ok(self.tx.get::<tables::Transactions<Self::Transaction>>(id)?),
)
}
fn transaction_by_id_unhashed(
&self,
id: TxNumber,
) -> ProviderResult<Option<TransactionSignedNoHash>> {
) -> ProviderResult<Option<Self::Transaction>> {
self.static_file_provider.get_with_static_file_or_database(
StaticFileSegment::Transactions,
id,
|static_file| static_file.transaction_by_id_unhashed(id),
|| Ok(self.tx.get::<tables::Transactions>(id)?),
|| Ok(self.tx.get::<tables::Transactions<Self::Transaction>>(id)?),
)
}
fn transaction_by_hash(&self, hash: TxHash) -> ProviderResult<Option<TransactionSigned>> {
fn transaction_by_hash(&self, hash: TxHash) -> ProviderResult<Option<Self::Transaction>> {
if let Some(id) = self.transaction_id(hash)? {
Ok(self
.transaction_by_id_unhashed(id)?
.map(|tx| TransactionSigned::new(tx.transaction, tx.signature, hash)))
Ok(self.transaction_by_id_unhashed(id)?)
} else {
Ok(None)
}
.map(|tx| tx.map(Into::into))
}
fn transaction_by_hash_with_meta(
&self,
tx_hash: TxHash,
) -> ProviderResult<Option<(TransactionSigned, TransactionMeta)>> {
) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>> {
let mut transaction_cursor = self.tx.cursor_read::<tables::TransactionBlocks>()?;
if let Some(transaction_id) = self.transaction_id(tx_hash)? {
if let Some(tx) = self.transaction_by_id_unhashed(transaction_id)? {
let transaction = TransactionSigned::new(tx.transaction, tx.signature, tx_hash);
if let Some(transaction) = self.transaction_by_id_unhashed(transaction_id)? {
if let Some(block_number) =
transaction_cursor.seek(transaction_id).map(|b| b.map(|(_, bn)| bn))?
{
@ -1553,8 +1541,8 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> Transaction
fn transactions_by_block(
&self,
id: BlockHashOrNumber,
) -> ProviderResult<Option<Vec<TransactionSigned>>> {
let mut tx_cursor = self.tx.cursor_read::<tables::Transactions>()?;
) -> ProviderResult<Option<Vec<Self::Transaction>>> {
let mut tx_cursor = self.tx.cursor_read::<tables::Transactions<Self::Transaction>>()?;
if let Some(block_number) = self.convert_hash_or_number(id)? {
if let Some(body) = self.block_body_indices(block_number)? {
@ -1562,12 +1550,7 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> Transaction
return if tx_range.is_empty() {
Ok(Some(Vec::new()))
} else {
Ok(Some(
self.transactions_by_tx_range_with_cursor(tx_range, &mut tx_cursor)?
.into_iter()
.map(Into::into)
.collect(),
))
Ok(Some(self.transactions_by_tx_range_with_cursor(tx_range, &mut tx_cursor)?))
}
}
}
@ -1577,8 +1560,8 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> Transaction
fn transactions_by_block_range(
&self,
range: impl RangeBounds<BlockNumber>,
) -> ProviderResult<Vec<Vec<TransactionSigned>>> {
let mut tx_cursor = self.tx.cursor_read::<tables::Transactions>()?;
) -> ProviderResult<Vec<Vec<Self::Transaction>>> {
let mut tx_cursor = self.tx.cursor_read::<tables::Transactions<Self::Transaction>>()?;
let mut results = Vec::new();
let mut body_cursor = self.tx.cursor_read::<tables::BlockBodyIndices>()?;
for entry in body_cursor.walk_range(range)? {
@ -1590,7 +1573,6 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> Transaction
results.push(
self.transactions_by_tx_range_with_cursor(tx_num_range, &mut tx_cursor)?
.into_iter()
.map(Into::into)
.collect(),
);
}
@ -1601,10 +1583,10 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> Transaction
fn transactions_by_tx_range(
&self,
range: impl RangeBounds<TxNumber>,
) -> ProviderResult<Vec<TransactionSignedNoHash>> {
) -> ProviderResult<Vec<Self::Transaction>> {
self.transactions_by_tx_range_with_cursor(
range,
&mut self.tx.cursor_read::<tables::Transactions>()?,
&mut self.tx.cursor_read::<tables::Transactions<_>>()?,
)
}
@ -1620,9 +1602,7 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> Transaction
}
}
impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> ReceiptProvider
for DatabaseProvider<TX, N>
{
impl<TX: DbTx + 'static, N: NodeTypesForProvider> ReceiptProvider for DatabaseProvider<TX, N> {
fn receipt(&self, id: TxNumber) -> ProviderResult<Option<Receipt>> {
self.static_file_provider.get_with_static_file_or_database(
StaticFileSegment::Receipts,
@ -1887,7 +1867,9 @@ impl<TX: DbTx + 'static, N: NodeTypes> StorageReader for DatabaseProvider<TX, N>
}
}
impl<TX: DbTxMut + DbTx + 'static, N: NodeTypes> StateChangeWriter for DatabaseProvider<TX, N> {
impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider> StateChangeWriter
for DatabaseProvider<TX, N>
{
fn write_state_reverts(
&self,
reverts: PlainStateReverts,
@ -2710,13 +2692,13 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypes> HistoryWriter for DatabaseProvi
}
}
impl<TX: DbTx + 'static, N: NodeTypes> StateReader for DatabaseProvider<TX, N> {
impl<TX: DbTx + 'static, N: NodeTypesForProvider> StateReader for DatabaseProvider<TX, N> {
fn get_state(&self, block: BlockNumber) -> ProviderResult<Option<ExecutionOutcome>> {
self.get_state(block..=block)
}
}
impl<TX: DbTxMut + DbTx + 'static, N: ProviderNodeTypes + 'static> BlockExecutionWriter
impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider + 'static> BlockExecutionWriter
for DatabaseProvider<TX, N>
{
fn take_block_and_execution_above(
@ -2766,7 +2748,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: ProviderNodeTypes + 'static> BlockExecutio
}
}
impl<TX: DbTxMut + DbTx + 'static, N: ProviderNodeTypes + 'static> BlockWriter
impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider + 'static> BlockWriter
for DatabaseProvider<TX, N>
{
type Body = <<N::Primitives as NodePrimitives>::Block as reth_primitives_traits::Block>::Body;

View File

@ -23,10 +23,10 @@ use reth_chainspec::{ChainInfo, EthereumHardforks};
use reth_db::table::Value;
use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices};
use reth_evm::ConfigureEvmEnv;
use reth_node_types::{FullNodePrimitives, NodeTypes, NodeTypesWithDB};
use reth_node_types::{FullNodePrimitives, NodeTypes, NodeTypesWithDB, TxTy};
use reth_primitives::{
Account, Block, BlockWithSenders, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader,
TransactionMeta, TransactionSigned, TransactionSignedNoHash,
TransactionMeta, TransactionSigned,
};
use reth_prune_types::{PruneCheckpoint, PruneSegment};
use reth_stages_types::{StageCheckpoint, StageId};
@ -76,7 +76,9 @@ where
Self: NodeTypes<
ChainSpec: EthereumHardforks,
Storage: ChainStorage<Self::Primitives>,
Primitives: FullNodePrimitives<SignedTx: Value>,
Primitives: FullNodePrimitives<
SignedTx: Value + From<TransactionSigned> + Into<TransactionSigned>,
>,
>,
{
}
@ -85,7 +87,9 @@ impl<T> NodeTypesForProvider for T where
T: NodeTypes<
ChainSpec: EthereumHardforks,
Storage: ChainStorage<T::Primitives>,
Primitives: FullNodePrimitives<SignedTx: Value>,
Primitives: FullNodePrimitives<
SignedTx: Value + From<TransactionSigned> + Into<TransactionSigned>,
>,
>
{
}
@ -417,29 +421,31 @@ impl<N: ProviderNodeTypes> BlockReader for BlockchainProvider<N> {
}
impl<N: ProviderNodeTypes> TransactionsProvider for BlockchainProvider<N> {
type Transaction = TxTy<N>;
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
self.database.transaction_id(tx_hash)
}
fn transaction_by_id(&self, id: TxNumber) -> ProviderResult<Option<TransactionSigned>> {
fn transaction_by_id(&self, id: TxNumber) -> ProviderResult<Option<Self::Transaction>> {
self.database.transaction_by_id(id)
}
fn transaction_by_id_unhashed(
&self,
id: TxNumber,
) -> ProviderResult<Option<TransactionSignedNoHash>> {
) -> ProviderResult<Option<Self::Transaction>> {
self.database.transaction_by_id_unhashed(id)
}
fn transaction_by_hash(&self, hash: TxHash) -> ProviderResult<Option<TransactionSigned>> {
fn transaction_by_hash(&self, hash: TxHash) -> ProviderResult<Option<Self::Transaction>> {
self.database.transaction_by_hash(hash)
}
fn transaction_by_hash_with_meta(
&self,
tx_hash: TxHash,
) -> ProviderResult<Option<(TransactionSigned, TransactionMeta)>> {
) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>> {
self.database.transaction_by_hash_with_meta(tx_hash)
}
@ -450,21 +456,21 @@ impl<N: ProviderNodeTypes> TransactionsProvider for BlockchainProvider<N> {
fn transactions_by_block(
&self,
id: BlockHashOrNumber,
) -> ProviderResult<Option<Vec<TransactionSigned>>> {
) -> ProviderResult<Option<Vec<Self::Transaction>>> {
self.database.transactions_by_block(id)
}
fn transactions_by_block_range(
&self,
range: impl RangeBounds<BlockNumber>,
) -> ProviderResult<Vec<Vec<TransactionSigned>>> {
) -> ProviderResult<Vec<Vec<Self::Transaction>>> {
self.database.transactions_by_block_range(range)
}
fn transactions_by_tx_range(
&self,
range: impl RangeBounds<TxNumber>,
) -> ProviderResult<Vec<TransactionSignedNoHash>> {
) -> ProviderResult<Vec<Self::Transaction>> {
self.database.transactions_by_tx_range(range)
}

View File

@ -7,17 +7,19 @@ use crate::{
TransactionsProvider,
};
use alloy_consensus::Header;
use alloy_eips::BlockHashOrNumber;
use alloy_eips::{eip2718::Encodable2718, BlockHashOrNumber};
use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256};
use reth_chainspec::ChainInfo;
use reth_db::static_file::{
BlockHashMask, HeaderMask, HeaderWithHashMask, ReceiptMask, StaticFileCursor, TDWithHashMask,
TotalDifficultyMask, TransactionMask,
use reth_db::{
static_file::{
BlockHashMask, HeaderMask, HeaderWithHashMask, ReceiptMask, StaticFileCursor,
TDWithHashMask, TotalDifficultyMask, TransactionMask,
},
table::Decompress,
};
use reth_node_types::NodePrimitives;
use reth_primitives::{
Receipt, SealedHeader, TransactionMeta, TransactionSigned, TransactionSignedNoHash,
};
use reth_primitives::{transaction::recover_signers, Receipt, SealedHeader, TransactionMeta};
use reth_primitives_traits::SignedTransaction;
use reth_storage_errors::provider::{ProviderError, ProviderResult};
use std::{
fmt::Debug,
@ -207,40 +209,38 @@ impl<N: NodePrimitives> BlockNumReader for StaticFileJarProvider<'_, N> {
}
}
impl<N: NodePrimitives> TransactionsProvider for StaticFileJarProvider<'_, N> {
impl<N: NodePrimitives<SignedTx: Decompress + SignedTransaction>> TransactionsProvider
for StaticFileJarProvider<'_, N>
{
type Transaction = N::SignedTx;
fn transaction_id(&self, hash: TxHash) -> ProviderResult<Option<TxNumber>> {
let mut cursor = self.cursor()?;
Ok(cursor
.get_one::<TransactionMask<TransactionSignedNoHash>>((&hash).into())?
.and_then(|res| (res.hash() == hash).then(|| cursor.number()).flatten()))
.get_one::<TransactionMask<Self::Transaction>>((&hash).into())?
.and_then(|res| (res.trie_hash() == hash).then(|| cursor.number()).flatten()))
}
fn transaction_by_id(&self, num: TxNumber) -> ProviderResult<Option<TransactionSigned>> {
Ok(self
.cursor()?
.get_one::<TransactionMask<TransactionSignedNoHash>>(num.into())?
.map(|tx| tx.with_hash()))
fn transaction_by_id(&self, num: TxNumber) -> ProviderResult<Option<Self::Transaction>> {
self.cursor()?.get_one::<TransactionMask<Self::Transaction>>(num.into())
}
fn transaction_by_id_unhashed(
&self,
num: TxNumber,
) -> ProviderResult<Option<TransactionSignedNoHash>> {
self.cursor()?.get_one::<TransactionMask<TransactionSignedNoHash>>(num.into())
) -> ProviderResult<Option<Self::Transaction>> {
self.cursor()?.get_one::<TransactionMask<Self::Transaction>>(num.into())
}
fn transaction_by_hash(&self, hash: TxHash) -> ProviderResult<Option<TransactionSigned>> {
Ok(self
.cursor()?
.get_one::<TransactionMask<TransactionSignedNoHash>>((&hash).into())?
.map(|tx| tx.with_hash()))
fn transaction_by_hash(&self, hash: TxHash) -> ProviderResult<Option<Self::Transaction>> {
self.cursor()?.get_one::<TransactionMask<Self::Transaction>>((&hash).into())
}
fn transaction_by_hash_with_meta(
&self,
_hash: TxHash,
) -> ProviderResult<Option<(TransactionSigned, TransactionMeta)>> {
) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>> {
// Information required on indexing table [`tables::TransactionBlocks`]
Err(ProviderError::UnsupportedProvider)
}
@ -253,7 +253,7 @@ impl<N: NodePrimitives> TransactionsProvider for StaticFileJarProvider<'_, N> {
fn transactions_by_block(
&self,
_block_id: BlockHashOrNumber,
) -> ProviderResult<Option<Vec<TransactionSigned>>> {
) -> ProviderResult<Option<Vec<Self::Transaction>>> {
// Related to indexing tables. Live database should get the tx_range and call static file
// provider with `transactions_by_tx_range` instead.
Err(ProviderError::UnsupportedProvider)
@ -262,7 +262,7 @@ impl<N: NodePrimitives> TransactionsProvider for StaticFileJarProvider<'_, N> {
fn transactions_by_block_range(
&self,
_range: impl RangeBounds<BlockNumber>,
) -> ProviderResult<Vec<Vec<TransactionSigned>>> {
) -> ProviderResult<Vec<Vec<Self::Transaction>>> {
// Related to indexing tables. Live database should get the tx_range and call static file
// provider with `transactions_by_tx_range` instead.
Err(ProviderError::UnsupportedProvider)
@ -271,15 +271,13 @@ impl<N: NodePrimitives> TransactionsProvider for StaticFileJarProvider<'_, N> {
fn transactions_by_tx_range(
&self,
range: impl RangeBounds<TxNumber>,
) -> ProviderResult<Vec<reth_primitives::TransactionSignedNoHash>> {
) -> ProviderResult<Vec<Self::Transaction>> {
let range = to_range(range);
let mut cursor = self.cursor()?;
let mut txes = Vec::with_capacity((range.end - range.start) as usize);
for num in range {
if let Some(tx) =
cursor.get_one::<TransactionMask<TransactionSignedNoHash>>(num.into())?
{
if let Some(tx) = cursor.get_one::<TransactionMask<Self::Transaction>>(num.into())? {
txes.push(tx)
}
}
@ -291,19 +289,20 @@ impl<N: NodePrimitives> TransactionsProvider for StaticFileJarProvider<'_, N> {
range: impl RangeBounds<TxNumber>,
) -> ProviderResult<Vec<Address>> {
let txs = self.transactions_by_tx_range(range)?;
TransactionSignedNoHash::recover_signers(&txs, txs.len())
.ok_or(ProviderError::SenderRecoveryError)
recover_signers(&txs, txs.len()).ok_or(ProviderError::SenderRecoveryError)
}
fn transaction_sender(&self, num: TxNumber) -> ProviderResult<Option<Address>> {
Ok(self
.cursor()?
.get_one::<TransactionMask<TransactionSignedNoHash>>(num.into())?
.get_one::<TransactionMask<Self::Transaction>>(num.into())?
.and_then(|tx| tx.recover_signer()))
}
}
impl<N: NodePrimitives> ReceiptProvider for StaticFileJarProvider<'_, N> {
impl<N: NodePrimitives<SignedTx: Decompress + SignedTransaction>> ReceiptProvider
for StaticFileJarProvider<'_, N>
{
fn receipt(&self, num: TxNumber) -> ProviderResult<Option<Receipt>> {
self.cursor()?.get_one::<ReceiptMask<Receipt>>(num.into())
}

View File

@ -9,6 +9,7 @@ use crate::{
};
use alloy_consensus::Header;
use alloy_eips::{
eip2718::Encodable2718,
eip4895::{Withdrawal, Withdrawals},
BlockHashOrNumber,
};
@ -23,6 +24,7 @@ use reth_db::{
iter_static_files, BlockHashMask, HeaderMask, HeaderWithHashMask, ReceiptMask,
StaticFileCursor, TDWithHashMask, TransactionMask,
},
table::{Decompress, Value},
tables,
};
use reth_db_api::{
@ -35,9 +37,11 @@ use reth_primitives::{
find_fixed_range, HighestStaticFiles, SegmentHeader, SegmentRangeInclusive,
DEFAULT_BLOCKS_PER_STATIC_FILE,
},
transaction::recover_signers,
Block, BlockWithSenders, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader,
StaticFileSegment, TransactionMeta, TransactionSigned, TransactionSignedNoHash,
StaticFileSegment, TransactionMeta, TransactionSignedNoHash,
};
use reth_primitives_traits::SignedTransaction;
use reth_stages_types::{PipelineTarget, StageId};
use reth_storage_api::DBProvider;
use reth_storage_errors::provider::{ProviderError, ProviderResult};
@ -1337,7 +1341,9 @@ impl<N: NodePrimitives> BlockHashReader for StaticFileProvider<N> {
}
}
impl<N: NodePrimitives> ReceiptProvider for StaticFileProvider<N> {
impl<N: NodePrimitives<SignedTx: Value + SignedTransaction>> ReceiptProvider
for StaticFileProvider<N>
{
fn receipt(&self, num: TxNumber) -> ProviderResult<Option<Receipt>> {
self.get_segment_provider_from_transaction(StaticFileSegment::Receipts, num, None)
.and_then(|provider| provider.receipt(num))
@ -1374,7 +1380,9 @@ impl<N: NodePrimitives> ReceiptProvider for StaticFileProvider<N> {
}
}
impl<N: NodePrimitives> TransactionsProviderExt for StaticFileProvider<N> {
impl<N: NodePrimitives<SignedTx: Value + SignedTransaction>> TransactionsProviderExt
for StaticFileProvider<N>
{
fn transaction_hashes_by_range(
&self,
tx_range: Range<TxNumber>,
@ -1435,13 +1443,17 @@ impl<N: NodePrimitives> TransactionsProviderExt for StaticFileProvider<N> {
}
}
impl<N: NodePrimitives> TransactionsProvider for StaticFileProvider<N> {
impl<N: NodePrimitives<SignedTx: Decompress + SignedTransaction>> TransactionsProvider
for StaticFileProvider<N>
{
type Transaction = N::SignedTx;
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
self.find_static_file(StaticFileSegment::Transactions, |jar_provider| {
let mut cursor = jar_provider.cursor()?;
if cursor
.get_one::<TransactionMask<TransactionSignedNoHash>>((&tx_hash).into())?
.and_then(|tx| (tx.hash() == tx_hash).then_some(tx))
.get_one::<TransactionMask<Self::Transaction>>((&tx_hash).into())?
.and_then(|tx| (tx.trie_hash() == tx_hash).then_some(tx))
.is_some()
{
Ok(cursor.number())
@ -1451,7 +1463,7 @@ impl<N: NodePrimitives> TransactionsProvider for StaticFileProvider<N> {
})
}
fn transaction_by_id(&self, num: TxNumber) -> ProviderResult<Option<TransactionSigned>> {
fn transaction_by_id(&self, num: TxNumber) -> ProviderResult<Option<Self::Transaction>> {
self.get_segment_provider_from_transaction(StaticFileSegment::Transactions, num, None)
.and_then(|provider| provider.transaction_by_id(num))
.or_else(|err| {
@ -1466,7 +1478,7 @@ impl<N: NodePrimitives> TransactionsProvider for StaticFileProvider<N> {
fn transaction_by_id_unhashed(
&self,
num: TxNumber,
) -> ProviderResult<Option<TransactionSignedNoHash>> {
) -> ProviderResult<Option<Self::Transaction>> {
self.get_segment_provider_from_transaction(StaticFileSegment::Transactions, num, None)
.and_then(|provider| provider.transaction_by_id_unhashed(num))
.or_else(|err| {
@ -1478,20 +1490,19 @@ impl<N: NodePrimitives> TransactionsProvider for StaticFileProvider<N> {
})
}
fn transaction_by_hash(&self, hash: TxHash) -> ProviderResult<Option<TransactionSigned>> {
fn transaction_by_hash(&self, hash: TxHash) -> ProviderResult<Option<Self::Transaction>> {
self.find_static_file(StaticFileSegment::Transactions, |jar_provider| {
Ok(jar_provider
.cursor()?
.get_one::<TransactionMask<TransactionSignedNoHash>>((&hash).into())?
.map(|tx| tx.with_hash())
.and_then(|tx| (tx.hash_ref() == &hash).then_some(tx)))
.get_one::<TransactionMask<Self::Transaction>>((&hash).into())?
.and_then(|tx| (tx.trie_hash() == hash).then_some(tx)))
})
}
fn transaction_by_hash_with_meta(
&self,
_hash: TxHash,
) -> ProviderResult<Option<(TransactionSigned, TransactionMeta)>> {
) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>> {
// Required data not present in static_files
Err(ProviderError::UnsupportedProvider)
}
@ -1504,7 +1515,7 @@ impl<N: NodePrimitives> TransactionsProvider for StaticFileProvider<N> {
fn transactions_by_block(
&self,
_block_id: BlockHashOrNumber,
) -> ProviderResult<Option<Vec<TransactionSigned>>> {
) -> ProviderResult<Option<Vec<Self::Transaction>>> {
// Required data not present in static_files
Err(ProviderError::UnsupportedProvider)
}
@ -1512,7 +1523,7 @@ impl<N: NodePrimitives> TransactionsProvider for StaticFileProvider<N> {
fn transactions_by_block_range(
&self,
_range: impl RangeBounds<BlockNumber>,
) -> ProviderResult<Vec<Vec<TransactionSigned>>> {
) -> ProviderResult<Vec<Vec<Self::Transaction>>> {
// Required data not present in static_files
Err(ProviderError::UnsupportedProvider)
}
@ -1520,13 +1531,11 @@ impl<N: NodePrimitives> TransactionsProvider for StaticFileProvider<N> {
fn transactions_by_tx_range(
&self,
range: impl RangeBounds<TxNumber>,
) -> ProviderResult<Vec<TransactionSignedNoHash>> {
) -> ProviderResult<Vec<Self::Transaction>> {
self.fetch_range_with_predicate(
StaticFileSegment::Transactions,
to_range(range),
|cursor, number| {
cursor.get_one::<TransactionMask<TransactionSignedNoHash>>(number.into())
},
|cursor, number| cursor.get_one::<TransactionMask<Self::Transaction>>(number.into()),
|_| true,
)
}
@ -1536,8 +1545,7 @@ impl<N: NodePrimitives> TransactionsProvider for StaticFileProvider<N> {
range: impl RangeBounds<TxNumber>,
) -> ProviderResult<Vec<Address>> {
let txes = self.transactions_by_tx_range(range)?;
TransactionSignedNoHash::recover_signers(&txes, txes.len())
.ok_or(ProviderError::SenderRecoveryError)
recover_signers(&txes, txes.len()).ok_or(ProviderError::SenderRecoveryError)
}
fn transaction_sender(&self, id: TxNumber) -> ProviderResult<Option<Address>> {
@ -1569,7 +1577,7 @@ impl<N: NodePrimitives> BlockNumReader for StaticFileProvider<N> {
}
}
impl<N: NodePrimitives> BlockReader for StaticFileProvider<N> {
impl<N: NodePrimitives<SignedTx: Value + SignedTransaction>> BlockReader for StaticFileProvider<N> {
fn find_block_by_hash(
&self,
_hash: B256,

View File

@ -415,7 +415,7 @@ mod tests {
#[allow(clippy::too_many_arguments)]
fn prune_and_validate(
sf_rw: &StaticFileProvider<()>,
sf_rw: &StaticFileProvider<EthPrimitives>,
static_dir: impl AsRef<Path>,
segment: StaticFileSegment,
prune_count: u64,

View File

@ -25,7 +25,6 @@ use reth_node_types::NodeTypes;
use reth_primitives::{
Account, Block, BlockWithSenders, Bytecode, EthPrimitives, GotExpected, Receipt, SealedBlock,
SealedBlockWithSenders, SealedHeader, TransactionMeta, TransactionSigned,
TransactionSignedNoHash,
};
use reth_stages_types::{StageCheckpoint, StageId};
use reth_storage_api::{
@ -244,6 +243,8 @@ impl ChainSpecProvider for MockEthProvider {
}
impl TransactionsProvider for MockEthProvider {
type Transaction = TransactionSigned;
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
let lock = self.blocks.lock();
let tx_number = lock
@ -255,7 +256,7 @@ impl TransactionsProvider for MockEthProvider {
Ok(tx_number)
}
fn transaction_by_id(&self, id: TxNumber) -> ProviderResult<Option<TransactionSigned>> {
fn transaction_by_id(&self, id: TxNumber) -> ProviderResult<Option<Self::Transaction>> {
let lock = self.blocks.lock();
let transaction =
lock.values().flat_map(|block| &block.body.transactions).nth(id as usize).cloned();
@ -266,13 +267,10 @@ impl TransactionsProvider for MockEthProvider {
fn transaction_by_id_unhashed(
&self,
id: TxNumber,
) -> ProviderResult<Option<TransactionSignedNoHash>> {
) -> ProviderResult<Option<Self::Transaction>> {
let lock = self.blocks.lock();
let transaction = lock
.values()
.flat_map(|block| &block.body.transactions)
.nth(id as usize)
.map(|tx| Into::<TransactionSignedNoHash>::into(tx.clone()));
let transaction =
lock.values().flat_map(|block| &block.body.transactions).nth(id as usize).cloned();
Ok(transaction)
}
@ -286,7 +284,7 @@ impl TransactionsProvider for MockEthProvider {
fn transaction_by_hash_with_meta(
&self,
hash: TxHash,
) -> ProviderResult<Option<(TransactionSigned, TransactionMeta)>> {
) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>> {
let lock = self.blocks.lock();
for (block_hash, block) in lock.iter() {
for (index, tx) in block.body.transactions.iter().enumerate() {
@ -322,14 +320,14 @@ impl TransactionsProvider for MockEthProvider {
fn transactions_by_block(
&self,
id: BlockHashOrNumber,
) -> ProviderResult<Option<Vec<TransactionSigned>>> {
) -> ProviderResult<Option<Vec<Self::Transaction>>> {
Ok(self.block(id)?.map(|b| b.body.transactions))
}
fn transactions_by_block_range(
&self,
range: impl RangeBounds<alloy_primitives::BlockNumber>,
) -> ProviderResult<Vec<Vec<TransactionSigned>>> {
) -> ProviderResult<Vec<Vec<Self::Transaction>>> {
// init btreemap so we can return in order
let mut map = BTreeMap::new();
for (_, block) in self.blocks.lock().iter() {
@ -344,14 +342,14 @@ impl TransactionsProvider for MockEthProvider {
fn transactions_by_tx_range(
&self,
range: impl RangeBounds<TxNumber>,
) -> ProviderResult<Vec<reth_primitives::TransactionSignedNoHash>> {
) -> ProviderResult<Vec<Self::Transaction>> {
let lock = self.blocks.lock();
let transactions = lock
.values()
.flat_map(|block| &block.body.transactions)
.enumerate()
.filter(|&(tx_number, _)| range.contains(&(tx_number as TxNumber)))
.map(|(_, tx)| tx.clone().into())
.map(|(_, tx)| tx.clone())
.collect();
Ok(transactions)

View File

@ -23,7 +23,7 @@ use reth_errors::ProviderError;
use reth_evm::ConfigureEvmEnv;
use reth_primitives::{
Account, Block, BlockWithSenders, Bytecode, Receipt, SealedBlock, SealedBlockWithSenders,
SealedHeader, TransactionMeta, TransactionSigned, TransactionSignedNoHash,
SealedHeader, TransactionMeta, TransactionSigned,
};
use reth_prune_types::{PruneCheckpoint, PruneSegment};
use reth_stages_types::{StageCheckpoint, StageId};
@ -192,29 +192,31 @@ impl BlockIdReader for NoopProvider {
}
impl TransactionsProvider for NoopProvider {
type Transaction = TransactionSigned;
fn transaction_id(&self, _tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
Ok(None)
}
fn transaction_by_id(&self, _id: TxNumber) -> ProviderResult<Option<TransactionSigned>> {
fn transaction_by_id(&self, _id: TxNumber) -> ProviderResult<Option<Self::Transaction>> {
Ok(None)
}
fn transaction_by_id_unhashed(
&self,
_id: TxNumber,
) -> ProviderResult<Option<TransactionSignedNoHash>> {
) -> ProviderResult<Option<Self::Transaction>> {
Ok(None)
}
fn transaction_by_hash(&self, _hash: TxHash) -> ProviderResult<Option<TransactionSigned>> {
fn transaction_by_hash(&self, _hash: TxHash) -> ProviderResult<Option<Self::Transaction>> {
Ok(None)
}
fn transaction_by_hash_with_meta(
&self,
_hash: TxHash,
) -> ProviderResult<Option<(TransactionSigned, TransactionMeta)>> {
) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>> {
Ok(None)
}
@ -225,21 +227,21 @@ impl TransactionsProvider for NoopProvider {
fn transactions_by_block(
&self,
_block_id: BlockHashOrNumber,
) -> ProviderResult<Option<Vec<TransactionSigned>>> {
) -> ProviderResult<Option<Vec<Self::Transaction>>> {
Ok(None)
}
fn transactions_by_block_range(
&self,
_range: impl RangeBounds<BlockNumber>,
) -> ProviderResult<Vec<Vec<TransactionSigned>>> {
) -> ProviderResult<Vec<Vec<Self::Transaction>>> {
Ok(Vec::default())
}
fn transactions_by_tx_range(
&self,
_range: impl RangeBounds<TxNumber>,
) -> ProviderResult<Vec<reth_primitives::TransactionSignedNoHash>> {
) -> ProviderResult<Vec<Self::Transaction>> {
Ok(Vec::default())
}

View File

@ -7,13 +7,13 @@ use crate::{
};
use reth_chain_state::{CanonStateSubscriptions, ForkChoiceSubscriptions};
use reth_chainspec::EthereumHardforks;
use reth_node_types::NodeTypesWithDB;
use reth_node_types::{NodeTypesWithDB, TxTy};
/// Helper trait to unify all provider traits for simplicity.
pub trait FullProvider<N: NodeTypesWithDB>:
DatabaseProviderFactory<DB = N::DB>
+ StaticFileProviderFactory
+ BlockReaderIdExt
+ StaticFileProviderFactory<Primitives = N::Primitives>
+ BlockReaderIdExt<Transaction = TxTy<N>>
+ AccountReader
+ StateProviderFactory
+ EvmEnvProvider
@ -30,8 +30,8 @@ pub trait FullProvider<N: NodeTypesWithDB>:
impl<T, N: NodeTypesWithDB> FullProvider<N> for T where
T: DatabaseProviderFactory<DB = N::DB>
+ StaticFileProviderFactory
+ BlockReaderIdExt
+ StaticFileProviderFactory<Primitives = N::Primitives>
+ BlockReaderIdExt<Transaction = TxTy<N>>
+ AccountReader
+ StateProviderFactory
+ EvmEnvProvider

View File

@ -1,7 +1,8 @@
use crate::{BlockNumReader, BlockReader};
use alloy_eips::BlockHashOrNumber;
use alloy_primitives::{Address, BlockNumber, TxHash, TxNumber};
use reth_primitives::{TransactionMeta, TransactionSigned, TransactionSignedNoHash};
use reth_primitives::TransactionMeta;
use reth_primitives_traits::SignedTransaction;
use reth_storage_errors::provider::{ProviderError, ProviderResult};
use std::ops::{Range, RangeBounds, RangeInclusive};
@ -18,9 +19,12 @@ pub enum TransactionVariant {
WithHash,
}
/// Client trait for fetching [TransactionSigned] related data.
/// Client trait for fetching transactions related data.
#[auto_impl::auto_impl(&, Arc)]
pub trait TransactionsProvider: BlockNumReader + Send + Sync {
/// The transaction type this provider reads.
type Transaction: Send + Sync + SignedTransaction;
/// Get internal transaction identifier by transaction hash.
///
/// This is the inverse of [TransactionsProvider::transaction_by_id].
@ -28,23 +32,21 @@ pub trait TransactionsProvider: BlockNumReader + Send + Sync {
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>>;
/// Get transaction by id, computes hash every time so more expensive.
fn transaction_by_id(&self, id: TxNumber) -> ProviderResult<Option<TransactionSigned>>;
fn transaction_by_id(&self, id: TxNumber) -> ProviderResult<Option<Self::Transaction>>;
/// Get transaction by id without computing the hash.
fn transaction_by_id_unhashed(
&self,
id: TxNumber,
) -> ProviderResult<Option<TransactionSignedNoHash>>;
fn transaction_by_id_unhashed(&self, id: TxNumber)
-> ProviderResult<Option<Self::Transaction>>;
/// Get transaction by transaction hash.
fn transaction_by_hash(&self, hash: TxHash) -> ProviderResult<Option<TransactionSigned>>;
fn transaction_by_hash(&self, hash: TxHash) -> ProviderResult<Option<Self::Transaction>>;
/// Get transaction by transaction hash and additional metadata of the block the transaction was
/// mined in
fn transaction_by_hash_with_meta(
&self,
hash: TxHash,
) -> ProviderResult<Option<(TransactionSigned, TransactionMeta)>>;
) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>>;
/// Get transaction block number
fn transaction_block(&self, id: TxNumber) -> ProviderResult<Option<BlockNumber>>;
@ -53,19 +55,19 @@ pub trait TransactionsProvider: BlockNumReader + Send + Sync {
fn transactions_by_block(
&self,
block: BlockHashOrNumber,
) -> ProviderResult<Option<Vec<TransactionSigned>>>;
) -> ProviderResult<Option<Vec<Self::Transaction>>>;
/// Get transactions by block range.
fn transactions_by_block_range(
&self,
range: impl RangeBounds<BlockNumber>,
) -> ProviderResult<Vec<Vec<TransactionSigned>>>;
) -> ProviderResult<Vec<Vec<Self::Transaction>>>;
/// Get transactions by tx range.
fn transactions_by_tx_range(
&self,
range: impl RangeBounds<TxNumber>,
) -> ProviderResult<Vec<TransactionSignedNoHash>>;
) -> ProviderResult<Vec<Self::Transaction>>;
/// Get Senders from a tx range.
fn senders_by_tx_range(
@ -79,7 +81,10 @@ pub trait TransactionsProvider: BlockNumReader + Send + Sync {
fn transaction_sender(&self, id: TxNumber) -> ProviderResult<Option<Address>>;
}
/// Client trait for fetching additional [TransactionSigned] related data.
/// A helper type alias to access [`TransactionsProvider::Transaction`].
pub type ProviderTx<P> = <P as TransactionsProvider>::Transaction;
/// Client trait for fetching additional transactions related data.
#[auto_impl::auto_impl(&, Arc)]
pub trait TransactionsProviderExt: BlockReader + Send + Sync {
/// Get transactions range by block range.