From 516fdfefe91b5e7da0ff03f840a597ce910e2fbe Mon Sep 17 00:00:00 2001 From: Ratan Kaliani Date: Wed, 20 Nov 2024 12:17:37 -0800 Subject: [PATCH] feat: Add `skip_deferred_proof_verification` (#1760) --- crates/core/executor/src/context.rs | 20 +++++++++++++-- crates/core/executor/src/executor.rs | 17 +++++++++++++ crates/core/executor/src/syscalls/verify.rs | 28 +++++++++++++-------- crates/sdk/src/action.rs | 12 +++++++++ 4 files changed, 65 insertions(+), 12 deletions(-) diff --git a/crates/core/executor/src/context.rs b/crates/core/executor/src/context.rs index 9585c6b851..0d6c05b170 100644 --- a/crates/core/executor/src/context.rs +++ b/crates/core/executor/src/context.rs @@ -21,6 +21,9 @@ pub struct SP1Context<'a> { /// The maximum number of cpu cycles to use for execution. pub max_cycles: Option, + + /// Skip deferred proof verification. + pub skip_deferred_proof_verification: bool, } /// A builder for [`SP1Context`]. @@ -30,6 +33,7 @@ pub struct SP1ContextBuilder<'a> { hook_registry_entries: Vec<(u32, BoxedHook<'a>)>, subproof_verifier: Option>, max_cycles: Option, + skip_deferred_proof_verification: bool, } impl<'a> SP1Context<'a> { @@ -68,7 +72,13 @@ impl<'a> SP1ContextBuilder<'a> { }); let subproof_verifier = take(&mut self.subproof_verifier); let cycle_limit = take(&mut self.max_cycles); - SP1Context { hook_registry, subproof_verifier, max_cycles: cycle_limit } + let skip_deferred_proof_verification = take(&mut self.skip_deferred_proof_verification); + SP1Context { + hook_registry, + subproof_verifier, + max_cycles: cycle_limit, + skip_deferred_proof_verification, + } } /// Add a runtime [Hook](super::Hook) into the context. @@ -110,6 +120,12 @@ impl<'a> SP1ContextBuilder<'a> { self.max_cycles = Some(max_cycles); self } + + /// Set the skip deferred proof verification flag. + pub fn set_skip_deferred_proof_verification(&mut self, skip: bool) -> &mut Self { + self.skip_deferred_proof_verification = skip; + self + } } #[cfg(test)] @@ -120,7 +136,7 @@ mod tests { #[test] fn defaults() { - let SP1Context { hook_registry, subproof_verifier, max_cycles: cycle_limit } = + let SP1Context { hook_registry, subproof_verifier, max_cycles: cycle_limit, .. } = SP1Context::builder().build(); assert!(hook_registry.is_none()); assert!(subproof_verifier.is_none()); diff --git a/crates/core/executor/src/executor.rs b/crates/core/executor/src/executor.rs index cfbc8cacd5..f53c346a98 100644 --- a/crates/core/executor/src/executor.rs +++ b/crates/core/executor/src/executor.rs @@ -27,6 +27,15 @@ use crate::{ Instruction, Opcode, Program, Register, }; +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +/// Whether to verify deferred proofs during execution. +pub enum DeferredProofVerification { + /// Verify deferred proofs during execution. + Enabled, + /// Skip verification of deferred proofs + Disabled, +} + /// An executor for the SP1 RISC-V zkVM. /// /// The exeuctor is responsible for executing a user program and tracing important events which @@ -78,6 +87,9 @@ pub struct Executor<'a> { /// The maximum number of cpu cycles to use for execution. pub max_cycles: Option, + /// Skip deferred proof verification. + pub deferred_proof_verification: DeferredProofVerification, + /// The state of the execution. pub state: ExecutionState, @@ -228,6 +240,11 @@ impl<'a> Executor<'a> { hook_registry, opts, max_cycles: context.max_cycles, + deferred_proof_verification: if context.skip_deferred_proof_verification { + DeferredProofVerification::Disabled + } else { + DeferredProofVerification::Enabled + }, memory_checkpoint: PagedMemory::new_preallocated(), uninitialized_memory_checkpoint: PagedMemory::new_preallocated(), local_memory_access: HashMap::new(), diff --git a/crates/core/executor/src/syscalls/verify.rs b/crates/core/executor/src/syscalls/verify.rs index 0197199e51..b17d795d3d 100644 --- a/crates/core/executor/src/syscalls/verify.rs +++ b/crates/core/executor/src/syscalls/verify.rs @@ -1,3 +1,5 @@ +use crate::DeferredProofVerification; + use super::{Syscall, SyscallCode, SyscallContext}; pub(crate) struct VerifySyscall; @@ -32,16 +34,22 @@ impl Syscall for VerifySyscall { let vkey_bytes: [u32; 8] = vkey.try_into().unwrap(); let pv_digest_bytes: [u32; 8] = pv_digest.try_into().unwrap(); - ctx.rt - .subproof_verifier - .verify_deferred_proof(proof, proof_vk, vkey_bytes, pv_digest_bytes) - .unwrap_or_else(|e| { - panic!( - "Failed to verify proof {proof_index} with digest {}: {}", - hex::encode(bytemuck::cast_slice(&pv_digest_bytes)), - e - ) - }); + // Skip deferred proof verification if the corresponding runtime flag is set. + match ctx.rt.deferred_proof_verification { + DeferredProofVerification::Enabled => { + ctx.rt + .subproof_verifier + .verify_deferred_proof(proof, proof_vk, vkey_bytes, pv_digest_bytes) + .unwrap_or_else(|e| { + panic!( + "Failed to verify proof {proof_index} with digest {}: {}", + hex::encode(bytemuck::cast_slice(&pv_digest_bytes)), + e + ) + }); + } + DeferredProofVerification::Disabled => {} + } None } diff --git a/crates/sdk/src/action.rs b/crates/sdk/src/action.rs index 6c0767ff83..6437cb447c 100644 --- a/crates/sdk/src/action.rs +++ b/crates/sdk/src/action.rs @@ -69,6 +69,12 @@ impl<'a> Execute<'a> { self.context_builder.max_cycles(max_cycles); self } + + /// Skip deferred proof verification. + pub fn set_skip_deferred_proof_verification(mut self, value: bool) -> Self { + self.context_builder.set_skip_deferred_proof_verification(value); + self + } } /// Builder to prepare and configure proving execution of a program on an input. @@ -217,4 +223,10 @@ impl<'a> Prove<'a> { self.timeout = Some(timeout); self } + + /// Set the skip deferred proof verification flag. + pub fn set_skip_deferred_proof_verification(mut self, value: bool) -> Self { + self.context_builder.set_skip_deferred_proof_verification(value); + self + } }