Skip to content

Commit

Permalink
@mattsse review
Browse files Browse the repository at this point in the history
  • Loading branch information
clabby committed Nov 24, 2023
1 parent 1781791 commit 8c6e1df
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 36 deletions.
4 changes: 2 additions & 2 deletions crates/primitives/src/chain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use strum::{AsRefStr, EnumCount, EnumIter, EnumString, EnumVariantNames};
// The chain spec module.
mod spec;
pub use spec::{
AllGenesisFormats, BaseFeeParams, ChainSpec, ChainSpecBuilder, DisplayHardforks, ForkCondition,
ForkTimestamps, DEV, GOERLI, HOLESKY, MAINNET, SEPOLIA,
AllGenesisFormats, BaseFeeParams, BaseFeeParamsWrapper, ChainSpec, ChainSpecBuilder,
DisplayHardforks, ForkCondition, ForkTimestamps, DEV, GOERLI, HOLESKY, MAINNET, SEPOLIA,
};

#[cfg(feature = "optimism")]
Expand Down
83 changes: 52 additions & 31 deletions crates/primitives/src/chain/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub static MAINNET: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
11052984,
b256!("649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"),
)),
base_fee_params: vec![(Hardfork::London, BaseFeeParams::ethereum())],
base_fee_params: BaseFeeParamsWrapper::Constant(BaseFeeParams::ethereum()),
prune_delete_limit: 3500,
snapshot_block_interval: 500_000,
}
Expand Down Expand Up @@ -106,7 +106,7 @@ pub static GOERLI: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
4367322,
b256!("649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"),
)),
base_fee_params: vec![(Hardfork::London, BaseFeeParams::ethereum())],
base_fee_params: BaseFeeParamsWrapper::Constant(BaseFeeParams::ethereum()),
prune_delete_limit: 1700,
snapshot_block_interval: 1_000_000,
}
Expand Down Expand Up @@ -153,7 +153,7 @@ pub static SEPOLIA: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
1273020,
b256!("649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"),
)),
base_fee_params: vec![(Hardfork::London, BaseFeeParams::ethereum())],
base_fee_params: BaseFeeParamsWrapper::Constant(BaseFeeParams::ethereum()),
prune_delete_limit: 1700,
snapshot_block_interval: 1_000_000,
}
Expand Down Expand Up @@ -195,7 +195,7 @@ pub static HOLESKY: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
0,
b256!("649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"),
)),
base_fee_params: vec![(Hardfork::London, BaseFeeParams::ethereum())],
base_fee_params: BaseFeeParamsWrapper::Constant(BaseFeeParams::ethereum()),
prune_delete_limit: 1700,
snapshot_block_interval: 1_000_000,
}
Expand Down Expand Up @@ -235,7 +235,7 @@ pub static DEV: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
),
(Hardfork::Shanghai, ForkCondition::Timestamp(0)),
]),
base_fee_params: vec![(Hardfork::London, BaseFeeParams::ethereum())],
base_fee_params: BaseFeeParamsWrapper::Constant(BaseFeeParams::ethereum()),
deposit_contract: None, // TODO: do we even have?
..Default::default()
}
Expand Down Expand Up @@ -277,10 +277,10 @@ pub static OP_GOERLI: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
(Hardfork::Shanghai, ForkCondition::Timestamp(1699981200)),
(Hardfork::Canyon, ForkCondition::Timestamp(1699981200)),
]),
base_fee_params: vec![
base_fee_params: BaseFeeParamsWrapper::Variable(vec![
(Hardfork::London, BaseFeeParams::optimism_goerli()),
(Hardfork::Canyon, BaseFeeParams::optimism_goerli_canyon()),
],
]),
prune_delete_limit: 1700,
snapshot_block_interval: 1_000_000,
..Default::default()
Expand Down Expand Up @@ -323,10 +323,10 @@ pub static BASE_GOERLI: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
(Hardfork::Shanghai, ForkCondition::Timestamp(1699981200)),
(Hardfork::Canyon, ForkCondition::Timestamp(1699981200)),
]),
base_fee_params: vec![
base_fee_params: BaseFeeParamsWrapper::Variable(vec![
(Hardfork::London, BaseFeeParams::optimism_goerli()),
(Hardfork::Canyon, BaseFeeParams::optimism_goerli_canyon()),
],
]),
prune_delete_limit: 1700,
snapshot_block_interval: 1_000_000,
..Default::default()
Expand Down Expand Up @@ -367,17 +367,28 @@ pub static BASE_MAINNET: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
(Hardfork::Bedrock, ForkCondition::Block(0)),
(Hardfork::Regolith, ForkCondition::Timestamp(0)),
]),
base_fee_params: vec![
base_fee_params: BaseFeeParamsWrapper::Variable(vec![
(Hardfork::London, BaseFeeParams::optimism()),
(Hardfork::Canyon, BaseFeeParams::optimism_canyon()),
],
]),
prune_delete_limit: 1700,
snapshot_block_interval: 1_000_000,
..Default::default()
}
.into()
});

