79 lines
3.1 KiB
Rust
Raw Normal View History

2025-07-19 19:12:56 -03:00
use core::types::PrivacyExecutionOutput;
2025-07-18 10:29:41 -03:00
use risc0_zkvm::Receipt;
2025-07-19 22:31:25 -03:00
use super::error::Error;
2025-07-18 10:29:41 -03:00
use super::MockedSequencer;
impl MockedSequencer {
2025-07-18 16:42:55 -03:00
/// Processes a privacy execution request.
/// Verifies the proof of the privacy execution and updates the state of the chain.
2025-07-19 22:31:25 -03:00
pub fn process_privacy_execution(&mut self, receipt: Receipt) -> Result<(), Error> {
2025-07-19 18:08:57 -03:00
// Parse the output of the "outer" program
let output: PrivacyExecutionOutput = receipt.journal.decode().unwrap();
2025-07-18 10:29:41 -03:00
2025-07-18 16:42:55 -03:00
// Reject in case the root used in the privacy execution is not the current root.
2025-07-19 18:08:57 -03:00
if output.commitment_tree_root != self.get_commitment_tree_root() {
2025-07-19 22:31:25 -03:00
return Err(Error::Generic);
2025-07-18 10:29:41 -03:00
}
2025-07-19 18:08:57 -03:00
// Reject in case the number of accounts pre states is different from the post states
if output.public_accounts_pre.len() != output.public_accounts_post.len() {
2025-07-19 22:31:25 -03:00
return Err(Error::Generic);
2025-07-18 10:29:41 -03:00
}
2025-07-18 16:42:55 -03:00
// Reject if the states of the public input accounts used in the inner execution do not
// coincide with the on-chain state.
2025-07-19 18:08:57 -03:00
for account in output.public_accounts_pre.iter() {
2025-07-19 22:31:25 -03:00
let current_account = self.get_account(&account.address).ok_or(Error::Generic)?;
2025-07-18 10:29:41 -03:00
if &current_account != account {
2025-07-19 22:31:25 -03:00
return Err(Error::Generic);
2025-07-18 10:29:41 -03:00
}
}
2025-07-18 16:42:55 -03:00
// Reject if the nullifiers of this privacy execution have already been published.
2025-07-19 18:08:57 -03:00
if output
.nullifiers
2025-07-18 10:29:41 -03:00
.iter()
.any(|nullifier| self.nullifier_set.contains(nullifier))
{
2025-07-19 22:31:25 -03:00
return Err(Error::Generic);
2025-07-18 10:29:41 -03:00
}
2025-07-18 16:42:55 -03:00
// Reject if the commitments have already been seen.
2025-07-19 18:08:57 -03:00
if output
.private_output_commitments
2025-07-18 10:29:41 -03:00
.iter()
.any(|commitment| self.commitment_tree.values().contains(commitment))
{
2025-07-19 22:31:25 -03:00
return Err(Error::Generic);
2025-07-18 10:29:41 -03:00
}
2025-07-18 16:42:55 -03:00
// Verify the proof of the privacy execution.
// This includes a proof of the following statements
// - Public inputs, public outputs, commitments and nullifiers are consistent with the
// execution of some program.
// - The given nullifiers correctly correspond to commitments that currently belong to
// the commitment tree.
// - The given commitments are correctly computed from valid accounts.
2025-07-19 22:31:25 -03:00
nssa::verify_privacy_execution(receipt).map_err(|_| Error::Generic)?;
2025-07-18 10:29:41 -03:00
2025-07-18 16:42:55 -03:00
// At this point the privacy execution is considered valid.
//
// Update the state of the public accounts with the post-state of this privacy execution
2025-07-19 18:08:57 -03:00
output.public_accounts_post.into_iter().for_each(|account_post_state| {
self.accounts.insert(account_post_state.address, account_post_state);
});
2025-07-18 10:29:41 -03:00
2025-07-18 16:42:55 -03:00
// Add all nullifiers to the nullifier set.
2025-07-19 18:08:57 -03:00
self.nullifier_set.extend(output.nullifiers);
2025-07-18 10:29:41 -03:00
2025-07-18 16:42:55 -03:00
// Add commitments to the commitment tree.
2025-07-19 18:08:57 -03:00
for commitment in output.private_output_commitments.iter() {
2025-07-18 10:29:41 -03:00
self.commitment_tree.add_value(*commitment);
}
Ok(())
}
}