From 51d8ac47cf2835b9ba759e52ad1facbf55dbf9d9 Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Sat, 9 Aug 2025 20:16:18 -0300 Subject: [PATCH] refactor program --- common/src/test_utils.rs | 29 ++------------- nssa/core/src/program.rs | 5 --- nssa/src/lib.rs | 69 ++++++++++++++++++++---------------- nssa/src/state.rs | 6 ++-- sequencer_rpc/src/process.rs | 4 +-- wallet/src/lib.rs | 2 +- 6 files changed, 47 insertions(+), 68 deletions(-) diff --git a/common/src/test_utils.rs b/common/src/test_utils.rs index bf734af..6fe3324 100644 --- a/common/src/test_utils.rs +++ b/common/src/test_utils.rs @@ -31,7 +31,7 @@ pub fn produce_dummy_block( } pub fn produce_dummy_empty_transaction() -> nssa::PublicTransaction { - let program_id = nssa::AUTHENTICATED_TRANSFER_PROGRAM.id; + let program_id = nssa::AUTHENTICATED_TRANSFER_PROGRAM.id(); let addresses = vec![]; let nonces = vec![]; let instruction_data = 0; @@ -42,31 +42,6 @@ pub fn produce_dummy_empty_transaction() -> nssa::PublicTransaction { nssa::PublicTransaction::new(message, witness_set) } -// pub fn create_dummy_private_transaction_random_signer( -// nullifier_created_hashes: Vec<[u8; 32]>, -// utxo_commitments_spent_hashes: Vec<[u8; 32]>, -// utxo_commitments_created_hashes: Vec<[u8; 32]>, -// ) -> Transaction { -// let mut rng = rand::thread_rng(); -// -// let body = TransactionBody { -// tx_kind: TxKind::Private, -// execution_input: vec![], -// execution_output: vec![], -// utxo_commitments_spent_hashes, -// utxo_commitments_created_hashes, -// nullifier_created_hashes, -// execution_proof_private: "dummy_proof".to_string(), -// encoded_data: vec![], -// ephemeral_pub_key: vec![10, 11, 12], -// commitment: vec![], -// tweak: Tweak::new(&mut rng), -// secret_r: [0; 32], -// sc_addr: "sc_addr".to_string(), -// }; -// Transaction::new(body, SignaturePrivateKey::random(&mut rng)) -// } - pub fn create_dummy_transaction_native_token_transfer( from: [u8; 32], nonce: u128, @@ -76,7 +51,7 @@ pub fn create_dummy_transaction_native_token_transfer( ) -> nssa::PublicTransaction { let addresses = vec![nssa::Address::new(from), nssa::Address::new(to)]; let nonces = vec![nonce]; - let program_id = nssa::AUTHENTICATED_TRANSFER_PROGRAM.id; + let program_id = nssa::AUTHENTICATED_TRANSFER_PROGRAM.id(); let message = nssa::public_transaction::Message::new(program_id, addresses, nonces, balance_to_move); let witness_set = nssa::public_transaction::WitnessSet::for_message(&message, &[&signing_key]); diff --git a/nssa/core/src/program.rs b/nssa/core/src/program.rs index 6ecd4cf..ce58a3b 100644 --- a/nssa/core/src/program.rs +++ b/nssa/core/src/program.rs @@ -3,11 +3,6 @@ use crate::account::{Account, AccountWithMetadata}; pub type ProgramId = [u32; 8]; pub const DEFAULT_PROGRAM_ID: ProgramId = [0; 8]; -pub struct Program { - pub id: ProgramId, - pub elf: &'static [u8], -} - /// Validates well-behaved program execution /// /// # Parameters diff --git a/nssa/src/lib.rs b/nssa/src/lib.rs index 11f2231..ee4d2ff 100644 --- a/nssa/src/lib.rs +++ b/nssa/src/lib.rs @@ -1,6 +1,6 @@ use nssa_core::{ account::{Account, AccountWithMetadata}, - program::DEFAULT_PROGRAM_ID, + program::{DEFAULT_PROGRAM_ID, ProgramId}, }; use program_methods::{AUTHENTICATED_TRANSFER_ELF, AUTHENTICATED_TRANSFER_ID}; use risc0_zkvm::{ExecutorEnv, ExecutorEnvBuilder, default_executor}; @@ -12,7 +12,6 @@ mod signature; mod state; pub use address::Address; -pub use nssa_core::program::Program; pub use public_transaction::PublicTransaction; pub use signature::PrivateKey; pub use signature::PublicKey; @@ -26,6 +25,11 @@ pub const AUTHENTICATED_TRANSFER_PROGRAM: Program = Program { elf: AUTHENTICATED_TRANSFER_ELF, }; +pub struct Program { + id: ProgramId, + elf: &'static [u8], +} + /// Writes inputs to `env_builder` in the order expected by the programs fn write_inputs( pre_states: &[AccountWithMetadata], @@ -42,34 +46,39 @@ fn write_inputs( Ok(()) } -fn execute_public( - pre_states: &[AccountWithMetadata], - instruction_data: u128, - program: &Program, -) -> Result, NssaError> { - // Write inputs to the program - let mut env_builder = ExecutorEnv::builder(); - write_inputs(pre_states, instruction_data, &mut env_builder)?; - let env = env_builder.build().unwrap(); - - // Execute the program (without proving) - let executor = default_executor(); - let session_info = executor - .execute(env, program.elf) - .map_err(|e| NssaError::ProgramExecutionFailed(e.to_string()))?; - - // Get outputs - let mut post_states: Vec = session_info - .journal - .decode() - .map_err(|e| NssaError::ProgramExecutionFailed(e.to_string()))?; - - // Claim any output account with default program owner field - for account in post_states.iter_mut() { - if account.program_owner == DEFAULT_PROGRAM_ID { - account.program_owner = program.id; - } +impl Program { + pub fn id(&self) -> ProgramId { + self.id } + pub(crate) fn execute( + &self, + pre_states: &[AccountWithMetadata], + instruction_data: u128, + ) -> Result, NssaError> { + // Write inputs to the program + let mut env_builder = ExecutorEnv::builder(); + write_inputs(pre_states, instruction_data, &mut env_builder)?; + let env = env_builder.build().unwrap(); - Ok(post_states) + // Execute the program (without proving) + let executor = default_executor(); + let session_info = executor + .execute(env, self.elf) + .map_err(|e| NssaError::ProgramExecutionFailed(e.to_string()))?; + + // Get outputs + let mut post_states: Vec = session_info + .journal + .decode() + .map_err(|e| NssaError::ProgramExecutionFailed(e.to_string()))?; + + // Claim any output account with default program owner field + for account in post_states.iter_mut() { + if account.program_owner == DEFAULT_PROGRAM_ID { + account.program_owner = self.id; + } + } + + Ok(post_states) + } } diff --git a/nssa/src/state.rs b/nssa/src/state.rs index 6459a30..31d3695 100644 --- a/nssa/src/state.rs +++ b/nssa/src/state.rs @@ -1,10 +1,10 @@ use crate::{ - AUTHENTICATED_TRANSFER_PROGRAM, address::Address, error::NssaError, execute_public, + AUTHENTICATED_TRANSFER_PROGRAM, Program, address::Address, error::NssaError, public_transaction::PublicTransaction, }; use nssa_core::{ account::{Account, AccountWithMetadata}, - program::{Program, ProgramId, validate_constraints}, + program::{ProgramId, validate_constraints}, }; use std::collections::{HashMap, HashSet}; @@ -129,7 +129,7 @@ impl V01State { }; // // Execute program - let post_states = execute_public(&pre_states, message.instruction_data, program)?; + let post_states = program.execute(&pre_states, message.instruction_data)?; // Verify execution corresponds to a well-behaved program. // See the # Programs section for the definition of the `validate_constraints` method. diff --git a/sequencer_rpc/src/process.rs b/sequencer_rpc/src/process.rs index 7647b6d..8aede21 100644 --- a/sequencer_rpc/src/process.rs +++ b/sequencer_rpc/src/process.rs @@ -267,7 +267,7 @@ mod tests { let addresses = vec![from, to]; let nonces = vec![0]; - let program_id = nssa::AUTHENTICATED_TRANSFER_PROGRAM.id; + let program_id = nssa::AUTHENTICATED_TRANSFER_PROGRAM.id(); let message = nssa::public_transaction::Message::new(program_id, addresses, nonces, balance_to_move); let witness_set = @@ -501,7 +501,7 @@ mod tests { ], "instruction_data": 10, "nonces": [0], - "program_id": nssa::AUTHENTICATED_TRANSFER_PROGRAM.id, + "program_id": nssa::AUTHENTICATED_TRANSFER_PROGRAM.id(), }, "witness_set": { "signatures_and_public_keys": [ diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index 9f80d8e..472159c 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -86,7 +86,7 @@ impl NodeCore { if let Some(account) = account { let addresses = vec![nssa::Address::new(from), nssa::Address::new(to)]; let nonces = vec![nonce]; - let program_id = nssa::AUTHENTICATED_TRANSFER_PROGRAM.id; + let program_id = nssa::AUTHENTICATED_TRANSFER_PROGRAM.id(); let message = nssa::public_transaction::Message::new( program_id, addresses,