Skip to content

Commit ff50ee9

Browse files
committed
feat(sp1-cc-host): allow custom chains
1 parent b20a765 commit ff50ee9

File tree

7 files changed

+78
-43
lines changed

7 files changed

+78
-43
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ resolver = "2"
33
members = [
44
"bin/*",
55
"crates/*",
6-
"example/preloader",
6+
"example/preloader",
77
"canoe/bindings",
88
"canoe/provider",
99
"canoe/steel/apps",
1010
"canoe/steel/methods",
11-
"canoe/steel/verifier",
11+
"canoe/steel/verifier",
1212
"canoe/sp1-cc/host",
1313
"canoe/sp1-cc/client",
1414
"canoe/sp1-cc/vkey-bin",
@@ -55,12 +55,12 @@ hokulea-zkvm-verification = { path = "crates/zkvm-verification", version = "0.1.
5555
eigenda-cert = { path = "crates/eigenda-cert" }
5656

5757
# Alloy (Network)
58-
alloy-rlp = { version = "0.3.12", default-features = false }
59-
alloy-provider = { version = "1.0.38", default-features = false }
6058
alloy-consensus = { version = "1.0.38", default-features = false }
61-
alloy-rpc-types = { version = "1.0.38", default-features = false }
6259
alloy-genesis = { version = "1.0.38", default-features = false }
6360
alloy-primitives = { version = "1.3.1", default-features = false }
61+
alloy-provider = { version = "1.0.38", default-features = false }
62+
alloy-rlp = { version = "0.3.12", default-features = false }
63+
alloy-rpc-types = { version = "1.0.38", default-features = false }
6464
alloy-sol-types = { version = "1.3.1", default-features = false }
6565

6666
# Execution
@@ -137,7 +137,7 @@ sp1-core-executor = "5.2.1"
137137
sp1-prover = "5.2.1"
138138
sp1-cc-client-executor = { git = "https://github.com/succinctlabs/sp1-contract-call.git", tag = "reth-1.9.1" }
139139
sp1-cc-host-executor = { git = "https://github.com/succinctlabs/sp1-contract-call.git", tag = "reth-1.9.1" }
140-
rsp-primitives = { git = "https://github.com/succinctlabs/rsp", tag = "reth-1.9.1" }
140+
rsp-primitives = { git = "https://github.com/succinctlabs/rsp", tag = "reth-1.9.1" }
141141

142142
# ZKVM deps
143143
hex = "0.4"

canoe/sp1-cc/host/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ sp1-cc-host-executor = { workspace = true }
88
sp1-cc-client-executor = { workspace = true }
99
rsp-primitives = { workspace = true }
1010

11+
alloy-genesis.workspace = true
1112
alloy-primitives.workspace = true
12-
alloy-sol-types = { workspace = true }
13+
alloy-sol-types.workspace = true
1314
bincode.workspace = true
1415

1516
anyhow = { workspace = true }
@@ -25,4 +26,4 @@ tracing.workspace = true
2526
# sp1
2627
sp1-sdk.workspace = true
2728
sp1-core-executor.workspace = true
28-
sp1-prover.workspace = true
29+
sp1-prover.workspace = true

canoe/sp1-cc/host/src/lib.rs

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
use alloy_genesis::ChainConfig;
12
use alloy_primitives::Address;
23
use alloy_rpc_types::BlockNumberOrTag;
34
use alloy_sol_types::SolType;
45
use anyhow::Result;
56
use async_trait::async_trait;
67
use canoe_bindings::{Journal, StatusCode};
78
use canoe_provider::{CanoeInput, CanoeProvider, CertVerifierCall};
9+
use rsp_primitives::genesis::genesis_from_json;
810
use sp1_cc_client_executor::ContractInput;
911
use sp1_cc_host_executor::{EvmSketch, Genesis};
1012
use sp1_sdk::{
@@ -19,8 +21,6 @@ use std::{
1921
use tracing::{debug, info, warn};
2022
use url::Url;
2123

22-
use rsp_primitives::genesis::genesis_from_json;
23-
2424
/// The ELF we want to execute inside the zkVM.
2525
pub const ELF: &[u8] = include_bytes!("../../elf/canoe-sp1-cc-client");
2626

@@ -62,6 +62,8 @@ pub struct CanoeSp1CCProvider {
6262
pub eth_rpc_url: String,
6363
/// if true, execute and return a mock proof
6464
pub mock_mode: bool,
65+
/// optional custom chain configuration for genesis block
66+
pub custom_chain_config: Option<ChainConfig>,
6567
}
6668

6769
#[async_trait]
@@ -77,7 +79,15 @@ impl CanoeProvider for CanoeSp1CCProvider {
7779
return None;
7880
}
7981

80-
Some(get_sp1_cc_proof(canoe_inputs, &self.eth_rpc_url, self.mock_mode).await)
82+
Some(
83+
get_sp1_cc_proof(
84+
canoe_inputs,
85+
&self.eth_rpc_url,
86+
self.mock_mode,
87+
self.custom_chain_config.clone(),
88+
)
89+
.await,
90+
)
8191
}
8292
}
8393

@@ -92,6 +102,8 @@ pub struct CanoeSp1CCReducedProofProvider {
92102
pub eth_rpc_url: String,
93103
/// if true, execute and return a mock proof
94104
pub mock_mode: bool,
105+
/// optional custom chain configuration for genesis block
106+
pub custom_chain_config: Option<ChainConfig>,
95107
}
96108

97109
#[async_trait]
@@ -107,7 +119,14 @@ impl CanoeProvider for CanoeSp1CCReducedProofProvider {
107119
return None;
108120
}
109121

110-
match get_sp1_cc_proof(canoe_inputs, &self.eth_rpc_url, self.mock_mode).await {
122+
match get_sp1_cc_proof(
123+
canoe_inputs,
124+
&self.eth_rpc_url,
125+
self.mock_mode,
126+
self.custom_chain_config.clone(),
127+
)
128+
.await
129+
{
111130
Ok(proof) => {
112131
let SP1Proof::Compressed(proof) = proof.proof else {
113132
panic!("cannot get Sp1ReducedProof")
@@ -123,6 +142,7 @@ async fn get_sp1_cc_proof(
123142
canoe_inputs: Vec<CanoeInput>,
124143
eth_rpc_url: &str,
125144
mock_mode: bool,
145+
custom_chain_config: Option<ChainConfig>,
126146
) -> Result<sp1_sdk::SP1ProofWithPublicValues> {
127147
// ensure chain id and l1 block number across all DAcerts are identical
128148
let l1_chain_id = canoe_inputs[0].l1_chain_id;
@@ -147,35 +167,26 @@ async fn get_sp1_cc_proof(
147167

148168
let rpc_url = Url::from_str(eth_rpc_url).unwrap();
149169

150-
let sketch = match Genesis::try_from(l1_chain_id) {
151-
Ok(genesis) => {
152-
EvmSketch::builder()
153-
.at_block(block_number)
154-
.with_genesis(genesis)
155-
.el_rpc_url(rpc_url)
156-
.build()
157-
.await?
158-
}
159-
// if genesis is not available in the sp1-cc library, the code uses custom genesis config
160-
Err(_) => {
161-
let chain_config = match l1_chain_id {
162-
17000 => genesis_from_json(HOLESKY_GENESIS).expect("genesis from json"),
163-
3151908 => genesis_from_json(KURTOSIS_DEVNET_GENESIS).expect("genesis from json"),
164-
_ => panic!("chain id {l1_chain_id} is not supported by canoe sp1 cc"),
165-
};
166-
167-
let genesis = Genesis::Custom(chain_config.config);
168-
169-
EvmSketch::builder()
170-
.at_block(block_number)
171-
.with_genesis(genesis)
172-
.el_rpc_url(rpc_url)
173-
.build()
174-
.await
175-
.expect("evm sketch builder")
176-
}
170+
let genesis = if let Some(chain_config) = custom_chain_config {
171+
Genesis::Custom(chain_config)
172+
} else if let Ok(genesis) = Genesis::try_from(l1_chain_id) {
173+
genesis
174+
} else {
175+
let chain_config = match l1_chain_id {
176+
17000 => genesis_from_json(HOLESKY_GENESIS).expect("genesis from json"),
177+
3151908 => genesis_from_json(KURTOSIS_DEVNET_GENESIS).expect("genesis from json"),
178+
_ => panic!("chain id {l1_chain_id} is not supported by canoe sp1 cc"),
179+
};
180+
Genesis::Custom(chain_config.config)
177181
};
178182

183+
let sketch = EvmSketch::builder()
184+
.at_block(block_number)
185+
.with_genesis(genesis)
186+
.el_rpc_url(rpc_url)
187+
.build()
188+
.await?;
189+
179190
let derived_l1_header_hash = sketch.anchor.header().hash_slow();
180191
assert!(l1_head_block_hash == derived_l1_header_hash);
181192

canoe/verifier-address-fetcher/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,13 @@ fn cert_verifier_address_abi_encode_interface(
9595
}
9696
}
9797
}
98+
99+
impl CanoeVerifierAddressFetcher for Address {
100+
fn fetch_address(
101+
&self,
102+
_chain_id: u64,
103+
_versioned_cert: &EigenDAVersionedCert,
104+
) -> Result<Address, CanoeVerifierAddressFetcherError> {
105+
Ok(*self)
106+
}
107+
}

example/preloader/Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@ hokulea-client.workspace = true
1313
hokulea-compute-proof.workspace = true
1414

1515
# General
16+
alloy-genesis.workspace = true
1617
anyhow.workspace = true
17-
tokio = { workspace = true, features = ["full"] }
18-
clap = { workspace = true, features = ["derive", "env"] }
1918
cfg-if = { workspace = true }
20-
tracing = { workspace = true }
19+
clap = { workspace = true, features = ["derive", "env"] }
2120
serde_json.workspace = true
21+
tokio = { workspace = true, features = ["full"] }
22+
tracing = { workspace = true }
2223

2324
kona-client.workspace = true
2425
kona-preimage.workspace = true

example/preloader/src/main.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,19 @@ async fn main() -> anyhow::Result<()> {
8787
.and_then(|v| v.parse::<bool>().ok())
8888
.unwrap_or(false);
8989

90-
let canoe_provider = CanoeSp1CCReducedProofProvider{
90+
let custom_chain_config = if let Some(path) = cfg.kona_cfg.l1_config_path {
91+
let json = std::fs::read_to_string(&path)
92+
.with_context(|| format!("failed to read genesis file at {}", path.display()))?;
93+
let genesis = serde_json::from_str::<alloy_genesis::Genesis>(&json)
94+
.with_context(|| format!("failed to parse L1 genesis from {}", path.display()))?;
95+
Some(genesis.config)
96+
} else {
97+
None
98+
};
99+
let canoe_provider = CanoeSp1CCReducedProofProvider {
91100
eth_rpc_url: cfg.kona_cfg.l1_node_address.clone().unwrap(),
92101
mock_mode,
102+
custom_chain_config,
93103
};
94104
let canoe_verifier = CanoeNoOpVerifier{};
95105
} else {

0 commit comments

Comments
 (0)