mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
feat(provider): add TransactionsProvider and WithdrawalsProvider (#1431)
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
use crate::{BlockNumber, H256};
|
||||
|
||||
/// Current status of the blockchain's head.
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
#[derive(Default, Debug, Eq, PartialEq)]
|
||||
pub struct ChainInfo {
|
||||
/// The block hash of the highest fully synced block.
|
||||
pub best_hash: H256,
|
||||
|
||||
@ -191,8 +191,8 @@ where
|
||||
self.inner.signers.iter().flat_map(|s| s.accounts()).collect()
|
||||
}
|
||||
|
||||
async fn transaction_by_hash(&self, _hash: H256) -> Result<Option<TransactionSigned>> {
|
||||
todo!()
|
||||
async fn transaction_by_hash(&self, hash: H256) -> Result<Option<TransactionSigned>> {
|
||||
self.client().transaction_by_hash(hash)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -11,8 +11,8 @@
|
||||
/// Various provider traits.
|
||||
mod traits;
|
||||
pub use traits::{
|
||||
AccountProvider, BlockHashProvider, BlockProvider, HeaderProvider, StateProvider,
|
||||
StateProviderFactory,
|
||||
AccountProvider, BlockHashProvider, BlockIdProvider, BlockProvider, HeaderProvider,
|
||||
StateProvider, StateProviderFactory, TransactionsProvider, WithdrawalsProvider,
|
||||
};
|
||||
|
||||
/// Provider trait implementations.
|
||||
|
||||
@ -1,17 +1,21 @@
|
||||
use crate::{BlockHashProvider, BlockProvider, Error, HeaderProvider, StateProviderFactory};
|
||||
use crate::{
|
||||
BlockHashProvider, BlockIdProvider, BlockProvider, Error, HeaderProvider, StateProviderFactory,
|
||||
TransactionsProvider, WithdrawalsProvider,
|
||||
};
|
||||
use reth_db::{
|
||||
cursor::DbCursorRO,
|
||||
database::{Database, DatabaseGAT},
|
||||
tables,
|
||||
transaction::DbTx,
|
||||
};
|
||||
use reth_interfaces::Result;
|
||||
use reth_primitives::{
|
||||
rpc::BlockId, Block, BlockHash, BlockNumber, ChainInfo, ChainSpec, Hardfork, Header, H256, U256,
|
||||
rpc::BlockId, Block, BlockHash, BlockNumber, ChainInfo, ChainSpec, Hardfork, Header,
|
||||
TransactionSigned, TxHash, TxNumber, Withdrawal, H256, U256,
|
||||
};
|
||||
use std::{ops::RangeBounds, sync::Arc};
|
||||
|
||||
mod state;
|
||||
use reth_db::cursor::DbCursorRO;
|
||||
pub use state::{
|
||||
chain::ChainState,
|
||||
historical::{HistoricalStateProvider, HistoricalStateProviderRef},
|
||||
@ -92,7 +96,7 @@ impl<DB: Database> BlockHashProvider for ShareableDatabase<DB> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<DB: Database> BlockProvider for ShareableDatabase<DB> {
|
||||
impl<DB: Database> BlockIdProvider for ShareableDatabase<DB> {
|
||||
fn chain_info(&self) -> Result<ChainInfo> {
|
||||
let best_number = self
|
||||
.db
|
||||
@ -103,47 +107,116 @@ impl<DB: Database> BlockProvider for ShareableDatabase<DB> {
|
||||
Ok(ChainInfo { best_hash, best_number, last_finalized: None, safe_finalized: None })
|
||||
}
|
||||
|
||||
fn block_number(&self, hash: H256) -> Result<Option<BlockNumber>> {
|
||||
self.db.view(|tx| tx.get::<tables::HeaderNumbers>(hash))?.map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
impl<DB: Database> BlockProvider for ShareableDatabase<DB> {
|
||||
fn block(&self, id: BlockId) -> Result<Option<Block>> {
|
||||
if let Some(number) = self.block_number_for_id(id)? {
|
||||
if let Some(header) = self.header_by_number(number)? {
|
||||
let id = BlockId::Number(number.into());
|
||||
let tx = self.db.tx()?;
|
||||
let body = tx
|
||||
.get::<tables::BlockBodies>(header.number)?
|
||||
.ok_or(Error::BlockBody { number })?;
|
||||
|
||||
let mut tx_cursor = tx.cursor_read::<tables::Transactions>()?;
|
||||
let mut transactions = Vec::with_capacity(body.tx_count as usize);
|
||||
for id in body.tx_id_range() {
|
||||
let (_, transaction) =
|
||||
tx_cursor.seek_exact(id)?.ok_or(Error::Transaction { id })?;
|
||||
transactions.push(transaction);
|
||||
}
|
||||
let transactions =
|
||||
self.transactions_by_block(id)?.ok_or(Error::BlockBody { number })?;
|
||||
|
||||
let ommers = tx.get::<tables::BlockOmmers>(header.number)?.map(|o| o.ommers);
|
||||
let withdrawals = self.withdrawals_by_block(id, header.timestamp)?;
|
||||
|
||||
let header_timestamp = header.timestamp;
|
||||
let mut block = Block {
|
||||
return Ok(Some(Block {
|
||||
header,
|
||||
body: transactions,
|
||||
ommers: ommers.unwrap_or_default(),
|
||||
withdrawals: None,
|
||||
};
|
||||
|
||||
if self.chain_spec.fork(Hardfork::Shanghai).active_at_timestamp(header_timestamp) {
|
||||
let withdrawals =
|
||||
tx.get::<tables::BlockWithdrawals>(number)?.map(|w| w.withdrawals);
|
||||
block.withdrawals = Some(withdrawals.unwrap_or_default());
|
||||
}
|
||||
|
||||
return Ok(Some(block))
|
||||
withdrawals,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn block_number(&self, hash: H256) -> Result<Option<BlockNumber>> {
|
||||
self.db.view(|tx| tx.get::<tables::HeaderNumbers>(hash))?.map_err(Into::into)
|
||||
impl<DB: Database> TransactionsProvider for ShareableDatabase<DB> {
|
||||
fn transaction_by_id(&self, id: TxNumber) -> Result<Option<TransactionSigned>> {
|
||||
self.db.view(|tx| tx.get::<tables::Transactions>(id))?.map_err(Into::into)
|
||||
}
|
||||
|
||||
fn transaction_by_hash(&self, hash: TxHash) -> Result<Option<TransactionSigned>> {
|
||||
self.db
|
||||
.view(|tx| {
|
||||
if let Some(id) = tx.get::<tables::TxHashNumber>(hash)? {
|
||||
tx.get::<tables::Transactions>(id)
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
})?
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
fn transactions_by_block(&self, id: BlockId) -> Result<Option<Vec<TransactionSigned>>> {
|
||||
if let Some(number) = self.block_number_for_id(id)? {
|
||||
let tx = self.db.tx()?;
|
||||
if let Some(body) = tx.get::<tables::BlockBodies>(number)? {
|
||||
let tx_range = body.tx_id_range();
|
||||
if tx_range.is_empty() {
|
||||
Ok(Some(Vec::default()))
|
||||
} else {
|
||||
let mut tx_cursor = tx.cursor_read::<tables::Transactions>()?;
|
||||
let transactions = tx_cursor
|
||||
.walk_range(tx_range)?
|
||||
.map(|result| result.map(|(_, tx)| tx))
|
||||
.collect::<std::result::Result<Vec<_>, _>>()?;
|
||||
Ok(Some(transactions))
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn transactions_by_block_range(
|
||||
&self,
|
||||
range: impl RangeBounds<BlockNumber>,
|
||||
) -> Result<Vec<Vec<TransactionSigned>>> {
|
||||
let tx = self.db.tx()?;
|
||||
let mut results = Vec::default();
|
||||
let mut body_cursor = tx.cursor_read::<tables::BlockBodies>()?;
|
||||
let mut tx_cursor = tx.cursor_read::<tables::Transactions>()?;
|
||||
for entry in body_cursor.walk_range(range)? {
|
||||
let (_, body) = entry?;
|
||||
let tx_range = body.tx_id_range();
|
||||
if body.tx_id_range().is_empty() {
|
||||
results.push(Vec::default());
|
||||
} else {
|
||||
results.push(
|
||||
tx_cursor
|
||||
.walk_range(tx_range)?
|
||||
.map(|result| result.map(|(_, tx)| tx))
|
||||
.collect::<std::result::Result<Vec<_>, _>>()?,
|
||||
);
|
||||
}
|
||||
}
|
||||
Ok(results)
|
||||
}
|
||||
}
|
||||
|
||||
impl<DB: Database> WithdrawalsProvider for ShareableDatabase<DB> {
|
||||
fn withdrawals_by_block(&self, id: BlockId, timestamp: u64) -> Result<Option<Vec<Withdrawal>>> {
|
||||
if self.chain_spec.fork(Hardfork::Shanghai).active_at_timestamp(timestamp) {
|
||||
if let Some(number) = self.block_number_for_id(id)? {
|
||||
Ok(self
|
||||
.db
|
||||
.view(|tx| tx.get::<tables::BlockWithdrawals>(number))??
|
||||
.map(|w| w.withdrawals))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,9 +256,8 @@ impl<DB: Database> StateProviderFactory for ShareableDatabase<DB> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{BlockProvider, StateProviderFactory};
|
||||
|
||||
use super::ShareableDatabase;
|
||||
use crate::{BlockIdProvider, StateProviderFactory};
|
||||
use reth_db::mdbx::{test_utils::create_test_db, EnvKind, WriteMap};
|
||||
use reth_primitives::{ChainSpecBuilder, H256};
|
||||
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
use crate::{
|
||||
AccountProvider, BlockHashProvider, BlockProvider, HeaderProvider, StateProvider,
|
||||
StateProviderFactory,
|
||||
AccountProvider, BlockHashProvider, BlockIdProvider, BlockProvider, HeaderProvider,
|
||||
StateProvider, StateProviderFactory, TransactionsProvider,
|
||||
};
|
||||
use parking_lot::Mutex;
|
||||
use reth_interfaces::Result;
|
||||
use reth_primitives::{
|
||||
keccak256,
|
||||
rpc::{BlockId, BlockNumber},
|
||||
Account, Address, Block, BlockHash, Bytes, ChainInfo, Header, StorageKey, StorageValue, H256,
|
||||
U256,
|
||||
Account, Address, Block, BlockHash, Bytes, ChainInfo, Header, StorageKey, StorageValue,
|
||||
TransactionSigned, TxHash, H256, U256,
|
||||
};
|
||||
use std::{collections::HashMap, ops::RangeBounds, sync::Arc};
|
||||
|
||||
@ -119,6 +119,34 @@ impl HeaderProvider for MockEthProvider {
|
||||
}
|
||||
}
|
||||
|
||||
impl TransactionsProvider for MockEthProvider {
|
||||
fn transaction_by_id(
|
||||
&self,
|
||||
_id: reth_primitives::TxNumber,
|
||||
) -> Result<Option<TransactionSigned>> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn transaction_by_hash(&self, hash: TxHash) -> Result<Option<TransactionSigned>> {
|
||||
Ok(self
|
||||
.blocks
|
||||
.lock()
|
||||
.iter()
|
||||
.find_map(|(_, block)| block.body.iter().find(|tx| tx.hash == hash).cloned()))
|
||||
}
|
||||
|
||||
fn transactions_by_block(&self, id: BlockId) -> Result<Option<Vec<TransactionSigned>>> {
|
||||
Ok(self.block(id)?.map(|b| b.body))
|
||||
}
|
||||
|
||||
fn transactions_by_block_range(
|
||||
&self,
|
||||
_range: impl RangeBounds<reth_primitives::BlockNumber>,
|
||||
) -> Result<Vec<Vec<TransactionSigned>>> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl BlockHashProvider for MockEthProvider {
|
||||
fn block_hash(&self, number: U256) -> Result<Option<H256>> {
|
||||
let lock = self.blocks.lock();
|
||||
@ -137,7 +165,7 @@ impl BlockHashProvider for MockEthProvider {
|
||||
}
|
||||
}
|
||||
|
||||
impl BlockProvider for MockEthProvider {
|
||||
impl BlockIdProvider for MockEthProvider {
|
||||
fn chain_info(&self) -> Result<ChainInfo> {
|
||||
let lock = self.headers.lock();
|
||||
Ok(lock
|
||||
@ -152,6 +180,14 @@ impl BlockProvider for MockEthProvider {
|
||||
.expect("provider is empty"))
|
||||
}
|
||||
|
||||
fn block_number(&self, hash: H256) -> Result<Option<reth_primitives::BlockNumber>> {
|
||||
let lock = self.blocks.lock();
|
||||
let num = lock.iter().find_map(|(h, b)| if *h == hash { Some(b.number) } else { None });
|
||||
Ok(num)
|
||||
}
|
||||
}
|
||||
|
||||
impl BlockProvider for MockEthProvider {
|
||||
fn block(&self, id: BlockId) -> Result<Option<Block>> {
|
||||
let lock = self.blocks.lock();
|
||||
match id {
|
||||
@ -164,12 +200,6 @@ impl BlockProvider for MockEthProvider {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn block_number(&self, hash: H256) -> Result<Option<reth_primitives::BlockNumber>> {
|
||||
let lock = self.blocks.lock();
|
||||
let num = lock.iter().find_map(|(h, b)| if *h == hash { Some(b.number) } else { None });
|
||||
Ok(num)
|
||||
}
|
||||
}
|
||||
|
||||
impl AccountProvider for MockEthProvider {
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
use crate::{
|
||||
AccountProvider, BlockHashProvider, BlockProvider, HeaderProvider, StateProvider,
|
||||
StateProviderFactory,
|
||||
AccountProvider, BlockHashProvider, BlockIdProvider, BlockProvider, HeaderProvider,
|
||||
StateProvider, StateProviderFactory, TransactionsProvider,
|
||||
};
|
||||
use reth_interfaces::Result;
|
||||
use reth_primitives::{
|
||||
rpc::BlockId, Account, Address, Block, BlockHash, BlockNumber, Bytes, ChainInfo, Header,
|
||||
StorageKey, StorageValue, H256, U256,
|
||||
StorageKey, StorageValue, TransactionSigned, TxHash, TxNumber, H256, U256,
|
||||
};
|
||||
use std::ops::RangeBounds;
|
||||
|
||||
@ -21,18 +21,9 @@ impl BlockHashProvider for NoopProvider {
|
||||
}
|
||||
}
|
||||
|
||||
impl BlockProvider for NoopProvider {
|
||||
impl BlockIdProvider for NoopProvider {
|
||||
fn chain_info(&self) -> Result<ChainInfo> {
|
||||
Ok(ChainInfo {
|
||||
best_hash: Default::default(),
|
||||
best_number: 0,
|
||||
last_finalized: None,
|
||||
safe_finalized: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn block(&self, _id: BlockId) -> Result<Option<Block>> {
|
||||
Ok(None)
|
||||
Ok(ChainInfo::default())
|
||||
}
|
||||
|
||||
fn block_number(&self, _hash: H256) -> Result<Option<BlockNumber>> {
|
||||
@ -40,6 +31,33 @@ impl BlockProvider for NoopProvider {
|
||||
}
|
||||
}
|
||||
|
||||
impl BlockProvider for NoopProvider {
|
||||
fn block(&self, _id: BlockId) -> Result<Option<Block>> {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
impl TransactionsProvider for NoopProvider {
|
||||
fn transaction_by_hash(&self, _hash: TxHash) -> Result<Option<TransactionSigned>> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn transaction_by_id(&self, _id: TxNumber) -> Result<Option<TransactionSigned>> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn transactions_by_block(&self, _block_id: BlockId) -> Result<Option<Vec<TransactionSigned>>> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn transactions_by_block_range(
|
||||
&self,
|
||||
_range: impl RangeBounds<BlockNumber>,
|
||||
) -> Result<Vec<Vec<TransactionSigned>>> {
|
||||
Ok(Vec::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl HeaderProvider for NoopProvider {
|
||||
fn header(&self, _block_hash: &BlockHash) -> Result<Option<Header>> {
|
||||
Ok(None)
|
||||
|
||||
@ -1,63 +1,12 @@
|
||||
use super::BlockHashProvider;
|
||||
use crate::HeaderProvider;
|
||||
use crate::{BlockIdProvider, HeaderProvider, TransactionsProvider};
|
||||
use reth_interfaces::Result;
|
||||
use reth_primitives::{
|
||||
rpc::{BlockId, BlockNumber},
|
||||
Block, ChainInfo, H256, U256,
|
||||
};
|
||||
use reth_primitives::{rpc::BlockId, Block};
|
||||
|
||||
/// Api trait for fetching `Block` related data.
|
||||
#[auto_impl::auto_impl(&, Arc)]
|
||||
pub trait BlockProvider: BlockHashProvider + HeaderProvider + Send + Sync {
|
||||
/// Returns the current info for the chain.
|
||||
fn chain_info(&self) -> Result<ChainInfo>;
|
||||
|
||||
pub trait BlockProvider:
|
||||
BlockIdProvider + HeaderProvider + TransactionsProvider + Send + Sync
|
||||
{
|
||||
/// Returns the block. Returns `None` if block is not found.
|
||||
fn block(&self, id: BlockId) -> Result<Option<Block>>;
|
||||
|
||||
/// Converts the `BlockNumber` variants.
|
||||
fn convert_block_number(
|
||||
&self,
|
||||
num: BlockNumber,
|
||||
) -> Result<Option<reth_primitives::BlockNumber>> {
|
||||
let num = match num {
|
||||
BlockNumber::Latest => self.chain_info()?.best_number,
|
||||
BlockNumber::Earliest => 0,
|
||||
BlockNumber::Pending => return Ok(None),
|
||||
BlockNumber::Number(num) => num.as_u64(),
|
||||
BlockNumber::Finalized => return Ok(self.chain_info()?.last_finalized),
|
||||
BlockNumber::Safe => return Ok(self.chain_info()?.safe_finalized),
|
||||
};
|
||||
Ok(Some(num))
|
||||
}
|
||||
|
||||
/// Get the hash of the block by matching the given id.
|
||||
fn block_hash_for_id(&self, block_id: BlockId) -> Result<Option<H256>> {
|
||||
match block_id {
|
||||
BlockId::Hash(hash) => Ok(Some(H256(hash.0))),
|
||||
BlockId::Number(num) => {
|
||||
if matches!(num, BlockNumber::Latest) {
|
||||
return Ok(Some(self.chain_info()?.best_hash))
|
||||
}
|
||||
self.convert_block_number(num)?
|
||||
.map(|num| self.block_hash(U256::from(num)))
|
||||
.transpose()
|
||||
.map(|maybe_hash| maybe_hash.flatten())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the number of the block by matching the given id.
|
||||
fn block_number_for_id(
|
||||
&self,
|
||||
block_id: BlockId,
|
||||
) -> Result<Option<reth_primitives::BlockNumber>> {
|
||||
match block_id {
|
||||
BlockId::Hash(hash) => self.block_number(H256(hash.0)),
|
||||
BlockId::Number(num) => self.convert_block_number(num),
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the `Block` for the given hash. Returns `None` if no block with this hash exists.
|
||||
fn block_number(&self, hash: H256) -> Result<Option<reth_primitives::BlockNumber>>;
|
||||
}
|
||||
|
||||
59
crates/storage/provider/src/traits/block_id.rs
Normal file
59
crates/storage/provider/src/traits/block_id.rs
Normal file
@ -0,0 +1,59 @@
|
||||
use super::BlockHashProvider;
|
||||
use reth_interfaces::Result;
|
||||
use reth_primitives::{
|
||||
rpc::{BlockId, BlockNumber},
|
||||
ChainInfo, H256, U256,
|
||||
};
|
||||
|
||||
/// Client trait for transforming [BlockId].
|
||||
#[auto_impl::auto_impl(&, Arc)]
|
||||
pub trait BlockIdProvider: BlockHashProvider + Send + Sync {
|
||||
/// Returns the current info for the chain.
|
||||
fn chain_info(&self) -> Result<ChainInfo>;
|
||||
|
||||
/// Converts the `BlockNumber` variants.
|
||||
fn convert_block_number(
|
||||
&self,
|
||||
num: BlockNumber,
|
||||
) -> Result<Option<reth_primitives::BlockNumber>> {
|
||||
let num = match num {
|
||||
BlockNumber::Latest => self.chain_info()?.best_number,
|
||||
BlockNumber::Earliest => 0,
|
||||
BlockNumber::Pending => return Ok(None),
|
||||
BlockNumber::Number(num) => num.as_u64(),
|
||||
BlockNumber::Finalized => return Ok(self.chain_info()?.last_finalized),
|
||||
BlockNumber::Safe => return Ok(self.chain_info()?.safe_finalized),
|
||||
};
|
||||
Ok(Some(num))
|
||||
}
|
||||
|
||||
/// Get the hash of the block by matching the given id.
|
||||
fn block_hash_for_id(&self, block_id: BlockId) -> Result<Option<H256>> {
|
||||
match block_id {
|
||||
BlockId::Hash(hash) => Ok(Some(H256(hash.0))),
|
||||
BlockId::Number(num) => {
|
||||
if matches!(num, BlockNumber::Latest) {
|
||||
return Ok(Some(self.chain_info()?.best_hash))
|
||||
}
|
||||
self.convert_block_number(num)?
|
||||
.map(|num| self.block_hash(U256::from(num)))
|
||||
.transpose()
|
||||
.map(|maybe_hash| maybe_hash.flatten())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the number of the block by matching the given id.
|
||||
fn block_number_for_id(
|
||||
&self,
|
||||
block_id: BlockId,
|
||||
) -> Result<Option<reth_primitives::BlockNumber>> {
|
||||
match block_id {
|
||||
BlockId::Hash(hash) => self.block_number(H256(hash.0)),
|
||||
BlockId::Number(num) => self.convert_block_number(num),
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the `Block` for the given hash. Returns `None` if no block with this hash exists.
|
||||
fn block_number(&self, hash: H256) -> Result<Option<reth_primitives::BlockNumber>>;
|
||||
}
|
||||
@ -9,8 +9,17 @@ pub use block::BlockProvider;
|
||||
mod block_hash;
|
||||
pub use block_hash::BlockHashProvider;
|
||||
|
||||
mod block_id;
|
||||
pub use block_id::BlockIdProvider;
|
||||
|
||||
mod header;
|
||||
pub use header::HeaderProvider;
|
||||
|
||||
mod state;
|
||||
pub use state::{StateProvider, StateProviderFactory};
|
||||
|
||||
mod transactions;
|
||||
pub use transactions::TransactionsProvider;
|
||||
|
||||
mod withdrawals;
|
||||
pub use withdrawals::WithdrawalsProvider;
|
||||
|
||||
23
crates/storage/provider/src/traits/transactions.rs
Normal file
23
crates/storage/provider/src/traits/transactions.rs
Normal file
@ -0,0 +1,23 @@
|
||||
use crate::BlockIdProvider;
|
||||
use reth_interfaces::Result;
|
||||
use reth_primitives::{rpc::BlockId, BlockNumber, TransactionSigned, TxHash, TxNumber};
|
||||
use std::ops::RangeBounds;
|
||||
|
||||
/// Client trait for fetching [TransactionSigned] related data.
|
||||
#[auto_impl::auto_impl(&, Arc)]
|
||||
pub trait TransactionsProvider: BlockIdProvider + Send + Sync {
|
||||
/// Get transaction by id.
|
||||
fn transaction_by_id(&self, id: TxNumber) -> Result<Option<TransactionSigned>>;
|
||||
|
||||
/// Get transaction by transaction hash.
|
||||
fn transaction_by_hash(&self, hash: TxHash) -> Result<Option<TransactionSigned>>;
|
||||
|
||||
/// Get transactions by block id.
|
||||
fn transactions_by_block(&self, block: BlockId) -> Result<Option<Vec<TransactionSigned>>>;
|
||||
|
||||
/// Get transactions by block range.
|
||||
fn transactions_by_block_range(
|
||||
&self,
|
||||
range: impl RangeBounds<BlockNumber>,
|
||||
) -> Result<Vec<Vec<TransactionSigned>>>;
|
||||
}
|
||||
8
crates/storage/provider/src/traits/withdrawals.rs
Normal file
8
crates/storage/provider/src/traits/withdrawals.rs
Normal file
@ -0,0 +1,8 @@
|
||||
use reth_interfaces::Result;
|
||||
use reth_primitives::{rpc::BlockId, Withdrawal};
|
||||
|
||||
/// Client trait for fetching [Withdrawal] related data.
|
||||
pub trait WithdrawalsProvider: Send + Sync {
|
||||
/// Get withdrawals by block id.
|
||||
fn withdrawals_by_block(&self, id: BlockId, timestamp: u64) -> Result<Option<Vec<Withdrawal>>>;
|
||||
}
|
||||
Reference in New Issue
Block a user