Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion crates/optimism/rpc/src/eth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use reth_rpc::eth::{core::EthApiInner, DevSigner};
use reth_rpc_eth_api::{
helpers::{
pending_block::BuildPendingEnv, spec::SignersForApi, AddDevSigners, EthApiSpec, EthFees,
EthState, LoadFee, LoadState, SpawnBlocking, Trace,
EthState, LoadFee, LoadPendingBlock, LoadState, SpawnBlocking, Trace,
},
EthApiTypes, FromEvmError, FullEthApiServer, RpcConvert, RpcConverter, RpcNodeCore,
RpcNodeCoreExt, RpcTypes, SignableTxRequest,
Expand Down Expand Up @@ -210,13 +210,15 @@ impl<N, Rpc> LoadState for OpEthApi<N, Rpc>
where
N: RpcNodeCore,
Rpc: RpcConvert<Primitives = N::Primitives>,
Self: LoadPendingBlock,
{
}

impl<N, Rpc> EthState for OpEthApi<N, Rpc>
where
N: RpcNodeCore,
Rpc: RpcConvert<Primitives = N::Primitives>,
Self: LoadPendingBlock,
{
#[inline]
fn max_proof_window(&self) -> u64 {
Expand Down
36 changes: 29 additions & 7 deletions crates/rpc/rpc-eth-api/src/helpers/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ use alloy_serde::JsonStorageKey;
use futures::Future;
use reth_errors::RethError;
use reth_evm::{ConfigureEvm, EvmEnvFor};
use reth_rpc_eth_types::{EthApiError, PendingBlockEnv, RpcInvalidTransactionError};
use reth_rpc_convert::RpcConvert;
use reth_rpc_eth_types::{
error::FromEvmError, EthApiError, PendingBlockEnv, RpcInvalidTransactionError,
};
use reth_storage_api::{
BlockIdReader, BlockNumReader, StateProvider, StateProviderBox, StateProviderFactory,
};
use reth_transaction_pool::TransactionPool;
use std::future;

/// Helper methods for `eth_` methods relating to state (accounts).
pub trait EthState: LoadState + SpawnBlocking {
Expand Down Expand Up @@ -195,7 +197,13 @@ pub trait EthState: LoadState + SpawnBlocking {
/// Loads state from database.
///
/// Behaviour shared by several `eth_` RPC methods, not exclusive to `eth_` state RPC methods.
pub trait LoadState: EthApiTypes + RpcNodeCoreExt {
pub trait LoadState:
LoadPendingBlock
+ EthApiTypes<
Error: FromEvmError<Self::Evm> + FromEthApiError,
RpcConvert: RpcConvert<Network = Self::NetworkTypes>,
> + RpcNodeCoreExt
{
/// Returns the state at the given block number
fn state_at_hash(&self, block_hash: B256) -> Result<StateProviderBox, Self::Error> {
self.provider().history_by_block_hash(block_hash).map_err(Self::Error::from_eth_err)
Expand All @@ -208,8 +216,19 @@ pub trait LoadState: EthApiTypes + RpcNodeCoreExt {
fn state_at_block_id(
&self,
at: BlockId,
) -> impl Future<Output = Result<StateProviderBox, Self::Error>> + Send {
future::ready(self.provider().state_by_block_id(at).map_err(Self::Error::from_eth_err))
) -> impl Future<Output = Result<StateProviderBox, Self::Error>> + Send
where
Self: SpawnBlocking,
{
async move {
if at.is_pending() {
if let Ok(Some(state)) = self.local_pending_state().await {
return Ok(state)
}
}

self.provider().state_by_block_id(at).map_err(Self::Error::from_eth_err)
Comment on lines +224 to +230
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will no ignore the real pending state right?

hmm, this is a bit tricky because we don't have a nice way to obtain just the optional pending state from the provider, only if the real pending block exists, but imo we could ignore this case for now and then add this functionality separately as an additional optional fn to:

/// Storage provider for pending state.
///
/// Represents the state at the block that extends the canonical chain by one.
/// If there's no `pending` block, then this is equal to [`StateProviderFactory::latest`]
fn pending(&self) -> ProviderResult<StateProviderBox>;

as fn maybe_pending?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, this won't ignore the real pending state.

However, the local_pending_state only returns the pool-based pending state, not the real pending state.

}
}

/// Returns the _latest_ state
Expand All @@ -223,7 +242,10 @@ pub trait LoadState: EthApiTypes + RpcNodeCoreExt {
fn state_at_block_id_or_latest(
&self,
block_id: Option<BlockId>,
) -> impl Future<Output = Result<StateProviderBox, Self::Error>> + Send {
) -> impl Future<Output = Result<StateProviderBox, Self::Error>> + Send
where
Self: SpawnBlocking,
{
async move {
if let Some(block_id) = block_id {
self.state_at_block_id(block_id).await
Expand All @@ -244,7 +266,7 @@ pub trait LoadState: EthApiTypes + RpcNodeCoreExt {
at: BlockId,
) -> impl Future<Output = Result<(EvmEnvFor<Self::Evm>, BlockId), Self::Error>> + Send
where
Self: LoadPendingBlock + SpawnBlocking,
Self: SpawnBlocking,
{
async move {
if at.is_pending() {
Expand Down
7 changes: 4 additions & 3 deletions crates/rpc/rpc/src/eth/helpers/state.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
//! Contains RPC handler implementations specific to state.

use crate::EthApi;
use reth_rpc_convert::RpcConvert;
use reth_rpc_eth_api::{
helpers::{EthState, LoadState},
helpers::{EthState, LoadPendingBlock, LoadState},
RpcNodeCore,
};

use crate::EthApi;

impl<N, Rpc> EthState for EthApi<N, Rpc>
where
N: RpcNodeCore,
Rpc: RpcConvert<Primitives = N::Primitives>,
Self: LoadPendingBlock,
{
fn max_proof_window(&self) -> u64 {
self.inner.eth_proof_window()
Expand All @@ -22,6 +22,7 @@ impl<N, Rpc> LoadState for EthApi<N, Rpc>
where
N: RpcNodeCore,
Rpc: RpcConvert<Primitives = N::Primitives>,
Self: LoadPendingBlock,
{
}

Expand Down