mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: add Transaction AT to TransactionsProvider (#12794)
This commit is contained in:
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -8655,6 +8655,7 @@ dependencies = [
|
|||||||
name = "reth-prune"
|
name = "reth-prune"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"alloy-eips",
|
||||||
"alloy-primitives",
|
"alloy-primitives",
|
||||||
"assert_matches",
|
"assert_matches",
|
||||||
"itertools 0.13.0",
|
"itertools 0.13.0",
|
||||||
@ -8988,6 +8989,7 @@ dependencies = [
|
|||||||
"reth-execution-types",
|
"reth-execution-types",
|
||||||
"reth-metrics",
|
"reth-metrics",
|
||||||
"reth-primitives",
|
"reth-primitives",
|
||||||
|
"reth-primitives-traits",
|
||||||
"reth-revm",
|
"reth-revm",
|
||||||
"reth-rpc-server-types",
|
"reth-rpc-server-types",
|
||||||
"reth-rpc-types-compat",
|
"reth-rpc-types-compat",
|
||||||
@ -9062,6 +9064,7 @@ name = "reth-stages"
|
|||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alloy-consensus",
|
"alloy-consensus",
|
||||||
|
"alloy-eips",
|
||||||
"alloy-primitives",
|
"alloy-primitives",
|
||||||
"alloy-rlp",
|
"alloy-rlp",
|
||||||
"assert_matches",
|
"assert_matches",
|
||||||
|
|||||||
@ -238,3 +238,6 @@ pub type HeaderTy<N> = <<N as NodeTypes>::Primitives as NodePrimitives>::BlockHe
|
|||||||
|
|
||||||
/// Helper adapter type for accessing [`NodePrimitives::BlockBody`] on [`NodeTypes`].
|
/// Helper adapter type for accessing [`NodePrimitives::BlockBody`] on [`NodeTypes`].
|
||||||
pub type BodyTy<N> = <<N as NodeTypes>::Primitives as NodePrimitives>::BlockBody;
|
pub type BodyTy<N> = <<N as NodeTypes>::Primitives as NodePrimitives>::BlockBody;
|
||||||
|
|
||||||
|
/// Helper adapter type for accessing [`NodePrimitives::SignedTx`] on [`NodeTypes`].
|
||||||
|
pub type TxTy<N> = <<N as NodeTypes>::Primitives as NodePrimitives>::SignedTx;
|
||||||
|
|||||||
@ -250,6 +250,7 @@ impl Encodable2718 for TransactionSigned {
|
|||||||
Transaction::Deposit(deposit_tx) => deposit_tx.eip2718_encoded_length(),
|
Transaction::Deposit(deposit_tx) => deposit_tx.eip2718_encoded_length(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_2718(&self, out: &mut dyn alloy_rlp::BufMut) {
|
fn encode_2718(&self, out: &mut dyn alloy_rlp::BufMut) {
|
||||||
self.transaction.eip2718_encode(&self.signature, out)
|
self.transaction.eip2718_encode(&self.signature, out)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ use reth_optimism_chainspec::OpChainSpec;
|
|||||||
use reth_optimism_evm::RethL1BlockInfo;
|
use reth_optimism_evm::RethL1BlockInfo;
|
||||||
use reth_optimism_forks::OpHardforks;
|
use reth_optimism_forks::OpHardforks;
|
||||||
use reth_primitives::{Receipt, TransactionMeta, TransactionSigned, TxType};
|
use reth_primitives::{Receipt, TransactionMeta, TransactionSigned, TxType};
|
||||||
use reth_provider::ChainSpecProvider;
|
use reth_provider::{ChainSpecProvider, TransactionsProvider};
|
||||||
use reth_rpc_eth_api::{helpers::LoadReceipt, FromEthApiError, RpcReceipt};
|
use reth_rpc_eth_api::{helpers::LoadReceipt, FromEthApiError, RpcReceipt};
|
||||||
use reth_rpc_eth_types::{receipt::build_receipt, EthApiError};
|
use reth_rpc_eth_types::{receipt::build_receipt, EthApiError};
|
||||||
|
|
||||||
@ -21,6 +21,7 @@ impl<N> LoadReceipt for OpEthApi<N>
|
|||||||
where
|
where
|
||||||
Self: Send + Sync,
|
Self: Send + Sync,
|
||||||
N: FullNodeComponents<Types: NodeTypes<ChainSpec = OpChainSpec>>,
|
N: FullNodeComponents<Types: NodeTypes<ChainSpec = OpChainSpec>>,
|
||||||
|
Self::Provider: TransactionsProvider<Transaction = TransactionSigned>,
|
||||||
{
|
{
|
||||||
async fn build_transaction_receipt(
|
async fn build_transaction_receipt(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@ -58,6 +58,7 @@ impl<N> LoadTransaction for OpEthApi<N>
|
|||||||
where
|
where
|
||||||
Self: SpawnBlocking + FullEthApiTypes,
|
Self: SpawnBlocking + FullEthApiTypes,
|
||||||
N: RpcNodeCore<Provider: TransactionsProvider, Pool: TransactionPool>,
|
N: RpcNodeCore<Provider: TransactionsProvider, Pool: TransactionPool>,
|
||||||
|
Self::Pool: TransactionPool,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1624,6 +1624,10 @@ impl Encodable2718 for TransactionSigned {
|
|||||||
fn encode_2718(&self, out: &mut dyn alloy_rlp::BufMut) {
|
fn encode_2718(&self, out: &mut dyn alloy_rlp::BufMut) {
|
||||||
self.transaction.eip2718_encode(&self.signature, out)
|
self.transaction.eip2718_encode(&self.signature, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn trie_hash(&self) -> B256 {
|
||||||
|
self.hash()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable2718 for TransactionSigned {
|
impl Decodable2718 for TransactionSigned {
|
||||||
@ -1720,50 +1724,47 @@ impl<'a> arbitrary::Arbitrary<'a> for TransactionSigned {
|
|||||||
|
|
||||||
/// Signed transaction with recovered signer.
|
/// Signed transaction with recovered signer.
|
||||||
#[derive(Debug, Clone, PartialEq, Hash, Eq, AsRef, Deref)]
|
#[derive(Debug, Clone, PartialEq, Hash, Eq, AsRef, Deref)]
|
||||||
pub struct TransactionSignedEcRecovered {
|
pub struct TransactionSignedEcRecovered<T = TransactionSigned> {
|
||||||
/// Signer of the transaction
|
/// Signer of the transaction
|
||||||
signer: Address,
|
signer: Address,
|
||||||
/// Signed transaction
|
/// Signed transaction
|
||||||
#[deref]
|
#[deref]
|
||||||
#[as_ref]
|
#[as_ref]
|
||||||
signed_transaction: TransactionSigned,
|
signed_transaction: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
// === impl TransactionSignedEcRecovered ===
|
// === impl TransactionSignedEcRecovered ===
|
||||||
|
|
||||||
impl TransactionSignedEcRecovered {
|
impl<T> TransactionSignedEcRecovered<T> {
|
||||||
/// Signer of transaction recovered from signature
|
/// Signer of transaction recovered from signature
|
||||||
pub const fn signer(&self) -> Address {
|
pub const fn signer(&self) -> Address {
|
||||||
self.signer
|
self.signer
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to [`TransactionSigned`]
|
/// Returns a reference to [`TransactionSigned`]
|
||||||
pub const fn as_signed(&self) -> &TransactionSigned {
|
pub const fn as_signed(&self) -> &T {
|
||||||
&self.signed_transaction
|
&self.signed_transaction
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transform back to [`TransactionSigned`]
|
/// Transform back to [`TransactionSigned`]
|
||||||
pub fn into_signed(self) -> TransactionSigned {
|
pub fn into_signed(self) -> T {
|
||||||
self.signed_transaction
|
self.signed_transaction
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Dissolve Self to its component
|
/// Dissolve Self to its component
|
||||||
pub fn to_components(self) -> (TransactionSigned, Address) {
|
pub fn to_components(self) -> (T, Address) {
|
||||||
(self.signed_transaction, self.signer)
|
(self.signed_transaction, self.signer)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create [`TransactionSignedEcRecovered`] from [`TransactionSigned`] and [`Address`] of the
|
/// Create [`TransactionSignedEcRecovered`] from [`TransactionSigned`] and [`Address`] of the
|
||||||
/// signer.
|
/// signer.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn from_signed_transaction(
|
pub const fn from_signed_transaction(signed_transaction: T, signer: Address) -> Self {
|
||||||
signed_transaction: TransactionSigned,
|
|
||||||
signer: Address,
|
|
||||||
) -> Self {
|
|
||||||
Self { signed_transaction, signer }
|
Self { signed_transaction, signer }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for TransactionSignedEcRecovered {
|
impl<T: Encodable> Encodable for TransactionSignedEcRecovered<T> {
|
||||||
/// This encodes the transaction _with_ the signature, and an rlp header.
|
/// This encodes the transaction _with_ the signature, and an rlp header.
|
||||||
///
|
///
|
||||||
/// Refer to docs for [`TransactionSigned::encode`] for details on the exact format.
|
/// Refer to docs for [`TransactionSigned::encode`] for details on the exact format.
|
||||||
@ -1776,9 +1777,9 @@ impl Encodable for TransactionSignedEcRecovered {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for TransactionSignedEcRecovered {
|
impl<T: SignedTransaction> Decodable for TransactionSignedEcRecovered<T> {
|
||||||
fn decode(buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
|
fn decode(buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
|
||||||
let signed_transaction = TransactionSigned::decode(buf)?;
|
let signed_transaction = T::decode(buf)?;
|
||||||
let signer = signed_transaction
|
let signer = signed_transaction
|
||||||
.recover_signer()
|
.recover_signer()
|
||||||
.ok_or(RlpError::Custom("Unable to recover decoded transaction signer."))?;
|
.ok_or(RlpError::Custom("Unable to recover decoded transaction signer."))?;
|
||||||
@ -1786,6 +1787,20 @@ impl Decodable for TransactionSignedEcRecovered {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extension trait for [`SignedTransaction`] to convert it into [`TransactionSignedEcRecovered`].
|
||||||
|
pub trait SignedTransactionIntoRecoveredExt: SignedTransaction {
|
||||||
|
/// Consumes the type, recover signer and return [`TransactionSignedEcRecovered`] _without
|
||||||
|
/// ensuring that the signature has a low `s` value_ (EIP-2).
|
||||||
|
///
|
||||||
|
/// Returns `None` if the transaction's signature is invalid.
|
||||||
|
fn into_ecrecovered_unchecked(self) -> Option<TransactionSignedEcRecovered<Self>> {
|
||||||
|
let signer = self.recover_signer_unchecked()?;
|
||||||
|
Some(TransactionSignedEcRecovered::from_signed_transaction(self, signer))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> SignedTransactionIntoRecoveredExt for T where T: SignedTransaction {}
|
||||||
|
|
||||||
/// Bincode-compatible transaction type serde implementations.
|
/// Bincode-compatible transaction type serde implementations.
|
||||||
#[cfg(feature = "serde-bincode-compat")]
|
#[cfg(feature = "serde-bincode-compat")]
|
||||||
pub mod serde_bincode_compat {
|
pub mod serde_bincode_compat {
|
||||||
@ -1991,6 +2006,21 @@ pub mod serde_bincode_compat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Recovers a list of signers from a transaction list iterator.
|
||||||
|
///
|
||||||
|
/// Returns `None`, if some transaction's signature is invalid
|
||||||
|
pub fn recover_signers<'a, I, T>(txes: I, num_txes: usize) -> Option<Vec<Address>>
|
||||||
|
where
|
||||||
|
T: SignedTransaction,
|
||||||
|
I: IntoParallelIterator<Item = &'a T> + IntoIterator<Item = &'a T> + Send,
|
||||||
|
{
|
||||||
|
if num_txes < *PARALLEL_SENDER_RECOVERY_THRESHOLD {
|
||||||
|
txes.into_iter().map(|tx| tx.recover_signer()).collect()
|
||||||
|
} else {
|
||||||
|
txes.into_par_iter().map(|tx| tx.recover_signer()).collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|||||||
@ -24,6 +24,9 @@ reth-config.workspace = true
|
|||||||
reth-prune-types.workspace = true
|
reth-prune-types.workspace = true
|
||||||
reth-static-file-types.workspace = true
|
reth-static-file-types.workspace = true
|
||||||
|
|
||||||
|
# ethereum
|
||||||
|
alloy-eips.workspace = true
|
||||||
|
|
||||||
# metrics
|
# metrics
|
||||||
reth-metrics.workspace = true
|
reth-metrics.workspace = true
|
||||||
metrics.workspace = true
|
metrics.workspace = true
|
||||||
|
|||||||
@ -3,6 +3,7 @@ use crate::{
|
|||||||
segments::{PruneInput, Segment, SegmentOutput},
|
segments::{PruneInput, Segment, SegmentOutput},
|
||||||
PrunerError,
|
PrunerError,
|
||||||
};
|
};
|
||||||
|
use alloy_eips::eip2718::Encodable2718;
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use reth_db::{tables, transaction::DbTxMut};
|
use reth_db::{tables, transaction::DbTxMut};
|
||||||
use reth_provider::{BlockReader, DBProvider, TransactionsProvider};
|
use reth_provider::{BlockReader, DBProvider, TransactionsProvider};
|
||||||
@ -58,7 +59,7 @@ where
|
|||||||
let hashes = provider
|
let hashes = provider
|
||||||
.transactions_by_tx_range(tx_range.clone())?
|
.transactions_by_tx_range(tx_range.clone())?
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.map(|transaction| transaction.hash())
|
.map(|transaction| transaction.trie_hash())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
// Number of transactions retrieved from the database should match the tx range count
|
// Number of transactions retrieved from the database should match the tx range count
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
//! use alloy_consensus::Header;
|
//! use alloy_consensus::Header;
|
||||||
//! use reth_evm::{execute::BlockExecutorProvider, ConfigureEvm};
|
//! use reth_evm::{execute::BlockExecutorProvider, ConfigureEvm};
|
||||||
//! use reth_network_api::{NetworkInfo, Peers};
|
//! use reth_network_api::{NetworkInfo, Peers};
|
||||||
|
//! use reth_primitives::TransactionSigned;
|
||||||
//! use reth_provider::{AccountReader, CanonStateSubscriptions, ChangeSetReader, FullRpcProvider};
|
//! use reth_provider::{AccountReader, CanonStateSubscriptions, ChangeSetReader, FullRpcProvider};
|
||||||
//! use reth_rpc::EthApi;
|
//! use reth_rpc::EthApi;
|
||||||
//! use reth_rpc_builder::{
|
//! use reth_rpc_builder::{
|
||||||
@ -36,7 +37,8 @@
|
|||||||
//! block_executor: BlockExecutor,
|
//! block_executor: BlockExecutor,
|
||||||
//! consensus: Consensus,
|
//! consensus: Consensus,
|
||||||
//! ) where
|
//! ) where
|
||||||
//! Provider: FullRpcProvider + AccountReader + ChangeSetReader,
|
//! Provider:
|
||||||
|
//! FullRpcProvider<Transaction = TransactionSigned> + AccountReader + ChangeSetReader,
|
||||||
//! Pool: TransactionPool + Unpin + 'static,
|
//! Pool: TransactionPool + Unpin + 'static,
|
||||||
//! Network: NetworkInfo + Peers + Clone + 'static,
|
//! Network: NetworkInfo + Peers + Clone + 'static,
|
||||||
//! Events: CanonStateSubscriptions + Clone + 'static,
|
//! Events: CanonStateSubscriptions + Clone + 'static,
|
||||||
@ -77,6 +79,7 @@
|
|||||||
//! use reth_engine_primitives::EngineTypes;
|
//! use reth_engine_primitives::EngineTypes;
|
||||||
//! use reth_evm::{execute::BlockExecutorProvider, ConfigureEvm};
|
//! use reth_evm::{execute::BlockExecutorProvider, ConfigureEvm};
|
||||||
//! use reth_network_api::{NetworkInfo, Peers};
|
//! use reth_network_api::{NetworkInfo, Peers};
|
||||||
|
//! use reth_primitives::TransactionSigned;
|
||||||
//! use reth_provider::{AccountReader, CanonStateSubscriptions, ChangeSetReader, FullRpcProvider};
|
//! use reth_provider::{AccountReader, CanonStateSubscriptions, ChangeSetReader, FullRpcProvider};
|
||||||
//! use reth_rpc::EthApi;
|
//! use reth_rpc::EthApi;
|
||||||
//! use reth_rpc_api::EngineApiServer;
|
//! use reth_rpc_api::EngineApiServer;
|
||||||
@ -109,7 +112,8 @@
|
|||||||
//! block_executor: BlockExecutor,
|
//! block_executor: BlockExecutor,
|
||||||
//! consensus: Consensus,
|
//! consensus: Consensus,
|
||||||
//! ) where
|
//! ) where
|
||||||
//! Provider: FullRpcProvider + AccountReader + ChangeSetReader,
|
//! Provider:
|
||||||
|
//! FullRpcProvider<Transaction = TransactionSigned> + AccountReader + ChangeSetReader,
|
||||||
//! Pool: TransactionPool + Unpin + 'static,
|
//! Pool: TransactionPool + Unpin + 'static,
|
||||||
//! Network: NetworkInfo + Peers + Clone + 'static,
|
//! Network: NetworkInfo + Peers + Clone + 'static,
|
||||||
//! Events: CanonStateSubscriptions + Clone + 'static,
|
//! Events: CanonStateSubscriptions + Clone + 'static,
|
||||||
|
|||||||
@ -2,18 +2,21 @@
|
|||||||
//! loads receipt data w.r.t. network.
|
//! loads receipt data w.r.t. network.
|
||||||
|
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
use reth_primitives::{Receipt, TransactionMeta, TransactionSigned};
|
use reth_primitives::{Receipt, TransactionMeta};
|
||||||
|
use reth_provider::TransactionsProvider;
|
||||||
|
|
||||||
use crate::{EthApiTypes, RpcNodeCoreExt, RpcReceipt};
|
use crate::{EthApiTypes, RpcNodeCoreExt, RpcReceipt};
|
||||||
|
|
||||||
/// Assembles transaction receipt data w.r.t to network.
|
/// Assembles transaction receipt data w.r.t to network.
|
||||||
///
|
///
|
||||||
/// Behaviour shared by several `eth_` RPC methods, not exclusive to `eth_` receipts RPC methods.
|
/// Behaviour shared by several `eth_` RPC methods, not exclusive to `eth_` receipts RPC methods.
|
||||||
pub trait LoadReceipt: EthApiTypes + RpcNodeCoreExt + Send + Sync {
|
pub trait LoadReceipt:
|
||||||
|
EthApiTypes + RpcNodeCoreExt<Provider: TransactionsProvider> + Send + Sync
|
||||||
|
{
|
||||||
/// Helper method for `eth_getBlockReceipts` and `eth_getTransactionReceipt`.
|
/// Helper method for `eth_getBlockReceipts` and `eth_getTransactionReceipt`.
|
||||||
fn build_transaction_receipt(
|
fn build_transaction_receipt(
|
||||||
&self,
|
&self,
|
||||||
tx: TransactionSigned,
|
tx: <Self::Provider as TransactionsProvider>::Transaction,
|
||||||
meta: TransactionMeta,
|
meta: TransactionMeta,
|
||||||
receipt: Receipt,
|
receipt: Receipt,
|
||||||
) -> impl Future<Output = Result<RpcReceipt<Self::NetworkTypes>, Self::Error>> + Send;
|
) -> impl Future<Output = Result<RpcReceipt<Self::NetworkTypes>, Self::Error>> + Send;
|
||||||
|
|||||||
@ -9,7 +9,9 @@ use alloy_primitives::{Address, Bytes, TxHash, B256};
|
|||||||
use alloy_rpc_types_eth::{transaction::TransactionRequest, BlockNumberOrTag, TransactionInfo};
|
use alloy_rpc_types_eth::{transaction::TransactionRequest, BlockNumberOrTag, TransactionInfo};
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
use reth_primitives::{Receipt, SealedBlockWithSenders, TransactionMeta, TransactionSigned};
|
use reth_primitives::{Receipt, SealedBlockWithSenders, TransactionMeta, TransactionSigned};
|
||||||
use reth_provider::{BlockNumReader, BlockReaderIdExt, ReceiptProvider, TransactionsProvider};
|
use reth_provider::{
|
||||||
|
BlockNumReader, BlockReaderIdExt, ProviderTx, ReceiptProvider, TransactionsProvider,
|
||||||
|
};
|
||||||
use reth_rpc_eth_types::{
|
use reth_rpc_eth_types::{
|
||||||
utils::{binary_search, recover_raw_transaction},
|
utils::{binary_search, recover_raw_transaction},
|
||||||
EthApiError, SignError, TransactionSource,
|
EthApiError, SignError, TransactionSource,
|
||||||
@ -60,10 +62,13 @@ pub trait EthTransactions: LoadTransaction<Provider: BlockReaderIdExt> {
|
|||||||
/// Checks the pool and state.
|
/// Checks the pool and state.
|
||||||
///
|
///
|
||||||
/// Returns `Ok(None)` if no matching transaction was found.
|
/// Returns `Ok(None)` if no matching transaction was found.
|
||||||
|
#[expect(clippy::complexity)]
|
||||||
fn transaction_by_hash(
|
fn transaction_by_hash(
|
||||||
&self,
|
&self,
|
||||||
hash: B256,
|
hash: B256,
|
||||||
) -> impl Future<Output = Result<Option<TransactionSource>, Self::Error>> + Send {
|
) -> impl Future<
|
||||||
|
Output = Result<Option<TransactionSource<ProviderTx<Self::Provider>>>, Self::Error>,
|
||||||
|
> + Send {
|
||||||
LoadTransaction::transaction_by_hash(self, hash)
|
LoadTransaction::transaction_by_hash(self, hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,11 +153,15 @@ pub trait EthTransactions: LoadTransaction<Provider: BlockReaderIdExt> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Helper method that loads a transaction and its receipt.
|
/// Helper method that loads a transaction and its receipt.
|
||||||
|
#[expect(clippy::complexity)]
|
||||||
fn load_transaction_and_receipt(
|
fn load_transaction_and_receipt(
|
||||||
&self,
|
&self,
|
||||||
hash: TxHash,
|
hash: TxHash,
|
||||||
) -> impl Future<
|
) -> impl Future<
|
||||||
Output = Result<Option<(TransactionSigned, TransactionMeta, Receipt)>, Self::Error>,
|
Output = Result<
|
||||||
|
Option<(ProviderTx<Self::Provider>, TransactionMeta, Receipt)>,
|
||||||
|
Self::Error,
|
||||||
|
>,
|
||||||
> + Send
|
> + Send
|
||||||
where
|
where
|
||||||
Self: 'static,
|
Self: 'static,
|
||||||
@ -477,10 +486,13 @@ pub trait LoadTransaction:
|
|||||||
/// Checks the pool and state.
|
/// Checks the pool and state.
|
||||||
///
|
///
|
||||||
/// Returns `Ok(None)` if no matching transaction was found.
|
/// Returns `Ok(None)` if no matching transaction was found.
|
||||||
|
#[expect(clippy::complexity)]
|
||||||
fn transaction_by_hash(
|
fn transaction_by_hash(
|
||||||
&self,
|
&self,
|
||||||
hash: B256,
|
hash: B256,
|
||||||
) -> impl Future<Output = Result<Option<TransactionSource>, Self::Error>> + Send {
|
) -> impl Future<
|
||||||
|
Output = Result<Option<TransactionSource<ProviderTx<Self::Provider>>>, Self::Error>,
|
||||||
|
> + Send {
|
||||||
async move {
|
async move {
|
||||||
// Try to find the transaction on disk
|
// Try to find the transaction on disk
|
||||||
let mut resp = self
|
let mut resp = self
|
||||||
|
|||||||
@ -7,9 +7,11 @@ use std::{
|
|||||||
|
|
||||||
use alloy_network::Network;
|
use alloy_network::Network;
|
||||||
use alloy_rpc_types_eth::Block;
|
use alloy_rpc_types_eth::Block;
|
||||||
|
use reth_primitives::TransactionSigned;
|
||||||
|
use reth_provider::TransactionsProvider;
|
||||||
use reth_rpc_types_compat::TransactionCompat;
|
use reth_rpc_types_compat::TransactionCompat;
|
||||||
|
|
||||||
use crate::{AsEthApiError, FromEthApiError, FromEvmError};
|
use crate::{AsEthApiError, FromEthApiError, FromEvmError, RpcNodeCore};
|
||||||
|
|
||||||
/// Network specific `eth` API types.
|
/// Network specific `eth` API types.
|
||||||
pub trait EthApiTypes: Send + Sync + Clone {
|
pub trait EthApiTypes: Send + Sync + Clone {
|
||||||
@ -43,22 +45,27 @@ pub type RpcReceipt<T> = <T as Network>::ReceiptResponse;
|
|||||||
pub type RpcError<T> = <T as EthApiTypes>::Error;
|
pub type RpcError<T> = <T as EthApiTypes>::Error;
|
||||||
|
|
||||||
/// Helper trait holds necessary trait bounds on [`EthApiTypes`] to implement `eth` API.
|
/// Helper trait holds necessary trait bounds on [`EthApiTypes`] to implement `eth` API.
|
||||||
pub trait FullEthApiTypes:
|
pub trait FullEthApiTypes
|
||||||
EthApiTypes<
|
where
|
||||||
TransactionCompat: TransactionCompat<
|
Self: RpcNodeCore<Provider: TransactionsProvider<Transaction = TransactionSigned>>
|
||||||
Transaction = RpcTransaction<Self::NetworkTypes>,
|
+ EthApiTypes<
|
||||||
Error = RpcError<Self>,
|
TransactionCompat: TransactionCompat<
|
||||||
>,
|
<Self::Provider as TransactionsProvider>::Transaction,
|
||||||
>
|
Transaction = RpcTransaction<Self::NetworkTypes>,
|
||||||
|
Error = RpcError<Self>,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> FullEthApiTypes for T where
|
impl<T> FullEthApiTypes for T where
|
||||||
T: EthApiTypes<
|
T: RpcNodeCore<Provider: TransactionsProvider<Transaction = TransactionSigned>>
|
||||||
TransactionCompat: TransactionCompat<
|
+ EthApiTypes<
|
||||||
Transaction = RpcTransaction<T::NetworkTypes>,
|
TransactionCompat: TransactionCompat<
|
||||||
Error = RpcError<T>,
|
<Self::Provider as TransactionsProvider>::Transaction,
|
||||||
>,
|
Transaction = RpcTransaction<T::NetworkTypes>,
|
||||||
>
|
Error = RpcError<T>,
|
||||||
|
>,
|
||||||
|
>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ reth-evm.workspace = true
|
|||||||
reth-execution-types.workspace = true
|
reth-execution-types.workspace = true
|
||||||
reth-metrics.workspace = true
|
reth-metrics.workspace = true
|
||||||
reth-primitives = { workspace = true, features = ["secp256k1"] }
|
reth-primitives = { workspace = true, features = ["secp256k1"] }
|
||||||
|
reth-primitives-traits.workspace = true
|
||||||
reth-storage-api.workspace = true
|
reth-storage-api.workspace = true
|
||||||
reth-revm.workspace = true
|
reth-revm.workspace = true
|
||||||
reth-rpc-server-types.workspace = true
|
reth-rpc-server-types.workspace = true
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
//!
|
//!
|
||||||
//! Log parsing for building filter.
|
//! Log parsing for building filter.
|
||||||
|
|
||||||
use alloy_eips::BlockNumHash;
|
use alloy_eips::{eip2718::Encodable2718, BlockNumHash};
|
||||||
use alloy_primitives::TxHash;
|
use alloy_primitives::TxHash;
|
||||||
use alloy_rpc_types_eth::{FilteredParams, Log};
|
use alloy_rpc_types_eth::{FilteredParams, Log};
|
||||||
use reth_chainspec::ChainInfo;
|
use reth_chainspec::ChainInfo;
|
||||||
@ -110,7 +110,7 @@ pub fn append_matching_block_logs<P: BlockReader>(
|
|||||||
ProviderError::TransactionNotFound(transaction_id.into())
|
ProviderError::TransactionNotFound(transaction_id.into())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Some(transaction.hash())
|
Some(transaction.trie_hash())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
use alloy_primitives::B256;
|
use alloy_primitives::B256;
|
||||||
use alloy_rpc_types_eth::TransactionInfo;
|
use alloy_rpc_types_eth::TransactionInfo;
|
||||||
use reth_primitives::TransactionSignedEcRecovered;
|
use reth_primitives::{TransactionSigned, TransactionSignedEcRecovered};
|
||||||
|
use reth_primitives_traits::SignedTransaction;
|
||||||
use reth_rpc_types_compat::{
|
use reth_rpc_types_compat::{
|
||||||
transaction::{from_recovered, from_recovered_with_block_context},
|
transaction::{from_recovered, from_recovered_with_block_context},
|
||||||
TransactionCompat,
|
TransactionCompat,
|
||||||
@ -12,15 +13,15 @@ use reth_rpc_types_compat::{
|
|||||||
|
|
||||||
/// Represents from where a transaction was fetched.
|
/// Represents from where a transaction was fetched.
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub enum TransactionSource {
|
pub enum TransactionSource<T = TransactionSigned> {
|
||||||
/// Transaction exists in the pool (Pending)
|
/// Transaction exists in the pool (Pending)
|
||||||
Pool(TransactionSignedEcRecovered),
|
Pool(TransactionSignedEcRecovered<T>),
|
||||||
/// Transaction already included in a block
|
/// Transaction already included in a block
|
||||||
///
|
///
|
||||||
/// This can be a historical block or a pending block (received from the CL)
|
/// This can be a historical block or a pending block (received from the CL)
|
||||||
Block {
|
Block {
|
||||||
/// Transaction fetched via provider
|
/// Transaction fetched via provider
|
||||||
transaction: TransactionSignedEcRecovered,
|
transaction: TransactionSignedEcRecovered<T>,
|
||||||
/// Index of the transaction in the block
|
/// Index of the transaction in the block
|
||||||
index: u64,
|
index: u64,
|
||||||
/// Hash of the block.
|
/// Hash of the block.
|
||||||
@ -34,22 +35,22 @@ pub enum TransactionSource {
|
|||||||
|
|
||||||
// === impl TransactionSource ===
|
// === impl TransactionSource ===
|
||||||
|
|
||||||
impl TransactionSource {
|
impl<T: SignedTransaction> TransactionSource<T> {
|
||||||
/// Consumes the type and returns the wrapped transaction.
|
/// Consumes the type and returns the wrapped transaction.
|
||||||
pub fn into_recovered(self) -> TransactionSignedEcRecovered {
|
pub fn into_recovered(self) -> TransactionSignedEcRecovered<T> {
|
||||||
self.into()
|
self.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Conversion into network specific transaction type.
|
/// Conversion into network specific transaction type.
|
||||||
pub fn into_transaction<T: TransactionCompat>(
|
pub fn into_transaction<Builder: TransactionCompat<T>>(
|
||||||
self,
|
self,
|
||||||
resp_builder: &T,
|
resp_builder: &Builder,
|
||||||
) -> Result<T::Transaction, T::Error> {
|
) -> Result<Builder::Transaction, Builder::Error> {
|
||||||
match self {
|
match self {
|
||||||
Self::Pool(tx) => from_recovered(tx, resp_builder),
|
Self::Pool(tx) => from_recovered(tx, resp_builder),
|
||||||
Self::Block { transaction, index, block_hash, block_number, base_fee } => {
|
Self::Block { transaction, index, block_hash, block_number, base_fee } => {
|
||||||
let tx_info = TransactionInfo {
|
let tx_info = TransactionInfo {
|
||||||
hash: Some(transaction.hash()),
|
hash: Some(transaction.trie_hash()),
|
||||||
index: Some(index),
|
index: Some(index),
|
||||||
block_hash: Some(block_hash),
|
block_hash: Some(block_hash),
|
||||||
block_number: Some(block_number),
|
block_number: Some(block_number),
|
||||||
@ -62,14 +63,14 @@ impl TransactionSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the transaction and block related info, if not pending
|
/// Returns the transaction and block related info, if not pending
|
||||||
pub fn split(self) -> (TransactionSignedEcRecovered, TransactionInfo) {
|
pub fn split(self) -> (TransactionSignedEcRecovered<T>, TransactionInfo) {
|
||||||
match self {
|
match self {
|
||||||
Self::Pool(tx) => {
|
Self::Pool(tx) => {
|
||||||
let hash = tx.hash();
|
let hash = tx.trie_hash();
|
||||||
(tx, TransactionInfo { hash: Some(hash), ..Default::default() })
|
(tx, TransactionInfo { hash: Some(hash), ..Default::default() })
|
||||||
}
|
}
|
||||||
Self::Block { transaction, index, block_hash, block_number, base_fee } => {
|
Self::Block { transaction, index, block_hash, block_number, base_fee } => {
|
||||||
let hash = transaction.hash();
|
let hash = transaction.trie_hash();
|
||||||
(
|
(
|
||||||
transaction,
|
transaction,
|
||||||
TransactionInfo {
|
TransactionInfo {
|
||||||
@ -85,8 +86,8 @@ impl TransactionSource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TransactionSource> for TransactionSignedEcRecovered {
|
impl<T> From<TransactionSource<T>> for TransactionSignedEcRecovered<T> {
|
||||||
fn from(value: TransactionSource) -> Self {
|
fn from(value: TransactionSource<T>) -> Self {
|
||||||
match value {
|
match value {
|
||||||
TransactionSource::Pool(tx) => tx,
|
TransactionSource::Pool(tx) => tx,
|
||||||
TransactionSource::Block { transaction, .. } => transaction,
|
TransactionSource::Block { transaction, .. } => transaction,
|
||||||
|
|||||||
@ -7,7 +7,7 @@ use alloy_rlp::Encodable;
|
|||||||
use alloy_rpc_types_eth::{
|
use alloy_rpc_types_eth::{
|
||||||
Block, BlockTransactions, BlockTransactionsKind, Header, TransactionInfo,
|
Block, BlockTransactions, BlockTransactionsKind, Header, TransactionInfo,
|
||||||
};
|
};
|
||||||
use reth_primitives::{Block as PrimitiveBlock, BlockWithSenders};
|
use reth_primitives::{Block as PrimitiveBlock, BlockWithSenders, TransactionSigned};
|
||||||
|
|
||||||
use crate::{transaction::from_recovered_with_block_context, TransactionCompat};
|
use crate::{transaction::from_recovered_with_block_context, TransactionCompat};
|
||||||
|
|
||||||
@ -87,7 +87,11 @@ pub fn from_block_full<T: TransactionCompat>(
|
|||||||
index: Some(idx as u64),
|
index: Some(idx as u64),
|
||||||
};
|
};
|
||||||
|
|
||||||
from_recovered_with_block_context::<T>(signed_tx_ec_recovered, tx_info, tx_resp_builder)
|
from_recovered_with_block_context::<TransactionSigned, T>(
|
||||||
|
signed_tx_ec_recovered,
|
||||||
|
tx_info,
|
||||||
|
tx_resp_builder,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, T::Error>>()?;
|
.collect::<Result<Vec<_>, T::Error>>()?;
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ use alloy_rpc_types_eth::{
|
|||||||
request::{TransactionInput, TransactionRequest},
|
request::{TransactionInput, TransactionRequest},
|
||||||
TransactionInfo,
|
TransactionInfo,
|
||||||
};
|
};
|
||||||
use reth_primitives::TransactionSignedEcRecovered;
|
use reth_primitives::{TransactionSigned, TransactionSignedEcRecovered};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// Create a new rpc transaction result for a mined transaction, using the given block hash,
|
/// Create a new rpc transaction result for a mined transaction, using the given block hash,
|
||||||
@ -16,8 +16,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
///
|
///
|
||||||
/// The block hash, number, and tx index fields should be from the original block where the
|
/// The block hash, number, and tx index fields should be from the original block where the
|
||||||
/// transaction was mined.
|
/// transaction was mined.
|
||||||
pub fn from_recovered_with_block_context<T: TransactionCompat>(
|
pub fn from_recovered_with_block_context<Tx, T: TransactionCompat<Tx>>(
|
||||||
tx: TransactionSignedEcRecovered,
|
tx: TransactionSignedEcRecovered<Tx>,
|
||||||
tx_info: TransactionInfo,
|
tx_info: TransactionInfo,
|
||||||
resp_builder: &T,
|
resp_builder: &T,
|
||||||
) -> Result<T::Transaction, T::Error> {
|
) -> Result<T::Transaction, T::Error> {
|
||||||
@ -26,15 +26,17 @@ pub fn from_recovered_with_block_context<T: TransactionCompat>(
|
|||||||
|
|
||||||
/// Create a new rpc transaction result for a _pending_ signed transaction, setting block
|
/// Create a new rpc transaction result for a _pending_ signed transaction, setting block
|
||||||
/// environment related fields to `None`.
|
/// environment related fields to `None`.
|
||||||
pub fn from_recovered<T: TransactionCompat>(
|
pub fn from_recovered<Tx, T: TransactionCompat<Tx>>(
|
||||||
tx: TransactionSignedEcRecovered,
|
tx: TransactionSignedEcRecovered<Tx>,
|
||||||
resp_builder: &T,
|
resp_builder: &T,
|
||||||
) -> Result<T::Transaction, T::Error> {
|
) -> Result<T::Transaction, T::Error> {
|
||||||
resp_builder.fill(tx, TransactionInfo::default())
|
resp_builder.fill(tx, TransactionInfo::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds RPC transaction w.r.t. network.
|
/// Builds RPC transaction w.r.t. network.
|
||||||
pub trait TransactionCompat: Send + Sync + Unpin + Clone + fmt::Debug {
|
pub trait TransactionCompat<T = TransactionSigned>:
|
||||||
|
Send + Sync + Unpin + Clone + fmt::Debug
|
||||||
|
{
|
||||||
/// RPC transaction response type.
|
/// RPC transaction response type.
|
||||||
type Transaction: Serialize
|
type Transaction: Serialize
|
||||||
+ for<'de> Deserialize<'de>
|
+ for<'de> Deserialize<'de>
|
||||||
@ -51,7 +53,7 @@ pub trait TransactionCompat: Send + Sync + Unpin + Clone + fmt::Debug {
|
|||||||
/// environment related fields to `None`.
|
/// environment related fields to `None`.
|
||||||
fn fill(
|
fn fill(
|
||||||
&self,
|
&self,
|
||||||
tx: TransactionSignedEcRecovered,
|
tx: TransactionSignedEcRecovered<T>,
|
||||||
tx_inf: TransactionInfo,
|
tx_inf: TransactionInfo,
|
||||||
) -> Result<Self::Transaction, Self::Error>;
|
) -> Result<Self::Transaction, Self::Error>;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
//! Builds an RPC receipt response w.r.t. data layout of network.
|
//! Builds an RPC receipt response w.r.t. data layout of network.
|
||||||
|
|
||||||
use reth_primitives::{Receipt, TransactionMeta, TransactionSigned};
|
use reth_primitives::{Receipt, TransactionMeta, TransactionSigned};
|
||||||
|
use reth_provider::TransactionsProvider;
|
||||||
use reth_rpc_eth_api::{helpers::LoadReceipt, FromEthApiError, RpcNodeCoreExt, RpcReceipt};
|
use reth_rpc_eth_api::{helpers::LoadReceipt, FromEthApiError, RpcNodeCoreExt, RpcReceipt};
|
||||||
use reth_rpc_eth_types::{EthApiError, EthReceiptBuilder};
|
use reth_rpc_eth_types::{EthApiError, EthReceiptBuilder};
|
||||||
|
|
||||||
@ -8,7 +9,7 @@ use crate::EthApi;
|
|||||||
|
|
||||||
impl<Provider, Pool, Network, EvmConfig> LoadReceipt for EthApi<Provider, Pool, Network, EvmConfig>
|
impl<Provider, Pool, Network, EvmConfig> LoadReceipt for EthApi<Provider, Pool, Network, EvmConfig>
|
||||||
where
|
where
|
||||||
Self: RpcNodeCoreExt,
|
Self: RpcNodeCoreExt<Provider: TransactionsProvider<Transaction = TransactionSigned>>,
|
||||||
{
|
{
|
||||||
async fn build_transaction_receipt(
|
async fn build_transaction_receipt(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@ -39,6 +39,7 @@ reth-trie-db = { workspace = true, features = ["metrics"] }
|
|||||||
|
|
||||||
reth-testing-utils = { workspace = true, optional = true }
|
reth-testing-utils = { workspace = true, optional = true }
|
||||||
|
|
||||||
|
alloy-eips.workspace = true
|
||||||
alloy-primitives.workspace = true
|
alloy-primitives.workspace = true
|
||||||
alloy-consensus.workspace = true
|
alloy-consensus.workspace = true
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,15 @@
|
|||||||
|
use alloy_eips::eip2718::Encodable2718;
|
||||||
use alloy_primitives::{TxHash, TxNumber};
|
use alloy_primitives::{TxHash, TxNumber};
|
||||||
use num_traits::Zero;
|
use num_traits::Zero;
|
||||||
use reth_config::config::{EtlConfig, TransactionLookupConfig};
|
use reth_config::config::{EtlConfig, TransactionLookupConfig};
|
||||||
use reth_db::{tables, RawKey, RawValue};
|
use reth_db::{table::Value, tables, RawKey, RawValue};
|
||||||
use reth_db_api::{
|
use reth_db_api::{
|
||||||
cursor::{DbCursorRO, DbCursorRW},
|
cursor::{DbCursorRO, DbCursorRW},
|
||||||
transaction::{DbTx, DbTxMut},
|
transaction::{DbTx, DbTxMut},
|
||||||
};
|
};
|
||||||
use reth_etl::Collector;
|
use reth_etl::Collector;
|
||||||
|
use reth_primitives::NodePrimitives;
|
||||||
|
use reth_primitives_traits::SignedTransaction;
|
||||||
use reth_provider::{
|
use reth_provider::{
|
||||||
BlockReader, DBProvider, PruneCheckpointReader, PruneCheckpointWriter,
|
BlockReader, DBProvider, PruneCheckpointReader, PruneCheckpointWriter,
|
||||||
StaticFileProviderFactory, StatsReader, TransactionsProvider, TransactionsProviderExt,
|
StaticFileProviderFactory, StatsReader, TransactionsProvider, TransactionsProviderExt,
|
||||||
@ -60,7 +63,7 @@ where
|
|||||||
+ BlockReader
|
+ BlockReader
|
||||||
+ PruneCheckpointReader
|
+ PruneCheckpointReader
|
||||||
+ StatsReader
|
+ StatsReader
|
||||||
+ StaticFileProviderFactory
|
+ StaticFileProviderFactory<Primitives: NodePrimitives<SignedTx: Value + SignedTransaction>>
|
||||||
+ TransactionsProviderExt,
|
+ TransactionsProviderExt,
|
||||||
{
|
{
|
||||||
/// Return the id of the stage
|
/// Return the id of the stage
|
||||||
@ -206,7 +209,7 @@ where
|
|||||||
for tx_id in body.tx_num_range() {
|
for tx_id in body.tx_num_range() {
|
||||||
// First delete the transaction and hash to id mapping
|
// First delete the transaction and hash to id mapping
|
||||||
if let Some(transaction) = static_file_provider.transaction_by_id(tx_id)? {
|
if let Some(transaction) = static_file_provider.transaction_by_id(tx_id)? {
|
||||||
if tx_hash_number_cursor.seek_exact(transaction.hash())?.is_some() {
|
if tx_hash_number_cursor.seek_exact(transaction.trie_hash())?.is_some() {
|
||||||
tx_hash_number_cursor.delete_current()?;
|
tx_hash_number_cursor.delete_current()?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,7 +25,7 @@ use reth_db::{models::BlockNumberAddress, transaction::DbTx, Database};
|
|||||||
use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices};
|
use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices};
|
||||||
use reth_evm::ConfigureEvmEnv;
|
use reth_evm::ConfigureEvmEnv;
|
||||||
use reth_execution_types::ExecutionOutcome;
|
use reth_execution_types::ExecutionOutcome;
|
||||||
use reth_node_types::NodeTypesWithDB;
|
use reth_node_types::{NodeTypesWithDB, TxTy};
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
Account, Block, BlockWithSenders, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader,
|
Account, Block, BlockWithSenders, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader,
|
||||||
StorageEntry, TransactionMeta, TransactionSigned, TransactionSignedNoHash,
|
StorageEntry, TransactionMeta, TransactionSigned, TransactionSignedNoHash,
|
||||||
@ -331,29 +331,31 @@ impl<N: ProviderNodeTypes> BlockReader for BlockchainProvider2<N> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<N: ProviderNodeTypes> TransactionsProvider for BlockchainProvider2<N> {
|
impl<N: ProviderNodeTypes> TransactionsProvider for BlockchainProvider2<N> {
|
||||||
|
type Transaction = TxTy<N>;
|
||||||
|
|
||||||
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
|
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
|
||||||
self.consistent_provider()?.transaction_id(tx_hash)
|
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)
|
self.consistent_provider()?.transaction_by_id(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_by_id_unhashed(
|
fn transaction_by_id_unhashed(
|
||||||
&self,
|
&self,
|
||||||
id: TxNumber,
|
id: TxNumber,
|
||||||
) -> ProviderResult<Option<TransactionSignedNoHash>> {
|
) -> ProviderResult<Option<Self::Transaction>> {
|
||||||
self.consistent_provider()?.transaction_by_id_unhashed(id)
|
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)
|
self.consistent_provider()?.transaction_by_hash(hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_by_hash_with_meta(
|
fn transaction_by_hash_with_meta(
|
||||||
&self,
|
&self,
|
||||||
tx_hash: TxHash,
|
tx_hash: TxHash,
|
||||||
) -> ProviderResult<Option<(TransactionSigned, TransactionMeta)>> {
|
) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>> {
|
||||||
self.consistent_provider()?.transaction_by_hash_with_meta(tx_hash)
|
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(
|
fn transactions_by_block(
|
||||||
&self,
|
&self,
|
||||||
id: BlockHashOrNumber,
|
id: BlockHashOrNumber,
|
||||||
) -> ProviderResult<Option<Vec<TransactionSigned>>> {
|
) -> ProviderResult<Option<Vec<Self::Transaction>>> {
|
||||||
self.consistent_provider()?.transactions_by_block(id)
|
self.consistent_provider()?.transactions_by_block(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transactions_by_block_range(
|
fn transactions_by_block_range(
|
||||||
&self,
|
&self,
|
||||||
range: impl RangeBounds<BlockNumber>,
|
range: impl RangeBounds<BlockNumber>,
|
||||||
) -> ProviderResult<Vec<Vec<TransactionSigned>>> {
|
) -> ProviderResult<Vec<Vec<Self::Transaction>>> {
|
||||||
self.consistent_provider()?.transactions_by_block_range(range)
|
self.consistent_provider()?.transactions_by_block_range(range)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transactions_by_tx_range(
|
fn transactions_by_tx_range(
|
||||||
&self,
|
&self,
|
||||||
range: impl RangeBounds<TxNumber>,
|
range: impl RangeBounds<TxNumber>,
|
||||||
) -> ProviderResult<Vec<TransactionSignedNoHash>> {
|
) -> ProviderResult<Vec<Self::Transaction>> {
|
||||||
self.consistent_provider()?.transactions_by_tx_range(range)
|
self.consistent_provider()?.transactions_by_tx_range(range)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2244,9 +2246,7 @@ mod tests {
|
|||||||
(transactions_by_tx_range, |block: &SealedBlock, _: &Vec<Vec<Receipt>>| block
|
(transactions_by_tx_range, |block: &SealedBlock, _: &Vec<Vec<Receipt>>| block
|
||||||
.body
|
.body
|
||||||
.transactions
|
.transactions
|
||||||
.iter()
|
.clone()),
|
||||||
.map(|tx| Into::<TransactionSignedNoHash>::into(tx.clone()))
|
|
||||||
.collect::<Vec<_>>()),
|
|
||||||
(receipts_by_tx_range, |block: &SealedBlock, receipts: &Vec<Vec<Receipt>>| receipts
|
(receipts_by_tx_range, |block: &SealedBlock, receipts: &Vec<Vec<Receipt>>| receipts
|
||||||
[block.number as usize]
|
[block.number as usize]
|
||||||
.clone())
|
.clone())
|
||||||
@ -2591,9 +2591,7 @@ mod tests {
|
|||||||
transaction_by_id_unhashed,
|
transaction_by_id_unhashed,
|
||||||
|block: &SealedBlock, tx_num: TxNumber, _: B256, _: &Vec<Vec<Receipt>>| (
|
|block: &SealedBlock, tx_num: TxNumber, _: B256, _: &Vec<Vec<Receipt>>| (
|
||||||
tx_num,
|
tx_num,
|
||||||
Some(Into::<TransactionSignedNoHash>::into(
|
Some(block.body.transactions[test_tx_index].clone())
|
||||||
block.body.transactions[test_tx_index].clone()
|
|
||||||
))
|
|
||||||
),
|
),
|
||||||
u64::MAX
|
u64::MAX
|
||||||
),
|
),
|
||||||
|
|||||||
@ -18,9 +18,10 @@ use reth_db::models::BlockNumberAddress;
|
|||||||
use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices};
|
use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices};
|
||||||
use reth_evm::ConfigureEvmEnv;
|
use reth_evm::ConfigureEvmEnv;
|
||||||
use reth_execution_types::{BundleStateInit, ExecutionOutcome, RevertsInit};
|
use reth_execution_types::{BundleStateInit, ExecutionOutcome, RevertsInit};
|
||||||
|
use reth_node_types::TxTy;
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
Account, Block, BlockWithSenders, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader,
|
Account, Block, BlockWithSenders, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader,
|
||||||
StorageEntry, TransactionMeta, TransactionSigned, TransactionSignedNoHash,
|
StorageEntry, TransactionMeta,
|
||||||
};
|
};
|
||||||
use reth_prune_types::{PruneCheckpoint, PruneSegment};
|
use reth_prune_types::{PruneCheckpoint, PruneSegment};
|
||||||
use reth_stages_types::{StageCheckpoint, StageId};
|
use reth_stages_types::{StageCheckpoint, StageId};
|
||||||
@ -927,6 +928,8 @@ impl<N: ProviderNodeTypes> BlockReader for ConsistentProvider<N> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<N: ProviderNodeTypes> TransactionsProvider for ConsistentProvider<N> {
|
impl<N: ProviderNodeTypes> TransactionsProvider for ConsistentProvider<N> {
|
||||||
|
type Transaction = TxTy<N>;
|
||||||
|
|
||||||
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
|
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
|
||||||
self.get_in_memory_or_storage_by_tx(
|
self.get_in_memory_or_storage_by_tx(
|
||||||
tx_hash.into(),
|
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(
|
self.get_in_memory_or_storage_by_tx(
|
||||||
id.into(),
|
id.into(),
|
||||||
|provider| provider.transaction_by_id(id),
|
|provider| provider.transaction_by_id(id),
|
||||||
|tx_index, _, block_state| {
|
|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(
|
fn transaction_by_id_unhashed(
|
||||||
&self,
|
&self,
|
||||||
id: TxNumber,
|
id: TxNumber,
|
||||||
) -> ProviderResult<Option<TransactionSignedNoHash>> {
|
) -> ProviderResult<Option<Self::Transaction>> {
|
||||||
self.get_in_memory_or_storage_by_tx(
|
self.get_in_memory_or_storage_by_tx(
|
||||||
id.into(),
|
id.into(),
|
||||||
|provider| provider.transaction_by_id_unhashed(id),
|
|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)) {
|
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)
|
self.storage_provider.transaction_by_hash(hash)
|
||||||
@ -976,11 +986,11 @@ impl<N: ProviderNodeTypes> TransactionsProvider for ConsistentProvider<N> {
|
|||||||
fn transaction_by_hash_with_meta(
|
fn transaction_by_hash_with_meta(
|
||||||
&self,
|
&self,
|
||||||
tx_hash: TxHash,
|
tx_hash: TxHash,
|
||||||
) -> ProviderResult<Option<(TransactionSigned, TransactionMeta)>> {
|
) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>> {
|
||||||
if let Some((tx, meta)) =
|
if let Some((tx, meta)) =
|
||||||
self.head_block.as_ref().and_then(|b| b.transaction_meta_on_chain(tx_hash))
|
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)
|
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(
|
fn transactions_by_block(
|
||||||
&self,
|
&self,
|
||||||
id: BlockHashOrNumber,
|
id: BlockHashOrNumber,
|
||||||
) -> ProviderResult<Option<Vec<TransactionSigned>>> {
|
) -> ProviderResult<Option<Vec<Self::Transaction>>> {
|
||||||
self.get_in_memory_or_storage_by_block(
|
self.get_in_memory_or_storage_by_block(
|
||||||
id,
|
id,
|
||||||
|provider| provider.transactions_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(
|
fn transactions_by_block_range(
|
||||||
&self,
|
&self,
|
||||||
range: impl RangeBounds<BlockNumber>,
|
range: impl RangeBounds<BlockNumber>,
|
||||||
) -> ProviderResult<Vec<Vec<TransactionSigned>>> {
|
) -> ProviderResult<Vec<Vec<Self::Transaction>>> {
|
||||||
self.get_in_memory_or_storage_by_block_range_while(
|
self.get_in_memory_or_storage_by_block_range_while(
|
||||||
range,
|
range,
|
||||||
|db_provider, range, _| db_provider.transactions_by_block_range(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,
|
|_| true,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -1020,7 +1052,7 @@ impl<N: ProviderNodeTypes> TransactionsProvider for ConsistentProvider<N> {
|
|||||||
fn transactions_by_tx_range(
|
fn transactions_by_tx_range(
|
||||||
&self,
|
&self,
|
||||||
range: impl RangeBounds<TxNumber>,
|
range: impl RangeBounds<TxNumber>,
|
||||||
) -> ProviderResult<Vec<TransactionSignedNoHash>> {
|
) -> ProviderResult<Vec<Self::Transaction>> {
|
||||||
self.get_in_memory_or_storage_by_tx_range(
|
self.get_in_memory_or_storage_by_tx_range(
|
||||||
range,
|
range,
|
||||||
|db_provider, db_range| db_provider.transactions_by_tx_range(db_range),
|
|db_provider, db_range| db_provider.transactions_by_tx_range(db_range),
|
||||||
|
|||||||
@ -19,10 +19,10 @@ use reth_db::{init_db, mdbx::DatabaseArguments, DatabaseEnv};
|
|||||||
use reth_db_api::{database::Database, models::StoredBlockBodyIndices};
|
use reth_db_api::{database::Database, models::StoredBlockBodyIndices};
|
||||||
use reth_errors::{RethError, RethResult};
|
use reth_errors::{RethError, RethResult};
|
||||||
use reth_evm::ConfigureEvmEnv;
|
use reth_evm::ConfigureEvmEnv;
|
||||||
use reth_node_types::NodeTypesWithDB;
|
use reth_node_types::{NodeTypesWithDB, TxTy};
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
Block, BlockWithSenders, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader,
|
Block, BlockWithSenders, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader,
|
||||||
StaticFileSegment, TransactionMeta, TransactionSigned, TransactionSignedNoHash,
|
StaticFileSegment, TransactionMeta,
|
||||||
};
|
};
|
||||||
use reth_prune_types::{PruneCheckpoint, PruneModes, PruneSegment};
|
use reth_prune_types::{PruneCheckpoint, PruneModes, PruneSegment};
|
||||||
use reth_stages_types::{StageCheckpoint, StageId};
|
use reth_stages_types::{StageCheckpoint, StageId};
|
||||||
@ -420,11 +420,13 @@ impl<N: ProviderNodeTypes> BlockReader for ProviderFactory<N> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<N: ProviderNodeTypes> TransactionsProvider for ProviderFactory<N> {
|
impl<N: ProviderNodeTypes> TransactionsProvider for ProviderFactory<N> {
|
||||||
|
type Transaction = TxTy<N>;
|
||||||
|
|
||||||
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
|
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
|
||||||
self.provider()?.transaction_id(tx_hash)
|
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(
|
self.static_file_provider.get_with_static_file_or_database(
|
||||||
StaticFileSegment::Transactions,
|
StaticFileSegment::Transactions,
|
||||||
id,
|
id,
|
||||||
@ -436,7 +438,7 @@ impl<N: ProviderNodeTypes> TransactionsProvider for ProviderFactory<N> {
|
|||||||
fn transaction_by_id_unhashed(
|
fn transaction_by_id_unhashed(
|
||||||
&self,
|
&self,
|
||||||
id: TxNumber,
|
id: TxNumber,
|
||||||
) -> ProviderResult<Option<TransactionSignedNoHash>> {
|
) -> ProviderResult<Option<Self::Transaction>> {
|
||||||
self.static_file_provider.get_with_static_file_or_database(
|
self.static_file_provider.get_with_static_file_or_database(
|
||||||
StaticFileSegment::Transactions,
|
StaticFileSegment::Transactions,
|
||||||
id,
|
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)
|
self.provider()?.transaction_by_hash(hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_by_hash_with_meta(
|
fn transaction_by_hash_with_meta(
|
||||||
&self,
|
&self,
|
||||||
tx_hash: TxHash,
|
tx_hash: TxHash,
|
||||||
) -> ProviderResult<Option<(TransactionSigned, TransactionMeta)>> {
|
) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>> {
|
||||||
self.provider()?.transaction_by_hash_with_meta(tx_hash)
|
self.provider()?.transaction_by_hash_with_meta(tx_hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -463,21 +465,21 @@ impl<N: ProviderNodeTypes> TransactionsProvider for ProviderFactory<N> {
|
|||||||
fn transactions_by_block(
|
fn transactions_by_block(
|
||||||
&self,
|
&self,
|
||||||
id: BlockHashOrNumber,
|
id: BlockHashOrNumber,
|
||||||
) -> ProviderResult<Option<Vec<TransactionSigned>>> {
|
) -> ProviderResult<Option<Vec<Self::Transaction>>> {
|
||||||
self.provider()?.transactions_by_block(id)
|
self.provider()?.transactions_by_block(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transactions_by_block_range(
|
fn transactions_by_block_range(
|
||||||
&self,
|
&self,
|
||||||
range: impl RangeBounds<BlockNumber>,
|
range: impl RangeBounds<BlockNumber>,
|
||||||
) -> ProviderResult<Vec<Vec<TransactionSigned>>> {
|
) -> ProviderResult<Vec<Vec<Self::Transaction>>> {
|
||||||
self.provider()?.transactions_by_block_range(range)
|
self.provider()?.transactions_by_block_range(range)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transactions_by_tx_range(
|
fn transactions_by_tx_range(
|
||||||
&self,
|
&self,
|
||||||
range: impl RangeBounds<TxNumber>,
|
range: impl RangeBounds<TxNumber>,
|
||||||
) -> ProviderResult<Vec<TransactionSignedNoHash>> {
|
) -> ProviderResult<Vec<Self::Transaction>> {
|
||||||
self.provider()?.transactions_by_tx_range(range)
|
self.provider()?.transactions_by_tx_range(range)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@ use crate::{
|
|||||||
providers::{
|
providers::{
|
||||||
database::{chain::ChainStorage, metrics},
|
database::{chain::ChainStorage, metrics},
|
||||||
static_file::StaticFileWriter,
|
static_file::StaticFileWriter,
|
||||||
ProviderNodeTypes, StaticFileProvider,
|
NodeTypesForProvider, StaticFileProvider,
|
||||||
},
|
},
|
||||||
to_range,
|
to_range,
|
||||||
traits::{
|
traits::{
|
||||||
@ -46,7 +46,7 @@ use reth_db_api::{
|
|||||||
use reth_evm::ConfigureEvmEnv;
|
use reth_evm::ConfigureEvmEnv;
|
||||||
use reth_execution_types::{Chain, ExecutionOutcome};
|
use reth_execution_types::{Chain, ExecutionOutcome};
|
||||||
use reth_network_p2p::headers::downloader::SyncTarget;
|
use reth_network_p2p::headers::downloader::SyncTarget;
|
||||||
use reth_node_types::NodeTypes;
|
use reth_node_types::{NodeTypes, TxTy};
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
Account, Block, BlockBody, BlockWithSenders, Bytecode, GotExpected, NodePrimitives, Receipt,
|
Account, Block, BlockBody, BlockWithSenders, Bytecode, GotExpected, NodePrimitives, Receipt,
|
||||||
SealedBlock, SealedBlockWithSenders, SealedHeader, StaticFileSegment, StorageEntry,
|
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.
|
/// Unwinds trie state for the given range.
|
||||||
///
|
///
|
||||||
/// This includes calculating the resulted state root and comparing it with the parent block
|
/// 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.
|
// TODO: uncomment below, once `reth debug_cmd` has been feature gated with dev.
|
||||||
// #[cfg(any(test, feature = "test-utils"))]
|
// #[cfg(any(test, feature = "test-utils"))]
|
||||||
/// Inserts an historical block. **Used for setting up test environments**
|
/// 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 {
|
pub fn chain_spec(&self) -> &N::ChainSpec {
|
||||||
&self.chain_spec
|
&self.chain_spec
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<TX: DbTx + 'static, N: NodeTypesForProvider> DatabaseProvider<TX, N> {
|
||||||
fn transactions_by_tx_range_with_cursor<C>(
|
fn transactions_by_tx_range_with_cursor<C>(
|
||||||
&self,
|
&self,
|
||||||
range: impl RangeBounds<TxNumber>,
|
range: impl RangeBounds<TxNumber>,
|
||||||
cursor: &mut C,
|
cursor: &mut C,
|
||||||
) -> ProviderResult<Vec<TransactionSignedNoHash>>
|
) -> ProviderResult<Vec<TxTy<N>>>
|
||||||
where
|
where
|
||||||
C: DbCursorRO<tables::Transactions>,
|
C: DbCursorRO<tables::Transactions<TxTy<N>>>,
|
||||||
{
|
{
|
||||||
self.static_file_provider.get_range_with_static_file_or_database(
|
self.static_file_provider.get_range_with_static_file_or_database(
|
||||||
StaticFileSegment::Transactions,
|
StaticFileSegment::Transactions,
|
||||||
@ -507,7 +509,7 @@ impl<TX: DbTx + 'static, N: NodeTypes> DatabaseProvider<TX, N> {
|
|||||||
fn block_with_senders<H, HF, B, BF>(
|
fn block_with_senders<H, HF, B, BF>(
|
||||||
&self,
|
&self,
|
||||||
id: BlockHashOrNumber,
|
id: BlockHashOrNumber,
|
||||||
transaction_kind: TransactionVariant,
|
_transaction_kind: TransactionVariant,
|
||||||
header_by_number: HF,
|
header_by_number: HF,
|
||||||
construct_block: BF,
|
construct_block: BF,
|
||||||
) -> ProviderResult<Option<B>>
|
) -> 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)?)
|
(self.transactions_by_tx_range(tx_range.clone())?, self.senders_by_tx_range(tx_range)?)
|
||||||
};
|
};
|
||||||
|
|
||||||
let body = transactions
|
let body = transactions.into_iter().map(Into::into).collect();
|
||||||
.into_iter()
|
|
||||||
.map(|tx| match transaction_kind {
|
|
||||||
TransactionVariant::NoHash => {
|
|
||||||
TransactionSigned::new_unhashed(tx.transaction, tx.signature)
|
|
||||||
}
|
|
||||||
TransactionVariant::WithHash => tx.with_hash(),
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
construct_block(header, body, senders, ommers, withdrawals)
|
construct_block(header, body, senders, ommers, withdrawals)
|
||||||
}
|
}
|
||||||
@ -663,7 +657,7 @@ impl<TX: DbTx + 'static, N: NodeTypes> DatabaseProvider<TX, N> {
|
|||||||
Vec<Address>,
|
Vec<Address>,
|
||||||
) -> ProviderResult<B>,
|
) -> 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>()?;
|
let mut senders_cursor = self.tx.cursor_read::<tables::TransactionSenders>()?;
|
||||||
|
|
||||||
self.block_range(range, headers_range, |header, tx_range, ommers, withdrawals| {
|
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
|
impl<TX: DbTx + 'static, N: NodeTypesForProvider> BlockReader for DatabaseProvider<TX, N> {
|
||||||
for DatabaseProvider<TX, N>
|
|
||||||
{
|
|
||||||
fn find_block_by_hash(&self, hash: B256, source: BlockSource) -> ProviderResult<Option<Block>> {
|
fn find_block_by_hash(&self, hash: B256, source: BlockSource) -> ProviderResult<Option<Block>> {
|
||||||
if source.is_canonical() {
|
if source.is_canonical() {
|
||||||
self.block(hash.into())
|
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
|
// If they exist but are not indexed, we don't have enough
|
||||||
// information to return the block anyways, so we return `None`.
|
// information to return the block anyways, so we return `None`.
|
||||||
let transactions = match self.transactions_by_block(number.into())? {
|
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),
|
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>> {
|
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(
|
self.block_range(
|
||||||
range,
|
range,
|
||||||
|range| self.headers_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>
|
for DatabaseProvider<TX, N>
|
||||||
{
|
{
|
||||||
/// Recovers transaction hashes by walking through `Transactions` table and
|
/// 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
|
// Calculates the hash of the given transaction
|
||||||
impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> TransactionsProvider
|
impl<TX: DbTx + 'static, N: NodeTypesForProvider> TransactionsProvider for DatabaseProvider<TX, N> {
|
||||||
for DatabaseProvider<TX, N>
|
type Transaction = TxTy<N>;
|
||||||
{
|
|
||||||
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
|
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
|
||||||
Ok(self.tx.get::<tables::TransactionHashNumbers>(tx_hash)?)
|
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(
|
self.static_file_provider.get_with_static_file_or_database(
|
||||||
StaticFileSegment::Transactions,
|
StaticFileSegment::Transactions,
|
||||||
id,
|
id,
|
||||||
|static_file| static_file.transaction_by_id(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(
|
fn transaction_by_id_unhashed(
|
||||||
&self,
|
&self,
|
||||||
id: TxNumber,
|
id: TxNumber,
|
||||||
) -> ProviderResult<Option<TransactionSignedNoHash>> {
|
) -> ProviderResult<Option<Self::Transaction>> {
|
||||||
self.static_file_provider.get_with_static_file_or_database(
|
self.static_file_provider.get_with_static_file_or_database(
|
||||||
StaticFileSegment::Transactions,
|
StaticFileSegment::Transactions,
|
||||||
id,
|
id,
|
||||||
|static_file| static_file.transaction_by_id_unhashed(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)? {
|
if let Some(id) = self.transaction_id(hash)? {
|
||||||
Ok(self
|
Ok(self.transaction_by_id_unhashed(id)?)
|
||||||
.transaction_by_id_unhashed(id)?
|
|
||||||
.map(|tx| TransactionSigned::new(tx.transaction, tx.signature, hash)))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
.map(|tx| tx.map(Into::into))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_by_hash_with_meta(
|
fn transaction_by_hash_with_meta(
|
||||||
&self,
|
&self,
|
||||||
tx_hash: TxHash,
|
tx_hash: TxHash,
|
||||||
) -> ProviderResult<Option<(TransactionSigned, TransactionMeta)>> {
|
) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>> {
|
||||||
let mut transaction_cursor = self.tx.cursor_read::<tables::TransactionBlocks>()?;
|
let mut transaction_cursor = self.tx.cursor_read::<tables::TransactionBlocks>()?;
|
||||||
if let Some(transaction_id) = self.transaction_id(tx_hash)? {
|
if let Some(transaction_id) = self.transaction_id(tx_hash)? {
|
||||||
if let Some(tx) = self.transaction_by_id_unhashed(transaction_id)? {
|
if let Some(transaction) = self.transaction_by_id_unhashed(transaction_id)? {
|
||||||
let transaction = TransactionSigned::new(tx.transaction, tx.signature, tx_hash);
|
|
||||||
if let Some(block_number) =
|
if let Some(block_number) =
|
||||||
transaction_cursor.seek(transaction_id).map(|b| b.map(|(_, bn)| bn))?
|
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(
|
fn transactions_by_block(
|
||||||
&self,
|
&self,
|
||||||
id: BlockHashOrNumber,
|
id: BlockHashOrNumber,
|
||||||
) -> ProviderResult<Option<Vec<TransactionSigned>>> {
|
) -> ProviderResult<Option<Vec<Self::Transaction>>> {
|
||||||
let mut tx_cursor = self.tx.cursor_read::<tables::Transactions>()?;
|
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(block_number) = self.convert_hash_or_number(id)? {
|
||||||
if let Some(body) = self.block_body_indices(block_number)? {
|
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() {
|
return if tx_range.is_empty() {
|
||||||
Ok(Some(Vec::new()))
|
Ok(Some(Vec::new()))
|
||||||
} else {
|
} else {
|
||||||
Ok(Some(
|
Ok(Some(self.transactions_by_tx_range_with_cursor(tx_range, &mut tx_cursor)?))
|
||||||
self.transactions_by_tx_range_with_cursor(tx_range, &mut tx_cursor)?
|
|
||||||
.into_iter()
|
|
||||||
.map(Into::into)
|
|
||||||
.collect(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1577,8 +1560,8 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> Transaction
|
|||||||
fn transactions_by_block_range(
|
fn transactions_by_block_range(
|
||||||
&self,
|
&self,
|
||||||
range: impl RangeBounds<BlockNumber>,
|
range: impl RangeBounds<BlockNumber>,
|
||||||
) -> ProviderResult<Vec<Vec<TransactionSigned>>> {
|
) -> ProviderResult<Vec<Vec<Self::Transaction>>> {
|
||||||
let mut tx_cursor = self.tx.cursor_read::<tables::Transactions>()?;
|
let mut tx_cursor = self.tx.cursor_read::<tables::Transactions<Self::Transaction>>()?;
|
||||||
let mut results = Vec::new();
|
let mut results = Vec::new();
|
||||||
let mut body_cursor = self.tx.cursor_read::<tables::BlockBodyIndices>()?;
|
let mut body_cursor = self.tx.cursor_read::<tables::BlockBodyIndices>()?;
|
||||||
for entry in body_cursor.walk_range(range)? {
|
for entry in body_cursor.walk_range(range)? {
|
||||||
@ -1590,7 +1573,6 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> Transaction
|
|||||||
results.push(
|
results.push(
|
||||||
self.transactions_by_tx_range_with_cursor(tx_num_range, &mut tx_cursor)?
|
self.transactions_by_tx_range_with_cursor(tx_num_range, &mut tx_cursor)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Into::into)
|
|
||||||
.collect(),
|
.collect(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1601,10 +1583,10 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> Transaction
|
|||||||
fn transactions_by_tx_range(
|
fn transactions_by_tx_range(
|
||||||
&self,
|
&self,
|
||||||
range: impl RangeBounds<TxNumber>,
|
range: impl RangeBounds<TxNumber>,
|
||||||
) -> ProviderResult<Vec<TransactionSignedNoHash>> {
|
) -> ProviderResult<Vec<Self::Transaction>> {
|
||||||
self.transactions_by_tx_range_with_cursor(
|
self.transactions_by_tx_range_with_cursor(
|
||||||
range,
|
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
|
impl<TX: DbTx + 'static, N: NodeTypesForProvider> ReceiptProvider for DatabaseProvider<TX, N> {
|
||||||
for DatabaseProvider<TX, N>
|
|
||||||
{
|
|
||||||
fn receipt(&self, id: TxNumber) -> ProviderResult<Option<Receipt>> {
|
fn receipt(&self, id: TxNumber) -> ProviderResult<Option<Receipt>> {
|
||||||
self.static_file_provider.get_with_static_file_or_database(
|
self.static_file_provider.get_with_static_file_or_database(
|
||||||
StaticFileSegment::Receipts,
|
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(
|
fn write_state_reverts(
|
||||||
&self,
|
&self,
|
||||||
reverts: PlainStateReverts,
|
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>> {
|
fn get_state(&self, block: BlockNumber) -> ProviderResult<Option<ExecutionOutcome>> {
|
||||||
self.get_state(block..=block)
|
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>
|
for DatabaseProvider<TX, N>
|
||||||
{
|
{
|
||||||
fn take_block_and_execution_above(
|
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>
|
for DatabaseProvider<TX, N>
|
||||||
{
|
{
|
||||||
type Body = <<N::Primitives as NodePrimitives>::Block as reth_primitives_traits::Block>::Body;
|
type Body = <<N::Primitives as NodePrimitives>::Block as reth_primitives_traits::Block>::Body;
|
||||||
|
|||||||
@ -23,10 +23,10 @@ use reth_chainspec::{ChainInfo, EthereumHardforks};
|
|||||||
use reth_db::table::Value;
|
use reth_db::table::Value;
|
||||||
use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices};
|
use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices};
|
||||||
use reth_evm::ConfigureEvmEnv;
|
use reth_evm::ConfigureEvmEnv;
|
||||||
use reth_node_types::{FullNodePrimitives, NodeTypes, NodeTypesWithDB};
|
use reth_node_types::{FullNodePrimitives, NodeTypes, NodeTypesWithDB, TxTy};
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
Account, Block, BlockWithSenders, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader,
|
Account, Block, BlockWithSenders, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader,
|
||||||
TransactionMeta, TransactionSigned, TransactionSignedNoHash,
|
TransactionMeta, TransactionSigned,
|
||||||
};
|
};
|
||||||
use reth_prune_types::{PruneCheckpoint, PruneSegment};
|
use reth_prune_types::{PruneCheckpoint, PruneSegment};
|
||||||
use reth_stages_types::{StageCheckpoint, StageId};
|
use reth_stages_types::{StageCheckpoint, StageId};
|
||||||
@ -76,7 +76,9 @@ where
|
|||||||
Self: NodeTypes<
|
Self: NodeTypes<
|
||||||
ChainSpec: EthereumHardforks,
|
ChainSpec: EthereumHardforks,
|
||||||
Storage: ChainStorage<Self::Primitives>,
|
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<
|
T: NodeTypes<
|
||||||
ChainSpec: EthereumHardforks,
|
ChainSpec: EthereumHardforks,
|
||||||
Storage: ChainStorage<T::Primitives>,
|
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> {
|
impl<N: ProviderNodeTypes> TransactionsProvider for BlockchainProvider<N> {
|
||||||
|
type Transaction = TxTy<N>;
|
||||||
|
|
||||||
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
|
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
|
||||||
self.database.transaction_id(tx_hash)
|
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)
|
self.database.transaction_by_id(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_by_id_unhashed(
|
fn transaction_by_id_unhashed(
|
||||||
&self,
|
&self,
|
||||||
id: TxNumber,
|
id: TxNumber,
|
||||||
) -> ProviderResult<Option<TransactionSignedNoHash>> {
|
) -> ProviderResult<Option<Self::Transaction>> {
|
||||||
self.database.transaction_by_id_unhashed(id)
|
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)
|
self.database.transaction_by_hash(hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_by_hash_with_meta(
|
fn transaction_by_hash_with_meta(
|
||||||
&self,
|
&self,
|
||||||
tx_hash: TxHash,
|
tx_hash: TxHash,
|
||||||
) -> ProviderResult<Option<(TransactionSigned, TransactionMeta)>> {
|
) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>> {
|
||||||
self.database.transaction_by_hash_with_meta(tx_hash)
|
self.database.transaction_by_hash_with_meta(tx_hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,21 +456,21 @@ impl<N: ProviderNodeTypes> TransactionsProvider for BlockchainProvider<N> {
|
|||||||
fn transactions_by_block(
|
fn transactions_by_block(
|
||||||
&self,
|
&self,
|
||||||
id: BlockHashOrNumber,
|
id: BlockHashOrNumber,
|
||||||
) -> ProviderResult<Option<Vec<TransactionSigned>>> {
|
) -> ProviderResult<Option<Vec<Self::Transaction>>> {
|
||||||
self.database.transactions_by_block(id)
|
self.database.transactions_by_block(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transactions_by_block_range(
|
fn transactions_by_block_range(
|
||||||
&self,
|
&self,
|
||||||
range: impl RangeBounds<BlockNumber>,
|
range: impl RangeBounds<BlockNumber>,
|
||||||
) -> ProviderResult<Vec<Vec<TransactionSigned>>> {
|
) -> ProviderResult<Vec<Vec<Self::Transaction>>> {
|
||||||
self.database.transactions_by_block_range(range)
|
self.database.transactions_by_block_range(range)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transactions_by_tx_range(
|
fn transactions_by_tx_range(
|
||||||
&self,
|
&self,
|
||||||
range: impl RangeBounds<TxNumber>,
|
range: impl RangeBounds<TxNumber>,
|
||||||
) -> ProviderResult<Vec<TransactionSignedNoHash>> {
|
) -> ProviderResult<Vec<Self::Transaction>> {
|
||||||
self.database.transactions_by_tx_range(range)
|
self.database.transactions_by_tx_range(range)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,17 +7,19 @@ use crate::{
|
|||||||
TransactionsProvider,
|
TransactionsProvider,
|
||||||
};
|
};
|
||||||
use alloy_consensus::Header;
|
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 alloy_primitives::{Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256};
|
||||||
use reth_chainspec::ChainInfo;
|
use reth_chainspec::ChainInfo;
|
||||||
use reth_db::static_file::{
|
use reth_db::{
|
||||||
BlockHashMask, HeaderMask, HeaderWithHashMask, ReceiptMask, StaticFileCursor, TDWithHashMask,
|
static_file::{
|
||||||
TotalDifficultyMask, TransactionMask,
|
BlockHashMask, HeaderMask, HeaderWithHashMask, ReceiptMask, StaticFileCursor,
|
||||||
|
TDWithHashMask, TotalDifficultyMask, TransactionMask,
|
||||||
|
},
|
||||||
|
table::Decompress,
|
||||||
};
|
};
|
||||||
use reth_node_types::NodePrimitives;
|
use reth_node_types::NodePrimitives;
|
||||||
use reth_primitives::{
|
use reth_primitives::{transaction::recover_signers, Receipt, SealedHeader, TransactionMeta};
|
||||||
Receipt, SealedHeader, TransactionMeta, TransactionSigned, TransactionSignedNoHash,
|
use reth_primitives_traits::SignedTransaction;
|
||||||
};
|
|
||||||
use reth_storage_errors::provider::{ProviderError, ProviderResult};
|
use reth_storage_errors::provider::{ProviderError, ProviderResult};
|
||||||
use std::{
|
use std::{
|
||||||
fmt::Debug,
|
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>> {
|
fn transaction_id(&self, hash: TxHash) -> ProviderResult<Option<TxNumber>> {
|
||||||
let mut cursor = self.cursor()?;
|
let mut cursor = self.cursor()?;
|
||||||
|
|
||||||
Ok(cursor
|
Ok(cursor
|
||||||
.get_one::<TransactionMask<TransactionSignedNoHash>>((&hash).into())?
|
.get_one::<TransactionMask<Self::Transaction>>((&hash).into())?
|
||||||
.and_then(|res| (res.hash() == hash).then(|| cursor.number()).flatten()))
|
.and_then(|res| (res.trie_hash() == hash).then(|| cursor.number()).flatten()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_by_id(&self, num: TxNumber) -> ProviderResult<Option<TransactionSigned>> {
|
fn transaction_by_id(&self, num: TxNumber) -> ProviderResult<Option<Self::Transaction>> {
|
||||||
Ok(self
|
self.cursor()?.get_one::<TransactionMask<Self::Transaction>>(num.into())
|
||||||
.cursor()?
|
|
||||||
.get_one::<TransactionMask<TransactionSignedNoHash>>(num.into())?
|
|
||||||
.map(|tx| tx.with_hash()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_by_id_unhashed(
|
fn transaction_by_id_unhashed(
|
||||||
&self,
|
&self,
|
||||||
num: TxNumber,
|
num: TxNumber,
|
||||||
) -> ProviderResult<Option<TransactionSignedNoHash>> {
|
) -> ProviderResult<Option<Self::Transaction>> {
|
||||||
self.cursor()?.get_one::<TransactionMask<TransactionSignedNoHash>>(num.into())
|
self.cursor()?.get_one::<TransactionMask<Self::Transaction>>(num.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_by_hash(&self, hash: TxHash) -> ProviderResult<Option<TransactionSigned>> {
|
fn transaction_by_hash(&self, hash: TxHash) -> ProviderResult<Option<Self::Transaction>> {
|
||||||
Ok(self
|
self.cursor()?.get_one::<TransactionMask<Self::Transaction>>((&hash).into())
|
||||||
.cursor()?
|
|
||||||
.get_one::<TransactionMask<TransactionSignedNoHash>>((&hash).into())?
|
|
||||||
.map(|tx| tx.with_hash()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_by_hash_with_meta(
|
fn transaction_by_hash_with_meta(
|
||||||
&self,
|
&self,
|
||||||
_hash: TxHash,
|
_hash: TxHash,
|
||||||
) -> ProviderResult<Option<(TransactionSigned, TransactionMeta)>> {
|
) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>> {
|
||||||
// Information required on indexing table [`tables::TransactionBlocks`]
|
// Information required on indexing table [`tables::TransactionBlocks`]
|
||||||
Err(ProviderError::UnsupportedProvider)
|
Err(ProviderError::UnsupportedProvider)
|
||||||
}
|
}
|
||||||
@ -253,7 +253,7 @@ impl<N: NodePrimitives> TransactionsProvider for StaticFileJarProvider<'_, N> {
|
|||||||
fn transactions_by_block(
|
fn transactions_by_block(
|
||||||
&self,
|
&self,
|
||||||
_block_id: BlockHashOrNumber,
|
_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
|
// Related to indexing tables. Live database should get the tx_range and call static file
|
||||||
// provider with `transactions_by_tx_range` instead.
|
// provider with `transactions_by_tx_range` instead.
|
||||||
Err(ProviderError::UnsupportedProvider)
|
Err(ProviderError::UnsupportedProvider)
|
||||||
@ -262,7 +262,7 @@ impl<N: NodePrimitives> TransactionsProvider for StaticFileJarProvider<'_, N> {
|
|||||||
fn transactions_by_block_range(
|
fn transactions_by_block_range(
|
||||||
&self,
|
&self,
|
||||||
_range: impl RangeBounds<BlockNumber>,
|
_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
|
// Related to indexing tables. Live database should get the tx_range and call static file
|
||||||
// provider with `transactions_by_tx_range` instead.
|
// provider with `transactions_by_tx_range` instead.
|
||||||
Err(ProviderError::UnsupportedProvider)
|
Err(ProviderError::UnsupportedProvider)
|
||||||
@ -271,15 +271,13 @@ impl<N: NodePrimitives> TransactionsProvider for StaticFileJarProvider<'_, N> {
|
|||||||
fn transactions_by_tx_range(
|
fn transactions_by_tx_range(
|
||||||
&self,
|
&self,
|
||||||
range: impl RangeBounds<TxNumber>,
|
range: impl RangeBounds<TxNumber>,
|
||||||
) -> ProviderResult<Vec<reth_primitives::TransactionSignedNoHash>> {
|
) -> ProviderResult<Vec<Self::Transaction>> {
|
||||||
let range = to_range(range);
|
let range = to_range(range);
|
||||||
let mut cursor = self.cursor()?;
|
let mut cursor = self.cursor()?;
|
||||||
let mut txes = Vec::with_capacity((range.end - range.start) as usize);
|
let mut txes = Vec::with_capacity((range.end - range.start) as usize);
|
||||||
|
|
||||||
for num in range {
|
for num in range {
|
||||||
if let Some(tx) =
|
if let Some(tx) = cursor.get_one::<TransactionMask<Self::Transaction>>(num.into())? {
|
||||||
cursor.get_one::<TransactionMask<TransactionSignedNoHash>>(num.into())?
|
|
||||||
{
|
|
||||||
txes.push(tx)
|
txes.push(tx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -291,19 +289,20 @@ impl<N: NodePrimitives> TransactionsProvider for StaticFileJarProvider<'_, N> {
|
|||||||
range: impl RangeBounds<TxNumber>,
|
range: impl RangeBounds<TxNumber>,
|
||||||
) -> ProviderResult<Vec<Address>> {
|
) -> ProviderResult<Vec<Address>> {
|
||||||
let txs = self.transactions_by_tx_range(range)?;
|
let txs = self.transactions_by_tx_range(range)?;
|
||||||
TransactionSignedNoHash::recover_signers(&txs, txs.len())
|
recover_signers(&txs, txs.len()).ok_or(ProviderError::SenderRecoveryError)
|
||||||
.ok_or(ProviderError::SenderRecoveryError)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_sender(&self, num: TxNumber) -> ProviderResult<Option<Address>> {
|
fn transaction_sender(&self, num: TxNumber) -> ProviderResult<Option<Address>> {
|
||||||
Ok(self
|
Ok(self
|
||||||
.cursor()?
|
.cursor()?
|
||||||
.get_one::<TransactionMask<TransactionSignedNoHash>>(num.into())?
|
.get_one::<TransactionMask<Self::Transaction>>(num.into())?
|
||||||
.and_then(|tx| tx.recover_signer()))
|
.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>> {
|
fn receipt(&self, num: TxNumber) -> ProviderResult<Option<Receipt>> {
|
||||||
self.cursor()?.get_one::<ReceiptMask<Receipt>>(num.into())
|
self.cursor()?.get_one::<ReceiptMask<Receipt>>(num.into())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use alloy_consensus::Header;
|
use alloy_consensus::Header;
|
||||||
use alloy_eips::{
|
use alloy_eips::{
|
||||||
|
eip2718::Encodable2718,
|
||||||
eip4895::{Withdrawal, Withdrawals},
|
eip4895::{Withdrawal, Withdrawals},
|
||||||
BlockHashOrNumber,
|
BlockHashOrNumber,
|
||||||
};
|
};
|
||||||
@ -23,6 +24,7 @@ use reth_db::{
|
|||||||
iter_static_files, BlockHashMask, HeaderMask, HeaderWithHashMask, ReceiptMask,
|
iter_static_files, BlockHashMask, HeaderMask, HeaderWithHashMask, ReceiptMask,
|
||||||
StaticFileCursor, TDWithHashMask, TransactionMask,
|
StaticFileCursor, TDWithHashMask, TransactionMask,
|
||||||
},
|
},
|
||||||
|
table::{Decompress, Value},
|
||||||
tables,
|
tables,
|
||||||
};
|
};
|
||||||
use reth_db_api::{
|
use reth_db_api::{
|
||||||
@ -35,9 +37,11 @@ use reth_primitives::{
|
|||||||
find_fixed_range, HighestStaticFiles, SegmentHeader, SegmentRangeInclusive,
|
find_fixed_range, HighestStaticFiles, SegmentHeader, SegmentRangeInclusive,
|
||||||
DEFAULT_BLOCKS_PER_STATIC_FILE,
|
DEFAULT_BLOCKS_PER_STATIC_FILE,
|
||||||
},
|
},
|
||||||
|
transaction::recover_signers,
|
||||||
Block, BlockWithSenders, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader,
|
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_stages_types::{PipelineTarget, StageId};
|
||||||
use reth_storage_api::DBProvider;
|
use reth_storage_api::DBProvider;
|
||||||
use reth_storage_errors::provider::{ProviderError, ProviderResult};
|
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>> {
|
fn receipt(&self, num: TxNumber) -> ProviderResult<Option<Receipt>> {
|
||||||
self.get_segment_provider_from_transaction(StaticFileSegment::Receipts, num, None)
|
self.get_segment_provider_from_transaction(StaticFileSegment::Receipts, num, None)
|
||||||
.and_then(|provider| provider.receipt(num))
|
.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(
|
fn transaction_hashes_by_range(
|
||||||
&self,
|
&self,
|
||||||
tx_range: Range<TxNumber>,
|
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>> {
|
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
|
||||||
self.find_static_file(StaticFileSegment::Transactions, |jar_provider| {
|
self.find_static_file(StaticFileSegment::Transactions, |jar_provider| {
|
||||||
let mut cursor = jar_provider.cursor()?;
|
let mut cursor = jar_provider.cursor()?;
|
||||||
if cursor
|
if cursor
|
||||||
.get_one::<TransactionMask<TransactionSignedNoHash>>((&tx_hash).into())?
|
.get_one::<TransactionMask<Self::Transaction>>((&tx_hash).into())?
|
||||||
.and_then(|tx| (tx.hash() == tx_hash).then_some(tx))
|
.and_then(|tx| (tx.trie_hash() == tx_hash).then_some(tx))
|
||||||
.is_some()
|
.is_some()
|
||||||
{
|
{
|
||||||
Ok(cursor.number())
|
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)
|
self.get_segment_provider_from_transaction(StaticFileSegment::Transactions, num, None)
|
||||||
.and_then(|provider| provider.transaction_by_id(num))
|
.and_then(|provider| provider.transaction_by_id(num))
|
||||||
.or_else(|err| {
|
.or_else(|err| {
|
||||||
@ -1466,7 +1478,7 @@ impl<N: NodePrimitives> TransactionsProvider for StaticFileProvider<N> {
|
|||||||
fn transaction_by_id_unhashed(
|
fn transaction_by_id_unhashed(
|
||||||
&self,
|
&self,
|
||||||
num: TxNumber,
|
num: TxNumber,
|
||||||
) -> ProviderResult<Option<TransactionSignedNoHash>> {
|
) -> ProviderResult<Option<Self::Transaction>> {
|
||||||
self.get_segment_provider_from_transaction(StaticFileSegment::Transactions, num, None)
|
self.get_segment_provider_from_transaction(StaticFileSegment::Transactions, num, None)
|
||||||
.and_then(|provider| provider.transaction_by_id_unhashed(num))
|
.and_then(|provider| provider.transaction_by_id_unhashed(num))
|
||||||
.or_else(|err| {
|
.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| {
|
self.find_static_file(StaticFileSegment::Transactions, |jar_provider| {
|
||||||
Ok(jar_provider
|
Ok(jar_provider
|
||||||
.cursor()?
|
.cursor()?
|
||||||
.get_one::<TransactionMask<TransactionSignedNoHash>>((&hash).into())?
|
.get_one::<TransactionMask<Self::Transaction>>((&hash).into())?
|
||||||
.map(|tx| tx.with_hash())
|
.and_then(|tx| (tx.trie_hash() == hash).then_some(tx)))
|
||||||
.and_then(|tx| (tx.hash_ref() == &hash).then_some(tx)))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_by_hash_with_meta(
|
fn transaction_by_hash_with_meta(
|
||||||
&self,
|
&self,
|
||||||
_hash: TxHash,
|
_hash: TxHash,
|
||||||
) -> ProviderResult<Option<(TransactionSigned, TransactionMeta)>> {
|
) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>> {
|
||||||
// Required data not present in static_files
|
// Required data not present in static_files
|
||||||
Err(ProviderError::UnsupportedProvider)
|
Err(ProviderError::UnsupportedProvider)
|
||||||
}
|
}
|
||||||
@ -1504,7 +1515,7 @@ impl<N: NodePrimitives> TransactionsProvider for StaticFileProvider<N> {
|
|||||||
fn transactions_by_block(
|
fn transactions_by_block(
|
||||||
&self,
|
&self,
|
||||||
_block_id: BlockHashOrNumber,
|
_block_id: BlockHashOrNumber,
|
||||||
) -> ProviderResult<Option<Vec<TransactionSigned>>> {
|
) -> ProviderResult<Option<Vec<Self::Transaction>>> {
|
||||||
// Required data not present in static_files
|
// Required data not present in static_files
|
||||||
Err(ProviderError::UnsupportedProvider)
|
Err(ProviderError::UnsupportedProvider)
|
||||||
}
|
}
|
||||||
@ -1512,7 +1523,7 @@ impl<N: NodePrimitives> TransactionsProvider for StaticFileProvider<N> {
|
|||||||
fn transactions_by_block_range(
|
fn transactions_by_block_range(
|
||||||
&self,
|
&self,
|
||||||
_range: impl RangeBounds<BlockNumber>,
|
_range: impl RangeBounds<BlockNumber>,
|
||||||
) -> ProviderResult<Vec<Vec<TransactionSigned>>> {
|
) -> ProviderResult<Vec<Vec<Self::Transaction>>> {
|
||||||
// Required data not present in static_files
|
// Required data not present in static_files
|
||||||
Err(ProviderError::UnsupportedProvider)
|
Err(ProviderError::UnsupportedProvider)
|
||||||
}
|
}
|
||||||
@ -1520,13 +1531,11 @@ impl<N: NodePrimitives> TransactionsProvider for StaticFileProvider<N> {
|
|||||||
fn transactions_by_tx_range(
|
fn transactions_by_tx_range(
|
||||||
&self,
|
&self,
|
||||||
range: impl RangeBounds<TxNumber>,
|
range: impl RangeBounds<TxNumber>,
|
||||||
) -> ProviderResult<Vec<TransactionSignedNoHash>> {
|
) -> ProviderResult<Vec<Self::Transaction>> {
|
||||||
self.fetch_range_with_predicate(
|
self.fetch_range_with_predicate(
|
||||||
StaticFileSegment::Transactions,
|
StaticFileSegment::Transactions,
|
||||||
to_range(range),
|
to_range(range),
|
||||||
|cursor, number| {
|
|cursor, number| cursor.get_one::<TransactionMask<Self::Transaction>>(number.into()),
|
||||||
cursor.get_one::<TransactionMask<TransactionSignedNoHash>>(number.into())
|
|
||||||
},
|
|
||||||
|_| true,
|
|_| true,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -1536,8 +1545,7 @@ impl<N: NodePrimitives> TransactionsProvider for StaticFileProvider<N> {
|
|||||||
range: impl RangeBounds<TxNumber>,
|
range: impl RangeBounds<TxNumber>,
|
||||||
) -> ProviderResult<Vec<Address>> {
|
) -> ProviderResult<Vec<Address>> {
|
||||||
let txes = self.transactions_by_tx_range(range)?;
|
let txes = self.transactions_by_tx_range(range)?;
|
||||||
TransactionSignedNoHash::recover_signers(&txes, txes.len())
|
recover_signers(&txes, txes.len()).ok_or(ProviderError::SenderRecoveryError)
|
||||||
.ok_or(ProviderError::SenderRecoveryError)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_sender(&self, id: TxNumber) -> ProviderResult<Option<Address>> {
|
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(
|
fn find_block_by_hash(
|
||||||
&self,
|
&self,
|
||||||
_hash: B256,
|
_hash: B256,
|
||||||
|
|||||||
@ -415,7 +415,7 @@ mod tests {
|
|||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn prune_and_validate(
|
fn prune_and_validate(
|
||||||
sf_rw: &StaticFileProvider<()>,
|
sf_rw: &StaticFileProvider<EthPrimitives>,
|
||||||
static_dir: impl AsRef<Path>,
|
static_dir: impl AsRef<Path>,
|
||||||
segment: StaticFileSegment,
|
segment: StaticFileSegment,
|
||||||
prune_count: u64,
|
prune_count: u64,
|
||||||
|
|||||||
@ -25,7 +25,6 @@ use reth_node_types::NodeTypes;
|
|||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
Account, Block, BlockWithSenders, Bytecode, EthPrimitives, GotExpected, Receipt, SealedBlock,
|
Account, Block, BlockWithSenders, Bytecode, EthPrimitives, GotExpected, Receipt, SealedBlock,
|
||||||
SealedBlockWithSenders, SealedHeader, TransactionMeta, TransactionSigned,
|
SealedBlockWithSenders, SealedHeader, TransactionMeta, TransactionSigned,
|
||||||
TransactionSignedNoHash,
|
|
||||||
};
|
};
|
||||||
use reth_stages_types::{StageCheckpoint, StageId};
|
use reth_stages_types::{StageCheckpoint, StageId};
|
||||||
use reth_storage_api::{
|
use reth_storage_api::{
|
||||||
@ -244,6 +243,8 @@ impl ChainSpecProvider for MockEthProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TransactionsProvider for MockEthProvider {
|
impl TransactionsProvider for MockEthProvider {
|
||||||
|
type Transaction = TransactionSigned;
|
||||||
|
|
||||||
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
|
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
|
||||||
let lock = self.blocks.lock();
|
let lock = self.blocks.lock();
|
||||||
let tx_number = lock
|
let tx_number = lock
|
||||||
@ -255,7 +256,7 @@ impl TransactionsProvider for MockEthProvider {
|
|||||||
Ok(tx_number)
|
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 lock = self.blocks.lock();
|
||||||
let transaction =
|
let transaction =
|
||||||
lock.values().flat_map(|block| &block.body.transactions).nth(id as usize).cloned();
|
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(
|
fn transaction_by_id_unhashed(
|
||||||
&self,
|
&self,
|
||||||
id: TxNumber,
|
id: TxNumber,
|
||||||
) -> ProviderResult<Option<TransactionSignedNoHash>> {
|
) -> ProviderResult<Option<Self::Transaction>> {
|
||||||
let lock = self.blocks.lock();
|
let lock = self.blocks.lock();
|
||||||
let transaction = lock
|
let transaction =
|
||||||
.values()
|
lock.values().flat_map(|block| &block.body.transactions).nth(id as usize).cloned();
|
||||||
.flat_map(|block| &block.body.transactions)
|
|
||||||
.nth(id as usize)
|
|
||||||
.map(|tx| Into::<TransactionSignedNoHash>::into(tx.clone()));
|
|
||||||
|
|
||||||
Ok(transaction)
|
Ok(transaction)
|
||||||
}
|
}
|
||||||
@ -286,7 +284,7 @@ impl TransactionsProvider for MockEthProvider {
|
|||||||
fn transaction_by_hash_with_meta(
|
fn transaction_by_hash_with_meta(
|
||||||
&self,
|
&self,
|
||||||
hash: TxHash,
|
hash: TxHash,
|
||||||
) -> ProviderResult<Option<(TransactionSigned, TransactionMeta)>> {
|
) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>> {
|
||||||
let lock = self.blocks.lock();
|
let lock = self.blocks.lock();
|
||||||
for (block_hash, block) in lock.iter() {
|
for (block_hash, block) in lock.iter() {
|
||||||
for (index, tx) in block.body.transactions.iter().enumerate() {
|
for (index, tx) in block.body.transactions.iter().enumerate() {
|
||||||
@ -322,14 +320,14 @@ impl TransactionsProvider for MockEthProvider {
|
|||||||
fn transactions_by_block(
|
fn transactions_by_block(
|
||||||
&self,
|
&self,
|
||||||
id: BlockHashOrNumber,
|
id: BlockHashOrNumber,
|
||||||
) -> ProviderResult<Option<Vec<TransactionSigned>>> {
|
) -> ProviderResult<Option<Vec<Self::Transaction>>> {
|
||||||
Ok(self.block(id)?.map(|b| b.body.transactions))
|
Ok(self.block(id)?.map(|b| b.body.transactions))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transactions_by_block_range(
|
fn transactions_by_block_range(
|
||||||
&self,
|
&self,
|
||||||
range: impl RangeBounds<alloy_primitives::BlockNumber>,
|
range: impl RangeBounds<alloy_primitives::BlockNumber>,
|
||||||
) -> ProviderResult<Vec<Vec<TransactionSigned>>> {
|
) -> ProviderResult<Vec<Vec<Self::Transaction>>> {
|
||||||
// init btreemap so we can return in order
|
// init btreemap so we can return in order
|
||||||
let mut map = BTreeMap::new();
|
let mut map = BTreeMap::new();
|
||||||
for (_, block) in self.blocks.lock().iter() {
|
for (_, block) in self.blocks.lock().iter() {
|
||||||
@ -344,14 +342,14 @@ impl TransactionsProvider for MockEthProvider {
|
|||||||
fn transactions_by_tx_range(
|
fn transactions_by_tx_range(
|
||||||
&self,
|
&self,
|
||||||
range: impl RangeBounds<TxNumber>,
|
range: impl RangeBounds<TxNumber>,
|
||||||
) -> ProviderResult<Vec<reth_primitives::TransactionSignedNoHash>> {
|
) -> ProviderResult<Vec<Self::Transaction>> {
|
||||||
let lock = self.blocks.lock();
|
let lock = self.blocks.lock();
|
||||||
let transactions = lock
|
let transactions = lock
|
||||||
.values()
|
.values()
|
||||||
.flat_map(|block| &block.body.transactions)
|
.flat_map(|block| &block.body.transactions)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|&(tx_number, _)| range.contains(&(tx_number as TxNumber)))
|
.filter(|&(tx_number, _)| range.contains(&(tx_number as TxNumber)))
|
||||||
.map(|(_, tx)| tx.clone().into())
|
.map(|(_, tx)| tx.clone())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Ok(transactions)
|
Ok(transactions)
|
||||||
|
|||||||
@ -23,7 +23,7 @@ use reth_errors::ProviderError;
|
|||||||
use reth_evm::ConfigureEvmEnv;
|
use reth_evm::ConfigureEvmEnv;
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
Account, Block, BlockWithSenders, Bytecode, Receipt, SealedBlock, SealedBlockWithSenders,
|
Account, Block, BlockWithSenders, Bytecode, Receipt, SealedBlock, SealedBlockWithSenders,
|
||||||
SealedHeader, TransactionMeta, TransactionSigned, TransactionSignedNoHash,
|
SealedHeader, TransactionMeta, TransactionSigned,
|
||||||
};
|
};
|
||||||
use reth_prune_types::{PruneCheckpoint, PruneSegment};
|
use reth_prune_types::{PruneCheckpoint, PruneSegment};
|
||||||
use reth_stages_types::{StageCheckpoint, StageId};
|
use reth_stages_types::{StageCheckpoint, StageId};
|
||||||
@ -192,29 +192,31 @@ impl BlockIdReader for NoopProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TransactionsProvider for NoopProvider {
|
impl TransactionsProvider for NoopProvider {
|
||||||
|
type Transaction = TransactionSigned;
|
||||||
|
|
||||||
fn transaction_id(&self, _tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
|
fn transaction_id(&self, _tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
|
||||||
Ok(None)
|
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)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_by_id_unhashed(
|
fn transaction_by_id_unhashed(
|
||||||
&self,
|
&self,
|
||||||
_id: TxNumber,
|
_id: TxNumber,
|
||||||
) -> ProviderResult<Option<TransactionSignedNoHash>> {
|
) -> ProviderResult<Option<Self::Transaction>> {
|
||||||
Ok(None)
|
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)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_by_hash_with_meta(
|
fn transaction_by_hash_with_meta(
|
||||||
&self,
|
&self,
|
||||||
_hash: TxHash,
|
_hash: TxHash,
|
||||||
) -> ProviderResult<Option<(TransactionSigned, TransactionMeta)>> {
|
) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>> {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,21 +227,21 @@ impl TransactionsProvider for NoopProvider {
|
|||||||
fn transactions_by_block(
|
fn transactions_by_block(
|
||||||
&self,
|
&self,
|
||||||
_block_id: BlockHashOrNumber,
|
_block_id: BlockHashOrNumber,
|
||||||
) -> ProviderResult<Option<Vec<TransactionSigned>>> {
|
) -> ProviderResult<Option<Vec<Self::Transaction>>> {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transactions_by_block_range(
|
fn transactions_by_block_range(
|
||||||
&self,
|
&self,
|
||||||
_range: impl RangeBounds<BlockNumber>,
|
_range: impl RangeBounds<BlockNumber>,
|
||||||
) -> ProviderResult<Vec<Vec<TransactionSigned>>> {
|
) -> ProviderResult<Vec<Vec<Self::Transaction>>> {
|
||||||
Ok(Vec::default())
|
Ok(Vec::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transactions_by_tx_range(
|
fn transactions_by_tx_range(
|
||||||
&self,
|
&self,
|
||||||
_range: impl RangeBounds<TxNumber>,
|
_range: impl RangeBounds<TxNumber>,
|
||||||
) -> ProviderResult<Vec<reth_primitives::TransactionSignedNoHash>> {
|
) -> ProviderResult<Vec<Self::Transaction>> {
|
||||||
Ok(Vec::default())
|
Ok(Vec::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,13 +7,13 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use reth_chain_state::{CanonStateSubscriptions, ForkChoiceSubscriptions};
|
use reth_chain_state::{CanonStateSubscriptions, ForkChoiceSubscriptions};
|
||||||
use reth_chainspec::EthereumHardforks;
|
use reth_chainspec::EthereumHardforks;
|
||||||
use reth_node_types::NodeTypesWithDB;
|
use reth_node_types::{NodeTypesWithDB, TxTy};
|
||||||
|
|
||||||
/// Helper trait to unify all provider traits for simplicity.
|
/// Helper trait to unify all provider traits for simplicity.
|
||||||
pub trait FullProvider<N: NodeTypesWithDB>:
|
pub trait FullProvider<N: NodeTypesWithDB>:
|
||||||
DatabaseProviderFactory<DB = N::DB>
|
DatabaseProviderFactory<DB = N::DB>
|
||||||
+ StaticFileProviderFactory
|
+ StaticFileProviderFactory<Primitives = N::Primitives>
|
||||||
+ BlockReaderIdExt
|
+ BlockReaderIdExt<Transaction = TxTy<N>>
|
||||||
+ AccountReader
|
+ AccountReader
|
||||||
+ StateProviderFactory
|
+ StateProviderFactory
|
||||||
+ EvmEnvProvider
|
+ EvmEnvProvider
|
||||||
@ -30,8 +30,8 @@ pub trait FullProvider<N: NodeTypesWithDB>:
|
|||||||
|
|
||||||
impl<T, N: NodeTypesWithDB> FullProvider<N> for T where
|
impl<T, N: NodeTypesWithDB> FullProvider<N> for T where
|
||||||
T: DatabaseProviderFactory<DB = N::DB>
|
T: DatabaseProviderFactory<DB = N::DB>
|
||||||
+ StaticFileProviderFactory
|
+ StaticFileProviderFactory<Primitives = N::Primitives>
|
||||||
+ BlockReaderIdExt
|
+ BlockReaderIdExt<Transaction = TxTy<N>>
|
||||||
+ AccountReader
|
+ AccountReader
|
||||||
+ StateProviderFactory
|
+ StateProviderFactory
|
||||||
+ EvmEnvProvider
|
+ EvmEnvProvider
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
use crate::{BlockNumReader, BlockReader};
|
use crate::{BlockNumReader, BlockReader};
|
||||||
use alloy_eips::BlockHashOrNumber;
|
use alloy_eips::BlockHashOrNumber;
|
||||||
use alloy_primitives::{Address, BlockNumber, TxHash, TxNumber};
|
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 reth_storage_errors::provider::{ProviderError, ProviderResult};
|
||||||
use std::ops::{Range, RangeBounds, RangeInclusive};
|
use std::ops::{Range, RangeBounds, RangeInclusive};
|
||||||
|
|
||||||
@ -18,9 +19,12 @@ pub enum TransactionVariant {
|
|||||||
WithHash,
|
WithHash,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Client trait for fetching [TransactionSigned] related data.
|
/// Client trait for fetching transactions related data.
|
||||||
#[auto_impl::auto_impl(&, Arc)]
|
#[auto_impl::auto_impl(&, Arc)]
|
||||||
pub trait TransactionsProvider: BlockNumReader + Send + Sync {
|
pub trait TransactionsProvider: BlockNumReader + Send + Sync {
|
||||||
|
/// The transaction type this provider reads.
|
||||||
|
type Transaction: Send + Sync + SignedTransaction;
|
||||||
|
|
||||||
/// Get internal transaction identifier by transaction hash.
|
/// Get internal transaction identifier by transaction hash.
|
||||||
///
|
///
|
||||||
/// This is the inverse of [TransactionsProvider::transaction_by_id].
|
/// 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>>;
|
fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult<Option<TxNumber>>;
|
||||||
|
|
||||||
/// Get transaction by id, computes hash every time so more expensive.
|
/// 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.
|
/// Get transaction by id without computing the hash.
|
||||||
fn transaction_by_id_unhashed(
|
fn transaction_by_id_unhashed(&self, id: TxNumber)
|
||||||
&self,
|
-> ProviderResult<Option<Self::Transaction>>;
|
||||||
id: TxNumber,
|
|
||||||
) -> ProviderResult<Option<TransactionSignedNoHash>>;
|
|
||||||
|
|
||||||
/// Get transaction by transaction hash.
|
/// 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
|
/// Get transaction by transaction hash and additional metadata of the block the transaction was
|
||||||
/// mined in
|
/// mined in
|
||||||
fn transaction_by_hash_with_meta(
|
fn transaction_by_hash_with_meta(
|
||||||
&self,
|
&self,
|
||||||
hash: TxHash,
|
hash: TxHash,
|
||||||
) -> ProviderResult<Option<(TransactionSigned, TransactionMeta)>>;
|
) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>>;
|
||||||
|
|
||||||
/// Get transaction block number
|
/// Get transaction block number
|
||||||
fn transaction_block(&self, id: TxNumber) -> ProviderResult<Option<BlockNumber>>;
|
fn transaction_block(&self, id: TxNumber) -> ProviderResult<Option<BlockNumber>>;
|
||||||
@ -53,19 +55,19 @@ pub trait TransactionsProvider: BlockNumReader + Send + Sync {
|
|||||||
fn transactions_by_block(
|
fn transactions_by_block(
|
||||||
&self,
|
&self,
|
||||||
block: BlockHashOrNumber,
|
block: BlockHashOrNumber,
|
||||||
) -> ProviderResult<Option<Vec<TransactionSigned>>>;
|
) -> ProviderResult<Option<Vec<Self::Transaction>>>;
|
||||||
|
|
||||||
/// Get transactions by block range.
|
/// Get transactions by block range.
|
||||||
fn transactions_by_block_range(
|
fn transactions_by_block_range(
|
||||||
&self,
|
&self,
|
||||||
range: impl RangeBounds<BlockNumber>,
|
range: impl RangeBounds<BlockNumber>,
|
||||||
) -> ProviderResult<Vec<Vec<TransactionSigned>>>;
|
) -> ProviderResult<Vec<Vec<Self::Transaction>>>;
|
||||||
|
|
||||||
/// Get transactions by tx range.
|
/// Get transactions by tx range.
|
||||||
fn transactions_by_tx_range(
|
fn transactions_by_tx_range(
|
||||||
&self,
|
&self,
|
||||||
range: impl RangeBounds<TxNumber>,
|
range: impl RangeBounds<TxNumber>,
|
||||||
) -> ProviderResult<Vec<TransactionSignedNoHash>>;
|
) -> ProviderResult<Vec<Self::Transaction>>;
|
||||||
|
|
||||||
/// Get Senders from a tx range.
|
/// Get Senders from a tx range.
|
||||||
fn senders_by_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>>;
|
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)]
|
#[auto_impl::auto_impl(&, Arc)]
|
||||||
pub trait TransactionsProviderExt: BlockReader + Send + Sync {
|
pub trait TransactionsProviderExt: BlockReader + Send + Sync {
|
||||||
/// Get transactions range by block range.
|
/// Get transactions range by block range.
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use reth_chainspec::ChainSpecBuilder;
|
|||||||
use reth_db::{open_db_read_only, DatabaseEnv};
|
use reth_db::{open_db_read_only, DatabaseEnv};
|
||||||
use reth_node_ethereum::EthereumNode;
|
use reth_node_ethereum::EthereumNode;
|
||||||
use reth_node_types::NodeTypesWithDBAdapter;
|
use reth_node_types::NodeTypesWithDBAdapter;
|
||||||
use reth_primitives::SealedHeader;
|
use reth_primitives::{SealedHeader, TransactionSigned};
|
||||||
use reth_provider::{
|
use reth_provider::{
|
||||||
providers::StaticFileProvider, AccountReader, BlockReader, BlockSource, HeaderProvider,
|
providers::StaticFileProvider, AccountReader, BlockReader, BlockSource, HeaderProvider,
|
||||||
ProviderFactory, ReceiptProvider, StateProvider, TransactionsProvider,
|
ProviderFactory, ReceiptProvider, StateProvider, TransactionsProvider,
|
||||||
@ -83,7 +83,9 @@ fn header_provider_example<T: HeaderProvider>(provider: T, number: u64) -> eyre:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The `TransactionsProvider` allows querying transaction-related information
|
/// The `TransactionsProvider` allows querying transaction-related information
|
||||||
fn txs_provider_example<T: TransactionsProvider>(provider: T) -> eyre::Result<()> {
|
fn txs_provider_example<T: TransactionsProvider<Transaction = TransactionSigned>>(
|
||||||
|
provider: T,
|
||||||
|
) -> eyre::Result<()> {
|
||||||
// Try the 5th tx
|
// Try the 5th tx
|
||||||
let txid = 5;
|
let txid = 5;
|
||||||
|
|
||||||
@ -160,7 +162,9 @@ fn block_provider_example<T: BlockReader>(provider: T, number: u64) -> eyre::Res
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The `ReceiptProvider` allows querying the receipts tables.
|
/// The `ReceiptProvider` allows querying the receipts tables.
|
||||||
fn receipts_provider_example<T: ReceiptProvider + TransactionsProvider + HeaderProvider>(
|
fn receipts_provider_example<
|
||||||
|
T: ReceiptProvider + TransactionsProvider<Transaction = TransactionSigned> + HeaderProvider,
|
||||||
|
>(
|
||||||
provider: T,
|
provider: T,
|
||||||
) -> eyre::Result<()> {
|
) -> eyre::Result<()> {
|
||||||
let txid = 5;
|
let txid = 5;
|
||||||
|
|||||||
Reference in New Issue
Block a user