diff --git a/nssa/core/src/program.rs b/nssa/core/src/program.rs index a4e6722..233a0f7 100644 --- a/nssa/core/src/program.rs +++ b/nssa/core/src/program.rs @@ -71,8 +71,8 @@ pub fn validate_execution( // 5. Data changes only allowed if owned by executing program if pre.account.data != post.data - && (executing_program_id != pre.account.program_owner - || executing_program_id != post.program_owner) + && (pre.account != Account::default() && (executing_program_id != pre.account.program_owner + || executing_program_id != post.program_owner)) { return false; } diff --git a/nssa/program_methods/guest/src/bin/token.rs b/nssa/program_methods/guest/src/bin/token.rs index caa7692..49da9d7 100644 --- a/nssa/program_methods/guest/src/bin/token.rs +++ b/nssa/program_methods/guest/src/bin/token.rs @@ -4,11 +4,14 @@ use nssa_core::{ }; use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize)] -enum Instruction { - Transfer(u128), - NewDefinition([u8; 6], u128), -} +// #[derive(Serialize, Deserialize)] +// enum Instruction { +// Transfer(u128), +// NewDefinition([u8; 6], u128), +// } +// +/// [type (1) || amount (16) || name (6)] +type Instruction = [u8; 23]; const TOKEN_DEFINITION_TYPE: u8 = 0; const TOKEN_DEFINITION_SIZE: usize = 23; @@ -52,8 +55,8 @@ impl TokenHolding { None } else { let account_type = data[0]; - let definition_id = AccountId::new(data[33..65].try_into().unwrap()); - let balance = u128::from_le_bytes(data[65..].try_into().unwrap()); + let definition_id = AccountId::new(data[1..33].try_into().unwrap()); + let balance = u128::from_le_bytes(data[33..].try_into().unwrap()); Some(Self { definition_id, balance, @@ -157,10 +160,19 @@ fn main() { instruction, } = read_nssa_inputs::(); - match instruction { - Instruction::Transfer(balance_to_move) => transfer(pre_states, balance_to_move), - Instruction::NewDefinition(name, total_supply) => { + match instruction[0] { + 0 => { + let total_supply = u128::from_le_bytes(instruction[1..17].try_into().unwrap()); + let name: [u8; 6] = instruction[17..].try_into().unwrap(); + assert_ne!(name, [0; 6]); new_definition(pre_states, name, total_supply) } + 1 => { + let balance_to_move = u128::from_le_bytes(instruction[1..17].try_into().unwrap()); + let name: [u8; 6] = instruction[17..].try_into().unwrap(); + assert_eq!(name, [0; 6]); + transfer(pre_states, balance_to_move) + } + _ => panic!("Invalid instruction"), }; } diff --git a/nssa/src/lib.rs b/nssa/src/lib.rs index 25a9368..dd0df31 100644 --- a/nssa/src/lib.rs +++ b/nssa/src/lib.rs @@ -7,6 +7,7 @@ pub mod public_transaction; mod signature; mod state; +pub use nssa_core::account::Account; pub use address::Address; pub use nssa_core::account::Account; pub use privacy_preserving_transaction::{ diff --git a/nssa/src/state.rs b/nssa/src/state.rs index 8f48888..42f9196 100644 --- a/nssa/src/state.rs +++ b/nssa/src/state.rs @@ -257,14 +257,14 @@ pub mod tests { let addr1 = Address::from(&PublicKey::new_from_private_key(&key1)); let addr2 = Address::from(&PublicKey::new_from_private_key(&key2)); let initial_data = [(addr1, 100u128), (addr2, 151u128)]; - let program = Program::authenticated_transfer_program(); + let authenticated_transfers_program = Program::authenticated_transfer_program(); let expected_public_state = { let mut this = HashMap::new(); this.insert( addr1, Account { balance: 100, - program_owner: program.id(), + program_owner: authenticated_transfers_program.id(), ..Account::default() }, ); @@ -272,7 +272,7 @@ pub mod tests { addr2, Account { balance: 151, - program_owner: program.id(), + program_owner: authenticated_transfers_program.id(), ..Account::default() }, ); @@ -280,7 +280,11 @@ pub mod tests { }; let expected_builtin_programs = { let mut this = HashMap::new(); - this.insert(program.id(), program); + this.insert( + authenticated_transfers_program.id(), + authenticated_transfers_program, + ); + this.insert(Program::token().id(), Program::token()); this }; @@ -660,12 +664,13 @@ pub mod tests { #[test] fn test_program_should_fail_if_modifies_data_of_non_owned_account() { let initial_data = []; - let mut state = V01State::new_with_genesis_accounts(&initial_data).with_test_programs(); - let address = Address::new([1; 32]); + let mut state = V01State::new_with_genesis_accounts(&initial_data) + .with_test_programs() + .with_non_default_accounts_but_default_program_owners(); + let address = Address::new([255; 32]); let program_id = Program::data_changer().id(); - // Consider the extreme case where the target account is the default account - assert_eq!(state.get_account_by_address(&address), Account::default()); + assert_ne!(state.get_account_by_address(&address), Account::default()); assert_ne!( state.get_account_by_address(&address).program_owner, program_id