mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: make base fee computation parameters configurable via chain spec (#3992)
This commit is contained in:
@ -339,9 +339,10 @@ impl RpcServerArgs {
|
||||
) -> Result<AuthServerHandle, RpcError>
|
||||
where
|
||||
Provider: BlockReaderIdExt
|
||||
+ ChainSpecProvider
|
||||
+ EvmEnvProvider
|
||||
+ HeaderProvider
|
||||
+ StateProviderFactory
|
||||
+ EvmEnvProvider
|
||||
+ Clone
|
||||
+ Unpin
|
||||
+ 'static,
|
||||
|
||||
@ -273,6 +273,7 @@ mod tests {
|
||||
genesis_hash: None,
|
||||
paris_block_and_final_difficulty: None,
|
||||
deposit_contract: None,
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let db = create_test_rw_db();
|
||||
|
||||
@ -246,10 +246,16 @@ impl StorageInner {
|
||||
|
||||
/// Fills in pre-execution header fields based on the current best block and given
|
||||
/// transactions.
|
||||
pub(crate) fn build_header_template(&self, transactions: &Vec<TransactionSigned>) -> Header {
|
||||
pub(crate) fn build_header_template(
|
||||
&self,
|
||||
transactions: &Vec<TransactionSigned>,
|
||||
chain_spec: Arc<ChainSpec>,
|
||||
) -> Header {
|
||||
// check previous block for base fee
|
||||
let base_fee_per_gas =
|
||||
self.headers.get(&self.best_block).and_then(|parent| parent.next_block_base_fee());
|
||||
let base_fee_per_gas = self
|
||||
.headers
|
||||
.get(&self.best_block)
|
||||
.and_then(|parent| parent.next_block_base_fee(chain_spec.base_fee_params));
|
||||
|
||||
let mut header = Header {
|
||||
parent_hash: self.best_hash,
|
||||
@ -337,8 +343,9 @@ impl StorageInner {
|
||||
&mut self,
|
||||
transactions: Vec<TransactionSigned>,
|
||||
executor: &mut Executor<DB>,
|
||||
chain_spec: Arc<ChainSpec>,
|
||||
) -> Result<(SealedHeader, PostState), BlockExecutionError> {
|
||||
let header = self.build_header_template(&transactions);
|
||||
let header = self.build_header_template(&transactions, chain_spec);
|
||||
|
||||
let block = Block { header, body: transactions, ommers: vec![], withdrawals: None };
|
||||
|
||||
|
||||
@ -129,9 +129,10 @@ where
|
||||
|
||||
// execute the new block
|
||||
let substate = SubState::new(State::new(client.latest().unwrap()));
|
||||
let mut executor = Executor::new(chain_spec, substate);
|
||||
let mut executor = Executor::new(Arc::clone(&chain_spec), substate);
|
||||
|
||||
match storage.build_and_execute(transactions.clone(), &mut executor) {
|
||||
match storage.build_and_execute(transactions.clone(), &mut executor, chain_spec)
|
||||
{
|
||||
Ok((new_header, post_state)) => {
|
||||
// clear all transactions from pool
|
||||
pool.remove_transactions(transactions.iter().map(|tx| tx.hash()));
|
||||
|
||||
@ -271,7 +271,7 @@ pub fn validate_header_regarding_parent(
|
||||
// By consensus, gas_limit is multiplied by elasticity (*2) on
|
||||
// on exact block that hardfork happens.
|
||||
if chain_spec.fork(Hardfork::London).transitions_at_block(child.number) {
|
||||
parent_gas_limit = parent.gas_limit * constants::EIP1559_ELASTICITY_MULTIPLIER;
|
||||
parent_gas_limit = parent.gas_limit * chain_spec.base_fee_params.elasticity_multiplier;
|
||||
}
|
||||
|
||||
// Check gas limit, max diff between child/parent gas_limit should be max_diff=parent_gas/1024
|
||||
@ -298,7 +298,9 @@ pub fn validate_header_regarding_parent(
|
||||
constants::EIP1559_INITIAL_BASE_FEE
|
||||
} else {
|
||||
// This BaseFeeMissing will not happen as previous blocks are checked to have them.
|
||||
parent.next_block_base_fee().ok_or(ConsensusError::BaseFeeMissing)?
|
||||
parent
|
||||
.next_block_base_fee(chain_spec.base_fee_params)
|
||||
.ok_or(ConsensusError::BaseFeeMissing)?
|
||||
};
|
||||
if expected_base_fee != base_fee {
|
||||
return Err(ConsensusError::BaseFeeDiff { expected: expected_base_fee, got: base_fee })
|
||||
|
||||
@ -134,7 +134,9 @@ impl PayloadBuilderAttributes {
|
||||
prevrandao: Some(self.prev_randao),
|
||||
gas_limit: U256::from(parent.gas_limit),
|
||||
// calculate basefee based on parent block's gas usage
|
||||
basefee: U256::from(parent.next_block_base_fee().unwrap_or_default()),
|
||||
basefee: U256::from(
|
||||
parent.next_block_base_fee(chain_spec.base_fee_params).unwrap_or_default(),
|
||||
),
|
||||
};
|
||||
|
||||
(cfg, block_env)
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
//! Helpers for working with EIP-1559 base fee
|
||||
|
||||
use crate::constants;
|
||||
|
||||
/// Calculate base fee for next block. [EIP-1559](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md) spec
|
||||
pub fn calculate_next_block_base_fee(gas_used: u64, gas_limit: u64, base_fee: u64) -> u64 {
|
||||
let gas_target = gas_limit / constants::EIP1559_ELASTICITY_MULTIPLIER;
|
||||
|
||||
pub fn calculate_next_block_base_fee(
|
||||
gas_used: u64,
|
||||
gas_limit: u64,
|
||||
base_fee: u64,
|
||||
base_fee_params: crate::BaseFeeParams,
|
||||
) -> u64 {
|
||||
let gas_target = gas_limit / base_fee_params.elasticity_multiplier;
|
||||
if gas_used == gas_target {
|
||||
return base_fee
|
||||
}
|
||||
@ -15,14 +17,14 @@ pub fn calculate_next_block_base_fee(gas_used: u64, gas_limit: u64, base_fee: u6
|
||||
1,
|
||||
base_fee as u128 * gas_used_delta as u128 /
|
||||
gas_target as u128 /
|
||||
constants::EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR as u128,
|
||||
base_fee_params.max_change_denominator as u128,
|
||||
);
|
||||
base_fee + (base_fee_delta as u64)
|
||||
} else {
|
||||
let gas_used_delta = gas_target - gas_used;
|
||||
let base_fee_per_gas_delta = base_fee as u128 * gas_used_delta as u128 /
|
||||
gas_target as u128 /
|
||||
constants::EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR as u128;
|
||||
base_fee_params.max_change_denominator as u128;
|
||||
|
||||
base_fee.saturating_sub(base_fee_per_gas_delta as u64)
|
||||
}
|
||||
@ -54,7 +56,12 @@ mod tests {
|
||||
for i in 0..base_fee.len() {
|
||||
assert_eq!(
|
||||
next_base_fee[i],
|
||||
calculate_next_block_base_fee(gas_used[i], gas_limit[i], base_fee[i])
|
||||
calculate_next_block_base_fee(
|
||||
gas_used[i],
|
||||
gas_limit[i],
|
||||
base_fee[i],
|
||||
crate::BaseFeeParams::ethereum(),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ use std::{fmt, str::FromStr};
|
||||
// The chain spec module.
|
||||
mod spec;
|
||||
pub use spec::{
|
||||
AllGenesisFormats, ChainSpec, ChainSpecBuilder, DisplayHardforks, ForkCondition,
|
||||
AllGenesisFormats, BaseFeeParams, ChainSpec, ChainSpecBuilder, DisplayHardforks, ForkCondition,
|
||||
ForkTimestamps, DEV, GOERLI, MAINNET, SEPOLIA,
|
||||
};
|
||||
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
use crate::{
|
||||
constants::{EIP1559_INITIAL_BASE_FEE, EMPTY_WITHDRAWALS},
|
||||
constants::{
|
||||
EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR, EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
|
||||
EIP1559_INITIAL_BASE_FEE, EMPTY_WITHDRAWALS,
|
||||
},
|
||||
forkid::ForkFilterKey,
|
||||
header::Head,
|
||||
proofs::genesis_state_root,
|
||||
@ -60,6 +63,7 @@ pub static MAINNET: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
|
||||
11052984,
|
||||
H256(hex!("649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5")),
|
||||
)),
|
||||
..Default::default()
|
||||
}
|
||||
.into()
|
||||
});
|
||||
@ -100,6 +104,7 @@ pub static GOERLI: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
|
||||
4367322,
|
||||
H256(hex!("649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5")),
|
||||
)),
|
||||
..Default::default()
|
||||
}
|
||||
.into()
|
||||
});
|
||||
@ -144,6 +149,7 @@ pub static SEPOLIA: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
|
||||
1273020,
|
||||
H256(hex!("649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5")),
|
||||
)),
|
||||
..Default::default()
|
||||
}
|
||||
.into()
|
||||
});
|
||||
@ -182,10 +188,30 @@ pub static DEV: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
|
||||
(Hardfork::Shanghai, ForkCondition::Timestamp(0)),
|
||||
]),
|
||||
deposit_contract: None, // TODO: do we even have?
|
||||
..Default::default()
|
||||
}
|
||||
.into()
|
||||
});
|
||||
|
||||
/// BaseFeeParams contains the config parameters that control block base fee computation
|
||||
#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub struct BaseFeeParams {
|
||||
/// The base_fee_max_change_denominator from EIP-1559
|
||||
pub max_change_denominator: u64,
|
||||
/// The elasticity multiplier from EIP-1559
|
||||
pub elasticity_multiplier: u64,
|
||||
}
|
||||
|
||||
impl BaseFeeParams {
|
||||
/// Get the base fee parameters for ethereum mainnet
|
||||
pub const fn ethereum() -> BaseFeeParams {
|
||||
BaseFeeParams {
|
||||
max_change_denominator: EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR,
|
||||
elasticity_multiplier: EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An Ethereum chain specification.
|
||||
///
|
||||
/// A chain specification describes:
|
||||
@ -224,6 +250,24 @@ pub struct ChainSpec {
|
||||
/// The deposit contract deployed for PoS.
|
||||
#[serde(skip, default)]
|
||||
pub deposit_contract: Option<DepositContract>,
|
||||
|
||||
/// The parameters that configure how a block's base fee is computed
|
||||
pub base_fee_params: BaseFeeParams,
|
||||
}
|
||||
|
||||
impl Default for ChainSpec {
|
||||
fn default() -> ChainSpec {
|
||||
ChainSpec {
|
||||
chain: Default::default(),
|
||||
genesis_hash: Default::default(),
|
||||
genesis: Default::default(),
|
||||
paris_block_and_final_difficulty: Default::default(),
|
||||
fork_timestamps: Default::default(),
|
||||
hardforks: Default::default(),
|
||||
deposit_contract: Default::default(),
|
||||
base_fee_params: BaseFeeParams::ethereum(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ChainSpec {
|
||||
@ -457,6 +501,7 @@ impl From<Genesis> for ChainSpec {
|
||||
hardforks,
|
||||
paris_block_and_final_difficulty: None,
|
||||
deposit_contract: None,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -680,6 +725,7 @@ impl ChainSpecBuilder {
|
||||
hardforks: self.hardforks,
|
||||
paris_block_and_final_difficulty: None,
|
||||
deposit_contract: None,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,11 +37,15 @@ pub const BEACON_NONCE: u64 = 0u64;
|
||||
/// See <https://github.com/paradigmxyz/reth/issues/3233>.
|
||||
pub const ETHEREUM_BLOCK_GAS_LIMIT: u64 = 30_000_000;
|
||||
|
||||
/// The minimal value the basefee can decrease to.
|
||||
/// The minimum tx fee below which the txpool will reject the transaction.
|
||||
///
|
||||
/// The `BASE_FEE_MAX_CHANGE_DENOMINATOR` <https://eips.ethereum.org/EIPS/eip-1559> is `8`, or 12.5%.
|
||||
/// Once the base fee has dropped to `7` WEI it cannot decrease further because 12.5% of 7 is less
|
||||
/// than 1.
|
||||
/// Configured to `7` WEI which is the lowest possible value of base fee under mainnet EIP-1559
|
||||
/// parameters. `BASE_FEE_MAX_CHANGE_DENOMINATOR` <https://eips.ethereum.org/EIPS/eip-1559>
|
||||
/// is `8`, or 12.5%. Once the base fee has dropped to `7` WEI it cannot decrease further because
|
||||
/// 12.5% of 7 is less than 1.
|
||||
///
|
||||
/// Note that min base fee under different 1559 parameterizations may differ, but there's no
|
||||
/// signifant harm in leaving this setting as is.
|
||||
pub const MIN_PROTOCOL_BASE_FEE: u64 = 7;
|
||||
|
||||
/// Same as [MIN_PROTOCOL_BASE_FEE] but as a U256.
|
||||
@ -51,10 +55,10 @@ pub const MIN_PROTOCOL_BASE_FEE_U256: U256 = U256::from_limbs([7u64, 0, 0, 0]);
|
||||
pub const EIP1559_INITIAL_BASE_FEE: u64 = 1_000_000_000;
|
||||
|
||||
/// Base fee max change denominator as defined in [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)
|
||||
pub const EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR: u64 = 8;
|
||||
pub const EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR: u64 = 8;
|
||||
|
||||
/// Elasticity multiplier as defined in [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)
|
||||
pub const EIP1559_ELASTICITY_MULTIPLIER: u64 = 2;
|
||||
pub const EIP1559_DEFAULT_ELASTICITY_MULTIPLIER: u64 = 2;
|
||||
|
||||
/// Multiplier for converting gwei to wei.
|
||||
pub const GWEI_TO_WEI: u64 = 1_000_000_000;
|
||||
|
||||
@ -162,9 +162,9 @@ mod tests {
|
||||
genesis: Genesis::default(),
|
||||
genesis_hash: None,
|
||||
hardforks: BTreeMap::from([(Hardfork::Frontier, ForkCondition::Never)]),
|
||||
fork_timestamps: Default::default(),
|
||||
paris_block_and_final_difficulty: None,
|
||||
deposit_contract: None,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
assert_eq!(Hardfork::Frontier.fork_id(&spec), None);
|
||||
@ -177,9 +177,9 @@ mod tests {
|
||||
genesis: Genesis::default(),
|
||||
genesis_hash: None,
|
||||
hardforks: BTreeMap::from([(Hardfork::Shanghai, ForkCondition::Never)]),
|
||||
fork_timestamps: Default::default(),
|
||||
paris_block_and_final_difficulty: None,
|
||||
deposit_contract: None,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
assert_eq!(Hardfork::Shanghai.fork_filter(&spec), None);
|
||||
|
||||
@ -3,7 +3,8 @@ use crate::{
|
||||
blobfee::calculate_excess_blob_gas,
|
||||
keccak256,
|
||||
proofs::{EMPTY_LIST_HASH, EMPTY_ROOT},
|
||||
BlockBodyRoots, BlockHash, BlockNumHash, BlockNumber, Bloom, Bytes, H160, H256, H64, U256,
|
||||
BaseFeeParams, BlockBodyRoots, BlockHash, BlockNumHash, BlockNumber, Bloom, Bytes, H160, H256,
|
||||
H64, U256,
|
||||
};
|
||||
use bytes::{Buf, BufMut, BytesMut};
|
||||
|
||||
@ -176,8 +177,13 @@ impl Header {
|
||||
/// Calculate base fee for next block according to the EIP-1559 spec.
|
||||
///
|
||||
/// Returns a `None` if no base fee is set, no EIP-1559 support
|
||||
pub fn next_block_base_fee(&self) -> Option<u64> {
|
||||
Some(calculate_next_block_base_fee(self.gas_used, self.gas_limit, self.base_fee_per_gas?))
|
||||
pub fn next_block_base_fee(&self, base_fee_params: BaseFeeParams) -> Option<u64> {
|
||||
Some(calculate_next_block_base_fee(
|
||||
self.gas_used,
|
||||
self.gas_limit,
|
||||
self.base_fee_per_gas?,
|
||||
base_fee_params,
|
||||
))
|
||||
}
|
||||
|
||||
/// Calculate excess blob gas for the next block according to the EIP-4844 spec.
|
||||
|
||||
@ -60,8 +60,8 @@ pub use block::{
|
||||
};
|
||||
pub use bloom::Bloom;
|
||||
pub use chain::{
|
||||
AllGenesisFormats, Chain, ChainInfo, ChainSpec, ChainSpecBuilder, DisplayHardforks,
|
||||
ForkCondition, ForkTimestamps, DEV, GOERLI, MAINNET, SEPOLIA,
|
||||
AllGenesisFormats, BaseFeeParams, Chain, ChainInfo, ChainSpec, ChainSpecBuilder,
|
||||
DisplayHardforks, ForkCondition, ForkTimestamps, DEV, GOERLI, MAINNET, SEPOLIA,
|
||||
};
|
||||
pub use compression::*;
|
||||
pub use constants::{
|
||||
|
||||
@ -12,7 +12,8 @@ use jsonrpsee::{
|
||||
};
|
||||
use reth_network_api::{NetworkInfo, Peers};
|
||||
use reth_provider::{
|
||||
BlockReaderIdExt, EvmEnvProvider, HeaderProvider, ReceiptProviderIdExt, StateProviderFactory,
|
||||
BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, HeaderProvider, ReceiptProviderIdExt,
|
||||
StateProviderFactory,
|
||||
};
|
||||
use reth_rpc::{
|
||||
eth::{cache::EthStateCache, gas_oracle::GasPriceOracle},
|
||||
@ -40,10 +41,11 @@ pub async fn launch<Provider, Pool, Network, Tasks, EngineApi>(
|
||||
) -> Result<AuthServerHandle, RpcError>
|
||||
where
|
||||
Provider: BlockReaderIdExt
|
||||
+ ReceiptProviderIdExt
|
||||
+ HeaderProvider
|
||||
+ StateProviderFactory
|
||||
+ ChainSpecProvider
|
||||
+ EvmEnvProvider
|
||||
+ HeaderProvider
|
||||
+ ReceiptProviderIdExt
|
||||
+ StateProviderFactory
|
||||
+ Clone
|
||||
+ Unpin
|
||||
+ 'static,
|
||||
@ -86,9 +88,10 @@ pub async fn launch_with_eth_api<Provider, Pool, Network, EngineApi>(
|
||||
) -> Result<AuthServerHandle, RpcError>
|
||||
where
|
||||
Provider: BlockReaderIdExt
|
||||
+ ChainSpecProvider
|
||||
+ EvmEnvProvider
|
||||
+ HeaderProvider
|
||||
+ StateProviderFactory
|
||||
+ EvmEnvProvider
|
||||
+ Clone
|
||||
+ Unpin
|
||||
+ 'static,
|
||||
|
||||
@ -9,13 +9,14 @@ use crate::{
|
||||
};
|
||||
use reth_network_api::NetworkInfo;
|
||||
use reth_primitives::{BlockId, BlockNumberOrTag, TransactionMeta};
|
||||
use reth_provider::{BlockReaderIdExt, EvmEnvProvider, StateProviderFactory};
|
||||
use reth_provider::{BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, StateProviderFactory};
|
||||
use reth_rpc_types::{Block, Index, RichBlock, TransactionReceipt};
|
||||
use reth_transaction_pool::TransactionPool;
|
||||
|
||||
impl<Provider, Pool, Network> EthApi<Provider, Pool, Network>
|
||||
where
|
||||
Provider: BlockReaderIdExt + StateProviderFactory + EvmEnvProvider + 'static,
|
||||
Provider:
|
||||
BlockReaderIdExt + ChainSpecProvider + StateProviderFactory + EvmEnvProvider + 'static,
|
||||
Pool: TransactionPool + Clone + 'static,
|
||||
Network: NetworkInfo + Send + Sync + 'static,
|
||||
{
|
||||
|
||||
@ -14,7 +14,9 @@ use crate::{
|
||||
use ethers_core::utils::get_contract_address;
|
||||
use reth_network_api::NetworkInfo;
|
||||
use reth_primitives::{AccessList, BlockId, BlockNumberOrTag, Bytes, U256};
|
||||
use reth_provider::{BlockReaderIdExt, EvmEnvProvider, StateProvider, StateProviderFactory};
|
||||
use reth_provider::{
|
||||
BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, StateProvider, StateProviderFactory,
|
||||
};
|
||||
use reth_revm::{
|
||||
access_list::AccessListInspector,
|
||||
database::{State, SubState},
|
||||
@ -38,7 +40,8 @@ const MIN_CREATE_GAS: u64 = 53_000u64;
|
||||
impl<Provider, Pool, Network> EthApi<Provider, Pool, Network>
|
||||
where
|
||||
Pool: TransactionPool + Clone + 'static,
|
||||
Provider: BlockReaderIdExt + StateProviderFactory + EvmEnvProvider + 'static,
|
||||
Provider:
|
||||
BlockReaderIdExt + ChainSpecProvider + StateProviderFactory + EvmEnvProvider + 'static,
|
||||
Network: NetworkInfo + Send + Sync + 'static,
|
||||
{
|
||||
/// Estimate gas needed for execution of the `request` at the [BlockId].
|
||||
|
||||
@ -8,7 +8,7 @@ use reth_network_api::NetworkInfo;
|
||||
use reth_primitives::{
|
||||
basefee::calculate_next_block_base_fee, BlockNumberOrTag, SealedHeader, U256,
|
||||
};
|
||||
use reth_provider::{BlockReaderIdExt, EvmEnvProvider, StateProviderFactory};
|
||||
use reth_provider::{BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, StateProviderFactory};
|
||||
use reth_rpc_types::{FeeHistory, TxGasAndReward};
|
||||
use reth_transaction_pool::TransactionPool;
|
||||
use tracing::debug;
|
||||
@ -16,7 +16,8 @@ use tracing::debug;
|
||||
impl<Provider, Pool, Network> EthApi<Provider, Pool, Network>
|
||||
where
|
||||
Pool: TransactionPool + Clone + 'static,
|
||||
Provider: BlockReaderIdExt + StateProviderFactory + EvmEnvProvider + 'static,
|
||||
Provider:
|
||||
BlockReaderIdExt + ChainSpecProvider + StateProviderFactory + EvmEnvProvider + 'static,
|
||||
Network: NetworkInfo + Send + Sync + 'static,
|
||||
{
|
||||
/// Returns a suggestion for a gas price for legacy transactions.
|
||||
@ -115,10 +116,12 @@ where
|
||||
//
|
||||
// The unwrap is safe since we checked earlier that we got at least 1 header.
|
||||
let last_header = headers.last().unwrap();
|
||||
let chain_spec = self.provider().chain_spec();
|
||||
base_fee_per_gas.push(U256::from(calculate_next_block_base_fee(
|
||||
last_header.gas_used,
|
||||
last_header.gas_limit,
|
||||
last_header.base_fee_per_gas.unwrap_or_default(),
|
||||
chain_spec.base_fee_params,
|
||||
)));
|
||||
|
||||
Ok(FeeHistory {
|
||||
|
||||
@ -16,7 +16,9 @@ use reth_network_api::NetworkInfo;
|
||||
use reth_primitives::{
|
||||
Address, BlockId, BlockNumberOrTag, ChainInfo, SealedBlock, H256, U256, U64,
|
||||
};
|
||||
use reth_provider::{BlockReaderIdExt, EvmEnvProvider, StateProviderBox, StateProviderFactory};
|
||||
use reth_provider::{
|
||||
BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, StateProviderBox, StateProviderFactory,
|
||||
};
|
||||
use reth_rpc_types::{SyncInfo, SyncStatus};
|
||||
use reth_tasks::{TaskSpawner, TokioTaskExecutor};
|
||||
use reth_transaction_pool::TransactionPool;
|
||||
@ -79,7 +81,7 @@ pub struct EthApi<Provider, Pool, Network> {
|
||||
|
||||
impl<Provider, Pool, Network> EthApi<Provider, Pool, Network>
|
||||
where
|
||||
Provider: BlockReaderIdExt,
|
||||
Provider: BlockReaderIdExt + ChainSpecProvider,
|
||||
{
|
||||
/// Creates a new, shareable instance using the default tokio task spawner.
|
||||
pub fn new(
|
||||
@ -194,7 +196,8 @@ where
|
||||
|
||||
impl<Provider, Pool, Network> EthApi<Provider, Pool, Network>
|
||||
where
|
||||
Provider: BlockReaderIdExt + StateProviderFactory + EvmEnvProvider + 'static,
|
||||
Provider:
|
||||
BlockReaderIdExt + ChainSpecProvider + StateProviderFactory + EvmEnvProvider + 'static,
|
||||
{
|
||||
/// Returns the state at the given [BlockId] enum.
|
||||
pub fn state_at_block_id(&self, at: BlockId) -> EthResult<StateProviderBox<'_>> {
|
||||
@ -228,7 +231,8 @@ where
|
||||
|
||||
impl<Provider, Pool, Network> EthApi<Provider, Pool, Network>
|
||||
where
|
||||
Provider: BlockReaderIdExt + StateProviderFactory + EvmEnvProvider + 'static,
|
||||
Provider:
|
||||
BlockReaderIdExt + ChainSpecProvider + StateProviderFactory + EvmEnvProvider + 'static,
|
||||
Pool: TransactionPool + Clone + 'static,
|
||||
Network: NetworkInfo + Send + Sync + 'static,
|
||||
{
|
||||
@ -249,7 +253,8 @@ where
|
||||
// assumed child block is in the next slot
|
||||
latest.timestamp += 12;
|
||||
// base fee of the child block
|
||||
latest.base_fee_per_gas = latest.next_block_base_fee();
|
||||
let chain_spec = self.provider().chain_spec();
|
||||
latest.base_fee_per_gas = latest.next_block_base_fee(chain_spec.base_fee_params);
|
||||
|
||||
PendingBlockEnvOrigin::DerivedFromLatest(latest)
|
||||
};
|
||||
@ -327,7 +332,8 @@ impl<Provider, Pool, Events> Clone for EthApi<Provider, Pool, Events> {
|
||||
impl<Provider, Pool, Network> EthApiSpec for EthApi<Provider, Pool, Network>
|
||||
where
|
||||
Pool: TransactionPool + Clone + 'static,
|
||||
Provider: BlockReaderIdExt + StateProviderFactory + EvmEnvProvider + 'static,
|
||||
Provider:
|
||||
BlockReaderIdExt + ChainSpecProvider + StateProviderFactory + EvmEnvProvider + 'static,
|
||||
Network: NetworkInfo + 'static,
|
||||
{
|
||||
/// Returns the current ethereum protocol version.
|
||||
|
||||
@ -16,8 +16,8 @@ use reth_primitives::{
|
||||
AccessListWithGasUsed, Address, BlockId, BlockNumberOrTag, Bytes, H256, H64, U256, U64,
|
||||
};
|
||||
use reth_provider::{
|
||||
BlockIdReader, BlockReader, BlockReaderIdExt, EvmEnvProvider, HeaderProvider,
|
||||
StateProviderFactory,
|
||||
BlockIdReader, BlockReader, BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider,
|
||||
HeaderProvider, StateProviderFactory,
|
||||
};
|
||||
use reth_rpc_api::EthApiServer;
|
||||
use reth_rpc_types::{
|
||||
@ -37,6 +37,7 @@ where
|
||||
Provider: BlockReader
|
||||
+ BlockIdReader
|
||||
+ BlockReaderIdExt
|
||||
+ ChainSpecProvider
|
||||
+ HeaderProvider
|
||||
+ StateProviderFactory
|
||||
+ EvmEnvProvider
|
||||
@ -410,12 +411,13 @@ mod tests {
|
||||
use reth_interfaces::test_utils::{generators, generators::Rng};
|
||||
use reth_network_api::noop::NoopNetwork;
|
||||
use reth_primitives::{
|
||||
basefee::calculate_next_block_base_fee, constants::ETHEREUM_BLOCK_GAS_LIMIT, Block,
|
||||
BlockNumberOrTag, Header, TransactionSigned, H256, U256,
|
||||
basefee::calculate_next_block_base_fee,
|
||||
constants::{self, ETHEREUM_BLOCK_GAS_LIMIT},
|
||||
BaseFeeParams, Block, BlockNumberOrTag, Header, TransactionSigned, H256, U256,
|
||||
};
|
||||
use reth_provider::{
|
||||
test_utils::{MockEthProvider, NoopProvider},
|
||||
BlockReader, BlockReaderIdExt, EvmEnvProvider, StateProviderFactory,
|
||||
BlockReader, BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, StateProviderFactory,
|
||||
};
|
||||
use reth_rpc_api::EthApiServer;
|
||||
use reth_rpc_types::FeeHistory;
|
||||
@ -424,6 +426,7 @@ mod tests {
|
||||
fn build_test_eth_api<
|
||||
P: BlockReaderIdExt
|
||||
+ BlockReader
|
||||
+ ChainSpecProvider
|
||||
+ EvmEnvProvider
|
||||
+ StateProviderFactory
|
||||
+ Unpin
|
||||
@ -538,6 +541,7 @@ mod tests {
|
||||
last_header.gas_used,
|
||||
last_header.gas_limit,
|
||||
last_header.base_fee_per_gas.unwrap_or_default(),
|
||||
BaseFeeParams::ethereum(),
|
||||
)));
|
||||
|
||||
let eth_api = build_test_eth_api(mock_provider);
|
||||
|
||||
@ -9,14 +9,16 @@ use reth_primitives::{
|
||||
U256,
|
||||
};
|
||||
use reth_provider::{
|
||||
AccountReader, BlockReaderIdExt, EvmEnvProvider, StateProvider, StateProviderFactory,
|
||||
AccountReader, BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, StateProvider,
|
||||
StateProviderFactory,
|
||||
};
|
||||
use reth_rpc_types::{EIP1186AccountProofResponse, StorageProof};
|
||||
use reth_transaction_pool::{PoolTransaction, TransactionPool};
|
||||
|
||||
impl<Provider, Pool, Network> EthApi<Provider, Pool, Network>
|
||||
where
|
||||
Provider: BlockReaderIdExt + StateProviderFactory + EvmEnvProvider + 'static,
|
||||
Provider:
|
||||
BlockReaderIdExt + ChainSpecProvider + StateProviderFactory + EvmEnvProvider + 'static,
|
||||
Pool: TransactionPool + Clone + 'static,
|
||||
Network: Send + Sync + 'static,
|
||||
{
|
||||
|
||||
@ -19,7 +19,9 @@ use reth_primitives::{
|
||||
TransactionKind::{Call, Create},
|
||||
TransactionMeta, TransactionSigned, TransactionSignedEcRecovered, H256, U128, U256, U64,
|
||||
};
|
||||
use reth_provider::{BlockReaderIdExt, EvmEnvProvider, StateProviderBox, StateProviderFactory};
|
||||
use reth_provider::{
|
||||
BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, StateProviderBox, StateProviderFactory,
|
||||
};
|
||||
use reth_revm::{
|
||||
database::{State, SubState},
|
||||
env::{fill_block_env_with_coinbase, tx_env_with_recovered},
|
||||
@ -236,7 +238,8 @@ pub trait EthTransactions: Send + Sync {
|
||||
impl<Provider, Pool, Network> EthTransactions for EthApi<Provider, Pool, Network>
|
||||
where
|
||||
Pool: TransactionPool + Clone + 'static,
|
||||
Provider: BlockReaderIdExt + StateProviderFactory + EvmEnvProvider + 'static,
|
||||
Provider:
|
||||
BlockReaderIdExt + ChainSpecProvider + StateProviderFactory + EvmEnvProvider + 'static,
|
||||
Network: NetworkInfo + Send + Sync + 'static,
|
||||
{
|
||||
fn call_gas_limit(&self) -> u64 {
|
||||
@ -668,7 +671,8 @@ where
|
||||
|
||||
impl<Provider, Pool, Network> EthApi<Provider, Pool, Network>
|
||||
where
|
||||
Provider: BlockReaderIdExt + StateProviderFactory + EvmEnvProvider + 'static,
|
||||
Provider:
|
||||
BlockReaderIdExt + ChainSpecProvider + StateProviderFactory + EvmEnvProvider + 'static,
|
||||
Network: 'static,
|
||||
{
|
||||
/// Helper function for `eth_getTransactionReceipt`
|
||||
@ -692,7 +696,8 @@ where
|
||||
impl<Provider, Pool, Network> EthApi<Provider, Pool, Network>
|
||||
where
|
||||
Pool: TransactionPool + 'static,
|
||||
Provider: BlockReaderIdExt + StateProviderFactory + EvmEnvProvider + 'static,
|
||||
Provider:
|
||||
BlockReaderIdExt + ChainSpecProvider + StateProviderFactory + EvmEnvProvider + 'static,
|
||||
Network: NetworkInfo + Send + Sync + 'static,
|
||||
{
|
||||
pub(crate) fn sign_request(
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
use crate::{
|
||||
traits::{BlockSource, ReceiptProvider},
|
||||
AccountReader, BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt,
|
||||
EvmEnvProvider, HeaderProvider, PostState, PostStateDataProvider, ReceiptProviderIdExt,
|
||||
StateProvider, StateProviderBox, StateProviderFactory, StateRootProvider, TransactionsProvider,
|
||||
WithdrawalsProvider,
|
||||
ChainSpecProvider, EvmEnvProvider, HeaderProvider, PostState, PostStateDataProvider,
|
||||
ReceiptProviderIdExt, StateProvider, StateProviderBox, StateProviderFactory, StateRootProvider,
|
||||
TransactionsProvider, WithdrawalsProvider,
|
||||
};
|
||||
use parking_lot::Mutex;
|
||||
use reth_db::models::StoredBlockBodyIndices;
|
||||
use reth_interfaces::{provider::ProviderError, Result};
|
||||
use reth_primitives::{
|
||||
keccak256, Account, Address, Block, BlockHash, BlockHashOrNumber, BlockId, BlockNumber,
|
||||
BlockWithSenders, Bytecode, Bytes, ChainInfo, Header, Receipt, SealedBlock, SealedHeader,
|
||||
StorageKey, StorageValue, TransactionMeta, TransactionSigned, TransactionSignedNoHash, TxHash,
|
||||
TxNumber, H256, U256,
|
||||
BlockWithSenders, Bytecode, Bytes, ChainInfo, ChainSpec, Header, Receipt, SealedBlock,
|
||||
SealedHeader, StorageKey, StorageValue, TransactionMeta, TransactionSigned,
|
||||
TransactionSignedNoHash, TxHash, TxNumber, H256, U256,
|
||||
};
|
||||
use reth_revm_primitives::primitives::{BlockEnv, CfgEnv};
|
||||
use std::{
|
||||
@ -22,7 +22,7 @@ use std::{
|
||||
};
|
||||
|
||||
/// A mock implementation for Provider interfaces.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MockEthProvider {
|
||||
/// Local block store
|
||||
pub blocks: Arc<Mutex<HashMap<H256, Block>>>,
|
||||
@ -30,6 +30,19 @@ pub struct MockEthProvider {
|
||||
pub headers: Arc<Mutex<HashMap<H256, Header>>>,
|
||||
/// Local account store
|
||||
pub accounts: Arc<Mutex<HashMap<Address, ExtendedAccount>>>,
|
||||
/// Local chain spec
|
||||
pub chain_spec: Arc<ChainSpec>,
|
||||
}
|
||||
|
||||
impl Default for MockEthProvider {
|
||||
fn default() -> MockEthProvider {
|
||||
MockEthProvider {
|
||||
blocks: Default::default(),
|
||||
headers: Default::default(),
|
||||
accounts: Default::default(),
|
||||
chain_spec: Arc::new(reth_primitives::ChainSpecBuilder::mainnet().build()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An extended account for local store
|
||||
@ -160,6 +173,12 @@ impl HeaderProvider for MockEthProvider {
|
||||
}
|
||||
}
|
||||
|
||||
impl ChainSpecProvider for MockEthProvider {
|
||||
fn chain_spec(&self) -> Arc<ChainSpec> {
|
||||
self.chain_spec.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl TransactionsProvider for MockEthProvider {
|
||||
fn transaction_id(&self, _tx_hash: TxHash) -> Result<Option<TxNumber>> {
|
||||
todo!()
|
||||
|
||||
@ -92,10 +92,10 @@
|
||||
//!
|
||||
//! ```
|
||||
//! use reth_primitives::MAINNET;
|
||||
//! use reth_provider::StateProviderFactory;
|
||||
//! use reth_provider::{ChainSpecProvider, StateProviderFactory};
|
||||
//! use reth_tasks::TokioTaskExecutor;
|
||||
//! use reth_transaction_pool::{EthTransactionValidator, Pool, TransactionPool};
|
||||
//! async fn t<C>(client: C) where C: StateProviderFactory + Clone + 'static{
|
||||
//! async fn t<C>(client: C) where C: StateProviderFactory + ChainSpecProvider + Clone + 'static{
|
||||
//! let pool = Pool::eth_pool(
|
||||
//! EthTransactionValidator::new(client, MAINNET.clone(), TokioTaskExecutor::default()),
|
||||
//! Default::default(),
|
||||
@ -117,12 +117,12 @@
|
||||
//! ```
|
||||
//! use futures_util::Stream;
|
||||
//! use reth_primitives::MAINNET;
|
||||
//! use reth_provider::{BlockReaderIdExt, CanonStateNotification, StateProviderFactory};
|
||||
//! use reth_provider::{BlockReaderIdExt, CanonStateNotification, ChainSpecProvider, StateProviderFactory};
|
||||
//! use reth_tasks::TokioTaskExecutor;
|
||||
//! use reth_transaction_pool::{EthTransactionValidator, Pool};
|
||||
//! use reth_transaction_pool::maintain::maintain_transaction_pool_future;
|
||||
//! async fn t<C, St>(client: C, stream: St)
|
||||
//! where C: StateProviderFactory + BlockReaderIdExt + Clone + 'static,
|
||||
//! where C: StateProviderFactory + BlockReaderIdExt + ChainSpecProvider + Clone + 'static,
|
||||
//! St: Stream<Item = CanonStateNotification> + Send + Unpin + 'static,
|
||||
//! {
|
||||
//! let pool = Pool::eth_pool(
|
||||
|
||||
@ -10,7 +10,9 @@ use futures_util::{
|
||||
FutureExt, Stream, StreamExt,
|
||||
};
|
||||
use reth_primitives::{Address, BlockHash, BlockNumberOrTag, FromRecoveredTransaction};
|
||||
use reth_provider::{BlockReaderIdExt, CanonStateNotification, PostState, StateProviderFactory};
|
||||
use reth_provider::{
|
||||
BlockReaderIdExt, CanonStateNotification, ChainSpecProvider, PostState, StateProviderFactory,
|
||||
};
|
||||
use reth_tasks::TaskSpawner;
|
||||
use std::{
|
||||
borrow::Borrow,
|
||||
@ -49,7 +51,7 @@ pub fn maintain_transaction_pool_future<Client, P, St, Tasks>(
|
||||
config: MaintainPoolConfig,
|
||||
) -> BoxFuture<'static, ()>
|
||||
where
|
||||
Client: StateProviderFactory + BlockReaderIdExt + Clone + Send + 'static,
|
||||
Client: StateProviderFactory + BlockReaderIdExt + ChainSpecProvider + Clone + Send + 'static,
|
||||
P: TransactionPoolExt + 'static,
|
||||
St: Stream<Item = CanonStateNotification> + Send + Unpin + 'static,
|
||||
Tasks: TaskSpawner + 'static,
|
||||
@ -70,7 +72,7 @@ pub async fn maintain_transaction_pool<Client, P, St, Tasks>(
|
||||
task_spawner: Tasks,
|
||||
config: MaintainPoolConfig,
|
||||
) where
|
||||
Client: StateProviderFactory + BlockReaderIdExt + Clone + Send + 'static,
|
||||
Client: StateProviderFactory + BlockReaderIdExt + ChainSpecProvider + Clone + Send + 'static,
|
||||
P: TransactionPoolExt + 'static,
|
||||
St: Stream<Item = CanonStateNotification> + Send + Unpin + 'static,
|
||||
Tasks: TaskSpawner + 'static,
|
||||
@ -80,10 +82,13 @@ pub async fn maintain_transaction_pool<Client, P, St, Tasks>(
|
||||
// ensure the pool points to latest state
|
||||
if let Ok(Some(latest)) = client.block_by_number_or_tag(BlockNumberOrTag::Latest) {
|
||||
let latest = latest.seal_slow();
|
||||
let chain_spec = client.chain_spec();
|
||||
let info = BlockInfo {
|
||||
last_seen_block_hash: latest.hash,
|
||||
last_seen_block_number: latest.number,
|
||||
pending_basefee: latest.next_block_base_fee().unwrap_or_default(),
|
||||
pending_basefee: latest
|
||||
.next_block_base_fee(chain_spec.base_fee_params)
|
||||
.unwrap_or_default(),
|
||||
};
|
||||
pool.set_block_info(info);
|
||||
}
|
||||
@ -204,8 +209,11 @@ pub async fn maintain_transaction_pool<Client, P, St, Tasks>(
|
||||
maintained_state = MaintainedPoolState::Drifted;
|
||||
}
|
||||
|
||||
let chain_spec = client.chain_spec();
|
||||
|
||||
// base fee for the next block: `new_tip+1`
|
||||
let pending_block_base_fee = new_tip.next_block_base_fee().unwrap_or_default();
|
||||
let pending_block_base_fee =
|
||||
new_tip.next_block_base_fee(chain_spec.base_fee_params).unwrap_or_default();
|
||||
|
||||
// we know all changed account in the new chain
|
||||
let new_changed_accounts: HashSet<_> =
|
||||
@ -279,9 +287,11 @@ pub async fn maintain_transaction_pool<Client, P, St, Tasks>(
|
||||
CanonStateNotification::Commit { new } => {
|
||||
let (blocks, state) = new.inner();
|
||||
let tip = blocks.tip();
|
||||
let chain_spec = client.chain_spec();
|
||||
|
||||
// base fee for the next block: `tip+1`
|
||||
let pending_block_base_fee = tip.next_block_base_fee().unwrap_or_default();
|
||||
let pending_block_base_fee =
|
||||
tip.next_block_base_fee(chain_spec.base_fee_params).unwrap_or_default();
|
||||
|
||||
let first_block = blocks.first();
|
||||
trace!(
|
||||
|
||||
Reference in New Issue
Block a user