Skip to content

Commit

Permalink
Adds instructions_to_load_program_of_loader_v4() and load_program_of_…
Browse files Browse the repository at this point in the history
…loader_v4().

Removes load_and_finalize_program() and load_program().
  • Loading branch information
Lichtso committed Sep 3, 2024
1 parent c717fb9 commit b280978
Showing 1 changed file with 86 additions and 58 deletions.
144 changes: 86 additions & 58 deletions runtime/src/loader_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use {
client::{Client, SyncClient},
clock::Clock,
instruction::{AccountMeta, Instruction},
loader_instruction,
loader_v4,
message::Message,
pubkey::Pubkey,
signature::{Keypair, Signer},
Expand Down Expand Up @@ -65,63 +65,6 @@ pub fn create_program(bank: &Bank, loader_id: &Pubkey, name: &str) -> Pubkey {
program_id
}

pub fn load_and_finalize_program<T: Client>(
bank_client: &T,
loader_id: &Pubkey,
program_keypair: Option<Keypair>,
payer_keypair: &Keypair,
name: &str,
) -> (Keypair, Instruction) {
let program = load_program_from_file(name);
let program_keypair = program_keypair.unwrap_or_else(|| {
let program_keypair = Keypair::new();
let instruction = system_instruction::create_account(
&payer_keypair.pubkey(),
&program_keypair.pubkey(),
1.max(
bank_client
.get_minimum_balance_for_rent_exemption(program.len())
.unwrap(),
),
program.len() as u64,
loader_id,
);
let message = Message::new(&[instruction], Some(&payer_keypair.pubkey()));
bank_client
.send_and_confirm_message(&[payer_keypair, &program_keypair], message)
.unwrap();
program_keypair
});
let chunk_size = CHUNK_SIZE;
let mut offset = 0;
for chunk in program.chunks(chunk_size) {
let instruction =
loader_instruction::write(&program_keypair.pubkey(), loader_id, offset, chunk.to_vec());
let message = Message::new(&[instruction], Some(&payer_keypair.pubkey()));
bank_client
.send_and_confirm_message(&[payer_keypair, &program_keypair], message)
.unwrap();
offset += chunk_size as u32;
}
let instruction = loader_instruction::finalize(&program_keypair.pubkey(), loader_id);
(program_keypair, instruction)
}

pub fn load_program<T: Client>(
bank_client: &T,
loader_id: &Pubkey,
payer_keypair: &Keypair,
name: &str,
) -> Pubkey {
let (program_keypair, instruction) =
load_and_finalize_program(bank_client, loader_id, None, payer_keypair, name);
let message = Message::new(&[instruction], Some(&payer_keypair.pubkey()));
bank_client
.send_and_confirm_message(&[payer_keypair, &program_keypair], message)
.unwrap();
program_keypair.pubkey()
}

pub fn load_upgradeable_buffer<T: Client>(
bank_client: &T,
from_keypair: &Keypair,
Expand Down Expand Up @@ -313,6 +256,91 @@ pub fn set_upgrade_authority<T: Client>(
.unwrap();
}

pub fn instructions_to_load_program_of_loader_v4<T: Client>(
bank_client: &T,
payer_keypair: &Keypair,
authority_keypair: &Keypair,
name: &str,
program_keypair: Option<Keypair>,
target_program_id: Option<&Pubkey>,
) -> (Keypair, Vec<Instruction>) {
let mut instructions = Vec::new();
let loader_id = &loader_v4::id();
let program = load_program_from_file(name);
let program_keypair = program_keypair.unwrap_or_else(|| {
let program_keypair = Keypair::new();
instructions.push(system_instruction::create_account(
&payer_keypair.pubkey(),
&program_keypair.pubkey(),
bank_client
.get_minimum_balance_for_rent_exemption(program.len())
.unwrap(),
0,
loader_id,
));
program_keypair
});
instructions.push(loader_v4::truncate_uninitialized(
&program_keypair.pubkey(),
&authority_keypair.pubkey(),
program.len() as u32,
&payer_keypair.pubkey(),
));
let chunk_size = CHUNK_SIZE;
let mut offset = 0;
for chunk in program.chunks(chunk_size) {
instructions.push(loader_v4::write(
&program_keypair.pubkey(),
&authority_keypair.pubkey(),
offset,
chunk.to_vec(),
));
offset += chunk_size as u32;
}
instructions.push(if let Some(target_program_id) = target_program_id {
loader_v4::deploy_from_source(
target_program_id,
&authority_keypair.pubkey(),
&program_keypair.pubkey(),
)
} else {
loader_v4::deploy(&program_keypair.pubkey(), &authority_keypair.pubkey())
});
(program_keypair, instructions)
}

pub fn load_program_of_loader_v4(
bank_client: &mut BankClient,
bank_forks: &RwLock<BankForks>,
payer_keypair: &Keypair,
authority_keypair: &Keypair,
name: &str,
) -> (Arc<Bank>, Pubkey) {
let (program_keypair, instructions) = instructions_to_load_program_of_loader_v4(
bank_client,
payer_keypair,
authority_keypair,
name,
None,
None,
);
let signers: &[&[&Keypair]] = &[
&[payer_keypair, &program_keypair],
&[payer_keypair, &program_keypair, authority_keypair],
&[payer_keypair, authority_keypair],
];
for (index, instruction) in instructions.into_iter().enumerate() {
let message = Message::new(&[instruction], Some(&payer_keypair.pubkey()));
bank_client
.send_and_confirm_message(signers[index.min(signers.len() - 1)], message)
.unwrap();
}
let bank = bank_client
.advance_slot(1, bank_forks, &Pubkey::default())
.expect("Failed to advance the slot");
(bank, program_keypair.pubkey())
}

// Return an Instruction that invokes `program_id` with `data` and required
// a signature from `from_pubkey`.
pub fn create_invoke_instruction<T: Serialize>(
Expand Down

0 comments on commit b280978

Please sign in to comment.