reth_optimism_rpc/eth/
pending_block.rs1use crate::{OpEthApi, OpEthApiError};
4use alloy_consensus::BlockHeader;
5use alloy_eips::BlockNumberOrTag;
6use reth_chain_state::BlockState;
7use reth_rpc_eth_api::{
8 helpers::{pending_block::PendingEnvBuilder, LoadPendingBlock, SpawnBlocking},
9 FromEvmError, RpcConvert, RpcNodeCore, RpcNodeCoreExt,
10};
11use reth_rpc_eth_types::{
12 block::BlockAndReceipts, builder::config::PendingBlockKind, error::FromEthApiError,
13 EthApiError, PendingBlock,
14};
15use reth_storage_api::{BlockReaderIdExt, StateProviderBox, StateProviderFactory};
16
17impl<N, Rpc> LoadPendingBlock for OpEthApi<N, Rpc>
18where
19 N: RpcNodeCore,
20 OpEthApiError: FromEvmError<N::Evm>,
21 Rpc: RpcConvert<Primitives = N::Primitives, Error = OpEthApiError>,
22{
23 #[inline]
24 fn pending_block(&self) -> &tokio::sync::Mutex<Option<PendingBlock<N::Primitives>>> {
25 self.inner.eth_api.pending_block()
26 }
27
28 #[inline]
29 fn pending_env_builder(&self) -> &dyn PendingEnvBuilder<Self::Evm> {
30 self.inner.eth_api.pending_env_builder()
31 }
32
33 #[inline]
34 fn pending_block_kind(&self) -> PendingBlockKind {
35 self.inner.eth_api.pending_block_kind()
36 }
37
38 async fn local_pending_state(&self) -> Result<Option<StateProviderBox>, Self::Error>
40 where
41 Self: SpawnBlocking,
42 {
43 let Ok(Some(pending_block)) = self.pending_flashblock().await else {
44 return Ok(None);
45 };
46
47 let latest_historical = self
48 .provider()
49 .history_by_block_hash(pending_block.block().parent_hash())
50 .map_err(Self::Error::from_eth_err)?;
51
52 let state = BlockState::from(pending_block);
53
54 Ok(Some(Box::new(state.state_provider(latest_historical)) as StateProviderBox))
55 }
56
57 async fn local_pending_block(
59 &self,
60 ) -> Result<Option<BlockAndReceipts<Self::Primitives>>, Self::Error> {
61 if let Ok(Some(pending)) = self.pending_flashblock().await {
62 return Ok(Some(pending.into_block_and_receipts()));
63 }
64
65 let latest = self
67 .provider()
68 .latest_header()?
69 .ok_or(EthApiError::HeaderNotFound(BlockNumberOrTag::Latest.into()))?;
70
71 let latest = self
72 .cache()
73 .get_block_and_receipts(latest.hash())
74 .await
75 .map_err(Self::Error::from_eth_err)?
76 .map(|(block, receipts)| BlockAndReceipts { block, receipts });
77 Ok(latest)
78 }
79}