Skip to content

Commit

Permalink
Program-Runtime: Add EnvironmentConfig to InvokeContext (#1059)
Browse files Browse the repository at this point in the history
* program-runtime: add `EnvironmentConfig` to `InvokeContext`

* move `blockhash` to `EnvironmentConfig`

* move `lamports_per_signature` to `EnvironmentConfig`

* move `feature_set` to `EnvironmentConfig`

* move `sysvar_cache` to `EnvironmentConfig`

* add `get_feature_set` getter
  • Loading branch information
buffalojoec authored May 1, 2024
1 parent 61a6f36 commit 34b76ac
Show file tree
Hide file tree
Showing 17 changed files with 214 additions and 149 deletions.
2 changes: 1 addition & 1 deletion ledger-tool/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ fn load_program<'a>(
};
let account_size = contents.len();
let program_runtime_environment = create_program_runtime_environment_v1(
&invoke_context.feature_set,
invoke_context.get_feature_set(),
invoke_context.get_compute_budget(),
false, /* deployment */
true, /* debugging_features */
Expand Down
73 changes: 53 additions & 20 deletions program-runtime/src/invoke_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,28 @@ impl BpfAllocator {
}
}

pub struct EnvironmentConfig<'a> {
pub blockhash: Hash,
pub feature_set: Arc<FeatureSet>,
pub lamports_per_signature: u64,
sysvar_cache: &'a SysvarCache,
}
impl<'a> EnvironmentConfig<'a> {
pub fn new(
blockhash: Hash,
feature_set: Arc<FeatureSet>,
lamports_per_signature: u64,
sysvar_cache: &'a SysvarCache,
) -> Self {
Self {
blockhash,
feature_set,
lamports_per_signature,
sysvar_cache,
}
}
}

