multiversx_chain_vm/blockchain/state/
blockchain_state_account_util.rs1use 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}