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,
10};
11use reth_rpc_eth_types::{
12 block::BlockAndReceipts, builder::config::PendingBlockKind, error::FromEthApiError,
13 EthApiError, PendingBlock,
14};
15use reth_storage_api::{
16 BlockReader, BlockReaderIdExt, ReceiptProvider, StateProviderBox, StateProviderFactory,
17};
18use std::sync::Arc;
19
20impl<N, Rpc> LoadPendingBlock for OpEthApi<N, Rpc>
21where
22 N: RpcNodeCore,
23 OpEthApiError: FromEvmError<N::Evm>,
24 Rpc: RpcConvert<Primitives = N::Primitives>,
25{
26 #[inline]
27 fn pending_block(&self) -> &tokio::sync::Mutex<Option<PendingBlock<N::Primitives>>> {
28 self.inner.eth_api.pending_block()
29 }
30
31 #[inline]
32 fn pending_env_builder(&self) -> &dyn PendingEnvBuilder<Self::Evm> {
33 self.inner.eth_api.pending_env_builder()
34 }
35
36 #[inline]
37 fn pending_block_kind(&self) -> PendingBlockKind {
38 self.inner.eth_api.pending_block_kind()
39 }
40
41 async fn local_pending_block(
43 &self,
44 ) -> Result<Option<BlockAndReceipts<Self::Primitives>>, Self::Error> {
45 if let Ok(Some(pending)) = self.pending_flashblock().await {
46 return Ok(Some(pending.into_block_and_receipts()));
47 }
48
49 let latest = self
51 .provider()
52 .latest_header()?
53 .ok_or(EthApiError::HeaderNotFound(BlockNumberOrTag::Latest.into()))?;
54 let block_id = latest.hash().into();
55 let block = self
56 .provider()
57 .recovered_block(block_id, Default::default())?
58 .ok_or(EthApiError::HeaderNotFound(block_id.into()))?;
59
60 let receipts = self
61 .provider()
62 .receipts_by_block(block_id)?
63 .ok_or(EthApiError::ReceiptsNotFound(block_id.into()))?;
64
65 Ok(Some(BlockAndReceipts { block: Arc::new(block), receipts: Arc::new(receipts) }))
66 }
67
68 async fn local_pending_state(&self) -> Result<Option<StateProviderBox>, Self::Error>
70 where
71 Self: SpawnBlocking,
72 {
73 let Ok(Some(pending_block)) = self.pending_flashblock().await else {
74 return Ok(None);
75 };
76
77 let latest_historical = self
78 .provider()
79 .history_by_block_hash(pending_block.block().parent_hash())
80 .map_err(Self::Error::from_eth_err)?;
81
82 let state = BlockState::from(pending_block);
83
84 Ok(Some(Box::new(state.state_provider(latest_historical)) as StateProviderBox))
85 }
86}