Skip to content

Commit aba8ce5

Browse files
authored
Move code to check_program_modification_slot out of SVM (#329)
* Move code to check_program_modification_slot out of SVM * add documentation for the public function
1 parent 261b3e9 commit aba8ce5

File tree

2 files changed

+42
-43
lines changed

2 files changed

+42
-43
lines changed

runtime/src/bank.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ use {
9999
compute_budget_processor::process_compute_budget_instructions,
100100
invoke_context::BuiltinFunctionWithContext,
101101
loaded_programs::{
102-
LoadedProgram, LoadedProgramType, LoadedPrograms, ProgramRuntimeEnvironments,
102+
LoadedProgram, LoadedProgramMatchCriteria, LoadedProgramType, LoadedPrograms,
103+
ProgramRuntimeEnvironments,
103104
},
104105
runtime_config::RuntimeConfig,
105106
timings::{ExecuteTimingType, ExecuteTimings},
@@ -168,7 +169,8 @@ use {
168169
account_overrides::AccountOverrides,
169170
transaction_error_metrics::TransactionErrorMetrics,
170171
transaction_processor::{
171-
TransactionBatchProcessor, TransactionLogMessages, TransactionProcessingCallback,
172+
ExecutionRecordingConfig, TransactionBatchProcessor, TransactionLogMessages,
173+
TransactionProcessingCallback,
172174
},
173175
transaction_results::{
174176
TransactionExecutionDetails, TransactionExecutionResult, TransactionResults,
@@ -271,7 +273,6 @@ pub struct BankRc {
271273

272274
#[cfg(RUSTC_WITH_SPECIALIZATION)]
273275
use solana_frozen_abi::abi_example::AbiExample;
274-
use solana_svm::transaction_processor::ExecutionRecordingConfig;
275276

276277
#[cfg(RUSTC_WITH_SPECIALIZATION)]
277278
impl AbiExample for BankRc {
@@ -550,6 +551,7 @@ impl PartialEq for Bank {
550551
loaded_programs_cache: _,
551552
epoch_reward_status: _,
552553
transaction_processor: _,
554+
check_program_modification_slot: _,
553555
// Ignore new fields explicitly if they do not impact PartialEq.
554556
// Adding ".." will remove compile-time checks that if a new field
555557
// is added to the struct, this PartialEq is accordingly updated.
@@ -810,6 +812,8 @@ pub struct Bank {
810812
epoch_reward_status: EpochRewardStatus,
811813

812814
transaction_processor: TransactionBatchProcessor<BankForks>,
815+
816+
check_program_modification_slot: bool,
813817
}
814818

815819
struct VoteWithStakeDelegations {
@@ -996,6 +1000,7 @@ impl Bank {
9961000
))),
9971001
epoch_reward_status: EpochRewardStatus::default(),
9981002
transaction_processor: TransactionBatchProcessor::default(),
1003+
check_program_modification_slot: false,
9991004
};
10001005

10011006
bank.transaction_processor = TransactionBatchProcessor::new(
@@ -1314,6 +1319,7 @@ impl Bank {
13141319
loaded_programs_cache: parent.loaded_programs_cache.clone(),
13151320
epoch_reward_status: parent.epoch_reward_status.clone(),
13161321
transaction_processor: TransactionBatchProcessor::default(),
1322+
check_program_modification_slot: false,
13171323
};
13181324

13191325
new.transaction_processor = TransactionBatchProcessor::new(
@@ -1864,6 +1870,7 @@ impl Bank {
18641870
))),
18651871
epoch_reward_status: fields.epoch_reward_status,
18661872
transaction_processor: TransactionBatchProcessor::default(),
1873+
check_program_modification_slot: false,
18671874
};
18681875

18691876
bank.transaction_processor = TransactionBatchProcessor::new(
@@ -7517,7 +7524,7 @@ impl Bank {
75177524
}
75187525

75197526
pub fn check_program_modification_slot(&mut self) {
7520-
self.transaction_processor.check_program_modification_slot = true;
7527+
self.check_program_modification_slot = true;
75217528
}
75227529

75237530
pub fn load_program(
@@ -7579,6 +7586,18 @@ impl TransactionProcessingCallback for Bank {
75797586
Ok(())
75807587
}
75817588
}
7589+
7590+
fn get_program_match_criteria(&self, program: &Pubkey) -> LoadedProgramMatchCriteria {
7591+
if self.check_program_modification_slot {
7592+
self.transaction_processor
7593+
.program_modification_slot(self, program)
7594+
.map_or(LoadedProgramMatchCriteria::Tombstone, |slot| {
7595+
LoadedProgramMatchCriteria::DeployedOnOrAfterSlot(slot)
7596+
})
7597+
} else {
7598+
LoadedProgramMatchCriteria::NoCriteria
7599+
}
7600+
}
75827601
}
75837602

75847603
#[cfg(feature = "dev-context-only-utils")]

svm/src/transaction_processor.rs

Lines changed: 19 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ pub trait TransactionProcessingCallback {
103103
) -> transaction::Result<()> {
104104
Ok(())
105105
}
106+
107+
fn get_program_match_criteria(&self, _program: &Pubkey) -> LoadedProgramMatchCriteria {
108+
LoadedProgramMatchCriteria::NoCriteria
109+
}
106110
}
107111

108112
#[derive(Debug)]
@@ -128,8 +132,6 @@ pub struct TransactionBatchProcessor<FG: ForkGraph> {
128132
/// Transaction fee structure
129133
fee_structure: FeeStructure,
130134

131-
pub check_program_modification_slot: bool,
132-
133135
/// Optional config parameters that can override runtime behavior
134136
runtime_config: Arc<RuntimeConfig>,
135137

@@ -145,10 +147,6 @@ impl<FG: ForkGraph> Debug for TransactionBatchProcessor<FG> {
145147
.field("epoch", &self.epoch)
146148
.field("epoch_schedule", &self.epoch_schedule)
147149
.field("fee_structure", &self.fee_structure)
148-
.field(
149-
"check_program_modification_slot",
150-
&self.check_program_modification_slot,
151-
)
152150
.field("runtime_config", &self.runtime_config)
153151
.field("sysvar_cache", &self.sysvar_cache)
154152
.field("loaded_programs_cache", &self.loaded_programs_cache)
@@ -163,7 +161,6 @@ impl<FG: ForkGraph> Default for TransactionBatchProcessor<FG> {
163161
epoch: Epoch::default(),
164162
epoch_schedule: EpochSchedule::default(),
165163
fee_structure: FeeStructure::default(),
166-
check_program_modification_slot: false,
167164
runtime_config: Arc::<RuntimeConfig>::default(),
168165
sysvar_cache: RwLock::<SysvarCache>::default(),
169166
loaded_programs_cache: Arc::new(RwLock::new(LoadedPrograms::new(
@@ -188,7 +185,6 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
188185
epoch,
189186
epoch_schedule,
190187
fee_structure,
191-
check_program_modification_slot: false,
192188
runtime_config,
193189
sysvar_cache: RwLock::<SysvarCache>::default(),
194190
loaded_programs_cache,
@@ -491,30 +487,15 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
491487
limit_to_load_programs: bool,
492488
) -> LoadedProgramsForTxBatch {
493489
let mut missing_programs: Vec<(Pubkey, (LoadedProgramMatchCriteria, u64))> =
494-
if self.check_program_modification_slot {
495-
program_accounts_map
496-
.iter()
497-
.map(|(pubkey, (_, count))| {
498-
(
499-
*pubkey,
500-
(
501-
self.program_modification_slot(callback, pubkey)
502-
.map_or(LoadedProgramMatchCriteria::Tombstone, |slot| {
503-
LoadedProgramMatchCriteria::DeployedOnOrAfterSlot(slot)
504-
}),
505-
*count,
506-
),
507-
)
508-
})
509-
.collect()
510-
} else {
511-
program_accounts_map
512-
.iter()
513-
.map(|(pubkey, (_, count))| {
514-
(*pubkey, (LoadedProgramMatchCriteria::NoCriteria, *count))
515-
})
516-
.collect()
517-
};
490+
program_accounts_map
491+
.iter()
492+
.map(|(pubkey, (_, count))| {
493+
(
494+
*pubkey,
495+
(callback.get_program_match_criteria(pubkey), *count),
496+
)
497+
})
498+
.collect();
518499

519500
let mut loaded_programs_for_txs = None;
520501
let mut program_to_store = None;
@@ -763,7 +744,11 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
763744
}
764745
}
765746

766-
fn program_modification_slot<CB: TransactionProcessingCallback>(
747+
/// Find the slot in which the program was most recently modified.
748+
/// Returns slot 0 for programs deployed with v1/v2 loaders, since programs deployed
749+
/// with those loaders do not retain deployment slot information.
750+
/// Returns an error if the program's account state can not be found or parsed.
751+
pub fn program_modification_slot<CB: TransactionProcessingCallback>(
767752
&self,
768753
callbacks: &CB,
769754
pubkey: &Pubkey,
@@ -1815,10 +1800,7 @@ mod tests {
18151800
fn test_replenish_program_cache() {
18161801
// Case 1
18171802
let mut mock_bank = MockBankCallback::default();
1818-
let mut batch_processor = TransactionBatchProcessor::<TestForkGraph> {
1819-
check_program_modification_slot: true,
1820-
..TransactionBatchProcessor::default()
1821-
};
1803+
let batch_processor = TransactionBatchProcessor::<TestForkGraph>::default();
18221804
batch_processor
18231805
.loaded_programs_cache
18241806
.write()
@@ -1848,8 +1830,6 @@ mod tests {
18481830
));
18491831

18501832
// Case 2
1851-
batch_processor.check_program_modification_slot = false;
1852-
18531833
let result = batch_processor.replenish_program_cache(&mock_bank, &account_maps, true);
18541834

18551835
let program1 = result.find(&key1).unwrap();

0 commit comments

Comments
 (0)