reth_chainspec/
api.rs

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