Skip to content

Commit 34b76ac

Browse files
authored
Program-Runtime: Add EnvironmentConfig to InvokeContext (#1059)
* 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
1 parent 61a6f36 commit 34b76ac

File tree

17 files changed

+214
-149
lines changed

17 files changed

+214
-149
lines changed

ledger-tool/src/program.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ fn load_program<'a>(
325325
};
326326
let account_size = contents.len();
327327
let program_runtime_environment = create_program_runtime_environment_v1(
328-
&invoke_context.feature_set,
328+
invoke_context.get_feature_set(),
329329
invoke_context.get_compute_budget(),
330330
false, /* deployment */
331331
true, /* debugging_features */

program-runtime/src/invoke_context.rs

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,28 @@ impl BpfAllocator {
144144
}
145145
}
146146

147+
pub struct EnvironmentConfig<'a> {
148+
pub blockhash: Hash,
149+
pub feature_set: Arc<FeatureSet>,
150+
pub lamports_per_signature: u64,
151+
sysvar_cache: &'a SysvarCache,
152+
}
153+
impl<'a> EnvironmentConfig<'a> {
154+
pub fn new(
155+
blockhash: Hash,
156+
feature_set: Arc<FeatureSet>,
157+
lamports_per_signature: u64,
158+
sysvar_cache: &'a SysvarCache,
159+
) -> Self {
160+
Self {
161+
blockhash,
162+
feature_set,
163+
lamports_per_signature,
164+
sysvar_cache,
165+
}
166+
}
167+
}
168+
147169
pub struct SyscallContext {
148170
pub allocator: BpfAllocator,
149171
pub accounts_metadata: Vec<SerializedAccountMetadata>,
@@ -159,19 +181,19 @@ pub struct SerializedAccountMetadata {
159181
pub vm_owner_addr: u64,
160182
}
161183

184+
/// Main pipeline from runtime to program execution.
162185
pub struct InvokeContext<'a> {
186+
/// Information about the currently executing transaction.
163187
pub transaction_context: &'a mut TransactionContext,
164-
sysvar_cache: &'a SysvarCache,
188+
/// Runtime configurations used to provision the invocation environment.
189+
pub environment_config: EnvironmentConfig<'a>,
165190
log_collector: Option<Rc<RefCell<LogCollector>>>,
166191
compute_budget: ComputeBudget,
167192
current_compute_budget: ComputeBudget,
168193
compute_meter: RefCell<u64>,
169194
pub programs_loaded_for_tx_batch: &'a ProgramCacheForTxBatch,
170195
pub programs_modified_by_tx: &'a mut ProgramCacheForTxBatch,
171-
pub feature_set: Arc<FeatureSet>,
172196
pub timings: ExecuteDetailsTimings,
173-
pub blockhash: Hash,
174-
pub lamports_per_signature: u64,
175197
pub syscall_context: Vec<Option<SyscallContext>>,
176198
traces: Vec<Vec<[u64; 12]>>,
177199
}
@@ -180,28 +202,22 @@ impl<'a> InvokeContext<'a> {
180202
#[allow(clippy::too_many_arguments)]
181203
pub fn new(
182204
transaction_context: &'a mut TransactionContext,
183-
sysvar_cache: &'a SysvarCache,
205+
environment_config: EnvironmentConfig<'a>,
184206
log_collector: Option<Rc<RefCell<LogCollector>>>,
185207
compute_budget: ComputeBudget,
186208
programs_loaded_for_tx_batch: &'a ProgramCacheForTxBatch,
187209
programs_modified_by_tx: &'a mut ProgramCacheForTxBatch,
188-
feature_set: Arc<FeatureSet>,
189-
blockhash: Hash,
190-
lamports_per_signature: u64,
191210
) -> Self {
192211
Self {
193212
transaction_context,
194-
sysvar_cache,
213+
environment_config,
195214
log_collector,
196215
current_compute_budget: compute_budget,
197216
compute_budget,
198217
compute_meter: RefCell::new(compute_budget.compute_unit_limit),
199218
programs_loaded_for_tx_batch,
200219
programs_modified_by_tx,
201-
feature_set,
202220
timings: ExecuteDetailsTimings::default(),
203-
blockhash,
204-
lamports_per_signature,
205221
syscall_context: Vec::new(),
206222
traces: Vec::new(),
207223
}
@@ -219,7 +235,7 @@ impl<'a> InvokeContext<'a> {
219235
&self,
220236
effective_slot: Slot,
221237
) -> Result<&ProgramRuntimeEnvironments, InstructionError> {
222-
let epoch_schedule = self.sysvar_cache.get_epoch_schedule()?;
238+
let epoch_schedule = self.environment_config.sysvar_cache.get_epoch_schedule()?;
223239
let epoch = epoch_schedule.get_epoch(effective_slot);
224240
Ok(self
225241
.programs_loaded_for_tx_batch
@@ -578,9 +594,21 @@ impl<'a> InvokeContext<'a> {
578594
&self.current_compute_budget
579595
}
580596

597+
/// Get the current feature set.
598+
pub fn get_feature_set(&self) -> &FeatureSet {
599+
&self.environment_config.feature_set
600+
}
601+
602+
/// Set feature set.
603+
///
604+
/// Only use for tests and benchmarks.
605+
pub fn mock_set_feature_set(&mut self, feature_set: Arc<FeatureSet>) {
606+
self.environment_config.feature_set = feature_set;
607+
}
608+
581609
/// Get cached sysvars
582610
pub fn get_sysvar_cache(&self) -> &SysvarCache {
583-
self.sysvar_cache
611+
self.environment_config.sysvar_cache
584612
}
585613

586614
// Should alignment be enforced during user pointer translation
@@ -645,8 +673,10 @@ macro_rules! with_mock_invoke_context {
645673
},
646674
std::sync::Arc,
647675
$crate::{
648-
compute_budget::ComputeBudget, invoke_context::InvokeContext,
649-
loaded_programs::ProgramCacheForTxBatch, log_collector::LogCollector,
676+
compute_budget::ComputeBudget,
677+
invoke_context::{EnvironmentConfig, InvokeContext},
678+
loaded_programs::ProgramCacheForTxBatch,
679+
log_collector::LogCollector,
650680
sysvar_cache::SysvarCache,
651681
},
652682
};
@@ -675,18 +705,21 @@ macro_rules! with_mock_invoke_context {
675705
}
676706
}
677707
});
708+
let environment_config = EnvironmentConfig::new(
709+
Hash::default(),
710+
Arc::new(FeatureSet::all_enabled()),
711+
0,
712+
&sysvar_cache,
713+
);
678714
let programs_loaded_for_tx_batch = ProgramCacheForTxBatch::default();
679715
let mut programs_modified_by_tx = ProgramCacheForTxBatch::default();
680716
let mut $invoke_context = InvokeContext::new(
681717
&mut $transaction_context,
682-
&sysvar_cache,
718+
environment_config,
683719
Some(LogCollector::new_ref()),
684720
compute_budget,
685721
&programs_loaded_for_tx_batch,
686722
&mut programs_modified_by_tx,
687-
Arc::new(FeatureSet::all_enabled()),
688-
Hash::default(),
689-
0,
690723
);
691724
};
692725
}

