refactor outer program for readability

This commit is contained in:
Sergio Chouhy 2025-07-20 19:58:02 -03:00
parent 7b5db43238
commit 1e95534610

View File

@ -33,8 +33,8 @@ fn main() {
let num_inputs = inner_program_output.accounts_pre.len();
// Read visibilities
let account_visibilities: Vec<AccountVisibility> = env::read();
assert_eq!(account_visibilities.len(), num_inputs);
let visibilities: Vec<AccountVisibility> = env::read();
assert_eq!(visibilities.len(), num_inputs);
// Read nonces for outputs
let output_nonces: Vec<Nonce> = env::read();
@ -45,8 +45,89 @@ fn main() {
let program_id: ProgramId = env::read();
// Authentication step:
// Check private accounts are owned by caller and that they are consistent
// with the commitments tree.
let nullifiers = verify_and_nullify_private_inputs(&inner_program_output, &visibilities, commitment_tree_root);
// Verify pre states and post states of accounts are consistent
// with the execution of the `program_id` program
env::verify(program_id, &to_vec(&inner_program_output).unwrap()).unwrap();
// Assert accounts pre- and post-states preserve chains invariants
assert!(inputs_outputs_preserve_invariants(
&inner_program_output.accounts_pre,
&inner_program_output.accounts_post
));
// From this point on the execution is considered valid
let output = assemble_privacy_execution_output(
inner_program_output,
visibilities,
output_nonces,
commitment_tree_root,
nullifiers,
);
env::commit(&output);
}
fn assemble_privacy_execution_output(
inner_program_output: ProgramOutput,
visibilities: Vec<AccountVisibility>,
output_nonces: Vec<[u32; 8]>,
commitment_tree_root: [u32; 8],
nullifiers: Vec<[u32; 8]>,
) -> PrivacyExecutionOutput {
// Insert new nonces in outputs (including public ones)
let accounts_pre = inner_program_output.accounts_pre;
let mut accounts_post = inner_program_output.accounts_post;
accounts_post
.iter_mut()
.zip(output_nonces)
.for_each(|(account, new_nonce)| account.nonce = new_nonce);
// Compute commitments for every private output
let mut private_outputs = Vec::new();
for (output, visibility) in accounts_post.iter().zip(visibilities.iter()) {
match visibility {
AccountVisibility::Public => continue,
AccountVisibility::Private(_) => private_outputs.push(output),
}
}
let private_output_commitments: Vec<_> = private_outputs.iter().map(|account| account.commitment()).collect();
// Get the list of public accounts pre and post states
let mut public_accounts_pre = Vec::new();
let mut public_accounts_post = Vec::new();
for ((account_pre, account_post), visibility) in accounts_pre
.into_iter()
.zip(accounts_post.into_iter())
.zip(visibilities)
{
match visibility {
AccountVisibility::Public => {
public_accounts_pre.push(account_pre);
public_accounts_post.push(account_post);
}
AccountVisibility::Private(_) => continue,
}
}
let output = PrivacyExecutionOutput {
public_accounts_pre,
public_accounts_post,
private_output_commitments,
nullifiers,
commitment_tree_root,
};
output
}
/// Compute nullifiers of private accounts pre states and check that their commitments belong to the commitments tree
fn verify_and_nullify_private_inputs(
inner_program_output: &ProgramOutput,
account_visibilities: &Vec<AccountVisibility>,
commitment_tree_root: [u32; 8],
) -> Vec<[u32; 8]> {
let mut nullifiers = Vec::new();
for (visibility, input_account) in account_visibilities
.iter()
@ -73,61 +154,5 @@ fn main() {
AccountVisibility::Public => continue,
}
}
// Verify pre states and post states of accounts are consistent
// with the execution of the `program_id` program
env::verify(program_id, &to_vec(&inner_program_output).unwrap()).unwrap();
// Assert accounts pre- and post-states preserve chains invariants
assert!(inputs_outputs_preserve_invariants(
&inner_program_output.accounts_pre,
&inner_program_output.accounts_post
));
// From this point on the execution is considered valid
//
// Insert new nonces in outputs (including public ones)
let accounts_pre = inner_program_output.accounts_pre;
let mut accounts_post = inner_program_output.accounts_post;
accounts_post
.iter_mut()
.zip(output_nonces)
.for_each(|(account, new_nonce)| account.nonce = new_nonce);
// Compute commitments for every private output
let mut private_outputs = Vec::new();
for (output, visibility) in accounts_post.iter().zip(account_visibilities.iter()) {
match visibility {
AccountVisibility::Public => continue,
AccountVisibility::Private(_) => private_outputs.push(output),
}
}
let private_output_commitments: Vec<_> = private_outputs.iter().map(|account| account.commitment()).collect();
// Get the list of public accounts pre and post states
let mut public_accounts_pre = Vec::new();
let mut public_accounts_post = Vec::new();
for ((account_pre, account_post), visibility) in accounts_pre
.into_iter()
.zip(accounts_post.into_iter())
.zip(account_visibilities)
{
match visibility {
AccountVisibility::Public => {
public_accounts_pre.push(account_pre);
public_accounts_post.push(account_post);
}
AccountVisibility::Private(_) => continue,
}
}
let output = PrivacyExecutionOutput {
public_accounts_pre,
public_accounts_post,
private_output_commitments,
nullifiers,
commitment_tree_root,
};
env::commit(&output);
nullifiers
}