Skip to content

Commit 921cdfe

Browse files
authored
feat(genesis): add host genesis files (#52)
- [x] Pecorino host genesis file - [x] Ethereum mainnet genesis file - [x] Localnet genesis file Closes ENG-1591
1 parent 80d7c1a commit 921cdfe

File tree

7 files changed

+27878
-43
lines changed

7 files changed

+27878
-43
lines changed

crates/genesis/README.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ Genesis configuration and utilities for the Signet Node.
44

55
This library contains the following:
66

7-
- `GenesisSpec` - An enum representing different genesis specifications, either
8-
Pecorino, Test, or a custom genesis file path, which can be used to load
9-
genesis data.
10-
- `PECORINO_GENESIS` - The Pecorino genesis data.
11-
- `TEST_GENESIS` - A local test genesis for testing purposes.
7+
- `GenesisSpec` - An enum representing different genesis specifications (Mainnet,
8+
Pecorino, Test, or custom file paths), which can be used to load genesis data.
9+
- `NetworkGenesis` - A struct containing both rollup and host genesis configurations.
10+
- `PECORINO_GENESIS` / `PECORINO_HOST_GENESIS` - The Pecorino genesis data.
11+
- `TEST_GENESIS` / `TEST_HOST_GENESIS` - Local test genesis for testing purposes.
1212
- `GenesisError` - Errors that can occur when loading or parsing genesis data.
1313

1414
## Example
@@ -17,6 +17,10 @@ This library contains the following:
1717
# use signet_genesis::GenesisSpec;
1818
# fn _main() -> Result<(), Box<dyn std::error::Error>> {
1919
let genesis = GenesisSpec::Pecorino.load_genesis()?;
20+
// Access rollup (L2/Signet) genesis
21+
let rollup = &genesis.rollup;
22+
// Access host (L1/Ethereum) genesis
23+
let host = &genesis.host;
2024
# Ok(())
2125
# }
2226
```

crates/genesis/src/lib.rs

Lines changed: 119 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,56 @@ use std::{borrow::Cow, path::PathBuf, str::FromStr, sync::LazyLock};
2121
/// Signet mainnet genesis file.
2222
pub const MAINNET_GENESIS_JSON: &str = include_str!("./mainnet.genesis.json");
2323

24+
/// Signet mainnet host genesis file.
25+
pub const MAINNET_HOST_GENESIS_JSON: &str = include_str!("./mainnet.host.genesis.json");
26+
2427
/// Pecorino genesis file.
2528
pub const PECORINO_GENESIS_JSON: &str = include_str!("./pecorino.genesis.json");
2629

30+
/// Pecorino host genesis file.
31+
pub const PECORINO_HOST_GENESIS_JSON: &str = include_str!("./pecorino.host.genesis.json");
32+
2733
/// Local genesis file for testing purposes.
2834
pub const TEST_GENESIS_JSON: &str = include_str!("./local.genesis.json");
2935

36+
/// Local host genesis file for testing purposes.
37+
pub const TEST_HOST_GENESIS_JSON: &str = include_str!("./local.host.genesis.json");
38+
3039
/// Mainnet genesis for the Signet mainnet.
3140
pub static MAINNET_GENESIS: LazyLock<Genesis> = LazyLock::new(|| {
3241
serde_json::from_str(MAINNET_GENESIS_JSON).expect("Failed to parse mainnet genesis")
3342
});
3443

44+
/// Signet mainnet host genesis for the Signet mainnet.
45+
pub static MAINNET_HOST_GENESIS: LazyLock<Genesis> = LazyLock::new(|| {
46+
serde_json::from_str(MAINNET_HOST_GENESIS_JSON).expect("Failed to parse mainnet host genesis")
47+
});
48+
3549
/// Genesis for the Pecorino testnet.
3650
pub static PECORINO_GENESIS: LazyLock<Genesis> = LazyLock::new(|| {
3751
serde_json::from_str(PECORINO_GENESIS_JSON).expect("Failed to parse pecorino genesis")
3852
});
3953

54+
/// Genesis for the Pecorino host testnet.
55+
pub static PECORINO_HOST_GENESIS: LazyLock<Genesis> = LazyLock::new(|| {
56+
serde_json::from_str(PECORINO_HOST_GENESIS_JSON).expect("Failed to parse pecorino host genesis")
57+
});
58+
4059
/// Test genesis for local testing.
4160
pub static TEST_GENESIS: LazyLock<Genesis> = LazyLock::new(|| {
4261
serde_json::from_str(TEST_GENESIS_JSON).expect("Failed to parse test genesis")
4362
});
4463

45-
/// Environment variable for specifying the genesis JSON file path.
46-
const GENESIS_JSON_PATH: &str = "GENESIS_JSON_PATH";
64+
/// Test host genesis for local testing.
65+
pub static TEST_HOST_GENESIS: LazyLock<Genesis> = LazyLock::new(|| {
66+
serde_json::from_str(TEST_HOST_GENESIS_JSON).expect("Failed to parse test host genesis")
67+
});
68+
69+
/// Environment variable for specifying the rollup genesis JSON file path.
70+
const ROLLUP_GENESIS_JSON_PATH: &str = "ROLLUP_GENESIS_JSON_PATH";
71+
72+
/// Environment variable for specifying the host genesis JSON file path.
73+
const HOST_GENESIS_JSON_PATH: &str = "HOST_GENESIS_JSON_PATH";
4774

4875
/// Result type for genesis operations.
4976
pub type Result<T, E = GenesisError> = std::result::Result<T, E>;
@@ -59,6 +86,24 @@ pub enum GenesisError {
5986
Json(#[from] serde_json::Error),
6087
}
6188

89+
/// Genesis configurations for a network, containing both rollup and host chain genesis.
90+
#[derive(Debug, Clone)]
91+
pub struct NetworkGenesis {
92+
/// The rollup genesis configuration.
93+
pub rollup: Genesis,
94+
/// The host genesis configuration.
95+
pub host: Genesis,
96+
}
97+
98+
/// Raw genesis JSON strings for a network.
99+
#[derive(Debug, Clone)]
100+
pub struct RawNetworkGenesis {
101+
/// The rollup genesis JSON.
102+
pub rollup: Cow<'static, str>,
103+
/// The host genesis JSON.
104+
pub host: Cow<'static, str>,
105+
}
106+
62107
/// Different genesis configurations available.
63108
#[derive(Debug, Clone, serde::Deserialize)]
64109
#[serde(untagged)]
@@ -69,49 +114,80 @@ pub enum GenesisSpec {
69114
Pecorino,
70115
/// Local testnet.
71116
Test,
72-
/// Custom path to a genesis file.
73-
Path(PathBuf),
117+
/// Custom paths to genesis files.
118+
Custom {
119+
/// Path to the rollup genesis file.
120+
rollup: PathBuf,
121+
/// Path to the host genesis file.
122+
host: PathBuf,
123+
},
74124
}
75125

76126
impl GenesisSpec {
77-
/// Load the genesis JSON from the specified source.
127+
/// Load the raw genesis JSON strings from the specified source.
78128
///
79-
/// This will alwys return a valid string for [`KnownChains`].
80-
pub fn load_raw_genesis(&self) -> Result<Cow<'static, str>> {
129+
/// Returns both rollup and host genesis JSON strings.
130+
pub fn load_raw_genesis(&self) -> Result<RawNetworkGenesis> {
81131
match self {
82-
GenesisSpec::Mainnet => Ok(Cow::Borrowed(MAINNET_GENESIS_JSON)),
83-
GenesisSpec::Pecorino => Ok(Cow::Borrowed(PECORINO_GENESIS_JSON)),
84-
GenesisSpec::Test => Ok(Cow::Borrowed(TEST_GENESIS_JSON)),
85-
GenesisSpec::Path(path) => {
86-
std::fs::read_to_string(path).map(Cow::Owned).map_err(Into::into)
87-
}
132+
GenesisSpec::Mainnet => Ok(RawNetworkGenesis {
133+
rollup: Cow::Borrowed(MAINNET_GENESIS_JSON),
134+
host: Cow::Borrowed(MAINNET_HOST_GENESIS_JSON),
135+
}),
136+
GenesisSpec::Pecorino => Ok(RawNetworkGenesis {
137+
rollup: Cow::Borrowed(PECORINO_GENESIS_JSON),
138+
host: Cow::Borrowed(PECORINO_HOST_GENESIS_JSON),
139+
}),
140+
GenesisSpec::Test => Ok(RawNetworkGenesis {
141+
rollup: Cow::Borrowed(TEST_GENESIS_JSON),
142+
host: Cow::Borrowed(TEST_HOST_GENESIS_JSON),
143+
}),
144+
GenesisSpec::Custom { rollup, host } => Ok(RawNetworkGenesis {
145+
rollup: Cow::Owned(std::fs::read_to_string(rollup)?),
146+
host: Cow::Owned(std::fs::read_to_string(host)?),
147+
}),
88148
}
89149
}
90150

91-
/// Load the genesis from the specified source.
151+
/// Load the genesis configurations from the specified source.
92152
///
93-
/// This will always return a valid genesis for [`KnownChains`].
94-
pub fn load_genesis(&self) -> Result<alloy::genesis::Genesis> {
153+
/// Returns both rollup and host genesis configurations.
154+
pub fn load_genesis(&self) -> Result<NetworkGenesis> {
95155
match self {
96-
GenesisSpec::Mainnet => Ok(MAINNET_GENESIS.clone()),
97-
GenesisSpec::Pecorino => Ok(PECORINO_GENESIS.clone()),
98-
GenesisSpec::Test => Ok(TEST_GENESIS.clone()),
99-
GenesisSpec::Path(_) => self
100-
.load_raw_genesis()
101-
.and_then(|raw| serde_json::from_str(&raw).map_err(Into::into)),
156+
GenesisSpec::Mainnet => Ok(NetworkGenesis {
157+
rollup: MAINNET_GENESIS.clone(),
158+
host: MAINNET_HOST_GENESIS.clone(),
159+
}),
160+
GenesisSpec::Pecorino => Ok(NetworkGenesis {
161+
rollup: PECORINO_GENESIS.clone(),
162+
host: PECORINO_HOST_GENESIS.clone(),
163+
}),
164+
GenesisSpec::Test => {
165+
Ok(NetworkGenesis { rollup: TEST_GENESIS.clone(), host: TEST_HOST_GENESIS.clone() })
166+
}
167+
GenesisSpec::Custom { .. } => self.load_raw_genesis().and_then(|genesis| {
168+
Ok(NetworkGenesis {
169+
rollup: serde_json::from_str(&genesis.rollup)?,
170+
host: serde_json::from_str(&genesis.host)?,
171+
})
172+
}),
102173
}
103174
}
104175
}
105176

177+
/// Error returned when parsing an unknown chain name.
178+
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
179+
#[error("unknown chain name: {0}")]
180+
pub struct UnknownChainError(String);
181+
106182
impl FromStr for GenesisSpec {
107-
type Err = <PathBuf as FromStr>::Err;
183+
type Err = UnknownChainError;
108184

109185
fn from_str(s: &str) -> Result<Self, Self::Err> {
110186
if let Ok(known) = KnownChains::from_str(s) {
111187
return Ok(known.into());
112188
}
113189

114-
Ok(GenesisSpec::Path(s.parse()?))
190+
Err(UnknownChainError(s.to_string()))
115191
}
116192
}
117193

@@ -134,17 +210,31 @@ impl FromEnv for GenesisSpec {
134210
optional: true,
135211
},
136212
&EnvItemInfo {
137-
var: GENESIS_JSON_PATH,
138-
description: "A filepath to the genesis JSON file. Required if CHAIN_NAME is not set.",
213+
var: ROLLUP_GENESIS_JSON_PATH,
214+
description: "A filepath to the rollup genesis JSON file. Required if CHAIN_NAME is not set.",
215+
optional: true,
216+
},
217+
&EnvItemInfo {
218+
var: HOST_GENESIS_JSON_PATH,
219+
description: "A filepath to the host genesis JSON file. Required if CHAIN_NAME is not set.",
139220
optional: true,
140221
},
141222
]
142223
}
143224

144225
fn from_env() -> Result<Self, FromEnvErr<Self::Error>> {
145-
parse_env_if_present::<KnownChains>("CHAIN_NAME")
146-
.map(Into::into)
147-
.or_else(|_| parse_env_if_present::<PathBuf>(GENESIS_JSON_PATH).map(Into::into))
226+
// First try to parse from CHAIN_NAME
227+
if let Ok(spec) = parse_env_if_present::<KnownChains>("CHAIN_NAME").map(Into::into) {
228+
return Ok(spec);
229+
}
230+
231+
// Otherwise, try to load from custom paths
232+
let rollup = parse_env_if_present::<PathBuf>(ROLLUP_GENESIS_JSON_PATH)
233+
.map_err(|_| FromEnvErr::empty(ROLLUP_GENESIS_JSON_PATH))?;
234+
let host = parse_env_if_present::<PathBuf>(HOST_GENESIS_JSON_PATH)
235+
.map_err(|_| FromEnvErr::empty(HOST_GENESIS_JSON_PATH))?;
236+
237+
Ok(GenesisSpec::Custom { rollup, host })
148238
}
149239
}
150240

@@ -156,9 +246,3 @@ impl From<KnownChains> for GenesisSpec {
156246
}
157247
}
158248
}
159-
160-
impl From<PathBuf> for GenesisSpec {
161-
fn from(path: PathBuf) -> Self {
162-
GenesisSpec::Path(path)
163-
}
164-
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"chainId": 1,
3+
"homesteadBlock": 1150000,
4+
"daoForkBlock": 1920000,
5+
"daoForkSupport": true,
6+
"eip150Block": 2463000,
7+
"eip155Block": 2675000,
8+
"eip158Block": 2675000,
9+
"byzantiumBlock": 4370000,
10+
"constantinopleBlock": 7280000,
11+
"petersburgBlock": 7280000,
12+
"istanbulBlock": 9069000,
13+
"muirGlacierBlock": 9200000,
14+
"berlinBlock": 12244000,
15+
"londonBlock": 12965000,
16+
"arrowGlacierBlock": 13773000,
17+
"grayGlacierBlock": 15050000,
18+
"shanghaiTime": 1681338455,
19+
"cancunTime": 1710338135,
20+
"pragueTime": 1746612311,
21+
"osakaTime": 1764798551,
22+
"bpo1Time": 1765290071,
23+
"bpo2Time": 1767747671,
24+
"terminalTotalDifficulty": 58750000000000000000000,
25+
"terminalTotalDifficultyPassed": true,
26+
"depositContractAddress": "0x00000000219ab540356cbb839cbe05303d7705fa",
27+
"ethash": {},
28+
"blobSchedule": {
29+
"cancun": {
30+
"target": 3,
31+
"max": 6,
32+
"baseFeeUpdateFraction": 3338477
33+
},
34+
"prague": {
35+
"target": 6,
36+
"max": 9,
37+
"baseFeeUpdateFraction": 5007716
38+
},
39+
"osaka": {
40+
"target": 6,
41+
"max": 9,
42+
"baseFeeUpdateFraction": 5007716
43+
},
44+
"bpo1": {
45+
"target": 10,
46+
"max": 15,
47+
"baseFeeUpdateFraction": 8346193
48+
},
49+
"bpo2": {
50+
"target": 14,
51+
"max": 21,
52+
"baseFeeUpdateFraction": 11684671
53+
}
54+
}
55+
}

0 commit comments

Comments
 (0)