mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: abstract OpBeaconConsensus over primitives and chainspec (#14171)
This commit is contained in:
@ -19,7 +19,7 @@ mod op_sepolia;
|
||||
|
||||
use alloc::{boxed::Box, vec, vec::Vec};
|
||||
use alloy_chains::Chain;
|
||||
use alloy_consensus::{BlockHeader, Header};
|
||||
use alloy_consensus::Header;
|
||||
use alloy_eips::eip7840::BlobParams;
|
||||
use alloy_genesis::Genesis;
|
||||
use alloy_primitives::{B256, U256};
|
||||
@ -28,7 +28,6 @@ pub use base_sepolia::BASE_SEPOLIA;
|
||||
use derive_more::{Constructor, Deref, Display, From, Into};
|
||||
pub use dev::OP_DEV;
|
||||
pub use op::OP_MAINNET;
|
||||
use op_alloy_consensus::{decode_holocene_extra_data, EIP1559ParamError};
|
||||
pub use op_sepolia::OP_SEPOLIA;
|
||||
use reth_chainspec::{
|
||||
BaseFeeParams, BaseFeeParamsKind, ChainSpec, ChainSpecBuilder, DepositContract, EthChainSpec,
|
||||
@ -195,55 +194,6 @@ impl OpChainSpec {
|
||||
pub fn from_genesis(genesis: Genesis) -> Self {
|
||||
genesis.into()
|
||||
}
|
||||
|
||||
/// Extracts the Holocene 1599 parameters from the encoded extra data from the parent header.
|
||||
///
|
||||
/// Caution: Caller must ensure that holocene is active in the parent header.
|
||||
///
|
||||
/// See also [Base fee computation](https://github.com/ethereum-optimism/specs/blob/main/specs/protocol/holocene/exec-engine.md#base-fee-computation)
|
||||
pub fn decode_holocene_base_fee<H: BlockHeader>(
|
||||
&self,
|
||||
parent: &H,
|
||||
timestamp: u64,
|
||||
) -> Result<u64, EIP1559ParamError> {
|
||||
let (elasticity, denominator) = decode_holocene_extra_data(parent.extra_data())?;
|
||||
let base_fee = if elasticity == 0 && denominator == 0 {
|
||||
parent
|
||||
.next_block_base_fee(self.base_fee_params_at_timestamp(timestamp))
|
||||
.unwrap_or_default()
|
||||
} else {
|
||||
let base_fee_params = BaseFeeParams::new(denominator as u128, elasticity as u128);
|
||||
parent.next_block_base_fee(base_fee_params).unwrap_or_default()
|
||||
};
|
||||
Ok(base_fee)
|
||||
}
|
||||
|
||||
/// Read from parent to determine the base fee for the next block
|
||||
///
|
||||
/// See also [Base fee computation](https://github.com/ethereum-optimism/specs/blob/main/specs/protocol/holocene/exec-engine.md#base-fee-computation)
|
||||
pub fn next_block_base_fee<H: BlockHeader>(
|
||||
&self,
|
||||
parent: &H,
|
||||
timestamp: u64,
|
||||
) -> Result<U256, EIP1559ParamError> {
|
||||
// > if Holocene is active in parent_header.timestamp, then the parameters from
|
||||
// > parent_header.extraData are used.
|
||||
let is_holocene_activated =
|
||||
self.inner.is_fork_active_at_timestamp(OpHardfork::Holocene, parent.timestamp());
|
||||
|
||||
// If we are in the Holocene, we need to use the base fee params
|
||||
// from the parent block's extra data.
|
||||
// Else, use the base fee params (default values) from chainspec
|
||||
if is_holocene_activated {
|
||||
Ok(U256::from(self.decode_holocene_base_fee(parent, timestamp)?))
|
||||
} else {
|
||||
Ok(U256::from(
|
||||
parent
|
||||
.next_block_base_fee(self.base_fee_params_at_timestamp(timestamp))
|
||||
.unwrap_or_default(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EthChainSpec for OpChainSpec {
|
||||
@ -483,10 +433,8 @@ impl OpGenesisInfo {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::sync::Arc;
|
||||
|
||||
use alloy_genesis::{ChainConfig, Genesis};
|
||||
use alloy_primitives::{b256, hex, Bytes};
|
||||
use alloy_primitives::b256;
|
||||
use reth_chainspec::{test_fork_ids, BaseFeeParams, BaseFeeParamsKind};
|
||||
use reth_ethereum_forks::{EthereumHardfork, ForkCondition, ForkHash, ForkId, Head};
|
||||
use reth_optimism_forks::{OpHardfork, OpHardforks};
|
||||
@ -1026,105 +974,6 @@ mod tests {
|
||||
assert_eq!(expected_hardforks.len(), hardforks.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_base_fee_pre_holocene() {
|
||||
let op_chain_spec = &BASE_SEPOLIA;
|
||||
let parent = Header {
|
||||
base_fee_per_gas: Some(1),
|
||||
gas_used: 15763614,
|
||||
gas_limit: 144000000,
|
||||
..Default::default()
|
||||
};
|
||||
let base_fee = op_chain_spec.next_block_base_fee(&parent, 0);
|
||||
assert_eq!(
|
||||
base_fee.unwrap(),
|
||||
U256::from(
|
||||
parent
|
||||
.next_block_base_fee(op_chain_spec.base_fee_params_at_timestamp(0))
|
||||
.unwrap_or_default()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
fn holocene_chainspec() -> Arc<OpChainSpec> {
|
||||
let mut hardforks = OpHardfork::base_sepolia();
|
||||
hardforks.insert(OpHardfork::Holocene.boxed(), ForkCondition::Timestamp(1800000000));
|
||||
Arc::new(OpChainSpec {
|
||||
inner: ChainSpec {
|
||||
chain: BASE_SEPOLIA.inner.chain,
|
||||
genesis: BASE_SEPOLIA.inner.genesis.clone(),
|
||||
genesis_hash: BASE_SEPOLIA.inner.genesis_hash.clone(),
|
||||
paris_block_and_final_difficulty: Some((0, U256::from(0))),
|
||||
hardforks,
|
||||
base_fee_params: BASE_SEPOLIA.inner.base_fee_params.clone(),
|
||||
prune_delete_limit: 10000,
|
||||
..Default::default()
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_base_fee_holocene_extra_data_not_set() {
|
||||
let op_chain_spec = holocene_chainspec();
|
||||
let parent = Header {
|
||||
base_fee_per_gas: Some(1),
|
||||
gas_used: 15763614,
|
||||
gas_limit: 144000000,
|
||||
timestamp: 1800000003,
|
||||
extra_data: Bytes::from_static(&[0, 0, 0, 0, 0, 0, 0, 0, 0]),
|
||||
..Default::default()
|
||||
};
|
||||
let base_fee = op_chain_spec.next_block_base_fee(&parent, 1800000005);
|
||||
assert_eq!(
|
||||
base_fee.unwrap(),
|
||||
U256::from(
|
||||
parent
|
||||
.next_block_base_fee(op_chain_spec.base_fee_params_at_timestamp(0))
|
||||
.unwrap_or_default()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_base_fee_holocene_extra_data_set() {
|
||||
let op_chain_spec = holocene_chainspec();
|
||||
let parent = Header {
|
||||
base_fee_per_gas: Some(1),
|
||||
gas_used: 15763614,
|
||||
gas_limit: 144000000,
|
||||
extra_data: Bytes::from_static(&[0, 0, 0, 0, 8, 0, 0, 0, 8]),
|
||||
timestamp: 1800000003,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let base_fee = op_chain_spec.next_block_base_fee(&parent, 1800000005);
|
||||
assert_eq!(
|
||||
base_fee.unwrap(),
|
||||
U256::from(
|
||||
parent
|
||||
.next_block_base_fee(BaseFeeParams::new(0x00000008, 0x00000008))
|
||||
.unwrap_or_default()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// <https://sepolia.basescan.org/block/19773628>
|
||||
#[test]
|
||||
fn test_get_base_fee_holocene_extra_data_set_base_sepolia() {
|
||||
let op_chain_spec = BASE_SEPOLIA.clone();
|
||||
let parent = Header {
|
||||
base_fee_per_gas: Some(507),
|
||||
gas_used: 4847634,
|
||||
gas_limit: 60000000,
|
||||
extra_data: hex!("00000000fa0000000a").into(),
|
||||
timestamp: 1735315544,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let base_fee = op_chain_spec.next_block_base_fee(&parent, 1735315546).unwrap();
|
||||
assert_eq!(base_fee, U256::from(507));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn json_genesis() {
|
||||
let geth_genesis = r#"
|
||||
|
||||
Reference in New Issue
Block a user