feat: add ReceiptProvider (#1735)

This commit is contained in:
Matthias Seitz
2023-03-13 14:35:28 +01:00
committed by GitHub
parent c110c91629
commit 31411681ed
6 changed files with 99 additions and 11 deletions

View File

@@ -12,8 +12,8 @@
mod traits;
pub use traits::{
AccountProvider, BlockExecutor, BlockHashProvider, BlockIdProvider, BlockProvider,
EvmEnvProvider, ExecutorFactory, HeaderProvider, StateProvider, StateProviderFactory,
TransactionsProvider, WithdrawalsProvider,
EvmEnvProvider, ExecutorFactory, HeaderProvider, ReceiptProvider, StateProvider,
StateProviderFactory, TransactionsProvider, WithdrawalsProvider,
};
/// Provider trait implementations.

View File

@@ -10,7 +10,7 @@ use reth_db::{
};
use reth_interfaces::Result;
use reth_primitives::{
Block, BlockHash, BlockId, BlockNumber, ChainInfo, ChainSpec, Hardfork, Head, Header,
Block, BlockHash, BlockId, BlockNumber, ChainInfo, ChainSpec, Hardfork, Head, Header, Receipt,
TransactionSigned, TxHash, TxNumber, Withdrawal, H256, U256,
};
use reth_revm_primitives::{
@@ -21,6 +21,7 @@ use revm_primitives::{BlockEnv, CfgEnv, SpecId};
use std::{ops::RangeBounds, sync::Arc};
mod state;
use crate::traits::ReceiptProvider;
pub use state::{
chain::ChainState,
historical::{HistoricalStateProvider, HistoricalStateProviderRef},
@@ -176,7 +177,7 @@ impl<DB: Database> TransactionsProvider for ShareableDatabase<DB> {
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()))
Ok(Some(Vec::new()))
} else {
let mut tx_cursor = tx.cursor_read::<tables::Transactions>()?;
let transactions = tx_cursor
@@ -219,6 +220,47 @@ impl<DB: Database> TransactionsProvider for ShareableDatabase<DB> {
}
}
impl<DB: Database> ReceiptProvider for ShareableDatabase<DB> {
fn receipt(&self, id: TxNumber) -> Result<Option<Receipt>> {
self.db.view(|tx| tx.get::<tables::Receipts>(id))?.map_err(Into::into)
}
fn receipt_by_hash(&self, hash: TxHash) -> Result<Option<Receipt>> {
self.db
.view(|tx| {
if let Some(id) = tx.get::<tables::TxHashNumber>(hash)? {
tx.get::<tables::Receipts>(id)
} else {
Ok(None)
}
})?
.map_err(Into::into)
}
fn receipts_by_block(&self, block: BlockId) -> Result<Option<Vec<Receipt>>> {
if let Some(number) = self.block_number_for_id(block)? {
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::new()))
} else {
let mut tx_cursor = tx.cursor_read::<tables::Receipts>()?;
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)
}
}
}
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) {

View File

@@ -1,13 +1,13 @@
use crate::{
AccountProvider, BlockHashProvider, BlockIdProvider, BlockProvider, EvmEnvProvider,
HeaderProvider, StateProvider, StateProviderFactory, TransactionsProvider,
traits::ReceiptProvider, AccountProvider, BlockHashProvider, BlockIdProvider, BlockProvider,
EvmEnvProvider, HeaderProvider, StateProvider, StateProviderFactory, TransactionsProvider,
};
use parking_lot::Mutex;
use reth_interfaces::Result;
use reth_primitives::{
keccak256, Account, Address, Block, BlockHash, BlockId, BlockNumber, BlockNumberOrTag,
Bytecode, Bytes, ChainInfo, Header, StorageKey, StorageValue, TransactionSigned, TxHash, H256,
U256,
Bytecode, Bytes, ChainInfo, Header, Receipt, StorageKey, StorageValue, TransactionSigned,
TxHash, TxNumber, H256, U256,
};
use revm_primitives::{BlockEnv, CfgEnv};
use std::{collections::HashMap, ops::RangeBounds, sync::Arc};
@@ -156,6 +156,20 @@ impl TransactionsProvider for MockEthProvider {
}
}
impl ReceiptProvider for MockEthProvider {
fn receipt(&self, _id: TxNumber) -> Result<Option<Receipt>> {
Ok(None)
}
fn receipt_by_hash(&self, _hash: TxHash) -> Result<Option<Receipt>> {
Ok(None)
}
fn receipts_by_block(&self, _block: BlockId) -> Result<Option<Vec<Receipt>>> {
Ok(None)
}
}
impl BlockHashProvider for MockEthProvider {
fn block_hash(&self, number: U256) -> Result<Option<H256>> {
let lock = self.blocks.lock();

View File

@@ -1,10 +1,10 @@
use crate::{
AccountProvider, BlockHashProvider, BlockIdProvider, BlockProvider, EvmEnvProvider,
HeaderProvider, StateProvider, StateProviderFactory, TransactionsProvider,
traits::ReceiptProvider, AccountProvider, BlockHashProvider, BlockIdProvider, BlockProvider,
EvmEnvProvider, HeaderProvider, StateProvider, StateProviderFactory, TransactionsProvider,
};
use reth_interfaces::Result;
use reth_primitives::{
Account, Address, Block, BlockHash, BlockId, BlockNumber, Bytecode, ChainInfo, Header,
Account, Address, Block, BlockHash, BlockId, BlockNumber, Bytecode, ChainInfo, Header, Receipt,
StorageKey, StorageValue, TransactionSigned, TxHash, TxNumber, H256, U256,
};
use revm_primitives::{BlockEnv, CfgEnv};
@@ -63,6 +63,20 @@ impl TransactionsProvider for NoopProvider {
}
}
impl ReceiptProvider for NoopProvider {
fn receipt(&self, _id: TxNumber) -> Result<Option<Receipt>> {
Ok(None)
}
fn receipt_by_hash(&self, _hash: TxHash) -> Result<Option<Receipt>> {
Ok(None)
}
fn receipts_by_block(&self, _block: BlockId) -> Result<Option<Vec<Receipt>>> {
Ok(None)
}
}
impl HeaderProvider for NoopProvider {
fn header(&self, _block_hash: &BlockHash) -> Result<Option<Header>> {
Ok(None)

View File

@@ -18,6 +18,9 @@ pub use evm_env::EvmEnvProvider;
mod header;
pub use header::HeaderProvider;
mod receipts;
pub use receipts::ReceiptProvider;
mod state;
pub use state::{StateProvider, StateProviderFactory};

View File

@@ -0,0 +1,15 @@
use reth_interfaces::Result;
use reth_primitives::{BlockId, Receipt, TxHash, TxNumber};
/// Client trait for fetching [Receipt] data .
#[auto_impl::auto_impl(&, Arc)]
pub trait ReceiptProvider: Send + Sync {
/// Get receipt by transaction number
fn receipt(&self, id: TxNumber) -> Result<Option<Receipt>>;
/// Get receipt by transaction hash.
fn receipt_by_hash(&self, hash: TxHash) -> Result<Option<Receipt>>;
/// Get receipts by block id.
fn receipts_by_block(&self, block: BlockId) -> Result<Option<Vec<Receipt>>>;
}