perf(rpc): use cache for latest block and receipts (#19483)

This commit is contained in:
Matthias Seitz
2025-11-04 11:08:52 +01:00
committed by GitHub
parent 44e99e56f0
commit 6021a68dab

View File

@@ -6,16 +6,13 @@ use alloy_eips::BlockNumberOrTag;
use reth_chain_state::BlockState;
use reth_rpc_eth_api::{
helpers::{pending_block::PendingEnvBuilder, LoadPendingBlock, SpawnBlocking},
FromEvmError, RpcConvert, RpcNodeCore,
FromEvmError, RpcConvert, RpcNodeCore, RpcNodeCoreExt,
};
use reth_rpc_eth_types::{
block::BlockAndReceipts, builder::config::PendingBlockKind, error::FromEthApiError,
EthApiError, PendingBlock,
};
use reth_storage_api::{
BlockReader, BlockReaderIdExt, ReceiptProvider, StateProviderBox, StateProviderFactory,
};
use std::sync::Arc;
use reth_storage_api::{BlockReaderIdExt, StateProviderBox, StateProviderFactory};
impl<N, Rpc> LoadPendingBlock for OpEthApi<N, Rpc>
where
@@ -38,33 +35,6 @@ where
self.inner.eth_api.pending_block_kind()
}
/// Returns the locally built pending block
async fn local_pending_block(
&self,
) -> Result<Option<BlockAndReceipts<Self::Primitives>>, Self::Error> {
if let Ok(Some(pending)) = self.pending_flashblock().await {
return Ok(Some(pending.into_block_and_receipts()));
}
// See: <https://github.com/ethereum-optimism/op-geth/blob/f2e69450c6eec9c35d56af91389a1c47737206ca/miner/worker.go#L367-L375>
let latest = self
.provider()
.latest_header()?
.ok_or(EthApiError::HeaderNotFound(BlockNumberOrTag::Latest.into()))?;
let block_id = latest.hash().into();
let block = self
.provider()
.recovered_block(block_id, Default::default())?
.ok_or(EthApiError::HeaderNotFound(block_id.into()))?;
let receipts = self
.provider()
.receipts_by_block(block_id)?
.ok_or(EthApiError::ReceiptsNotFound(block_id.into()))?;
Ok(Some(BlockAndReceipts { block: Arc::new(block), receipts: Arc::new(receipts) }))
}
/// Returns a [`StateProviderBox`] on a mem-pool built pending block overlaying latest.
async fn local_pending_state(&self) -> Result<Option<StateProviderBox>, Self::Error>
where
@@ -83,4 +53,27 @@ where
Ok(Some(Box::new(state.state_provider(latest_historical)) as StateProviderBox))
}
/// Returns the locally built pending block
async fn local_pending_block(
&self,
) -> Result<Option<BlockAndReceipts<Self::Primitives>>, Self::Error> {
if let Ok(Some(pending)) = self.pending_flashblock().await {
return Ok(Some(pending.into_block_and_receipts()));
}
// See: <https://github.com/ethereum-optimism/op-geth/blob/f2e69450c6eec9c35d56af91389a1c47737206ca/miner/worker.go#L367-L375>
let latest = self
.provider()
.latest_header()?
.ok_or(EthApiError::HeaderNotFound(BlockNumberOrTag::Latest.into()))?;
let latest = self
.cache()
.get_block_and_receipts(latest.hash())
.await
.map_err(Self::Error::from_eth_err)?
.map(|(block, receipts)| BlockAndReceipts { block, receipts });
Ok(latest)
}
}