Rename BpfComputeBudget (#18768)
This commit is contained in:
parent
cbe2ed47e2
commit
7fc4cfebc8
|
@ -17,6 +17,7 @@ use {
|
|||
account::{Account, AccountSharedData, ReadableAccount, WritableAccount},
|
||||
account_info::AccountInfo,
|
||||
clock::{Clock, Slot},
|
||||
compute_budget::ComputeBudget,
|
||||
entrypoint::{ProgramResult, SUCCESS},
|
||||
epoch_schedule::EpochSchedule,
|
||||
fee_calculator::{FeeCalculator, FeeRateGovernor},
|
||||
|
@ -26,9 +27,7 @@ use {
|
|||
instruction::InstructionError,
|
||||
message::Message,
|
||||
native_token::sol_to_lamports,
|
||||
process_instruction::{
|
||||
stable_log, BpfComputeBudget, InvokeContext, ProcessInstructionWithContext,
|
||||
},
|
||||
process_instruction::{stable_log, InvokeContext, ProcessInstructionWithContext},
|
||||
program_error::{ProgramError, ACCOUNT_BORROW_FAILED, UNSUPPORTED_SYSVAR},
|
||||
pubkey::Pubkey,
|
||||
rent::Rent,
|
||||
|
@ -212,7 +211,7 @@ fn get_sysvar<T: Default + Sysvar + Sized + serde::de::DeserializeOwned>(
|
|||
.try_borrow_mut()
|
||||
.map_err(|_| ACCOUNT_BORROW_FAILED)
|
||||
.unwrap()
|
||||
.consume(invoke_context.get_bpf_compute_budget().sysvar_base_cost + T::size_of() as u64)
|
||||
.consume(invoke_context.get_compute_budget().sysvar_base_cost + T::size_of() as u64)
|
||||
.is_err()
|
||||
{
|
||||
panic!("Exceeded compute budget");
|
||||
|
@ -462,7 +461,7 @@ fn setup_fee_calculator(bank: Bank) -> Bank {
|
|||
pub struct ProgramTest {
|
||||
accounts: Vec<(Pubkey, AccountSharedData)>,
|
||||
builtins: Vec<Builtin>,
|
||||
bpf_compute_max_units: Option<u64>,
|
||||
compute_max_units: Option<u64>,
|
||||
prefer_bpf: bool,
|
||||
use_bpf_jit: bool,
|
||||
}
|
||||
|
@ -492,7 +491,7 @@ impl Default for ProgramTest {
|
|||
Self {
|
||||
accounts: vec![],
|
||||
builtins: vec![],
|
||||
bpf_compute_max_units: None,
|
||||
compute_max_units: None,
|
||||
prefer_bpf,
|
||||
use_bpf_jit: false,
|
||||
}
|
||||
|
@ -522,9 +521,16 @@ impl ProgramTest {
|
|||
self.prefer_bpf = prefer_bpf;
|
||||
}
|
||||
|
||||
/// Override the default maximum compute units
|
||||
pub fn set_compute_max_units(&mut self, compute_max_units: u64) {
|
||||
self.compute_max_units = Some(compute_max_units);
|
||||
}
|
||||
|
||||
/// Override the BPF compute budget
|
||||
#[allow(deprecated)]
|
||||
#[deprecated(since = "1.8.0", note = "please use `set_compute_max_units` instead")]
|
||||
pub fn set_bpf_compute_max_units(&mut self, bpf_compute_max_units: u64) {
|
||||
self.bpf_compute_max_units = Some(bpf_compute_max_units);
|
||||
self.compute_max_units = Some(bpf_compute_max_units);
|
||||
}
|
||||
|
||||
/// Execute the BPF program with JIT if true, interpreted if false
|
||||
|
@ -783,10 +789,10 @@ impl ProgramTest {
|
|||
bank.store_account(address, account);
|
||||
}
|
||||
bank.set_capitalization();
|
||||
if let Some(max_units) = self.bpf_compute_max_units {
|
||||
bank.set_bpf_compute_budget(Some(BpfComputeBudget {
|
||||
if let Some(max_units) = self.compute_max_units {
|
||||
bank.set_compute_budget(Some(ComputeBudget {
|
||||
max_units,
|
||||
..BpfComputeBudget::default()
|
||||
..ComputeBudget::default()
|
||||
}));
|
||||
}
|
||||
let bank = setup_fee_calculator(bank);
|
||||
|
|
|
@ -34,7 +34,6 @@ use solana_sdk::{
|
|||
bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable,
|
||||
client::SyncClient,
|
||||
clock::MAX_PROCESSING_AGE,
|
||||
compute_budget,
|
||||
entrypoint::{MAX_PERMITTED_DATA_INCREASE, SUCCESS},
|
||||
instruction::{AccountMeta, CompiledInstruction, Instruction, InstructionError},
|
||||
keyed_account::KeyedAccount,
|
||||
|
@ -1231,7 +1230,7 @@ fn test_program_bpf_ro_modify() {
|
|||
#[cfg(feature = "bpf_rust")]
|
||||
#[test]
|
||||
fn test_program_bpf_call_depth() {
|
||||
use solana_sdk::process_instruction::BpfComputeBudget;
|
||||
use solana_sdk::compute_budget::ComputeBudget;
|
||||
|
||||
solana_logger::setup();
|
||||
|
||||
|
@ -1253,7 +1252,7 @@ fn test_program_bpf_call_depth() {
|
|||
|
||||
let instruction = Instruction::new_with_bincode(
|
||||
program_id,
|
||||
&(BpfComputeBudget::default().max_call_depth - 1),
|
||||
&(ComputeBudget::default().max_call_depth - 1),
|
||||
vec![],
|
||||
);
|
||||
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction);
|
||||
|
@ -1261,7 +1260,7 @@ fn test_program_bpf_call_depth() {
|
|||
|
||||
let instruction = Instruction::new_with_bincode(
|
||||
program_id,
|
||||
&BpfComputeBudget::default().max_call_depth,
|
||||
&ComputeBudget::default().max_call_depth,
|
||||
vec![],
|
||||
);
|
||||
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction);
|
||||
|
@ -1290,7 +1289,7 @@ fn test_program_bpf_compute_budget() {
|
|||
);
|
||||
let message = Message::new(
|
||||
&[
|
||||
compute_budget::request_units(1),
|
||||
solana_sdk::compute_budget::ComputeBudgetInstruction::request_units(1),
|
||||
Instruction::new_with_bincode(program_id, &0, vec![]),
|
||||
],
|
||||
Some(&mint_keypair.pubkey()),
|
||||
|
|
|
@ -78,10 +78,10 @@ pub fn create_executor(
|
|||
ic_msg!(invoke_context, "Failed to register syscalls: {}", e);
|
||||
InstructionError::ProgramEnvironmentSetupFailure
|
||||
})?;
|
||||
let bpf_compute_budget = invoke_context.get_bpf_compute_budget();
|
||||
let compute_budget = invoke_context.get_compute_budget();
|
||||
let config = Config {
|
||||
max_call_depth: bpf_compute_budget.max_call_depth,
|
||||
stack_frame_size: bpf_compute_budget.stack_frame_size,
|
||||
max_call_depth: compute_budget.max_call_depth,
|
||||
stack_frame_size: compute_budget.stack_frame_size,
|
||||
enable_instruction_tracing: log_enabled!(Trace),
|
||||
..Config::default()
|
||||
};
|
||||
|
@ -149,11 +149,9 @@ pub fn create_vm<'a>(
|
|||
parameter_bytes: &mut [u8],
|
||||
invoke_context: &'a mut dyn InvokeContext,
|
||||
) -> Result<EbpfVm<'a, BpfError, ThisInstructionMeter>, EbpfError<BpfError>> {
|
||||
let bpf_compute_budget = invoke_context.get_bpf_compute_budget();
|
||||
let heap = AlignedMemory::new_with_size(
|
||||
bpf_compute_budget.heap_size.unwrap_or(HEAP_LENGTH),
|
||||
HOST_ALIGN,
|
||||
);
|
||||
let compute_budget = invoke_context.get_compute_budget();
|
||||
let heap =
|
||||
AlignedMemory::new_with_size(compute_budget.heap_size.unwrap_or(HEAP_LENGTH), HOST_ALIGN);
|
||||
let heap_region = MemoryRegion::new_from_slice(heap.as_slice(), MM_HEAP_START, 0, true);
|
||||
let mut vm = EbpfVm::new(program, parameter_bytes, &[heap_region])?;
|
||||
syscalls::bind_syscall_context_objects(loader_id, &mut vm, invoke_context, heap)?;
|
||||
|
@ -866,6 +864,7 @@ mod tests {
|
|||
account_utils::StateMut,
|
||||
client::SyncClient,
|
||||
clock::Clock,
|
||||
compute_budget::ComputeBudget,
|
||||
feature_set::FeatureSet,
|
||||
genesis_config::create_genesis_config,
|
||||
instruction::Instruction,
|
||||
|
@ -873,8 +872,7 @@ mod tests {
|
|||
keyed_account::KeyedAccount,
|
||||
message::Message,
|
||||
process_instruction::{
|
||||
BpfComputeBudget, InvokeContextStackFrame, MockComputeMeter, MockInvokeContext,
|
||||
MockLogger,
|
||||
InvokeContextStackFrame, MockComputeMeter, MockInvokeContext, MockLogger,
|
||||
},
|
||||
pubkey::Pubkey,
|
||||
rent::Rent,
|
||||
|
@ -1133,7 +1131,8 @@ mod tests {
|
|||
keyed_accounts_range,
|
||||
}],
|
||||
logger: MockLogger::default(),
|
||||
bpf_compute_budget: BpfComputeBudget::default(),
|
||||
compute_budget: ComputeBudget::default(),
|
||||
bpf_compute_budget: ComputeBudget::default().into(),
|
||||
compute_meter: MockComputeMeter::default(),
|
||||
programs: vec![],
|
||||
accounts: vec![],
|
||||
|
|
|
@ -197,7 +197,7 @@ pub fn bind_syscall_context_objects<'a>(
|
|||
invoke_context: &'a mut dyn InvokeContext,
|
||||
heap: AlignedMemory,
|
||||
) -> Result<(), EbpfError<BpfError>> {
|
||||
let bpf_compute_budget = invoke_context.get_bpf_compute_budget();
|
||||
let compute_budget = invoke_context.get_compute_budget();
|
||||
let enforce_aligned_host_addrs =
|
||||
invoke_context.is_feature_active(&enforce_aligned_host_addrs::id());
|
||||
|
||||
|
@ -223,7 +223,7 @@ pub fn bind_syscall_context_objects<'a>(
|
|||
)?;
|
||||
vm.bind_syscall_context_object(
|
||||
Box::new(SyscallLogU64 {
|
||||
cost: bpf_compute_budget.log_64_units,
|
||||
cost: compute_budget.log_64_units,
|
||||
compute_meter: invoke_context.get_compute_meter(),
|
||||
logger: invoke_context.get_logger(),
|
||||
}),
|
||||
|
@ -241,7 +241,7 @@ pub fn bind_syscall_context_objects<'a>(
|
|||
|
||||
vm.bind_syscall_context_object(
|
||||
Box::new(SyscallLogPubkey {
|
||||
cost: bpf_compute_budget.log_pubkey_units,
|
||||
cost: compute_budget.log_pubkey_units,
|
||||
compute_meter: invoke_context.get_compute_meter(),
|
||||
logger: invoke_context.get_logger(),
|
||||
loader_id,
|
||||
|
@ -252,7 +252,7 @@ pub fn bind_syscall_context_objects<'a>(
|
|||
|
||||
vm.bind_syscall_context_object(
|
||||
Box::new(SyscallCreateProgramAddress {
|
||||
cost: bpf_compute_budget.create_program_address_units,
|
||||
cost: compute_budget.create_program_address_units,
|
||||
compute_meter: invoke_context.get_compute_meter(),
|
||||
loader_id,
|
||||
enforce_aligned_host_addrs,
|
||||
|
@ -262,7 +262,7 @@ pub fn bind_syscall_context_objects<'a>(
|
|||
|
||||
vm.bind_syscall_context_object(
|
||||
Box::new(SyscallTryFindProgramAddress {
|
||||
cost: bpf_compute_budget.create_program_address_units,
|
||||
cost: compute_budget.create_program_address_units,
|
||||
compute_meter: invoke_context.get_compute_meter(),
|
||||
loader_id,
|
||||
enforce_aligned_host_addrs,
|
||||
|
@ -272,8 +272,8 @@ pub fn bind_syscall_context_objects<'a>(
|
|||
|
||||
vm.bind_syscall_context_object(
|
||||
Box::new(SyscallSha256 {
|
||||
sha256_base_cost: bpf_compute_budget.sha256_base_cost,
|
||||
sha256_byte_cost: bpf_compute_budget.sha256_byte_cost,
|
||||
sha256_base_cost: compute_budget.sha256_base_cost,
|
||||
sha256_byte_cost: compute_budget.sha256_byte_cost,
|
||||
compute_meter: invoke_context.get_compute_meter(),
|
||||
loader_id,
|
||||
enforce_aligned_host_addrs,
|
||||
|
@ -285,8 +285,8 @@ pub fn bind_syscall_context_objects<'a>(
|
|||
vm,
|
||||
invoke_context.is_feature_active(&keccak256_syscall_enabled::id()),
|
||||
Box::new(SyscallKeccak256 {
|
||||
base_cost: bpf_compute_budget.sha256_base_cost,
|
||||
byte_cost: bpf_compute_budget.sha256_byte_cost,
|
||||
base_cost: compute_budget.sha256_base_cost,
|
||||
byte_cost: compute_budget.sha256_byte_cost,
|
||||
compute_meter: invoke_context.get_compute_meter(),
|
||||
loader_id,
|
||||
}),
|
||||
|
@ -296,7 +296,7 @@ pub fn bind_syscall_context_objects<'a>(
|
|||
vm,
|
||||
invoke_context.is_feature_active(&memory_ops_syscalls::id()),
|
||||
Box::new(SyscallMemcpy {
|
||||
cost: invoke_context.get_bpf_compute_budget().cpi_bytes_per_unit,
|
||||
cost: invoke_context.get_compute_budget().cpi_bytes_per_unit,
|
||||
compute_meter: invoke_context.get_compute_meter(),
|
||||
loader_id,
|
||||
}),
|
||||
|
@ -305,7 +305,7 @@ pub fn bind_syscall_context_objects<'a>(
|
|||
vm,
|
||||
invoke_context.is_feature_active(&memory_ops_syscalls::id()),
|
||||
Box::new(SyscallMemmove {
|
||||
cost: invoke_context.get_bpf_compute_budget().cpi_bytes_per_unit,
|
||||
cost: invoke_context.get_compute_budget().cpi_bytes_per_unit,
|
||||
compute_meter: invoke_context.get_compute_meter(),
|
||||
loader_id,
|
||||
}),
|
||||
|
@ -314,7 +314,7 @@ pub fn bind_syscall_context_objects<'a>(
|
|||
vm,
|
||||
invoke_context.is_feature_active(&memory_ops_syscalls::id()),
|
||||
Box::new(SyscallMemcmp {
|
||||
cost: invoke_context.get_bpf_compute_budget().cpi_bytes_per_unit,
|
||||
cost: invoke_context.get_compute_budget().cpi_bytes_per_unit,
|
||||
compute_meter: invoke_context.get_compute_meter(),
|
||||
loader_id,
|
||||
}),
|
||||
|
@ -323,7 +323,7 @@ pub fn bind_syscall_context_objects<'a>(
|
|||
vm,
|
||||
invoke_context.is_feature_active(&memory_ops_syscalls::id()),
|
||||
Box::new(SyscallMemset {
|
||||
cost: invoke_context.get_bpf_compute_budget().cpi_bytes_per_unit,
|
||||
cost: invoke_context.get_compute_budget().cpi_bytes_per_unit,
|
||||
compute_meter: invoke_context.get_compute_meter(),
|
||||
loader_id,
|
||||
}),
|
||||
|
@ -332,8 +332,8 @@ pub fn bind_syscall_context_objects<'a>(
|
|||
vm,
|
||||
invoke_context.is_feature_active(&blake3_syscall_enabled::id()),
|
||||
Box::new(SyscallBlake3 {
|
||||
base_cost: bpf_compute_budget.sha256_base_cost,
|
||||
byte_cost: bpf_compute_budget.sha256_byte_cost,
|
||||
base_cost: compute_budget.sha256_base_cost,
|
||||
byte_cost: compute_budget.sha256_byte_cost,
|
||||
compute_meter: invoke_context.get_compute_meter(),
|
||||
loader_id,
|
||||
}),
|
||||
|
@ -343,7 +343,7 @@ pub fn bind_syscall_context_objects<'a>(
|
|||
vm,
|
||||
invoke_context.is_feature_active(&secp256k1_recover_syscall_enabled::id()),
|
||||
Box::new(SyscallSecp256k1Recover {
|
||||
cost: bpf_compute_budget.secp256k1_recover_cost,
|
||||
cost: compute_budget.secp256k1_recover_cost,
|
||||
compute_meter: invoke_context.get_compute_meter(),
|
||||
loader_id,
|
||||
libsecp256k1_0_5_upgrade_enabled: invoke_context
|
||||
|
@ -1043,9 +1043,9 @@ fn get_sysvar<T: std::fmt::Debug + Sysvar + SysvarId>(
|
|||
.try_borrow()
|
||||
.map_err(|_| SyscallError::InvokeContextBorrowFailed)?;
|
||||
|
||||
invoke_context.get_compute_meter().consume(
|
||||
invoke_context.get_bpf_compute_budget().sysvar_base_cost + size_of::<T>() as u64,
|
||||
)?;
|
||||
invoke_context
|
||||
.get_compute_meter()
|
||||
.consume(invoke_context.get_compute_budget().sysvar_base_cost + size_of::<T>() as u64)?;
|
||||
let var = translate_type_mut::<T>(
|
||||
memory_mapping,
|
||||
var_addr,
|
||||
|
@ -1689,8 +1689,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
|
|||
|
||||
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,
|
||||
data.len() as u64 / invoke_context.get_compute_budget().cpi_bytes_per_unit,
|
||||
)?;
|
||||
}
|
||||
|
||||
|
@ -2009,8 +2008,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
|
|||
|
||||
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,
|
||||
account_info.data_len / invoke_context.get_compute_budget().cpi_bytes_per_unit,
|
||||
)?;
|
||||
}
|
||||
|
||||
|
@ -2213,9 +2211,7 @@ fn check_instruction_size(
|
|||
let size = num_accounts
|
||||
.saturating_mul(size_of::<AccountMeta>())
|
||||
.saturating_add(data_len);
|
||||
let max_size = invoke_context
|
||||
.get_bpf_compute_budget()
|
||||
.max_cpi_instruction_size;
|
||||
let max_size = invoke_context.get_compute_budget().max_cpi_instruction_size;
|
||||
if size > max_size {
|
||||
return Err(SyscallError::InstructionTooLarge(size, max_size).into());
|
||||
}
|
||||
|
@ -2226,11 +2222,7 @@ fn check_account_infos(
|
|||
len: usize,
|
||||
invoke_context: &Ref<&mut dyn InvokeContext>,
|
||||
) -> Result<(), EbpfError<BpfError>> {
|
||||
if len * size_of::<Pubkey>()
|
||||
> invoke_context
|
||||
.get_bpf_compute_budget()
|
||||
.max_cpi_instruction_size
|
||||
{
|
||||
if len * size_of::<Pubkey>() > invoke_context.get_compute_budget().max_cpi_instruction_size {
|
||||
// Cap the number of account_infos a caller can pass to approximate
|
||||
// maximum that accounts that could be passed in an instruction
|
||||
return Err(SyscallError::TooManyAccounts.into());
|
||||
|
@ -2305,7 +2297,7 @@ fn call<'a>(
|
|||
|
||||
invoke_context
|
||||
.get_compute_meter()
|
||||
.consume(invoke_context.get_bpf_compute_budget().invoke_units)?;
|
||||
.consume(invoke_context.get_compute_budget().invoke_units)?;
|
||||
|
||||
let enforce_aligned_host_addrs =
|
||||
invoke_context.is_feature_active(&enforce_aligned_host_addrs::id());
|
||||
|
|
|
@ -76,7 +76,7 @@ use solana_sdk::{
|
|||
INITIAL_RENT_EPOCH, MAX_PROCESSING_AGE, MAX_RECENT_BLOCKHASHES,
|
||||
MAX_TRANSACTION_FORWARDING_DELAY, SECONDS_PER_DAY,
|
||||
},
|
||||
compute_budget,
|
||||
compute_budget::ComputeBudget,
|
||||
epoch_info::EpochInfo,
|
||||
epoch_schedule::EpochSchedule,
|
||||
feature,
|
||||
|
@ -93,9 +93,7 @@ use solana_sdk::{
|
|||
native_loader,
|
||||
native_token::sol_to_lamports,
|
||||
nonce, nonce_account,
|
||||
process_instruction::{
|
||||
BpfComputeBudget, ComputeMeter, Executor, ProcessInstructionWithContext,
|
||||
},
|
||||
process_instruction::{ComputeMeter, Executor, ProcessInstructionWithContext},
|
||||
program_utils::limited_deserialize,
|
||||
pubkey::Pubkey,
|
||||
recent_blockhashes_account,
|
||||
|
@ -1001,7 +999,7 @@ pub struct Bank {
|
|||
/// The Message processor
|
||||
message_processor: MessageProcessor,
|
||||
|
||||
bpf_compute_budget: Option<BpfComputeBudget>,
|
||||
compute_budget: Option<ComputeBudget>,
|
||||
|
||||
/// Builtin programs activated dynamically by feature
|
||||
#[allow(clippy::rc_buffer)]
|
||||
|
@ -1236,7 +1234,7 @@ impl Bank {
|
|||
tick_height: AtomicU64::new(parent.tick_height.load(Relaxed)),
|
||||
signature_count: AtomicU64::new(0),
|
||||
message_processor: parent.message_processor.clone(),
|
||||
bpf_compute_budget: parent.bpf_compute_budget,
|
||||
compute_budget: parent.compute_budget,
|
||||
feature_builtins: parent.feature_builtins.clone(),
|
||||
hard_forks: parent.hard_forks.clone(),
|
||||
last_vote_sync: AtomicU64::new(parent.last_vote_sync.load(Relaxed)),
|
||||
|
@ -1396,7 +1394,7 @@ impl Bank {
|
|||
epoch_stakes: fields.epoch_stakes,
|
||||
is_delta: AtomicBool::new(fields.is_delta),
|
||||
message_processor: new(),
|
||||
bpf_compute_budget: None,
|
||||
compute_budget: None,
|
||||
feature_builtins: new(),
|
||||
last_vote_sync: new(),
|
||||
rewards: new(),
|
||||
|
@ -3232,12 +3230,10 @@ impl Bank {
|
|||
let feature_set = self.feature_set.clone();
|
||||
signature_count += u64::from(tx.message().header.num_required_signatures);
|
||||
|
||||
let mut bpf_compute_budget = self
|
||||
.bpf_compute_budget
|
||||
.unwrap_or_else(BpfComputeBudget::new);
|
||||
let mut compute_budget = self.compute_budget.unwrap_or_else(ComputeBudget::new);
|
||||
|
||||
let mut process_result = if feature_set.is_active(&tx_wide_compute_cap::id()) {
|
||||
compute_budget::process_request(&mut bpf_compute_budget, tx)
|
||||
compute_budget.process_transaction(tx)
|
||||
} else {
|
||||
Ok(())
|
||||
};
|
||||
|
@ -3267,7 +3263,7 @@ impl Bank {
|
|||
};
|
||||
|
||||
let compute_meter = Rc::new(RefCell::new(TransactionComputeMeter::new(
|
||||
bpf_compute_budget.max_units,
|
||||
compute_budget.max_units,
|
||||
)));
|
||||
|
||||
process_result = self.message_processor.process_message(
|
||||
|
@ -3279,7 +3275,7 @@ impl Bank {
|
|||
executors.clone(),
|
||||
instruction_recorders.as_deref(),
|
||||
feature_set,
|
||||
bpf_compute_budget,
|
||||
compute_budget,
|
||||
compute_meter,
|
||||
&mut timings.details,
|
||||
self.rc.accounts.clone(),
|
||||
|
@ -4434,8 +4430,17 @@ impl Bank {
|
|||
*self.inflation.write().unwrap() = inflation;
|
||||
}
|
||||
|
||||
pub fn set_bpf_compute_budget(&mut self, bpf_compute_budget: Option<BpfComputeBudget>) {
|
||||
self.bpf_compute_budget = bpf_compute_budget;
|
||||
pub fn set_compute_budget(&mut self, compute_budget: Option<ComputeBudget>) {
|
||||
self.compute_budget = compute_budget;
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
#[deprecated(since = "1.8.0", note = "please use `set_compute_budget` instead")]
|
||||
pub fn set_bpf_compute_budget(
|
||||
&mut self,
|
||||
bpf_compute_budget: Option<solana_sdk::process_instruction::BpfComputeBudget>,
|
||||
) {
|
||||
self.compute_budget = bpf_compute_budget.map(|budget| budget.into());
|
||||
}
|
||||
|
||||
pub fn hard_forks(&self) -> Arc<RwLock<HardForks>> {
|
||||
|
@ -5556,7 +5561,7 @@ pub(crate) mod tests {
|
|||
use solana_sdk::{
|
||||
account::Account,
|
||||
clock::{DEFAULT_SLOTS_PER_EPOCH, DEFAULT_TICKS_PER_SLOT},
|
||||
compute_budget,
|
||||
compute_budget::ComputeBudgetInstruction,
|
||||
epoch_schedule::MINIMUM_SLOTS_PER_EPOCH,
|
||||
feature::Feature,
|
||||
genesis_config::create_genesis_config,
|
||||
|
@ -13795,12 +13800,12 @@ pub(crate) mod tests {
|
|||
_data: &[u8],
|
||||
invoke_context: &mut dyn InvokeContext,
|
||||
) -> std::result::Result<(), InstructionError> {
|
||||
let compute_budget = invoke_context.get_bpf_compute_budget();
|
||||
let compute_budget = invoke_context.get_compute_budget();
|
||||
assert_eq!(
|
||||
*compute_budget,
|
||||
BpfComputeBudget {
|
||||
ComputeBudget {
|
||||
max_units: 1,
|
||||
..BpfComputeBudget::default()
|
||||
..ComputeBudget::default()
|
||||
}
|
||||
);
|
||||
Ok(())
|
||||
|
@ -13810,7 +13815,7 @@ pub(crate) mod tests {
|
|||
|
||||
let message = Message::new(
|
||||
&[
|
||||
compute_budget::request_units(1),
|
||||
ComputeBudgetInstruction::request_units(1),
|
||||
Instruction::new_with_bincode(program_id, &0, vec![]),
|
||||
],
|
||||
Some(&mint_keypair.pubkey()),
|
||||
|
|
|
@ -9,6 +9,7 @@ use solana_sdk::{
|
|||
account::{AccountSharedData, ReadableAccount, WritableAccount},
|
||||
account_utils::StateMut,
|
||||
bpf_loader_upgradeable::{self, UpgradeableLoaderState},
|
||||
compute_budget::ComputeBudget,
|
||||
feature_set::{
|
||||
instructions_sysvar_enabled, neon_evm_compute_budget, tx_wide_compute_cap,
|
||||
updated_verify_policy, FeatureSet,
|
||||
|
@ -19,7 +20,7 @@ use solana_sdk::{
|
|||
message::Message,
|
||||
native_loader,
|
||||
process_instruction::{
|
||||
BpfComputeBudget, ComputeMeter, Executor, InvokeContext, InvokeContextStackFrame, Logger,
|
||||
ComputeMeter, Executor, InvokeContext, InvokeContextStackFrame, Logger,
|
||||
ProcessInstructionWithContext,
|
||||
},
|
||||
pubkey::Pubkey,
|
||||
|
@ -290,7 +291,9 @@ pub struct ThisInvokeContext<'a> {
|
|||
accounts: &'a [(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||
programs: &'a [(Pubkey, ProcessInstructionWithContext)],
|
||||
logger: Rc<RefCell<dyn Logger>>,
|
||||
bpf_compute_budget: BpfComputeBudget,
|
||||
compute_budget: ComputeBudget,
|
||||
#[allow(deprecated)]
|
||||
bpf_compute_budget: solana_sdk::process_instruction::BpfComputeBudget,
|
||||
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
||||
executors: Rc<RefCell<Executors>>,
|
||||
instruction_recorder: Option<InstructionRecorder>,
|
||||
|
@ -312,7 +315,7 @@ impl<'a> ThisInvokeContext<'a> {
|
|||
accounts: &'a [(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||
programs: &'a [(Pubkey, ProcessInstructionWithContext)],
|
||||
log_collector: Option<Rc<LogCollector>>,
|
||||
bpf_compute_budget: BpfComputeBudget,
|
||||
compute_budget: ComputeBudget,
|
||||
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
||||
executors: Rc<RefCell<Executors>>,
|
||||
instruction_recorder: Option<InstructionRecorder>,
|
||||
|
@ -331,17 +334,18 @@ impl<'a> ThisInvokeContext<'a> {
|
|||
compute_meter
|
||||
} else {
|
||||
Rc::new(RefCell::new(ThisComputeMeter {
|
||||
remaining: bpf_compute_budget.max_units,
|
||||
remaining: compute_budget.max_units,
|
||||
}))
|
||||
};
|
||||
let mut invoke_context = Self {
|
||||
invoke_stack: Vec::with_capacity(bpf_compute_budget.max_invoke_depth),
|
||||
invoke_stack: Vec::with_capacity(compute_budget.max_invoke_depth),
|
||||
rent,
|
||||
pre_accounts,
|
||||
accounts,
|
||||
programs,
|
||||
logger: Rc::new(RefCell::new(ThisLogger { log_collector })),
|
||||
bpf_compute_budget,
|
||||
compute_budget,
|
||||
bpf_compute_budget: compute_budget.into(),
|
||||
compute_meter,
|
||||
executors,
|
||||
instruction_recorder,
|
||||
|
@ -366,7 +370,7 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
|||
key: &Pubkey,
|
||||
keyed_accounts: &[(bool, bool, &Pubkey, &RefCell<AccountSharedData>)],
|
||||
) -> Result<(), InstructionError> {
|
||||
if self.invoke_stack.len() > self.bpf_compute_budget.max_invoke_depth {
|
||||
if self.invoke_stack.len() > self.compute_budget.max_invoke_depth {
|
||||
return Err(InstructionError::CallDepth);
|
||||
}
|
||||
|
||||
|
@ -470,7 +474,8 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
|||
fn get_logger(&self) -> Rc<RefCell<dyn Logger>> {
|
||||
self.logger.clone()
|
||||
}
|
||||
fn get_bpf_compute_budget(&self) -> &BpfComputeBudget {
|
||||
#[allow(deprecated)]
|
||||
fn get_bpf_compute_budget(&self) -> &solana_sdk::process_instruction::BpfComputeBudget {
|
||||
&self.bpf_compute_budget
|
||||
}
|
||||
fn get_compute_meter(&self) -> Rc<RefCell<dyn ComputeMeter>> {
|
||||
|
@ -531,6 +536,9 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
|||
None
|
||||
}
|
||||
}
|
||||
fn get_compute_budget(&self) -> &ComputeBudget {
|
||||
&self.compute_budget
|
||||
}
|
||||
}
|
||||
pub struct ThisLogger {
|
||||
log_collector: Option<Rc<LogCollector>>,
|
||||
|
@ -1155,7 +1163,7 @@ impl MessageProcessor {
|
|||
instruction_recorder: Option<InstructionRecorder>,
|
||||
instruction_index: usize,
|
||||
feature_set: Arc<FeatureSet>,
|
||||
bpf_compute_budget: BpfComputeBudget,
|
||||
compute_budget: ComputeBudget,
|
||||
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
||||
timings: &mut ExecuteDetailsTimings,
|
||||
account_db: Arc<Accounts>,
|
||||
|
@ -1178,13 +1186,13 @@ impl MessageProcessor {
|
|||
|
||||
let program_id = instruction.program_id(&message.account_keys);
|
||||
|
||||
let mut bpf_compute_budget = bpf_compute_budget;
|
||||
let mut compute_budget = compute_budget;
|
||||
if feature_set.is_active(&neon_evm_compute_budget::id())
|
||||
&& *program_id == crate::neon_evm_program::id()
|
||||
{
|
||||
// Bump the compute budget for neon_evm
|
||||
bpf_compute_budget.max_units = bpf_compute_budget.max_units.max(500_000);
|
||||
bpf_compute_budget.heap_size = Some(256 * 1024);
|
||||
compute_budget.max_units = compute_budget.max_units.max(500_000);
|
||||
compute_budget.heap_size = Some(256 * 1024);
|
||||
}
|
||||
|
||||
let mut invoke_context = ThisInvokeContext::new(
|
||||
|
@ -1196,7 +1204,7 @@ impl MessageProcessor {
|
|||
accounts,
|
||||
&self.programs,
|
||||
log_collector,
|
||||
bpf_compute_budget,
|
||||
compute_budget,
|
||||
compute_meter,
|
||||
executors,
|
||||
instruction_recorder,
|
||||
|
@ -1237,7 +1245,7 @@ impl MessageProcessor {
|
|||
executors: Rc<RefCell<Executors>>,
|
||||
instruction_recorders: Option<&[InstructionRecorder]>,
|
||||
feature_set: Arc<FeatureSet>,
|
||||
bpf_compute_budget: BpfComputeBudget,
|
||||
compute_budget: ComputeBudget,
|
||||
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
||||
timings: &mut ExecuteDetailsTimings,
|
||||
account_db: Arc<Accounts>,
|
||||
|
@ -1261,7 +1269,7 @@ impl MessageProcessor {
|
|||
instruction_recorder,
|
||||
instruction_index,
|
||||
feature_set.clone(),
|
||||
bpf_compute_budget,
|
||||
compute_budget,
|
||||
compute_meter.clone(),
|
||||
timings,
|
||||
account_db.clone(),
|
||||
|
@ -1338,7 +1346,7 @@ mod tests {
|
|||
&accounts,
|
||||
&[],
|
||||
None,
|
||||
BpfComputeBudget::default(),
|
||||
ComputeBudget::default(),
|
||||
Rc::new(RefCell::new(MockComputeMeter::default())),
|
||||
Rc::new(RefCell::new(Executors::default())),
|
||||
None,
|
||||
|
@ -1952,7 +1960,7 @@ mod tests {
|
|||
executors.clone(),
|
||||
None,
|
||||
Arc::new(FeatureSet::all_enabled()),
|
||||
BpfComputeBudget::new(),
|
||||
ComputeBudget::new(),
|
||||
Rc::new(RefCell::new(MockComputeMeter::default())),
|
||||
&mut ExecuteDetailsTimings::default(),
|
||||
Arc::new(Accounts::default()),
|
||||
|
@ -1980,7 +1988,7 @@ mod tests {
|
|||
executors.clone(),
|
||||
None,
|
||||
Arc::new(FeatureSet::all_enabled()),
|
||||
BpfComputeBudget::new(),
|
||||
ComputeBudget::new(),
|
||||
Rc::new(RefCell::new(MockComputeMeter::default())),
|
||||
&mut ExecuteDetailsTimings::default(),
|
||||
Arc::new(Accounts::default()),
|
||||
|
@ -2012,7 +2020,7 @@ mod tests {
|
|||
executors,
|
||||
None,
|
||||
Arc::new(FeatureSet::all_enabled()),
|
||||
BpfComputeBudget::new(),
|
||||
ComputeBudget::new(),
|
||||
Rc::new(RefCell::new(MockComputeMeter::default())),
|
||||
&mut ExecuteDetailsTimings::default(),
|
||||
Arc::new(Accounts::default()),
|
||||
|
@ -2136,7 +2144,7 @@ mod tests {
|
|||
executors.clone(),
|
||||
None,
|
||||
Arc::new(FeatureSet::all_enabled()),
|
||||
BpfComputeBudget::new(),
|
||||
ComputeBudget::new(),
|
||||
Rc::new(RefCell::new(MockComputeMeter::default())),
|
||||
&mut ExecuteDetailsTimings::default(),
|
||||
Arc::new(Accounts::default()),
|
||||
|
@ -2168,7 +2176,7 @@ mod tests {
|
|||
executors.clone(),
|
||||
None,
|
||||
Arc::new(FeatureSet::all_enabled()),
|
||||
BpfComputeBudget::new(),
|
||||
ComputeBudget::new(),
|
||||
Rc::new(RefCell::new(MockComputeMeter::default())),
|
||||
&mut ExecuteDetailsTimings::default(),
|
||||
Arc::new(Accounts::default()),
|
||||
|
@ -2198,7 +2206,7 @@ mod tests {
|
|||
executors,
|
||||
None,
|
||||
Arc::new(FeatureSet::all_enabled()),
|
||||
BpfComputeBudget::new(),
|
||||
ComputeBudget::new(),
|
||||
Rc::new(RefCell::new(MockComputeMeter::default())),
|
||||
&mut ExecuteDetailsTimings::default(),
|
||||
Arc::new(Accounts::default()),
|
||||
|
@ -2300,7 +2308,7 @@ mod tests {
|
|||
&accounts,
|
||||
programs.as_slice(),
|
||||
None,
|
||||
BpfComputeBudget::default(),
|
||||
ComputeBudget::default(),
|
||||
Rc::new(RefCell::new(MockComputeMeter::default())),
|
||||
Rc::new(RefCell::new(Executors::default())),
|
||||
None,
|
||||
|
@ -2357,7 +2365,7 @@ mod tests {
|
|||
&accounts,
|
||||
programs.as_slice(),
|
||||
None,
|
||||
BpfComputeBudget::default(),
|
||||
ComputeBudget::default(),
|
||||
Rc::new(RefCell::new(MockComputeMeter::default())),
|
||||
Rc::new(RefCell::new(Executors::default())),
|
||||
None,
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
#![cfg(feature = "full")]
|
||||
|
||||
use crate::{
|
||||
process_instruction::BpfComputeBudget,
|
||||
transaction::{Transaction, TransactionError},
|
||||
};
|
||||
use crate::transaction::{Transaction, TransactionError};
|
||||
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
|
||||
use solana_sdk::{
|
||||
borsh::try_from_slice_unchecked,
|
||||
|
@ -32,70 +29,126 @@ pub enum ComputeBudgetInstruction {
|
|||
/// allowed to consume.
|
||||
RequestUnits(u64),
|
||||
}
|
||||
|
||||
/// Create a `ComputeBudgetInstruction::RequestUnits` `Instruction`
|
||||
pub fn request_units(units: u64) -> Instruction {
|
||||
Instruction::new_with_borsh(id(), &ComputeBudgetInstruction::RequestUnits(units), vec![])
|
||||
impl ComputeBudgetInstruction {
|
||||
/// Create a `ComputeBudgetInstruction::RequestUnits` `Instruction`
|
||||
pub fn request_units(units: u64) -> Instruction {
|
||||
Instruction::new_with_borsh(id(), &ComputeBudgetInstruction::RequestUnits(units), vec![])
|
||||
}
|
||||
}
|
||||
|
||||
pub fn process_request(
|
||||
compute_budget: &mut BpfComputeBudget,
|
||||
tx: &Transaction,
|
||||
) -> Result<(), TransactionError> {
|
||||
let error = TransactionError::InstructionError(0, InstructionError::InvalidInstructionData);
|
||||
// Compute budget instruction must be in 1st or 2nd instruction (avoid nonce marker)
|
||||
for instruction in tx.message().instructions.iter().take(2) {
|
||||
if check_id(instruction.program_id(&tx.message().account_keys)) {
|
||||
let ComputeBudgetInstruction::RequestUnits(units) =
|
||||
try_from_slice_unchecked::<ComputeBudgetInstruction>(&instruction.data)
|
||||
.map_err(|_| error.clone())?;
|
||||
if units > MAX_UNITS {
|
||||
return Err(error);
|
||||
}
|
||||
compute_budget.max_units = units;
|
||||
#[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,
|
||||
/// Optional program heap region size, if `None` then loader default
|
||||
pub heap_size: Option<usize>,
|
||||
}
|
||||
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,
|
||||
heap_size: None,
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
pub fn process_transaction(&mut self, tx: &Transaction) -> Result<(), TransactionError> {
|
||||
let error = TransactionError::InstructionError(0, InstructionError::InvalidInstructionData);
|
||||
// Compute budget instruction must be in 1st or 2nd instruction (avoid nonce marker)
|
||||
for instruction in tx.message().instructions.iter().take(2) {
|
||||
if check_id(instruction.program_id(&tx.message().account_keys)) {
|
||||
let ComputeBudgetInstruction::RequestUnits(units) =
|
||||
try_from_slice_unchecked::<ComputeBudgetInstruction>(&instruction.data)
|
||||
.map_err(|_| error.clone())?;
|
||||
if units > MAX_UNITS {
|
||||
return Err(error);
|
||||
}
|
||||
self.max_units = units;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
compute_budget, hash::Hash, message::Message, pubkey::Pubkey, signature::Keypair,
|
||||
signer::Signer,
|
||||
};
|
||||
use crate::{hash::Hash, message::Message, pubkey::Pubkey, signature::Keypair, signer::Signer};
|
||||
|
||||
#[test]
|
||||
fn test_process_request() {
|
||||
fn test_process_transaction() {
|
||||
let payer_keypair = Keypair::new();
|
||||
let mut compute_budget = BpfComputeBudget::default();
|
||||
let mut compute_budget = ComputeBudget::default();
|
||||
|
||||
let tx = Transaction::new(
|
||||
&[&payer_keypair],
|
||||
Message::new(&[], Some(&payer_keypair.pubkey())),
|
||||
Hash::default(),
|
||||
);
|
||||
process_request(&mut compute_budget, &tx).unwrap();
|
||||
assert_eq!(compute_budget, BpfComputeBudget::default());
|
||||
compute_budget.process_transaction(&tx).unwrap();
|
||||
assert_eq!(compute_budget, ComputeBudget::default());
|
||||
|
||||
let tx = Transaction::new(
|
||||
&[&payer_keypair],
|
||||
Message::new(
|
||||
&[
|
||||
compute_budget::request_units(1),
|
||||
ComputeBudgetInstruction::request_units(1),
|
||||
Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]),
|
||||
],
|
||||
Some(&payer_keypair.pubkey()),
|
||||
),
|
||||
Hash::default(),
|
||||
);
|
||||
process_request(&mut compute_budget, &tx).unwrap();
|
||||
compute_budget.process_transaction(&tx).unwrap();
|
||||
assert_eq!(
|
||||
compute_budget,
|
||||
BpfComputeBudget {
|
||||
ComputeBudget {
|
||||
max_units: 1,
|
||||
..BpfComputeBudget::default()
|
||||
..ComputeBudget::default()
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -103,14 +156,14 @@ mod tests {
|
|||
&[&payer_keypair],
|
||||
Message::new(
|
||||
&[
|
||||
compute_budget::request_units(MAX_UNITS + 1),
|
||||
ComputeBudgetInstruction::request_units(MAX_UNITS + 1),
|
||||
Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]),
|
||||
],
|
||||
Some(&payer_keypair.pubkey()),
|
||||
),
|
||||
Hash::default(),
|
||||
);
|
||||
let result = process_request(&mut compute_budget, &tx);
|
||||
let result = compute_budget.process_transaction(&tx);
|
||||
assert_eq!(
|
||||
result,
|
||||
Err(TransactionError::InstructionError(
|
||||
|
@ -124,18 +177,18 @@ mod tests {
|
|||
Message::new(
|
||||
&[
|
||||
Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]),
|
||||
compute_budget::request_units(MAX_UNITS),
|
||||
ComputeBudgetInstruction::request_units(MAX_UNITS),
|
||||
],
|
||||
Some(&payer_keypair.pubkey()),
|
||||
),
|
||||
Hash::default(),
|
||||
);
|
||||
process_request(&mut compute_budget, &tx).unwrap();
|
||||
compute_budget.process_transaction(&tx).unwrap();
|
||||
assert_eq!(
|
||||
compute_budget,
|
||||
BpfComputeBudget {
|
||||
ComputeBudget {
|
||||
max_units: MAX_UNITS,
|
||||
..BpfComputeBudget::default()
|
||||
..ComputeBudget::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![cfg(feature = "full")]
|
||||
|
||||
use crate::{
|
||||
account::{ReadableAccount, WritableAccount},
|
||||
account_utils::State as AccountUtilsState,
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#![cfg(feature = "full")]
|
||||
|
||||
use solana_sdk::{
|
||||
account::AccountSharedData,
|
||||
compute_budget::ComputeBudget,
|
||||
instruction::{CompiledInstruction, Instruction, InstructionError},
|
||||
keyed_account::{create_keyed_accounts_unified, KeyedAccount},
|
||||
pubkey::Pubkey,
|
||||
|
@ -76,6 +79,8 @@ pub trait InvokeContext {
|
|||
/// Get this invocation's logger
|
||||
fn get_logger(&self) -> Rc<RefCell<dyn Logger>>;
|
||||
/// Get this invocation's compute budget
|
||||
#[allow(deprecated)]
|
||||
#[deprecated(since = "1.8.0", note = "please use `get_compute_budget` instead")]
|
||||
fn get_bpf_compute_budget(&self) -> &BpfComputeBudget;
|
||||
/// Get this invocation's compute meter
|
||||
fn get_compute_meter(&self) -> Rc<RefCell<dyn ComputeMeter>>;
|
||||
|
@ -100,6 +105,8 @@ pub trait InvokeContext {
|
|||
);
|
||||
/// Get sysvar data
|
||||
fn get_sysvar_data(&self, id: &Pubkey) -> Option<Rc<Vec<u8>>>;
|
||||
/// Get this invocation's compute budget
|
||||
fn get_compute_budget(&self) -> &ComputeBudget;
|
||||
}
|
||||
|
||||
/// Convenience macro to log a message with an `Rc<RefCell<dyn Logger>>`
|
||||
|
@ -147,7 +154,8 @@ pub fn get_sysvar<T: Sysvar>(
|
|||
})
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, AbiExample, PartialEq)]
|
||||
#[deprecated(since = "1.8.0", note = "please use `ComputeBudget` instead")]
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct BpfComputeBudget {
|
||||
/// Number of compute units that an instruction is allowed. Compute units
|
||||
/// are consumed by program execution, resources they use, etc...
|
||||
|
@ -182,30 +190,60 @@ pub struct BpfComputeBudget {
|
|||
/// Optional program heap region size, if `None` then loader default
|
||||
pub heap_size: Option<usize>,
|
||||
}
|
||||
impl Default for BpfComputeBudget {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
#[allow(deprecated)]
|
||||
impl From<ComputeBudget> for BpfComputeBudget {
|
||||
fn from(item: ComputeBudget) -> Self {
|
||||
BpfComputeBudget {
|
||||
max_units: item.max_units,
|
||||
log_64_units: item.log_64_units,
|
||||
create_program_address_units: item.create_program_address_units,
|
||||
invoke_units: item.invoke_units,
|
||||
max_invoke_depth: item.max_invoke_depth,
|
||||
sha256_base_cost: item.sha256_base_cost,
|
||||
sha256_byte_cost: item.sha256_byte_cost,
|
||||
max_call_depth: item.max_call_depth,
|
||||
stack_frame_size: item.stack_frame_size,
|
||||
log_pubkey_units: item.log_pubkey_units,
|
||||
max_cpi_instruction_size: item.max_cpi_instruction_size,
|
||||
cpi_bytes_per_unit: item.cpi_bytes_per_unit,
|
||||
sysvar_base_cost: item.sysvar_base_cost,
|
||||
secp256k1_recover_cost: item.secp256k1_recover_cost,
|
||||
heap_size: item.heap_size,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(deprecated)]
|
||||
impl From<BpfComputeBudget> for ComputeBudget {
|
||||
fn from(item: BpfComputeBudget) -> Self {
|
||||
ComputeBudget {
|
||||
max_units: item.max_units,
|
||||
log_64_units: item.log_64_units,
|
||||
create_program_address_units: item.create_program_address_units,
|
||||
invoke_units: item.invoke_units,
|
||||
max_invoke_depth: item.max_invoke_depth,
|
||||
sha256_base_cost: item.sha256_base_cost,
|
||||
sha256_byte_cost: item.sha256_byte_cost,
|
||||
max_call_depth: item.max_call_depth,
|
||||
stack_frame_size: item.stack_frame_size,
|
||||
log_pubkey_units: item.log_pubkey_units,
|
||||
max_cpi_instruction_size: item.max_cpi_instruction_size,
|
||||
cpi_bytes_per_unit: item.cpi_bytes_per_unit,
|
||||
sysvar_base_cost: item.sysvar_base_cost,
|
||||
secp256k1_recover_cost: item.secp256k1_recover_cost,
|
||||
heap_size: item.heap_size,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(deprecated)]
|
||||
impl Default for BpfComputeBudget {
|
||||
fn default() -> Self {
|
||||
ComputeBudget::default().into()
|
||||
}
|
||||
}
|
||||
#[allow(deprecated)]
|
||||
impl BpfComputeBudget {
|
||||
pub fn new() -> Self {
|
||||
BpfComputeBudget {
|
||||
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,
|
||||
heap_size: None,
|
||||
}
|
||||
BpfComputeBudget::default()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,9 +374,12 @@ impl Logger for MockLogger {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
pub struct MockInvokeContext<'a> {
|
||||
pub invoke_stack: Vec<InvokeContextStackFrame<'a>>,
|
||||
pub logger: MockLogger,
|
||||
pub compute_budget: ComputeBudget,
|
||||
#[allow(deprecated)]
|
||||
pub bpf_compute_budget: BpfComputeBudget,
|
||||
pub compute_meter: MockComputeMeter,
|
||||
pub programs: Vec<(Pubkey, ProcessInstructionWithContext)>,
|
||||
|
@ -348,11 +389,13 @@ pub struct MockInvokeContext<'a> {
|
|||
}
|
||||
impl<'a> MockInvokeContext<'a> {
|
||||
pub fn new(keyed_accounts: Vec<KeyedAccount<'a>>) -> Self {
|
||||
let bpf_compute_budget = BpfComputeBudget::default();
|
||||
let compute_budget = ComputeBudget::default();
|
||||
let mut invoke_context = MockInvokeContext {
|
||||
invoke_stack: Vec::with_capacity(bpf_compute_budget.max_invoke_depth),
|
||||
invoke_stack: Vec::with_capacity(compute_budget.max_invoke_depth),
|
||||
logger: MockLogger::default(),
|
||||
bpf_compute_budget,
|
||||
compute_budget,
|
||||
#[allow(deprecated)]
|
||||
bpf_compute_budget: compute_budget.into(),
|
||||
compute_meter: MockComputeMeter {
|
||||
remaining: std::i64::MAX as u64,
|
||||
},
|
||||
|
@ -442,7 +485,9 @@ impl<'a> InvokeContext for MockInvokeContext<'a> {
|
|||
fn get_logger(&self) -> Rc<RefCell<dyn Logger>> {
|
||||
Rc::new(RefCell::new(self.logger.clone()))
|
||||
}
|
||||
#[allow(deprecated)]
|
||||
fn get_bpf_compute_budget(&self) -> &BpfComputeBudget {
|
||||
#[allow(deprecated)]
|
||||
&self.bpf_compute_budget
|
||||
}
|
||||
fn get_compute_meter(&self) -> Rc<RefCell<dyn ComputeMeter>> {
|
||||
|
@ -477,4 +522,7 @@ impl<'a> InvokeContext for MockInvokeContext<'a> {
|
|||
.iter()
|
||||
.find_map(|(key, sysvar)| if id == key { sysvar.clone() } else { None })
|
||||
}
|
||||
fn get_compute_budget(&self) -> &ComputeBudget {
|
||||
&self.compute_budget
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue