1use {
2 crate::cpi::request::CallerAccountInfo,
3 sbpf_vm::{errors::SbpfVmResult, memory::Memory},
4 solana_account::Account,
5 solana_address::Address,
6 std::collections::HashMap,
7};
8
9const MAX_PERMITTED_DATA_INCREASE: usize = 10240;
11
12pub fn sync_from_caller(
14 memory: &Memory,
15 caller_accounts: &[CallerAccountInfo],
16 accounts: &mut HashMap<Address, Account>,
17) -> SbpfVmResult<()> {
18 for info in caller_accounts {
19 let lamports = memory.read_u64(info.lamports_addr)?;
20 let data = memory
21 .read_bytes(info.data_addr, info.data_len as usize)?
22 .to_vec();
23 let owner_bytes = memory.read_bytes(info.owner_addr, 32)?;
24 let owner = Address::new_from_array(owner_bytes.try_into().unwrap());
25
26 let account = accounts.entry(info.pubkey).or_default();
27 account.lamports = lamports;
28 account.data = data;
29 account.owner = owner;
30 }
31 Ok(())
32}
33
34pub fn sync_to_caller(
36 memory: &mut Memory,
37 caller_accounts: &[CallerAccountInfo],
38 accounts: &HashMap<Address, Account>,
39) -> SbpfVmResult<()> {
40 for info in caller_accounts {
41 if !info.is_writable {
42 continue;
43 }
44 let Some(account) = accounts.get(&info.pubkey) else {
45 continue;
46 };
47
48 memory.write_u64(info.lamports_addr, account.lamports)?;
50 memory.write_bytes(info.owner_addr, account.owner.as_ref())?;
51
52 let prev_len = info.data_len as usize;
53 let post_len = account.data.len();
54 let max_allowed = prev_len.saturating_add(MAX_PERMITTED_DATA_INCREASE);
55
56 if post_len > max_allowed {
57 return Err(sbpf_vm::errors::SbpfVmError::SyscallError(format!(
58 "Account data realloc limited to {}",
59 MAX_PERMITTED_DATA_INCREASE
60 )));
61 }
62
63 if prev_len != post_len {
65 if post_len < prev_len {
66 let zeros = vec![0u8; prev_len - post_len];
67 memory.write_bytes(info.data_addr + post_len as u64, &zeros)?;
68 }
69 memory.write_u64(info.vm_data_len_addr, post_len as u64)?;
70 memory.write_u64(info.data_addr.saturating_sub(8), post_len as u64)?;
71 }
72
73 memory.write_bytes(info.data_addr, &account.data)?;
75 }
76 Ok(())
77}