From af90bb8c21de451c43776ce44b4fea5962df6cfb Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Mon, 19 Aug 2024 23:40:12 +0300 Subject: [PATCH] Remove Receipt output type --- Cargo.lock | 1 - .../provers/risc0/guest-bitcoin/Cargo.lock | 1 - .../provers/risc0/guest-mock/Cargo.lock | 1 - crates/fullnode/src/runner.rs | 12 ++--- crates/prover/src/runner.rs | 13 +++-- crates/risc0-bonsai/src/host.rs | 31 ++++++------ .../adapters/mock-zkvm/src/lib.rs | 50 ++++++++----------- .../adapters/risc0/src/guest/mod.rs | 6 +-- .../sovereign-sdk/adapters/risc0/src/host.rs | 38 ++++++-------- .../sovereign-sdk/rollup-interface/Cargo.toml | 1 - .../src/state_machine/zk/mod.rs | 15 ++---- 11 files changed, 70 insertions(+), 99 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 011555e81..4a970006a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7814,7 +7814,6 @@ dependencies = [ "hex", "proptest", "proptest-derive", - "risc0-zkvm", "serde", "serde_json", "sha2", diff --git a/bin/citrea/provers/risc0/guest-bitcoin/Cargo.lock b/bin/citrea/provers/risc0/guest-bitcoin/Cargo.lock index f9a4757cb..6ff0d9744 100644 --- a/bin/citrea/provers/risc0/guest-bitcoin/Cargo.lock +++ b/bin/citrea/provers/risc0/guest-bitcoin/Cargo.lock @@ -2915,7 +2915,6 @@ dependencies = [ "digest 0.10.7", "hex", "proptest", - "risc0-zkvm", "serde", "sha2", "thiserror", diff --git a/bin/citrea/provers/risc0/guest-mock/Cargo.lock b/bin/citrea/provers/risc0/guest-mock/Cargo.lock index dd54835c3..d7add3b1e 100644 --- a/bin/citrea/provers/risc0/guest-mock/Cargo.lock +++ b/bin/citrea/provers/risc0/guest-mock/Cargo.lock @@ -2682,7 +2682,6 @@ dependencies = [ "digest 0.10.7", "hex", "proptest", - "risc0-zkvm", "serde", "sha2", "thiserror", diff --git a/crates/fullnode/src/runner.rs b/crates/fullnode/src/runner.rs index e2abaf50c..e4e47cae2 100644 --- a/crates/fullnode/src/runner.rs +++ b/crates/fullnode/src/runner.rs @@ -232,7 +232,7 @@ where ); tracing::debug!("ZK proof: {:?}", proof); - let (state_transition, receipt) = + let state_transition = Vm::extract_output::<::Spec, Stf::StateRoot>(&proof) .expect("Proof should be deserializable"); if state_transition.sequencer_da_public_key != self.sequencer_da_pub_key @@ -243,16 +243,14 @@ where ).into()); } - match proof { - Proof::Full(_) => { - let receipt = receipt.expect("Receipt must exist with full proof"); + match &proof { + Proof::Full(data) => { let code_commitment = self .code_commitments_by_spec .get(&state_transition.final_spec_id) .expect("Proof public input must contain valid spec id"); - receipt - .verify(code_commitment.clone()) - .map_err(|err| anyhow!("Proof verification: SNARK verification failed: {}. Skipping to next proof...", err))?; + Vm::verify(data, code_commitment) + .map_err(|err| anyhow!("Failed to verify proof: {:?}. Skipping it...", err))?; } Proof::PublicInput(_) => { if !self.accept_public_input_as_proven { diff --git a/crates/prover/src/runner.rs b/crates/prover/src/runner.rs index 8facc082f..da116cf71 100644 --- a/crates/prover/src/runner.rs +++ b/crates/prover/src/runner.rs @@ -798,22 +798,21 @@ where // l1_height => (tx_id, proof, transition_data) // save proof along with tx id to db, should be queriable by slot number or slot hash - let (transition_data, receipt) = - Vm::extract_output::<::Spec, Stf::StateRoot>(&proof) - .expect("Proof should be deserializable"); + let transition_data = Vm::extract_output::<::Spec, Stf::StateRoot>(&proof) + .expect("Proof should be deserializable"); - match proof { + match &proof { Proof::PublicInput(_) => { warn!("Proof is public input, skipping"); } - Proof::Full(_) => { + Proof::Full(data) => { info!("Verifying proof!"); - let receipt = receipt.expect("Receipt must exist in full proof"); let code_commitment = self .code_commitments_by_spec .get(&transition_data.final_spec_id) .expect("Proof public input must contain valid spec id"); - receipt.verify(code_commitment.clone())?; + Vm::verify(data, code_commitment) + .map_err(|err| anyhow!("Failed to verify proof: {:?}. Skipping it...", err))?; } } diff --git a/crates/risc0-bonsai/src/host.rs b/crates/risc0-bonsai/src/host.rs index f17c7c46a..eb34823a9 100644 --- a/crates/risc0-bonsai/src/host.rs +++ b/crates/risc0-bonsai/src/host.rs @@ -358,24 +358,18 @@ impl<'a> ZkvmHost for Risc0BonsaiHost<'a> { fn extract_output( proof: &Proof, - ) -> Result< - ( - sov_rollup_interface::zk::StateTransition, - Option, - ), - Self::Error, - > { - let (journal, receipt) = match proof { + ) -> Result, Self::Error> { + let journal = match proof { Proof::PublicInput(journal) => { let journal: Journal = bincode::deserialize(journal)?; - (journal, None) + journal } Proof::Full(data) => { let receipt: Receipt = bincode::deserialize(data)?; - (receipt.journal.clone(), Some(receipt)) + receipt.journal } }; - Ok((BorshDeserialize::try_from_slice(&journal.bytes)?, receipt)) + Ok(BorshDeserialize::try_from_slice(&journal.bytes)?) } fn recover_proving_sessions(&self) -> Result, anyhow::Error> { @@ -411,11 +405,16 @@ impl<'host> Zkvm for Risc0BonsaiHost<'host> { type Error = anyhow::Error; - fn verify<'a>( - _serialized_proof: &'a [u8], - _code_commitment: &Self::CodeCommitment, - ) -> Result<&'a [u8], Self::Error> { - unimplemented!(); + fn verify( + serialized_proof: &[u8], + code_commitment: &Self::CodeCommitment, + ) -> Result, Self::Error> { + let receipt: Receipt = bincode::deserialize(serialized_proof)?; + + #[allow(clippy::clone_on_copy)] + receipt.verify(code_commitment.clone())?; + + Ok(receipt.journal.bytes) } fn verify_and_extract_output( diff --git a/crates/sovereign-sdk/adapters/mock-zkvm/src/lib.rs b/crates/sovereign-sdk/adapters/mock-zkvm/src/lib.rs index 03a2e4281..dc6507e72 100644 --- a/crates/sovereign-sdk/adapters/mock-zkvm/src/lib.rs +++ b/crates/sovereign-sdk/adapters/mock-zkvm/src/lib.rs @@ -8,7 +8,6 @@ use std::sync::{Arc, Condvar, Mutex}; use anyhow::ensure; use borsh::{BorshDeserialize, BorshSerialize}; use risc0_zkvm::sha::Digest; -use risc0_zkvm::Receipt; use serde::{Deserialize, Serialize}; use sov_rollup_interface::da::BlockHeaderTrait; use sov_rollup_interface::spec::SpecId; @@ -131,17 +130,17 @@ impl sov_rollup_interface::zk::Zkvm for MockZkv type Error = anyhow::Error; - fn verify<'a>( - serialized_proof: &'a [u8], + fn verify( + serialized_proof: &[u8], code_commitment: &Self::CodeCommitment, - ) -> Result<&'a [u8], Self::Error> { + ) -> Result, Self::Error> { let proof = MockProof::decode(serialized_proof)?; anyhow::ensure!( proof.program_id.matches(code_commitment), "Proof failed to verify against requested code commitment" ); anyhow::ensure!(proof.is_valid, "Proof is not valid"); - Ok(&serialized_proof[33..]) + Ok(serialized_proof[33..].to_vec()) } fn verify_and_extract_output( @@ -181,34 +180,25 @@ impl sov_rollup_interface::zk::ZkvmHost fn extract_output( proof: &Proof, - ) -> Result< - ( - sov_rollup_interface::zk::StateTransition, - Option, - ), - Self::Error, - > { + ) -> Result, Self::Error> { match proof { sov_rollup_interface::zk::Proof::PublicInput(pub_input) => { let data: ProofInfo = bincode::deserialize(pub_input)?; let st: StateTransitionData = BorshDeserialize::deserialize(&mut &*data.hint)?; - Ok(( - sov_rollup_interface::zk::StateTransition { - initial_state_root: st.initial_state_root, - final_state_root: st.final_state_root, - initial_batch_hash: st.initial_batch_hash, - validity_condition: data.validity_condition, - state_diff: Default::default(), - da_slot_hash: st.da_block_header_of_commitments.hash(), - sequencer_public_key: vec![], - sequencer_da_public_key: vec![], - sequencer_commitments_range: (0, 0), - final_spec_id: SpecId::Genesis, - }, - None, - )) + Ok(sov_rollup_interface::zk::StateTransition { + initial_state_root: st.initial_state_root, + final_state_root: st.final_state_root, + initial_batch_hash: st.initial_batch_hash, + validity_condition: data.validity_condition, + state_diff: Default::default(), + da_slot_hash: st.da_block_header_of_commitments.hash(), + sequencer_public_key: vec![], + sequencer_da_public_key: vec![], + sequencer_commitments_range: (0, 0), + final_spec_id: SpecId::Genesis, + }) } sov_rollup_interface::zk::Proof::Full(_) => { panic!("Mock DA doesn't generate real proofs") @@ -229,10 +219,10 @@ impl sov_rollup_interface::zk::Zkvm for MockZkGuest { type Error = anyhow::Error; - fn verify<'a>( - _serialized_proof: &'a [u8], + fn verify( + _serialized_proof: &[u8], _code_commitment: &Self::CodeCommitment, - ) -> Result<&'a [u8], Self::Error> { + ) -> Result, Self::Error> { unimplemented!() } diff --git a/crates/sovereign-sdk/adapters/risc0/src/guest/mod.rs b/crates/sovereign-sdk/adapters/risc0/src/guest/mod.rs index 28e9e71b4..1d1e5429f 100644 --- a/crates/sovereign-sdk/adapters/risc0/src/guest/mod.rs +++ b/crates/sovereign-sdk/adapters/risc0/src/guest/mod.rs @@ -28,10 +28,10 @@ impl Zkvm for Risc0Guest { type Error = anyhow::Error; - fn verify<'a>( - _serialized_proof: &'a [u8], + fn verify( + _serialized_proof: &[u8], _code_commitment: &Self::CodeCommitment, - ) -> Result<&'a [u8], Self::Error> { + ) -> Result, Self::Error> { // Implement this method once risc0 supports recursion: issue #633 todo!("Implement once risc0 supports recursion: https://github.com/Sovereign-Labs/sovereign-sdk/issues/633") } diff --git a/crates/sovereign-sdk/adapters/risc0/src/host.rs b/crates/sovereign-sdk/adapters/risc0/src/host.rs index d75e97edb..e6ecf955f 100644 --- a/crates/sovereign-sdk/adapters/risc0/src/host.rs +++ b/crates/sovereign-sdk/adapters/risc0/src/host.rs @@ -92,24 +92,18 @@ impl<'a> ZkvmHost for Risc0Host<'a> { fn extract_output( proof: &Proof, - ) -> Result< - ( - sov_rollup_interface::zk::StateTransition, - Option, - ), - Self::Error, - > { - let (journal, receipt) = match proof { + ) -> Result, Self::Error> { + let journal = match proof { Proof::PublicInput(journal) => { let journal: Journal = bincode::deserialize(journal)?; - (journal, None) + journal } Proof::Full(data) => { let receipt: Receipt = bincode::deserialize(data)?; - (receipt.journal.clone(), Some(receipt)) + receipt.journal } }; - Ok((BorshDeserialize::try_from_slice(&journal.bytes)?, receipt)) + Ok(BorshDeserialize::try_from_slice(&journal.bytes)?) } fn recover_proving_sessions(&self) -> Result, anyhow::Error> { @@ -122,10 +116,10 @@ impl<'host> Zkvm for Risc0Host<'host> { type Error = anyhow::Error; - fn verify<'a>( - serialized_proof: &'a [u8], + fn verify( + serialized_proof: &[u8], code_commitment: &Self::CodeCommitment, - ) -> Result<&'a [u8], Self::Error> { + ) -> Result, Self::Error> { verify_from_slice(serialized_proof, code_commitment) } @@ -146,10 +140,10 @@ impl Zkvm for Risc0Verifier { type Error = anyhow::Error; - fn verify<'a>( - serialized_proof: &'a [u8], + fn verify( + serialized_proof: &[u8], code_commitment: &Self::CodeCommitment, - ) -> Result<&'a [u8], Self::Error> { + ) -> Result, Self::Error> { verify_from_slice(serialized_proof, code_commitment) } @@ -162,11 +156,11 @@ impl Zkvm for Risc0Verifier { } } -fn verify_from_slice<'a>( - serialized_proof: &'a [u8], +fn verify_from_slice( + serialized_proof: &[u8], code_commitment: &Risc0MethodId, -) -> Result<&'a [u8], anyhow::Error> { - let Risc0Proof::<'a> { +) -> Result, anyhow::Error> { + let Risc0Proof { receipt, journal, .. } = bincode::deserialize(serialized_proof)?; @@ -176,7 +170,7 @@ fn verify_from_slice<'a>( receipt.verify(code_commitment.0)?; - Ok(journal) + Ok(journal.to_vec()) } /// A convenience type which contains the same data a Risc0 [`Receipt`] but borrows the journal diff --git a/crates/sovereign-sdk/rollup-interface/Cargo.toml b/crates/sovereign-sdk/rollup-interface/Cargo.toml index 64d5b0694..81ee847db 100644 --- a/crates/sovereign-sdk/rollup-interface/Cargo.toml +++ b/crates/sovereign-sdk/rollup-interface/Cargo.toml @@ -21,7 +21,6 @@ borsh = { workspace = true } bytes = { workspace = true, optional = true, default-features = true } digest = { workspace = true } hex = { workspace = true } -risc0-zkvm = { workspace = true } serde = { workspace = true } sha2 = { workspace = true, optional = true } thiserror = { workspace = true, optional = true } diff --git a/crates/sovereign-sdk/rollup-interface/src/state_machine/zk/mod.rs b/crates/sovereign-sdk/rollup-interface/src/state_machine/zk/mod.rs index 489d4ae20..68b9f4acc 100644 --- a/crates/sovereign-sdk/rollup-interface/src/state_machine/zk/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/state_machine/zk/mod.rs @@ -16,7 +16,6 @@ use core::fmt::Debug; use borsh::{BorshDeserialize, BorshSerialize}; use digest::Digest; -use risc0_zkvm::Receipt; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; @@ -57,7 +56,7 @@ pub trait ZkvmHost: Zkvm + Clone { #[allow(clippy::type_complexity)] fn extract_output( proof: &Proof, - ) -> Result<(StateTransition, Option), Self::Error>; + ) -> Result, Self::Error>; /// Host recovers pending proving sessions and returns proving results fn recover_proving_sessions(&self) -> Result, anyhow::Error>; @@ -67,21 +66,17 @@ pub trait ZkvmHost: Zkvm + Clone { /// Must support recursive proofs. pub trait Zkvm: Send + Sync { /// A commitment to the zkVM program which is being proven - type CodeCommitment: Clone - + Debug - + Serialize - + DeserializeOwned - + Into; + type CodeCommitment: Clone + Debug + Serialize + DeserializeOwned; /// The error type which is returned when a proof fails to verify type Error: Debug; /// Interpret a sequence of a bytes as a proof and attempt to verify it against the code commitment. /// If the proof is valid, return a reference to the public outputs of the proof. - fn verify<'a>( - serialized_proof: &'a [u8], + fn verify( + serialized_proof: &[u8], code_commitment: &Self::CodeCommitment, - ) -> Result<&'a [u8], Self::Error>; + ) -> Result, Self::Error>; /// Same as [`verify`](Zkvm::verify), except that instead of returning the output /// as a serialized array, it returns a state transition structure.