mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
fix: use pending block tag for actual pending block (#4966)
This commit is contained in:
@ -263,8 +263,9 @@ where
|
|||||||
|
|
||||||
let mut cfg = CfgEnv::default();
|
let mut cfg = CfgEnv::default();
|
||||||
let mut block_env = BlockEnv::default();
|
let mut block_env = BlockEnv::default();
|
||||||
self.provider().fill_block_env_with_header(&mut block_env, origin.header())?;
|
// Note: for the PENDING block we assume it is past the known merge block and thus this will
|
||||||
self.provider().fill_cfg_env_with_header(&mut cfg, origin.header())?;
|
// not fail when looking up the total difficulty value for the blockenv.
|
||||||
|
self.provider().fill_env_with_header(&mut cfg, &mut block_env, origin.header())?;
|
||||||
|
|
||||||
Ok(PendingBlockEnv { cfg, block_env, origin })
|
Ok(PendingBlockEnv { cfg, block_env, origin })
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,8 +4,8 @@ use crate::eth::error::{EthApiError, EthResult};
|
|||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
constants::{eip4844::MAX_DATA_GAS_PER_BLOCK, BEACON_NONCE},
|
constants::{eip4844::MAX_DATA_GAS_PER_BLOCK, BEACON_NONCE},
|
||||||
proofs, Block, ChainSpec, Header, IntoRecoveredTransaction, Receipt, Receipts, SealedBlock,
|
proofs, Block, BlockId, BlockNumberOrTag, ChainSpec, Header, IntoRecoveredTransaction, Receipt,
|
||||||
SealedHeader, B256, EMPTY_OMMER_ROOT, U256,
|
Receipts, SealedBlock, SealedHeader, B256, EMPTY_OMMER_ROOT, U256,
|
||||||
};
|
};
|
||||||
use reth_provider::{BundleStateWithReceipts, ChainSpecProvider, StateProviderFactory};
|
use reth_provider::{BundleStateWithReceipts, ChainSpecProvider, StateProviderFactory};
|
||||||
use reth_revm::{
|
use reth_revm::{
|
||||||
@ -305,7 +305,18 @@ impl PendingBlockEnvOrigin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the hash of the pending block should be built on
|
/// Returns the [BlockId] that represents the state of the block.
|
||||||
|
///
|
||||||
|
/// If this is the actual pending block, the state is the "Pending" tag, otherwise we can safely
|
||||||
|
/// identify the block by its hash.
|
||||||
|
pub(crate) fn state_block_id(&self) -> BlockId {
|
||||||
|
match self {
|
||||||
|
PendingBlockEnvOrigin::ActualPending(_) => BlockNumberOrTag::Pending.into(),
|
||||||
|
PendingBlockEnvOrigin::DerivedFromLatest(header) => BlockId::Hash(header.hash.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the hash of the block the pending block should be built on.
|
||||||
fn build_target_hash(&self) -> B256 {
|
fn build_target_hash(&self) -> B256 {
|
||||||
match self {
|
match self {
|
||||||
PendingBlockEnvOrigin::ActualPending(block) => block.parent_hash,
|
PendingBlockEnvOrigin::ActualPending(block) => block.parent_hash,
|
||||||
|
|||||||
@ -69,8 +69,10 @@ pub trait EthTransactions: Send + Sync {
|
|||||||
|
|
||||||
/// Returns the revm evm env for the requested [BlockId]
|
/// Returns the revm evm env for the requested [BlockId]
|
||||||
///
|
///
|
||||||
/// If the [BlockId] this will return the [BlockId::Hash] of the block the env was configured
|
/// If the [BlockId] this will return the [BlockId] of the block the env was configured
|
||||||
/// for.
|
/// for.
|
||||||
|
/// If the [BlockId] is pending, this will return the "Pending" tag, otherwise this returns the
|
||||||
|
/// hash of the exact block.
|
||||||
async fn evm_env_at(&self, at: BlockId) -> EthResult<(CfgEnv, BlockEnv, BlockId)>;
|
async fn evm_env_at(&self, at: BlockId) -> EthResult<(CfgEnv, BlockEnv, BlockId)>;
|
||||||
|
|
||||||
/// Returns the revm evm env for the raw block header
|
/// Returns the revm evm env for the raw block header
|
||||||
@ -279,7 +281,7 @@ where
|
|||||||
async fn evm_env_at(&self, at: BlockId) -> EthResult<(CfgEnv, BlockEnv, BlockId)> {
|
async fn evm_env_at(&self, at: BlockId) -> EthResult<(CfgEnv, BlockEnv, BlockId)> {
|
||||||
if at.is_pending() {
|
if at.is_pending() {
|
||||||
let PendingBlockEnv { cfg, block_env, origin } = self.pending_block_env_and_cfg()?;
|
let PendingBlockEnv { cfg, block_env, origin } = self.pending_block_env_and_cfg()?;
|
||||||
Ok((cfg, block_env, origin.header().hash.into()))
|
Ok((cfg, block_env, origin.state_block_id()))
|
||||||
} else {
|
} else {
|
||||||
// Use cached values if there is no pending block
|
// Use cached values if there is no pending block
|
||||||
let block_hash = self
|
let block_hash = self
|
||||||
|
|||||||
@ -521,14 +521,20 @@ where
|
|||||||
state
|
state
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Storage provider for pending state.
|
/// Returns the state provider for pending state.
|
||||||
|
///
|
||||||
|
/// If there's no pending block available then the latest state provider is returned:
|
||||||
|
/// [Self::latest]
|
||||||
fn pending(&self) -> RethResult<StateProviderBox<'_>> {
|
fn pending(&self) -> RethResult<StateProviderBox<'_>> {
|
||||||
trace!(target: "providers::blockchain", "Getting provider for pending state");
|
trace!(target: "providers::blockchain", "Getting provider for pending state");
|
||||||
|
|
||||||
if let Some(block) = self.tree.pending_block_num_hash() {
|
if let Some(block) = self.tree.pending_block_num_hash() {
|
||||||
let pending = self.tree.pending_state_provider(block.hash)?;
|
if let Ok(pending) = self.tree.pending_state_provider(block.hash) {
|
||||||
return self.pending_with_provider(pending)
|
return self.pending_with_provider(pending)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fallback to latest state if the pending block is not available
|
||||||
self.latest()
|
self.latest()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -107,7 +107,8 @@ pub trait StateProviderFactory: BlockIdReader + Send + Sync {
|
|||||||
|
|
||||||
/// Returns a [StateProvider] indexed by the given [BlockId].
|
/// Returns a [StateProvider] indexed by the given [BlockId].
|
||||||
///
|
///
|
||||||
/// Note: if a number or hash is provided this will only look at historical(canonical) state.
|
/// Note: if a number or hash is provided this will __only__ look at historical(canonical)
|
||||||
|
/// state.
|
||||||
fn state_by_block_id(&self, block_id: BlockId) -> RethResult<StateProviderBox<'_>> {
|
fn state_by_block_id(&self, block_id: BlockId) -> RethResult<StateProviderBox<'_>> {
|
||||||
match block_id {
|
match block_id {
|
||||||
BlockId::Number(block_number) => self.state_by_block_number_or_tag(block_number),
|
BlockId::Number(block_number) => self.state_by_block_number_or_tag(block_number),
|
||||||
|
|||||||
Reference in New Issue
Block a user