Add Bank::set_bpf_compute_budget()

This commit is contained in:
Michael Vines 2020-10-28 13:16:13 -07:00
parent 66e51a7363
commit 7d686b72a0
7 changed files with 77 additions and 59 deletions

View File

@ -24,7 +24,7 @@ use solana_sdk::{
instruction::{AccountMeta, CompiledInstruction, Instruction, InstructionError}, instruction::{AccountMeta, CompiledInstruction, Instruction, InstructionError},
keyed_account::KeyedAccount, keyed_account::KeyedAccount,
message::Message, message::Message,
process_instruction::{ComputeBudget, InvokeContext, MockInvokeContext}, process_instruction::{BpfComputeBudget, InvokeContext, MockInvokeContext},
pubkey::Pubkey, pubkey::Pubkey,
signature::{Keypair, Signer}, signature::{Keypair, Signer},
sysvar::{clock, fees, rent, slot_hashes, stake_history}, sysvar::{clock, fees, rent, slot_hashes, stake_history},
@ -721,14 +721,14 @@ fn test_program_bpf_call_depth() {
let instruction = Instruction::new( let instruction = Instruction::new(
program_id, program_id,
&(ComputeBudget::default().max_call_depth - 1), &(BpfComputeBudget::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);
assert!(result.is_ok()); assert!(result.is_ok());
let instruction = let instruction =
Instruction::new(program_id, &ComputeBudget::default().max_call_depth, vec![]); Instruction::new(program_id, &BpfComputeBudget::default().max_call_depth, vec![]);
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction); let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction);
assert!(result.is_err()); assert!(result.is_err());
} }

View File

