Skip to content

Commit e0fac34

Browse files
committed
refactor: fallback proof
1 parent de9d2f7 commit e0fac34

File tree

5 files changed

+117
-67
lines changed

5 files changed

+117
-67
lines changed

consensus/types/src/execution_proof_id.rs

Lines changed: 7 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,6 @@ use tree_hash::TreeHash;
99
/// TODO(zkproofs): The number 8 is a parameter that we will want to configure in the future
1010
pub const EXECUTION_PROOF_TYPE_COUNT: u8 = 8;
1111

12-
/// TODO(ethproofs): Added to handle when proof generation fails.
13-
///
14-
/// Special proof ID reserved for fallback proofs
15-
pub const FALLBACK_EXECUTION_PROOF_ID: u8 = 255;
16-
1712
/// ExecutionProofId identifies which zkVM/proof system a proof belongs to.
1813
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
1914
pub struct ExecutionProofId(u8);
@@ -75,39 +70,30 @@ impl TreeHash for ExecutionProofId {
7570

7671
impl ExecutionProofId {
7772
/// Creates a new ExecutionProofId if the value is valid
73+
///
74+
/// Valid IDs are in the range [0, EXECUTION_PROOF_TYPE_COUNT).
7875
pub fn new(id: u8) -> Result<Self, String> {
79-
if id < EXECUTION_PROOF_TYPE_COUNT || id == FALLBACK_EXECUTION_PROOF_ID {
76+
if id < EXECUTION_PROOF_TYPE_COUNT {
8077
Ok(Self(id))
8178
} else {
8279
Err(format!(
83-
"Invalid ExecutionProofId: {}, must be < {} or {}",
84-
id, EXECUTION_PROOF_TYPE_COUNT, FALLBACK_EXECUTION_PROOF_ID
80+
"Invalid ExecutionProofId: {}, must be < {}",
81+
id, EXECUTION_PROOF_TYPE_COUNT
8582
))
8683
}
8784
}
8885

89-
/// Creates a fallback ExecutionProofId (255)
90-
/// Used for dummy proofs when Ethproofs API fails or times out
91-
pub fn fallback() -> Self {
92-
Self(FALLBACK_EXECUTION_PROOF_ID)
93-
}
94-
9586
/// Returns the inner u8 value
9687
pub fn as_u8(&self) -> u8 {
9788
self.0
9889
}
9990

100-
/// Check if this is a fallback proof ID
101-
pub fn is_fallback(&self) -> bool {
102-
self.0 == FALLBACK_EXECUTION_PROOF_ID
103-
}
104-
105-
/// Returns the subnet ID as a usize
91+
/// Returns the proof ID as a usize
10692
pub fn as_usize(&self) -> usize {
10793
self.0 as usize
10894
}
10995

110-
/// Returns all valid subnet IDs
96+
/// Returns all valid proof IDs
11197
pub fn all() -> Vec<Self> {
11298
(0..EXECUTION_PROOF_TYPE_COUNT).map(Self).collect()
11399
}
@@ -157,23 +143,4 @@ mod tests {
157143
assert_eq!(proof_id.as_usize(), idx);
158144
}
159145
}
160-
161-
#[test]
162-
fn test_fallback_proof_id() {
163-
// Test that fallback() creates an ID with value 255
164-
let fallback = ExecutionProofId::fallback();
165-
assert_eq!(fallback.as_u8(), FALLBACK_EXECUTION_PROOF_ID);
166-
assert!(fallback.is_fallback());
167-
168-
// Test that new(255) creates a valid fallback ID
169-
let fallback_from_new = ExecutionProofId::new(FALLBACK_EXECUTION_PROOF_ID);
170-
assert!(fallback_from_new.is_ok());
171-
assert_eq!(fallback_from_new.unwrap().as_u8(), FALLBACK_EXECUTION_PROOF_ID);
172-
173-
// Test that fallback ID can be SSZ encoded and decoded
174-
let encoded = fallback.as_ssz_bytes();
175-
let decoded = ExecutionProofId::from_ssz_bytes(&encoded);
176-
assert!(decoded.is_ok());
177-
assert_eq!(decoded.unwrap(), fallback);
178-
}
179146
}

zkvm_execution_layer/src/dummy_proof_gen.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use async_trait::async_trait;
66
use std::time::Duration;
77
use tokio::time::sleep;
88
use tracing::{info, warn};
9-
use types::execution_proof_id::FALLBACK_EXECUTION_PROOF_ID;
109
use types::{ExecutionBlockHash, ExecutionProof, ExecutionProofId, Hash256, Slot};
1110

1211
/// TODO(ethproofs): Implementation of proof generation for demo.
@@ -39,23 +38,24 @@ impl DummyProofGenerator {
3938

4039
/// TODO(ethproofs): Fallback when the Ethproofs API fails or test verification fails.
4140
///
42-
/// Create a fallback dummy proof with a reserved fallback proof ID
41+
/// Create a fallback dummy proof using proof_id 0, which maps to the FallbackVerifier.
42+
/// The FallbackVerifier skips cryptographic verification and accepts all proofs.
4343
fn create_dummy_proof(
4444
&self,
4545
slot: Slot,
4646
payload_hash: &ExecutionBlockHash,
4747
block_root: &Hash256,
4848
) -> ProofGenerationResult<ExecutionProof> {
4949
let dummy_data = format!(
50-
"ethproofs_fallback_proof_id_{}_slot_{}_hash_{}",
51-
FALLBACK_EXECUTION_PROOF_ID,
50+
"ethproofs_fallback_proof_id_0_slot_{}_hash_{}",
5251
slot.as_u64(),
5352
payload_hash
5453
)
5554
.into_bytes();
5655

57-
// Use the fallback proof ID to mark this as a dummy proof
58-
let fallback_proof_id = ExecutionProofId::fallback();
56+
// Use proof_id 0 (Fallback verifier) to mark this as a dummy proof
57+
let fallback_proof_id = ExecutionProofId::new(0)
58+
.expect("proof_id 0 is always valid");
5959
ExecutionProof::new(
6060
fallback_proof_id,
6161
slot,
@@ -190,7 +190,8 @@ mod tests {
190190

191191
let proof = result.unwrap();
192192

193-
assert!(proof.proof_id.is_fallback());
193+
// Should create a fallback proof (proof_id = 0)
194+
assert_eq!(proof.proof_id.as_u8(), 0);
194195
assert_eq!(proof.slot, slot);
195196
assert_eq!(proof.block_hash, block_hash);
196197
assert_eq!(proof.block_root, block_root);

zkvm_execution_layer/src/ethproofs_demo.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,14 +161,15 @@ pub async fn download_proof_binary(proof_id: u64) -> Result<Vec<u8>, String> {
161161
/// 1. Looking up the verifier for the proof's proof_id
162162
/// 2. Running the cryptographic verification function
163163
/// 3. Returning whether the proof is valid
164+
///
165+
/// Note: Fallback proofs (proof_id = 0) bypass this pipeline and are accepted immediately.
164166
pub fn validate_proof(proof: &ExecutionProof) -> bool {
165-
// Check if this is a fallback proof (created when Ethproofs API failed/timed out)
166-
if proof.proof_id.is_fallback() {
167+
// Fallback proofs (proof_id 0) are accepted without verification
168+
if proof.proof_id.as_u8() == 0 {
167169
info!(
168170
slot = %proof.slot,
169171
block_hash = %proof.block_hash,
170-
proof_id = %proof.proof_id,
171-
"[Ethproofs] Fallback proof detected, skipping verification"
172+
"[Ethproofs] Fallback proof accepted without cryptographic verification"
172173
);
173174
return true;
174175
}
@@ -206,7 +207,7 @@ pub fn validate_proof(proof: &ExecutionProof) -> bool {
206207
block_hash = %proof.block_hash,
207208
prover_id = %prover_uuid,
208209
verifier = verifier_entry.name,
209-
"[Ethproofs] Found verifier, starting verification"
210+
"[Ethproofs] Verification started"
210211
);
211212

212213
// Run the actual cryptographic verification
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//! Fallback proof verifier
2+
//!
3+
//! This module implements a pass-through verifier for fallback proofs.
4+
//! Fallback proofs are created when the Ethproofs API fails or times out,
5+
//! and they are used to allow blocks to progress without cryptographic verification.
6+
7+
use super::{ProofVerifier, VerificationResult};
8+
use tracing::debug;
9+
10+
/// Fallback verifier that accepts all proofs without cryptographic verification.
11+
///
12+
/// This verifier is used for fallback proofs created when:
13+
/// - The Ethproofs API times out
14+
/// - The Ethproofs API returns an error
15+
/// - Other proof generation systems are unavailable
16+
///
17+
/// Since fallback proofs are created locally and represent a "best effort" state,
18+
/// they bypass the full cryptographic verification pipeline.
19+
pub struct FallbackVerifier;
20+
21+
impl ProofVerifier for FallbackVerifier {
22+
fn verify(_proof_data: &[u8], _vk_data: &[u8]) -> VerificationResult {
23+
debug!("Fallback verifier: accepting proof without cryptographic verification");
24+
Ok(true)
25+
}
26+
27+
fn name() -> &'static str {
28+
"fallback"
29+
}
30+
}
31+
32+
#[cfg(test)]
33+
mod tests {
34+
use super::*;
35+
36+
#[test]
37+
fn test_fallback_verifier_name() {
38+
assert_eq!(FallbackVerifier::name(), "fallback");
39+
}
40+
41+
#[test]
42+
fn test_fallback_verifier_always_accepts() {
43+
// Fallback verifier should accept any input without verification
44+
let result = FallbackVerifier::verify(&[], &[]);
45+
assert_eq!(result, Ok(true));
46+
47+
// Test with non-empty data
48+
let proof_data = vec![1, 2, 3, 4, 5];
49+
let vk_data = vec![6, 7, 8, 9, 10];
50+
let result = FallbackVerifier::verify(&proof_data, &vk_data);
51+
assert_eq!(result, Ok(true));
52+
}
53+
}

zkvm_execution_layer/src/verifiers/mod.rs

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
//! This module manages different proof verification systems based on prover type.
44
//! Each verifier implements cryptographic proof verification for a specific zkVM or proof system.
55
6+
pub mod fallback;
67
pub mod pico;
78
pub mod sp1_hypercube;
89
pub mod zisk;
@@ -19,24 +20,42 @@ pub type VerificationResult = Result<bool, String>;
1920
/// Ethproofs demo prover UUIDs - hardcoded mapping for demo testing
2021
/// These constants define the relationship between internal proof_ids (0, 1, 2, etc.)
2122
/// and Ethproofs prover UUIDs.
23+
///
24+
/// Proof ID Mapping:
25+
/// - proof_id 0 → Fallback verifier (used when Ethproofs API fails/times out)
26+
/// - proof_id 1 → Brevis/Pico Prism verifier
27+
/// - proof_id 2 → ZisK verifier
28+
/// - proof_id 3 → ZkCloud verifier
29+
/// - proof_id 4 → ZKM verifier
30+
/// - proof_id 5 → SP1-Hypercube verifier
31+
/// - proof_id 6-7 → reserved for future use
2232
pub mod ethproofs_ids {
2333
use uuid::Uuid;
2434

25-
/// Brevis/Pico Prism verifier UUID (proof_id = 0)
35+
/// Fallback verifier UUID (proof_id = 0)
36+
/// Used for dummy proofs when Ethproofs API fails or times out
37+
pub const FALLBACK_UUID: &str = "00000000-0000-0000-0000-000000000000";
38+
39+
/// Brevis/Pico Prism verifier UUID (proof_id = 1)
2640
pub const BREVIS_UUID: &str = "79041a5b-ee8d-49b3-8207-86c7debf8e13";
2741

28-
/// ZisK verifier UUID (proof_id = 1)
42+
/// ZisK verifier UUID (proof_id = 2)
2943
pub const ZISK_UUID: &str = "33f14a82-47b7-42d7-9bc1-b81a46eea4fe";
3044

31-
/// ZkCloud verifier UUID (proof_id = 2)
45+
/// ZkCloud verifier UUID (proof_id = 3)
3246
pub const ZKCLOUD_UUID: &str = "884fcc21-d522-4b4a-b535-7cfde199485c";
3347

34-
/// ZKM verifier UUID (proof_id = 3)
48+
/// ZKM verifier UUID (proof_id = 4)
3549
pub const ZKM_UUID: &str = "84a01f4b-8078-44cf-b463-90ddcd124960";
3650

37-
/// SP1-Hypercube verifier UUID (proof_id = 4)
51+
/// SP1-Hypercube verifier UUID (proof_id = 5)
3852
pub const SP1_HYPERCUBE_UUID: &str = "9d0bd54d-69f9-4404-8f30-020516a8155d";
3953

54+
/// Parse a Fallback UUID
55+
pub fn fallback() -> Uuid {
56+
Uuid::parse_str(FALLBACK_UUID).expect("Valid UUID")
57+
}
58+
4059
/// Parse a Brevis UUID
4160
pub fn brevis() -> Uuid {
4261
Uuid::parse_str(BREVIS_UUID).expect("Valid UUID")
@@ -134,19 +153,21 @@ impl VerifierStore {
134153
/// Get the prover UUID corresponding to a proof_id (Ethproofs demo mapping)
135154
///
136155
/// For Ethproofs demo testing, this provides a hardcoded mapping of proof_ids to prover UUIDs:
137-
/// - proof_id 0 → brevis (Pico verifier)
138-
/// - proof_id 1 → zisk (ZisK verifier)
139-
/// - proof_id 2 → zkcloud (ZkCloud verifier)
140-
/// - proof_id 3 → zkm (ZKM verifier)
141-
/// - proof_id 4 → sp1-hypercube (SP1-Hypercube verifier)
156+
/// - proof_id 0 → fallback (Fallback verifier)
157+
/// - proof_id 1 → brevis (Pico verifier)
158+
/// - proof_id 2 → zisk (ZisK verifier)
159+
/// - proof_id 3 → zkcloud (ZkCloud verifier)
160+
/// - proof_id 4 → zkm (ZKM verifier)
161+
/// - proof_id 5 → sp1-hypercube (SP1-Hypercube verifier)
142162
pub fn get_prover_uuid_for_proof_id(&self, proof_id: ExecutionProofId) -> Option<Uuid> {
143163
let id = proof_id.as_u8() as u32;
144164
match id {
145-
0 => Some(ethproofs_ids::brevis()),
146-
1 => Some(ethproofs_ids::zisk()),
147-
2 => Some(ethproofs_ids::zkcloud()),
148-
3 => Some(ethproofs_ids::zkm()),
149-
4 => Some(ethproofs_ids::sp1_hypercube()),
165+
0 => Some(ethproofs_ids::fallback()),
166+
1 => Some(ethproofs_ids::brevis()),
167+
2 => Some(ethproofs_ids::zisk()),
168+
3 => Some(ethproofs_ids::zkcloud()),
169+
4 => Some(ethproofs_ids::zkm()),
170+
5 => Some(ethproofs_ids::sp1_hypercube()),
150171
_ => None,
151172
}
152173
}
@@ -157,6 +178,13 @@ impl VerifierStore {
157178
pub fn with_defaults() -> Self {
158179
let mut store = Self::new();
159180

181+
// Register Fallback verifier
182+
store.register(
183+
ethproofs_ids::fallback(),
184+
fallback::FallbackVerifier::name(),
185+
fallback::FallbackVerifier::verify,
186+
);
187+
160188
// Register Pico verifier for brevis
161189
store.register(
162190
ethproofs_ids::brevis(),

0 commit comments

Comments
 (0)