cbrzn_ethers_core/utils/
genesis.rs

1use std::collections::HashMap;
2
3use crate::{
4    types::{Address, Bytes, H256, U256, U64},
5    utils::{from_int_or_hex, from_int_or_hex_opt, from_u64_or_hex_opt},
6};
7use serde::{Deserialize, Serialize};
8
9/// This represents the chain configuration, specifying the genesis block, header fields, and hard
10/// fork switch blocks.
11#[derive(Clone, Debug, Default, Serialize, Deserialize)]
12#[serde(rename_all = "camelCase")]
13pub struct Genesis {
14    /// The fork configuration for this network.
15    #[serde(default)]
16    pub config: ChainConfig,
17
18    /// The genesis header nonce.
19    #[serde(default)]
20    pub nonce: U64,
21
22    /// The genesis header timestamp.
23    #[serde(default)]
24    pub timestamp: U64,
25
26    /// The genesis header extra data.
27    #[serde(default)]
28    pub extra_data: Bytes,
29
30    /// The genesis header gas limit.
31    pub gas_limit: U64,
32
33    /// The genesis header difficulty.
34    #[serde(deserialize_with = "from_int_or_hex")]
35    pub difficulty: U256,
36
37    /// The genesis header mix hash.
38    #[serde(default)]
39    pub mix_hash: H256,
40
41    /// The genesis header coinbase address.
42    #[serde(default)]
43    pub coinbase: Address,
44
45    /// The initial state of the genesis block.
46    pub alloc: HashMap<Address, GenesisAccount>,
47
48    // The following fields are only included for tests, and should not be used in real genesis
49    // blocks.
50    /// The block number
51    #[serde(skip_serializing_if = "Option::is_none", default)]
52    pub number: Option<U64>,
53
54    /// The block gas gasUsed
55    #[serde(skip_serializing_if = "Option::is_none", default)]
56    pub gas_used: Option<U64>,
57
58    /// The block parent hash
59    #[serde(skip_serializing_if = "Option::is_none", default)]
60    pub parent_hash: Option<H256>,
61
62    /// The base fee
63    #[serde(skip_serializing_if = "Option::is_none", default)]
64    pub base_fee_per_gas: Option<U256>,
65}
66
67impl Genesis {
68    /// Creates a chain config using the given chain id.
69    /// and funds the given address with max coins.
70    ///
71    /// Enables all hard forks up to London at genesis.
72    pub fn new(chain_id: u64, signer_addr: Address) -> Genesis {
73        // set up a clique config with an instant sealing period and short (8 block) epoch
74        let clique_config = CliqueConfig { period: Some(0), epoch: Some(8) };
75
76        let config = ChainConfig {
77            chain_id,
78            eip155_block: Some(0),
79            eip150_block: Some(0),
80            eip158_block: Some(0),
81
82            homestead_block: Some(0),
83            byzantium_block: Some(0),
84            constantinople_block: Some(0),
85            petersburg_block: Some(0),
86            istanbul_block: Some(0),
87            muir_glacier_block: Some(0),
88            berlin_block: Some(0),
89            london_block: Some(0),
90            clique: Some(clique_config),
91            ..Default::default()
92        };
93
94        // fund account
95        let mut alloc = HashMap::new();
96        alloc.insert(
97            signer_addr,
98            GenesisAccount { balance: U256::MAX, nonce: None, code: None, storage: None },
99        );
100
101        // put signer address in the extra data, padded by the required amount of zeros
102        // Clique issue: https://github.com/ethereum/EIPs/issues/225
103        // Clique EIP: https://eips.ethereum.org/EIPS/eip-225
104        //
105        // The first 32 bytes are vanity data, so we will populate it with zeros
106        // This is followed by the signer address, which is 20 bytes
107        // There are 65 bytes of zeros after the signer address, which is usually populated with the
108        // proposer signature. Because the genesis does not have a proposer signature, it will be
109        // populated with zeros.
110        let extra_data_bytes = [&[0u8; 32][..], signer_addr.as_bytes(), &[0u8; 65][..]].concat();
111        let extra_data = Bytes::from(extra_data_bytes);
112
113        Genesis {
114            config,
115            alloc,
116            difficulty: U256::one(),
117            gas_limit: U64::from(5000000),
118            extra_data,
119            ..Default::default()
120        }
121    }
122}
123
124/// An account in the state of the genesis block.
125#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
126pub struct GenesisAccount {
127    #[serde(
128        skip_serializing_if = "Option::is_none",
129        deserialize_with = "from_u64_or_hex_opt",
130        default
131    )]
132    pub nonce: Option<u64>,
133    pub balance: U256,
134    #[serde(skip_serializing_if = "Option::is_none", default)]
135    pub code: Option<Bytes>,
136    #[serde(flatten, skip_serializing_if = "Option::is_none", default)]
137    pub storage: Option<HashMap<H256, H256>>,
138}
139
140/// Represents a node's chain configuration.
141///
142/// See [geth's `ChainConfig`
143/// struct](https://github.com/ethereum/go-ethereum/blob/64dccf7aa411c5c7cd36090c3d9b9892945ae813/params/config.go#L349)
144/// for the source of each field.
145#[derive(Clone, Debug, Deserialize, Serialize, Default)]
146#[serde(default, rename_all = "camelCase")]
147pub struct ChainConfig {
148    /// The network's chain ID.
149    #[serde(default = "one")]
150    pub chain_id: u64,
151
152    /// The homestead switch block (None = no fork, 0 = already homestead).
153    #[serde(skip_serializing_if = "Option::is_none")]
154    pub homestead_block: Option<u64>,
155
156    /// The DAO fork switch block (None = no fork).
157    #[serde(skip_serializing_if = "Option::is_none")]
158    pub dao_fork_block: Option<u64>,
159
160    /// Whether or not the node supports the DAO hard-fork.
161    pub dao_fork_support: bool,
162
163    /// The EIP-150 hard fork block (None = no fork).
164    #[serde(skip_serializing_if = "Option::is_none")]
165    pub eip150_block: Option<u64>,
166
167    /// The EIP-150 hard fork hash.
168    #[serde(skip_serializing_if = "Option::is_none")]
169    pub eip150_hash: Option<H256>,
170
171    /// The EIP-155 hard fork block.
172    #[serde(skip_serializing_if = "Option::is_none")]
173    pub eip155_block: Option<u64>,
174
175    /// The EIP-158 hard fork block.
176    #[serde(skip_serializing_if = "Option::is_none")]
177    pub eip158_block: Option<u64>,
178
179    /// The Byzantium hard fork block.
180    #[serde(skip_serializing_if = "Option::is_none")]
181    pub byzantium_block: Option<u64>,
182
183    /// The Constantinople hard fork block.
184    #[serde(skip_serializing_if = "Option::is_none")]
185    pub constantinople_block: Option<u64>,
186
187    /// The Petersburg hard fork block.
188    #[serde(skip_serializing_if = "Option::is_none")]
189    pub petersburg_block: Option<u64>,
190
191    /// The Istanbul hard fork block.
192    #[serde(skip_serializing_if = "Option::is_none")]
193    pub istanbul_block: Option<u64>,
194
195    /// The Muir Glacier hard fork block.
196    #[serde(skip_serializing_if = "Option::is_none")]
197    pub muir_glacier_block: Option<u64>,
198
199    /// The Berlin hard fork block.
200    #[serde(skip_serializing_if = "Option::is_none")]
201    pub berlin_block: Option<u64>,
202
203    /// The London hard fork block.
204    #[serde(skip_serializing_if = "Option::is_none")]
205    pub london_block: Option<u64>,
206
207    /// The Arrow Glacier hard fork block.
208    #[serde(skip_serializing_if = "Option::is_none")]
209    pub arrow_glacier_block: Option<u64>,
210
211    /// The Gray Glacier hard fork block.
212    #[serde(skip_serializing_if = "Option::is_none")]
213    pub gray_glacier_block: Option<u64>,
214
215    /// Virtual fork after the merge to use as a network splitter.
216    #[serde(skip_serializing_if = "Option::is_none")]
217    pub merge_netsplit_block: Option<u64>,
218
219    /// Shanghai switch time.
220    #[serde(skip_serializing_if = "Option::is_none")]
221    pub shanghai_time: Option<u64>,
222
223    /// Cancun switch time.
224    #[serde(skip_serializing_if = "Option::is_none")]
225    pub cancun_time: Option<u64>,
226
227    /// Total difficulty reached that triggers the merge consensus upgrade.
228    #[serde(skip_serializing_if = "Option::is_none", deserialize_with = "from_int_or_hex_opt")]
229    pub terminal_total_difficulty: Option<U256>,
230
231    /// A flag specifying that the network already passed the terminal total difficulty. Its
232    /// purpose is to disable legacy sync without having seen the TTD locally.
233    pub terminal_total_difficulty_passed: bool,
234
235    /// Ethash parameters.
236    #[serde(skip_serializing_if = "Option::is_none")]
237    pub ethash: Option<EthashConfig>,
238
239    /// Clique parameters.
240    #[serde(skip_serializing_if = "Option::is_none")]
241    pub clique: Option<CliqueConfig>,
242}
243
244// used only for serde
245#[inline]
246const fn one() -> u64 {
247    1
248}
249
250/// Empty consensus configuration for proof-of-work networks.
251#[derive(Clone, Debug, Deserialize, Serialize)]
252pub struct EthashConfig {}
253
254/// Consensus configuration for Clique.
255#[derive(Clone, Debug, Deserialize, Serialize)]
256pub struct CliqueConfig {
257    /// Number of seconds between blocks to enforce.
258    #[serde(default, skip_serializing_if = "Option::is_none")]
259    pub period: Option<u64>,
260
261    /// Epoch length to reset votes and checkpoints.
262    #[serde(default, skip_serializing_if = "Option::is_none")]
263    pub epoch: Option<u64>,
264}
265
266#[cfg(test)]
267mod tests {
268    use super::{Genesis, H256};
269
270    #[test]
271    fn parse_hive_genesis() {
272        let geth_genesis = r#"
273        {
274            "difficulty": "0x20000",
275            "gasLimit": "0x1",
276            "alloc": {},
277            "config": {
278              "ethash": {},
279              "chainId": 1
280            }
281        }
282        "#;
283
284        let _genesis: Genesis = serde_json::from_str(geth_genesis).unwrap();
285    }
286
287    #[test]
288    fn parse_hive_clique_smoke_genesis() {
289        let geth_genesis = r#"
290        {
291          "difficulty": "0x1",
292          "gasLimit": "0x400000",
293          "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000658bdf435d810c91414ec09147daa6db624063790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
294          "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
295          "nonce": "0x0",
296          "timestamp": "0x5c51a607",
297          "alloc": {}
298        }
299        "#;
300
301        let _genesis: Genesis = serde_json::from_str(geth_genesis).unwrap();
302    }
303
304    #[test]
305    fn parse_hive_rpc_genesis() {
306        let geth_genesis = r#"
307        {
308          "config": {
309            "chainId": 7,
310            "homesteadBlock": 0,
311            "eip150Block": 0,
312            "eip150Hash": "0x5de1ee4135274003348e80b788e5afa4b18b18d320a5622218d5c493fedf5689",
313            "eip155Block": 0,
314            "eip158Block": 0
315          },
316          "coinbase": "0x0000000000000000000000000000000000000000",
317          "difficulty": "0x20000",
318          "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000658bdf435d810c91414ec09147daa6db624063790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
319          "gasLimit": "0x2fefd8",
320          "nonce": "0x0000000000000000",
321          "timestamp": "0x1234",
322          "alloc": {
323            "cf49fda3be353c69b41ed96333cd24302da4556f": {
324              "balance": "0x123450000000000000000"
325            },
326            "0161e041aad467a890839d5b08b138c1e6373072": {
327              "balance": "0x123450000000000000000"
328            },
329            "87da6a8c6e9eff15d703fc2773e32f6af8dbe301": {
330              "balance": "0x123450000000000000000"
331            },
332            "b97de4b8c857e4f6bc354f226dc3249aaee49209": {
333              "balance": "0x123450000000000000000"
334            },
335            "c5065c9eeebe6df2c2284d046bfc906501846c51": {
336              "balance": "0x123450000000000000000"
337            },
338            "0000000000000000000000000000000000000314": {
339              "balance": "0x0",
340              "code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063a223e05d1461006a578063abd1a0cf1461008d578063abfced1d146100d4578063e05c914a14610110578063e6768b451461014c575b610000565b346100005761007761019d565b6040518082815260200191505060405180910390f35b34610000576100be600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506101a3565b6040518082815260200191505060405180910390f35b346100005761010e600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506101ed565b005b346100005761014a600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610236565b005b346100005761017960048080359060200190919080359060200190919080359060200190919050506103c4565b60405180848152602001838152602001828152602001935050505060405180910390f35b60005481565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b919050565b80600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b5050565b7f6031a8d62d7c95988fa262657cd92107d90ed96e08d8f867d32f26edfe85502260405180905060405180910390a17f47e2689743f14e97f7dcfa5eec10ba1dff02f83b3d1d4b9c07b206cbbda66450826040518082815260200191505060405180910390a1817fa48a6b249a5084126c3da369fbc9b16827ead8cb5cdc094b717d3f1dcd995e2960405180905060405180910390a27f7890603b316f3509577afd111710f9ebeefa15e12f72347d9dffd0d65ae3bade81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18073ffffffffffffffffffffffffffffffffffffffff167f7efef9ea3f60ddc038e50cccec621f86a0195894dc0520482abf8b5c6b659e4160405180905060405180910390a28181604051808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a05b5050565b6000600060008585859250925092505b935093509390505600a165627a7a72305820aaf842d0d0c35c45622c5263cbb54813d2974d3999c8c38551d7c613ea2bc1170029",
341              "storage": {
342                "0x0000000000000000000000000000000000000000000000000000000000000000": "0x1234",
343                "0x6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9": "0x01"
344              }
345            },
346            "0000000000000000000000000000000000000315": {
347              "balance": "0x9999999999999999999999999999999",
348              "code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063ef2769ca1461003e575b610000565b3461000057610078600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061007a565b005b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051809050600060405180830381858888f1935050505015610106578173ffffffffffffffffffffffffffffffffffffffff167f30a3c50752f2552dcc2b93f5b96866280816a986c0c0408cb6778b9fa198288f826040518082815260200191505060405180910390a25b5b50505600a165627a7a72305820637991fabcc8abad4294bf2bb615db78fbec4edff1635a2647d3894e2daf6a610029"
349            }
350          }
351        }
352        "#;
353
354        let _genesis: Genesis = serde_json::from_str(geth_genesis).unwrap();
355    }
356
357    #[test]
358    fn parse_hive_graphql_genesis() {
359        let geth_genesis = r#"
360        {
361            "config"     : {},
362            "coinbase"   : "0x8888f1f195afa192cfee860698584c030f4c9db1",
363            "difficulty" : "0x020000",
364            "extraData"  : "0x42",
365            "gasLimit"   : "0x2fefd8",
366            "mixHash"    : "0x2c85bcbce56429100b2108254bb56906257582aeafcbd682bc9af67a9f5aee46",
367            "nonce"      : "0x78cc16f7b4f65485",
368            "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
369            "timestamp"  : "0x54c98c81",
370            "alloc"      : {
371                "a94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
372                    "balance" : "0x09184e72a000"
373                }
374            }
375        }
376        "#;
377
378        let _genesis: Genesis = serde_json::from_str(geth_genesis).unwrap();
379    }
380
381    #[test]
382    fn parse_hive_engine_genesis() {
383        let geth_genesis = r#"
384        {
385          "config": {
386            "chainId": 7,
387            "homesteadBlock": 0,
388            "eip150Block": 0,
389            "eip150Hash": "0x5de1ee4135274003348e80b788e5afa4b18b18d320a5622218d5c493fedf5689",
390            "eip155Block": 0,
391            "eip158Block": 0,
392            "byzantiumBlock": 0,
393            "constantinopleBlock": 0,
394            "petersburgBlock": 0,
395            "istanbulBlock": 0,
396            "muirGlacierBlock": 0,
397            "berlinBlock": 0,
398            "yolov2Block": 0,
399            "yolov3Block": 0,
400            "londonBlock": 0
401          },
402          "coinbase": "0x0000000000000000000000000000000000000000",
403          "difficulty": "0x30000",
404          "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000658bdf435d810c91414ec09147daa6db624063790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
405          "gasLimit": "0x2fefd8",
406          "nonce": "0x0000000000000000",
407          "timestamp": "0x1234",
408          "alloc": {
409            "cf49fda3be353c69b41ed96333cd24302da4556f": {
410              "balance": "0x123450000000000000000"
411            },
412            "0161e041aad467a890839d5b08b138c1e6373072": {
413              "balance": "0x123450000000000000000"
414            },
415            "87da6a8c6e9eff15d703fc2773e32f6af8dbe301": {
416              "balance": "0x123450000000000000000"
417            },
418            "b97de4b8c857e4f6bc354f226dc3249aaee49209": {
419              "balance": "0x123450000000000000000"
420            },
421            "c5065c9eeebe6df2c2284d046bfc906501846c51": {
422              "balance": "0x123450000000000000000"
423            },
424            "0000000000000000000000000000000000000314": {
425              "balance": "0x0",
426              "code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063a223e05d1461006a578063abd1a0cf1461008d578063abfced1d146100d4578063e05c914a14610110578063e6768b451461014c575b610000565b346100005761007761019d565b6040518082815260200191505060405180910390f35b34610000576100be600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506101a3565b6040518082815260200191505060405180910390f35b346100005761010e600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506101ed565b005b346100005761014a600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610236565b005b346100005761017960048080359060200190919080359060200190919080359060200190919050506103c4565b60405180848152602001838152602001828152602001935050505060405180910390f35b60005481565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b919050565b80600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b5050565b7f6031a8d62d7c95988fa262657cd92107d90ed96e08d8f867d32f26edfe85502260405180905060405180910390a17f47e2689743f14e97f7dcfa5eec10ba1dff02f83b3d1d4b9c07b206cbbda66450826040518082815260200191505060405180910390a1817fa48a6b249a5084126c3da369fbc9b16827ead8cb5cdc094b717d3f1dcd995e2960405180905060405180910390a27f7890603b316f3509577afd111710f9ebeefa15e12f72347d9dffd0d65ae3bade81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18073ffffffffffffffffffffffffffffffffffffffff167f7efef9ea3f60ddc038e50cccec621f86a0195894dc0520482abf8b5c6b659e4160405180905060405180910390a28181604051808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a05b5050565b6000600060008585859250925092505b935093509390505600a165627a7a72305820aaf842d0d0c35c45622c5263cbb54813d2974d3999c8c38551d7c613ea2bc1170029",
427              "storage": {
428                "0x0000000000000000000000000000000000000000000000000000000000000000": "0x1234",
429                "0x6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9": "0x01"
430              }
431            },
432            "0000000000000000000000000000000000000315": {
433              "balance": "0x9999999999999999999999999999999",
434              "code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063ef2769ca1461003e575b610000565b3461000057610078600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061007a565b005b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051809050600060405180830381858888f1935050505015610106578173ffffffffffffffffffffffffffffffffffffffff167f30a3c50752f2552dcc2b93f5b96866280816a986c0c0408cb6778b9fa198288f826040518082815260200191505060405180910390a25b5b50505600a165627a7a72305820637991fabcc8abad4294bf2bb615db78fbec4edff1635a2647d3894e2daf6a610029"
435            },
436            "0000000000000000000000000000000000000316": {
437              "balance": "0x0",
438              "code": "0x444355"
439            },
440            "0000000000000000000000000000000000000317": {
441              "balance": "0x0",
442              "code": "0x600160003555"
443            }
444          }
445        }
446        "#;
447
448        let _genesis: Genesis = serde_json::from_str(geth_genesis).unwrap();
449    }
450
451    #[test]
452    fn parse_hive_devp2p_genesis() {
453        let geth_genesis = r#"
454        {
455            "config": {
456                "chainId": 19763,
457                "homesteadBlock": 0,
458                "eip150Block": 0,
459                "eip155Block": 0,
460                "eip158Block": 0,
461                "byzantiumBlock": 0,
462                "ethash": {}
463            },
464            "nonce": "0xdeadbeefdeadbeef",
465            "timestamp": "0x0",
466            "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000",
467            "gasLimit": "0x80000000",
468            "difficulty": "0x20000",
469            "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
470            "coinbase": "0x0000000000000000000000000000000000000000",
471            "alloc": {
472                "71562b71999873db5b286df957af199ec94617f7": {
473                    "balance": "0xffffffffffffffffffffffffff"
474                }
475            },
476            "number": "0x0",
477            "gasUsed": "0x0",
478            "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
479        }
480        "#;
481
482        let _genesis: Genesis = serde_json::from_str(geth_genesis).unwrap();
483    }
484
485    #[test]
486    fn parse_execution_apis_genesis() {
487        let geth_genesis = r#"
488        {
489          "config": {
490            "chainId": 1337,
491            "homesteadBlock": 0,
492            "eip150Block": 0,
493            "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
494            "eip155Block": 0,
495            "eip158Block": 0,
496            "byzantiumBlock": 0,
497            "constantinopleBlock": 0,
498            "petersburgBlock": 0,
499            "istanbulBlock": 0,
500            "muirGlacierBlock": 0,
501            "berlinBlock": 0,
502            "londonBlock": 0,
503            "arrowGlacierBlock": 0,
504            "grayGlacierBlock": 0,
505            "shanghaiTime": 0,
506            "terminalTotalDifficulty": 0,
507            "terminalTotalDifficultyPassed": true,
508            "ethash": {}
509          },
510          "nonce": "0x0",
511          "timestamp": "0x0",
512          "extraData": "0x",
513          "gasLimit": "0x4c4b40",
514          "difficulty": "0x1",
515          "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
516          "coinbase": "0x0000000000000000000000000000000000000000",
517          "alloc": {
518            "658bdf435d810c91414ec09147daa6db62406379": {
519              "balance": "0x487a9a304539440000"
520            },
521            "aa00000000000000000000000000000000000000": {
522              "code": "0x6042",
523              "storage": {
524                "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000",
525                "0x0100000000000000000000000000000000000000000000000000000000000000": "0x0100000000000000000000000000000000000000000000000000000000000000",
526                "0x0200000000000000000000000000000000000000000000000000000000000000": "0x0200000000000000000000000000000000000000000000000000000000000000",
527                "0x0300000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000303"
528              },
529              "balance": "0x1",
530              "nonce": "0x1"
531            },
532            "bb00000000000000000000000000000000000000": {
533              "code": "0x600154600354",
534              "storage": {
535                "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000",
536                "0x0100000000000000000000000000000000000000000000000000000000000000": "0x0100000000000000000000000000000000000000000000000000000000000000",
537                "0x0200000000000000000000000000000000000000000000000000000000000000": "0x0200000000000000000000000000000000000000000000000000000000000000",
538                "0x0300000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000303"
539              },
540              "balance": "0x2",
541              "nonce": "0x1"
542            }
543          },
544          "number": "0x0",
545          "gasUsed": "0x0",
546          "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
547          "baseFeePerGas": "0x3b9aca00"
548        }
549        "#;
550
551        let genesis: Genesis = serde_json::from_str(geth_genesis).unwrap();
552
553        // ensure the test fields are parsed correctly
554        assert_eq!(genesis.base_fee_per_gas, Some(1000000000.into()));
555        assert_eq!(genesis.number, Some(0.into()));
556        assert_eq!(genesis.gas_used, Some(0.into()));
557        assert_eq!(genesis.parent_hash, Some(H256::zero()));
558    }
559
560    #[test]
561    fn parse_hive_rpc_genesis_full() {
562        let geth_genesis = r#"
563        {
564          "config": {
565            "clique": {
566              "period": 1
567            },
568            "chainId": 7,
569            "homesteadBlock": 0,
570            "eip150Block": 0,
571            "eip155Block": 0,
572            "eip158Block": 0
573          },
574          "coinbase": "0x0000000000000000000000000000000000000000",
575          "difficulty": "0x020000",
576          "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000658bdf435d810c91414ec09147daa6db624063790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
577          "gasLimit": "0x2fefd8",
578          "nonce": "0x0000000000000000",
579          "timestamp": "0x1234",
580          "alloc": {
581            "cf49fda3be353c69b41ed96333cd24302da4556f": {
582              "balance": "0x123450000000000000000"
583            },
584            "0161e041aad467a890839d5b08b138c1e6373072": {
585              "balance": "0x123450000000000000000"
586            },
587            "87da6a8c6e9eff15d703fc2773e32f6af8dbe301": {
588              "balance": "0x123450000000000000000"
589            },
590            "b97de4b8c857e4f6bc354f226dc3249aaee49209": {
591              "balance": "0x123450000000000000000"
592            },
593            "c5065c9eeebe6df2c2284d046bfc906501846c51": {
594              "balance": "0x123450000000000000000"
595            },
596            "0000000000000000000000000000000000000314": {
597              "balance": "0x0",
598              "code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063a223e05d1461006a578063abd1a0cf1461008d578063abfced1d146100d4578063e05c914a14610110578063e6768b451461014c575b610000565b346100005761007761019d565b6040518082815260200191505060405180910390f35b34610000576100be600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506101a3565b6040518082815260200191505060405180910390f35b346100005761010e600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506101ed565b005b346100005761014a600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610236565b005b346100005761017960048080359060200190919080359060200190919080359060200190919050506103c4565b60405180848152602001838152602001828152602001935050505060405180910390f35b60005481565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b919050565b80600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b5050565b7f6031a8d62d7c95988fa262657cd92107d90ed96e08d8f867d32f26edfe85502260405180905060405180910390a17f47e2689743f14e97f7dcfa5eec10ba1dff02f83b3d1d4b9c07b206cbbda66450826040518082815260200191505060405180910390a1817fa48a6b249a5084126c3da369fbc9b16827ead8cb5cdc094b717d3f1dcd995e2960405180905060405180910390a27f7890603b316f3509577afd111710f9ebeefa15e12f72347d9dffd0d65ae3bade81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18073ffffffffffffffffffffffffffffffffffffffff167f7efef9ea3f60ddc038e50cccec621f86a0195894dc0520482abf8b5c6b659e4160405180905060405180910390a28181604051808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a05b5050565b6000600060008585859250925092505b935093509390505600a165627a7a72305820aaf842d0d0c35c45622c5263cbb54813d2974d3999c8c38551d7c613ea2bc1170029",
599              "storage": {
600                "0x0000000000000000000000000000000000000000000000000000000000000000": "0x1234",
601                "0x6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9": "0x01"
602              }
603            },
604            "0000000000000000000000000000000000000315": {
605              "balance": "0x9999999999999999999999999999999",
606              "code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063ef2769ca1461003e575b610000565b3461000057610078600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061007a565b005b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051809050600060405180830381858888f1935050505015610106578173ffffffffffffffffffffffffffffffffffffffff167f30a3c50752f2552dcc2b93f5b96866280816a986c0c0408cb6778b9fa198288f826040518082815260200191505060405180910390a25b5b50505600a165627a7a72305820637991fabcc8abad4294bf2bb615db78fbec4edff1635a2647d3894e2daf6a610029"
607            }
608          },
609          "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
610          "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
611        }
612        "#;
613
614        let _genesis: Genesis = serde_json::from_str(geth_genesis).unwrap();
615    }
616}