From b2809787501f44c7d93d435499fa22e480e1e5e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Tue, 27 Aug 2024 16:54:44 +0200 Subject: [PATCH] Adds instructions_to_load_program_of_loader_v4() and load_program_of_loader_v4(). Removes load_and_finalize_program() and load_program(). --- runtime/src/loader_utils.rs | 144 +++++++++++++++++++++--------------- 1 file changed, 86 insertions(+), 58 deletions(-) diff --git a/runtime/src/loader_utils.rs b/runtime/src/loader_utils.rs index 436a7242d93fd7..894784c9055b44 100644 --- a/runtime/src/loader_utils.rs +++ b/runtime/src/loader_utils.rs @@ -8,7 +8,7 @@ use { client::{Client, SyncClient}, clock::Clock, instruction::{AccountMeta, Instruction}, - loader_instruction, + loader_v4, message::Message, pubkey::Pubkey, signature::{Keypair, Signer}, @@ -65,63 +65,6 @@ pub fn create_program(bank: &Bank, loader_id: &Pubkey, name: &str) -> Pubkey { program_id } -pub fn load_and_finalize_program( - bank_client: &T, - loader_id: &Pubkey, - program_keypair: Option, - 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( - 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( bank_client: &T, from_keypair: &Keypair, @@ -313,6 +256,91 @@ pub fn set_upgrade_authority( .unwrap(); } +pub fn instructions_to_load_program_of_loader_v4( + bank_client: &T, + payer_keypair: &Keypair, + authority_keypair: &Keypair, + name: &str, + program_keypair: Option, + target_program_id: Option<&Pubkey>, +) -> (Keypair, Vec) { + 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, + payer_keypair: &Keypair, + authority_keypair: &Keypair, + name: &str, +) -> (Arc, 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(