pub struct SyscallContext {
pub allocator: BpfAllocator,
pub accounts_metadata: Vec<SerializedAccountMetadata>,
Expand All @@ -159,19 +181,19 @@ pub struct SerializedAccountMetadata {
pub vm_owner_addr: u64,
}

/// Main pipeline from runtime to program execution.
pub struct InvokeContext<'a> {
/// Information about the currently executing transaction.
pub transaction_context: &'a mut TransactionContext,
sysvar_cache: &'a SysvarCache,
/// Runtime configurations used to provision the invocation environment.
pub environment_config: EnvironmentConfig<'a>,
log_collector: Option<Rc<RefCell<LogCollector>>>,
compute_budget: ComputeBudget,
current_compute_budget: ComputeBudget,
compute_meter: RefCell<u64>,
pub programs_loaded_for_tx_batch: &'a ProgramCacheForTxBatch,
pub programs_modified_by_tx: &'a mut ProgramCacheForTxBatch,
pub feature_set: Arc<FeatureSet>,
pub timings: ExecuteDetailsTimings,
pub blockhash: Hash,
pub lamports_per_signature: u64,
pub syscall_context: Vec<Option<SyscallContext>>,
traces: Vec<Vec<[u64; 12]>>,
}
Expand All @@ -180,28 +202,22 @@ impl<'a> InvokeContext<'a> {
#[allow(clippy::too_many_arguments)]
pub fn new(
transaction_context: &'a mut TransactionContext,
sysvar_cache: &'a SysvarCache,
environment_config: EnvironmentConfig<'a>,
log_collector: Option<Rc<RefCell<LogCollector>>>,
compute_budget: ComputeBudget,
programs_loaded_for_tx_batch: &'a ProgramCacheForTxBatch,
programs_modified_by_tx: &'a mut ProgramCacheForTxBatch,
feature_set: Arc<FeatureSet>,
blockhash: Hash,
lamports_per_signature: u64,
) -> Self {
Self {
transaction_context,
sysvar_cache,
environment_config,
log_collector,
current_compute_budget: compute_budget,
compute_budget,
compute_meter: RefCell::new(compute_budget.compute_unit_limit),
programs_loaded_for_tx_batch,
programs_modified_by_tx,
feature_set,
timings: ExecuteDetailsTimings::default(),
blockhash,
lamports_per_signature,
syscall_context: Vec::new(),
traces: Vec::new(),
}
Expand All @@ -219,7 +235,7 @@ impl<'a> InvokeContext<'a> {
&self,
effective_slot: Slot,
) -> Result<&ProgramRuntimeEnvironments, InstructionError> {
let epoch_schedule = self.sysvar_cache.get_epoch_schedule()?;
let epoch_schedule = self.environment_config.sysvar_cache.get_epoch_schedule()?;
let epoch = epoch_schedule.get_epoch(effective_slot);
Ok(self
.programs_loaded_for_tx_batch
Expand Down Expand Up @@ -578,9 +594,21 @@ impl<'a> InvokeContext<'a> {
&self.current_compute_budget
}

/// Get the current feature set.
pub fn get_feature_set(&self) -> &FeatureSet {
&self.environment_config.feature_set
}

/// Set feature set.
///
/// Only use for tests and benchmarks.
pub fn mock_set_feature_set(&mut self, feature_set: Arc<FeatureSet>) {
self.environment_config.feature_set = feature_set;
}

/// Get cached sysvars
pub fn get_sysvar_cache(&self) -> &SysvarCache {
self.sysvar_cache
self.environment_config.sysvar_cache
}

// Should alignment be enforced during user pointer translation
Expand Down Expand Up @@ -645,8 +673,10 @@ macro_rules! with_mock_invoke_context {
},
std::sync::Arc,
$crate::{
compute_budget::ComputeBudget, invoke_context::InvokeContext,
loaded_programs::ProgramCacheForTxBatch, log_collector::LogCollector,
compute_budget::ComputeBudget,
invoke_context::{EnvironmentConfig, InvokeContext},
loaded_programs::ProgramCacheForTxBatch,
log_collector::LogCollector,
sysvar_cache::SysvarCache,
},
};
Expand Down Expand Up @@ -675,18 +705,21 @@ macro_rules! with_mock_invoke_context {
}
}
});
let environment_config = EnvironmentConfig::new(
Hash::default(),
Arc::new(FeatureSet::all_enabled()),
0,
&sysvar_cache,
);
let programs_loaded_for_tx_batch = ProgramCacheForTxBatch::default();
let mut programs_modified_by_tx = ProgramCacheForTxBatch::default();
let mut $invoke_context = InvokeContext::new(
&mut $transaction_context,
&sysvar_cache,
environment_config,
Some(LogCollector::new_ref()),
compute_budget,
&programs_loaded_for_tx_batch,
&mut programs_modified_by_tx,
Arc::new(FeatureSet::all_enabled()),
Hash::default(),
0,
);
};
}
Expand Down
6 changes: 3 additions & 3 deletions programs/address-lookup-table/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ impl Processor {
let table_key = *lookup_table_account.get_key();
let lookup_table_owner = *lookup_table_account.get_owner();
if !invoke_context
.feature_set
.get_feature_set()
.is_active(&feature_set::relax_authority_signer_check_for_lookup_table_creation::id())
&& !lookup_table_account.get_data().is_empty()
{
Expand All @@ -74,7 +74,7 @@ impl Processor {
instruction_context.try_borrow_instruction_account(transaction_context, 1)?;
let authority_key = *authority_account.get_key();
if !invoke_context
.feature_set
.get_feature_set()
.is_active(&feature_set::relax_authority_signer_check_for_lookup_table_creation::id())
&& !authority_account.is_signer()
{
Expand Down Expand Up @@ -127,7 +127,7 @@ impl Processor {
}

if invoke_context
.feature_set
.get_feature_set()
.is_active(&feature_set::relax_authority_signer_check_for_lookup_table_creation::id())
&& check_id(&lookup_table_owner)
{
Expand Down
6 changes: 3 additions & 3 deletions programs/bpf_loader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -957,7 +957,7 @@ fn process_loader_upgradeable_instruction(
}
UpgradeableLoaderInstruction::SetAuthorityChecked => {
if !invoke_context
.feature_set
.get_feature_set()
.is_active(&enable_bpf_loader_set_authority_checked_ix::id())
{
return Err(InstructionError::InvalidInstructionData);
Expand Down Expand Up @@ -1352,7 +1352,7 @@ fn execute<'a, 'b: 'a>(
#[cfg(all(not(target_os = "windows"), target_arch = "x86_64"))]
let use_jit = executable.get_compiled_program().is_some();
let direct_mapping = invoke_context
.feature_set
.get_feature_set()
.is_active(&bpf_account_data_direct_mapping::id());

let mut serialize_time = Measure::start("serialize");
Expand Down Expand Up @@ -1505,7 +1505,7 @@ pub mod test_utils {
pub fn load_all_invoked_programs(invoke_context: &mut InvokeContext) {
let mut load_program_metrics = LoadProgramMetrics::default();
let program_runtime_environment = create_program_runtime_environment_v1(
&invoke_context.feature_set,
invoke_context.get_feature_set(),
invoke_context.get_compute_budget(),
false, /* deployment */
false, /* debugging_features */
Expand Down
25 changes: 13 additions & 12 deletions programs/bpf_loader/src/syscalls/cpi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ impl<'a, 'b> CallerAccount<'a, 'b> {
account_metadata: &SerializedAccountMetadata,
) -> Result<CallerAccount<'a, 'b>, Error> {
let direct_mapping = invoke_context
.feature_set
.get_feature_set()
.is_active(&feature_set::bpf_account_data_direct_mapping::id());

if direct_mapping {
Expand Down Expand Up @@ -244,7 +244,7 @@ impl<'a, 'b> CallerAccount<'a, 'b> {
account_metadata: &SerializedAccountMetadata,
) -> Result<CallerAccount<'a, 'b>, Error> {
let direct_mapping = invoke_context
.feature_set
.get_feature_set()
.is_active(&feature_set::bpf_account_data_direct_mapping::id());

if direct_mapping {
Expand Down Expand Up @@ -452,7 +452,7 @@ impl SyscallInvokeSigned for SyscallInvokeSignedRust {

let ix_data_len = ix.data.len() as u64;
if invoke_context
.feature_set
.get_feature_set()
.is_active(&feature_set::loosen_cpi_size_restriction::id())
{
consume_compute_meter(
Expand Down Expand Up @@ -666,7 +666,7 @@ impl SyscallInvokeSigned for SyscallInvokeSignedC {

let ix_data_len = ix_c.data_len;
if invoke_context
.feature_set
.get_feature_set()
.is_active(&feature_set::loosen_cpi_size_restriction::id())
{
consume_compute_meter(
Expand Down Expand Up @@ -866,7 +866,7 @@ where
.accounts_metadata;

let direct_mapping = invoke_context
.feature_set
.get_feature_set()
.is_active(&feature_set::bpf_account_data_direct_mapping::id());

for (instruction_account_index, instruction_account) in instruction_accounts.iter().enumerate()
Expand Down Expand Up @@ -961,7 +961,7 @@ fn check_instruction_size(
invoke_context: &mut InvokeContext,
) -> Result<(), Error> {
if invoke_context
.feature_set
.get_feature_set()
.is_active(&feature_set::loosen_cpi_size_restriction::id())
{
let data_len = data_len as u64;
Expand Down Expand Up @@ -998,11 +998,11 @@ fn check_account_infos(
invoke_context: &mut InvokeContext,
) -> Result<(), Error> {
if invoke_context
.feature_set
.get_feature_set()
.is_active(&feature_set::loosen_cpi_size_restriction::id())
{
let max_cpi_account_infos = if invoke_context
.feature_set
.get_feature_set()
.is_active(&feature_set::increase_tx_account_lock_limit::id())
{
MAX_CPI_ACCOUNT_INFOS
Expand Down Expand Up @@ -1041,14 +1041,14 @@ fn check_authorized_program(
&& !(bpf_loader_upgradeable::is_upgrade_instruction(instruction_data)
|| bpf_loader_upgradeable::is_set_authority_instruction(instruction_data)
|| (invoke_context
.feature_set
.get_feature_set()
.is_active(&enable_bpf_loader_set_authority_checked_ix::id())
&& bpf_loader_upgradeable::is_set_authority_checked_instruction(
instruction_data,
))
|| bpf_loader_upgradeable::is_close_instruction(instruction_data)))
|| is_precompile(program_id, |feature_id: &Pubkey| {
invoke_context.feature_set.is_active(feature_id)
invoke_context.get_feature_set().is_active(feature_id)
})
{
return Err(Box::new(SyscallError::ProgramNotSupported(*program_id)));
Expand Down Expand Up @@ -1122,7 +1122,7 @@ fn cpi_common<S: SyscallInvokeSigned>(
//
// Synchronize the callee's account changes so the caller can see them.
let direct_mapping = invoke_context
.feature_set
.get_feature_set()
.is_active(&feature_set::bpf_account_data_direct_mapping::id());

if direct_mapping {
Expand Down Expand Up @@ -1629,8 +1629,9 @@ mod tests {
.map(|a| (a.0, a.1))
.collect::<Vec<TransactionAccount>>();
with_mock_invoke_context!($invoke_context, $transaction_context, transaction_accounts);
let feature_set = Arc::make_mut(&mut $invoke_context.feature_set);
let mut feature_set = $invoke_context.get_feature_set().clone();
feature_set.deactivate(&bpf_account_data_direct_mapping::id());
$invoke_context.mock_set_feature_set(Arc::new(feature_set));
$invoke_context
.transaction_context
.get_next_instruction_context()
Expand Down
6 changes: 3 additions & 3 deletions programs/bpf_loader/src/syscalls/mem_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ declare_builtin_function!(
mem_op_consume(invoke_context, n)?;

if invoke_context
.feature_set
.get_feature_set()
.is_active(&feature_set::bpf_account_data_direct_mapping::id())
{
let cmp_result = translate_type_mut::<i32>(
Expand Down Expand Up @@ -125,7 +125,7 @@ declare_builtin_function!(
mem_op_consume(invoke_context, n)?;

if invoke_context
.feature_set
.get_feature_set()
.is_active(&feature_set::bpf_account_data_direct_mapping::id())
{
memset_non_contiguous(dst_addr, c as u8, n, memory_mapping)
Expand All @@ -150,7 +150,7 @@ fn memmove(
memory_mapping: &MemoryMapping,
) -> Result<u64, Error> {
if invoke_context
.feature_set
.get_feature_set()
.is_active(&feature_set::bpf_account_data_direct_mapping::id())
{
memmove_non_contiguous(dst_addr, src_addr, n, memory_mapping)
Expand Down
Loading

0 comments on commit 34b76ac

Please sign in to comment.