feat(storage): add an option to return hashed transactions in block_with_senders (#5095)

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
Thomas Coratger
2023-10-20 00:56:01 +02:00
committed by GitHub
parent 5d217a2867
commit 93e837e28a
9 changed files with 59 additions and 22 deletions

View File

@ -19,7 +19,7 @@ use reth_primitives::{
}; };
use reth_provider::{ use reth_provider::{
BlockReader, DatabaseProviderRW, ExecutorFactory, HeaderProvider, LatestStateProviderRef, BlockReader, DatabaseProviderRW, ExecutorFactory, HeaderProvider, LatestStateProviderRef,
OriginalValuesKnown, ProviderError, OriginalValuesKnown, ProviderError, TransactionVariant,
}; };
use std::{ use std::{
ops::RangeInclusive, ops::RangeInclusive,
@ -144,8 +144,10 @@ impl<EF: ExecutorFactory> ExecutionStage<EF> {
let td = provider let td = provider
.header_td_by_number(block_number)? .header_td_by_number(block_number)?
.ok_or_else(|| ProviderError::HeaderNotFound(block_number.into()))?; .ok_or_else(|| ProviderError::HeaderNotFound(block_number.into()))?;
// we need the block's transactions but we don't need the transaction hashes
let block = provider let block = provider
.block_with_senders(block_number)? .block_with_senders(block_number, TransactionVariant::NoHash)?
.ok_or_else(|| ProviderError::BlockNotFound(block_number.into()))?; .ok_or_else(|| ProviderError::BlockNotFound(block_number.into()))?;
fetch_block_duration += time.elapsed(); fetch_block_duration += time.elapsed();

View File

@ -24,7 +24,8 @@ pub use traits::{
HashingWriter, HeaderProvider, HistoryWriter, PrunableBlockExecutor, PruneCheckpointReader, HashingWriter, HeaderProvider, HistoryWriter, PrunableBlockExecutor, PruneCheckpointReader,
PruneCheckpointWriter, ReceiptProvider, ReceiptProviderIdExt, StageCheckpointReader, PruneCheckpointWriter, ReceiptProvider, ReceiptProviderIdExt, StageCheckpointReader,
StageCheckpointWriter, StateProvider, StateProviderBox, StateProviderFactory, StageCheckpointWriter, StateProvider, StateProviderBox, StateProviderFactory,
StateRootProvider, StorageReader, TransactionsProvider, WithdrawalsProvider, StateRootProvider, StorageReader, TransactionVariant, TransactionsProvider,
WithdrawalsProvider,
}; };
/// Provider trait implementations. /// Provider trait implementations.

View File

@ -3,7 +3,7 @@ use crate::{
traits::{BlockSource, ReceiptProvider}, traits::{BlockSource, ReceiptProvider},
BlockHashReader, BlockNumReader, BlockReader, ChainSpecProvider, EvmEnvProvider, BlockHashReader, BlockNumReader, BlockReader, ChainSpecProvider, EvmEnvProvider,
HeaderProvider, ProviderError, PruneCheckpointReader, StageCheckpointReader, StateProviderBox, HeaderProvider, ProviderError, PruneCheckpointReader, StageCheckpointReader, StateProviderBox,
TransactionsProvider, WithdrawalsProvider, TransactionVariant, TransactionsProvider, WithdrawalsProvider,
}; };
use reth_db::{database::Database, init_db, models::StoredBlockBodyIndices, DatabaseEnv}; use reth_db::{database::Database, init_db, models::StoredBlockBodyIndices, DatabaseEnv};
use reth_interfaces::{db::LogLevel, RethError, RethResult}; use reth_interfaces::{db::LogLevel, RethError, RethResult};
@ -246,8 +246,12 @@ impl<DB: Database> BlockReader for ProviderFactory<DB> {
self.provider()?.block_body_indices(number) self.provider()?.block_body_indices(number)
} }
fn block_with_senders(&self, number: BlockNumber) -> RethResult<Option<BlockWithSenders>> { fn block_with_senders(
self.provider()?.block_with_senders(number) &self,
number: BlockNumber,
transaction_kind: TransactionVariant,
) -> RethResult<Option<BlockWithSenders>> {
self.provider()?.block_with_senders(number, transaction_kind)
} }
fn block_range(&self, range: RangeInclusive<BlockNumber>) -> RethResult<Vec<Block>> { fn block_range(&self, range: RangeInclusive<BlockNumber>) -> RethResult<Vec<Block>> {

View File

@ -6,7 +6,7 @@ use crate::{
AccountReader, BlockExecutionWriter, BlockHashReader, BlockNumReader, BlockReader, BlockWriter, AccountReader, BlockExecutionWriter, BlockHashReader, BlockNumReader, BlockReader, BlockWriter,
Chain, EvmEnvProvider, HashingWriter, HeaderProvider, HistoryWriter, OriginalValuesKnown, Chain, EvmEnvProvider, HashingWriter, HeaderProvider, HistoryWriter, OriginalValuesKnown,
ProviderError, PruneCheckpointReader, PruneCheckpointWriter, StageCheckpointReader, ProviderError, PruneCheckpointReader, PruneCheckpointWriter, StageCheckpointReader,
StorageReader, TransactionsProvider, WithdrawalsProvider, StorageReader, TransactionVariant, TransactionsProvider, WithdrawalsProvider,
}; };
use itertools::{izip, Itertools}; use itertools::{izip, Itertools};
use reth_db::{ use reth_db::{
@ -1039,6 +1039,7 @@ impl<TX: DbTx> BlockReader for DatabaseProvider<TX> {
fn block_with_senders( fn block_with_senders(
&self, &self,
block_number: BlockNumber, block_number: BlockNumber,
transaction_kind: TransactionVariant,
) -> RethResult<Option<BlockWithSenders>> { ) -> RethResult<Option<BlockWithSenders>> {
let Some(header) = self.header_by_number(block_number)? else { return Ok(None) }; let Some(header) = self.header_by_number(block_number)? else { return Ok(None) };
@ -1066,14 +1067,14 @@ impl<TX: DbTx> BlockReader for DatabaseProvider<TX> {
let body = transactions let body = transactions
.into_iter() .into_iter()
.map(|tx| { .map(|tx| match transaction_kind {
TransactionSigned { TransactionVariant::NoHash => TransactionSigned {
// TODO: This is the fastest way right now to make everything just work with // Caller explicitly asked for no hash, so we don't calculate it
// a dummy transaction hash.
hash: Default::default(), hash: Default::default(),
signature: tx.signature, signature: tx.signature,
transaction: tx.transaction, transaction: tx.transaction,
} },
TransactionVariant::WithHash => tx.with_hash(),
}) })
.collect(); .collect();

View File

@ -4,7 +4,7 @@ use crate::{
CanonStateNotifications, CanonStateSubscriptions, ChainSpecProvider, ChangeSetReader, CanonStateNotifications, CanonStateSubscriptions, ChainSpecProvider, ChangeSetReader,
EvmEnvProvider, HeaderProvider, ProviderError, PruneCheckpointReader, ReceiptProvider, EvmEnvProvider, HeaderProvider, ProviderError, PruneCheckpointReader, ReceiptProvider,
ReceiptProviderIdExt, StageCheckpointReader, StateProviderBox, StateProviderFactory, ReceiptProviderIdExt, StageCheckpointReader, StateProviderBox, StateProviderFactory,
TransactionsProvider, WithdrawalsProvider, TransactionVariant, TransactionsProvider, WithdrawalsProvider,
}; };
use reth_db::{database::Database, models::StoredBlockBodyIndices}; use reth_db::{database::Database, models::StoredBlockBodyIndices};
use reth_interfaces::{ use reth_interfaces::{
@ -262,12 +262,16 @@ where
/// Returns the block with senders with matching number from database. /// Returns the block with senders with matching number from database.
/// ///
/// **NOTE: The transactions have invalid hashes, since they would need to be calculated on the /// **NOTE: If [TransactionVariant::NoHash] is provided then the transactions have invalid
/// spot, and we want fast querying.** /// hashes, since they would need to be calculated on the spot, and we want fast querying.**
/// ///
/// Returns `None` if block is not found. /// Returns `None` if block is not found.
fn block_with_senders(&self, number: BlockNumber) -> RethResult<Option<BlockWithSenders>> { fn block_with_senders(
self.database.provider()?.block_with_senders(number) &self,
number: BlockNumber,
transaction_kind: TransactionVariant,
) -> RethResult<Option<BlockWithSenders>> {
self.database.provider()?.block_with_senders(number, transaction_kind)
} }
fn block_range(&self, range: RangeInclusive<BlockNumber>) -> RethResult<Vec<Block>> { fn block_range(&self, range: RangeInclusive<BlockNumber>) -> RethResult<Vec<Block>> {

View File

@ -4,7 +4,7 @@ use crate::{
AccountReader, BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt, AccountReader, BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt,
BundleStateDataProvider, ChainSpecProvider, EvmEnvProvider, HeaderProvider, BundleStateDataProvider, ChainSpecProvider, EvmEnvProvider, HeaderProvider,
ReceiptProviderIdExt, StateProvider, StateProviderBox, StateProviderFactory, StateRootProvider, ReceiptProviderIdExt, StateProvider, StateProviderBox, StateProviderFactory, StateRootProvider,
TransactionsProvider, WithdrawalsProvider, TransactionVariant, TransactionsProvider, WithdrawalsProvider,
}; };
use parking_lot::Mutex; use parking_lot::Mutex;
use reth_db::models::StoredBlockBodyIndices; use reth_db::models::StoredBlockBodyIndices;
@ -437,7 +437,11 @@ impl BlockReader for MockEthProvider {
Ok(None) Ok(None)
} }
fn block_with_senders(&self, _number: BlockNumber) -> RethResult<Option<BlockWithSenders>> { fn block_with_senders(
&self,
_number: BlockNumber,
_transaction_kind: TransactionVariant,
) -> RethResult<Option<BlockWithSenders>> {
Ok(None) Ok(None)
} }

View File

@ -4,7 +4,8 @@ use crate::{
AccountReader, BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt, AccountReader, BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt,
ChainSpecProvider, ChangeSetReader, EvmEnvProvider, HeaderProvider, PruneCheckpointReader, ChainSpecProvider, ChangeSetReader, EvmEnvProvider, HeaderProvider, PruneCheckpointReader,
ReceiptProviderIdExt, StageCheckpointReader, StateProvider, StateProviderBox, ReceiptProviderIdExt, StageCheckpointReader, StateProvider, StateProviderBox,
StateProviderFactory, StateRootProvider, TransactionsProvider, WithdrawalsProvider, StateProviderFactory, StateRootProvider, TransactionVariant, TransactionsProvider,
WithdrawalsProvider,
}; };
use reth_db::models::{AccountBeforeTx, StoredBlockBodyIndices}; use reth_db::models::{AccountBeforeTx, StoredBlockBodyIndices};
use reth_interfaces::RethResult; use reth_interfaces::RethResult;
@ -94,6 +95,7 @@ impl BlockReader for NoopProvider {
fn block_with_senders( fn block_with_senders(
&self, &self,
_number: BlockNumber, _number: BlockNumber,
_transaction_kind: TransactionVariant,
) -> RethResult<Option<reth_primitives::BlockWithSenders>> { ) -> RethResult<Option<reth_primitives::BlockWithSenders>> {
Ok(None) Ok(None)
} }

View File

@ -12,6 +12,16 @@ use reth_primitives::{
}; };
use std::ops::RangeInclusive; use std::ops::RangeInclusive;
/// Enum to control transaction hash inclusion.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum TransactionVariant {
/// Indicates that transactions should be processed without including their hashes.
NoHash,
/// Indicates that transactions should be processed along with their hashes.
#[default]
WithHash,
}
/// A helper enum that represents the origin of the requested block. /// A helper enum that represents the origin of the requested block.
/// ///
/// This helper type's sole purpose is to give the caller more control over from where blocks can be /// This helper type's sole purpose is to give the caller more control over from where blocks can be
@ -104,8 +114,14 @@ pub trait BlockReader:
/// Returns the block with senders with matching number from database. /// Returns the block with senders with matching number from database.
/// ///
/// Returns the block's transactions in the requested variant.
///
/// Returns `None` if block is not found. /// Returns `None` if block is not found.
fn block_with_senders(&self, number: BlockNumber) -> RethResult<Option<BlockWithSenders>>; fn block_with_senders(
&self,
number: BlockNumber,
transaction_kind: TransactionVariant,
) -> RethResult<Option<BlockWithSenders>>;
/// Returns all blocks in the given inclusive range. /// Returns all blocks in the given inclusive range.
/// ///

View File

@ -7,7 +7,10 @@ mod storage;
pub use storage::StorageReader; pub use storage::StorageReader;
mod block; mod block;
pub use block::{BlockExecutionWriter, BlockReader, BlockReaderIdExt, BlockSource, BlockWriter}; pub use block::{
BlockExecutionWriter, BlockReader, BlockReaderIdExt, BlockSource, BlockWriter,
TransactionVariant,
};
mod block_hash; mod block_hash;
pub use block_hash::BlockHashReader; pub use block_hash::BlockHashReader;