Skip to content

Commit 82ffe4e

Browse files
committed
feat: move verification to filter to compute vk only once and in parallel
1 parent 0dd8dee commit 82ffe4e

4 files changed

Lines changed: 113 additions & 111 deletions

File tree

aggregation_mode/src/aggregators/mod.rs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -219,24 +219,3 @@ impl IsMerkleTreeBackend for AlignedProof {
219219
hasher.finalize().into()
220220
}
221221
}
222-
223-
#[derive(Debug)]
224-
pub enum AlignedVerificationError {
225-
Sp1(AlignedSP1VerificationError),
226-
Risc0(AlignedRisc0VerificationError),
227-
}
228-
229-
impl AlignedProof {
230-
pub fn verify(&self) -> Result<(), AlignedVerificationError> {
231-
match self {
232-
AlignedProof::SP1(proof) => sp1_aggregator::verify(proof).map_err(
233-
|arg0: sp1_aggregator::AlignedSP1VerificationError| {
234-
AlignedVerificationError::Sp1(arg0)
235-
},
236-
),
237-
AlignedProof::Risc0(proof) => {
238-
risc0_aggregator::verify(proof).map_err(AlignedVerificationError::Risc0)
239-
}
240-
}
241-
}
242-
}

aggregation_mode/src/aggregators/risc0_aggregator.rs

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,36 @@ pub struct Risc0ProofReceiptAndImageId {
88
pub receipt: Receipt,
99
}
1010

