mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-02-10 06:55:10 -05:00
feat: make base fee computation parameters configurable via chain spec (#3992)
This commit is contained in:
@@ -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::{
|
||||
|
||||
Reference in New Issue
Block a user