multiversx_chain_vm/blockchain/state/
blockchain_state_account_util.rs

1use std::{collections::HashMap, fmt::Write};
2
3use crate::{display_util::address_hex, types::VMAddress};
4
5use super::{AccountData, BlockchainState};
6
7impl BlockchainState {
8    pub fn add_account(&mut self, acct: AccountData) {
9        let address = acct.address.clone();
10        self.accounts.insert(address, acct);
11    }
12
13    pub fn validate_and_add_account(&mut self, acct: AccountData) {
14        self.validate_account(&acct);
15        self.add_account(acct);
16    }
17
18    pub fn update_accounts(&mut self, accounts: HashMap<VMAddress, AccountData>) {
19        self.accounts.extend(accounts);
20    }
21
22    pub fn print_accounts(&self) {
23        let mut accounts_buf = String::new();
24        for (address, account) in &self.accounts {
25            write!(accounts_buf, "\n\t{} -> {account}", address_hex(address)).unwrap();
26        }
27        println!("Accounts: {}", &accounts_buf);
28    }
29
30    pub fn put_new_address(
31        &mut self,
32        creator_address: VMAddress,
33        creator_nonce: u64,
34        new_address: VMAddress,
35    ) {
36        self.new_addresses
37            .insert((creator_address, creator_nonce), new_address);
38    }
39
40    pub fn get_new_address(
41        &self,
42        creator_address: VMAddress,
43        creator_nonce: u64,
44    ) -> Option<VMAddress> {
45        self.new_addresses
46            .get(&(creator_address, creator_nonce))
47            .cloned()
48    }
49
50    pub fn validate_account(&self, account: &AccountData) {
51        let is_sc = account.address.is_smart_contract_address();
52        let has_code = self.check_account_has_code(account);
53
54        assert!(
55            !is_sc || has_code,
56            "Account has a smart contract address but no code"
57        );
58
59        assert!(
60            is_sc || !has_code,
61            "Account has no smart contract address but has code"
62        );
63    }
64
65    pub fn check_account_has_code(&self, account: &AccountData) -> bool {
66        !account
67            .contract_path
68            .as_ref()
69            .unwrap_or(&Vec::<u8>::new())
70            .is_empty()
71    }
72}