feat: add header AT to provider (#13030)

Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
This commit is contained in:
Matthias Seitz
2024-12-02 14:24:48 +01:00
committed by GitHub
parent 519a10ae99
commit 332cce1f9b
71 changed files with 669 additions and 434 deletions

View File

@ -29,8 +29,11 @@ pub struct EthHandlers<Provider, Pool, Network, Events, EthApi: EthApiTypes> {
impl<Provider, Pool, Network, Events, EthApi> EthHandlers<Provider, Pool, Network, Events, EthApi>
where
Provider: StateProviderFactory
+ BlockReader<Block = reth_primitives::Block, Receipt = reth_primitives::Receipt>
+ EvmEnvProvider
+ BlockReader<
Block = reth_primitives::Block,
Receipt = reth_primitives::Receipt,
Header = reth_primitives::Header,
> + EvmEnvProvider
+ Clone
+ Unpin
+ 'static,

View File

@ -41,6 +41,7 @@
//! Transaction = TransactionSigned,
//! Block = reth_primitives::Block,
//! Receipt = reth_primitives::Receipt,
//! Header = reth_primitives::Header,
//! > + AccountReader
//! + ChangeSetReader,
//! Pool: TransactionPool + Unpin + 'static,
@ -121,6 +122,7 @@
//! Transaction = TransactionSigned,
//! Block = reth_primitives::Block,
//! Receipt = reth_primitives::Receipt,
//! Header = reth_primitives::Header,
//! > + AccountReader
//! + ChangeSetReader,
//! Pool: TransactionPool + Unpin + 'static,
@ -201,7 +203,7 @@ use reth_network_api::{noop::NoopNetwork, NetworkInfo, Peers};
use reth_primitives::{EthPrimitives, NodePrimitives};
use reth_provider::{
AccountReader, BlockReader, CanonStateSubscriptions, ChainSpecProvider, ChangeSetReader,
EvmEnvProvider, FullRpcProvider, ReceiptProvider, StateProviderFactory,
EvmEnvProvider, FullRpcProvider, HeaderProvider, ReceiptProvider, StateProviderFactory,
};
use reth_rpc::{
AdminApi, DebugApi, EngineEthApi, EthBundle, NetApi, OtterscanApi, RPCApi, RethApi, TraceApi,
@ -269,8 +271,11 @@ pub async fn launch<Provider, Pool, Network, Tasks, Events, EvmConfig, EthApi, B
consensus: Arc<dyn FullConsensus>,
) -> Result<RpcServerHandle, RpcError>
where
Provider: FullRpcProvider<Block = reth_primitives::Block, Receipt = reth_primitives::Receipt>
+ AccountReader
Provider: FullRpcProvider<
Block = reth_primitives::Block,
Receipt = reth_primitives::Receipt,
Header = reth_primitives::Header,
> + AccountReader
+ ChangeSetReader,
Pool: TransactionPool + 'static,
Network: NetworkInfo + Peers + Clone + 'static,
@ -667,6 +672,7 @@ where
Provider: BlockReader<
Block = <EthApi::Provider as BlockReader>::Block,
Receipt = <EthApi::Provider as ReceiptProvider>::Receipt,
Header = <EthApi::Provider as HeaderProvider>::Header,
>,
{
let Self {
@ -743,7 +749,11 @@ where
) -> RpcRegistryInner<Provider, Pool, Network, Tasks, Events, EthApi, BlockExecutor, Consensus>
where
EthApi: EthApiTypes + 'static,
Provider: BlockReader<Block = reth_primitives::Block, Receipt = reth_primitives::Receipt>,
Provider: BlockReader<
Block = reth_primitives::Block,
Receipt = reth_primitives::Receipt,
Header = reth_primitives::Header,
>,
{
let Self {
provider,
@ -781,6 +791,7 @@ where
Provider: BlockReader<
Block = <EthApi::Provider as BlockReader>::Block,
Receipt = <EthApi::Provider as ReceiptProvider>::Receipt,
Header = <EthApi::Provider as HeaderProvider>::Header,
>,
{
let mut modules = TransportRpcModules::default();
@ -940,8 +951,11 @@ impl<Provider, Pool, Network, Tasks, Events, EthApi, BlockExecutor, Consensus>
RpcRegistryInner<Provider, Pool, Network, Tasks, Events, EthApi, BlockExecutor, Consensus>
where
Provider: StateProviderFactory
+ BlockReader<Block = reth_primitives::Block, Receipt = reth_primitives::Receipt>
+ EvmEnvProvider
+ BlockReader<
Block = reth_primitives::Block,
Receipt = reth_primitives::Receipt,
Header = reth_primitives::Header,
> + EvmEnvProvider
+ Clone
+ Unpin
+ 'static,
@ -1311,6 +1325,7 @@ where
Provider: FullRpcProvider<
Block = <EthApi::Provider as BlockReader>::Block,
Receipt = <EthApi::Provider as ReceiptProvider>::Receipt,
Header = <EthApi::Provider as HeaderProvider>::Header,
> + AccountReader
+ ChangeSetReader,
Pool: TransactionPool + 'static,

View File

@ -163,11 +163,11 @@ pub trait EthFees: LoadFee {
for header in &headers {
base_fee_per_gas.push(header.base_fee_per_gas.unwrap_or_default() as u128);
gas_used_ratio.push(header.gas_used as f64 / header.gas_limit as f64);
base_fee_per_gas.push(header.base_fee_per_gas().unwrap_or_default() as u128);
gas_used_ratio.push(header.gas_used() as f64 / header.gas_limit() as f64);
base_fee_per_blob_gas.push(header.blob_fee().unwrap_or_default());
blob_gas_used_ratio.push(
header.blob_gas_used.unwrap_or_default() as f64
header.blob_gas_used().unwrap_or_default() as f64
/ alloy_eips::eip4844::MAX_DATA_GAS_PER_BLOCK as f64,
);
@ -181,8 +181,8 @@ pub trait EthFees: LoadFee {
rewards.push(
calculate_reward_percentiles_for_block(
percentiles,
header.gas_used,
header.base_fee_per_gas.unwrap_or_default(),
header.gas_used(),
header.base_fee_per_gas().unwrap_or_default(),
&block.body.transactions,
&receipts,
)
@ -198,14 +198,10 @@ pub trait EthFees: LoadFee {
// The unwrap is safe since we checked earlier that we got at least 1 header.
let last_header = headers.last().expect("is present");
base_fee_per_gas.push(
last_header.next_block_base_fee(
self.provider()
.chain_spec()
.base_fee_params_at_timestamp(last_header.timestamp)
.next_block_base_fee(
last_header.gas_used ,
last_header.gas_limit,
last_header.base_fee_per_gas.unwrap_or_default() ,
) as u128,
.base_fee_params_at_timestamp(last_header.timestamp())).unwrap_or_default() as u128
);
// Same goes for the `base_fee_per_blob_gas`:

View File

@ -3,7 +3,7 @@
use super::SpawnBlocking;
use crate::{EthApiTypes, FromEthApiError, FromEvmError, RpcNodeCore};
use alloy_consensus::{Header, EMPTY_OMMER_ROOT_HASH};
use alloy_consensus::{BlockHeader, Header, EMPTY_OMMER_ROOT_HASH};
use alloy_eips::{
eip4844::MAX_DATA_GAS_PER_BLOCK, eip7685::EMPTY_REQUESTS_HASH, merge::BEACON_NONCE,
};
@ -50,6 +50,7 @@ pub trait LoadPendingBlock:
Provider: BlockReaderIdExt<
Block = reth_primitives::Block,
Receipt = reth_primitives::Receipt,
Header = reth_primitives::Header,
> + EvmEnvProvider
+ ChainSpecProvider<ChainSpec: EthChainSpec + EthereumHardforks>
+ StateProviderFactory,
@ -88,7 +89,7 @@ pub trait LoadPendingBlock:
let chain_spec = self.provider().chain_spec();
latest_header.base_fee_per_gas = latest_header.next_block_base_fee(
chain_spec.base_fee_params_at_timestamp(latest_header.timestamp),
chain_spec.base_fee_params_at_timestamp(latest_header.timestamp()),
);
// update excess blob gas consumed above target

View File

@ -96,8 +96,11 @@ impl EthStateCache {
pub fn spawn<Provider>(provider: Provider, config: EthStateCacheConfig) -> Self
where
Provider: StateProviderFactory
+ BlockReader<Block = reth_primitives::Block, Receipt = reth_primitives::Receipt>
+ Clone
+ BlockReader<
Block = reth_primitives::Block,
Receipt = reth_primitives::Receipt,
Header = reth_primitives::Header,
> + Clone
+ Unpin
+ 'static,
{
@ -115,8 +118,11 @@ impl EthStateCache {
) -> Self
where
Provider: StateProviderFactory
+ BlockReader<Block = reth_primitives::Block, Receipt = reth_primitives::Receipt>
+ Clone
+ BlockReader<
Block = reth_primitives::Block,
Receipt = reth_primitives::Receipt,
Header = reth_primitives::Header,
> + Clone
+ Unpin
+ 'static,
Tasks: TaskSpawner + Clone + 'static,
@ -331,8 +337,11 @@ where
impl<Provider, Tasks> Future for EthStateCacheService<Provider, Tasks>
where
Provider: StateProviderFactory
+ BlockReader<Block = reth_primitives::Block, Receipt = reth_primitives::Receipt>
+ Clone
+ BlockReader<
Block = reth_primitives::Block,
Receipt = reth_primitives::Receipt,
Header = reth_primitives::Header,
> + Clone
+ Unpin
+ 'static,
Tasks: TaskSpawner + Clone + 'static,

View File

@ -1,7 +1,7 @@
//! An implementation of the eth gas price oracle, used for providing gas price estimates based on
//! previous blocks.
use alloy_consensus::constants::GWEI_TO_WEI;
use alloy_consensus::{constants::GWEI_TO_WEI, BlockHeader};
use alloy_eips::BlockNumberOrTag;
use alloy_primitives::{B256, U256};
use alloy_rpc_types_eth::BlockId;
@ -142,8 +142,8 @@ where
let mut populated_blocks = 0;
// we only check a maximum of 2 * max_block_history, or the number of blocks in the chain
let max_blocks = if self.oracle_config.max_block_history * 2 > header.number {
header.number
let max_blocks = if self.oracle_config.max_block_history * 2 > header.number() {
header.number()
} else {
self.oracle_config.max_block_history * 2
};

View File

@ -3,6 +3,7 @@
use std::sync::Arc;
use alloy_consensus::BlockHeader;
use alloy_eips::BlockNumberOrTag;
use alloy_network::Ethereum;
use alloy_primitives::U256;
@ -286,7 +287,7 @@ where
.header_by_number_or_tag(BlockNumberOrTag::Latest)
.ok()
.flatten()
.map(|header| header.number)
.map(|header| header.number())
.unwrap_or_default(),
);
@ -438,8 +439,11 @@ mod tests {
use crate::EthApi;
fn build_test_eth_api<
P: BlockReaderIdExt<Block = reth_primitives::Block, Receipt = reth_primitives::Receipt>
+ BlockReader
P: BlockReaderIdExt<
Block = reth_primitives::Block,
Receipt = reth_primitives::Receipt,
Header = reth_primitives::Header,
> + BlockReader
+ ChainSpecProvider<ChainSpec = ChainSpec>
+ EvmEnvProvider
+ StateProviderFactory

View File

@ -1,5 +1,6 @@
//! `eth_` `Filter` RPC handler implementation
use alloy_consensus::BlockHeader;
use alloy_primitives::TxHash;
use alloy_rpc_types_eth::{
BlockNumHash, Filter, FilterBlockOption, FilterChanges, FilterId, FilteredParams, Log,
@ -380,7 +381,7 @@ where
.header_by_hash_or_number(block_hash.into())?
.ok_or_else(|| ProviderError::HeaderNotFound(block_hash.into()))?;
let block_num_hash = BlockNumHash::new(header.number, block_hash);
let block_num_hash = BlockNumHash::new(header.number(), block_hash);
// we also need to ensure that the receipts are available and return an error if
// not, in case the block hash been reorged
@ -402,7 +403,7 @@ where
block_num_hash,
&receipts,
false,
header.timestamp,
header.timestamp(),
)?;
Ok(all_logs)
@ -483,20 +484,20 @@ where
for (idx, header) in headers.iter().enumerate() {
// only if filter matches
if FilteredParams::matches_address(header.logs_bloom, &address_filter) &&
FilteredParams::matches_topics(header.logs_bloom, &topics_filter)
if FilteredParams::matches_address(header.logs_bloom(), &address_filter) &&
FilteredParams::matches_topics(header.logs_bloom(), &topics_filter)
{
// these are consecutive headers, so we can use the parent hash of the next
// block to get the current header's hash
let block_hash = match headers.get(idx + 1) {
Some(parent) => parent.parent_hash,
Some(parent) => parent.parent_hash(),
None => self
.provider
.block_hash(header.number)?
.ok_or_else(|| ProviderError::HeaderNotFound(header.number.into()))?,
.block_hash(header.number())?
.ok_or_else(|| ProviderError::HeaderNotFound(header.number().into()))?,
};
let num_hash = BlockNumHash::new(header.number, block_hash);
let num_hash = BlockNumHash::new(header.number(), block_hash);
if let Some((receipts, maybe_block)) =
self.receipts_and_maybe_block(&num_hash, chain_info.best_number).await?
{
@ -509,7 +510,7 @@ where
num_hash,
&receipts,
false,
header.timestamp,
header.timestamp(),
)?;
// size check but only if range is multiple blocks, so we always return all

View File

@ -21,6 +21,7 @@ where
Provider: BlockReaderIdExt<
Block = reth_primitives::Block,
Receipt = reth_primitives::Receipt,
Header = reth_primitives::Header,
> + EvmEnvProvider
+ ChainSpecProvider<ChainSpec: EthChainSpec + EthereumHardforks>
+ StateProviderFactory,

View File

@ -89,7 +89,7 @@ where
impl<Provider, E> ValidationApi<Provider, E>
where
Provider: BlockReaderIdExt
Provider: BlockReaderIdExt<Header = reth_primitives::Header>
+ ChainSpecProvider<ChainSpec: EthereumHardforks>
+ StateProviderFactory
+ HeaderProvider
@ -410,7 +410,7 @@ where
#[async_trait]
impl<Provider, E> BlockSubmissionValidationApiServer for ValidationApi<Provider, E>
where
Provider: BlockReaderIdExt
Provider: BlockReaderIdExt<Header = reth_primitives::Header>
+ ChainSpecProvider<ChainSpec: EthereumHardforks>
+ StateProviderFactory
+ HeaderProvider