Charge compute budget for bytes passed via cpi (#15874)
This commit is contained in:
@ -1110,6 +1110,7 @@ mod tests {
|
||||
stack_frame_size: 4096,
|
||||
log_pubkey_units: 100,
|
||||
max_cpi_instruction_size: usize::MAX,
|
||||
cpi_bytes_per_unit: 250,
|
||||
},
|
||||
Rc::new(RefCell::new(Executors::default())),
|
||||
None,
|
||||
|
@ -16,7 +16,7 @@ use solana_sdk::{
|
||||
bpf_loader, bpf_loader_deprecated,
|
||||
bpf_loader_upgradeable::{self, UpgradeableLoaderState},
|
||||
entrypoint::{MAX_PERMITTED_DATA_INCREASE, SUCCESS},
|
||||
feature_set::{cpi_share_ro_and_exec_accounts, ristretto_mul_syscall_enabled},
|
||||
feature_set::{cpi_data_cost, cpi_share_ro_and_exec_accounts, ristretto_mul_syscall_enabled},
|
||||
hash::{Hasher, HASH_BYTES},
|
||||
ic_msg,
|
||||
instruction::{AccountMeta, Instruction, InstructionError},
|
||||
@ -957,7 +957,8 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
|
||||
})
|
||||
.collect::<Result<Vec<_>, EbpfError<BpfError>>>()?;
|
||||
|
||||
let translate = |account_info: &AccountInfo| {
|
||||
let translate = |account_info: &AccountInfo,
|
||||
invoke_context: &Ref<&mut dyn InvokeContext>| {
|
||||
// Translate the account from user space
|
||||
|
||||
let lamports = {
|
||||
@ -974,6 +975,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
|
||||
account_info.owner as *const _ as u64,
|
||||
self.loader_id,
|
||||
)?;
|
||||
|
||||
let (data, vm_data_addr, ref_to_len_in_vm, serialized_len_ptr) = {
|
||||
// Double translate data out of RefCell
|
||||
let data = *translate_type::<&[u8]>(
|
||||
@ -981,6 +983,14 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
|
||||
account_info.data.as_ptr() as *const _ as u64,
|
||||
self.loader_id,
|
||||
)?;
|
||||
|
||||
if invoke_context.is_feature_active(&cpi_data_cost::id()) {
|
||||
invoke_context.get_compute_meter().consume(
|
||||
data.len() as u64
|
||||
/ invoke_context.get_bpf_compute_budget().cpi_bytes_per_unit,
|
||||
)?;
|
||||
}
|
||||
|
||||
let translated = translate(
|
||||
memory_mapping,
|
||||
AccessType::Store,
|
||||
@ -1253,7 +1263,8 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
|
||||
})
|
||||
.collect::<Result<Vec<_>, EbpfError<BpfError>>>()?;
|
||||
|
||||
let translate = |account_info: &SolAccountInfo| {
|
||||
let translate = |account_info: &SolAccountInfo,
|
||||
invoke_context: &Ref<&mut dyn InvokeContext>| {
|
||||
// Translate the account from user space
|
||||
|
||||
let lamports = translate_type_mut::<u64>(
|
||||
@ -1267,6 +1278,14 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
|
||||
self.loader_id,
|
||||
)?;
|
||||
let vm_data_addr = account_info.data_addr;
|
||||
|
||||
if invoke_context.is_feature_active(&cpi_data_cost::id()) {
|
||||
invoke_context.get_compute_meter().consume(
|
||||
account_info.data_len
|
||||
/ invoke_context.get_bpf_compute_budget().cpi_bytes_per_unit,
|
||||
)?;
|
||||
}
|
||||
|
||||
let data = translate_slice_mut::<u8>(
|
||||
memory_mapping,
|
||||
vm_data_addr,
|
||||
@ -1408,7 +1427,7 @@ fn get_translated_accounts<'a, T, F>(
|
||||
do_translate: F,
|
||||
) -> Result<TranslatedAccounts<'a>, EbpfError<BpfError>>
|
||||
where
|
||||
F: Fn(&T) -> Result<TranslatedAccount<'a>, EbpfError<BpfError>>,
|
||||
F: Fn(&T, &Ref<&mut dyn InvokeContext>) -> Result<TranslatedAccount<'a>, EbpfError<BpfError>>,
|
||||
{
|
||||
let mut accounts = Vec::with_capacity(account_keys.len());
|
||||
let mut refs = Vec::with_capacity(account_keys.len());
|
||||
@ -1442,7 +1461,7 @@ where
|
||||
}
|
||||
})
|
||||
{
|
||||
let (account, account_ref) = do_translate(account_info)?;
|
||||
let (account, account_ref) = do_translate(account_info, invoke_context)?;
|
||||
accounts.push(account);
|
||||
refs.push(account_ref);
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user