Skip to content

Commit 0d253f7

Browse files
committed
feat(provers/sp1): support pacaya
1 parent bf274d2 commit 0d253f7

File tree

8 files changed

+258
-35
lines changed

8 files changed

+258
-35
lines changed

lib/src/builder.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::{
1313
};
1414
use anyhow::{bail, ensure, Result};
1515
use reth_chainspec::{
16-
ChainSpecBuilder, Hardfork, HOLESKY, MAINNET, TAIKO_A7, TAIKO_DEV, TAIKO_MAINNET,
16+
ChainSpecBuilder, ForkCondition, Hardfork, HOLESKY, MAINNET, TAIKO_A7, TAIKO_DEV, TAIKO_MAINNET,
1717
};
1818
use reth_evm::execute::{BlockExecutionOutput, BlockValidationError, Executor, ProviderError};
1919
use reth_evm_ethereum::execute::{
@@ -169,7 +169,16 @@ impl<DB: Database<Error = ProviderError> + DatabaseCommit + OptimisticDatabase>
169169
)
170170
}
171171
"holesky" => HOLESKY.clone(),
172-
"taiko_dev" => TAIKO_DEV.clone(),
172+
"taiko_dev" => {
173+
let mut reth_spec = TAIKO_DEV.as_ref().clone();
174+
reth_spec
175+
.hardforks
176+
.insert(Hardfork::Ontake, ForkCondition::Block(0));
177+
reth_spec
178+
.hardforks
179+
.insert(Hardfork::Pacaya, ForkCondition::Block(50));
180+
Arc::new(reth_spec)
181+
}
173182
_ => unimplemented!(),
174183
};
175184

provers/sp1/builder/src/main.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ use std::path::PathBuf;
55

