* Gate cpi program account passing (#14443)
(cherry picked from commit a8b5a32b50
)
# Conflicts:
# sdk/src/feature_set.rs
* resolve conflicts
Co-authored-by: Jack May <jack@solana.com>
This commit is contained in:
@ -18,7 +18,7 @@ use solana_sdk::{
|
|||||||
feature_set::{
|
feature_set::{
|
||||||
limit_cpi_loader_invoke, pubkey_log_syscall_enabled, ristretto_mul_syscall_enabled,
|
limit_cpi_loader_invoke, pubkey_log_syscall_enabled, ristretto_mul_syscall_enabled,
|
||||||
sha256_syscall_enabled, sol_log_compute_units_syscall,
|
sha256_syscall_enabled, sol_log_compute_units_syscall,
|
||||||
try_find_program_address_syscall_enabled,
|
try_find_program_address_syscall_enabled, use_loaded_program_accounts,
|
||||||
},
|
},
|
||||||
hash::{Hasher, HASH_BYTES},
|
hash::{Hasher, HASH_BYTES},
|
||||||
instruction::{AccountMeta, Instruction, InstructionError},
|
instruction::{AccountMeta, Instruction, InstructionError},
|
||||||
@ -739,6 +739,7 @@ trait SyscallInvokeSigned<'a> {
|
|||||||
) -> Result<Instruction, EbpfError<BPFError>>;
|
) -> Result<Instruction, EbpfError<BPFError>>;
|
||||||
fn translate_accounts(
|
fn translate_accounts(
|
||||||
&self,
|
&self,
|
||||||
|
skip_program: bool,
|
||||||
account_keys: &[Pubkey],
|
account_keys: &[Pubkey],
|
||||||
program_account_index: usize,
|
program_account_index: usize,
|
||||||
account_infos_addr: u64,
|
account_infos_addr: u64,
|
||||||
@ -804,6 +805,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
|
|||||||
|
|
||||||
fn translate_accounts(
|
fn translate_accounts(
|
||||||
&self,
|
&self,
|
||||||
|
skip_program: bool,
|
||||||
account_keys: &[Pubkey],
|
account_keys: &[Pubkey],
|
||||||
program_account_index: usize,
|
program_account_index: usize,
|
||||||
account_infos_addr: u64,
|
account_infos_addr: u64,
|
||||||
@ -826,7 +828,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
|
|||||||
let mut accounts = Vec::with_capacity(account_keys.len());
|
let mut accounts = Vec::with_capacity(account_keys.len());
|
||||||
let mut refs = Vec::with_capacity(account_keys.len());
|
let mut refs = Vec::with_capacity(account_keys.len());
|
||||||
'root: for (i, account_key) in account_keys.iter().enumerate() {
|
'root: for (i, account_key) in account_keys.iter().enumerate() {
|
||||||
if i == program_account_index {
|
if skip_program && i == program_account_index {
|
||||||
// Don't look for caller passed executable, runtime already has it
|
// Don't look for caller passed executable, runtime already has it
|
||||||
continue 'root;
|
continue 'root;
|
||||||
}
|
}
|
||||||
@ -1103,6 +1105,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
|
|||||||
|
|
||||||
fn translate_accounts(
|
fn translate_accounts(
|
||||||
&self,
|
&self,
|
||||||
|
skip_program: bool,
|
||||||
account_keys: &[Pubkey],
|
account_keys: &[Pubkey],
|
||||||
program_account_index: usize,
|
program_account_index: usize,
|
||||||
account_infos_addr: u64,
|
account_infos_addr: u64,
|
||||||
@ -1120,7 +1123,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
|
|||||||
let mut accounts = Vec::with_capacity(account_keys.len());
|
let mut accounts = Vec::with_capacity(account_keys.len());
|
||||||
let mut refs = Vec::with_capacity(account_keys.len());
|
let mut refs = Vec::with_capacity(account_keys.len());
|
||||||
'root: for (i, account_key) in account_keys.iter().enumerate() {
|
'root: for (i, account_key) in account_keys.iter().enumerate() {
|
||||||
if i == program_account_index {
|
if skip_program && i == program_account_index {
|
||||||
// Don't look for caller passed executable, runtime already has it
|
// Don't look for caller passed executable, runtime already has it
|
||||||
continue 'root;
|
continue 'root;
|
||||||
}
|
}
|
||||||
@ -1306,6 +1309,9 @@ fn call<'a>(
|
|||||||
.get_compute_meter()
|
.get_compute_meter()
|
||||||
.consume(invoke_context.get_bpf_compute_budget().invoke_units)?;
|
.consume(invoke_context.get_bpf_compute_budget().invoke_units)?;
|
||||||
|
|
||||||
|
let use_loaded_program_accounts =
|
||||||
|
invoke_context.is_feature_active(&use_loaded_program_accounts::id());
|
||||||
|
|
||||||
// Translate and verify caller's data
|
// Translate and verify caller's data
|
||||||
|
|
||||||
let instruction = syscall.translate_instruction(
|
let instruction = syscall.translate_instruction(
|
||||||
@ -1328,15 +1334,16 @@ fn call<'a>(
|
|||||||
.get_callers_keyed_accounts()
|
.get_callers_keyed_accounts()
|
||||||
.iter()
|
.iter()
|
||||||
.collect::<Vec<&KeyedAccount>>();
|
.collect::<Vec<&KeyedAccount>>();
|
||||||
let (message, callee_program_id, program_id_index) =
|
let (message, callee_program_id, callee_program_id_index) =
|
||||||
MessageProcessor::create_message(&instruction, &keyed_account_refs, &signers)
|
MessageProcessor::create_message(&instruction, &keyed_account_refs, &signers)
|
||||||
.map_err(SyscallError::InstructionError)?;
|
.map_err(SyscallError::InstructionError)?;
|
||||||
if invoke_context.is_feature_active(&limit_cpi_loader_invoke::id()) {
|
if invoke_context.is_feature_active(&limit_cpi_loader_invoke::id()) {
|
||||||
check_authorized_program(&callee_program_id, &instruction.data)?;
|
check_authorized_program(&callee_program_id, &instruction.data)?;
|
||||||
}
|
}
|
||||||
let (mut accounts, mut account_refs) = syscall.translate_accounts(
|
let (mut accounts, mut account_refs) = syscall.translate_accounts(
|
||||||
|
use_loaded_program_accounts,
|
||||||
&message.account_keys,
|
&message.account_keys,
|
||||||
program_id_index,
|
callee_program_id_index,
|
||||||
account_infos_addr,
|
account_infos_addr,
|
||||||
account_infos_len as usize,
|
account_infos_len as usize,
|
||||||
ro_regions,
|
ro_regions,
|
||||||
@ -1347,12 +1354,21 @@ fn call<'a>(
|
|||||||
|
|
||||||
invoke_context.record_instruction(&instruction);
|
invoke_context.record_instruction(&instruction);
|
||||||
|
|
||||||
let program_account =
|
let program_account = if use_loaded_program_accounts {
|
||||||
invoke_context
|
let program_account = invoke_context.get_account(&callee_program_id).ok_or(
|
||||||
.get_account(&callee_program_id)
|
SyscallError::InstructionError(InstructionError::MissingAccount),
|
||||||
|
)?;
|
||||||
|
accounts.insert(callee_program_id_index, Rc::new(program_account.clone()));
|
||||||
|
account_refs.insert(callee_program_id_index, None);
|
||||||
|
program_account
|
||||||
|
} else {
|
||||||
|
(**accounts
|
||||||
|
.get(callee_program_id_index)
|
||||||
.ok_or(SyscallError::InstructionError(
|
.ok_or(SyscallError::InstructionError(
|
||||||
InstructionError::MissingAccount,
|
InstructionError::MissingAccount,
|
||||||
))?;
|
))?)
|
||||||
|
.clone()
|
||||||
|
};
|
||||||
if !program_account.borrow().executable {
|
if !program_account.borrow().executable {
|
||||||
return Err(SyscallError::InstructionError(InstructionError::AccountNotExecutable).into());
|
return Err(SyscallError::InstructionError(InstructionError::AccountNotExecutable).into());
|
||||||
}
|
}
|
||||||
@ -1377,8 +1393,6 @@ fn call<'a>(
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
accounts.insert(program_id_index, Rc::new(program_account.clone()));
|
|
||||||
account_refs.insert(program_id_index, None);
|
|
||||||
let mut executable_accounts = vec![(callee_program_id, program_account)];
|
let mut executable_accounts = vec![(callee_program_id, program_account)];
|
||||||
if let Some(programdata) = programdata_executable {
|
if let Some(programdata) = programdata_executable {
|
||||||
executable_accounts.push(programdata);
|
executable_accounts.push(programdata);
|
||||||
|
@ -546,7 +546,7 @@ impl MessageProcessor {
|
|||||||
let _ = keyed_accounts
|
let _ = keyed_accounts
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|keyed_account| {
|
.find_map(|keyed_account| {
|
||||||
if &instruction.program_id == keyed_account.unsigned_key() {
|
if &program_id == keyed_account.unsigned_key() {
|
||||||
Some(keyed_account)
|
Some(keyed_account)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -122,6 +122,10 @@ pub mod try_find_program_address_syscall_enabled {
|
|||||||
solana_sdk::declare_id!("EMsMNadQNhCYDyGpYH5Tx6dGHxiUqKHk782PU5XaWfmi");
|
solana_sdk::declare_id!("EMsMNadQNhCYDyGpYH5Tx6dGHxiUqKHk782PU5XaWfmi");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod use_loaded_program_accounts {
|
||||||
|
solana_sdk::declare_id!("FLjgLeg1PJkZimQCVa5sVFtaq6VmSDPw3NvH8iQ3nyHn");
|
||||||
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// Map of feature identifiers to user-visible description
|
/// Map of feature identifiers to user-visible description
|
||||||
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
|
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
|
||||||
@ -154,6 +158,7 @@ lazy_static! {
|
|||||||
(max_cpi_instruction_size_ipv6_mtu::id(), "Max cross-program invocation size 1280"),
|
(max_cpi_instruction_size_ipv6_mtu::id(), "Max cross-program invocation size 1280"),
|
||||||
(limit_cpi_loader_invoke::id(), "Loader not authorized via CPI"),
|
(limit_cpi_loader_invoke::id(), "Loader not authorized via CPI"),
|
||||||
(try_find_program_address_syscall_enabled::id(), "add try_find_program_address syscall"),
|
(try_find_program_address_syscall_enabled::id(), "add try_find_program_address syscall"),
|
||||||
|
(use_loaded_program_accounts::id(), "Use loaded program accounts"),
|
||||||
/*************** ADD NEW FEATURES HERE ***************/
|
/*************** ADD NEW FEATURES HERE ***************/
|
||||||
]
|
]
|
||||||
.iter()
|
.iter()
|
||||||
|
Reference in New Issue
Block a user