seismic_node/
chainspec.rs

1use reth_chainspec::{ChainSpec, SEISMIC_DEV, SEISMIC_MAINNET};
2use reth_cli::chainspec::{parse_genesis, ChainSpecParser};
3use std::sync::Arc;
4
5/// Chains supported by reth. First value should be used as the default.
6pub const SUPPORTED_CHAINS: &[&str] = &["seismic", "dev"];
7
8/// Clap value parser for [`ChainSpec`]s.
9///
10/// The value parser matches either a known chain, the path
11/// to a json file, or a json formatted string in-memory. The json needs to be a Genesis struct.
12pub fn chain_value_parser(s: &str) -> eyre::Result<Arc<ChainSpec>, eyre::Error> {
13    Ok(match s {
14        "seismic" => SEISMIC_MAINNET.clone(),
15        "dev" => SEISMIC_DEV.clone(),
16        _ => Arc::new(parse_genesis(s)?.into()),
17    })
18}
19
20/// Ethereum chain specification parser.
21#[derive(Debug, Clone, Default)]
22#[non_exhaustive]
23pub struct SeismicChainSpecParser;
24
25impl ChainSpecParser for SeismicChainSpecParser {
26    type ChainSpec = ChainSpec;
27
28    const SUPPORTED_CHAINS: &'static [&'static str] = SUPPORTED_CHAINS;
29
30    fn parse(s: &str) -> eyre::Result<Arc<ChainSpec>> {
31        chain_value_parser(s)
32    }
33}
34
35#[cfg(test)]
36mod tests {
37    use super::*;
38    use reth_chainspec::EthereumHardforks;
39
40    #[test]
41    fn parse_known_chain_spec() {
42        for &chain in SeismicChainSpecParser::SUPPORTED_CHAINS {
43            assert!(<SeismicChainSpecParser as ChainSpecParser>::parse(chain).is_ok());
44        }
45    }
46
47    #[test]
48    fn parse_raw_chainspec_hardforks() {
49        let s = r#"{
50  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
51  "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
52  "coinbase": "0x0000000000000000000000000000000000000000",
53  "stateRoot": "0x76f118cb05a8bc558388df9e3b4ad66ae1f17ef656e5308cb8f600717251b509",
54  "transactionsTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
55  "receiptTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
56  "bloom": "0x000...000",
57  "difficulty": "0x00",
58  "number": "0x00",
59  "gasLimit": "0x016345785d8a0000",
60  "gasUsed": "0x00",
61  "timestamp": "0x01",
62  "extraData": "0x00",
63  "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
64  "nonce": "0x0000000000000000",
65  "baseFeePerGas": "0x07",
66  "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
67  "blobGasUsed": "0x00",
68  "excessBlobGas": "0x00",
69  "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
70  "requestsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
71  "hash": "0xc20e1a771553139cdc77e6c3d5f64a7165d972d327eee9632c9c7d0fe839ded4",
72  "alloc": {},
73  "config": {
74    "ethash": {},
75    "chainId": 1,
76    "homesteadBlock": 0,
77    "daoForkSupport": true,
78    "eip150Block": 0,
79    "eip155Block": 0,
80    "eip158Block": 0,
81    "byzantiumBlock": 0,
82    "constantinopleBlock": 0,
83    "petersburgBlock": 0,
84    "istanbulBlock": 0,
85    "berlinBlock": 0,
86    "londonBlock": 0,
87    "terminalTotalDifficulty": 0,
88    "shanghaiTime": 0,
89    "cancunTime": 0,
90    "pragueTime": 0,
91    "osakaTime": 0
92  }
93}"#;
94
95        let spec = <SeismicChainSpecParser as ChainSpecParser>::parse(s).unwrap();
96        assert!(spec.is_shanghai_active_at_timestamp(0));
97        assert!(spec.is_cancun_active_at_timestamp(0));
98        assert!(spec.is_prague_active_at_timestamp(0));
99        assert!(spec.is_osaka_active_at_timestamp(0));
100    }
101}