From c5a4e83e3e7bfbaa23cd2a2634b5208c064aa340 Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Thu, 14 Aug 2025 14:09:04 -0300 Subject: [PATCH] add pre states to program output --- nssa/core/src/program.rs | 16 ++++++++++++++ .../guest/src/bin/authenticated_transfer.rs | 5 ++--- nssa/src/program.rs | 21 +++++++++++-------- .../guest/src/bin/burner.rs | 7 +++---- .../guest/src/bin/data_changer.rs | 8 +++---- .../guest/src/bin/extra_output.rs | 10 +++++---- .../guest/src/bin/minter.rs | 7 +++---- .../guest/src/bin/missing_output.rs | 7 +++---- .../guest/src/bin/nonce_changer.rs | 7 +++---- .../guest/src/bin/program_owner_changer.rs | 7 +++---- .../guest/src/bin/simple_balance_transfer.rs | 8 ++++--- 11 files changed, 59 insertions(+), 44 deletions(-) diff --git a/nssa/core/src/program.rs b/nssa/core/src/program.rs index 9b99a61a..e7b13db3 100644 --- a/nssa/core/src/program.rs +++ b/nssa/core/src/program.rs @@ -1,17 +1,33 @@ use crate::account::{Account, AccountWithMetadata}; use risc0_zkvm::serde::Deserializer; use risc0_zkvm::{DeserializeOwned, guest::env}; +use serde::{Deserialize, Serialize}; pub type ProgramId = [u32; 8]; pub type InstructionData = Vec; pub const DEFAULT_PROGRAM_ID: ProgramId = [0; 8]; +#[derive(Serialize, Deserialize)] +pub struct ProgramOutput { + pub pre_states: Vec, + pub post_states: Vec, +} + pub fn read_nssa_inputs() -> (Vec, T) { let pre_states: Vec = env::read(); let words: InstructionData = env::read(); let instruction_data = T::deserialize(&mut Deserializer::new(words.as_ref())).unwrap(); (pre_states, instruction_data) } + +pub fn write_nssa_outputs(pre_states: Vec, post_states: Vec) { + let output = ProgramOutput { + pre_states, + post_states, + }; + env::commit(&output); +} + /// Validates well-behaved program execution /// /// # Parameters diff --git a/nssa/program_methods/guest/src/bin/authenticated_transfer.rs b/nssa/program_methods/guest/src/bin/authenticated_transfer.rs index a89b090e..74edad6b 100644 --- a/nssa/program_methods/guest/src/bin/authenticated_transfer.rs +++ b/nssa/program_methods/guest/src/bin/authenticated_transfer.rs @@ -1,5 +1,4 @@ -use nssa_core::program::read_nssa_inputs; -use risc0_zkvm::guest::env; +use nssa_core::program::{read_nssa_inputs, write_nssa_outputs}; type Instruction = u128; @@ -32,5 +31,5 @@ fn main() { sender_post.balance -= balance_to_move; receiver_post.balance += balance_to_move; - env::commit(&vec![sender_post, receiver_post]); + write_nssa_outputs(vec![sender, receiver], vec![sender_post, receiver_post]); } diff --git a/nssa/src/program.rs b/nssa/src/program.rs index 2195501f..7ab6d747 100644 --- a/nssa/src/program.rs +++ b/nssa/src/program.rs @@ -1,6 +1,6 @@ use nssa_core::{ account::{Account, AccountWithMetadata}, - program::{DEFAULT_PROGRAM_ID, InstructionData, ProgramId}, + program::{DEFAULT_PROGRAM_ID, InstructionData, ProgramId, ProgramOutput}, }; use program_methods::{AUTHENTICATED_TRANSFER_ELF, AUTHENTICATED_TRANSFER_ID}; use risc0_zkvm::{ @@ -44,7 +44,10 @@ impl Program { .map_err(|e| NssaError::ProgramExecutionFailed(e.to_string()))?; // Get outputs - let mut post_states: Vec = session_info + let ProgramOutput { + post_states: mut post_states, + .. + } = session_info .journal .decode() .map_err(|e| NssaError::ProgramExecutionFailed(e.to_string()))?; @@ -107,7 +110,10 @@ impl Program { #[cfg(test)] mod tests { - use nssa_core::account::{Account, AccountWithMetadata}; + use nssa_core::{ + account::{Account, AccountWithMetadata}, + program::ProgramOutput, + }; use crate::program::Program; @@ -256,15 +262,12 @@ mod tests { balance: balance_to_move, ..Account::default() }; + let receipt = program .execute_and_prove(&[sender, recipient], &instruction_data) .unwrap(); - let [sender_post, recipient_post] = receipt - .journal - .decode::>() - .unwrap() - .try_into() - .unwrap(); + let ProgramOutput { post_states, .. } = receipt.journal.decode().unwrap(); + let [sender_post, recipient_post] = post_states.try_into().unwrap(); let output = assert_eq!(sender_post, expected_sender_post); diff --git a/nssa/test_program_methods/guest/src/bin/burner.rs b/nssa/test_program_methods/guest/src/bin/burner.rs index 018c2032..40ba46ec 100644 --- a/nssa/test_program_methods/guest/src/bin/burner.rs +++ b/nssa/test_program_methods/guest/src/bin/burner.rs @@ -1,5 +1,4 @@ -use nssa_core::program::read_nssa_inputs; -use risc0_zkvm::guest::env; +use nssa_core::program::{read_nssa_inputs, write_nssa_outputs}; type Instruction = u128; @@ -11,9 +10,9 @@ fn main() { Err(_) => return, }; - let account_pre = pre.account; + let account_pre = &pre.account; let mut account_post = account_pre.clone(); account_post.balance -= balance_to_burn; - env::commit(&vec![account_post]); + write_nssa_outputs(vec![pre], vec![account_post]); } 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 fa1efd32..389bba0d 100644 --- a/nssa/test_program_methods/guest/src/bin/data_changer.rs +++ b/nssa/test_program_methods/guest/src/bin/data_changer.rs @@ -1,5 +1,4 @@ -use nssa_core::program::read_nssa_inputs; -use risc0_zkvm::guest::env; +use nssa_core::program::{read_nssa_inputs, write_nssa_outputs}; type Instruction = (); @@ -11,10 +10,9 @@ fn main() { Err(_) => return, }; - let account_pre = pre.account; + let account_pre = &pre.account; let mut account_post = account_pre.clone(); account_post.data.push(0); - env::commit(&vec![account_post]); + write_nssa_outputs(vec![pre], vec![account_post]); } - diff --git a/nssa/test_program_methods/guest/src/bin/extra_output.rs b/nssa/test_program_methods/guest/src/bin/extra_output.rs index c02c5e25..35069c60 100644 --- a/nssa/test_program_methods/guest/src/bin/extra_output.rs +++ b/nssa/test_program_methods/guest/src/bin/extra_output.rs @@ -1,5 +1,7 @@ -use nssa_core::{account::Account, program::read_nssa_inputs}; -use risc0_zkvm::guest::env; +use nssa_core::{ + account::Account, + program::{read_nssa_inputs, write_nssa_outputs}, +}; type Instruction = (); @@ -11,7 +13,7 @@ fn main() { Err(_) => return, }; - let account_pre = pre.account; + let account_pre = pre.account.clone(); - env::commit(&vec![account_pre, Account::default()]); + write_nssa_outputs(vec![pre], vec![account_pre, Account::default()]); } diff --git a/nssa/test_program_methods/guest/src/bin/minter.rs b/nssa/test_program_methods/guest/src/bin/minter.rs index b82d9e96..56ce113b 100644 --- a/nssa/test_program_methods/guest/src/bin/minter.rs +++ b/nssa/test_program_methods/guest/src/bin/minter.rs @@ -1,5 +1,4 @@ -use nssa_core::program::read_nssa_inputs; -use risc0_zkvm::guest::env; +use nssa_core::program::{read_nssa_inputs, write_nssa_outputs}; type Instruction = (); @@ -11,9 +10,9 @@ fn main() { Err(_) => return, }; - let account_pre = pre.account; + let account_pre = &pre.account; let mut account_post = account_pre.clone(); account_post.balance += 1; - env::commit(&vec![account_post]); + write_nssa_outputs(vec![pre], vec![account_post]); } diff --git a/nssa/test_program_methods/guest/src/bin/missing_output.rs b/nssa/test_program_methods/guest/src/bin/missing_output.rs index 61aa8c5c..d2bf37e0 100644 --- a/nssa/test_program_methods/guest/src/bin/missing_output.rs +++ b/nssa/test_program_methods/guest/src/bin/missing_output.rs @@ -1,5 +1,4 @@ -use nssa_core::program::read_nssa_inputs; -use risc0_zkvm::guest::env; +use nssa_core::program::{read_nssa_inputs, write_nssa_outputs}; type Instruction = (); @@ -11,7 +10,7 @@ fn main() { Err(_) => return, }; - let account_pre1 = pre1.account; + let account_pre1 = pre1.account.clone(); - env::commit(&vec![account_pre1]); + write_nssa_outputs(vec![pre1], vec![account_pre1]); } diff --git a/nssa/test_program_methods/guest/src/bin/nonce_changer.rs b/nssa/test_program_methods/guest/src/bin/nonce_changer.rs index eb1365ed..0aa7bbb9 100644 --- a/nssa/test_program_methods/guest/src/bin/nonce_changer.rs +++ b/nssa/test_program_methods/guest/src/bin/nonce_changer.rs @@ -1,5 +1,4 @@ -use nssa_core::program::read_nssa_inputs; -use risc0_zkvm::guest::env; +use nssa_core::program::{read_nssa_inputs, write_nssa_outputs}; type Instruction = (); @@ -11,9 +10,9 @@ fn main() { Err(_) => return, }; - let account_pre = pre.account; + let account_pre = &pre.account; let mut account_post = account_pre.clone(); account_post.nonce += 1; - env::commit(&vec![account_post]); + write_nssa_outputs(vec![pre], vec![account_post]); } diff --git a/nssa/test_program_methods/guest/src/bin/program_owner_changer.rs b/nssa/test_program_methods/guest/src/bin/program_owner_changer.rs index 4d11438e..990c0fba 100644 --- a/nssa/test_program_methods/guest/src/bin/program_owner_changer.rs +++ b/nssa/test_program_methods/guest/src/bin/program_owner_changer.rs @@ -1,5 +1,4 @@ -use nssa_core::program::read_nssa_inputs; -use risc0_zkvm::guest::env; +use nssa_core::program::{read_nssa_inputs, write_nssa_outputs}; type Instruction = (); @@ -11,9 +10,9 @@ fn main() { Err(_) => return, }; - let account_pre = pre.account; + let account_pre = &pre.account; let mut account_post = account_pre.clone(); account_post.program_owner = [0, 1, 2, 3, 4, 5, 6, 7]; - env::commit(&vec![account_post]); + write_nssa_outputs(vec![pre], vec![account_post]); } diff --git a/nssa/test_program_methods/guest/src/bin/simple_balance_transfer.rs b/nssa/test_program_methods/guest/src/bin/simple_balance_transfer.rs index 047e252c..7f131f6d 100644 --- a/nssa/test_program_methods/guest/src/bin/simple_balance_transfer.rs +++ b/nssa/test_program_methods/guest/src/bin/simple_balance_transfer.rs @@ -1,5 +1,4 @@ -use nssa_core::program::read_nssa_inputs; -use risc0_zkvm::guest::env; +use nssa_core::program::{read_nssa_inputs, write_nssa_outputs}; type Instruction = u128; @@ -16,5 +15,8 @@ fn main() { sender_post.balance -= balance; receiver_post.balance += balance; - env::commit(&vec![sender_post, receiver_post]); + write_nssa_outputs( + vec![sender_pre, receiver_pre], + vec![sender_post, receiver_post], + ); }