66
fn main() {
77
let pipeline = Sp1Pipeline::new("provers/sp1/guest", "release");
8-
pipeline.bins(&["sp1-guest", "sp1-aggregation"], "provers/sp1/guest/elf");
8+
pipeline.bins(
9+
&["sp1-guest", "sp1-aggregation", "sp1-batch"],
10+
"provers/sp1/guest/elf",
11+
);
912
#[cfg(feature = "test")]
1013
pipeline.tests(&["sp1-guest"], "provers/sp1/guest/elf");
1114
#[cfg(feature = "bench")]

provers/sp1/driver/src/lib.rs

+146-9
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@ use sp1_sdk::{
2121
};
2222
use sp1_sdk::{HashableKey, ProverClient, SP1Stdin};
2323
use std::{borrow::BorrowMut, env, sync::Arc, time::Duration};
24-
use tracing::{debug, error, info};
24+
use tracing::{debug, info};
2525

2626
mod proof_verify;
2727
use proof_verify::remote_contract_verify::verify_sol_by_contract_call;
2828

2929
pub const ELF: &[u8] = include_bytes!("../../guest/elf/sp1-guest");
3030
pub const AGGREGATION_ELF: &[u8] = include_bytes!("../../guest/elf/sp1-aggregation");
31+
pub const BATCH_ELF: &[u8] = include_bytes!("../../guest/elf/sp1-batch");
3132

3233
#[serde_as]
3334
#[derive(Clone, Debug, Serialize, Deserialize)]
@@ -110,6 +111,7 @@ struct Sp1ProverClient {
110111
//TODO: use prover object to save such local storage members.
111112
static BLOCK_PROOF_CLIENT: Lazy<DashMap<ProverMode, Sp1ProverClient>> = Lazy::new(DashMap::new);
112113
static AGGREGATION_CLIENT: Lazy<DashMap<ProverMode, Sp1ProverClient>> = Lazy::new(DashMap::new);
114+
static BATCH_PROOF_CLIENT: Lazy<DashMap<ProverMode, Sp1ProverClient>> = Lazy::new(DashMap::new);
113115

114116
impl Prover for Sp1Prover {
115117
async fn run(
@@ -197,8 +199,8 @@ impl Prover for Sp1Prover {
197199
.await?;
198200
}
199201
info!(
200-
"Sp1 Prover: block {:?} - proof id {proof_id:?}",
201-
output.header.number
202+
"Sp1: network proof id: {:?} for block {:?}",
203+
proof_id, output.header.number
202204
);
203205
network_client
204206
.wait_proof(proof_id.clone(), Some(Duration::from_secs(3600)))
@@ -319,7 +321,7 @@ impl Prover for Sp1Prover {
319321
stdin.write_proof(*block_proof, stark_vk.clone());
320322
}
321323
_ => {
322-
error!("unsupported proof type for aggregation: {sp1_proof:?}");
324+
panic!("unsupported proof type for aggregation: {sp1_proof:?}");
323325
}
324326
}
325327
}
@@ -387,6 +389,7 @@ impl Prover for Sp1Prover {
387389
.map_err(|e| {
388390
ProverError::GuestError(format!("Sp1: network proving failed: {e}"))
389391
})?;
392+
info!("Sp1: network proof id: {proof_id:?} for aggregation");
390393
network_client
391394
.wait_proof(proof_id.clone(), Some(Duration::from_secs(3600)))
392395
.await
@@ -429,12 +432,146 @@ impl Prover for Sp1Prover {
429432
}
430433

431434
async fn batch_run(
432-
_input: GuestBatchInput,
433-
_output: &GuestBatchOutput,
434-
_config: &ProverConfig,
435-
_store: Option<&mut dyn IdWrite>,
435+
input: GuestBatchInput,
436+
output: &GuestBatchOutput,
437+
config: &ProverConfig,
438+
id_store: Option<&mut dyn IdWrite>,
436439
) -> ProverResult<Proof> {
437-
unimplemented!();
440+
let param = Sp1Param::deserialize(config.get("sp1").unwrap()).unwrap();
441+
let mode = param.prover.clone().unwrap_or_else(get_env_mock);
442+
443+
println!("batch_run param: {param:?}");
444+
let mut stdin = SP1Stdin::new();
445+
stdin.write(&input);
446+
447+
let Sp1ProverClient {
448+
client,
449+
pk,
450+
vk,
451+
network_client,
452+
} = BATCH_PROOF_CLIENT
453+
.entry(mode.clone())
454+
.or_insert_with(|| {
455+
let network_client = Arc::new(ProverClient::builder().network().build());
456+
let base_client: Box<dyn SP1ProverTrait<CpuProverComponents>> = match mode {
457+
ProverMode::Mock => Box::new(ProverClient::builder().mock().build()),
458+
ProverMode::Local => Box::new(ProverClient::builder().cpu().build()),
459+
ProverMode::Network => Box::new(ProverClient::builder().network().build()),
460+
};
461+
462+
let client = Arc::new(base_client);
463+
let (pk, vk) = client.setup(BATCH_ELF);
464+
info!(
465+
"new client and setup() for batch {:?}.",
466+
input.taiko.batch_id
467+
);
468+
Sp1ProverClient {
469+
client,
470+
network_client,
471+
pk,
472+
vk,
473+
}
474+
})
475+
.clone();
476+
477+
info!(
478+
"Sp1 Prover: batch {:?} with vk {:?}, output.hash: {}",
479+
input.taiko.batch_id,
480+
vk.bytes32(),
481+
output.hash
482+
);
483+
484+
let prove_result = if !matches!(mode, ProverMode::Network) {
485+
debug!("Proving locally with recursion mode: {:?}", param.recursion);
486+
let prove_mode = match param.recursion {
487+
RecursionMode::Core => SP1ProofMode::Core,
488+
RecursionMode::Compressed => SP1ProofMode::Compressed,
489+
RecursionMode::Plonk => SP1ProofMode::Plonk,
490+
};
491+
client
492+
.prove(&pk, &stdin, prove_mode)
493+
.map_err(|e| ProverError::GuestError(format!("Sp1: local proving failed: {e}")))?
494+
} else {
495+
let proof_id = network_client
496+
.prove(&pk, &stdin)
497+
.mode(param.recursion.clone().into())
498+
.cycle_limit(1_000_000_000_000)
499+
.skip_simulation(true)
500+
.strategy(FulfillmentStrategy::Reserved)
501+
.request_async()
502+
.await
503+
.map_err(|e| {
504+
ProverError::GuestError(format!("Sp1: requesting proof failed: {e}"))
505+
})?;
506+
if let Some(id_store) = id_store {
507+
id_store
508+
.store_id(
509+
(
510+
input.taiko.chain_spec.chain_id,
511+
input.taiko.batch_id,
512+
output.hash,
513+
ProofType::Sp1 as u8,
514+
),
515+
proof_id.clone().to_string(),
516+
)
517+
.await?;
518+
}
519+
info!(
520+
"Sp1 Prover: batch {:?} - proof id {proof_id:?}",
521+
input.taiko.batch_id
522+
);
523+
network_client
524+
.wait_proof(proof_id.clone(), Some(Duration::from_secs(3600)))
525+
.await
526+
.map_err(|e| ProverError::GuestError(format!("Sp1: network proof failed {e:?}")))?
527+
};
528+
529+
let proof_bytes = match param.recursion {
530+
RecursionMode::Compressed => {
531+
info!("Compressed proof is used in aggregation mode only");
532+
vec![]
533+
}
534+
_ => prove_result.bytes(),
535+
};
536+
if param.verify && !proof_bytes.is_empty() {
537+
let time = Measurement::start("verify", false);
538+
let pi_hash = prove_result
539+
.clone()
540+
.borrow_mut()
541+
.public_values
542+
.read::<[u8; 32]>();
543+
let fixture = RaikoProofFixture {
544+
vkey: vk.bytes32(),
545+
public_values: B256::from_slice(&pi_hash).to_string(),
546+
proof: proof_bytes.clone(),
547+
};
548+
549+
verify_sol_by_contract_call(&fixture).await?;
550+
time.stop_with("==> Verification complete");
551+
}
552+
553+
let proof_string = (!proof_bytes.is_empty()).then_some(
554+
// 0x + 64 bytes of the vkey + the proof
555+
// vkey itself contains 0x prefix
556+
format!(
557+
"{}{}",
558+
vk.bytes32(),
559+
reth_primitives::hex::encode(proof_bytes)
560+
),
561+
);
562+
563+
info!(
564+
"Sp1 Prover: batch {:?} completed! proof: {proof_string:?}",
565+
input.taiko.batch_id,
566+
);
567+
Ok::<_, ProverError>(
568+
Sp1Response {
569+
proof: proof_string,
570+
sp1_proof: Some(prove_result),
571+
vkey: Some(vk.clone()),
572+
}
573+
.into(),
574+
)
438575
}
439576
}
440577

provers/sp1/guest/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ path = "src/zk_op.rs"
1313
name = "sp1-aggregation"
1414
path = "src/aggregation.rs"
1515

16+
[[bin]]
17+
name = "sp1-batch"
18+
path = "src/batch.rs"
19+
1620
[[bin]]
1721
name = "sha256"
1822
path = "src/benchmark/sha256.rs"

provers/sp1/guest/src/batch.rs

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#![no_main]
2+
sp1_zkvm::entrypoint!(main);
3+
4+
use raiko_lib::{
5+
builder::calculate_batch_blocks_final_header, input::GuestBatchInput, proof_type::ProofType,
6+
protocol_instance::ProtocolInstance, CycleTracker,
7+
};
8+
9+
pub mod sys;
10+
pub use sys::*;
11+
12+
pub fn main() {
13+
let mut ct = CycleTracker::start("input");
14+
let input = sp1_zkvm::io::read_vec();
15+
let batch_input = bincode::deserialize::<GuestBatchInput>(&input).unwrap();
16+
ct.end();
17+
18+
ct = CycleTracker::start("calculate_batch_blocks_final_header");
19+
let final_blocks = calculate_batch_blocks_final_header(&batch_input);
20+
ct.end();
21+
22+
ct = CycleTracker::start("batch_instance_hash");
23+
let pi = ProtocolInstance::new_batch(&batch_input, final_blocks, ProofType::Sp1)
24+
.unwrap()
25+
.instance_hash();
26+
ct.end();
27+
28+
sp1_zkvm::io::commit(&pi.0);
29+
}
30+
31+
harness::zk_suits!(
32+
pub mod tests {
33+
use reth_primitives::U256;
34+
use std::str::FromStr;
35+
#[test]
36+
pub fn test_build_from_mock_input() {
37+
// Todo: impl mock input for static unit test
38+
assert_eq!(1, 1);
39+
}
40+
pub fn test_signature() {
41+
let signature = reth_primitives::Signature {
42+
r: U256::from_str(
43+
"18515461264373351373200002665853028612451056578545711640558177340181847433846",
44+
)
45+
.unwrap(),
46+
s: U256::from_str(
47+
"46948507304638947509940763649030358759909902576025900602547168820602576006531",
48+
)
49+
.unwrap(),
50+
odd_y_parity: false,
51+
};
52+
let hash = reth_primitives::B256::from_str(
53+
"daf5a779ae972f972197303d7b574746c7ef83eadac0f2791ad23db92e4c8e53",
54+
)
55+
.unwrap();
56+
signature.recover_signer(hash).unwrap();
57+
}
58+
}
59+
);

script/build.sh

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
# Any error will result in failure
44
set -e
5+
set -x
56

67
TOOLCHAIN_RISC0=+nightly-2024-12-20
7-
TOOLCHAIN_SP1=+nightly-2024-12-20
8+
TOOLCHAIN_SP1="+1.82.0"
89
TOOLCHAIN_SGX=+nightly-2024-12-20
910

1011
check_toolchain() {

script/install.sh

+21-21
Original file line numberDiff line numberDiff line change
@@ -70,25 +70,25 @@ if [ -z "$1" ] || [ "$1" == "risc0" ]; then
7070
fi
7171
# SP1
7272
if [ -z "$1" ] || [ "$1" == "sp1" ]; then
73-
curl -L https://sp1.succinct.xyz | bash
74-
echo "SP1 installed"
75-
# if [ -z "${CI}" ] || [ ! command -v sp1up &> /dev/null ]; then
76-
# echo "Non-CI environment"
77-
# Need to add sp1up to the path here
78-
PROFILE=$HOME/.profile
79-
echo ${PROFILE}
80-
source ${PROFILE}
81-
if command -v sp1up >/dev/null 2>&1; then
82-
echo "sp1 found in path"
83-
sp1up -v v4.0.0-rc.1
84-
else
85-
echo "sp1 not found in path"
86-
"$HOME/.sp1/bin/sp1up" -v v4.0.0-rc.1
87-
fi
88-
# else
89-
# echo "CI environment"
90-
# source /home/runner/.bashrc
91-
# echo "/home/runner/.sp1/bin" >> $GITHUB_PATH
92-
# /home/runner/.sp1/bin/sp1up
93-
# fi
73+
curl -L https://sp1.succinct.xyz | bash
74+
echo "SP1 installed"
75+
# if [ -z "${CI}" ] || [ ! command -v sp1up &> /dev/null ]; then
76+
# echo "Non-CI environment"
77+
# Need to add sp1up to the path here
78+
PROFILE=$HOME/.profile
79+
echo ${PROFILE}
80+
source ${PROFILE}
81+
if command -v sp1up >/dev/null 2>&1; then
82+
echo "sp1 found in path"
83+
sp1up -v v4.0.0-rc.1
84+
else
85+
echo "sp1 not found in path"
86+
"$HOME/.sp1/bin/sp1up" -v v4.0.0-rc.1
87+
fi
88+
# else
89+
# echo "CI environment"
90+
# source /home/runner/.bashrc
91+
# echo "/home/runner/.sp1/bin" >> $GITHUB_PATH
92+
# /home/runner/.sp1/bin/sp1up
93+
# fi
9494
fi

script/prove-block.sh

+11-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,17 @@ elif [ "$proof" == "sp1" ]; then
7272
"sp1": {
7373
"recursion": "plonk",
7474
"prover": "network",
75-
"verify": true
75+
"verify": false
76+
}
77+
'
78+
elif [ "$proof" == "sp1-mock" ]; then
79+
proofParam='
80+
"proof_type": "sp1",
81+
"blob_proof_type": "proof_of_equivalence",
82+
"sp1": {
83+
"recursion": "plonk",
84+
"prover": "mock",
85+
"verify": false
7686
}
7787
'
7888
elif [ "$proof" == "sp1-aggregation" ]; then

0 commit comments

Comments
 (0)