diff --git a/integration_tests/src/data_changer.bin b/integration_tests/src/data_changer.bin index 6a36d52c..3d062c30 100644 Binary files a/integration_tests/src/data_changer.bin and b/integration_tests/src/data_changer.bin differ diff --git a/integration_tests/src/test_suite_map.rs b/integration_tests/src/test_suite_map.rs index 17caf260..7ee3ef48 100644 --- a/integration_tests/src/test_suite_map.rs +++ b/integration_tests/src/test_suite_map.rs @@ -1466,7 +1466,7 @@ pub fn prepare_function_map() -> HashMap { data_changer.id(), vec![account_id], vec![], - (), + vec![0], ) .unwrap(); let witness_set = nssa::public_transaction::WitnessSet::for_message(&message, &[]); diff --git a/nssa/core/Cargo.toml b/nssa/core/Cargo.toml index f179899a..80fe7df9 100644 --- a/nssa/core/Cargo.toml +++ b/nssa/core/Cargo.toml @@ -15,8 +15,8 @@ anyhow = { version = "1.0.98", optional = true } borsh = "1.5.7" [dev-dependencies] -serde_json.workspace = true +serde_json = "1.0.81" [features] default = [] -host = ["bytemuck", "k256", "base58", "anyhow"] +host = ["dep:bytemuck", "dep:k256", "dep:base58", "dep:anyhow"] diff --git a/nssa/core/src/account/data.rs b/nssa/core/src/account/data.rs index 281599c2..974cb06c 100644 --- a/nssa/core/src/account/data.rs +++ b/nssa/core/src/account/data.rs @@ -3,9 +3,6 @@ use std::ops::Deref; use borsh::{BorshDeserialize, BorshSerialize}; use serde::{Deserialize, Serialize}; -#[cfg(feature = "host")] -use crate::error::NssaCoreError; - pub const DATA_MAX_LENGTH_IN_BYTES: usize = 100 * 1024; // 100 KiB #[derive(Default, Clone, PartialEq, Eq, Serialize, BorshSerialize)] @@ -18,7 +15,9 @@ impl Data { } #[cfg(feature = "host")] - pub fn from_cursor(cursor: &mut std::io::Cursor<&[u8]>) -> Result { + pub fn from_cursor( + cursor: &mut std::io::Cursor<&[u8]>, + ) -> Result { use std::io::Read as _; let mut u32_bytes = [0u8; 4]; @@ -36,7 +35,7 @@ impl Data { } } -#[derive(Debug, thiserror::Error)] +#[derive(Debug, thiserror::Error, Clone, Copy, PartialEq, Eq)] #[error("data length exceeds maximum allowed length of {DATA_MAX_LENGTH_IN_BYTES} bytes")] pub struct DataTooBigError; diff --git a/nssa/src/state.rs b/nssa/src/state.rs index 5841f781..72efbd24 100644 --- a/nssa/src/state.rs +++ b/nssa/src/state.rs @@ -234,7 +234,7 @@ impl V02State { program_owner: Program::pinata().id(), balance: 1500, // Difficulty: 3 - data: vec![3; 33].try_into().unwrap(), + data: vec![3; 33].try_into().expect("should fit"), nonce: 0, }, ); @@ -730,7 +730,8 @@ pub mod tests { program_id ); let message = - public_transaction::Message::try_new(program_id, vec![account_id], vec![], ()).unwrap(); + public_transaction::Message::try_new(program_id, vec![account_id], vec![], vec![0]) + .unwrap(); let witness_set = public_transaction::WitnessSet::for_message(&message, &[]); let tx = PublicTransaction::new(message, witness_set); @@ -1248,7 +1249,7 @@ pub mod tests { let result = execute_and_prove( &[public_account], - &Program::serialize_instruction(()).unwrap(), + &Program::serialize_instruction(vec![0]).unwrap(), &[0], &[], &[], @@ -1259,6 +1260,34 @@ pub mod tests { assert!(matches!(result, Err(NssaError::CircuitProvingError(_)))); } + #[test] + fn test_data_changer_program_should_fail_for_too_large_data_in_privacy_preserving_circuit() { + let program = Program::data_changer(); + let public_account = AccountWithMetadata::new( + Account { + program_owner: program.id(), + balance: 0, + ..Account::default() + }, + true, + AccountId::new([0; 32]), + ); + + 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], + &[], + &[], + &[], + &program, + ); + + assert!(matches!(result, Err(NssaError::ProgramProveFailed(_)))); + } + #[test] fn test_extra_output_program_should_fail_in_privacy_preserving_circuit() { let program = Program::extra_output_program(); diff --git a/nssa/test_program_methods/guest/src/bin/data_changer.rs b/nssa/test_program_methods/guest/src/bin/data_changer.rs index 16c23599..b5908864 100644 --- a/nssa/test_program_methods/guest/src/bin/data_changer.rs +++ b/nssa/test_program_methods/guest/src/bin/data_changer.rs @@ -1,9 +1,10 @@ use nssa_core::program::{AccountPostState, ProgramInput, read_nssa_inputs, write_nssa_outputs}; -type Instruction = (); +type Instruction = Vec; +/// A program that modifies the account data by setting bytes sent in instruction. fn main() { - let ProgramInput { pre_states, .. } = read_nssa_inputs::(); + let ProgramInput { pre_states, instruction: data } = read_nssa_inputs::(); let [pre] = match pre_states.try_into() { Ok(array) => array, @@ -12,9 +13,7 @@ fn main() { let account_pre = &pre.account; let mut account_post = account_pre.clone(); - let mut data_vec = account_post.data.into_inner(); - data_vec.push(0); - account_post.data = data_vec.try_into().expect("data_vec should fit into Data"); + account_post.data = data.try_into().expect("provided data should fit into data limit"); write_nssa_outputs(vec![pre], vec![AccountPostState::new_claimed(account_post)]); }