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 ¤t_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(())
|
|
|
|
|
}
|
|
|
|
|
}
|