Răsfoiți Sursa

svm-test-harness: refactor for entrypoint composability (#8669)

* svm-test-harness: extract transaction context prep

* svm-test-harness: extract blockhash and lps prep

* svm-test-harness: extract compute budget prep

* svm-test-harness: extract sysvar cache prep

* svm-test-harness: extract program cache prep
Joe C 3 săptămâni în urmă
părinte
comite
b411caf311
3 a modificat fișierele cu 54 adăugiri și 70 ștergeri
  1. 0 1
      Cargo.lock
  2. 0 1
      svm-test-harness/Cargo.toml
  3. 54 68
      svm-test-harness/src/instr.rs

+ 0 - 1
Cargo.lock

@@ -10849,7 +10849,6 @@ dependencies = [
  "solana-clock",
  "solana-compute-budget",
  "solana-epoch-schedule",
- "solana-hash",
  "solana-instruction",
  "solana-instruction-error",
  "solana-last-restart-slot",

+ 0 - 1
svm-test-harness/Cargo.toml

@@ -34,7 +34,6 @@ solana-builtins = { workspace = true }
 solana-clock = { workspace = true, features = ["sysvar"] }
 solana-compute-budget = { workspace = true }
 solana-epoch-schedule = { workspace = true, features = ["sysvar"] }
-solana-hash = { workspace = true }
 solana-instruction = { workspace = true }
 solana-instruction-error = { workspace = true, features = ["serde"] }
 solana-last-restart-slot = { workspace = true, features = ["sysvar"] }

+ 54 - 68
svm-test-harness/src/instr.rs

@@ -7,18 +7,18 @@ use {
     crate::fixture::{instr_context::InstrContext, instr_effects::InstrEffects},
     agave_precompiles::{get_precompile, is_precompile},
     agave_syscalls::create_program_runtime_environment_v1,
-    solana_account::AccountSharedData,
+    solana_account::{Account, AccountSharedData},
+    solana_clock::Clock,
     solana_compute_budget::compute_budget::{ComputeBudget, SVMTransactionExecutionCost},
-    solana_hash::Hash,
     solana_instruction::AccountMeta,
     solana_instruction_error::InstructionError,
     solana_precompile_error::PrecompileError,
     solana_program_runtime::{
         invoke_context::{EnvironmentConfig, InvokeContext},
         loaded_programs::{ProgramCacheForTxBatch, ProgramRuntimeEnvironments},
-        sysvar_cache::SysvarCache,
     },
     solana_pubkey::Pubkey,
+    solana_rent::Rent,
     solana_stable_layout::stable_vec::StableVec,
     solana_svm_callback::{InvokeContextCallback, TransactionProcessingCallback},
     solana_svm_log_collector::LogCollector,
@@ -67,28 +67,11 @@ impl TransactionProcessingCallback for InstrContextCallback<'_> {
     }
 }
 
-fn create_invoke_context_fields(
+fn create_program_cache(
     input: &mut InstrContext,
-) -> Option<(
-    TransactionContext,
-    SysvarCache,
-    ProgramRuntimeEnvironments,
-    ProgramCacheForTxBatch,
-    Hash,
-    u64,
-    ComputeBudget,
-)> {
-    let compute_budget = {
-        let mut budget = ComputeBudget::new_with_defaults(false);
-        budget.compute_unit_limit = input.cu_avail;
-        budget
-    };
-
-    let sysvar_cache = crate::sysvar_cache::setup_sysvar_cache(&input.accounts);
-
-    let clock = sysvar_cache.get_clock().unwrap();
-    let rent = sysvar_cache.get_rent().unwrap();
-
+    clock: &Clock,
+    compute_budget: &ComputeBudget,
+) -> Option<(ProgramRuntimeEnvironments, ProgramCacheForTxBatch)> {
     if !input
         .accounts
         .iter()
@@ -100,19 +83,6 @@ fn create_invoke_context_fields(
         ));
     }
 
-    let transaction_accounts: Vec<KeyedAccountSharedData> = input
-        .accounts
-        .iter()
-        .map(|(pubkey, account)| (*pubkey, AccountSharedData::from(account.clone())))
-        .collect();
-
-    let transaction_context = TransactionContext::new(
-        transaction_accounts.clone(),
-        (*rent).clone(),
-        compute_budget.max_instruction_stack_depth,
-        compute_budget.max_instruction_trace_length,
-    );
-
     let environments = ProgramRuntimeEnvironments {
         program_runtime_v1: Arc::new(
             create_program_runtime_environment_v1(
@@ -130,14 +100,6 @@ fn create_invoke_context_fields(
     let mut program_cache =
         crate::program_cache::setup_program_cache(&input.feature_set, clock.slot);
 
-    #[allow(deprecated)]
-    let (blockhash, lamports_per_signature) = sysvar_cache
-        .get_recent_blockhashes()
-        .ok()
-        .and_then(|x| (*x).last().cloned())
-        .map(|x| (x.blockhash, x.fee_calculator.lamports_per_signature))
-        .unwrap_or_default();
-
     let mut newly_loaded_programs = HashSet::<Pubkey>::new();
 
     for acc in &input.accounts {
@@ -178,18 +140,10 @@ fn create_invoke_context_fields(
         }
     }
 
-    Some((
-        transaction_context,
-        sysvar_cache,
-        environments,
-        program_cache,
-        blockhash,
-        lamports_per_signature,
-        compute_budget,
-    ))
+    Some((environments, program_cache))
 }
 
-fn get_instr_accounts(
+fn create_instruction_accounts(
     txn_context: &TransactionContext,
     acct_metas: &StableVec<AccountMeta>,
 ) -> Vec<InstructionAccount> {
@@ -209,29 +163,61 @@ fn get_instr_accounts(
     instruction_accounts
 }
 
+fn create_transaction_context(
+    accounts: &[(Pubkey, Account)],
+    compute_budget: &ComputeBudget,
+    rent: Rent,
+) -> TransactionContext {
+    let transaction_accounts: Vec<KeyedAccountSharedData> = accounts
+        .iter()
+        .map(|(pubkey, account)| (*pubkey, AccountSharedData::from(account.clone())))
+        .collect();
+
+    TransactionContext::new(
+        transaction_accounts.clone(),
+        rent,
+        compute_budget.max_instruction_stack_depth,
+        compute_budget.max_instruction_trace_length,
+    )
+}
+
 /// Execute a single instruction against the Solana VM.
 pub fn execute_instr(mut input: InstrContext) -> Option<InstrEffects> {
+    let mut compute_units_consumed = 0u64;
+
+    let runtime_features = input.feature_set.runtime_features();
+    let sysvar_cache = crate::sysvar_cache::setup_sysvar_cache(&input.accounts);
+
     let log_collector = LogCollector::new_ref();
+    let compute_budget = {
+        let mut budget = ComputeBudget::new_with_defaults(false);
+        budget.compute_unit_limit = input.cu_avail;
+        budget
+    };
 
-    let (
-        mut transaction_context,
-        sysvar_cache,
-        environments,
-        mut program_cache,
-        blockhash,
-        lamports_per_signature,
-        compute_budget,
-    ) = create_invoke_context_fields(&mut input)?;
+    let clock = sysvar_cache.get_clock().unwrap();
+    let rent = sysvar_cache.get_rent().unwrap();
 
-    let mut compute_units_consumed = 0u64;
-    let runtime_features = input.feature_set.runtime_features();
+    let (environments, mut program_cache) =
+        create_program_cache(&mut input, &clock, &compute_budget)?;
+
+    let mut transaction_context =
+        create_transaction_context(&input.accounts, &compute_budget, (*rent).clone());
 
     let result = {
         let callback = InstrContextCallback(&input);
 
+        #[allow(deprecated)]
+        let (blockhash, blockhash_lamports_per_signature) = sysvar_cache
+            .get_recent_blockhashes()
+            .ok()
+            .and_then(|x| (*x).last().cloned())
+            .map(|x| (x.blockhash, x.fee_calculator.lamports_per_signature))
+            .unwrap_or_default();
+
         let environment_config = EnvironmentConfig::new(
             blockhash,
-            lamports_per_signature,
+            blockhash_lamports_per_signature,
             &callback,
             &runtime_features,
             &environments,
@@ -243,7 +229,7 @@ pub fn execute_instr(mut input: InstrContext) -> Option<InstrEffects> {
             transaction_context.find_index_of_account(&input.instruction.program_id)?;
 
         let instruction_accounts =
-            get_instr_accounts(&transaction_context, &input.instruction.accounts);
+            create_instruction_accounts(&transaction_context, &input.instruction.accounts);
 
         let mut invoke_context = InvokeContext::new(
             &mut transaction_context,