refactor program

This commit is contained in:
Sergio Chouhy 2025-08-09 20:25:58 -03:00
parent 51d8ac47cf
commit 6030e54cd7
11 changed files with 105 additions and 108 deletions

View File

@ -1,4 +1,3 @@
// TODO: Consider wrapping `AccountAddress` in a struct.
pub type AccountAddress = [u8; 32];

View File

@ -1,6 +1,5 @@
use serde::{Deserialize, Serialize};
//Requests
#[derive(Serialize, Deserialize, Debug)]

View File

@ -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::program::AUTHENTICATED_TRANSFER_PROGRAM.id();
let addresses = vec![];
let nonces = vec![];
let instruction_data = 0;
@ -42,7 +42,7 @@ pub fn produce_dummy_empty_transaction() -> nssa::PublicTransaction {
nssa::PublicTransaction::new(message, witness_set)
}
pub fn create_dummy_transaction_native_token_transfer(
pub fn create_transaction_native_token_transfer(
from: [u8; 32],
nonce: u128,
to: [u8; 32],
@ -51,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::program::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]);

View File

@ -1,12 +1,6 @@
use nssa_core::{
account::{Account, AccountWithMetadata},
program::{DEFAULT_PROGRAM_ID, ProgramId},
};
use program_methods::{AUTHENTICATED_TRANSFER_ELF, AUTHENTICATED_TRANSFER_ID};
use risc0_zkvm::{ExecutorEnv, ExecutorEnvBuilder, default_executor};
mod address;
pub mod error;
pub mod program;
pub mod public_transaction;
mod signature;
mod state;
@ -17,68 +11,3 @@ pub use signature::PrivateKey;
pub use signature::PublicKey;
pub use signature::Signature;
pub use state::V01State;
use crate::error::NssaError;
pub const AUTHENTICATED_TRANSFER_PROGRAM: Program = Program {
id: AUTHENTICATED_TRANSFER_ID,
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],
instruction_data: u128,
env_builder: &mut ExecutorEnvBuilder,
) -> Result<(), NssaError> {
let pre_states = pre_states.to_vec();
env_builder
.write(&pre_states)
.map_err(|e| NssaError::ProgramExecutionFailed(e.to_string()))?;
env_builder
.write(&instruction_data)
.map_err(|e| NssaError::ProgramExecutionFailed(e.to_string()))?;
Ok(())
}
impl Program {
pub fn id(&self) -> ProgramId {
self.id
}
pub(crate) fn execute(
&self,
pre_states: &[AccountWithMetadata],
instruction_data: u128,
) -> Result<Vec<Account>, 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, self.elf)
.map_err(|e| NssaError::ProgramExecutionFailed(e.to_string()))?;
// Get outputs
let mut post_states: Vec<Account> = 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)
}
}

71
nssa/src/program.rs Normal file
View File

@ -0,0 +1,71 @@
use nssa_core::{
account::{Account, AccountWithMetadata},
program::{DEFAULT_PROGRAM_ID, ProgramId},
};
use program_methods::{AUTHENTICATED_TRANSFER_ELF, AUTHENTICATED_TRANSFER_ID};
use risc0_zkvm::{ExecutorEnv, ExecutorEnvBuilder, default_executor};
use crate::error::NssaError;
pub struct Program {
id: ProgramId,
elf: &'static [u8],
}
pub const AUTHENTICATED_TRANSFER_PROGRAM: Program = Program {
id: AUTHENTICATED_TRANSFER_ID,
elf: AUTHENTICATED_TRANSFER_ELF,
};
impl Program {
pub fn id(&self) -> ProgramId {
self.id
}
pub(crate) fn execute(
&self,
pre_states: &[AccountWithMetadata],
instruction_data: u128,
) -> Result<Vec<Account>, NssaError> {
// Write inputs to the program
let mut env_builder = ExecutorEnv::builder();
Self::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, self.elf)
.map_err(|e| NssaError::ProgramExecutionFailed(e.to_string()))?;
// Get outputs
let mut post_states: Vec<Account> = 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)
}
/// Writes inputs to `env_builder` in the order expected by the programs
fn write_inputs(
pre_states: &[AccountWithMetadata],
instruction_data: u128,
env_builder: &mut ExecutorEnvBuilder,
) -> Result<(), NssaError> {
let pre_states = pre_states.to_vec();
env_builder
.write(&pre_states)
.map_err(|e| NssaError::ProgramExecutionFailed(e.to_string()))?;
env_builder
.write(&instruction_data)
.map_err(|e| NssaError::ProgramExecutionFailed(e.to_string()))?;
Ok(())
}
}

View File

@ -1,7 +1,4 @@
use nssa_core::{
account::Nonce,
program::ProgramId,
};
use nssa_core::{account::Nonce, program::ProgramId};
use serde::{Deserialize, Serialize};
use sha2::{Digest, digest::FixedOutput};

View File

