custom_hardforks/
chainspec.rs1use alloy_eips::eip7840::BlobParams;
7use alloy_genesis::Genesis;
8use alloy_primitives::{B256, U256};
9use reth_chainspec::{
10 hardfork, BaseFeeParams, Chain, ChainSpec, DepositContract, EthChainSpec, EthereumHardfork,
11 EthereumHardforks, ForkCondition, Hardfork, Hardforks,
12};
13use reth_network_peers::NodeRecord;
14use serde::{Deserialize, Serialize};
15
16hardfork!(
19 CustomHardfork {
24 BasicUpgrade,
26 AdvancedUpgrade,
28 }
29);
30
31#[derive(Debug, Clone, Serialize, Deserialize, Default)]
38#[serde(rename_all = "camelCase")]
39pub struct CustomHardforkConfig {
40 pub basic_upgrade_block: u64,
42 pub advanced_upgrade_block: u64,
44}
45
46#[derive(Debug, Clone)]
48pub struct CustomChainSpec {
49 pub inner: ChainSpec,
50}
51
52impl CustomChainSpec {
53 pub fn from_genesis(genesis: Genesis) -> Self {
57 let extra = genesis.config.extra_fields.deserialize_as::<CustomHardforkConfig>().unwrap();
58
59 let mut inner = ChainSpec::from_genesis(genesis);
60 inner.hardforks.insert(
61 CustomHardfork::BasicUpgrade,
62 ForkCondition::Timestamp(extra.basic_upgrade_block),
63 );
64 inner.hardforks.insert(
65 CustomHardfork::AdvancedUpgrade,
66 ForkCondition::Timestamp(extra.advanced_upgrade_block),
67 );
68 Self { inner }
69 }
70}
71
72impl Hardforks for CustomChainSpec {
74 fn fork<H: Hardfork>(&self, fork: H) -> ForkCondition {
75 self.inner.fork(fork)
76 }
77
78 fn forks_iter(&self) -> impl Iterator<Item = (&dyn Hardfork, ForkCondition)> {
79 self.inner.forks_iter()
80 }
81
82 fn fork_id(&self, head: &reth_chainspec::Head) -> reth_chainspec::ForkId {
83 self.inner.fork_id(head)
84 }
85
86 fn latest_fork_id(&self) -> reth_chainspec::ForkId {
87 self.inner.latest_fork_id()
88 }
89
90 fn fork_filter(&self, head: reth_chainspec::Head) -> reth_chainspec::ForkFilter {
91 self.inner.fork_filter(head)
92 }
93}
94
95impl EthChainSpec for CustomChainSpec {
97 type Header = alloy_consensus::Header;
98
99 fn chain(&self) -> Chain {
100 self.inner.chain()
101 }
102
103 fn base_fee_params_at_timestamp(&self, timestamp: u64) -> BaseFeeParams {
104 self.inner.base_fee_params_at_timestamp(timestamp)
105 }
106
107 fn blob_params_at_timestamp(&self, timestamp: u64) -> Option<BlobParams> {
108 self.inner.blob_params_at_timestamp(timestamp)
109 }
110
111 fn deposit_contract(&self) -> Option<&DepositContract> {
112 self.inner.deposit_contract()
113 }
114
115 fn genesis_hash(&self) -> B256 {
116 self.inner.genesis_hash()
117 }
118
119 fn prune_delete_limit(&self) -> usize {
120 self.inner.prune_delete_limit()
121 }
122
123 fn display_hardforks(&self) -> Box<dyn core::fmt::Display> {
124 Box::new(self.inner.display_hardforks())
125 }
126
127 fn genesis_header(&self) -> &Self::Header {
128 self.inner.genesis_header()
129 }
130
131 fn genesis(&self) -> &Genesis {
132 self.inner.genesis()
133 }
134
135 fn bootnodes(&self) -> Option<Vec<NodeRecord>> {
136 self.inner.bootnodes()
137 }
138
139 fn final_paris_total_difficulty(&self) -> Option<U256> {
140 self.inner.final_paris_total_difficulty()
141 }
142}
143
144impl EthereumHardforks for CustomChainSpec {
146 fn ethereum_fork_activation(&self, fork: EthereumHardfork) -> ForkCondition {
147 self.inner.ethereum_fork_activation(fork)
148 }
149}