Upgradeable programs needs program account's address as program id (#14417)
This commit is contained in:
@ -2,16 +2,24 @@
|
|||||||
|
|
||||||
extern crate solana_program;
|
extern crate solana_program;
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, msg, pubkey::Pubkey,
|
account_info::AccountInfo,
|
||||||
|
entrypoint,
|
||||||
|
entrypoint::ProgramResult,
|
||||||
|
msg,
|
||||||
|
pubkey::Pubkey,
|
||||||
|
sysvar::{clock, fees},
|
||||||
};
|
};
|
||||||
|
|
||||||
entrypoint!(process_instruction);
|
entrypoint!(process_instruction);
|
||||||
fn process_instruction(
|
fn process_instruction(
|
||||||
_program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
_instruction_data: &[u8],
|
_instruction_data: &[u8],
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
msg!("Upgradeable program");
|
msg!("Upgradeable program");
|
||||||
assert_eq!(accounts.len(), 2);
|
assert_eq!(accounts.len(), 3);
|
||||||
|
assert_eq!(accounts[0].key, program_id);
|
||||||
|
assert_eq!(*accounts[1].key, clock::id());
|
||||||
|
assert_eq!(*accounts[2].key, fees::id());
|
||||||
Err(42.into())
|
Err(42.into())
|
||||||
}
|
}
|
||||||
|
@ -2,16 +2,24 @@
|
|||||||
|
|
||||||
extern crate solana_program;
|
extern crate solana_program;
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, msg, pubkey::Pubkey,
|
account_info::AccountInfo,
|
||||||
|
entrypoint,
|
||||||
|
entrypoint::ProgramResult,
|
||||||
|
msg,
|
||||||
|
pubkey::Pubkey,
|
||||||
|
sysvar::{clock, fees},
|
||||||
};
|
};
|
||||||
|
|
||||||
entrypoint!(process_instruction);
|
entrypoint!(process_instruction);
|
||||||
fn process_instruction(
|
fn process_instruction(
|
||||||
_program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
_instruction_data: &[u8],
|
_instruction_data: &[u8],
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
msg!("Upgraded program");
|
msg!("Upgraded program");
|
||||||
assert_eq!(accounts.len(), 2);
|
assert_eq!(accounts.len(), 3);
|
||||||
|
assert_eq!(accounts[0].key, program_id);
|
||||||
|
assert_eq!(*accounts[1].key, clock::id());
|
||||||
|
assert_eq!(*accounts[2].key, fees::id());
|
||||||
Err(43.into())
|
Err(43.into())
|
||||||
}
|
}
|
||||||
|
@ -1533,7 +1533,6 @@ fn test_program_bpf_test_use_latest_executor2() {
|
|||||||
fn test_program_bpf_upgrade() {
|
fn test_program_bpf_upgrade() {
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
||||||
|
|
||||||
let mut nonce = 0;
|
|
||||||
let GenesisConfigInfo {
|
let GenesisConfigInfo {
|
||||||
genesis_config,
|
genesis_config,
|
||||||
mint_keypair,
|
mint_keypair,
|
||||||
@ -1548,17 +1547,18 @@ fn test_program_bpf_upgrade() {
|
|||||||
let (program_id, authority_keypair) =
|
let (program_id, authority_keypair) =
|
||||||
load_upgradeable_bpf_program(&bank_client, &mint_keypair, "solana_bpf_rust_upgradeable");
|
load_upgradeable_bpf_program(&bank_client, &mint_keypair, "solana_bpf_rust_upgradeable");
|
||||||
|
|
||||||
// Call upgrade program
|
let mut instruction = Instruction::new(
|
||||||
nonce += 1;
|
|
||||||
let instruction = Instruction::new(
|
|
||||||
program_id,
|
program_id,
|
||||||
&[nonce],
|
&[0],
|
||||||
vec![
|
vec![
|
||||||
|
AccountMeta::new(program_id.clone(), false),
|
||||||
AccountMeta::new(clock::id(), false),
|
AccountMeta::new(clock::id(), false),
|
||||||
AccountMeta::new(fees::id(), false),
|
AccountMeta::new(fees::id(), false),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction);
|
|
||||||
|
// Call upgrade program
|
||||||
|
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction.clone());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result.unwrap_err().unwrap(),
|
result.unwrap_err().unwrap(),
|
||||||
TransactionError::InstructionError(0, InstructionError::Custom(42))
|
TransactionError::InstructionError(0, InstructionError::Custom(42))
|
||||||
@ -1574,16 +1574,8 @@ fn test_program_bpf_upgrade() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Call upgraded program
|
// Call upgraded program
|
||||||
nonce += 1;
|
instruction.data[0] += 1;
|
||||||
let instruction = Instruction::new(
|
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction.clone());
|
||||||
program_id,
|
|
||||||
&[nonce],
|
|
||||||
vec![
|
|
||||||
AccountMeta::new(clock::id(), false),
|
|
||||||
AccountMeta::new(fees::id(), false),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result.unwrap_err().unwrap(),
|
result.unwrap_err().unwrap(),
|
||||||
TransactionError::InstructionError(0, InstructionError::Custom(43))
|
TransactionError::InstructionError(0, InstructionError::Custom(43))
|
||||||
@ -1609,15 +1601,7 @@ fn test_program_bpf_upgrade() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Call original program
|
// Call original program
|
||||||
nonce += 1;
|
instruction.data[0] += 1;
|
||||||
let instruction = Instruction::new(
|
|
||||||
program_id,
|
|
||||||
&[nonce],
|
|
||||||
vec![
|
|
||||||
AccountMeta::new(clock::id(), false),
|
|
||||||
AccountMeta::new(fees::id(), false),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction);
|
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result.unwrap_err().unwrap(),
|
result.unwrap_err().unwrap(),
|
||||||
@ -1630,7 +1614,6 @@ fn test_program_bpf_upgrade() {
|
|||||||
fn test_program_bpf_invoke_upgradeable_via_cpi() {
|
fn test_program_bpf_invoke_upgradeable_via_cpi() {
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
||||||
|
|
||||||
let mut nonce = 0;
|
|
||||||
let GenesisConfigInfo {
|
let GenesisConfigInfo {
|
||||||
genesis_config,
|
genesis_config,
|
||||||
mint_keypair,
|
mint_keypair,
|
||||||
@ -1653,18 +1636,20 @@ fn test_program_bpf_invoke_upgradeable_via_cpi() {
|
|||||||
let (program_id, authority_keypair) =
|
let (program_id, authority_keypair) =
|
||||||
load_upgradeable_bpf_program(&bank_client, &mint_keypair, "solana_bpf_rust_upgradeable");
|
load_upgradeable_bpf_program(&bank_client, &mint_keypair, "solana_bpf_rust_upgradeable");
|
||||||
|
|
||||||
// Call invoker program to invoke the upgradeable program
|
let mut instruction = Instruction::new(
|
||||||
nonce += 1;
|
|
||||||
let instruction = Instruction::new(
|
|
||||||
invoke_and_return,
|
invoke_and_return,
|
||||||
&[nonce],
|
&[0],
|
||||||
vec![
|
vec![
|
||||||
|
AccountMeta::new(program_id, false),
|
||||||
AccountMeta::new(program_id, false),
|
AccountMeta::new(program_id, false),
|
||||||
AccountMeta::new(clock::id(), false),
|
AccountMeta::new(clock::id(), false),
|
||||||
AccountMeta::new(fees::id(), false),
|
AccountMeta::new(fees::id(), false),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction);
|
|
||||||
|
// Call invoker program to invoke the upgradeable program
|
||||||
|
instruction.data[0] += 1;
|
||||||
|
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction.clone());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result.unwrap_err().unwrap(),
|
result.unwrap_err().unwrap(),
|
||||||
TransactionError::InstructionError(0, InstructionError::Custom(42))
|
TransactionError::InstructionError(0, InstructionError::Custom(42))
|
||||||
@ -1680,17 +1665,8 @@ fn test_program_bpf_invoke_upgradeable_via_cpi() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Call the upgraded program
|
// Call the upgraded program
|
||||||
nonce += 1;
|
instruction.data[0] += 1;
|
||||||
let instruction = Instruction::new(
|
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction.clone());
|
||||||
invoke_and_return,
|
|
||||||
&[nonce],
|
|
||||||
vec![
|
|
||||||
AccountMeta::new(program_id, false),
|
|
||||||
AccountMeta::new(clock::id(), false),
|
|
||||||
AccountMeta::new(fees::id(), false),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result.unwrap_err().unwrap(),
|
result.unwrap_err().unwrap(),
|
||||||
TransactionError::InstructionError(0, InstructionError::Custom(43))
|
TransactionError::InstructionError(0, InstructionError::Custom(43))
|
||||||
@ -1716,17 +1692,8 @@ fn test_program_bpf_invoke_upgradeable_via_cpi() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Call original program
|
// Call original program
|
||||||
nonce += 1;
|
instruction.data[0] += 1;
|
||||||
let instruction = Instruction::new(
|
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction.clone());
|
||||||
invoke_and_return,
|
|
||||||
&[nonce],
|
|
||||||
vec![
|
|
||||||
AccountMeta::new(program_id, false),
|
|
||||||
AccountMeta::new(clock::id(), false),
|
|
||||||
AccountMeta::new(fees::id(), false),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result.unwrap_err().unwrap(),
|
result.unwrap_err().unwrap(),
|
||||||
TransactionError::InstructionError(0, InstructionError::Custom(42))
|
TransactionError::InstructionError(0, InstructionError::Custom(42))
|
||||||
|
@ -273,6 +273,7 @@ fn process_instruction_common(
|
|||||||
};
|
};
|
||||||
executor.execute(
|
executor.execute(
|
||||||
loader_id,
|
loader_id,
|
||||||
|
first_account.unsigned_key(),
|
||||||
keyed_accounts,
|
keyed_accounts,
|
||||||
instruction_data,
|
instruction_data,
|
||||||
invoke_context,
|
invoke_context,
|
||||||
@ -664,6 +665,7 @@ impl Executor for BPFExecutor {
|
|||||||
fn execute(
|
fn execute(
|
||||||
&self,
|
&self,
|
||||||
loader_id: &Pubkey,
|
loader_id: &Pubkey,
|
||||||
|
program_id: &Pubkey,
|
||||||
keyed_accounts: &[KeyedAccount],
|
keyed_accounts: &[KeyedAccount],
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut dyn InvokeContext,
|
||||||
@ -676,12 +678,8 @@ impl Executor for BPFExecutor {
|
|||||||
let program = next_keyed_account(&mut keyed_accounts_iter)?;
|
let program = next_keyed_account(&mut keyed_accounts_iter)?;
|
||||||
|
|
||||||
let parameter_accounts = keyed_accounts_iter.as_slice();
|
let parameter_accounts = keyed_accounts_iter.as_slice();
|
||||||
let mut parameter_bytes = serialize_parameters(
|
let mut parameter_bytes =
|
||||||
loader_id,
|
serialize_parameters(loader_id, program_id, parameter_accounts, &instruction_data)?;
|
||||||
program.unsigned_key(),
|
|
||||||
parameter_accounts,
|
|
||||||
&instruction_data,
|
|
||||||
)?;
|
|
||||||
{
|
{
|
||||||
let compute_meter = invoke_context.get_compute_meter();
|
let compute_meter = invoke_context.get_compute_meter();
|
||||||
let mut vm = match create_vm(
|
let mut vm = match create_vm(
|
||||||
|
@ -10640,6 +10640,7 @@ pub(crate) mod tests {
|
|||||||
impl Executor for TestExecutor {
|
impl Executor for TestExecutor {
|
||||||
fn execute(
|
fn execute(
|
||||||
&self,
|
&self,
|
||||||
|
_loader_id: &Pubkey,
|
||||||
_program_id: &Pubkey,
|
_program_id: &Pubkey,
|
||||||
_keyed_accounts: &[KeyedAccount],
|
_keyed_accounts: &[KeyedAccount],
|
||||||
_instruction_data: &[u8],
|
_instruction_data: &[u8],
|
||||||
|
@ -248,6 +248,7 @@ pub trait Executor: Debug + Send + Sync {
|
|||||||
/// Execute the program
|
/// Execute the program
|
||||||
fn execute(
|
fn execute(
|
||||||
&self,
|
&self,
|
||||||
|
loader_id: &Pubkey,
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
keyed_accounts: &[KeyedAccount],
|
keyed_accounts: &[KeyedAccount],
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
|
Reference in New Issue
Block a user