@ -1,5 +1,7 @@
use crate::{
AUTHENTICATED_TRANSFER_PROGRAM, Program, address::Address, error::NssaError,
address::Address,
error::NssaError,
program::{AUTHENTICATED_TRANSFER_PROGRAM, Program},
public_transaction::PublicTransaction,
};
use nssa_core::{
@ -21,7 +23,7 @@ impl V01State {
.map(|(address_value, balance)| {
let account = Account {
balance,
program_owner: AUTHENTICATED_TRANSFER_PROGRAM.id,
program_owner: AUTHENTICATED_TRANSFER_PROGRAM.id(),
..Account::default()
};
let address = Address::new(address_value);
@ -30,7 +32,7 @@ impl V01State {
.collect();
let builtin_programs = HashMap::from([(
AUTHENTICATED_TRANSFER_PROGRAM.id,
AUTHENTICATED_TRANSFER_PROGRAM.id(),
AUTHENTICATED_TRANSFER_PROGRAM,
)]);
@ -155,7 +157,7 @@ mod tests {
) -> PublicTransaction {
let addresses = vec![from, to];
let nonces = vec![nonce];
let program_id = AUTHENTICATED_TRANSFER_PROGRAM.id;
let program_id = AUTHENTICATED_TRANSFER_PROGRAM.id();
let message = public_transaction::Message::new(program_id, addresses, nonces, balance);
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&from_key]);
PublicTransaction::new(message, witness_set)

View File

@ -369,7 +369,7 @@ mod tests {
let sign_key1 = create_signing_key_for_account1();
let tx = common::test_utils::create_dummy_transaction_native_token_transfer(
let tx = common::test_utils::create_transaction_native_token_transfer(
acc1, 0, acc2, 10, sign_key1,
);
let result = sequencer.transaction_pre_check(tx);
@ -395,7 +395,7 @@ mod tests {
let sign_key2 = create_signing_key_for_account2();
let tx = common::test_utils::create_dummy_transaction_native_token_transfer(
let tx = common::test_utils::create_transaction_native_token_transfer(
acc1, 0, acc2, 10, sign_key2,
);
@ -405,7 +405,10 @@ mod tests {
// Signature is not from sender. Execution fails
let result = sequencer.execute_check_transaction_on_state(tx);
assert!(matches!(result, Err(nssa::error::NssaError::ProgramExecutionFailed(_))));
assert!(matches!(
result,
Err(nssa::error::NssaError::ProgramExecutionFailed(_))
));
}
#[test]
@ -426,7 +429,7 @@ mod tests {
let sign_key1 = create_signing_key_for_account1();
let tx = common::test_utils::create_dummy_transaction_native_token_transfer(
let tx = common::test_utils::create_transaction_native_token_transfer(
acc1, 0, acc2, 10000000, sign_key1,
);
// let tx_roots = sequencer.get_tree_roots();
@ -462,7 +465,7 @@ mod tests {
let sign_key1 = create_signing_key_for_account1();
let tx = common::test_utils::create_dummy_transaction_native_token_transfer(
let tx = common::test_utils::create_transaction_native_token_transfer(
acc1, 0, acc2, 100, sign_key1,
);
@ -553,7 +556,7 @@ mod tests {
let sign_key1 = create_signing_key_for_account1();
let tx = common::test_utils::create_dummy_transaction_native_token_transfer(
let tx = common::test_utils::create_transaction_native_token_transfer(
acc1, 0, acc2, 100, sign_key1,
);
@ -595,7 +598,7 @@ mod tests {
let sign_key1 = create_signing_key_for_account1();
let tx = common::test_utils::create_dummy_transaction_native_token_transfer(
let tx = common::test_utils::create_transaction_native_token_transfer(
acc1, 0, acc2, 100, sign_key1,
);

View File

@ -76,7 +76,7 @@ fn block_to_transactions_map(block: &Block) -> HashMap<TreeHashType, u64> {
#[cfg(test)]
mod tests {
use super::*;
use tempfile::tempdir;
//
// fn create_dummy_block_with_transaction(block_id: u64) -> (Block, nssa::PublicTransaction) {

View File

@ -18,7 +18,8 @@ use common::{
use common::rpc_primitives::requests::{
GetBlockDataRequest, GetBlockDataResponse, GetGenesisIdRequest, GetGenesisIdResponse,
GetLastBlockRequest, GetLastBlockResponse, HelloRequest, HelloResponse, SendTxRequest, SendTxResponse,
GetLastBlockRequest, GetLastBlockResponse, HelloRequest, HelloResponse, SendTxRequest,
SendTxResponse,
};
use super::{respond, types::err_rpc::RpcErr, JsonHandler};
@ -203,7 +204,7 @@ mod tests {
use crate::{rpc_handler, JsonHandler};
use common::rpc_primitives::RpcPollingConfig;
use sequencer_core::{
config::{AccountInitialData, SequencerConfig},
SequencerCore,
@ -260,19 +261,15 @@ mod tests {
let mut sequencer_core = SequencerCore::start_from_config(config);
let initial_accounts = sequencer_core.sequencer_config.initial_accounts.clone();
let from = nssa::Address::new([1; 32]);
let signing_key = nssa::PrivateKey::new(1);
let to = nssa::Address::new([2; 32]);
let balance_to_move = 10;
let addresses = vec![from, to];
let nonces = vec![0];
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]);
let tx = nssa::PublicTransaction::new(message, witness_set);
let tx = common::test_utils::create_transaction_native_token_transfer(
[1; 32],
0,
[2; 32],
balance_to_move,
signing_key,
);
sequencer_core
.push_tx_into_mempool_pre_check(tx.clone())
@ -501,7 +498,7 @@ mod tests {
],
"instruction_data": 10,
"nonces": [0],
"program_id": nssa::AUTHENTICATED_TRANSFER_PROGRAM.id(),
"program_id": nssa::program::AUTHENTICATED_TRANSFER_PROGRAM.id(),
},
"witness_set": {
"signatures_and_public_keys": [

View File

@ -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::program::AUTHENTICATED_TRANSFER_PROGRAM.id();
let message = nssa::public_transaction::Message::new(
program_id,
addresses,