From 2c38a9213ffe487d4bfbebb23ddb8a7b8d69994a Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Mon, 17 Jan 2022 17:43:17 +0800 Subject: [PATCH] Revert "Refactor: move compute budget runtime logic into solana-program-runtime (#22533)" (#22542) This reverts commit b27976626aa1367274a76621c1013939f44a5d94. --- program-runtime/src/compute_budget.rs | 292 -------------------------- program-runtime/src/invoke_context.rs | 2 +- program-runtime/src/lib.rs | 1 - program-test/src/lib.rs | 4 +- runtime/src/bank.rs | 2 +- runtime/src/message_processor.rs | 2 +- sdk/src/compute_budget.rs | 281 ++++++++++++++++++++++++- 7 files changed, 283 insertions(+), 301 deletions(-) delete mode 100644 program-runtime/src/compute_budget.rs diff --git a/program-runtime/src/compute_budget.rs b/program-runtime/src/compute_budget.rs deleted file mode 100644 index 45e46d732..000000000 --- a/program-runtime/src/compute_budget.rs +++ /dev/null @@ -1,292 +0,0 @@ -use { - solana_sdk::{ - borsh::try_from_slice_unchecked, - compute_budget::{self, ComputeBudgetInstruction}, - entrypoint::HEAP_LENGTH as MIN_HEAP_FRAME_BYTES, - feature_set::{requestable_heap_size, FeatureSet}, - instruction::InstructionError, - transaction::{SanitizedTransaction, TransactionError}, - }, - std::sync::Arc, -}; - -const MAX_UNITS: u32 = 1_000_000; -const MAX_HEAP_FRAME_BYTES: u32 = 256 * 1024; - -#[cfg(RUSTC_WITH_SPECIALIZATION)] -impl ::solana_frozen_abi::abi_example::AbiExample for ComputeBudget { - fn example() -> Self { - // ComputeBudget is not Serialize so just rely on Default. - ComputeBudget::default() - } -} - -#[derive(Clone, Copy, Debug, PartialEq)] -pub struct ComputeBudget { - /// Number of compute units that an instruction is allowed. Compute units - /// are consumed by program execution, resources they use, etc... - pub max_units: u64, - /// Number of compute units consumed by a log_u64 call - pub log_64_units: u64, - /// Number of compute units consumed by a create_program_address call - pub create_program_address_units: u64, - /// Number of compute units consumed by an invoke call (not including the cost incurred by - /// the called program) - pub invoke_units: u64, - /// Maximum cross-program invocation depth allowed - pub max_invoke_depth: usize, - /// Base number of compute units consumed to call SHA256 - pub sha256_base_cost: u64, - /// Incremental number of units consumed by SHA256 (based on bytes) - pub sha256_byte_cost: u64, - /// Maximum BPF to BPF call depth - pub max_call_depth: usize, - /// Size of a stack frame in bytes, must match the size specified in the LLVM BPF backend - pub stack_frame_size: usize, - /// Number of compute units consumed by logging a `Pubkey` - pub log_pubkey_units: u64, - /// Maximum cross-program invocation instruction size - pub max_cpi_instruction_size: usize, - /// Number of account data bytes per conpute unit charged during a cross-program invocation - pub cpi_bytes_per_unit: u64, - /// Base number of compute units consumed to get a sysvar - pub sysvar_base_cost: u64, - /// Number of compute units consumed to call secp256k1_recover - pub secp256k1_recover_cost: u64, - /// Number of compute units consumed to do a syscall without any work - pub syscall_base_cost: u64, - /// Number of compute units consumed to call zktoken_crypto_op - pub zk_token_elgamal_op_cost: u64, - /// Optional program heap region size, if `None` then loader default - pub heap_size: Option, - /// Number of compute units per additional 32k heap above the default (~.5 - /// us per 32k at 15 units/us rounded up) - pub heap_cost: u64, - /// Memory operation syscall base cost - pub mem_op_base_cost: u64, -} - -impl Default for ComputeBudget { - fn default() -> Self { - Self::new() - } -} - -impl ComputeBudget { - pub fn new() -> Self { - ComputeBudget { - max_units: 200_000, - log_64_units: 100, - create_program_address_units: 1500, - invoke_units: 1000, - max_invoke_depth: 4, - sha256_base_cost: 85, - sha256_byte_cost: 1, - max_call_depth: 64, - stack_frame_size: 4_096, - log_pubkey_units: 100, - max_cpi_instruction_size: 1280, // IPv6 Min MTU size - cpi_bytes_per_unit: 250, // ~50MB at 200,000 units - sysvar_base_cost: 100, - secp256k1_recover_cost: 25_000, - syscall_base_cost: 100, - zk_token_elgamal_op_cost: 25_000, - heap_size: None, - heap_cost: 8, - mem_op_base_cost: 15, - } - } - - pub fn process_transaction( - &mut self, - tx: &SanitizedTransaction, - feature_set: Arc, - ) -> Result<(), TransactionError> { - let error = TransactionError::InstructionError(0, InstructionError::InvalidInstructionData); - // Compute budget instruction must be in the 1st 3 instructions (avoid - // nonce marker), otherwise ignored - for (program_id, instruction) in tx.message().program_instructions_iter().take(3) { - if compute_budget::check_id(program_id) { - match try_from_slice_unchecked(&instruction.data) { - Ok(ComputeBudgetInstruction::RequestUnits(units)) => { - if units > MAX_UNITS { - return Err(error); - } - self.max_units = units as u64; - } - Ok(ComputeBudgetInstruction::RequestHeapFrame(bytes)) => { - if !feature_set.is_active(&requestable_heap_size::id()) - || bytes > MAX_HEAP_FRAME_BYTES - || bytes < MIN_HEAP_FRAME_BYTES as u32 - || bytes % 1024 != 0 - { - return Err(error); - } - self.heap_size = Some(bytes as usize); - } - _ => return Err(error), - } - } - } - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use { - super::*, - solana_sdk::{ - hash::Hash, instruction::Instruction, message::Message, pubkey::Pubkey, - signature::Keypair, signer::Signer, transaction::Transaction, - }, - }; - - macro_rules! test { - ( $instructions: expr, $expected_error: expr, $expected_budget: expr ) => { - let payer_keypair = Keypair::new(); - let tx = SanitizedTransaction::from_transaction_for_tests(Transaction::new( - &[&payer_keypair], - Message::new($instructions, Some(&payer_keypair.pubkey())), - Hash::default(), - )); - let feature_set = Arc::new(FeatureSet::all_enabled()); - let mut compute_budget = ComputeBudget::default(); - let result = compute_budget.process_transaction(&tx, feature_set); - assert_eq!($expected_error as Result<(), TransactionError>, result); - assert_eq!(compute_budget, $expected_budget); - }; - } - - #[test] - fn test_process_transaction() { - // Units - test!(&[], Ok(()), ComputeBudget::default()); - test!( - &[ - ComputeBudgetInstruction::request_units(1), - Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), - ], - Ok(()), - ComputeBudget { - max_units: 1, - ..ComputeBudget::default() - } - ); - test!( - &[ - ComputeBudgetInstruction::request_units(MAX_UNITS + 1), - Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), - ], - Err(TransactionError::InstructionError( - 0, - InstructionError::InvalidInstructionData, - )), - ComputeBudget::default() - ); - test!( - &[ - Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), - ComputeBudgetInstruction::request_units(MAX_UNITS), - ], - Ok(()), - ComputeBudget { - max_units: MAX_UNITS as u64, - ..ComputeBudget::default() - } - ); - test!( - &[ - Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), - Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), - Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), - ComputeBudgetInstruction::request_units(1), - ], - Ok(()), - ComputeBudget::default() - ); - - // HeapFrame - test!(&[], Ok(()), ComputeBudget::default()); - test!( - &[ - ComputeBudgetInstruction::request_heap_frame(40 * 1024), - Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), - ], - Ok(()), - ComputeBudget { - heap_size: Some(40 * 1024), - ..ComputeBudget::default() - } - ); - test!( - &[ - ComputeBudgetInstruction::request_heap_frame(40 * 1024 + 1), - Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), - ], - Err(TransactionError::InstructionError( - 0, - InstructionError::InvalidInstructionData, - )), - ComputeBudget::default() - ); - test!( - &[ - ComputeBudgetInstruction::request_heap_frame(31 * 1024), - Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), - ], - Err(TransactionError::InstructionError( - 0, - InstructionError::InvalidInstructionData, - )), - ComputeBudget::default() - ); - test!( - &[ - ComputeBudgetInstruction::request_heap_frame(MAX_HEAP_FRAME_BYTES + 1), - Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), - ], - Err(TransactionError::InstructionError( - 0, - InstructionError::InvalidInstructionData, - )), - ComputeBudget::default() - ); - test!( - &[ - Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), - ComputeBudgetInstruction::request_heap_frame(MAX_HEAP_FRAME_BYTES), - ], - Ok(()), - ComputeBudget { - heap_size: Some(MAX_HEAP_FRAME_BYTES as usize), - ..ComputeBudget::default() - } - ); - test!( - &[ - Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), - Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), - Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), - ComputeBudgetInstruction::request_heap_frame(1), // ignored - ], - Ok(()), - ComputeBudget::default() - ); - - // Combined - test!( - &[ - Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), - ComputeBudgetInstruction::request_heap_frame(MAX_HEAP_FRAME_BYTES), - ComputeBudgetInstruction::request_units(MAX_UNITS), - ], - Ok(()), - ComputeBudget { - max_units: MAX_UNITS as u64, - heap_size: Some(MAX_HEAP_FRAME_BYTES as usize), - ..ComputeBudget::default() - } - ); - } -} diff --git a/program-runtime/src/invoke_context.rs b/program-runtime/src/invoke_context.rs index 6c9c0a1a2..5bb2cfaf2 100644 --- a/program-runtime/src/invoke_context.rs +++ b/program-runtime/src/invoke_context.rs @@ -1,7 +1,6 @@ use { crate::{ accounts_data_meter::AccountsDataMeter, - compute_budget::ComputeBudget, ic_logger_msg, ic_msg, instruction_recorder::InstructionRecorder, log_collector::LogCollector, @@ -14,6 +13,7 @@ use { solana_sdk::{ account::{AccountSharedData, ReadableAccount}, bpf_loader_upgradeable::{self, UpgradeableLoaderState}, + compute_budget::ComputeBudget, feature_set::{ cap_accounts_data_len, do_support_realloc, neon_evm_compute_budget, reject_empty_instruction_without_program, remove_native_loader, requestable_heap_size, diff --git a/program-runtime/src/lib.rs b/program-runtime/src/lib.rs index db911ab81..e313be69c 100644 --- a/program-runtime/src/lib.rs +++ b/program-runtime/src/lib.rs @@ -1,7 +1,6 @@ #![cfg_attr(RUSTC_WITH_SPECIALIZATION, feature(min_specialization))] pub mod accounts_data_meter; -pub mod compute_budget; pub mod instruction_recorder; pub mod invoke_context; pub mod log_collector; diff --git a/program-test/src/lib.rs b/program-test/src/lib.rs index b1922c778..aa7beb75a 100644 --- a/program-test/src/lib.rs +++ b/program-test/src/lib.rs @@ -10,8 +10,7 @@ use { solana_banks_client::start_client, solana_banks_server::banks_server::start_local_server, solana_program_runtime::{ - compute_budget::ComputeBudget, ic_msg, invoke_context::ProcessInstructionWithContext, - stable_log, timings::ExecuteTimings, + ic_msg, invoke_context::ProcessInstructionWithContext, stable_log, timings::ExecuteTimings, }, solana_runtime::{ bank::Bank, @@ -24,6 +23,7 @@ use { account::{Account, AccountSharedData, ReadableAccount, WritableAccount}, account_info::AccountInfo, clock::Slot, + compute_budget::ComputeBudget, entrypoint::{ProgramResult, SUCCESS}, fee_calculator::{FeeCalculator, FeeRateGovernor}, genesis_config::{ClusterType, GenesisConfig}, diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 253777887..908b28a0e 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -74,7 +74,6 @@ use { solana_measure::measure::Measure, solana_metrics::{inc_new_counter_debug, inc_new_counter_info}, solana_program_runtime::{ - compute_budget::ComputeBudget, instruction_recorder::InstructionRecorder, invoke_context::{ BuiltinProgram, Executor, Executors, ProcessInstructionWithContext, TransactionExecutor, @@ -94,6 +93,7 @@ use { INITIAL_RENT_EPOCH, MAX_PROCESSING_AGE, MAX_RECENT_BLOCKHASHES, MAX_TRANSACTION_FORWARDING_DELAY, SECONDS_PER_DAY, }, + compute_budget::ComputeBudget, ed25519_program, epoch_info::EpochInfo, epoch_schedule::EpochSchedule, diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index cb7aee2f5..c49bbb74c 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -2,7 +2,6 @@ use { serde::{Deserialize, Serialize}, solana_measure::measure::Measure, solana_program_runtime::{ - compute_budget::ComputeBudget, instruction_recorder::InstructionRecorder, invoke_context::{BuiltinProgram, Executors, InvokeContext}, log_collector::LogCollector, @@ -11,6 +10,7 @@ use { }, solana_sdk::{ account::WritableAccount, + compute_budget::ComputeBudget, feature_set::{prevent_calling_precompiles_as_programs, FeatureSet}, hash::Hash, message::SanitizedMessage, diff --git a/sdk/src/compute_budget.rs b/sdk/src/compute_budget.rs index 0662c83c3..595939d9a 100644 --- a/sdk/src/compute_budget.rs +++ b/sdk/src/compute_budget.rs @@ -1,12 +1,22 @@ #![cfg(feature = "full")] use { - crate::instruction::Instruction, + crate::{ + borsh::try_from_slice_unchecked, + entrypoint::HEAP_LENGTH as MIN_HEAP_FRAME_BYTES, + feature_set::{requestable_heap_size, FeatureSet}, + instruction::{Instruction, InstructionError}, + transaction::{SanitizedTransaction, TransactionError}, + }, borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, + std::sync::Arc, }; crate::declare_id!("ComputeBudget111111111111111111111111111111"); +const MAX_UNITS: u32 = 1_000_000; +const MAX_HEAP_FRAME_BYTES: u32 = 256 * 1024; + /// Compute Budget Instructions #[derive( Serialize, @@ -29,13 +39,11 @@ pub enum ComputeBudgetInstruction { /// applies to each program executed, including all calls to CPIs. RequestHeapFrame(u32), } - impl ComputeBudgetInstruction { /// Create a `ComputeBudgetInstruction::RequestUnits` `Instruction` pub fn request_units(units: u32) -> Instruction { Instruction::new_with_borsh(id(), &ComputeBudgetInstruction::RequestUnits(units), vec![]) } - /// Create a `ComputeBudgetInstruction::RequestHeapFrame` `Instruction` pub fn request_heap_frame(bytes: u32) -> Instruction { Instruction::new_with_borsh( @@ -45,3 +53,270 @@ impl ComputeBudgetInstruction { ) } } + +#[derive(Clone, Copy, Debug, AbiExample, PartialEq)] +pub struct ComputeBudget { + /// Number of compute units that an instruction is allowed. Compute units + /// are consumed by program execution, resources they use, etc... + pub max_units: u64, + /// Number of compute units consumed by a log_u64 call + pub log_64_units: u64, + /// Number of compute units consumed by a create_program_address call + pub create_program_address_units: u64, + /// Number of compute units consumed by an invoke call (not including the cost incurred by + /// the called program) + pub invoke_units: u64, + /// Maximum cross-program invocation depth allowed + pub max_invoke_depth: usize, + /// Base number of compute units consumed to call SHA256 + pub sha256_base_cost: u64, + /// Incremental number of units consumed by SHA256 (based on bytes) + pub sha256_byte_cost: u64, + /// Maximum BPF to BPF call depth + pub max_call_depth: usize, + /// Size of a stack frame in bytes, must match the size specified in the LLVM BPF backend + pub stack_frame_size: usize, + /// Number of compute units consumed by logging a `Pubkey` + pub log_pubkey_units: u64, + /// Maximum cross-program invocation instruction size + pub max_cpi_instruction_size: usize, + /// Number of account data bytes per conpute unit charged during a cross-program invocation + pub cpi_bytes_per_unit: u64, + /// Base number of compute units consumed to get a sysvar + pub sysvar_base_cost: u64, + /// Number of compute units consumed to call secp256k1_recover + pub secp256k1_recover_cost: u64, + /// Number of compute units consumed to do a syscall without any work + pub syscall_base_cost: u64, + /// Number of compute units consumed to call zktoken_crypto_op + pub zk_token_elgamal_op_cost: u64, + /// Optional program heap region size, if `None` then loader default + pub heap_size: Option, + /// Number of compute units per additional 32k heap above the default (~.5 + /// us per 32k at 15 units/us rounded up) + pub heap_cost: u64, + /// Memory operation syscall base cost + pub mem_op_base_cost: u64, +} +impl Default for ComputeBudget { + fn default() -> Self { + Self::new() + } +} +impl ComputeBudget { + pub fn new() -> Self { + ComputeBudget { + max_units: 200_000, + log_64_units: 100, + create_program_address_units: 1500, + invoke_units: 1000, + max_invoke_depth: 4, + sha256_base_cost: 85, + sha256_byte_cost: 1, + max_call_depth: 64, + stack_frame_size: 4_096, + log_pubkey_units: 100, + max_cpi_instruction_size: 1280, // IPv6 Min MTU size + cpi_bytes_per_unit: 250, // ~50MB at 200,000 units + sysvar_base_cost: 100, + secp256k1_recover_cost: 25_000, + syscall_base_cost: 100, + zk_token_elgamal_op_cost: 25_000, + heap_size: None, + heap_cost: 8, + mem_op_base_cost: 15, + } + } + pub fn process_transaction( + &mut self, + tx: &SanitizedTransaction, + feature_set: Arc, + ) -> Result<(), TransactionError> { + let error = TransactionError::InstructionError(0, InstructionError::InvalidInstructionData); + // Compute budget instruction must be in the 1st 3 instructions (avoid + // nonce marker), otherwise ignored + for (program_id, instruction) in tx.message().program_instructions_iter().take(3) { + if check_id(program_id) { + match try_from_slice_unchecked(&instruction.data) { + Ok(ComputeBudgetInstruction::RequestUnits(units)) => { + if units > MAX_UNITS { + return Err(error); + } + self.max_units = units as u64; + } + Ok(ComputeBudgetInstruction::RequestHeapFrame(bytes)) => { + if !feature_set.is_active(&requestable_heap_size::id()) + || bytes > MAX_HEAP_FRAME_BYTES + || bytes < MIN_HEAP_FRAME_BYTES as u32 + || bytes % 1024 != 0 + { + return Err(error); + } + self.heap_size = Some(bytes as usize); + } + _ => return Err(error), + } + } + } + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use { + super::*, + crate::{ + hash::Hash, message::Message, pubkey::Pubkey, signature::Keypair, signer::Signer, + transaction::Transaction, + }, + }; + + macro_rules! test { + ( $instructions: expr, $expected_error: expr, $expected_budget: expr ) => { + let payer_keypair = Keypair::new(); + let tx = SanitizedTransaction::from_transaction_for_tests(Transaction::new( + &[&payer_keypair], + Message::new($instructions, Some(&payer_keypair.pubkey())), + Hash::default(), + )); + let feature_set = Arc::new(FeatureSet::all_enabled()); + let mut compute_budget = ComputeBudget::default(); + let result = compute_budget.process_transaction(&tx, feature_set); + assert_eq!($expected_error as Result<(), TransactionError>, result); + assert_eq!(compute_budget, $expected_budget); + }; + } + + #[test] + fn test_process_transaction() { + // Units + test!(&[], Ok(()), ComputeBudget::default()); + test!( + &[ + ComputeBudgetInstruction::request_units(1), + Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), + ], + Ok(()), + ComputeBudget { + max_units: 1, + ..ComputeBudget::default() + } + ); + test!( + &[ + ComputeBudgetInstruction::request_units(MAX_UNITS + 1), + Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), + ], + Err(TransactionError::InstructionError( + 0, + InstructionError::InvalidInstructionData, + )), + ComputeBudget::default() + ); + test!( + &[ + Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), + ComputeBudgetInstruction::request_units(MAX_UNITS), + ], + Ok(()), + ComputeBudget { + max_units: MAX_UNITS as u64, + ..ComputeBudget::default() + } + ); + test!( + &[ + Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), + Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), + Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), + ComputeBudgetInstruction::request_units(1), + ], + Ok(()), + ComputeBudget::default() + ); + + // HeapFrame + test!(&[], Ok(()), ComputeBudget::default()); + test!( + &[ + ComputeBudgetInstruction::request_heap_frame(40 * 1024), + Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), + ], + Ok(()), + ComputeBudget { + heap_size: Some(40 * 1024), + ..ComputeBudget::default() + } + ); + test!( + &[ + ComputeBudgetInstruction::request_heap_frame(40 * 1024 + 1), + Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), + ], + Err(TransactionError::InstructionError( + 0, + InstructionError::InvalidInstructionData, + )), + ComputeBudget::default() + ); + test!( + &[ + ComputeBudgetInstruction::request_heap_frame(31 * 1024), + Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), + ], + Err(TransactionError::InstructionError( + 0, + InstructionError::InvalidInstructionData, + )), + ComputeBudget::default() + ); + test!( + &[ + ComputeBudgetInstruction::request_heap_frame(MAX_HEAP_FRAME_BYTES + 1), + Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), + ], + Err(TransactionError::InstructionError( + 0, + InstructionError::InvalidInstructionData, + )), + ComputeBudget::default() + ); + test!( + &[ + Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), + ComputeBudgetInstruction::request_heap_frame(MAX_HEAP_FRAME_BYTES), + ], + Ok(()), + ComputeBudget { + heap_size: Some(MAX_HEAP_FRAME_BYTES as usize), + ..ComputeBudget::default() + } + ); + test!( + &[ + Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), + Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), + Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), + ComputeBudgetInstruction::request_heap_frame(1), // ignored + ], + Ok(()), + ComputeBudget::default() + ); + + // Combined + test!( + &[ + Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), + ComputeBudgetInstruction::request_heap_frame(MAX_HEAP_FRAME_BYTES), + ComputeBudgetInstruction::request_units(MAX_UNITS), + ], + Ok(()), + ComputeBudget { + max_units: MAX_UNITS as u64, + heap_size: Some(MAX_HEAP_FRAME_BYTES as usize), + ..ComputeBudget::default() + } + ); + } +}