trident_svm/methods/
trident_svm_programs.rs1use solana_account::AccountSharedData;
2use solana_account::WritableAccount;
3use solana_loader_v3_interface::state::UpgradeableLoaderState;
4use solana_sysvar::rent::Rent;
5
6#[cfg(feature = "syscall-v2")]
7use crate::types::trident_entrypoint::TridentEntrypoint;
8#[cfg(feature = "syscall-v2")]
9use solana_program_runtime::loaded_programs::ProgramCacheEntry;
10
11use crate::trident_svm::TridentSVM;
12use crate::types::trident_program::TridentProgram;
13
14impl TridentSVM {
15 pub fn deploy_binary_program(&mut self, program: &TridentProgram) {
16 let rent = Rent::default();
17
18 let program_account = &program.program_id;
19
20 let program_data_account =
21 solana_loader_v3_interface::get_program_data_address(program_account);
22
23 let state = UpgradeableLoaderState::Program {
24 programdata_address: program_data_account,
25 };
26
27 let buffer = bincode::serialize(&state).unwrap();
28 let account_data = AccountSharedData::create(
29 rent.minimum_balance(buffer.len()),
30 buffer,
31 solana_sdk_ids::bpf_loader_upgradeable::id(),
32 true,
33 Default::default(),
34 );
35
36 self.accounts.set_program(program_account, &account_data);
37
38 let state = UpgradeableLoaderState::ProgramData {
39 slot: 0,
40 upgrade_authority_address: program.authority,
41 };
42 let mut header = bincode::serialize(&state).unwrap();
43
44 let mut complement = vec![
45 0;
46 std::cmp::max(
47 0,
48 UpgradeableLoaderState::size_of_programdata_metadata().saturating_sub(header.len())
49 )
50 ];
51
52 let mut buffer: Vec<u8> = program.data.to_vec();
53 header.append(&mut complement);
54 header.append(&mut buffer);
55
56 let account_data = AccountSharedData::create(
57 rent.minimum_balance(header.len()),
58 header,
59 solana_sdk_ids::bpf_loader_upgradeable::id(),
60 true,
61 Default::default(),
62 );
63
64 self.accounts
65 .set_program(&program_data_account, &account_data);
66 }
67
68 #[cfg(feature = "syscall-v2")]
69 pub fn deploy_entrypoint_program(&mut self, program: &TridentEntrypoint) {
70 use crate::utils::create_loadable_account_for_test;
71
72 let entry = match program.entry {
73 Some(entry) => entry,
74 None => panic!("Native programs have to have entry specified"),
75 };
76
77 self.accounts.set_program(
78 &program.program_id,
79 &create_loadable_account_for_test("program-name"),
80 );
81
82 let program_data_account =
83 solana_loader_v3_interface::get_program_data_address(&program.program_id);
84
85 let state = UpgradeableLoaderState::ProgramData {
86 slot: 0,
87 upgrade_authority_address: program.authority,
88 };
89 let mut header = bincode::serialize(&state).unwrap();
90
91 let mut complement = vec![
92 0;
93 std::cmp::max(
94 0,
95 UpgradeableLoaderState::size_of_programdata_metadata().saturating_sub(header.len())
96 )
97 ];
98
99 let mut buffer: Vec<u8> = vec![];
100 header.append(&mut complement);
101 header.append(&mut buffer);
102
103 let rent = Rent::default();
104
105 let account_data = AccountSharedData::create(
106 rent.minimum_balance(header.len()),
107 header,
108 solana_sdk_ids::bpf_loader_upgradeable::id(),
109 true,
110 Default::default(),
111 );
112
113 self.accounts
114 .set_program(&program_data_account, &account_data);
115
116 self.processor.add_builtin(
117 self,
118 program.program_id,
119 "program-name",
120 ProgramCacheEntry::new_builtin(0, "program-name".len(), entry),
121 );
122 }
123}