@ -21,7 +21,7 @@ use solana_sdk::{
bpf_loader, bpf_loader_deprecated, bpf_loader, bpf_loader_deprecated,
decode_error::DecodeError, decode_error::DecodeError,
entrypoint::SUCCESS, entrypoint::SUCCESS,
feature_set::{bpf_just_in_time_compilation, compute_budget_balancing}, feature_set::{bpf_compute_budget_balancing, bpf_just_in_time_compilation},
instruction::InstructionError, instruction::InstructionError,
keyed_account::{is_executable, next_keyed_account, KeyedAccount}, keyed_account::{is_executable, next_keyed_account, KeyedAccount},
loader_instruction::LoaderInstruction, loader_instruction::LoaderInstruction,
@ -100,7 +100,7 @@ pub fn create_and_cache_executor(
.map_err(|e| map_ebpf_error(invoke_context, e))?; .map_err(|e| map_ebpf_error(invoke_context, e))?;
bpf_verifier::check( bpf_verifier::check(
elf_bytes, elf_bytes,
!invoke_context.is_feature_active(&compute_budget_balancing::id()), !invoke_context.is_feature_active(&bpf_compute_budget_balancing::id()),
) )
.map_err(|e| map_ebpf_error(invoke_context, EbpfError::UserError(e)))?; .map_err(|e| map_ebpf_error(invoke_context, EbpfError::UserError(e)))?;
let executor = Arc::new(BPFExecutor { executable }); let executor = Arc::new(BPFExecutor { executable });
@ -122,12 +122,12 @@ pub fn create_vm<'a>(
) -> Result<EbpfVm<'a, BPFError, ThisInstructionMeter>, EbpfError<BPFError>> { ) -> Result<EbpfVm<'a, BPFError, ThisInstructionMeter>, EbpfError<BPFError>> {
let heap = vec![0_u8; DEFAULT_HEAP_SIZE]; let heap = vec![0_u8; DEFAULT_HEAP_SIZE];
let heap_region = MemoryRegion::new_from_slice(&heap, MM_HEAP_START, true); let heap_region = MemoryRegion::new_from_slice(&heap, MM_HEAP_START, true);
let compute_budget = invoke_context.get_compute_budget(); let bpf_compute_budget = invoke_context.get_bpf_compute_budget();
let mut vm = EbpfVm::new( let mut vm = EbpfVm::new(
executable, executable,
Config { Config {
max_call_depth: compute_budget.max_call_depth, max_call_depth: bpf_compute_budget.max_call_depth,
stack_frame_size: compute_budget.stack_frame_size, stack_frame_size: bpf_compute_budget.stack_frame_size,
}, },
parameter_bytes, parameter_bytes,
&[heap_region], &[heap_region],
@ -329,7 +329,7 @@ mod tests {
account::Account, account::Account,
feature_set::FeatureSet, feature_set::FeatureSet,
instruction::InstructionError, instruction::InstructionError,
process_instruction::{ComputeBudget, MockInvokeContext}, process_instruction::{BpfComputeBudget, MockInvokeContext},
rent::Rent, rent::Rent,
}; };
use std::{cell::RefCell, fs::File, io::Read, ops::Range, rc::Rc}; use std::{cell::RefCell, fs::File, io::Read, ops::Range, rc::Rc};
@ -554,7 +554,7 @@ mod tests {
vec![], vec![],
&[], &[],
None, None,
ComputeBudget { BpfComputeBudget {
max_units: 1, max_units: 1,
log_units: 100, log_units: 100,
log_64_units: 100, log_64_units: 100,

View File

@ -94,7 +94,7 @@ pub fn register_syscalls<'a>(
invoke_context: &'a mut dyn InvokeContext, invoke_context: &'a mut dyn InvokeContext,
heap: Vec<u8>, heap: Vec<u8>,
) -> Result<(), EbpfError<BPFError>> { ) -> Result<(), EbpfError<BPFError>> {
let compute_budget = invoke_context.get_compute_budget(); let bpf_compute_budget = invoke_context.get_bpf_compute_budget();
// Syscall functions common across languages // Syscall functions common across languages
@ -106,7 +106,7 @@ pub fn register_syscalls<'a>(
vm.register_syscall( vm.register_syscall(
hash_symbol_name(b"sol_log_"), hash_symbol_name(b"sol_log_"),
Syscall::Object(Box::new(SyscallLog { Syscall::Object(Box::new(SyscallLog {
cost: compute_budget.log_units, cost: bpf_compute_budget.log_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,
@ -115,7 +115,7 @@ pub fn register_syscalls<'a>(
vm.register_syscall( vm.register_syscall(
hash_symbol_name(b"sol_log_64_"), hash_symbol_name(b"sol_log_64_"),
Syscall::Object(Box::new(SyscallLogU64 { Syscall::Object(Box::new(SyscallLogU64 {
cost: compute_budget.log_64_units, cost: bpf_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(),
})), })),
@ -135,7 +135,7 @@ pub fn register_syscalls<'a>(
vm.register_syscall( vm.register_syscall(
hash_symbol_name(b"sol_log_pubkey"), hash_symbol_name(b"sol_log_pubkey"),
Syscall::Object(Box::new(SyscallLogPubkey { Syscall::Object(Box::new(SyscallLogPubkey {
cost: compute_budget.log_pubkey_units, cost: bpf_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,
@ -147,8 +147,8 @@ pub fn register_syscalls<'a>(
vm.register_syscall( vm.register_syscall(
hash_symbol_name(b"sol_sha256"), hash_symbol_name(b"sol_sha256"),
Syscall::Object(Box::new(SyscallSha256 { Syscall::Object(Box::new(SyscallSha256 {
sha256_base_cost: compute_budget.sha256_base_cost, sha256_base_cost: bpf_compute_budget.sha256_base_cost,
sha256_byte_cost: compute_budget.sha256_byte_cost, sha256_byte_cost: bpf_compute_budget.sha256_byte_cost,
compute_meter: invoke_context.get_compute_meter(), compute_meter: invoke_context.get_compute_meter(),
loader_id, loader_id,
})), })),
@ -169,7 +169,7 @@ pub fn register_syscalls<'a>(
vm.register_syscall( vm.register_syscall(
hash_symbol_name(b"sol_create_program_address"), hash_symbol_name(b"sol_create_program_address"),
Syscall::Object(Box::new(SyscallCreateProgramAddress { Syscall::Object(Box::new(SyscallCreateProgramAddress {
cost: compute_budget.create_program_address_units, cost: bpf_compute_budget.create_program_address_units,
compute_meter: invoke_context.get_compute_meter(), compute_meter: invoke_context.get_compute_meter(),
loader_id, loader_id,
})), })),
@ -1301,7 +1301,7 @@ fn call<'a>(
let mut invoke_context = syscall.get_context_mut()?; let mut invoke_context = syscall.get_context_mut()?;
invoke_context invoke_context
.get_compute_meter() .get_compute_meter()
.consume(invoke_context.get_compute_budget().invoke_units)?; .consume(invoke_context.get_bpf_compute_budget().invoke_units)?;
// Translate data passed from the VM // Translate data passed from the VM

View File

@ -51,7 +51,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::{Executor, ProcessInstructionWithContext}, process_instruction::{BpfComputeBudget, Executor, ProcessInstructionWithContext},
program_utils::limited_deserialize, program_utils::limited_deserialize,
pubkey::Pubkey, pubkey::Pubkey,
recent_blockhashes_account, recent_blockhashes_account,
@ -671,6 +671,8 @@ pub struct Bank {
/// The Message processor /// The Message processor
message_processor: MessageProcessor, message_processor: MessageProcessor,
bpf_compute_budget: Option<BpfComputeBudget>,
/// Builtin programs activated dynamically by feature /// Builtin programs activated dynamically by feature
feature_builtins: Arc<Vec<(Builtin, Pubkey)>>, feature_builtins: Arc<Vec<(Builtin, Pubkey)>>,
@ -807,6 +809,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,
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)),
@ -912,6 +915,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,
feature_builtins: new(), feature_builtins: new(),
last_vote_sync: new(), last_vote_sync: new(),
rewards: new(), rewards: new(),
@ -2353,6 +2357,9 @@ impl Bank {
let mut inner_instructions: Vec<Option<InnerInstructionsList>> = let mut inner_instructions: Vec<Option<InnerInstructionsList>> =
Vec::with_capacity(txs.len()); Vec::with_capacity(txs.len());
let mut transaction_logs: Vec<TransactionLogMessages> = Vec::with_capacity(txs.len()); let mut transaction_logs: Vec<TransactionLogMessages> = Vec::with_capacity(txs.len());
let bpf_compute_budget = self
.bpf_compute_budget
.unwrap_or_else(|| BpfComputeBudget::new(&self.feature_set));
let executed: Vec<TransactionProcessResult> = loaded_accounts let executed: Vec<TransactionProcessResult> = loaded_accounts
.iter_mut() .iter_mut()
@ -2391,6 +2398,7 @@ impl Bank {
executors.clone(), executors.clone(),
instruction_recorders.as_deref(), instruction_recorders.as_deref(),
self.feature_set.clone(), self.feature_set.clone(),
bpf_compute_budget,
); );
if enable_log_recording { if enable_log_recording {
@ -3358,6 +3366,10 @@ 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>) {
self.bpf_compute_budget = bpf_compute_budget;
}
pub fn hard_forks(&self) -> Arc<RwLock<HardForks>> { pub fn hard_forks(&self) -> Arc<RwLock<HardForks>> {
self.hard_forks.clone() self.hard_forks.clone()
} }

View File

@ -15,7 +15,8 @@ use solana_sdk::{
message::Message, message::Message,
native_loader, native_loader,
process_instruction::{ process_instruction::{
ComputeBudget, ComputeMeter, Executor, InvokeContext, Logger, ProcessInstructionWithContext, BpfComputeBudget, ComputeMeter, Executor, InvokeContext, Logger,
ProcessInstructionWithContext,
}, },
pubkey::Pubkey, pubkey::Pubkey,
rent::Rent, rent::Rent,
@ -206,7 +207,7 @@ pub struct ThisInvokeContext<'a> {
pre_accounts: Vec<PreAccount>, pre_accounts: Vec<PreAccount>,
programs: &'a [(Pubkey, ProcessInstructionWithContext)], programs: &'a [(Pubkey, ProcessInstructionWithContext)],
logger: Rc<RefCell<dyn Logger>>, logger: Rc<RefCell<dyn Logger>>,
compute_budget: ComputeBudget, bpf_compute_budget: 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>,
@ -219,12 +220,12 @@ impl<'a> ThisInvokeContext<'a> {
pre_accounts: Vec<PreAccount>, pre_accounts: Vec<PreAccount>,
programs: &'a [(Pubkey, ProcessInstructionWithContext)], programs: &'a [(Pubkey, ProcessInstructionWithContext)],
log_collector: Option<Rc<LogCollector>>, log_collector: Option<Rc<LogCollector>>,
compute_budget: ComputeBudget, bpf_compute_budget: BpfComputeBudget,
executors: Rc<RefCell<Executors>>, executors: Rc<RefCell<Executors>>,
instruction_recorder: Option<InstructionRecorder>, instruction_recorder: Option<InstructionRecorder>,
feature_set: Arc<FeatureSet>, feature_set: Arc<FeatureSet>,
) -> Self { ) -> Self {
let mut program_ids = Vec::with_capacity(compute_budget.max_invoke_depth); let mut program_ids = Vec::with_capacity(bpf_compute_budget.max_invoke_depth);
program_ids.push(*program_id); program_ids.push(*program_id);
Self { Self {
program_ids, program_ids,
@ -232,9 +233,9 @@ impl<'a> ThisInvokeContext<'a> {
pre_accounts, pre_accounts,
programs, programs,
logger: Rc::new(RefCell::new(ThisLogger { log_collector })), logger: Rc::new(RefCell::new(ThisLogger { log_collector })),
compute_budget, bpf_compute_budget,
compute_meter: Rc::new(RefCell::new(ThisComputeMeter { compute_meter: Rc::new(RefCell::new(ThisComputeMeter {
remaining: compute_budget.max_units, remaining: bpf_compute_budget.max_units,
})), })),
executors, executors,
instruction_recorder, instruction_recorder,
@ -244,7 +245,7 @@ impl<'a> ThisInvokeContext<'a> {
} }
impl<'a> InvokeContext for ThisInvokeContext<'a> { impl<'a> InvokeContext for ThisInvokeContext<'a> {
fn push(&mut self, key: &Pubkey) -> Result<(), InstructionError> { fn push(&mut self, key: &Pubkey) -> Result<(), InstructionError> {
if self.program_ids.len() > self.compute_budget.max_invoke_depth { if self.program_ids.len() > self.bpf_compute_budget.max_invoke_depth {
return Err(InstructionError::CallDepth); return Err(InstructionError::CallDepth);
} }
if self.program_ids.contains(key) && self.program_ids.last() != Some(key) { if self.program_ids.contains(key) && self.program_ids.last() != Some(key) {
@ -286,8 +287,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_compute_budget(&self) -> &ComputeBudget { fn get_bpf_compute_budget(&self) -> &BpfComputeBudget {
&self.compute_budget &self.bpf_compute_budget
} }
fn get_compute_meter(&self) -> Rc<RefCell<dyn ComputeMeter>> { fn get_compute_meter(&self) -> Rc<RefCell<dyn ComputeMeter>> {
self.compute_meter.clone() self.compute_meter.clone()
@ -412,10 +413,6 @@ impl MessageProcessor {
self.add_program(program_id, process_instruction); self.add_program(program_id, process_instruction);
} }
fn get_compute_budget(feature_set: &FeatureSet) -> ComputeBudget {
ComputeBudget::new(feature_set)
}
/// Create the KeyedAccounts that will be passed to the program /// Create the KeyedAccounts that will be passed to the program
fn create_keyed_accounts<'a>( fn create_keyed_accounts<'a>(
message: &'a Message, message: &'a Message,
@ -653,6 +650,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,
) -> Result<(), InstructionError> { ) -> Result<(), InstructionError> {
// Fixup the special instructions key if present // Fixup the special instructions key if present
// before the account pre-values are taken care of // before the account pre-values are taken care of
@ -676,7 +674,7 @@ impl MessageProcessor {
pre_accounts, pre_accounts,
&self.programs, &self.programs,
log_collector, log_collector,
Self::get_compute_budget(&feature_set), bpf_compute_budget,
executors, executors,
instruction_recorder, instruction_recorder,
feature_set, feature_set,
@ -709,6 +707,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,
) -> Result<(), TransactionError> { ) -> Result<(), TransactionError> {
for (instruction_index, instruction) in message.instructions.iter().enumerate() { for (instruction_index, instruction) in message.instructions.iter().enumerate() {
let instruction_recorder = instruction_recorders let instruction_recorder = instruction_recorders
@ -725,6 +724,7 @@ impl MessageProcessor {
instruction_recorder, instruction_recorder,
instruction_index, instruction_index,
feature_set.clone(), feature_set.clone(),
bpf_compute_budget,
) )
.map_err(|err| TransactionError::InstructionError(instruction_index as u8, err))?; .map_err(|err| TransactionError::InstructionError(instruction_index as u8, err))?;
} }
@ -769,7 +769,7 @@ mod tests {
pre_accounts, pre_accounts,
&[], &[],
None, None,
ComputeBudget::default(), BpfComputeBudget::default(),
Rc::new(RefCell::new(Executors::default())), Rc::new(RefCell::new(Executors::default())),
None, None,
Arc::new(FeatureSet::all_enabled()), Arc::new(FeatureSet::all_enabled()),
@ -1314,6 +1314,7 @@ mod tests {
executors.clone(), executors.clone(),
None, None,
Arc::new(FeatureSet::all_enabled()), Arc::new(FeatureSet::all_enabled()),
BpfComputeBudget::new(&FeatureSet::all_enabled()),
); );
assert_eq!(result, Ok(())); assert_eq!(result, Ok(()));
assert_eq!(accounts[0].borrow().lamports, 100); assert_eq!(accounts[0].borrow().lamports, 100);
@ -1337,6 +1338,7 @@ mod tests {
executors.clone(), executors.clone(),
None, None,
Arc::new(FeatureSet::all_enabled()), Arc::new(FeatureSet::all_enabled()),
BpfComputeBudget::new(&FeatureSet::all_enabled()),
); );
assert_eq!( assert_eq!(
result, result,
@ -1364,6 +1366,7 @@ mod tests {
executors, executors,
None, None,
Arc::new(FeatureSet::all_enabled()), Arc::new(FeatureSet::all_enabled()),
BpfComputeBudget::new(&FeatureSet::all_enabled()),
); );
assert_eq!( assert_eq!(
result, result,
@ -1475,6 +1478,7 @@ mod tests {
executors.clone(), executors.clone(),
None, None,
Arc::new(FeatureSet::all_enabled()), Arc::new(FeatureSet::all_enabled()),
BpfComputeBudget::new(&FeatureSet::all_enabled()),
); );
assert_eq!( assert_eq!(
result, result,
@ -1502,6 +1506,7 @@ mod tests {
executors.clone(), executors.clone(),
None, None,
Arc::new(FeatureSet::all_enabled()), Arc::new(FeatureSet::all_enabled()),
BpfComputeBudget::new(&FeatureSet::all_enabled()),
); );
assert_eq!(result, Ok(())); assert_eq!(result, Ok(()));
@ -1526,6 +1531,7 @@ mod tests {
executors, executors,
None, None,
Arc::new(FeatureSet::all_enabled()), Arc::new(FeatureSet::all_enabled()),
BpfComputeBudget::new(&FeatureSet::all_enabled()),
); );
assert_eq!(result, Ok(())); assert_eq!(result, Ok(()));
assert_eq!(accounts[0].borrow().lamports, 80); assert_eq!(accounts[0].borrow().lamports, 80);
@ -1600,7 +1606,7 @@ mod tests {
vec![owned_preaccount, not_owned_preaccount], vec![owned_preaccount, not_owned_preaccount],
&[], &[],
None, None,
ComputeBudget::default(), BpfComputeBudget::default(),
Rc::new(RefCell::new(Executors::default())), Rc::new(RefCell::new(Executors::default())),
None, None,
Arc::new(FeatureSet::all_enabled()), Arc::new(FeatureSet::all_enabled()),

View File

@ -34,7 +34,7 @@ pub mod bpf_loader2_program {
solana_sdk::declare_id!("DFBnrgThdzH4W6wZ12uGPoWcMnvfZj11EHnxHcVxLPhD"); solana_sdk::declare_id!("DFBnrgThdzH4W6wZ12uGPoWcMnvfZj11EHnxHcVxLPhD");
} }
pub mod compute_budget_balancing { pub mod bpf_compute_budget_balancing {
solana_sdk::declare_id!("HxvjqDSiF5sYdSYuCXsUnS8UeAoWsMT9iGoFP8pgV1mB"); solana_sdk::declare_id!("HxvjqDSiF5sYdSYuCXsUnS8UeAoWsMT9iGoFP8pgV1mB");
} }
@ -92,7 +92,7 @@ lazy_static! {
(inflation_kill_switch::id(), "inflation kill switch"), (inflation_kill_switch::id(), "inflation kill switch"),
(spl_token_v2_multisig_fix::id(), "spl-token multisig fix"), (spl_token_v2_multisig_fix::id(), "spl-token multisig fix"),
(bpf_loader2_program::id(), "bpf_loader2 program"), (bpf_loader2_program::id(), "bpf_loader2 program"),
(compute_budget_balancing::id(), "compute budget balancing"), (bpf_compute_budget_balancing::id(), "compute budget balancing"),
(sha256_syscall_enabled::id(), "sha256 syscall"), (sha256_syscall_enabled::id(), "sha256 syscall"),
(no_overflow_rent_distribution::id(), "no overflow rent distribution"), (no_overflow_rent_distribution::id(), "no overflow rent distribution"),
(ristretto_mul_syscall_enabled::id(), "ristretto multiply syscall"), (ristretto_mul_syscall_enabled::id(), "ristretto multiply syscall"),

View File

@ -1,7 +1,7 @@
use solana_sdk::{ use solana_sdk::{
account::Account, account::Account,
feature_set::{ feature_set::{
compute_budget_balancing, max_invoke_depth_4, max_program_call_depth_64, bpf_compute_budget_balancing, max_invoke_depth_4, max_program_call_depth_64,
pubkey_log_syscall_enabled, FeatureSet, pubkey_log_syscall_enabled, FeatureSet,
}, },
instruction::{CompiledInstruction, Instruction, InstructionError}, instruction::{CompiledInstruction, Instruction, InstructionError},
@ -47,7 +47,7 @@ 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
fn get_compute_budget(&self) -> &ComputeBudget; 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>>;
/// Loaders may need to do work in order to execute a program. Cache /// Loaders may need to do work in order to execute a program. Cache
@ -61,8 +61,8 @@ pub trait InvokeContext {
fn is_feature_active(&self, feature_id: &Pubkey) -> bool; fn is_feature_active(&self, feature_id: &Pubkey) -> bool;
} }
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug, AbiExample)]
pub struct ComputeBudget { 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...
pub max_units: u64, pub max_units: u64,
@ -88,16 +88,16 @@ pub struct ComputeBudget {
/// Number of compute units consumed by logging a `Pubkey` /// Number of compute units consumed by logging a `Pubkey`
pub log_pubkey_units: u64, pub log_pubkey_units: u64,
} }
impl Default for ComputeBudget { impl Default for BpfComputeBudget {
fn default() -> Self { fn default() -> Self {
Self::new(&FeatureSet::all_enabled()) Self::new(&FeatureSet::all_enabled())
} }
} }
impl ComputeBudget { impl BpfComputeBudget {
pub fn new(feature_set: &FeatureSet) -> Self { pub fn new(feature_set: &FeatureSet) -> Self {
let mut compute_budget = let mut bpf_compute_budget =
// Original // Original
ComputeBudget { BpfComputeBudget {
max_units: 100_000, max_units: 100_000,
log_units: 0, log_units: 0,
log_64_units: 0, log_64_units: 0,
@ -111,36 +111,36 @@ impl ComputeBudget {
log_pubkey_units: 0, log_pubkey_units: 0,
}; };
if feature_set.is_active(&compute_budget_balancing::id()) { if feature_set.is_active(&bpf_compute_budget_balancing::id()) {
compute_budget = ComputeBudget { bpf_compute_budget = BpfComputeBudget {
max_units: 200_000, max_units: 200_000,
log_units: 100, log_units: 100,
log_64_units: 100, log_64_units: 100,
create_program_address_units: 1500, create_program_address_units: 1500,
invoke_units: 1000, invoke_units: 1000,
..compute_budget ..bpf_compute_budget
}; };
} }
if feature_set.is_active(&max_invoke_depth_4::id()) { if feature_set.is_active(&max_invoke_depth_4::id()) {
compute_budget = ComputeBudget { bpf_compute_budget = BpfComputeBudget {
max_invoke_depth: 4, max_invoke_depth: 4,
..compute_budget ..bpf_compute_budget
}; };
} }
if feature_set.is_active(&max_program_call_depth_64::id()) { if feature_set.is_active(&max_program_call_depth_64::id()) {
compute_budget = ComputeBudget { bpf_compute_budget = BpfComputeBudget {
max_call_depth: 64, max_call_depth: 64,
..compute_budget ..bpf_compute_budget
}; };
} }
if feature_set.is_active(&pubkey_log_syscall_enabled::id()) { if feature_set.is_active(&pubkey_log_syscall_enabled::id()) {
compute_budget = ComputeBudget { bpf_compute_budget = BpfComputeBudget {
log_pubkey_units: 100, log_pubkey_units: 100,
..compute_budget ..bpf_compute_budget
}; };
} }
compute_budget bpf_compute_budget
} }
} }
@ -206,7 +206,7 @@ impl Logger for MockLogger {
pub struct MockInvokeContext { pub struct MockInvokeContext {
pub key: Pubkey, pub key: Pubkey,
pub logger: MockLogger, pub logger: MockLogger,
pub compute_budget: ComputeBudget, pub bpf_compute_budget: BpfComputeBudget,
pub compute_meter: MockComputeMeter, pub compute_meter: MockComputeMeter,
} }
impl Default for MockInvokeContext { impl Default for MockInvokeContext {
@ -214,7 +214,7 @@ impl Default for MockInvokeContext {
MockInvokeContext { MockInvokeContext {
key: Pubkey::default(), key: Pubkey::default(),
logger: MockLogger::default(), logger: MockLogger::default(),
compute_budget: ComputeBudget::default(), bpf_compute_budget: BpfComputeBudget::default(),
compute_meter: MockComputeMeter { compute_meter: MockComputeMeter {
remaining: std::i64::MAX as u64, remaining: std::i64::MAX as u64,
}, },
@ -243,8 +243,8 @@ impl InvokeContext for MockInvokeContext {
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()))
} }
fn get_compute_budget(&self) -> &ComputeBudget { fn get_bpf_compute_budget(&self) -> &BpfComputeBudget {
&self.compute_budget &self.bpf_compute_budget
} }
fn get_compute_meter(&self) -> Rc<RefCell<dyn ComputeMeter>> { fn get_compute_meter(&self) -> Rc<RefCell<dyn ComputeMeter>> {
Rc::new(RefCell::new(self.compute_meter.clone())) Rc::new(RefCell::new(self.compute_meter.clone()))