Charge compute budget for bytes passed via cpi (#15874)
This commit is contained in:
		@@ -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