reth_optimism_rpc/eth/
pending_block.rs

1//! Loads OP pending block for a RPC response.
2
3use std::sync::Arc;
4
5use crate::{OpEthApi, OpEthApiError};
6use alloy_eips::BlockNumberOrTag;
7use reth_primitives_traits::RecoveredBlock;
8use reth_rpc_eth_api::{
9    helpers::{pending_block::PendingEnvBuilder, LoadPendingBlock},
10    FromEvmError, RpcConvert, RpcNodeCore,
11};
12use reth_rpc_eth_types::{builder::config::PendingBlockKind, EthApiError, PendingBlock};
13use reth_storage_api::{
14    BlockReader, BlockReaderIdExt, ProviderBlock, ProviderReceipt, ReceiptProvider,
15};
16
17impl<N, Rpc> LoadPendingBlock for OpEthApi<N, Rpc>
18where
19    N: RpcNodeCore,
20    OpEthApiError: FromEvmError<N::Evm>,
21    Rpc: RpcConvert<Primitives = N::Primitives>,
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    /// Returns the locally built pending block
39    async fn local_pending_block(
40        &self,
41    ) -> Result<
42        Option<(
43            Arc<RecoveredBlock<ProviderBlock<Self::Provider>>>,
44            Arc<Vec<ProviderReceipt<Self::Provider>>>,
45        )>,
46        Self::Error,
47    > {
48        if let Ok(Some(block)) = self.pending_flashblock() {
49            return Ok(Some(block));
50        }
51
52        // See: <https://github.com/ethereum-optimism/op-geth/blob/f2e69450c6eec9c35d56af91389a1c47737206ca/miner/worker.go#L367-L375>
53        let latest = self
54            .provider()
55            .latest_header()?
56            .ok_or(EthApiError::HeaderNotFound(BlockNumberOrTag::Latest.into()))?;
57        let block_id = latest.hash().into();
58        let block = self
59            .provider()
60            .recovered_block(block_id, Default::default())?
61            .ok_or(EthApiError::HeaderNotFound(block_id.into()))?;
62
63        let receipts = self
64            .provider()
65            .receipts_by_block(block_id)?
66            .ok_or(EthApiError::ReceiptsNotFound(block_id.into()))?;
67
68        Ok(Some((Arc::new(block), Arc::new(receipts))))
69    }
70}