reth_optimism_rpc/eth/
pending_block.rs1use crate::OpEthApi;
4use alloy_consensus::BlockHeader;
5use alloy_eips::BlockNumberOrTag;
6use alloy_primitives::B256;
7use reth_chainspec::EthChainSpec;
8use reth_evm::execute::BlockExecutionStrategyFactory;
9use reth_node_api::NodePrimitives;
10use reth_optimism_evm::OpNextBlockEnvAttributes;
11use reth_optimism_forks::OpHardforks;
12use reth_optimism_primitives::{OpBlock, OpReceipt, OpTransactionSigned};
13use reth_primitives::{RecoveredBlock, SealedHeader};
14use reth_provider::{
15 BlockReader, BlockReaderIdExt, ChainSpecProvider, ProviderBlock, ProviderHeader,
16 ProviderReceipt, ProviderTx, ReceiptProvider, StateProviderFactory,
17};
18use reth_rpc_eth_api::{
19 helpers::{LoadPendingBlock, SpawnBlocking},
20 types::RpcTypes,
21 EthApiTypes, FromEthApiError, FromEvmError, RpcNodeCore,
22};
23use reth_rpc_eth_types::{EthApiError, PendingBlock};
24use reth_transaction_pool::{PoolTransaction, TransactionPool};
25
26impl<N> LoadPendingBlock for OpEthApi<N>
27where
28 Self: SpawnBlocking
29 + EthApiTypes<
30 NetworkTypes: RpcTypes<
31 Header = alloy_rpc_types_eth::Header<ProviderHeader<Self::Provider>>,
32 >,
33 Error: FromEvmError<Self::Evm>,
34 >,
35 N: RpcNodeCore<
36 Provider: BlockReaderIdExt<
37 Transaction = OpTransactionSigned,
38 Block = OpBlock,
39 Receipt = OpReceipt,
40 Header = reth_primitives::Header,
41 > + ChainSpecProvider<ChainSpec: EthChainSpec + OpHardforks>
42 + StateProviderFactory,
43 Pool: TransactionPool<Transaction: PoolTransaction<Consensus = ProviderTx<N::Provider>>>,
44 Evm: BlockExecutionStrategyFactory<
45 Primitives: NodePrimitives<
46 SignedTx = ProviderTx<Self::Provider>,
47 BlockHeader = ProviderHeader<Self::Provider>,
48 Receipt = ProviderReceipt<Self::Provider>,
49 Block = ProviderBlock<Self::Provider>,
50 >,
51 NextBlockEnvCtx = OpNextBlockEnvAttributes,
52 >,
53 >,
54{
55 #[inline]
56 fn pending_block(
57 &self,
58 ) -> &tokio::sync::Mutex<
59 Option<PendingBlock<ProviderBlock<Self::Provider>, ProviderReceipt<Self::Provider>>>,
60 > {
61 self.inner.eth_api.pending_block()
62 }
63
64 fn next_env_attributes(
65 &self,
66 parent: &SealedHeader<ProviderHeader<Self::Provider>>,
67 ) -> Result<<Self::Evm as reth_evm::ConfigureEvmEnv>::NextBlockEnvCtx, Self::Error> {
68 Ok(OpNextBlockEnvAttributes {
69 timestamp: parent.timestamp().saturating_add(12),
70 suggested_fee_recipient: parent.beneficiary(),
71 prev_randao: B256::random(),
72 gas_limit: parent.gas_limit(),
73 parent_beacon_block_root: parent.parent_beacon_block_root(),
74 extra_data: parent.extra_data.clone(),
75 })
76 }
77
78 async fn local_pending_block(
80 &self,
81 ) -> Result<
82 Option<(
83 RecoveredBlock<ProviderBlock<Self::Provider>>,
84 Vec<ProviderReceipt<Self::Provider>>,
85 )>,
86 Self::Error,
87 > {
88 let latest = self
90 .provider()
91 .latest_header()
92 .map_err(Self::Error::from_eth_err)?
93 .ok_or(EthApiError::HeaderNotFound(BlockNumberOrTag::Latest.into()))?;
94 let block_id = latest.hash().into();
95 let block = self
96 .provider()
97 .block_with_senders(block_id, Default::default())
98 .map_err(Self::Error::from_eth_err)?
99 .ok_or(EthApiError::HeaderNotFound(block_id.into()))?;
100
101 let receipts = self
102 .provider()
103 .receipts_by_block(block_id)
104 .map_err(Self::Error::from_eth_err)?
105 .ok_or(EthApiError::ReceiptsNotFound(block_id.into()))?;
106
107 Ok(Some((block, receipts)))
108 }
109}