Speed up program deploys by writing larger chunks (#19654)

This commit is contained in:
Justin Starry 2021-09-07 10:20:17 -07:00 committed by GitHub
parent 1560d5e3c3
commit 24fd47a32d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -40,9 +40,10 @@ use solana_sdk::{
loader_instruction, loader_instruction,
message::Message, message::Message,
native_token::Sol, native_token::Sol,
packet::PACKET_DATA_SIZE,
process_instruction::MockInvokeContext, process_instruction::MockInvokeContext,
pubkey::Pubkey, pubkey::Pubkey,
signature::{keypair_from_seed, read_keypair_file, Keypair, Signer}, signature::{keypair_from_seed, read_keypair_file, Keypair, Signature, Signer},
signers::Signers, signers::Signers,
system_instruction::{self, SystemError}, system_instruction::{self, SystemError},
system_program, system_program,
@ -63,8 +64,6 @@ use std::{
time::Duration, time::Duration,
}; };
const DATA_CHUNK_SIZE: usize = 229; // Keep program chunks under PACKET_DATA_SIZE
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum ProgramCliCommand { pub enum ProgramCliCommand {
Deploy { Deploy {
@ -1683,6 +1682,23 @@ pub fn process_deploy(
result result
} }
fn calculate_max_chunk_size<F>(create_msg: &F) -> usize
where
F: Fn(u32, Vec<u8>) -> Message,
{
let baseline_msg = create_msg(0, Vec::new());
let tx_size = bincode::serialized_size(&Transaction {
signatures: vec![
Signature::default();
baseline_msg.header.num_required_signatures as usize
],
message: baseline_msg,
})
.unwrap() as usize;
// add 1 byte buffer to account for shortvec encoding
PACKET_DATA_SIZE.saturating_sub(tx_size).saturating_sub(1)
}
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn do_process_program_write_and_deploy( fn do_process_program_write_and_deploy(
rpc_client: Arc<RpcClient>, rpc_client: Arc<RpcClient>,
@ -1755,25 +1771,25 @@ fn do_process_program_write_and_deploy(
// Create and add write messages // Create and add write messages
let mut write_messages = vec![]; let payer_pubkey = config.signers[0].pubkey();
for (chunk, i) in program_data.chunks(DATA_CHUNK_SIZE).zip(0..) { let create_msg = |offset: u32, bytes: Vec<u8>| {
let instruction = if loader_id == &bpf_loader_upgradeable::id() { let instruction = if loader_id == &bpf_loader_upgradeable::id() {
bpf_loader_upgradeable::write( bpf_loader_upgradeable::write(
buffer_pubkey, buffer_pubkey,
&buffer_authority_signer.pubkey(), &buffer_authority_signer.pubkey(),
(i * DATA_CHUNK_SIZE) as u32, offset,
chunk.to_vec(), bytes,
) )
} else { } else {
loader_instruction::write( loader_instruction::write(buffer_pubkey, loader_id, offset, bytes)
buffer_pubkey,
loader_id,
(i * DATA_CHUNK_SIZE) as u32,
chunk.to_vec(),
)
}; };
let message = Message::new(&[instruction], Some(&config.signers[0].pubkey())); Message::new(&[instruction], Some(&payer_pubkey))
write_messages.push(message); };
let mut write_messages = vec![];
let chunk_size = calculate_max_chunk_size(&create_msg);
for (chunk, i) in program_data.chunks(chunk_size).zip(0..) {
write_messages.push(create_msg((i * chunk_size) as u32, chunk.to_vec()));
} }
(initial_message, Some(write_messages), balance_needed) (initial_message, Some(write_messages), balance_needed)
@ -1905,17 +1921,24 @@ fn do_process_program_upgrade(
None None
}; };
let buffer_signer_pubkey = buffer_signer.pubkey();
let upgrade_authority_pubkey = upgrade_authority.pubkey();
let payer_pubkey = config.signers[0].pubkey();
let create_msg = |offset: u32, bytes: Vec<u8>| {
let instruction = bpf_loader_upgradeable::write(
&buffer_signer_pubkey,
&upgrade_authority_pubkey,
offset,
bytes,
);
Message::new(&[instruction], Some(&payer_pubkey))
};
// Create and add write messages // Create and add write messages
let mut write_messages = vec![]; let mut write_messages = vec![];
for (chunk, i) in program_data.chunks(DATA_CHUNK_SIZE).zip(0..) { let chunk_size = calculate_max_chunk_size(&create_msg);
let instruction = bpf_loader_upgradeable::write( for (chunk, i) in program_data.chunks(chunk_size).zip(0..) {
&buffer_signer.pubkey(), write_messages.push(create_msg((i * chunk_size) as u32, chunk.to_vec()));
&upgrade_authority.pubkey(),
(i * DATA_CHUNK_SIZE) as u32,
chunk.to_vec(),
);
let message = Message::new(&[instruction], Some(&config.signers[0].pubkey()));
write_messages.push(message);
} }
(initial_message, Some(write_messages), balance_needed) (initial_message, Some(write_messages), balance_needed)