/// A wrapper around [BaseFeeParams] that allows for specifying constant or dynamic EIP-1559
/// parameters based on the active [Hardfork].
#[derive(Clone, Debug)]
pub enum BaseFeeParamsWrapper {
/// Constant [BaseFeeParams]; used for chains that don't have dynamic EIP-1559 parameters
Constant(BaseFeeParams),
/// Variable [BaseFeeParams]; used for chains that have dynamic EIP-1559 parameters like
/// Optimism
Variable(Vec<(Hardfork, BaseFeeParams)>),
}

/// BaseFeeParams contains the config parameters that control block base fee computation
#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq)]
pub struct BaseFeeParams {
Expand Down Expand Up @@ -481,7 +492,11 @@ pub struct ChainSpec {
pub deposit_contract: Option<DepositContract>,

/// The parameters that configure how a block's base fee is computed
pub base_fee_params: Vec<(Hardfork, BaseFeeParams)>,
#[serde(
serialize_with = "crate::serde_helper::serialize_base_fee_params",
deserialize_with = "crate::serde_helper::deserialize_base_fee_params"
)]
pub base_fee_params: BaseFeeParamsWrapper,

/// The delete limit for pruner, per block. In the actual pruner run it will be multiplied by
/// the amount of blocks between pruner runs to account for the difference in amount of new
Expand All @@ -503,7 +518,7 @@ impl Default for ChainSpec {
fork_timestamps: Default::default(),
hardforks: Default::default(),
deposit_contract: Default::default(),
base_fee_params: Default::default(),
base_fee_params: BaseFeeParamsWrapper::Constant(BaseFeeParams::ethereum()),
prune_delete_limit: MAINNET.prune_delete_limit,
snapshot_block_interval: Default::default(),
}
Expand Down Expand Up @@ -592,15 +607,21 @@ impl ChainSpec {

/// Get the [BaseFeeParams] for the chain at the given timestamp.
pub fn base_fee_params(&self, timestamp: u64) -> BaseFeeParams {
// Walk through the base fee params configuration in reverse order, and return the first
// one that corresponds to a hardfork that is active at the given timestamp.
for (fork, params) in self.base_fee_params.iter().rev() {
if self.is_fork_active_at_timestamp(*fork, timestamp) {
return *params
match self.base_fee_params {
BaseFeeParamsWrapper::Constant(bf_params) => bf_params,
BaseFeeParamsWrapper::Variable(ref bf_params) => {
// Walk through the base fee params configuration in reverse order, and return the
// first one that corresponds to a hardfork that is active at the
// given timestamp.
for (fork, params) in bf_params.iter().rev() {
if self.is_fork_active_at_timestamp(*fork, timestamp) {
return *params;
}
}

bf_params.first().map(|(_, params)| *params).unwrap_or(BaseFeeParams::ethereum())
}
}

self.base_fee_params.first().map(|(_, params)| *params).unwrap_or(BaseFeeParams::ethereum())
}

/// Get the hash of the genesis block.
Expand Down Expand Up @@ -705,8 +726,8 @@ impl ChainSpec {
for (_, cond) in self.forks_iter() {
// handle block based forks and the sepolia merge netsplit block edge case (TTD
// ForkCondition with Some(block))
if let ForkCondition::Block(block) |
ForkCondition::TTD { fork_block: Some(block), .. } = cond
if let ForkCondition::Block(block)
| ForkCondition::TTD { fork_block: Some(block), .. } = cond
{
if cond.active_at_head(head) {
if block != current_applied {
Expand All @@ -716,7 +737,7 @@ impl ChainSpec {
} else {
// we can return here because this block fork is not active, so we set the
// `next` value
return ForkId { hash: forkhash, next: block }
return ForkId { hash: forkhash, next: block };
}
}
}
Expand All @@ -737,7 +758,7 @@ impl ChainSpec {
// can safely return here because we have already handled all block forks and
// have handled all active timestamp forks, and set the next value to the
// timestamp that is known but not active yet
return ForkId { hash: forkhash, next: timestamp }
return ForkId { hash: forkhash, next: timestamp };
}
}

Expand All @@ -752,7 +773,7 @@ impl ChainSpec {
// to satisfy every timestamp ForkCondition, we find the last ForkCondition::Block
// if one exists, and include its block_num in the returned Head
if let Some(last_block_num) = self.last_block_fork_before_merge_or_timestamp() {
return Head { timestamp, number: last_block_num, ..Default::default() }
return Head { timestamp, number: last_block_num, ..Default::default() };
}
Head { timestamp, ..Default::default() }
}
Expand Down Expand Up @@ -780,17 +801,17 @@ impl ChainSpec {
ForkCondition::TTD { fork_block, .. } => {
// handle Sepolia merge netsplit case
if fork_block.is_some() {
return *fork_block
return *fork_block;
}
// ensure curr_cond is indeed ForkCondition::Block and return block_num
if let ForkCondition::Block(block_num) = curr_cond {
return Some(block_num)
return Some(block_num);
}
}
ForkCondition::Timestamp(_) => {
// ensure curr_cond is indeed ForkCondition::Block and return block_num
if let ForkCondition::Block(block_num) = curr_cond {
return Some(block_num)
return Some(block_num);
}
}
ForkCondition::Block(_) | ForkCondition::Never => continue,
Expand Down Expand Up @@ -1246,9 +1267,9 @@ impl ForkCondition {
/// - The condition is satisfied by the timestamp;
/// - or the condition is satisfied by the total difficulty
pub fn active_at_head(&self, head: &Head) -> bool {
self.active_at_block(head.number) ||
self.active_at_timestamp(head.timestamp) ||
self.active_at_ttd(head.total_difficulty, head.difficulty)
self.active_at_block(head.number)
|| self.active_at_timestamp(head.timestamp)
|| self.active_at_ttd(head.total_difficulty, head.difficulty)
}

/// Get the total terminal difficulty for this fork condition.
Expand Down
6 changes: 3 additions & 3 deletions crates/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ pub use block::{
};
pub use bytes::{Buf, BufMut, BytesMut};
pub use chain::{
AllGenesisFormats, BaseFeeParams, Chain, ChainInfo, ChainSpec, ChainSpecBuilder,
DisplayHardforks, ForkCondition, ForkTimestamps, NamedChain, DEV, GOERLI, HOLESKY, MAINNET,
SEPOLIA,
AllGenesisFormats, BaseFeeParams, BaseFeeParamsWrapper, Chain, ChainInfo, ChainSpec,
ChainSpecBuilder, DisplayHardforks, ForkCondition, ForkTimestamps, NamedChain, DEV, GOERLI,
HOLESKY, MAINNET, SEPOLIA,
};
#[cfg(feature = "optimism")]
pub use chain::{BASE_GOERLI, BASE_MAINNET, OP_GOERLI};
Expand Down
68 changes: 68 additions & 0 deletions crates/primitives/src/serde_helper/base_fee_params.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use crate::{chain::BaseFeeParamsWrapper, BaseFeeParams, Hardfork};
use serde::{
de::{self, SeqAccess, Visitor},
ser::SerializeSeq,
Deserializer, Serializer,
};

/// Deserialize the [BaseFeeParamsWrapper]
pub fn deserialize_base_fee_params<'de, D>(
deserializer: D,
) -> Result<BaseFeeParamsWrapper, D::Error>
where
D: Deserializer<'de>,
{
struct BaseFeeParamsWrapperVisitor;

impl<'de> Visitor<'de> for BaseFeeParamsWrapperVisitor {
type Value = BaseFeeParamsWrapper;

fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str("struct BaseFeeParamsWrapper")
}

fn visit_seq<V>(self, mut seq: V) -> Result<BaseFeeParamsWrapper, V::Error>
where
V: SeqAccess<'de>,
{
let first = seq.next_element::<BaseFeeParams>()?;
if let Some(base_fee_params) = first {
// Found a Constant variant
Ok(BaseFeeParamsWrapper::Constant(base_fee_params))
} else {
// Expecting a Variable variant, which should be a sequence
let variable_params = seq
.next_element::<Vec<(Hardfork, BaseFeeParams)>>()?
.ok_or_else(|| de::Error::invalid_length(1, &self))?;
Ok(BaseFeeParamsWrapper::Variable(variable_params))
}
}
}

deserializer.deserialize_any(BaseFeeParamsWrapperVisitor)
}

/// Serialize the [BaseFeeParamsWrapper]
pub fn serialize_base_fee_params<S>(
base_fee_params: &BaseFeeParamsWrapper,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match base_fee_params {
BaseFeeParamsWrapper::Constant(base_fee_params) => serializer.serialize_newtype_variant(
"BaseFeeParamsWrapper",
0,
"Constant",
base_fee_params,
),
BaseFeeParamsWrapper::Variable(variable_params) => {
let mut seq = serializer.serialize_seq(Some(variable_params.len()))?;
for (hardfork, params) in variable_params {
seq.serialize_element(&(hardfork, params))?;
}
seq.end()
}
}
}
3 changes: 3 additions & 0 deletions crates/primitives/src/serde_helper/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ pub use reth_rpc_types::serde_helpers::*;

mod prune;
pub use prune::deserialize_opt_prune_mode_with_min_blocks;

mod base_fee_params;
pub use base_fee_params::{deserialize_base_fee_params, serialize_base_fee_params};

0 comments on commit 8c6e1df

Please sign in to comment.