From ac7b8d418d1db9913b737bf463196f3ec4fac174 Mon Sep 17 00:00:00 2001 From: Daniil Polyakov Date: Thu, 25 Dec 2025 01:49:34 +0300 Subject: [PATCH] feat: implement private multi chain calls in wallet (nssa) --- .../src/bin/run_hello_world_private.rs | 2 +- ...n_hello_world_through_tail_call_private.rs | 2 +- .../bin/run_hello_world_with_move_function.rs | 4 +- integration_tests/src/tps_test_utils.rs | 14 +- .../privacy_preserving_transaction/circuit.rs | 115 ++--- nssa/src/state.rs | 448 +++++++++--------- wallet/src/lib.rs | 16 +- .../native_token_transfer/deshielded.rs | 2 +- .../native_token_transfer/private.rs | 6 +- .../native_token_transfer/shielded.rs | 4 +- wallet/src/program_facades/pinata.rs | 2 +- wallet/src/program_facades/token.rs | 32 +- 12 files changed, 325 insertions(+), 322 deletions(-) diff --git a/examples/program_deployment/src/bin/run_hello_world_private.rs b/examples/program_deployment/src/bin/run_hello_world_private.rs index dcbe59a..ac6e123 100644 --- a/examples/program_deployment/src/bin/run_hello_world_private.rs +++ b/examples/program_deployment/src/bin/run_hello_world_private.rs @@ -53,7 +53,7 @@ async fn main() { wallet_core .send_privacy_preserving_tx( accounts, - &Program::serialize_instruction(greeting).unwrap(), + Program::serialize_instruction(greeting).unwrap(), &program.into(), ) .await diff --git a/examples/program_deployment/src/bin/run_hello_world_through_tail_call_private.rs b/examples/program_deployment/src/bin/run_hello_world_through_tail_call_private.rs index 5a014f2..40199ee 100644 --- a/examples/program_deployment/src/bin/run_hello_world_through_tail_call_private.rs +++ b/examples/program_deployment/src/bin/run_hello_world_through_tail_call_private.rs @@ -61,7 +61,7 @@ async fn main() { wallet_core .send_privacy_preserving_tx( accounts, - &Program::serialize_instruction(instruction).unwrap(), + Program::serialize_instruction(instruction).unwrap(), &program_with_dependencies, ) .await diff --git a/examples/program_deployment/src/bin/run_hello_world_with_move_function.rs b/examples/program_deployment/src/bin/run_hello_world_with_move_function.rs index 4307315..c9896b8 100644 --- a/examples/program_deployment/src/bin/run_hello_world_with_move_function.rs +++ b/examples/program_deployment/src/bin/run_hello_world_with_move_function.rs @@ -104,7 +104,7 @@ async fn main() { wallet_core .send_privacy_preserving_tx( accounts, - &Program::serialize_instruction(instruction).unwrap(), + Program::serialize_instruction(instruction).unwrap(), &program.into(), ) .await @@ -145,7 +145,7 @@ async fn main() { wallet_core .send_privacy_preserving_tx( accounts, - &Program::serialize_instruction(instruction).unwrap(), + Program::serialize_instruction(instruction).unwrap(), &program.into(), ) .await diff --git a/integration_tests/src/tps_test_utils.rs b/integration_tests/src/tps_test_utils.rs index 154253c..744b31c 100644 --- a/integration_tests/src/tps_test_utils.rs +++ b/integration_tests/src/tps_test_utils.rs @@ -159,16 +159,16 @@ fn build_privacy_transaction() -> PrivacyPreservingTransaction { ]], ); let (output, proof) = circuit::execute_and_prove( - &[sender_pre, recipient_pre], - &Program::serialize_instruction(balance_to_move).unwrap(), - &[1, 2], - &[0xdeadbeef1, 0xdeadbeef2], - &[ + vec![sender_pre, recipient_pre], + Program::serialize_instruction(balance_to_move).unwrap(), + vec![1, 2], + vec![0xdeadbeef1, 0xdeadbeef2], + vec![ (sender_npk.clone(), sender_ss), (recipient_npk.clone(), recipient_ss), ], - &[sender_nsk], - &[Some(proof)], + vec![sender_nsk], + vec![Some(proof)], &program.into(), ) .unwrap(); diff --git a/nssa/src/privacy_preserving_transaction/circuit.rs b/nssa/src/privacy_preserving_transaction/circuit.rs index f29eb1c..286d5fc 100644 --- a/nssa/src/privacy_preserving_transaction/circuit.rs +++ b/nssa/src/privacy_preserving_transaction/circuit.rs @@ -1,11 +1,11 @@ -use std::collections::HashMap; +use std::collections::{HashMap, VecDeque}; use borsh::{BorshDeserialize, BorshSerialize}; use nssa_core::{ MembershipProof, NullifierPublicKey, NullifierSecretKey, PrivacyPreservingCircuitInput, PrivacyPreservingCircuitOutput, SharedSecretKey, account::AccountWithMetadata, - program::{InstructionData, ProgramId, ProgramOutput}, + program::{ChainedCall, InstructionData, ProgramId, ProgramOutput}, }; use risc0_zkvm::{ExecutorEnv, InnerReceipt, Receipt, default_prover}; @@ -46,69 +46,72 @@ impl From for ProgramWithDependencies { /// circuit #[expect(clippy::too_many_arguments, reason = "TODO: fix later")] pub fn execute_and_prove( - pre_states: &[AccountWithMetadata], - instruction_data: &InstructionData, - visibility_mask: &[u8], - private_account_nonces: &[u128], - private_account_keys: &[(NullifierPublicKey, SharedSecretKey)], - private_account_nsks: &[NullifierSecretKey], - private_account_membership_proofs: &[Option], + pre_states: Vec, + instruction_data: InstructionData, + visibility_mask: Vec, + private_account_nonces: Vec, + private_account_keys: Vec<(NullifierPublicKey, SharedSecretKey)>, + private_account_nsks: Vec, + private_account_membership_proofs: Vec>, program_with_dependencies: &ProgramWithDependencies, ) -> Result<(PrivacyPreservingCircuitOutput, Proof), NssaError> { - let mut program = &program_with_dependencies.program; - let dependencies = &program_with_dependencies.dependencies; - let mut instruction_data = instruction_data.clone(); - let mut pre_states = pre_states.to_vec(); + let ProgramWithDependencies { + program, + dependencies, + } = program_with_dependencies; let mut env_builder = ExecutorEnv::builder(); let mut program_outputs = Vec::new(); - for _i in 0..MAX_NUMBER_CHAINED_CALLS { - let inner_receipt = execute_and_prove_program(program, &pre_states, &instruction_data)?; + let initial_call = ChainedCall { + program_id: program.id(), + instruction_data: instruction_data.clone(), + pre_states, + pda_seeds: vec![], + }; + + let mut chained_calls = VecDeque::from_iter([(initial_call, program)]); + let mut chain_calls_counter = 0; + while let Some((chained_call, program)) = chained_calls.pop_front() { + if chain_calls_counter >= MAX_NUMBER_CHAINED_CALLS { + return Err(NssaError::MaxChainedCallsDepthExceeded); + } + + let inner_receipt = execute_and_prove_program( + program, + &chained_call.pre_states, + &chained_call.instruction_data, + )?; let program_output: ProgramOutput = inner_receipt .journal .decode() .map_err(|e| NssaError::ProgramOutputDeserializationError(e.to_string()))?; + // TODO: Why private execution doesn't care about public account authorization? + // TODO: remove clone program_outputs.push(program_output.clone()); // Prove circuit. env_builder.add_assumption(inner_receipt); - // TODO: Remove when multi-chain calls are supported in the circuit - assert!(program_output.chained_calls.len() <= 1); - // TODO: Modify when multi-chain calls are supported in the circuit - if let Some(next_call) = program_output.chained_calls.first() { - program = dependencies - .get(&next_call.program_id) + for new_call in program_output.chained_calls.into_iter().rev() { + let next_program = dependencies + .get(&new_call.program_id) .ok_or(NssaError::InvalidProgramBehavior)?; - instruction_data = next_call.instruction_data.clone(); - // Build post states with metadata for next call - let mut post_states_with_metadata = Vec::new(); - for (pre, post) in program_output - .pre_states - .iter() - .zip(program_output.post_states) - { - let mut post_with_metadata = pre.clone(); - post_with_metadata.account = post.account().clone(); - post_states_with_metadata.push(post_with_metadata); - } - - pre_states = next_call.pre_states.clone(); - } else { - break; + chained_calls.push_front((new_call, next_program)); } + + chain_calls_counter += 1; } let circuit_input = PrivacyPreservingCircuitInput { program_outputs, - visibility_mask: visibility_mask.to_vec(), - private_account_nonces: private_account_nonces.to_vec(), - private_account_keys: private_account_keys.to_vec(), - private_account_nsks: private_account_nsks.to_vec(), - private_account_membership_proofs: private_account_membership_proofs.to_vec(), + visibility_mask, + private_account_nonces, + private_account_keys, + private_account_nsks, + private_account_membership_proofs, program_id: program_with_dependencies.program.id(), }; @@ -215,13 +218,13 @@ mod tests { let shared_secret = SharedSecretKey::new(&esk, &recipient_keys.ivk()); let (output, proof) = execute_and_prove( - &[sender, recipient], - &Program::serialize_instruction(balance_to_move).unwrap(), - &[0, 2], - &[0xdeadbeef], - &[(recipient_keys.npk(), shared_secret)], - &[], - &[None], + vec![sender, recipient], + Program::serialize_instruction(balance_to_move).unwrap(), + vec![0, 2], + vec![0xdeadbeef], + vec![(recipient_keys.npk(), shared_secret)], + vec![], + vec![None], &Program::authenticated_transfer_program().into(), ) .unwrap(); @@ -311,16 +314,16 @@ mod tests { let shared_secret_2 = SharedSecretKey::new(&esk_2, &recipient_keys.ivk()); let (output, proof) = execute_and_prove( - &[sender_pre.clone(), recipient], - &Program::serialize_instruction(balance_to_move).unwrap(), - &[1, 2], - &[0xdeadbeef1, 0xdeadbeef2], - &[ + vec![sender_pre.clone(), recipient], + Program::serialize_instruction(balance_to_move).unwrap(), + vec![1, 2], + vec![0xdeadbeef1, 0xdeadbeef2], + vec![ (sender_keys.npk(), shared_secret_1), (recipient_keys.npk(), shared_secret_2), ], - &[sender_keys.nsk], - &[commitment_set.get_proof_for(&commitment_sender), None], + vec![sender_keys.nsk], + vec![commitment_set.get_proof_for(&commitment_sender), None], &program.into(), ) .unwrap(); diff --git a/nssa/src/state.rs b/nssa/src/state.rs index bc0ff62..eab164c 100644 --- a/nssa/src/state.rs +++ b/nssa/src/state.rs @@ -865,13 +865,13 @@ pub mod tests { let epk = EphemeralPublicKey::from_scalar(esk); let (output, proof) = circuit::execute_and_prove( - &[sender, recipient], - &Program::serialize_instruction(balance_to_move).unwrap(), - &[0, 2], - &[0xdeadbeef], - &[(recipient_keys.npk(), shared_secret)], - &[], - &[None], + vec![sender, recipient], + Program::serialize_instruction(balance_to_move).unwrap(), + vec![0, 2], + vec![0xdeadbeef], + vec![(recipient_keys.npk(), shared_secret)], + vec![], + vec![None], &Program::authenticated_transfer_program().into(), ) .unwrap(); @@ -912,16 +912,16 @@ pub mod tests { let epk_2 = EphemeralPublicKey::from_scalar(esk_2); let (output, proof) = circuit::execute_and_prove( - &[sender_pre, recipient_pre], - &Program::serialize_instruction(balance_to_move).unwrap(), - &[1, 2], - &new_nonces, - &[ + vec![sender_pre, recipient_pre], + Program::serialize_instruction(balance_to_move).unwrap(), + vec![1, 2], + new_nonces.to_vec(), + vec![ (sender_keys.npk(), shared_secret_1), (recipient_keys.npk(), shared_secret_2), ], - &[sender_keys.nsk], - &[state.get_proof_for_commitment(&sender_commitment), None], + vec![sender_keys.nsk], + vec![state.get_proof_for_commitment(&sender_commitment), None], &program.into(), ) .unwrap(); @@ -965,13 +965,13 @@ pub mod tests { let epk = EphemeralPublicKey::from_scalar(esk); let (output, proof) = circuit::execute_and_prove( - &[sender_pre, recipient_pre], - &Program::serialize_instruction(balance_to_move).unwrap(), - &[1, 0], - &[new_nonce], - &[(sender_keys.npk(), shared_secret)], - &[sender_keys.nsk], - &[state.get_proof_for_commitment(&sender_commitment)], + vec![sender_pre, recipient_pre], + Program::serialize_instruction(balance_to_move).unwrap(), + vec![1, 0], + vec![new_nonce], + vec![(sender_keys.npk(), shared_secret)], + vec![sender_keys.nsk], + vec![state.get_proof_for_commitment(&sender_commitment)], &program.into(), ) .unwrap(); @@ -1179,13 +1179,13 @@ pub mod tests { ); let result = execute_and_prove( - &[public_account], - &Program::serialize_instruction(10u128).unwrap(), - &[0], - &[], - &[], - &[], - &[], + vec![public_account], + Program::serialize_instruction(10u128).unwrap(), + vec![0], + vec![], + vec![], + vec![], + vec![], &program.into(), ); @@ -1206,13 +1206,13 @@ pub mod tests { ); let result = execute_and_prove( - &[public_account], - &Program::serialize_instruction(10u128).unwrap(), - &[0], - &[], - &[], - &[], - &[], + vec![public_account], + Program::serialize_instruction(10u128).unwrap(), + vec![0], + vec![], + vec![], + vec![], + vec![], &program.into(), ); @@ -1233,13 +1233,13 @@ pub mod tests { ); let result = execute_and_prove( - &[public_account], - &Program::serialize_instruction(()).unwrap(), - &[0], - &[], - &[], - &[], - &[], + vec![public_account], + Program::serialize_instruction(()).unwrap(), + vec![0], + vec![], + vec![], + vec![], + vec![], &program.into(), ); @@ -1260,13 +1260,13 @@ pub mod tests { ); let result = execute_and_prove( - &[public_account], - &Program::serialize_instruction(vec![0]).unwrap(), - &[0], - &[], - &[], - &[], - &[], + vec![public_account], + Program::serialize_instruction(vec![0]).unwrap(), + vec![0], + vec![], + vec![], + vec![], + vec![], &program.into(), ); @@ -1289,13 +1289,13 @@ pub mod tests { let large_data: Vec = vec![0; nssa_core::account::data::DATA_MAX_LENGTH_IN_BYTES + 1]; let result = execute_and_prove( - &[public_account], - &Program::serialize_instruction(large_data).unwrap(), - &[0], - &[], - &[], - &[], - &[], + vec![public_account], + Program::serialize_instruction(large_data).unwrap(), + vec![0], + vec![], + vec![], + vec![], + vec![], &program.to_owned().into(), ); @@ -1316,13 +1316,13 @@ pub mod tests { ); let result = execute_and_prove( - &[public_account], - &Program::serialize_instruction(()).unwrap(), - &[0], - &[], - &[], - &[], - &[], + vec![public_account], + Program::serialize_instruction(()).unwrap(), + vec![0], + vec![], + vec![], + vec![], + vec![], &program.into(), ); @@ -1352,13 +1352,13 @@ pub mod tests { ); let result = execute_and_prove( - &[public_account_1, public_account_2], - &Program::serialize_instruction(()).unwrap(), - &[0, 0], - &[], - &[], - &[], - &[], + vec![public_account_1, public_account_2], + Program::serialize_instruction(()).unwrap(), + vec![0, 0], + vec![], + vec![], + vec![], + vec![], &program.into(), ); @@ -1379,13 +1379,13 @@ pub mod tests { ); let result = execute_and_prove( - &[public_account], - &Program::serialize_instruction(()).unwrap(), - &[0], - &[], - &[], - &[], - &[], + vec![public_account], + Program::serialize_instruction(()).unwrap(), + vec![0], + vec![], + vec![], + vec![], + vec![], &program.into(), ); @@ -1415,13 +1415,13 @@ pub mod tests { ); let result = execute_and_prove( - &[public_account_1, public_account_2], - &Program::serialize_instruction(10u128).unwrap(), - &[0, 0], - &[], - &[], - &[], - &[], + vec![public_account_1, public_account_2], + Program::serialize_instruction(10u128).unwrap(), + vec![0, 0], + vec![], + vec![], + vec![], + vec![], &program.into(), ); @@ -1453,13 +1453,13 @@ pub mod tests { // Setting only one visibility mask for a circuit execution with two pre_state accounts. let visibility_mask = [0]; let result = execute_and_prove( - &[public_account_1, public_account_2], - &Program::serialize_instruction(10u128).unwrap(), - &visibility_mask, - &[], - &[], - &[], - &[], + vec![public_account_1, public_account_2], + Program::serialize_instruction(10u128).unwrap(), + visibility_mask.to_vec(), + vec![], + vec![], + vec![], + vec![], &program.into(), ); @@ -1486,11 +1486,11 @@ pub mod tests { // Setting only one nonce for an execution with two private accounts. let private_account_nonces = [0xdeadbeef1]; let result = execute_and_prove( - &[private_account_1, private_account_2], - &Program::serialize_instruction(10u128).unwrap(), - &[1, 2], - &private_account_nonces, - &[ + vec![private_account_1, private_account_2], + Program::serialize_instruction(10u128).unwrap(), + vec![1, 2], + private_account_nonces.to_vec(), + vec![ ( sender_keys.npk(), SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), @@ -1500,8 +1500,8 @@ pub mod tests { SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()), ), ], - &[sender_keys.nsk], - &[Some((0, vec![]))], + vec![sender_keys.nsk], + vec![Some((0, vec![]))], &program.into(), ); @@ -1530,13 +1530,13 @@ pub mod tests { SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), )]; let result = execute_and_prove( - &[private_account_1, private_account_2], - &Program::serialize_instruction(10u128).unwrap(), - &[1, 2], - &[0xdeadbeef1, 0xdeadbeef2], - &private_account_keys, - &[sender_keys.nsk], - &[Some((0, vec![]))], + vec![private_account_1, private_account_2], + Program::serialize_instruction(10u128).unwrap(), + vec![1, 2], + vec![0xdeadbeef1, 0xdeadbeef2], + private_account_keys.to_vec(), + vec![sender_keys.nsk], + vec![Some((0, vec![]))], &program.into(), ); @@ -1563,11 +1563,11 @@ pub mod tests { // Setting no second commitment proof. let private_account_membership_proofs = [Some((0, vec![]))]; let result = execute_and_prove( - &[private_account_1, private_account_2], - &Program::serialize_instruction(10u128).unwrap(), - &[1, 2], - &[0xdeadbeef1, 0xdeadbeef2], - &[ + vec![private_account_1, private_account_2], + Program::serialize_instruction(10u128).unwrap(), + vec![1, 2], + vec![0xdeadbeef1, 0xdeadbeef2], + vec![ ( sender_keys.npk(), SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), @@ -1577,8 +1577,8 @@ pub mod tests { SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()), ), ], - &[sender_keys.nsk], - &private_account_membership_proofs, + vec![sender_keys.nsk], + private_account_membership_proofs.to_vec(), &program.into(), ); @@ -1605,11 +1605,11 @@ pub mod tests { // Setting no auth key for an execution with one non default private accounts. let private_account_nsks = []; let result = execute_and_prove( - &[private_account_1, private_account_2], - &Program::serialize_instruction(10u128).unwrap(), - &[1, 2], - &[0xdeadbeef1, 0xdeadbeef2], - &[ + vec![private_account_1, private_account_2], + Program::serialize_instruction(10u128).unwrap(), + vec![1, 2], + vec![0xdeadbeef1, 0xdeadbeef2], + vec![ ( sender_keys.npk(), SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), @@ -1619,8 +1619,8 @@ pub mod tests { SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()), ), ], - &private_account_nsks, - &[], + private_account_nsks.to_vec(), + vec![], &program.into(), ); @@ -1663,13 +1663,13 @@ pub mod tests { let private_account_nsks = [recipient_keys.nsk]; let private_account_membership_proofs = [Some((0, vec![]))]; let result = execute_and_prove( - &[private_account_1, private_account_2], - &Program::serialize_instruction(10u128).unwrap(), - &[1, 2], - &[0xdeadbeef1, 0xdeadbeef2], - &private_account_keys, - &private_account_nsks, - &private_account_membership_proofs, + vec![private_account_1, private_account_2], + Program::serialize_instruction(10u128).unwrap(), + vec![1, 2], + vec![0xdeadbeef1, 0xdeadbeef2], + private_account_keys.to_vec(), + private_account_nsks.to_vec(), + private_account_membership_proofs.to_vec(), &program.into(), ); @@ -1701,11 +1701,11 @@ pub mod tests { ); let result = execute_and_prove( - &[private_account_1, private_account_2], - &Program::serialize_instruction(10u128).unwrap(), - &[1, 2], - &[0xdeadbeef1, 0xdeadbeef2], - &[ + vec![private_account_1, private_account_2], + Program::serialize_instruction(10u128).unwrap(), + vec![1, 2], + vec![0xdeadbeef1, 0xdeadbeef2], + vec![ ( sender_keys.npk(), SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), @@ -1715,8 +1715,8 @@ pub mod tests { SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()), ), ], - &[sender_keys.nsk], - &[Some((0, vec![]))], + vec![sender_keys.nsk], + vec![Some((0, vec![]))], &program.into(), ); @@ -1749,11 +1749,11 @@ pub mod tests { ); let result = execute_and_prove( - &[private_account_1, private_account_2], - &Program::serialize_instruction(10u128).unwrap(), - &[1, 2], - &[0xdeadbeef1, 0xdeadbeef2], - &[ + vec![private_account_1, private_account_2], + Program::serialize_instruction(10u128).unwrap(), + vec![1, 2], + vec![0xdeadbeef1, 0xdeadbeef2], + vec![ ( sender_keys.npk(), SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), @@ -1763,8 +1763,8 @@ pub mod tests { SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()), ), ], - &[sender_keys.nsk], - &[Some((0, vec![]))], + vec![sender_keys.nsk], + vec![Some((0, vec![]))], &program.into(), ); @@ -1796,11 +1796,11 @@ pub mod tests { ); let result = execute_and_prove( - &[private_account_1, private_account_2], - &Program::serialize_instruction(10u128).unwrap(), - &[1, 2], - &[0xdeadbeef1, 0xdeadbeef2], - &[ + vec![private_account_1, private_account_2], + Program::serialize_instruction(10u128).unwrap(), + vec![1, 2], + vec![0xdeadbeef1, 0xdeadbeef2], + vec![ ( sender_keys.npk(), SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), @@ -1810,8 +1810,8 @@ pub mod tests { SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()), ), ], - &[sender_keys.nsk], - &[Some((0, vec![]))], + vec![sender_keys.nsk], + vec![Some((0, vec![]))], &program.into(), ); @@ -1843,11 +1843,11 @@ pub mod tests { ); let result = execute_and_prove( - &[private_account_1, private_account_2], - &Program::serialize_instruction(10u128).unwrap(), - &[1, 2], - &[0xdeadbeef1, 0xdeadbeef2], - &[ + vec![private_account_1, private_account_2], + Program::serialize_instruction(10u128).unwrap(), + vec![1, 2], + vec![0xdeadbeef1, 0xdeadbeef2], + vec![ ( sender_keys.npk(), SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), @@ -1857,8 +1857,8 @@ pub mod tests { SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()), ), ], - &[sender_keys.nsk], - &[Some((0, vec![]))], + vec![sender_keys.nsk], + vec![Some((0, vec![]))], &program.into(), ); @@ -1888,11 +1888,11 @@ pub mod tests { ); let result = execute_and_prove( - &[private_account_1, private_account_2], - &Program::serialize_instruction(10u128).unwrap(), - &[1, 2], - &[0xdeadbeef1, 0xdeadbeef2], - &[ + vec![private_account_1, private_account_2], + Program::serialize_instruction(10u128).unwrap(), + vec![1, 2], + vec![0xdeadbeef1, 0xdeadbeef2], + vec![ ( sender_keys.npk(), SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), @@ -1902,8 +1902,8 @@ pub mod tests { SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()), ), ], - &[sender_keys.nsk], - &[Some((0, vec![]))], + vec![sender_keys.nsk], + vec![Some((0, vec![]))], &program.into(), ); @@ -1927,13 +1927,13 @@ pub mod tests { let visibility_mask = [0, 3]; let result = execute_and_prove( - &[public_account_1, public_account_2], - &Program::serialize_instruction(10u128).unwrap(), - &visibility_mask, - &[], - &[], - &[], - &[], + vec![public_account_1, public_account_2], + Program::serialize_instruction(10u128).unwrap(), + visibility_mask.to_vec(), + vec![], + vec![], + vec![], + vec![], &program.into(), ); @@ -1961,11 +1961,11 @@ pub mod tests { // accounts. let private_account_nonces = [0xdeadbeef1, 0xdeadbeef2, 0xdeadbeef3]; let result = execute_and_prove( - &[private_account_1, private_account_2], - &Program::serialize_instruction(10u128).unwrap(), - &[1, 2], - &private_account_nonces, - &[ + vec![private_account_1, private_account_2], + Program::serialize_instruction(10u128).unwrap(), + vec![1, 2], + private_account_nonces.to_vec(), + vec![ ( sender_keys.npk(), SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), @@ -1975,8 +1975,8 @@ pub mod tests { SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()), ), ], - &[sender_keys.nsk], - &[Some((0, vec![]))], + vec![sender_keys.nsk], + vec![Some((0, vec![]))], &program.into(), ); @@ -2017,13 +2017,13 @@ pub mod tests { ), ]; let result = execute_and_prove( - &[private_account_1, private_account_2], - &Program::serialize_instruction(10u128).unwrap(), - &[1, 2], - &[0xdeadbeef1, 0xdeadbeef2], - &private_account_keys, - &[sender_keys.nsk], - &[Some((0, vec![]))], + vec![private_account_1, private_account_2], + Program::serialize_instruction(10u128).unwrap(), + vec![1, 2], + vec![0xdeadbeef1, 0xdeadbeef2], + private_account_keys.to_vec(), + vec![sender_keys.nsk], + vec![Some((0, vec![]))], &program.into(), ); @@ -2053,11 +2053,11 @@ pub mod tests { let private_account_nsks = [sender_keys.nsk, recipient_keys.nsk]; let private_account_membership_proofs = [Some((0, vec![])), Some((1, vec![]))]; let result = execute_and_prove( - &[private_account_1, private_account_2], - &Program::serialize_instruction(10u128).unwrap(), - &visibility_mask, - &[0xdeadbeef1, 0xdeadbeef2], - &[ + vec![private_account_1, private_account_2], + Program::serialize_instruction(10u128).unwrap(), + visibility_mask.to_vec(), + vec![0xdeadbeef1, 0xdeadbeef2], + vec![ ( sender_keys.npk(), SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), @@ -2067,8 +2067,8 @@ pub mod tests { SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()), ), ], - &private_account_nsks, - &private_account_membership_proofs, + private_account_nsks.to_vec(), + private_account_membership_proofs.to_vec(), &program.into(), ); @@ -2149,16 +2149,16 @@ pub mod tests { let private_account_membership_proofs = [Some((1, vec![])), Some((1, vec![]))]; let shared_secret = SharedSecretKey::new(&[55; 32], &sender_keys.ivk()); let result = execute_and_prove( - &[private_account_1.clone(), private_account_1], - &Program::serialize_instruction(100u128).unwrap(), - &visibility_mask, - &[0xdeadbeef1, 0xdeadbeef2], - &[ + vec![private_account_1.clone(), private_account_1], + Program::serialize_instruction(100u128).unwrap(), + visibility_mask.to_vec(), + vec![0xdeadbeef1, 0xdeadbeef2], + vec![ (sender_keys.npk(), shared_secret), (sender_keys.npk(), shared_secret), ], - &private_account_nsks, - &private_account_membership_proofs, + private_account_nsks.to_vec(), + private_account_membership_proofs.to_vec(), &program.into(), ); @@ -4014,13 +4014,13 @@ pub mod tests { // Act let (output, proof) = execute_and_prove( - &[to_account, from_account], - &Program::serialize_instruction(instruction).unwrap(), - &[1, 1], - &[from_new_nonce, to_new_nonce], - &[(from_keys.npk(), to_ss), (to_keys.npk(), from_ss)], - &[from_keys.nsk, to_keys.nsk], - &[ + vec![to_account, from_account], + Program::serialize_instruction(instruction).unwrap(), + vec![1, 1], + vec![from_new_nonce, to_new_nonce], + vec![(from_keys.npk(), to_ss), (to_keys.npk(), from_ss)], + vec![from_keys.nsk, to_keys.nsk], + vec![ state.get_proof_for_commitment(&from_commitment), state.get_proof_for_commitment(&to_commitment), ], @@ -4255,13 +4255,13 @@ pub mod tests { // Execute and prove the circuit with the authorized account but no commitment proof let (output, proof) = execute_and_prove( - std::slice::from_ref(&authorized_account), - &Program::serialize_instruction(balance).unwrap(), - &[1], - &[nonce], - &[(private_keys.npk(), shared_secret)], - &[private_keys.nsk], - &[None], + vec![authorized_account], + Program::serialize_instruction(balance).unwrap(), + vec![1], + vec![nonce], + vec![(private_keys.npk(), shared_secret)], + vec![private_keys.nsk], + vec![None], &program.into(), ) .unwrap(); @@ -4308,13 +4308,13 @@ pub mod tests { // Step 2: Execute claimer program to claim the account with authentication let (output, proof) = execute_and_prove( - std::slice::from_ref(&authorized_account), - &Program::serialize_instruction(balance).unwrap(), - &[1], - &[nonce], - &[(private_keys.npk(), shared_secret)], - &[private_keys.nsk], - &[None], + vec![authorized_account.clone()], + Program::serialize_instruction(balance).unwrap(), + vec![1], + vec![nonce], + vec![(private_keys.npk(), shared_secret)], + vec![private_keys.nsk], + vec![None], &claimer_program.into(), ) .unwrap(); @@ -4356,13 +4356,13 @@ pub mod tests { // Step 3: Try to execute noop program with authentication but without initialization let res = execute_and_prove( - std::slice::from_ref(&account_metadata), - &Program::serialize_instruction(()).unwrap(), - &[1], - &[nonce2], - &[(private_keys.npk(), shared_secret2)], - &[private_keys.nsk], - &[None], + vec![account_metadata], + Program::serialize_instruction(()).unwrap(), + vec![1], + vec![nonce2], + vec![(private_keys.npk(), shared_secret2)], + vec![private_keys.nsk], + vec![None], &noop_program.into(), ); diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index bad6435..20eca2b 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -335,7 +335,7 @@ impl WalletCore { pub async fn send_privacy_preserving_tx( &self, accounts: Vec, - instruction_data: &InstructionData, + instruction_data: InstructionData, program: &ProgramWithDependencies, ) -> Result<(SendTxResponse, Vec), ExecutionFailureKind> { self.send_privacy_preserving_tx_with_pre_check(accounts, instruction_data, program, |_| { @@ -347,7 +347,7 @@ impl WalletCore { pub async fn send_privacy_preserving_tx_with_pre_check( &self, accounts: Vec, - instruction_data: &InstructionData, + instruction_data: InstructionData, program: &ProgramWithDependencies, tx_pre_check: impl FnOnce(&[&Account]) -> Result<(), ExecutionFailureKind>, ) -> Result<(SendTxResponse, Vec), ExecutionFailureKind> { @@ -363,16 +363,16 @@ impl WalletCore { let private_account_keys = acc_manager.private_account_keys(); let (output, proof) = nssa::privacy_preserving_transaction::circuit::execute_and_prove( - &pre_states, + pre_states, instruction_data, - acc_manager.visibility_mask(), - &produce_random_nonces(private_account_keys.len()), - &private_account_keys + acc_manager.visibility_mask().to_vec(), + produce_random_nonces(private_account_keys.len()), + private_account_keys .iter() .map(|keys| (keys.npk.clone(), keys.ssk)) .collect::>(), - &acc_manager.private_account_auth(), - &acc_manager.private_account_membership_proofs(), + acc_manager.private_account_auth(), + acc_manager.private_account_membership_proofs(), &program.to_owned(), ) .unwrap(); diff --git a/wallet/src/program_facades/native_token_transfer/deshielded.rs b/wallet/src/program_facades/native_token_transfer/deshielded.rs index df604c6..7b77459 100644 --- a/wallet/src/program_facades/native_token_transfer/deshielded.rs +++ b/wallet/src/program_facades/native_token_transfer/deshielded.rs @@ -19,7 +19,7 @@ impl NativeTokenTransfer<'_> { PrivacyPreservingAccount::PrivateOwned(from), PrivacyPreservingAccount::Public(to), ], - &instruction_data, + instruction_data, &program.into(), tx_pre_check, ) diff --git a/wallet/src/program_facades/native_token_transfer/private.rs b/wallet/src/program_facades/native_token_transfer/private.rs index 0baeeac..5dcf066 100644 --- a/wallet/src/program_facades/native_token_transfer/private.rs +++ b/wallet/src/program_facades/native_token_transfer/private.rs @@ -17,7 +17,7 @@ impl NativeTokenTransfer<'_> { self.0 .send_privacy_preserving_tx_with_pre_check( vec![PrivacyPreservingAccount::PrivateOwned(from)], - &Program::serialize_instruction(instruction).unwrap(), + Program::serialize_instruction(instruction).unwrap(), &Program::authenticated_transfer_program().into(), |_| Ok(()), ) @@ -47,7 +47,7 @@ impl NativeTokenTransfer<'_> { ipk: to_ipk, }, ], - &instruction_data, + instruction_data, &program.into(), tx_pre_check, ) @@ -74,7 +74,7 @@ impl NativeTokenTransfer<'_> { PrivacyPreservingAccount::PrivateOwned(from), PrivacyPreservingAccount::PrivateOwned(to), ], - &instruction_data, + instruction_data, &program.into(), tx_pre_check, ) diff --git a/wallet/src/program_facades/native_token_transfer/shielded.rs b/wallet/src/program_facades/native_token_transfer/shielded.rs index 6abd2d2..85c8145 100644 --- a/wallet/src/program_facades/native_token_transfer/shielded.rs +++ b/wallet/src/program_facades/native_token_transfer/shielded.rs @@ -20,7 +20,7 @@ impl NativeTokenTransfer<'_> { PrivacyPreservingAccount::Public(from), PrivacyPreservingAccount::PrivateOwned(to), ], - &instruction_data, + instruction_data, &program.into(), tx_pre_check, ) @@ -52,7 +52,7 @@ impl NativeTokenTransfer<'_> { ipk: to_ipk, }, ], - &instruction_data, + instruction_data, &program.into(), tx_pre_check, ) diff --git a/wallet/src/program_facades/pinata.rs b/wallet/src/program_facades/pinata.rs index fdd5d70..6036a60 100644 --- a/wallet/src/program_facades/pinata.rs +++ b/wallet/src/program_facades/pinata.rs @@ -37,7 +37,7 @@ impl Pinata<'_> { PrivacyPreservingAccount::Public(pinata_account_id), PrivacyPreservingAccount::PrivateOwned(winner_account_id), ], - &nssa::program::Program::serialize_instruction(solution).unwrap(), + nssa::program::Program::serialize_instruction(solution).unwrap(), &nssa::program::Program::pinata().into(), ) .await diff --git a/wallet/src/program_facades/token.rs b/wallet/src/program_facades/token.rs index fc03a0a..0d3f79d 100644 --- a/wallet/src/program_facades/token.rs +++ b/wallet/src/program_facades/token.rs @@ -52,7 +52,7 @@ impl Token<'_> { PrivacyPreservingAccount::Public(definition_account_id), PrivacyPreservingAccount::PrivateOwned(supply_account_id), ], - &instruction_data, + instruction_data, &Program::token().into(), ) .await @@ -82,7 +82,7 @@ impl Token<'_> { PrivacyPreservingAccount::PrivateOwned(definition_account_id), PrivacyPreservingAccount::Public(supply_account_id), ], - &instruction_data, + instruction_data, &Program::token().into(), ) .await @@ -112,7 +112,7 @@ impl Token<'_> { PrivacyPreservingAccount::PrivateOwned(definition_account_id), PrivacyPreservingAccount::PrivateOwned(supply_account_id), ], - &instruction_data, + instruction_data, &Program::token().into(), ) .await @@ -180,7 +180,7 @@ impl Token<'_> { PrivacyPreservingAccount::PrivateOwned(sender_account_id), PrivacyPreservingAccount::PrivateOwned(recipient_account_id), ], - &instruction_data, + instruction_data, &Program::token().into(), ) .await @@ -212,7 +212,7 @@ impl Token<'_> { ipk: recipient_ipk, }, ], - &instruction_data, + instruction_data, &Program::token().into(), ) .await @@ -240,7 +240,7 @@ impl Token<'_> { PrivacyPreservingAccount::PrivateOwned(sender_account_id), PrivacyPreservingAccount::Public(recipient_account_id), ], - &instruction_data, + instruction_data, &Program::token().into(), ) .await @@ -269,7 +269,7 @@ impl Token<'_> { PrivacyPreservingAccount::Public(sender_account_id), PrivacyPreservingAccount::PrivateOwned(recipient_account_id), ], - &instruction_data, + instruction_data, &Program::token().into(), ) .await @@ -302,7 +302,7 @@ impl Token<'_> { ipk: recipient_ipk, }, ], - &instruction_data, + instruction_data, &Program::token().into(), ) .await @@ -365,7 +365,7 @@ impl Token<'_> { PrivacyPreservingAccount::PrivateOwned(definition_account_id), PrivacyPreservingAccount::PrivateOwned(holder_account_id), ], - &instruction_data, + instruction_data, &Program::token().into(), ) .await @@ -393,7 +393,7 @@ impl Token<'_> { PrivacyPreservingAccount::PrivateOwned(definition_account_id), PrivacyPreservingAccount::Public(holder_account_id), ], - &instruction_data, + instruction_data, &Program::token().into(), ) .await @@ -422,7 +422,7 @@ impl Token<'_> { PrivacyPreservingAccount::Public(definition_account_id), PrivacyPreservingAccount::PrivateOwned(holder_account_id), ], - &instruction_data, + instruction_data, &Program::token().into(), ) .await @@ -491,7 +491,7 @@ impl Token<'_> { PrivacyPreservingAccount::PrivateOwned(definition_account_id), PrivacyPreservingAccount::PrivateOwned(holder_account_id), ], - &instruction_data, + instruction_data, &Program::token().into(), ) .await @@ -523,7 +523,7 @@ impl Token<'_> { ipk: holder_ipk, }, ], - &instruction_data, + instruction_data, &Program::token().into(), ) .await @@ -551,7 +551,7 @@ impl Token<'_> { PrivacyPreservingAccount::PrivateOwned(definition_account_id), PrivacyPreservingAccount::Public(holder_account_id), ], - &instruction_data, + instruction_data, &Program::token().into(), ) .await @@ -580,7 +580,7 @@ impl Token<'_> { PrivacyPreservingAccount::Public(definition_account_id), PrivacyPreservingAccount::PrivateOwned(holder_account_id), ], - &instruction_data, + instruction_data, &Program::token().into(), ) .await @@ -613,7 +613,7 @@ impl Token<'_> { ipk: holder_ipk, }, ], - &instruction_data, + instruction_data, &Program::token().into(), ) .await