programs/address-lookup-table/src/processor.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl Processor {
6161
let table_key = *lookup_table_account.get_key();
6262
let lookup_table_owner = *lookup_table_account.get_owner();
6363
if !invoke_context
64-
.feature_set
64+
.get_feature_set()
6565
.is_active(&feature_set::relax_authority_signer_check_for_lookup_table_creation::id())
6666
&& !lookup_table_account.get_data().is_empty()
6767
{
@@ -74,7 +74,7 @@ impl Processor {
7474
instruction_context.try_borrow_instruction_account(transaction_context, 1)?;
7575
let authority_key = *authority_account.get_key();
7676
if !invoke_context
77-
.feature_set
77+
.get_feature_set()
7878
.is_active(&feature_set::relax_authority_signer_check_for_lookup_table_creation::id())
7979
&& !authority_account.is_signer()
8080
{
@@ -127,7 +127,7 @@ impl Processor {
127127
}
128128

129129
if invoke_context
130-
.feature_set
130+
.get_feature_set()
131131
.is_active(&feature_set::relax_authority_signer_check_for_lookup_table_creation::id())
132132
&& check_id(&lookup_table_owner)
133133
{

programs/bpf_loader/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -957,7 +957,7 @@ fn process_loader_upgradeable_instruction(
957957
}
958958
UpgradeableLoaderInstruction::SetAuthorityChecked => {
959959
if !invoke_context
960-
.feature_set
960+
.get_feature_set()
961961
.is_active(&enable_bpf_loader_set_authority_checked_ix::id())
962962
{
963963
return Err(InstructionError::InvalidInstructionData);
@@ -1352,7 +1352,7 @@ fn execute<'a, 'b: 'a>(
13521352
#[cfg(all(not(target_os = "windows"), target_arch = "x86_64"))]
13531353
let use_jit = executable.get_compiled_program().is_some();
13541354
let direct_mapping = invoke_context
1355-
.feature_set
1355+
.get_feature_set()
13561356
.is_active(&bpf_account_data_direct_mapping::id());
13571357

13581358
let mut serialize_time = Measure::start("serialize");
@@ -1505,7 +1505,7 @@ pub mod test_utils {
15051505
pub fn load_all_invoked_programs(invoke_context: &mut InvokeContext) {
15061506
let mut load_program_metrics = LoadProgramMetrics::default();
15071507
let program_runtime_environment = create_program_runtime_environment_v1(
1508-
&invoke_context.feature_set,
1508+
invoke_context.get_feature_set(),
15091509
invoke_context.get_compute_budget(),
15101510
false, /* deployment */
15111511
false, /* debugging_features */

programs/bpf_loader/src/syscalls/cpi.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl<'a, 'b> CallerAccount<'a, 'b> {
107107
account_metadata: &SerializedAccountMetadata,
108108
) -> Result<CallerAccount<'a, 'b>, Error> {
109109
let direct_mapping = invoke_context
110-
.feature_set
110+
.get_feature_set()
111111
.is_active(&feature_set::bpf_account_data_direct_mapping::id());
112112

113113
if direct_mapping {
@@ -244,7 +244,7 @@ impl<'a, 'b> CallerAccount<'a, 'b> {
244244
account_metadata: &SerializedAccountMetadata,
245245
) -> Result<CallerAccount<'a, 'b>, Error> {
246246
let direct_mapping = invoke_context
247-
.feature_set
247+
.get_feature_set()
248248
.is_active(&feature_set::bpf_account_data_direct_mapping::id());
249249

250250
if direct_mapping {
@@ -452,7 +452,7 @@ impl SyscallInvokeSigned for SyscallInvokeSignedRust {
452452

453453
let ix_data_len = ix.data.len() as u64;
454454
if invoke_context
455-
.feature_set
455+
.get_feature_set()
456456
.is_active(&feature_set::loosen_cpi_size_restriction::id())
457457
{
458458
consume_compute_meter(
@@ -666,7 +666,7 @@ impl SyscallInvokeSigned for SyscallInvokeSignedC {
666666

667667
let ix_data_len = ix_c.data_len;
668668
if invoke_context
669-
.feature_set
669+
.get_feature_set()
670670
.is_active(&feature_set::loosen_cpi_size_restriction::id())
671671
{
672672
consume_compute_meter(
@@ -866,7 +866,7 @@ where
866866
.accounts_metadata;
867867

868868
let direct_mapping = invoke_context
869-
.feature_set
869+
.get_feature_set()
870870
.is_active(&feature_set::bpf_account_data_direct_mapping::id());
871871

872872
for (instruction_account_index, instruction_account) in instruction_accounts.iter().enumerate()
@@ -961,7 +961,7 @@ fn check_instruction_size(
961961
invoke_context: &mut InvokeContext,
962962
) -> Result<(), Error> {
963963
if invoke_context
964-
.feature_set
964+
.get_feature_set()
965965
.is_active(&feature_set::loosen_cpi_size_restriction::id())
966966
{
967967
let data_len = data_len as u64;
@@ -998,11 +998,11 @@ fn check_account_infos(
998998
invoke_context: &mut InvokeContext,
999999
) -> Result<(), Error> {
10001000
if invoke_context
1001-
.feature_set
1001+
.get_feature_set()
10021002
.is_active(&feature_set::loosen_cpi_size_restriction::id())
10031003
{
10041004
let max_cpi_account_infos = if invoke_context
1005-
.feature_set
1005+
.get_feature_set()
10061006
.is_active(&feature_set::increase_tx_account_lock_limit::id())
10071007
{
10081008
MAX_CPI_ACCOUNT_INFOS
@@ -1041,14 +1041,14 @@ fn check_authorized_program(
10411041
&& !(bpf_loader_upgradeable::is_upgrade_instruction(instruction_data)
10421042
|| bpf_loader_upgradeable::is_set_authority_instruction(instruction_data)
10431043
|| (invoke_context
1044-
.feature_set
1044+
.get_feature_set()
10451045
.is_active(&enable_bpf_loader_set_authority_checked_ix::id())
10461046
&& bpf_loader_upgradeable::is_set_authority_checked_instruction(
10471047
instruction_data,
10481048
))
10491049
|| bpf_loader_upgradeable::is_close_instruction(instruction_data)))
10501050
|| is_precompile(program_id, |feature_id: &Pubkey| {
1051-
invoke_context.feature_set.is_active(feature_id)
1051+
invoke_context.get_feature_set().is_active(feature_id)
10521052
})
10531053
{
10541054
return Err(Box::new(SyscallError::ProgramNotSupported(*program_id)));
@@ -1122,7 +1122,7 @@ fn cpi_common<S: SyscallInvokeSigned>(
11221122
//
11231123
// Synchronize the callee's account changes so the caller can see them.
11241124
let direct_mapping = invoke_context
1125-
.feature_set
1125+
.get_feature_set()
11261126
.is_active(&feature_set::bpf_account_data_direct_mapping::id());
11271127

11281128
if direct_mapping {
@@ -1629,8 +1629,9 @@ mod tests {
16291629
.map(|a| (a.0, a.1))
16301630
.collect::<Vec<TransactionAccount>>();
16311631
with_mock_invoke_context!($invoke_context, $transaction_context, transaction_accounts);
1632-
let feature_set = Arc::make_mut(&mut $invoke_context.feature_set);
1632+
let mut feature_set = $invoke_context.get_feature_set().clone();
16331633
feature_set.deactivate(&bpf_account_data_direct_mapping::id());
1634+
$invoke_context.mock_set_feature_set(Arc::new(feature_set));
16341635
$invoke_context
16351636
.transaction_context
16361637
.get_next_instruction_context()

programs/bpf_loader/src/syscalls/mem_ops.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ declare_builtin_function!(
6969
mem_op_consume(invoke_context, n)?;
7070

7171
if invoke_context
72-
.feature_set
72+
.get_feature_set()
7373
.is_active(&feature_set::bpf_account_data_direct_mapping::id())
7474
{
7575
let cmp_result = translate_type_mut::<i32>(
@@ -125,7 +125,7 @@ declare_builtin_function!(
125125
mem_op_consume(invoke_context, n)?;
126126

127127
if invoke_context
128-
.feature_set
128+
.get_feature_set()
129129
.is_active(&feature_set::bpf_account_data_direct_mapping::id())
130130
{
131131
memset_non_contiguous(dst_addr, c as u8, n, memory_mapping)
@@ -150,7 +150,7 @@ fn memmove(
150150
memory_mapping: &MemoryMapping,
151151
) -> Result<u64, Error> {
152152
if invoke_context
153-
.feature_set
153+
.get_feature_set()
154154
.is_active(&feature_set::bpf_account_data_direct_mapping::id())
155155
{
156156
memmove_non_contiguous(dst_addr, src_addr, n, memory_mapping)

0 commit comments

Comments
 (0)