Skip to content

Commit eaaa607

Browse files
committed
feat: new genesis loading API
1 parent 137e683 commit eaaa607

File tree

4 files changed

+115
-43
lines changed

4 files changed

+115
-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: 103 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ pub const PECORINO_HOST_GENESIS_JSON: &str = include_str!("./pecorino.host.genes
3333
/// Local genesis file for testing purposes.
3434
pub const TEST_GENESIS_JSON: &str = include_str!("./local.genesis.json");
3535

36+
/// Local host genesis file for testing purposes.
37+
pub const TEST_HOST_GENESIS_JSON: &str = include_str!("./local.host.genesis.json");
38+
3639
/// Mainnet genesis for the Signet mainnet.
3740
pub static MAINNET_GENESIS: LazyLock<Genesis> = LazyLock::new(|| {
3841
serde_json::from_str(MAINNET_GENESIS_JSON).expect("Failed to parse mainnet genesis")
@@ -58,8 +61,16 @@ pub static TEST_GENESIS: LazyLock<Genesis> = LazyLock::new(|| {
5861
serde_json::from_str(TEST_GENESIS_JSON).expect("Failed to parse test genesis")
5962
});
6063

61-
/// Environment variable for specifying the genesis JSON file path.
62-
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";
6374

6475
/// Result type for genesis operations.
6576
pub type Result<T, E = GenesisError> = std::result::Result<T, E>;
@@ -75,6 +86,24 @@ pub enum GenesisError {
7586
Json(#[from] serde_json::Error),
7687
}
7788

89+
/// Genesis configurations for a network, containing both rollup and host chain genesis.
90+
#[derive(Debug, Clone)]
91+
pub struct NetworkGenesis {
92+
/// The rollup (L2/Signet) genesis configuration.
93+
pub rollup: Genesis,
94+
/// The host (L1/Ethereum) 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 (L2/Signet) genesis JSON.
102+
pub rollup: Cow<'static, str>,
103+
/// The host (L1/Ethereum) genesis JSON.
104+
pub host: Cow<'static, str>,
105+
}
106+
78107
/// Different genesis configurations available.
79108
#[derive(Debug, Clone, serde::Deserialize)]
80109
#[serde(untagged)]
@@ -85,49 +114,80 @@ pub enum GenesisSpec {
85114
Pecorino,
86115
/// Local testnet.
87116
Test,
88-
/// Custom path to a genesis file.
89-
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+
},
90124
}
91125

92126
impl GenesisSpec {
93-
/// Load the genesis JSON from the specified source.
127+
/// Load the raw genesis JSON strings from the specified source.
94128
///
95-
/// This will alwys return a valid string for [`KnownChains`].
96-
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> {
97131
match self {
98-
GenesisSpec::Mainnet => Ok(Cow::Borrowed(MAINNET_GENESIS_JSON)),
99-
GenesisSpec::Pecorino => Ok(Cow::Borrowed(PECORINO_GENESIS_JSON)),
100-
GenesisSpec::Test => Ok(Cow::Borrowed(TEST_GENESIS_JSON)),
101-
GenesisSpec::Path(path) => {
102-
std::fs::read_to_string(path).map(Cow::Owned).map_err(Into::into)
103-
}
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+
}),
104148
}
105149
}
106150

107-
/// Load the genesis from the specified source.
151+
/// Load the genesis configurations from the specified source.
108152
///
109-
/// This will always return a valid genesis for [`KnownChains`].
110-
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> {
111155
match self {
112-
GenesisSpec::Mainnet => Ok(MAINNET_GENESIS.clone()),
113-
GenesisSpec::Pecorino => Ok(PECORINO_GENESIS.clone()),
114-
GenesisSpec::Test => Ok(TEST_GENESIS.clone()),
115-
GenesisSpec::Path(_) => self
116-
.load_raw_genesis()
117-
.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+
}),
118173
}
119174
}
120175
}
121176

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+
122182
impl FromStr for GenesisSpec {
123-
type Err = <PathBuf as FromStr>::Err;
183+
type Err = UnknownChainError;
124184

125185
fn from_str(s: &str) -> Result<Self, Self::Err> {
126186
if let Ok(known) = KnownChains::from_str(s) {
127187
return Ok(known.into());
128188
}
129189

130-
Ok(GenesisSpec::Path(s.parse()?))
190+
Err(UnknownChainError(s.to_string()))
131191
}
132192
}
133193

@@ -150,17 +210,31 @@ impl FromEnv for GenesisSpec {
150210
optional: true,
151211
},
152212
&EnvItemInfo {
153-
var: GENESIS_JSON_PATH,
154-
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.",
155220
optional: true,
156221
},
157222
]
158223
}
159224

160225
fn from_env() -> Result<Self, FromEnvErr<Self::Error>> {
161-
parse_env_if_present::<KnownChains>("CHAIN_NAME")
162-
.map(Into::into)
163-
.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 })
164238
}
165239
}
166240

@@ -172,9 +246,3 @@ impl From<KnownChains> for GenesisSpec {
172246
}
173247
}
174248
}
175-
176-
impl From<PathBuf> for GenesisSpec {
177-
fn from(path: PathBuf) -> Self {
178-
GenesisSpec::Path(path)
179-
}
180-
}

crates/node-config/src/core.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,10 +196,10 @@ impl SignetNodeConfig {
196196
self.ipc_endpoint = Some(endpoint);
197197
}
198198

199-
/// Returns the genesis configuration if any has been loaded
199+
/// Returns the rollup genesis configuration if any has been loaded.
200200
pub fn genesis(&self) -> &'static Genesis {
201201
static ONCE: OnceLock<Genesis> = OnceLock::new();
202-
ONCE.get_or_init(|| self.genesis.load_genesis().expect("Failed to load genesis"))
202+
ONCE.get_or_init(|| self.genesis.load_genesis().expect("Failed to load genesis").rollup)
203203
}
204204

205205
/// Create a new chain spec for the Signet Node chain.

crates/node-tests/tests/basic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ async fn test_basic_reorg() {
7070
async fn test_genesis_allocs() {
7171
run_test(|ctx| async move {
7272
let genesis = GenesisSpec::Test.load_genesis().expect("Failed to load genesis");
73-
ctx.verify_allocs(&genesis);
73+
ctx.verify_allocs(&genesis.rollup);
7474
})
7575
.await;
7676
}

0 commit comments

Comments
 (0)