(cherry picked from commit e57b9c3b02
)
Co-authored-by: Jack May <jack@solana.com>
This commit is contained in:
@ -128,12 +128,10 @@ fn load_upgradeable_bpf_program(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn upgrade_bpf_program(
|
fn load_upgradeable_buffer(
|
||||||
bank_client: &BankClient,
|
bank_client: &BankClient,
|
||||||
payer_keypair: &Keypair,
|
payer_keypair: &Keypair,
|
||||||
buffer_keypair: &Keypair,
|
buffer_keypair: &Keypair,
|
||||||
executable_pubkey: &Pubkey,
|
|
||||||
authority_keypair: &Keypair,
|
|
||||||
name: &str,
|
name: &str,
|
||||||
) {
|
) {
|
||||||
let path = create_bpf_path(name);
|
let path = create_bpf_path(name);
|
||||||
@ -143,6 +141,17 @@ fn upgrade_bpf_program(
|
|||||||
let mut elf = Vec::new();
|
let mut elf = Vec::new();
|
||||||
file.read_to_end(&mut elf).unwrap();
|
file.read_to_end(&mut elf).unwrap();
|
||||||
load_buffer_account(bank_client, payer_keypair, &buffer_keypair, &elf);
|
load_buffer_account(bank_client, payer_keypair, &buffer_keypair, &elf);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn upgrade_bpf_program(
|
||||||
|
bank_client: &BankClient,
|
||||||
|
payer_keypair: &Keypair,
|
||||||
|
buffer_keypair: &Keypair,
|
||||||
|
executable_pubkey: &Pubkey,
|
||||||
|
authority_keypair: &Keypair,
|
||||||
|
name: &str,
|
||||||
|
) {
|
||||||
|
load_upgradeable_buffer(bank_client, payer_keypair, buffer_keypair, name);
|
||||||
upgrade_program(
|
upgrade_program(
|
||||||
bank_client,
|
bank_client,
|
||||||
payer_keypair,
|
payer_keypair,
|
||||||
@ -1605,6 +1614,81 @@ fn test_program_bpf_upgrade() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "bpf_rust")]
|
||||||
|
#[test]
|
||||||
|
fn test_program_bpf_upgrade_and_invoke_in_same_tx() {
|
||||||
|
solana_logger::setup();
|
||||||
|
|
||||||
|
let GenesisConfigInfo {
|
||||||
|
genesis_config,
|
||||||
|
mint_keypair,
|
||||||
|
..
|
||||||
|
} = create_genesis_config(50);
|
||||||
|
let mut bank = Bank::new(&genesis_config);
|
||||||
|
let (name, id, entrypoint) = solana_bpf_loader_upgradeable_program!();
|
||||||
|
bank.add_builtin(&name, id, entrypoint);
|
||||||
|
let bank = Arc::new(bank);
|
||||||
|
let bank_client = BankClient::new_shared(&bank);
|
||||||
|
|
||||||
|
// Deploy upgrade program
|
||||||
|
let buffer_keypair = Keypair::new();
|
||||||
|
let program_keypair = Keypair::new();
|
||||||
|
let program_id = program_keypair.pubkey();
|
||||||
|
let authority_keypair = Keypair::new();
|
||||||
|
load_upgradeable_bpf_program(
|
||||||
|
&bank_client,
|
||||||
|
&mint_keypair,
|
||||||
|
&buffer_keypair,
|
||||||
|
&program_keypair,
|
||||||
|
&authority_keypair,
|
||||||
|
"noop",
|
||||||
|
);
|
||||||
|
|
||||||
|
let invoke_instruction = Instruction::new(
|
||||||
|
program_id,
|
||||||
|
&[0],
|
||||||
|
vec![
|
||||||
|
AccountMeta::new(program_id.clone(), false),
|
||||||
|
AccountMeta::new(clock::id(), false),
|
||||||
|
AccountMeta::new(fees::id(), false),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
// Call upgradeable program
|
||||||
|
let result =
|
||||||
|
bank_client.send_and_confirm_instruction(&mint_keypair, invoke_instruction.clone());
|
||||||
|
assert!(result.is_ok());
|
||||||
|
|
||||||
|
// Prepare for upgrade
|
||||||
|
let buffer_keypair = Keypair::new();
|
||||||
|
load_upgradeable_buffer(&bank_client, &mint_keypair, &buffer_keypair, "panic");
|
||||||
|
|
||||||
|
// Invoke, then upgrade the program, and then invoke again in same tx
|
||||||
|
let message = Message::new(
|
||||||
|
&[
|
||||||
|
invoke_instruction.clone(),
|
||||||
|
bpf_loader_upgradeable::upgrade(
|
||||||
|
&program_id,
|
||||||
|
&buffer_keypair.pubkey(),
|
||||||
|
&authority_keypair.pubkey(),
|
||||||
|
&mint_keypair.pubkey(),
|
||||||
|
),
|
||||||
|
invoke_instruction,
|
||||||
|
],
|
||||||
|
Some(&mint_keypair.pubkey()),
|
||||||
|
);
|
||||||
|
let tx = Transaction::new(
|
||||||
|
&[&mint_keypair, &authority_keypair],
|
||||||
|
message.clone(),
|
||||||
|
bank.last_blockhash(),
|
||||||
|
);
|
||||||
|
let (result, _) = process_transaction_and_record_inner(&bank, tx);
|
||||||
|
assert_eq!(
|
||||||
|
result.unwrap_err(),
|
||||||
|
TransactionError::InstructionError(2, InstructionError::ProgramFailedToComplete)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bpf_rust")]
|
#[cfg(feature = "bpf_rust")]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_program_bpf_invoke_upgradeable_via_cpi() {
|
fn test_program_bpf_invoke_upgradeable_via_cpi() {
|
||||||
@ -1843,6 +1927,86 @@ fn test_program_bpf_upgrade_via_cpi() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "bpf_rust")]
|
||||||
|
#[test]
|
||||||
|
fn test_program_bpf_upgrade_self_via_cpi() {
|
||||||
|
solana_logger::setup();
|
||||||
|
|
||||||
|
let GenesisConfigInfo {
|
||||||
|
genesis_config,
|
||||||
|
mint_keypair,
|
||||||
|
..
|
||||||
|
} = create_genesis_config(50);
|
||||||
|
let mut bank = Bank::new(&genesis_config);
|
||||||
|
let (name, id, entrypoint) = solana_bpf_loader_program!();
|
||||||
|
bank.add_builtin(&name, id, entrypoint);
|
||||||
|
let (name, id, entrypoint) = solana_bpf_loader_upgradeable_program!();
|
||||||
|
bank.add_builtin(&name, id, entrypoint);
|
||||||
|
let bank = Arc::new(bank);
|
||||||
|
let bank_client = BankClient::new_shared(&bank);
|
||||||
|
let noop_program_id = load_bpf_program(&bank_client, &bpf_loader::id(), &mint_keypair, "noop");
|
||||||
|
|
||||||
|
// Deploy upgradeable program
|
||||||
|
let buffer_keypair = Keypair::new();
|
||||||
|
let program_keypair = Keypair::new();
|
||||||
|
let program_id = program_keypair.pubkey();
|
||||||
|
let authority_keypair = Keypair::new();
|
||||||
|
load_upgradeable_bpf_program(
|
||||||
|
&bank_client,
|
||||||
|
&mint_keypair,
|
||||||
|
&buffer_keypair,
|
||||||
|
&program_keypair,
|
||||||
|
&authority_keypair,
|
||||||
|
"solana_bpf_rust_invoke_and_return",
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut invoke_instruction = Instruction::new(
|
||||||
|
program_id,
|
||||||
|
&[0],
|
||||||
|
vec![
|
||||||
|
AccountMeta::new(noop_program_id, false),
|
||||||
|
AccountMeta::new(noop_program_id, false),
|
||||||
|
AccountMeta::new(clock::id(), false),
|
||||||
|
AccountMeta::new(fees::id(), false),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
// Call the upgraded program
|
||||||
|
invoke_instruction.data[0] += 1;
|
||||||
|
let result =
|
||||||
|
bank_client.send_and_confirm_instruction(&mint_keypair, invoke_instruction.clone());
|
||||||
|
assert!(result.is_ok());
|
||||||
|
|
||||||
|
// Prepare for upgrade
|
||||||
|
let buffer_keypair = Keypair::new();
|
||||||
|
load_upgradeable_buffer(&bank_client, &mint_keypair, &buffer_keypair, "panic");
|
||||||
|
|
||||||
|
// Invoke, then upgrade the program, and then invoke again in same tx
|
||||||
|
let message = Message::new(
|
||||||
|
&[
|
||||||
|
invoke_instruction.clone(),
|
||||||
|
bpf_loader_upgradeable::upgrade(
|
||||||
|
&program_id,
|
||||||
|
&buffer_keypair.pubkey(),
|
||||||
|
&authority_keypair.pubkey(),
|
||||||
|
&mint_keypair.pubkey(),
|
||||||
|
),
|
||||||
|
invoke_instruction,
|
||||||
|
],
|
||||||
|
Some(&mint_keypair.pubkey()),
|
||||||
|
);
|
||||||
|
let tx = Transaction::new(
|
||||||
|
&[&mint_keypair, &authority_keypair],
|
||||||
|
message.clone(),
|
||||||
|
bank.last_blockhash(),
|
||||||
|
);
|
||||||
|
let (result, _) = process_transaction_and_record_inner(&bank, tx);
|
||||||
|
assert_eq!(
|
||||||
|
result.unwrap_err(),
|
||||||
|
TransactionError::InstructionError(2, InstructionError::ProgramFailedToComplete)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bpf_rust")]
|
#[cfg(feature = "bpf_rust")]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_program_upgradeable_locks() {
|
fn test_program_upgradeable_locks() {
|
||||||
|
Reference in New Issue
Block a user