2025-08-06 20:05:04 -03:00
|
|
|
use crate::{
|
2025-08-10 00:53:53 -03:00
|
|
|
address::Address, error::NssaError, program::Program, public_transaction::PublicTransaction,
|
2025-08-06 20:05:04 -03:00
|
|
|
};
|
2025-08-10 14:33:40 -03:00
|
|
|
use nssa_core::{account::Account, program::ProgramId};
|
|
|
|
|
use std::collections::HashMap;
|
2025-08-06 20:05:04 -03:00
|
|
|
|
2025-08-07 15:19:06 -03:00
|
|
|
pub struct V01State {
|
2025-08-13 00:43:17 -03:00
|
|
|
pub(crate) public_state: HashMap<Address, Account>,
|
|
|
|
|
pub(crate) builtin_programs: HashMap<ProgramId, Program>,
|
2025-08-06 20:05:04 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl V01State {
|
2025-08-07 15:19:06 -03:00
|
|
|
pub fn new_with_genesis_accounts(initial_data: &[([u8; 32], u128)]) -> Self {
|
2025-08-10 00:53:53 -03:00
|
|
|
let authenticated_transfer_program = Program::authenticated_transfer_program();
|
2025-08-07 15:19:06 -03:00
|
|
|
let public_state = initial_data
|
2025-08-09 19:20:19 -03:00
|
|
|
.iter()
|
|
|
|
|
.copied()
|
2025-08-07 15:19:06 -03:00
|
|
|
.map(|(address_value, balance)| {
|
2025-08-09 18:40:32 -03:00
|
|
|
let account = Account {
|
2025-08-09 19:20:19 -03:00
|
|
|
balance,
|
2025-08-10 00:53:53 -03:00
|
|
|
program_owner: authenticated_transfer_program.id(),
|
2025-08-09 18:40:32 -03:00
|
|
|
..Account::default()
|
|
|
|
|
};
|
2025-08-07 15:19:06 -03:00
|
|
|
let address = Address::new(address_value);
|
|
|
|
|
(address, account)
|
|
|
|
|
})
|
|
|
|
|
.collect();
|
2025-08-08 16:19:50 -03:00
|
|
|
|
2025-08-10 09:57:10 -03:00
|
|
|
let mut this = Self {
|
2025-08-08 16:19:50 -03:00
|
|
|
public_state,
|
2025-08-10 09:57:10 -03:00
|
|
|
builtin_programs: HashMap::new(),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.insert_program(Program::authenticated_transfer_program());
|
|
|
|
|
|
|
|
|
|
this
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-12 21:27:27 -03:00
|
|
|
pub(crate) fn insert_program(&mut self, program: Program) {
|
2025-08-10 09:57:10 -03:00
|
|
|
self.builtin_programs.insert(program.id(), program);
|
2025-08-07 15:19:06 -03:00
|
|
|
}
|
|
|
|
|
|
2025-08-09 19:49:07 -03:00
|
|
|
pub fn transition_from_public_transaction(
|
|
|
|
|
&mut self,
|
|
|
|
|
tx: &PublicTransaction,
|
|
|
|
|
) -> Result<(), NssaError> {
|
2025-08-10 14:33:40 -03:00
|
|
|
let state_diff = tx.validate_and_compute_post_states(self)?;
|
2025-08-06 20:05:04 -03:00
|
|
|
|
|
|
|
|
for (address, post) in state_diff.into_iter() {
|
|
|
|
|
let current_account = self.get_account_by_address_mut(address);
|
|
|
|
|
*current_account = post;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for address in tx.signer_addresses() {
|
|
|
|
|
let current_account = self.get_account_by_address_mut(address);
|
|
|
|
|
current_account.nonce += 1;
|
|
|
|
|
}
|
2025-08-09 20:35:44 -03:00
|
|
|
|
2025-08-06 20:05:04 -03:00
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn get_account_by_address_mut(&mut self, address: Address) -> &mut Account {
|
2025-08-09 19:20:19 -03:00
|
|
|
self.public_state.entry(address).or_default()
|
2025-08-06 20:05:04 -03:00
|
|
|
}
|
|
|
|
|
|
2025-08-07 15:19:06 -03:00
|
|
|
pub fn get_account_by_address(&self, address: &Address) -> Account {
|
2025-08-06 20:05:04 -03:00
|
|
|
self.public_state
|
|
|
|
|
.get(address)
|
|
|
|
|
.cloned()
|
|
|
|
|
.unwrap_or(Account::default())
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-10 14:33:40 -03:00
|
|
|
pub(crate) fn builtin_programs(&self) -> &HashMap<ProgramId, Program> {
|
|
|
|
|
&self.builtin_programs
|
2025-08-06 20:05:04 -03:00
|
|
|
}
|
2025-08-10 11:58:25 -03:00
|
|
|
|
2025-08-12 21:27:27 -03:00
|
|
|
#[cfg(test)]
|
|
|
|
|
pub fn force_insert_account(&mut self, address: Address, account: Account) {
|
|
|
|
|
self.public_state.insert(address, account);
|
2025-08-10 11:58:25 -03:00
|
|
|
}
|
2025-08-06 20:05:04 -03:00
|
|
|
}
|