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