11+
#[derive(Debug)]
12+
pub enum AlignedRisc0VerificationError {
13+
Verification(String),
14+
UnsupportedProof,
15+
}
16+
1117
impl Risc0ProofReceiptAndImageId {
18+
pub fn new(image_id: [u8; 32], receipt: Receipt) -> Self {
19+
Self { image_id, receipt }
20+
}
21+
22+
pub fn new_with_verification(
23+
image_id: [u8; 32],
24+
receipt: Receipt,
25+
) -> Result<Self, AlignedRisc0VerificationError> {
26+
let is_supported_proof =
27+
proof.receipt.inner.composite().is_ok() || proof.receipt.inner.succinct().is_ok();
28+
29+
if is_supported_proof {
30+
proof
31+
.receipt
32+
.verify(proof.image_id)
33+
.map_err(|e| AlignedRisc0VerificationError::Verification(e.to_string()))?;
34+
} else {
35+
return Err(AlignedRisc0VerificationError::UnsupportedProof);
36+
}
37+
38+
Ok(Self { image_id, receipt })
39+
}
40+
1241
pub fn public_inputs(&self) -> &Vec<u8> {
1342
&self.receipt.journal.bytes
1443
}
@@ -22,12 +51,6 @@ pub enum Risc0AggregationError {
2251
Verification(String),
2352
}
2453

25-
#[derive(Debug)]
26-
pub enum AlignedRisc0VerificationError {
27-
Verification(String),
28-
UnsupportedProof,
29-
}
30-
3154
/// Byte representation of the user proofs aggregator image_id, converted from `[u32; 8]` to `[u8; 32]`.
3255
pub const RISC0_USER_PROOFS_AGGREGATOR_PROGRAM_ID_BYTES: [u8; 32] = {
3356
let mut res = [0u8; 32];
@@ -169,17 +192,3 @@ pub(crate) fn run_chunk_aggregator(
169192

170193
Ok(proof)
171194
}
172-
173-
pub(crate) fn verify(
174-
proof: &Risc0ProofReceiptAndImageId,
175-
) -> Result<(), AlignedRisc0VerificationError> {
176-
// only stark proofs are supported for recursion
177-
if proof.receipt.inner.composite().is_ok() || proof.receipt.inner.succinct().is_ok() {
178-
proof
179-
.receipt
180-
.verify(proof.image_id)
181-
.map_err(|e| AlignedRisc0VerificationError::Verification(e.to_string()))
182-
} else {
183-
Err(AlignedRisc0VerificationError::UnsupportedProof)
184-
}
185-
}

aggregation_mode/src/aggregators/sp1_aggregator.rs

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ pub struct SP1ProofWithPubValuesAndElf {
2626
pub vk: SP1VerifyingKey,
2727
}
2828

29+
#[derive(Debug)]
30+
pub enum AlignedSP1VerificationError {
31+
Verification(sp1_sdk::SP1VerificationError),
32+
UnsupportedProof,
33+
}
34+
2935
impl SP1ProofWithPubValuesAndElf {
3036
pub fn new(proof_with_pub_values: SP1ProofWithPublicValues, elf: Vec<u8>) -> Self {
3137
let vk = vk_from_elf(&elf);
@@ -37,6 +43,35 @@ impl SP1ProofWithPubValuesAndElf {
3743
}
3844
}
3945

46+
pub fn new_with_verification(
47+
proof_with_pub_values: SP1ProofWithPublicValues,
48+
elf: Vec<u8>,
49+
) -> Result<Self, AlignedSP1VerificationError> {
50+
let client = &*SP1_PROVER_CLIENT_CPU;
51+
52+
let (_pk, vk) = client.setup(&sp1_proof_with_pub_values_and_elf.elf);
53+
54+
// only sp1 compressed proofs are supported for aggregation now
55+
match sp1_proof_with_pub_values_and_elf
56+
.proof_with_pub_values
57+
.proof
58+
{
59+
sp1_sdk::SP1Proof::Compressed(_) => client
60+
.verify(
61+
&sp1_proof_with_pub_values_and_elf.proof_with_pub_values,
62+
&vk,
63+
)
64+
.map_err(AlignedSP1VerificationError::Verification),
65+
_ => Err(AlignedSP1VerificationError::UnsupportedProof),
66+
}?;
67+
68+
Ok(Self {
69+
proof_with_pub_values,
70+
elf,
71+
vk,
72+
})
73+
}
74+
4075
pub fn hash_vk_and_pub_inputs(&self) -> [u8; 32] {
4176
let mut hasher = Keccak256::new();
4277
let vk_bytes = &self.vk.hash_bytes();
@@ -187,34 +222,6 @@ pub(crate) fn run_chunk_aggregator(
187222
Ok(proof_and_elf)
188223
}
189224

190-
#[derive(Debug)]
191-
pub enum AlignedSP1VerificationError {
192-
Verification(sp1_sdk::SP1VerificationError),
193-
UnsupportedProof,
194-
}
195-
196-
pub(crate) fn verify(
197-
sp1_proof_with_pub_values_and_elf: &SP1ProofWithPubValuesAndElf,
198-
) -> Result<(), AlignedSP1VerificationError> {
199-
let client = &*SP1_PROVER_CLIENT_CPU;
200-
201-
let (_pk, vk) = client.setup(&sp1_proof_with_pub_values_and_elf.elf);
202-
203-
// only sp1 compressed proofs are supported for aggregation now
204-
match sp1_proof_with_pub_values_and_elf
205-
.proof_with_pub_values
206-
.proof
207-
{
208-
sp1_sdk::SP1Proof::Compressed(_) => client
209-
.verify(
210-
&sp1_proof_with_pub_values_and_elf.proof_with_pub_values,
211-
&vk,
212-
)
213-
.map_err(AlignedSP1VerificationError::Verification),
214-
_ => Err(AlignedSP1VerificationError::UnsupportedProof),
215-
}
216-
}
217-
218225
pub fn vk_from_elf(elf: &[u8]) -> SP1VerifyingKey {
219226
let prover = &*SP1_PROVER_CLIENT_CPU;
220227
let (_, vk) = prover.setup(elf);

aggregation_mode/src/backend/fetcher.rs

Lines changed: 49 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -112,38 +112,61 @@ impl ProofsFetcher {
112112
info!("Data downloaded from S3, number of proofs {}", data.len());
113113

114114
// Filter compatible proofs to be aggregated and push to queue
115-
let mut proofs_to_add: Vec<AlignedProof> = match engine {
115+
let proofs_to_add: Vec<AlignedProof> = match engine {
116116
ZKVMEngine::SP1 => data
117-
.into_iter()
118-
.filter_map(|p| match p.proving_system {
119-
ProvingSystemId::SP1 => {
120-
let elf = p.vm_program_code?;
121-
let proof_with_pub_values = bincode::deserialize(&p.proof).ok()?;
122-
let sp1_proof =
123-
SP1ProofWithPubValuesAndElf::new(proof_with_pub_values, elf);
124-
125-
Some(AlignedProof::SP1(sp1_proof.into()))
117+
.into_par_iter()
118+
.filter_map(|p| {
119+
if p.proving_system != ProvingSystemId::SP1 {
120+
return None;
121+
};
122+
123+
let elf = p.vm_program_code?;
124+
let proof_with_pub_values = bincode::deserialize(&p.proof).ok()?;
125+
let sp1_proof = if self.pre_verification_enabled {
126+
SP1ProofWithPubValuesAndElf::new_with_verification(
127+
proof_with_pub_values,
128+
elf,
129+
)
130+
} else {
131+
Ok(SP1ProofWithPubValuesAndElf::new(proof_with_pub_values, elf))
132+
};
133+
134+
match sp1_proof {
135+
Ok(proof) => Some(AlignedProof::SP1(sp1_proof)),
136+
Err(err) => {
137+
error!("Could not add proof, verification failed: {:?}", err);
138+
None
139+
}
126140
}
127-
128-
_ => None,
129141
})
130142
.collect(),
131143
ZKVMEngine::RISC0 => data
132-
.into_iter()
133-
.filter_map(|p| match p.proving_system {
134-
ProvingSystemId::Risc0 => {
135-
let mut image_id = [0u8; 32];
136-
image_id.copy_from_slice(p.vm_program_code?.as_slice());
137-
let public_inputs = p.pub_input?;
138-
let inner_receipt: risc0_zkvm::InnerReceipt =
139-
bincode::deserialize(&p.proof).ok()?;
140-
141-
let receipt = Receipt::new(inner_receipt, public_inputs);
142-
let risc0_proof = Risc0ProofReceiptAndImageId { image_id, receipt };
143-
144-
Some(AlignedProof::Risc0(risc0_proof.into()))
144+
.into_par_iter()
145+
.filter_map(|p| {
146+
if p.proving_system != ProvingSystemId::Risc0 {
147+
return None;
148+
};
149+
150+
let mut image_id = [0u8; 32];
151+
image_id.copy_from_slice(p.vm_program_code?.as_slice());
152+
let public_inputs = p.pub_input?;
153+
let inner_receipt: risc0_zkvm::InnerReceipt =
154+
bincode::deserialize(&p.proof).ok()?;
155+
156+
let receipt = Receipt::new(inner_receipt, public_inputs);
157+
let risc0_proof = if self.pre_verification_enabled {
158+
Risc0ProofReceiptAndImageId::new_with_verification(image_id, receipt)
159+
} else {
160+
Ok(Risc0ProofReceiptAndImageId::new(image_id, receipt))
161+
};
162+
163+
match risc0_proof {
164+
Ok(proof) => Some(AlignedProof::Risc0(risc0_proof)),
165+
Err(err) => {
166+
error!("Could not add proof, verification failed: {:?}", err);
167+
None
168+
}
145169
}
146-
_ => None,
147170
})
148171
.collect(),
149172
};
@@ -154,22 +177,6 @@ impl ProofsFetcher {
154177
proofs_to_add.len()
155178
);
156179

157-
if self.pre_verification_enabled {
158-
// Try to add them to the queue
159-
// We do this in parallel, as SP1 can take quite some time in verifying
160-
// because of the overhead of setting up the prover
161-
proofs_to_add = proofs_to_add
162-
.into_par_iter()
163-
.filter(|proof| match proof.verify() {
164-
Ok(_) => true,
165-
Err(err) => {
166-
error!("Could not add proof, verification failed: {:?}", err);
167-
return false;
168-
}
169-
})
170-
.collect();
171-
}
172-
173180
proofs.extend(proofs_to_add);
174181
}
175182

0 commit comments

Comments
 (0)