From 7ae7135ff719818bb02b39930ae3d322c9d6d104 Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Thu, 17 Jul 2025 14:02:54 -0300 Subject: [PATCH] add verify privacy method to mocked sequencer --- .../examples/sequencer_mock/mod.rs | 62 ++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/risc0-selective-privacy-poc/examples/sequencer_mock/mod.rs b/risc0-selective-privacy-poc/examples/sequencer_mock/mod.rs index b74e73f..2a4398d 100644 --- a/risc0-selective-privacy-poc/examples/sequencer_mock/mod.rs +++ b/risc0-selective-privacy-poc/examples/sequencer_mock/mod.rs @@ -1,11 +1,13 @@ use core::{ account::Account, - types::{Address, Key, Nullifier, ProgramId}, + bytes_to_words, + types::{Address, Commitment, Key, Nullifier, ProgramId}, }; use std::collections::{BTreeMap, HashSet}; use nssa; use program_methods::{PINATA_ID, TRANSFER_ID, TRANSFER_MULTIPLE_ID}; +use risc0_zkvm::Receipt; use sparse_merkle_tree::SparseMerkleTree; pub struct MockedSequencer { @@ -54,6 +56,64 @@ impl MockedSequencer { self.accounts.get(address).cloned() } + pub fn invoke_privacy_execution( + &mut self, + receipt: Receipt, + public_inputs_outputs: &[Account], + nullifiers: &[Nullifier], + commitments: &[Commitment], + ) -> Result<(), ()> { + let commitments_tree_root = bytes_to_words(&self.commitment_tree.root()); + if public_inputs_outputs.len() % 2 != 0 { + return Err(()); + } + + let num_input_public = public_inputs_outputs.len() >> 1; + for account in public_inputs_outputs.iter() { + let current_account = self.get_account(&account.address).ok_or(())?; + if ¤t_account != account { + return Err(()); + } + } + + // Check that nullifiers have not been added before + if nullifiers + .iter() + .any(|nullifier| self.nullifier_set.contains(nullifier)) + { + return Err(()); + } + + // Check that commitments are new too + if commitments + .iter() + .any(|commitment| self.commitment_tree.values().contains(commitment)) + { + return Err(()); + } + + // Verify consistency between public accounts, nullifiers and commitments + nssa::verify_privacy_execution( + receipt, + public_inputs_outputs, + nullifiers, + commitments, + &commitments_tree_root, + )?; + + // Update accounts + public_inputs_outputs + .iter() + .cloned() + .skip(num_input_public) + .for_each(|account_post_state| { + self.accounts + .insert(account_post_state.address, account_post_state); + }); + + Ok(()) + } + pub fn invoke_public( &mut self, input_account_addresses: &[Address],