svm_test_utils/
programs.rs

1use solana_program::{
2    bpf_loader_upgradeable::{self, UpgradeableLoaderState, get_program_data_address},
3    pubkey::Pubkey,
4    rent::Rent,
5};
6use solana_sdk::account::Account;
7
8/// Loads a program using the upgradable BPF Loader
9pub fn bpf_loader_upgradeable_program_accounts(
10    program_id: &Pubkey,
11    elf: &[u8],
12    rent: &Rent,
13) -> [(Pubkey, Account); 2] {
14    let programdata_address = get_program_data_address(program_id);
15
16    let program_account = {
17        let space = UpgradeableLoaderState::size_of_program();
18        let lamports = rent.minimum_balance(space);
19        let data = bincode::serialize(&UpgradeableLoaderState::Program {
20            programdata_address,
21        })
22        .unwrap();
23
24        Account {
25            lamports,
26            data,
27            owner: bpf_loader_upgradeable::id(),
28            executable: true,
29            rent_epoch: 0,
30        }
31    };
32
33    let programdata_account = {
34        let space = UpgradeableLoaderState::size_of_programdata_metadata() + elf.len();
35        let lamports = rent.minimum_balance(space);
36        let mut data = bincode::serialize(&UpgradeableLoaderState::ProgramData {
37            slot: 0,
38            upgrade_authority_address: Some(Pubkey::default()),
39        })
40        .unwrap();
41        data.extend_from_slice(elf);
42
43        Account {
44            lamports,
45            data,
46            owner: bpf_loader_upgradeable::id(),
47            executable: false,
48            rent_epoch: 0,
49        }
50    };
51
52    [
53        (*program_id, program_account),
54        (programdata_address, programdata_account),
55    ]
56}