mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: add Block AT to BlockReader (#12837)
This commit is contained in:
@ -2,21 +2,32 @@
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use alloy_consensus::BlockHeader;
|
||||
use alloy_eips::BlockId;
|
||||
use alloy_rpc_types_eth::{Block, Header, Index};
|
||||
use futures::Future;
|
||||
use reth_primitives::{Receipt, SealedBlock, SealedBlockWithSenders};
|
||||
use reth_node_api::BlockBody;
|
||||
use reth_primitives::{Receipt, SealedBlockFor, SealedBlockWithSenders};
|
||||
use reth_provider::{BlockIdReader, BlockReader, BlockReaderIdExt, HeaderProvider};
|
||||
use reth_rpc_types_compat::block::from_block;
|
||||
|
||||
use crate::{node::RpcNodeCoreExt, FromEthApiError, FullEthApiTypes, RpcBlock, RpcReceipt};
|
||||
use crate::{
|
||||
node::RpcNodeCoreExt, EthApiTypes, FromEthApiError, FullEthApiTypes, RpcBlock, RpcNodeCore,
|
||||
RpcReceipt,
|
||||
};
|
||||
|
||||
use super::{LoadPendingBlock, LoadReceipt, SpawnBlocking};
|
||||
|
||||
/// Result type of the fetched block receipts.
|
||||
pub type BlockReceiptsResult<N, E> = Result<Option<Vec<RpcReceipt<N>>>, E>;
|
||||
/// Result type of the fetched block and its receipts.
|
||||
pub type BlockAndReceiptsResult<E> = Result<Option<(SealedBlock, Arc<Vec<Receipt>>)>, E>;
|
||||
pub type BlockAndReceiptsResult<Eth> = Result<
|
||||
Option<(
|
||||
SealedBlockFor<<<Eth as RpcNodeCore>::Provider as BlockReader>::Block>,
|
||||
Arc<Vec<Receipt>>,
|
||||
)>,
|
||||
<Eth as EthApiTypes>::Error,
|
||||
>;
|
||||
|
||||
/// Block related functions for the [`EthApiServer`](crate::EthApiServer) trait in the
|
||||
/// `eth_` namespace.
|
||||
@ -49,7 +60,7 @@ pub trait EthBlocks: LoadBlock {
|
||||
let block_hash = block.hash();
|
||||
let mut total_difficulty = self
|
||||
.provider()
|
||||
.header_td_by_number(block.number)
|
||||
.header_td_by_number(block.number())
|
||||
.map_err(Self::Error::from_eth_err)?;
|
||||
if total_difficulty.is_none() {
|
||||
// if we failed to find td after we successfully loaded the block, try again using
|
||||
@ -83,7 +94,7 @@ pub trait EthBlocks: LoadBlock {
|
||||
.provider()
|
||||
.pending_block()
|
||||
.map_err(Self::Error::from_eth_err)?
|
||||
.map(|block| block.body.transactions.len()))
|
||||
.map(|block| block.body.transactions().len()))
|
||||
}
|
||||
|
||||
let block_hash = match self
|
||||
@ -120,7 +131,7 @@ pub trait EthBlocks: LoadBlock {
|
||||
fn load_block_and_receipts(
|
||||
&self,
|
||||
block_id: BlockId,
|
||||
) -> impl Future<Output = BlockAndReceiptsResult<Self::Error>> + Send
|
||||
) -> impl Future<Output = BlockAndReceiptsResult<Self>> + Send
|
||||
where
|
||||
Self: LoadReceipt,
|
||||
{
|
||||
@ -198,10 +209,16 @@ pub trait EthBlocks: LoadBlock {
|
||||
/// Behaviour shared by several `eth_` RPC methods, not exclusive to `eth_` blocks RPC methods.
|
||||
pub trait LoadBlock: LoadPendingBlock + SpawnBlocking + RpcNodeCoreExt {
|
||||
/// Returns the block object for the given block id.
|
||||
#[expect(clippy::type_complexity)]
|
||||
fn block_with_senders(
|
||||
&self,
|
||||
block_id: BlockId,
|
||||
) -> impl Future<Output = Result<Option<Arc<SealedBlockWithSenders>>, Self::Error>> + Send {
|
||||
) -> impl Future<
|
||||
Output = Result<
|
||||
Option<Arc<SealedBlockWithSenders<<Self::Provider as BlockReader>::Block>>>,
|
||||
Self::Error,
|
||||
>,
|
||||
> + Send {
|
||||
async move {
|
||||
if block_id.is_pending() {
|
||||
// Pending block can be fetched directly without need for caching
|
||||
|
||||
@ -18,6 +18,7 @@ use alloy_rpc_types_eth::{
|
||||
use futures::Future;
|
||||
use reth_chainspec::EthChainSpec;
|
||||
use reth_evm::{ConfigureEvm, ConfigureEvmEnv};
|
||||
use reth_node_api::BlockBody;
|
||||
use reth_primitives::TransactionSigned;
|
||||
use reth_provider::{BlockIdReader, ChainSpecProvider, HeaderProvider};
|
||||
use reth_revm::{
|
||||
@ -278,14 +279,15 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock {
|
||||
// we're essentially replaying the transactions in the block here, hence we need the
|
||||
// state that points to the beginning of the block, which is the state at
|
||||
// the parent block
|
||||
let mut at = block.parent_hash;
|
||||
let mut at = block.parent_hash();
|
||||
let mut replay_block_txs = true;
|
||||
|
||||
let num_txs = transaction_index.index().unwrap_or(block.body.transactions.len());
|
||||
let num_txs =
|
||||
transaction_index.index().unwrap_or_else(|| block.body.transactions().len());
|
||||
// but if all transactions are to be replayed, we can use the state at the block itself,
|
||||
// however only if we're not targeting the pending block, because for pending we can't
|
||||
// rely on the block's state being available
|
||||
if !is_block_target_pending && num_txs == block.body.transactions.len() {
|
||||
if !is_block_target_pending && num_txs == block.body.transactions().len() {
|
||||
at = block.hash();
|
||||
replay_block_txs = false;
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
//! Loads fee history from database. Helper trait for `eth_` fee and transaction RPC methods.
|
||||
|
||||
use alloy_consensus::BlockHeader;
|
||||
use alloy_primitives::U256;
|
||||
use alloy_rpc_types_eth::{BlockNumberOrTag, FeeHistory};
|
||||
use futures::Future;
|
||||
@ -287,7 +288,7 @@ pub trait LoadFee: LoadBlock {
|
||||
.block_with_senders(BlockNumberOrTag::Pending.into())
|
||||
.await?
|
||||
.ok_or(EthApiError::HeaderNotFound(BlockNumberOrTag::Pending.into()))?
|
||||
.base_fee_per_gas
|
||||
.base_fee_per_gas()
|
||||
.ok_or(EthApiError::InvalidTransaction(
|
||||
RpcInvalidTransactionError::TxTypeNotSupported,
|
||||
))?;
|
||||
@ -324,7 +325,7 @@ pub trait LoadFee: LoadBlock {
|
||||
let suggested_tip = self.suggested_priority_fee();
|
||||
async move {
|
||||
let (header, suggested_tip) = futures::try_join!(header, suggested_tip)?;
|
||||
let base_fee = header.and_then(|h| h.base_fee_per_gas).unwrap_or_default();
|
||||
let base_fee = header.and_then(|h| h.base_fee_per_gas()).unwrap_or_default();
|
||||
Ok(suggested_tip + U256::from(base_fee))
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ use tracing::debug;
|
||||
pub trait LoadPendingBlock:
|
||||
EthApiTypes
|
||||
+ RpcNodeCore<
|
||||
Provider: BlockReaderIdExt
|
||||
Provider: BlockReaderIdExt<Block = reth_primitives::Block>
|
||||
+ EvmEnvProvider
|
||||
+ ChainSpecProvider<ChainSpec: EthChainSpec + EthereumHardforks>
|
||||
+ StateProviderFactory,
|
||||
@ -114,9 +114,15 @@ pub trait LoadPendingBlock:
|
||||
}
|
||||
|
||||
/// Returns the locally built pending block
|
||||
#[expect(clippy::type_complexity)]
|
||||
fn local_pending_block(
|
||||
&self,
|
||||
) -> impl Future<Output = Result<Option<(SealedBlockWithSenders, Vec<Receipt>)>, Self::Error>> + Send
|
||||
) -> impl Future<
|
||||
Output = Result<
|
||||
Option<(SealedBlockWithSenders<<Self::Provider as BlockReader>::Block>, Vec<Receipt>)>,
|
||||
Self::Error,
|
||||
>,
|
||||
> + Send
|
||||
where
|
||||
Self: SpawnBlocking,
|
||||
{
|
||||
|
||||
@ -10,6 +10,7 @@ use futures::Future;
|
||||
use reth_chainspec::ChainSpecProvider;
|
||||
use reth_evm::{system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv};
|
||||
use reth_primitives::SealedBlockWithSenders;
|
||||
use reth_provider::BlockReader;
|
||||
use reth_revm::database::StateProviderDatabase;
|
||||
use reth_rpc_eth_types::{
|
||||
cache::db::{StateCacheDb, StateCacheDbRefMutWrapper, StateProviderTraitObjWrapper},
|
||||
@ -24,7 +25,7 @@ use revm_primitives::{
|
||||
use super::{Call, LoadBlock, LoadPendingBlock, LoadState, LoadTransaction};
|
||||
|
||||
/// Executes CPU heavy tasks.
|
||||
pub trait Trace: LoadState<Evm: ConfigureEvm<Header = Header>> {
|
||||
pub trait Trace: LoadState<Provider: BlockReader, Evm: ConfigureEvm<Header = Header>> {
|
||||
/// Executes the [`EnvWithHandlerCfg`] against the given [Database] without committing state
|
||||
/// changes.
|
||||
fn inspect<DB, I>(
|
||||
@ -230,7 +231,7 @@ pub trait Trace: LoadState<Evm: ConfigureEvm<Header = Header>> {
|
||||
fn trace_block_until<F, R>(
|
||||
&self,
|
||||
block_id: BlockId,
|
||||
block: Option<Arc<SealedBlockWithSenders>>,
|
||||
block: Option<Arc<SealedBlockWithSenders<<Self::Provider as BlockReader>::Block>>>,
|
||||
highest_index: Option<u64>,
|
||||
config: TracingInspectorConfig,
|
||||
f: F,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
//! Database access for `eth_` transaction RPC methods. Loads transaction and receipt data w.r.t.
|
||||
//! network.
|
||||
|
||||
use alloy_consensus::Transaction;
|
||||
use alloy_consensus::{BlockHeader, Transaction};
|
||||
use alloy_dyn_abi::TypedData;
|
||||
use alloy_eips::{eip2718::Encodable2718, BlockId};
|
||||
use alloy_network::TransactionBuilder;
|
||||
@ -199,8 +199,8 @@ pub trait EthTransactions: LoadTransaction<Provider: BlockReaderIdExt> {
|
||||
async move {
|
||||
if let Some(block) = self.block_with_senders(block_id).await? {
|
||||
let block_hash = block.hash();
|
||||
let block_number = block.number;
|
||||
let base_fee_per_gas = block.base_fee_per_gas;
|
||||
let block_number = block.number();
|
||||
let base_fee_per_gas = block.base_fee_per_gas();
|
||||
if let Some((signer, tx)) = block.transactions_with_sender().nth(index) {
|
||||
let tx_info = TransactionInfo {
|
||||
hash: Some(tx.hash()),
|
||||
@ -275,8 +275,8 @@ pub trait EthTransactions: LoadTransaction<Provider: BlockReaderIdExt> {
|
||||
.await?
|
||||
.and_then(|block| {
|
||||
let block_hash = block.hash();
|
||||
let block_number = block.number;
|
||||
let base_fee_per_gas = block.base_fee_per_gas;
|
||||
let block_number = block.number();
|
||||
let base_fee_per_gas = block.base_fee_per_gas();
|
||||
|
||||
block
|
||||
.transactions_with_sender()
|
||||
|
||||
Reference in New Issue
Block a user