kona_genesis/
genesis.rs

1//! Genesis types.
2
3use alloy_eips::eip1898::BlockNumHash;
4
5use crate::SystemConfig;
6
7/// Chain genesis information.
8#[derive(Debug, Copy, Clone, Default, Hash, Eq, PartialEq)]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
11pub struct ChainGenesis {
12    /// L1 genesis block
13    pub l1: BlockNumHash,
14    /// L2 genesis block
15    pub l2: BlockNumHash,
16    /// Timestamp of the L2 genesis block
17    pub l2_time: u64,
18    /// Optional System configuration
19    pub system_config: Option<SystemConfig>,
20}
21
22#[cfg(feature = "arbitrary")]
23impl<'a> arbitrary::Arbitrary<'a> for ChainGenesis {
24    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
25        let system_config = Option::<SystemConfig>::arbitrary(u)?;
26        let l1_num_hash = BlockNumHash {
27            number: u64::arbitrary(u)?,
28            hash: alloy_primitives::B256::arbitrary(u)?,
29        };
30        let l2_num_hash = BlockNumHash {
31            number: u64::arbitrary(u)?,
32            hash: alloy_primitives::B256::arbitrary(u)?,
33        };
34        Ok(Self { l1: l1_num_hash, l2: l2_num_hash, l2_time: u.arbitrary()?, system_config })
35    }
36}
37
38#[cfg(test)]
39#[cfg(feature = "serde")]
40mod tests {
41    use super::*;
42    use alloy_primitives::{address, b256, uint};
43
44    const fn ref_genesis() -> ChainGenesis {
45        ChainGenesis {
46            l1: BlockNumHash {
47                hash: b256!("438335a20d98863a4c0c97999eb2481921ccd28553eac6f913af7c12aec04108"),
48                number: 17422590,
49            },
50            l2: BlockNumHash {
51                hash: b256!("dbf6a80fef073de06add9b0d14026d6e5a86c85f6d102c36d3d8e9cf89c2afd3"),
52                number: 105235063,
53            },
54            l2_time: 1686068903,
55            system_config: Some(SystemConfig {
56                batcher_address: address!("6887246668a3b87F54DeB3b94Ba47a6f63F32985"),
57                overhead: uint!(0xbc_U256),
58                scalar: uint!(0xa6fe0_U256),
59                gas_limit: 30000000,
60                base_fee_scalar: None,
61                blob_base_fee_scalar: None,
62                eip1559_denominator: None,
63                eip1559_elasticity: None,
64                operator_fee_scalar: None,
65                operator_fee_constant: None,
66            }),
67        }
68    }
69
70    #[test]
71    fn test_genesis_serde() {
72        let genesis_str = r#"{
73            "l1": {
74              "hash": "0x438335a20d98863a4c0c97999eb2481921ccd28553eac6f913af7c12aec04108",
75              "number": 17422590
76            },
77            "l2": {
78              "hash": "0xdbf6a80fef073de06add9b0d14026d6e5a86c85f6d102c36d3d8e9cf89c2afd3",
79              "number": 105235063
80            },
81            "l2_time": 1686068903,
82            "system_config": {
83              "batcherAddress": "0x6887246668a3b87F54DeB3b94Ba47a6f63F32985",
84              "overhead": "0x00000000000000000000000000000000000000000000000000000000000000bc",
85              "scalar": "0x00000000000000000000000000000000000000000000000000000000000a6fe0",
86              "gasLimit": 30000000
87            }
88          }"#;
89        let genesis: ChainGenesis = serde_json::from_str(genesis_str).unwrap();
90        assert_eq!(genesis, ref_genesis());
91    }
92
93    #[test]
94    fn test_genesis_unknown_field_json() {
95        let raw: &str = r#"{
96            "l1": {
97              "hash": "0x438335a20d98863a4c0c97999eb2481921ccd28553eac6f913af7c12aec04108",
98              "number": 17422590
99            },
100            "l2": {
101              "hash": "0xdbf6a80fef073de06add9b0d14026d6e5a86c85f6d102c36d3d8e9cf89c2afd3",
102              "number": 105235063
103            },
104            "l2_time": 1686068903,
105            "system_config": {
106              "batcherAddress": "0x6887246668a3b87F54DeB3b94Ba47a6f63F32985",
107              "overhead": "0x00000000000000000000000000000000000000000000000000000000000000bc",
108              "scalar": "0x00000000000000000000000000000000000000000000000000000000000a6fe0",
109              "gasLimit": 30000000
110            },
111            "unknown_field": "unknown"
112        }"#;
113
114        let err = serde_json::from_str::<ChainGenesis>(raw).unwrap_err();
115        assert_eq!(err.classify(), serde_json::error::Category::Data);
116    }
117}