diff --git a/nssa/program_methods/guest/src/bin/privacy_preserving_circuit.rs b/nssa/program_methods/guest/src/bin/privacy_preserving_circuit.rs index 83f593a..947f6ea 100644 --- a/nssa/program_methods/guest/src/bin/privacy_preserving_circuit.rs +++ b/nssa/program_methods/guest/src/bin/privacy_preserving_circuit.rs @@ -32,7 +32,9 @@ fn main() { // Check that the program is well behaved. // See the # Programs section for the definition of the `validate_execution` method. - validate_execution(&pre_states, &post_states, program_id); + if !validate_execution(&pre_states, &post_states, program_id) { + panic!(); + } let n_accounts = pre_states.len(); if visibility_mask.len() != n_accounts { diff --git a/nssa/src/error.rs b/nssa/src/error.rs index 1d6d6ad..0e85789 100644 --- a/nssa/src/error.rs +++ b/nssa/src/error.rs @@ -45,4 +45,7 @@ pub enum NssaError { #[error("Invalid privacy preserving execution circuit proof")] InvalidPrivacyPreservingProof, + + #[error("Circuit proving error")] + CircuitProvingError(String), } diff --git a/nssa/src/privacy_preserving_transaction/circuit.rs b/nssa/src/privacy_preserving_transaction/circuit.rs index ed32f98..24cdc4a 100644 --- a/nssa/src/privacy_preserving_transaction/circuit.rs +++ b/nssa/src/privacy_preserving_transaction/circuit.rs @@ -55,7 +55,9 @@ pub fn execute_and_prove( env_builder.write(&circuit_input).unwrap(); let env = env_builder.build().unwrap(); let prover = default_prover(); - let prove_info = prover.prove(env, PRIVACY_PRESERVING_CIRCUIT_ELF).unwrap(); + let prove_info = prover + .prove(env, PRIVACY_PRESERVING_CIRCUIT_ELF) + .map_err(|e| NssaError::CircuitProvingError(e.to_string()))?; let proof = Proof(borsh::to_vec(&prove_info.receipt.inner)?); diff --git a/nssa/src/state.rs b/nssa/src/state.rs index 93ee06c..d0733ec 100644 --- a/nssa/src/state.rs +++ b/nssa/src/state.rs @@ -214,6 +214,7 @@ pub mod tests { use crate::{ Address, PublicKey, PublicTransaction, V01State, error::NssaError, + execute_and_prove, privacy_preserving_transaction::{ PrivacyPreservingTransaction, circuit, message::Message, witness_set::WitnessSet, }, @@ -1063,4 +1064,35 @@ pub mod tests { recipient_initial_balance + balance_to_move ); } + + #[test] + fn test_burner_program_should_fail_in_privacy_preserving_circuit() { + let keys = test_private_account_keys_1(); + let private_account = AccountWithMetadata { + account: Account { + balance: 100, + ..Account::default() + }, + is_authorized: true, + }; + let state = V01State::new_with_genesis_accounts(&[]) + .with_private_account(&keys, &private_account.account); + + let membership_proof = state + .get_proof_for_commitment(&Commitment::new(&keys.npk(), &private_account.account)) + .unwrap(); + + let program = Program::burner(); + let result = execute_and_prove( + &[private_account], + &Program::serialize_instruction(10u128).unwrap(), + &[1], + &[0xdeadbeef], + &[(keys.npk(), SharedSecretKey::new(&[0xca; 32], &keys.ivk()))], + &[(keys.nsk, membership_proof)], + &program, + ); + + assert!(matches!(result, Err(NssaError::CircuitProvingError(_)))); + } }