Sergio Chouhy acaf62f31f fmt clippy
2025-08-13 00:51:54 -03:00

199 lines
7.5 KiB
Rust

use std::collections::HashMap;
use crate::{
Address, PublicKey, PublicTransaction, V01State, error::NssaError, program::Program,
public_transaction, signature::PrivateKey,
};
use nssa_core::account::Account;
fn transfer_transaction(
from: Address,
from_key: PrivateKey,
nonce: u128,
to: Address,
balance: u128,
) -> PublicTransaction {
let addresses = vec![from, to];
let nonces = vec![nonce];
let program_id = Program::authenticated_transfer_program().id();
let message =
public_transaction::Message::try_new(program_id, addresses, nonces, balance).unwrap();
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&from_key]);
PublicTransaction::new(message, witness_set)
}
#[test]
fn test_new_with_genesis() {
let key1 = PrivateKey::try_new([1; 32]).unwrap();
let key2 = PrivateKey::try_new([2; 32]).unwrap();
let addr1 = Address::from_public_key(&PublicKey::new(&key1));
let addr2 = Address::from_public_key(&PublicKey::new(&key2));
let initial_data = [(*addr1.value(), 100u128), (*addr2.value(), 151u128)];
let program = Program::authenticated_transfer_program();
let expected_public_state = {
let mut this = HashMap::new();
this.insert(
addr1,
Account {
balance: 100,
program_owner: program.id(),
..Account::default()
},
);
this.insert(
addr2,
Account {
balance: 151,
program_owner: program.id(),
..Account::default()
},
);
this
};
let expected_builtin_programs = {
let mut this = HashMap::new();
this.insert(program.id(), program);
this
};
let state = V01State::new_with_genesis_accounts(&initial_data);
assert_eq!(state.public_state, expected_public_state);
assert_eq!(state.builtin_programs, expected_builtin_programs);
}
#[test]
fn test_insert_program() {
let mut state = V01State::new_with_genesis_accounts(&[]);
let program_to_insert = Program::simple_balance_transfer();
let program_id = program_to_insert.id();
assert!(!state.builtin_programs.contains_key(&program_id));
state.insert_program(program_to_insert);
assert!(state.builtin_programs.contains_key(&program_id));
}
#[test]
fn test_get_account_by_address_non_default_account() {
let key = PrivateKey::try_new([1; 32]).unwrap();
let addr = Address::from_public_key(&PublicKey::new(&key));
let initial_data = [(*addr.value(), 100u128)];
let state = V01State::new_with_genesis_accounts(&initial_data);
let expected_account = state.public_state.get(&addr).unwrap();
let account = state.get_account_by_address(&addr);
assert_eq!(&account, expected_account);
}
#[test]
fn test_get_account_by_address_default_account() {
let addr2 = Address::new([0; 32]);
let state = V01State::new_with_genesis_accounts(&[]);
let expected_account = Account::default();
let account = state.get_account_by_address(&addr2);
assert_eq!(account, expected_account);
}
#[test]
fn test_builtin_programs_getter() {
let state = V01State::new_with_genesis_accounts(&[]);
let builtin_programs = state.builtin_programs();
assert_eq!(builtin_programs, &state.builtin_programs);
}
#[test]
fn transition_from_authenticated_transfer_program_invocation_default_account_destination() {
let key = PrivateKey::try_new([1; 32]).unwrap();
let address = Address::from_public_key(&PublicKey::new(&key));
let initial_data = [(*address.value(), 100)];
let mut state = V01State::new_with_genesis_accounts(&initial_data);
let from = address;
let to = Address::new([2; 32]);
assert_eq!(state.get_account_by_address(&to), Account::default());
let balance_to_move = 5;
let tx = transfer_transaction(from.clone(), key, 0, to.clone(), balance_to_move);
state.transition_from_public_transaction(&tx).unwrap();
assert_eq!(state.get_account_by_address(&from).balance, 95);
assert_eq!(state.get_account_by_address(&to).balance, 5);
assert_eq!(state.get_account_by_address(&from).nonce, 1);
assert_eq!(state.get_account_by_address(&to).nonce, 0);
}
#[test]
fn transition_from_authenticated_transfer_program_invocation_insuficient_balance() {
let key = PrivateKey::try_new([1; 32]).unwrap();
let address = Address::from_public_key(&PublicKey::new(&key));
let initial_data = [(*address.value(), 100)];
let mut state = V01State::new_with_genesis_accounts(&initial_data);
let from = address;
let from_key = key;
let to = Address::new([2; 32]);
let balance_to_move = 101;
assert!(state.get_account_by_address(&from).balance < balance_to_move);
let tx = transfer_transaction(from.clone(), from_key, 0, to.clone(), balance_to_move);
let result = state.transition_from_public_transaction(&tx);
assert!(matches!(result, Err(NssaError::ProgramExecutionFailed(_))));
assert_eq!(state.get_account_by_address(&from).balance, 100);
assert_eq!(state.get_account_by_address(&to).balance, 0);
assert_eq!(state.get_account_by_address(&from).nonce, 0);
assert_eq!(state.get_account_by_address(&to).nonce, 0);
}
#[test]
fn transition_from_authenticated_transfer_program_invocation_non_default_account_destination() {
let key1 = PrivateKey::try_new([1; 32]).unwrap();
let key2 = PrivateKey::try_new([2; 32]).unwrap();
let address1 = Address::from_public_key(&PublicKey::new(&key1));
let address2 = Address::from_public_key(&PublicKey::new(&key2));
let initial_data = [(*address1.value(), 100), (*address2.value(), 200)];
let mut state = V01State::new_with_genesis_accounts(&initial_data);
let from = address2;
let from_key = key2;
let to = address1;
assert_ne!(state.get_account_by_address(&to), Account::default());
let balance_to_move = 8;
let tx = transfer_transaction(from.clone(), from_key, 0, to.clone(), balance_to_move);
state.transition_from_public_transaction(&tx).unwrap();
assert_eq!(state.get_account_by_address(&from).balance, 192);
assert_eq!(state.get_account_by_address(&to).balance, 108);
assert_eq!(state.get_account_by_address(&from).nonce, 1);
assert_eq!(state.get_account_by_address(&to).nonce, 0);
}
#[test]
fn transition_from_chained_authenticated_transfer_program_invocations() {
let key1 = PrivateKey::try_new([8; 32]).unwrap();
let address1 = Address::from_public_key(&PublicKey::new(&key1));
let key2 = PrivateKey::try_new([2; 32]).unwrap();
let address2 = Address::from_public_key(&PublicKey::new(&key2));
let initial_data = [(*address1.value(), 100)];
let mut state = V01State::new_with_genesis_accounts(&initial_data);
let address3 = Address::new([3; 32]);
let balance_to_move = 5;
let tx = transfer_transaction(address1.clone(), key1, 0, address2.clone(), balance_to_move);
state.transition_from_public_transaction(&tx).unwrap();
let balance_to_move = 3;
let tx = transfer_transaction(address2.clone(), key2, 0, address3.clone(), balance_to_move);
state.transition_from_public_transaction(&tx).unwrap();
assert_eq!(state.get_account_by_address(&address1).balance, 95);
assert_eq!(state.get_account_by_address(&address2).balance, 2);
assert_eq!(state.get_account_by_address(&address3).balance, 3);
assert_eq!(state.get_account_by_address(&address1).nonce, 1);
assert_eq!(state.get_account_by_address(&address2).nonce, 1);
assert_eq!(state.get_account_by_address(&address3).nonce, 0);
}