Add CPI support for upgradeable loader (bp #14193) (#14335)

* Add CPI support for upgradeable loader (#14193)


(cherry picked from commit e8cc0bef6c)

* update crate version

* nudge

Co-authored-by: Jack May <jack@solana.com>
This commit is contained in:
mergify[bot]
2020-12-29 23:05:40 +00:00
committed by GitHub
parent ebfbe5ed8a
commit 403220a559
10 changed files with 203 additions and 19 deletions

View File

@@ -11,7 +11,9 @@ use solana_runtime::message_processor::MessageProcessor;
use solana_sdk::{
account::Account,
account_info::AccountInfo,
account_utils::StateMut,
bpf_loader_deprecated,
bpf_loader_upgradeable::{self, UpgradeableLoaderState},
entrypoint::{MAX_PERMITTED_DATA_INCREASE, SUCCESS},
feature_set::{
pubkey_log_syscall_enabled, ristretto_mul_syscall_enabled, sha256_syscall_enabled,
@@ -1190,7 +1192,7 @@ fn call<'a>(
.get_callers_keyed_accounts()
.iter()
.collect::<Vec<&KeyedAccount>>();
let (message, callee_program_id, callee_program_id_index) =
let (message, callee_program_id) =
MessageProcessor::create_message(&instruction, &keyed_account_refs, &signers)
.map_err(SyscallError::InstructionError)?;
let (accounts, account_refs) = syscall.translate_accounts(
@@ -1204,17 +1206,40 @@ fn call<'a>(
// Process instruction
invoke_context.record_instruction(&instruction);
let program_account =
(**accounts
.get(callee_program_id_index)
invoke_context
.get_account(&callee_program_id)
.ok_or(SyscallError::InstructionError(
InstructionError::MissingAccount,
))?)
.clone();
if !program_account.borrow().executable {
))?;
if !program_account.executable {
return Err(SyscallError::InstructionError(InstructionError::AccountNotExecutable).into());
}
let executable_accounts = vec![(callee_program_id, program_account)];
let programdata_executable = if program_account.owner == bpf_loader_upgradeable::id() {
if let UpgradeableLoaderState::Program {
programdata_address,
} = program_account
.state()
.map_err(SyscallError::InstructionError)?
{
if let Some(account) = invoke_context.get_account(&programdata_address) {
Some((programdata_address, RefCell::new(account)))
} else {
return Err(
SyscallError::InstructionError(InstructionError::MissingAccount).into(),
);
}
} else {
return Err(SyscallError::InstructionError(InstructionError::MissingAccount).into());
}
} else {
None
};
let mut executable_accounts = vec![(callee_program_id, RefCell::new(program_account))];
if let Some(programdata) = programdata_executable {
executable_accounts.push(programdata);
}
#[allow(clippy::deref_addrof)]
match MessageProcessor::process_cross_program_instruction(