reth_chainspec/
api.rs

1use crate::{ChainSpec, DepositContract};
2use alloc::{boxed::Box, vec::Vec};
3use alloy_chains::Chain;
4use alloy_eips::{calc_next_block_base_fee, eip1559::BaseFeeParams, eip7840::BlobParams};
5use alloy_genesis::Genesis;
6use alloy_primitives::{B256, U256};
7use core::fmt::{Debug, Display};
8use reth_ethereum_forks::EthereumHardforks;
9use reth_network_peers::NodeRecord;
10use reth_primitives_traits::{AlloyBlockHeader, BlockHeader};
11
12/// Trait representing type configuring a chain spec.
13#[auto_impl::auto_impl(&, Arc)]
14pub trait EthChainSpec: Send + Sync + Unpin + Debug {
15    /// The header type of the network.
16    type Header: BlockHeader;
17
18    /// Returns the [`Chain`] object this spec targets.
19    fn chain(&self) -> Chain;
20
21    /// Returns the chain id number
22    fn chain_id(&self) -> u64 {
23        self.chain().id()
24    }
25
26    /// Get the [`BaseFeeParams`] for the chain at the given timestamp.
27    fn base_fee_params_at_timestamp(&self, timestamp: u64) -> BaseFeeParams;
28
29    /// Get the [`BlobParams`] for the given timestamp
30    fn blob_params_at_timestamp(&self, timestamp: u64) -> Option<BlobParams>;
31
32    /// Returns the deposit contract data for the chain, if it's present
33    fn deposit_contract(&self) -> Option<&DepositContract>;
34
35    /// The genesis hash.
36    fn genesis_hash(&self) -> B256;
37
38    /// The delete limit for pruner, per run.
39    fn prune_delete_limit(&self) -> usize;
40
41    /// Returns a string representation of the hardforks.
42    fn display_hardforks(&self) -> Box<dyn Display>;
43
44    /// The genesis header.
45    fn genesis_header(&self) -> &Self::Header;
46
47    /// The genesis block specification.
48    fn genesis(&self) -> &Genesis;
49
50    /// The bootnodes for the chain, if any.
51    fn bootnodes(&self) -> Option<Vec<NodeRecord>>;
52
53    /// Returns `true` if this chain contains Optimism configuration.
54    fn is_optimism(&self) -> bool {
55        self.chain().is_optimism()
56    }
57
58    /// Returns `true` if this chain contains Ethereum configuration.
59    fn is_ethereum(&self) -> bool {
60        self.chain().is_ethereum()
61    }
62
63    /// Returns the final total difficulty if the Paris hardfork is known.
64    fn final_paris_total_difficulty(&self) -> Option<U256>;
65
66    /// See [`calc_next_block_base_fee`].
67    fn next_block_base_fee(&self, parent: &Self::Header, target_timestamp: u64) -> Option<u64> {
68        Some(calc_next_block_base_fee(
69            parent.gas_used(),
70            parent.gas_limit(),
71            parent.base_fee_per_gas()?,
72            self.base_fee_params_at_timestamp(target_timestamp),
73        ))
74    }
75}
76
77impl<H: BlockHeader> EthChainSpec for ChainSpec<H> {
78    type Header = H;
79
80    fn chain(&self) -> Chain {
81        self.chain
82    }
83
84    fn base_fee_params_at_timestamp(&self, timestamp: u64) -> BaseFeeParams {
85        self.base_fee_params_at_timestamp(timestamp)
86    }
87
88    fn blob_params_at_timestamp(&self, timestamp: u64) -> Option<BlobParams> {
89        if let Some(blob_param) = self.blob_params.active_scheduled_params_at_timestamp(timestamp) {
90            Some(*blob_param)
91        } else if self.is_osaka_active_at_timestamp(timestamp) {
92            Some(self.blob_params.osaka)
93        } else if self.is_prague_active_at_timestamp(timestamp) {
94            Some(self.blob_params.prague)
95        } else if self.is_cancun_active_at_timestamp(timestamp) {
96            Some(self.blob_params.cancun)
97        } else {
98            None
99        }
100    }
101
102    fn deposit_contract(&self) -> Option<&DepositContract> {
103        self.deposit_contract.as_ref()
104    }
105
106    fn genesis_hash(&self) -> B256 {
107        self.genesis_hash()
108    }
109
110    fn prune_delete_limit(&self) -> usize {
111        self.prune_delete_limit
112    }
113
114    fn display_hardforks(&self) -> Box<dyn Display> {
115        Box::new(Self::display_hardforks(self))
116    }
117
118    fn genesis_header(&self) -> &Self::Header {
119        self.genesis_header()
120    }
121
122    fn genesis(&self) -> &Genesis {
123        self.genesis()
124    }
125
126    fn bootnodes(&self) -> Option<Vec<NodeRecord>> {
127        self.bootnodes()
128    }
129
130    fn is_optimism(&self) -> bool {
131        false
132    }
133
134    fn final_paris_total_difficulty(&self) -> Option<U256> {
135        self.paris_block_and_final_difficulty.map(|(_, final_difficulty)| final_difficulty)
136    }
137}