From f86719f54c2671c084b5d3d9dd0c8776309fb7f7 Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Sun, 10 Aug 2025 11:17:15 -0300 Subject: [PATCH] add test for invalid data modification --- nssa/src/program.rs | 10 +++++++++ nssa/src/state.rs | 1 + nssa/src/tests/valid_execution_tests.rs | 22 +++++++++++++++++++ .../guest/src/bin/data_changer.rs | 19 ++++++++++++++++ 4 files changed, 52 insertions(+) create mode 100644 nssa/test_program_methods/guest/src/bin/data_changer.rs diff --git a/nssa/src/program.rs b/nssa/src/program.rs index ba239e9..2e1583a 100644 --- a/nssa/src/program.rs +++ b/nssa/src/program.rs @@ -125,4 +125,14 @@ impl Program { elf: SIMPLE_BALANCE_TRANSFER_ELF, } } + + /// A program that modifies the data of an account + pub fn data_changer() -> Self { + use test_program_methods::{DATA_CHANGER_ELF, DATA_CHANGER_ID}; + + Program { + id: DATA_CHANGER_ID, + elf: DATA_CHANGER_ELF, + } + } } diff --git a/nssa/src/state.rs b/nssa/src/state.rs index 7b48c08..370a88a 100644 --- a/nssa/src/state.rs +++ b/nssa/src/state.rs @@ -151,6 +151,7 @@ impl V01State { self.insert_program(Program::missing_output_program()); self.insert_program(Program::program_owner_changer()); self.insert_program(Program::simple_balance_transfer()); + self.insert_program(Program::data_changer()); self } diff --git a/nssa/src/tests/valid_execution_tests.rs b/nssa/src/tests/valid_execution_tests.rs index 7ae5144..a0c6e51 100644 --- a/nssa/src/tests/valid_execution_tests.rs +++ b/nssa/src/tests/valid_execution_tests.rs @@ -164,3 +164,25 @@ fn test_program_should_fail_if_transfers_balance_from_non_owned_account() { assert!(matches!(result, Err(NssaError::InvalidProgramBehavior))); } + +#[test] +fn test_program_should_fail_if_modifies_data_of_non_owned_account() { + let initial_data = []; + let mut state = V01State::new_with_genesis_accounts(&initial_data).with_test_programs(); + let address = Address::new([1; 32]); + let program_id = Program::data_changer().id(); + + // Consider the extreme case where the target account is the default account + assert_eq!(state.get_account_by_address(&address), Account::default()); + assert_ne!( + state.get_account_by_address(&address).program_owner, + program_id + ); + let message = public_transaction::Message::new(program_id, vec![address], vec![], 0); + let witness_set = public_transaction::WitnessSet::for_message(&message, &[]); + let tx = PublicTransaction::new(message, witness_set); + + let result = state.transition_from_public_transaction(&tx); + + assert!(matches!(result, Err(NssaError::InvalidProgramBehavior))); +} diff --git a/nssa/test_program_methods/guest/src/bin/data_changer.rs b/nssa/test_program_methods/guest/src/bin/data_changer.rs new file mode 100644 index 0000000..9fd3850 --- /dev/null +++ b/nssa/test_program_methods/guest/src/bin/data_changer.rs @@ -0,0 +1,19 @@ +use nssa_core::account::AccountWithMetadata; +use risc0_zkvm::guest::env; + +fn main() { + let input_accounts: Vec = env::read(); + let _instruction_data: u128 = env::read(); + + let [pre] = match input_accounts.try_into() { + Ok(array) => array, + Err(_) => return, + }; + + let account_pre = pre.account; + let mut account_post = account_pre.clone(); + account_post.data.push(0); + + env::commit(&vec![account_post]); +} +