feat: introduce parameter to data_changer and add test for account data

This commit is contained in:
Daniil Polyakov 2025-12-05 17:16:41 +03:00
parent 4574acfc49
commit 31e7016948
6 changed files with 43 additions and 16 deletions

View File

@ -1466,7 +1466,7 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
data_changer.id(), data_changer.id(),
vec![account_id], vec![account_id],
vec![], vec![],
(), vec![0],
) )
.unwrap(); .unwrap();
let witness_set = nssa::public_transaction::WitnessSet::for_message(&message, &[]); let witness_set = nssa::public_transaction::WitnessSet::for_message(&message, &[]);

View File

@ -15,8 +15,8 @@ anyhow = { version = "1.0.98", optional = true }
borsh = "1.5.7" borsh = "1.5.7"
[dev-dependencies] [dev-dependencies]
serde_json.workspace = true serde_json = "1.0.81"
[features] [features]
default = [] default = []
host = ["bytemuck", "k256", "base58", "anyhow"] host = ["dep:bytemuck", "dep:k256", "dep:base58", "dep:anyhow"]

View File

@ -3,9 +3,6 @@ use std::ops::Deref;
use borsh::{BorshDeserialize, BorshSerialize}; use borsh::{BorshDeserialize, BorshSerialize};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[cfg(feature = "host")]
use crate::error::NssaCoreError;
pub const DATA_MAX_LENGTH_IN_BYTES: usize = 100 * 1024; // 100 KiB pub const DATA_MAX_LENGTH_IN_BYTES: usize = 100 * 1024; // 100 KiB
#[derive(Default, Clone, PartialEq, Eq, Serialize, BorshSerialize)] #[derive(Default, Clone, PartialEq, Eq, Serialize, BorshSerialize)]
@ -18,7 +15,9 @@ impl Data {
} }
#[cfg(feature = "host")] #[cfg(feature = "host")]
pub fn from_cursor(cursor: &mut std::io::Cursor<&[u8]>) -> Result<Self, NssaCoreError> { pub fn from_cursor(
cursor: &mut std::io::Cursor<&[u8]>,
) -> Result<Self, crate::error::NssaCoreError> {
use std::io::Read as _; use std::io::Read as _;
let mut u32_bytes = [0u8; 4]; 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")] #[error("data length exceeds maximum allowed length of {DATA_MAX_LENGTH_IN_BYTES} bytes")]
pub struct DataTooBigError; pub struct DataTooBigError;

View File

@ -234,7 +234,7 @@ impl V02State {
program_owner: Program::pinata().id(), program_owner: Program::pinata().id(),
balance: 1500, balance: 1500,
// Difficulty: 3 // Difficulty: 3
data: vec![3; 33].try_into().unwrap(), data: vec![3; 33].try_into().expect("should fit"),
nonce: 0, nonce: 0,
}, },
); );
@ -730,7 +730,8 @@ pub mod tests {
program_id program_id
); );
let message = 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 witness_set = public_transaction::WitnessSet::for_message(&message, &[]);
let tx = PublicTransaction::new(message, witness_set); let tx = PublicTransaction::new(message, witness_set);
@ -1248,7 +1249,7 @@ pub mod tests {
let result = execute_and_prove( let result = execute_and_prove(
&[public_account], &[public_account],
&Program::serialize_instruction(()).unwrap(), &Program::serialize_instruction(vec![0]).unwrap(),
&[0], &[0],
&[], &[],
&[], &[],
@ -1259,6 +1260,34 @@ pub mod tests {
assert!(matches!(result, Err(NssaError::CircuitProvingError(_)))); 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<u8> = 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] #[test]
fn test_extra_output_program_should_fail_in_privacy_preserving_circuit() { fn test_extra_output_program_should_fail_in_privacy_preserving_circuit() {
let program = Program::extra_output_program(); let program = Program::extra_output_program();

View File

@ -1,9 +1,10 @@
use nssa_core::program::{AccountPostState, ProgramInput, read_nssa_inputs, write_nssa_outputs}; use nssa_core::program::{AccountPostState, ProgramInput, read_nssa_inputs, write_nssa_outputs};
type Instruction = (); type Instruction = Vec<u8>;
/// A program that modifies the account data by setting bytes sent in instruction.
fn main() { fn main() {
let ProgramInput { pre_states, .. } = read_nssa_inputs::<Instruction>(); let ProgramInput { pre_states, instruction: data } = read_nssa_inputs::<Instruction>();
let [pre] = match pre_states.try_into() { let [pre] = match pre_states.try_into() {
Ok(array) => array, Ok(array) => array,
@ -12,9 +13,7 @@ fn main() {
let account_pre = &pre.account; let account_pre = &pre.account;
let mut account_post = account_pre.clone(); let mut account_post = account_pre.clone();
let mut data_vec = account_post.data.into_inner(); account_post.data = data.try_into().expect("provided data should fit into data limit");
data_vec.push(0);
account_post.data = data_vec.try_into().expect("data_vec should fit into Data");
write_nssa_outputs(vec![pre], vec![AccountPostState::new_claimed(account_post)]); write_nssa_outputs(vec![pre], vec![AccountPostState::new_claimed(account_post)]);
} }