فهرست منبع

Remove SVM dep on agave-precompile (#5599)

* Remove SVM dep on agave-precompile

- use new callbacks to call into precompile handlers

* rename trait
Pankaj Garg 7 ماه پیش
والد
کامیت
02f870208f

+ 3 - 3
Cargo.lock

@@ -6895,7 +6895,6 @@ name = "solana-bpf-loader-program"
 version = "2.3.0"
 dependencies = [
  "agave-feature-set",
- "agave-precompiles",
  "assert_matches",
  "bincode",
  "criterion",
@@ -9140,7 +9139,6 @@ name = "solana-program-runtime"
 version = "2.3.0"
 dependencies = [
  "agave-feature-set",
- "agave-precompiles",
  "assert_matches",
  "base64 0.22.1",
  "bincode",
@@ -9718,6 +9716,7 @@ dependencies = [
  "solana-nohash-hasher",
  "solana-nonce-account",
  "solana-perf",
+ "solana-precompile-error",
  "solana-program",
  "solana-program-runtime",
  "solana-pubkey",
@@ -10326,7 +10325,6 @@ name = "solana-svm"
 version = "2.3.0"
 dependencies = [
  "agave-feature-set",
- "agave-precompiles",
  "agave-reserved-account-keys",
  "ahash 0.8.11",
  "assert_matches",
@@ -10370,6 +10368,7 @@ dependencies = [
  "solana-native-token",
  "solana-nonce",
  "solana-nonce-account",
+ "solana-precompile-error",
  "solana-program-runtime",
  "solana-pubkey",
  "solana-rent",
@@ -10404,6 +10403,7 @@ name = "solana-svm-callback"
 version = "2.3.0"
 dependencies = [
  "solana-account",
+ "solana-precompile-error",
  "solana-pubkey",
 ]
 

+ 0 - 1
program-runtime/Cargo.toml

@@ -11,7 +11,6 @@ edition = { workspace = true }
 
 [dependencies]
 agave-feature-set = { workspace = true }
-agave-precompiles = { workspace = true }
 base64 = { workspace = true }
 bincode = { workspace = true }
 enum-iterator = { workspace = true }

+ 17 - 12
program-runtime/src/invoke_context.rs

@@ -11,7 +11,6 @@ use {
     agave_feature_set::{
         lift_cpi_caller_restriction, remove_accounts_executable_flag_checks, FeatureSet,
     },
-    agave_precompiles::Precompile,
     solana_account::{create_account_shared_data_for_test, AccountSharedData},
     solana_clock::Slot,
     solana_epoch_schedule::EpochSchedule,
@@ -31,7 +30,7 @@ use {
         bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable, loader_v4, native_loader, sysvar,
     },
     solana_stable_layout::stable_instruction::StableInstruction,
-    solana_svm_callback::EpochStakeCallback,
+    solana_svm_callback::InvokeContextCallback,
     solana_timings::{ExecuteDetailsTimings, ExecuteTimings},
     solana_transaction_context::{
         IndexOfAccount, InstructionAccount, TransactionAccount, TransactionContext,
@@ -147,7 +146,7 @@ impl BpfAllocator {
 pub struct EnvironmentConfig<'a> {
     pub blockhash: Hash,
     pub blockhash_lamports_per_signature: u64,
-    epoch_stake_callback: &'a dyn EpochStakeCallback,
+    epoch_stake_callback: &'a dyn InvokeContextCallback,
     pub feature_set: Arc<FeatureSet>,
     sysvar_cache: &'a SysvarCache,
 }
@@ -155,7 +154,7 @@ impl<'a> EnvironmentConfig<'a> {
     pub fn new(
         blockhash: Hash,
         blockhash_lamports_per_signature: u64,
-        epoch_stake_callback: &'a dyn EpochStakeCallback,
+        epoch_stake_callback: &'a dyn InvokeContextCallback,
         feature_set: Arc<FeatureSet>,
         sysvar_cache: &'a SysvarCache,
     ) -> Self {
@@ -484,7 +483,7 @@ impl<'a> InvokeContext<'a> {
     /// Processes a precompile instruction
     pub fn process_precompile<'ix_data>(
         &mut self,
-        precompile: &Precompile,
+        program_id: &Pubkey,
         instruction_data: &[u8],
         instruction_accounts: &[InstructionAccount],
         program_indices: &[IndexOfAccount],
@@ -495,10 +494,10 @@ impl<'a> InvokeContext<'a> {
             .configure(program_indices, instruction_accounts, instruction_data);
         self.push()?;
 
-        let feature_set = self.get_feature_set();
         let instruction_datas: Vec<_> = message_instruction_datas_iter.collect();
-        precompile
-            .verify(instruction_data, &instruction_datas, feature_set)
+        self.environment_config
+            .epoch_stake_callback
+            .process_precompile(program_id, instruction_data, instruction_datas)
             .map_err(InstructionError::from)
             .and(self.pop())
     }
@@ -677,6 +676,12 @@ impl<'a> InvokeContext<'a> {
             .get_epoch_stake_for_vote_account(pubkey)
     }
 
+    pub fn is_precompile(&self, pubkey: &Pubkey) -> bool {
+        self.environment_config
+            .epoch_stake_callback
+            .is_precompile(pubkey)
+    }
+
     // Should alignment be enforced during user pointer translation
     pub fn get_check_aligned(&self) -> bool {
         self.transaction_context
@@ -735,7 +740,7 @@ macro_rules! with_mock_invoke_context {
         use {
             agave_feature_set::FeatureSet,
             solana_log_collector::LogCollector,
-            solana_svm_callback::EpochStakeCallback,
+            solana_svm_callback::InvokeContextCallback,
             solana_type_overrides::sync::Arc,
             $crate::{
                 __private::{Hash, ReadableAccount, Rent, TransactionContext},
@@ -746,8 +751,8 @@ macro_rules! with_mock_invoke_context {
             },
         };
 
-        struct MockEpochStakeCallback {}
-        impl EpochStakeCallback for MockEpochStakeCallback {}
+        struct MockInvokeContextCallback {}
+        impl InvokeContextCallback for MockInvokeContextCallback {}
 
         let compute_budget = SVMTransactionExecutionBudget::default();
         let mut $transaction_context = TransactionContext::new(
@@ -777,7 +782,7 @@ macro_rules! with_mock_invoke_context {
         let environment_config = EnvironmentConfig::new(
             Hash::default(),
             0,
-            &MockEpochStakeCallback {},
+            &MockInvokeContextCallback {},
             Arc::new(FeatureSet::all_enabled()),
             &sysvar_cache,
         );

+ 0 - 1
programs/bpf_loader/Cargo.toml

@@ -11,7 +11,6 @@ edition = { workspace = true }
 
 [dependencies]
 agave-feature-set = { workspace = true }
-agave-precompiles = { workspace = true }
 bincode = { workspace = true }
 libsecp256k1 = { workspace = true }
 num-traits = { workspace = true }

+ 1 - 3
programs/bpf_loader/src/syscalls/cpi.rs

@@ -1069,9 +1069,7 @@ fn check_authorized_program(
                         instruction_data,
                     ))
                 || bpf_loader_upgradeable::is_close_instruction(instruction_data)))
-        || is_precompile(program_id, |feature_id: &Pubkey| {
-            invoke_context.get_feature_set().is_active(feature_id)
-        })
+        || invoke_context.is_precompile(program_id)
     {
         return Err(Box::new(SyscallError::ProgramNotSupported(*program_id)));
     }

+ 2 - 3
programs/bpf_loader/src/syscalls/mod.rs

@@ -24,7 +24,6 @@ use {
         last_restart_slot_sysvar, reenable_sbpf_v0_execution,
         remaining_compute_units_syscall_enabled, FeatureSet,
     },
-    agave_precompiles::is_precompile,
     solana_account_info::AccountInfo,
     solana_big_mod_exp::{big_mod_exp, BigModExpParams},
     solana_blake3_hasher as blake3,
@@ -4915,7 +4914,7 @@ mod tests {
         const EXPECTED_TOTAL_STAKE: u64 = 200_000_000_000_000;
 
         struct MockCallback {}
-        impl EpochStakeCallback for MockCallback {
+        impl InvokeContextCallback for MockCallback {
             fn get_epoch_stake(&self) -> u64 {
                 EXPECTED_TOTAL_STAKE
             }
@@ -4968,7 +4967,7 @@ mod tests {
         const EXPECTED_EPOCH_STAKE: u64 = 55_000_000_000;
 
         struct MockCallback {}
-        impl EpochStakeCallback for MockCallback {
+        impl InvokeContextCallback for MockCallback {
             // Total stake is not needed for this test.
             fn get_epoch_stake_for_vote_account(&self, vote_address: &Pubkey) -> u64 {
                 if *vote_address == TARGET_VOTE_ADDRESS {

+ 2 - 3
programs/sbf/Cargo.lock

@@ -5556,7 +5556,6 @@ name = "solana-bpf-loader-program"
 version = "2.3.0"
 dependencies = [
  "agave-feature-set",
- "agave-precompiles",
  "bincode",
  "libsecp256k1 0.6.0",
  "num-traits",
@@ -7147,7 +7146,6 @@ name = "solana-program-runtime"
 version = "2.3.0"
 dependencies = [
  "agave-feature-set",
- "agave-precompiles",
  "base64 0.22.1",
  "bincode",
  "enum-iterator",
@@ -7619,6 +7617,7 @@ dependencies = [
  "solana-nohash-hasher",
  "solana-nonce-account",
  "solana-perf",
+ "solana-precompile-error",
  "solana-program",
  "solana-program-runtime",
  "solana-pubkey",
@@ -8657,7 +8656,6 @@ name = "solana-svm"
 version = "2.3.0"
 dependencies = [
  "agave-feature-set",
- "agave-precompiles",
  "ahash 0.8.11",
  "itertools 0.12.1",
  "log",
@@ -8701,6 +8699,7 @@ name = "solana-svm-callback"
 version = "2.3.0"
 dependencies = [
  "solana-account",
+ "solana-precompile-error",
  "solana-pubkey",
 ]
 

+ 2 - 1
runtime/Cargo.toml

@@ -71,6 +71,7 @@ solana-metrics = { workspace = true }
 solana-nohash-hasher = { workspace = true }
 solana-nonce-account = { workspace = true }
 solana-perf = { workspace = true }
+solana-precompile-error = { workspace = true }
 solana-program = { workspace = true }
 solana-program-runtime = { workspace = true, features = ["metrics"] }
 solana-pubkey = { workspace = true }
@@ -123,7 +124,7 @@ solana-runtime-transaction = { workspace = true, features = [
 solana-sdk = { workspace = true, features = ["dev-context-only-utils"] }
 solana-sdk-ids = { workspace = true }
 solana-svm = { workspace = true, features = ["dev-context-only-utils"] }
-solana-transaction-context = { workspace = true, features = ["dev-context-only-utils" ] }
+solana-transaction-context = { workspace = true, features = ["dev-context-only-utils"] }
 static_assertions = { workspace = true }
 test-case = { workspace = true }
 

+ 25 - 3
runtime/src/bank.rs

@@ -59,7 +59,7 @@ use {
     },
     accounts_lt_hash::{CacheValue as AccountsLtHashCacheValue, Stats as AccountsLtHashStats},
     agave_feature_set::{self as feature_set, FeatureSet},
-    agave_precompiles::get_precompiles,
+    agave_precompiles::{get_precompile, get_precompiles, is_precompile},
     agave_reserved_account_keys::ReservedAccountKeys,
     ahash::AHashSet,
     dashmap::{DashMap, DashSet},
@@ -137,6 +137,7 @@ use {
         native_loader,
         native_token::LAMPORTS_PER_SOL,
         packet::PACKET_DATA_SIZE,
+        precompiles::PrecompileError,
         pubkey::Pubkey,
         rent_collector::{CollectedInfo, RentCollector},
         rent_debits::RentDebits,
@@ -171,7 +172,7 @@ use {
             TransactionProcessingConfig, TransactionProcessingEnvironment,
         },
     },
-    solana_svm_callback::{AccountState, EpochStakeCallback, TransactionProcessingCallback},
+    solana_svm_callback::{AccountState, InvokeContextCallback, TransactionProcessingCallback},
     solana_svm_transaction::svm_message::SVMMessage,
     solana_timings::{ExecuteTimingType, ExecuteTimings},
     solana_transaction_context::{TransactionAccount, TransactionReturnData},
@@ -6948,7 +6949,7 @@ impl Bank {
     }
 }
 
-impl EpochStakeCallback for Bank {
+impl InvokeContextCallback for Bank {
     fn get_epoch_stake(&self) -> u64 {
         self.get_current_epoch_total_stake()
     }
@@ -6959,6 +6960,27 @@ impl EpochStakeCallback for Bank {
             .map(|(stake, _)| (*stake))
             .unwrap_or(0)
     }
+
+    fn is_precompile(&self, program_id: &Pubkey) -> bool {
+        is_precompile(program_id, |feature_id: &Pubkey| {
+            self.feature_set.is_active(feature_id)
+        })
+    }
+
+    fn process_precompile(
+        &self,
+        program_id: &Pubkey,
+        data: &[u8],
+        instruction_datas: Vec<&[u8]>,
+    ) -> std::result::Result<(), PrecompileError> {
+        if let Some(precompile) = get_precompile(program_id, |feature_id: &Pubkey| {
+            self.feature_set.is_active(feature_id)
+        }) {
+            precompile.verify(data, &instruction_datas, &self.feature_set)
+        } else {
+            Err(PrecompileError::InvalidPublicKey)
+        }
+    }
 }
 
 impl TransactionProcessingCallback for Bank {

+ 2 - 2
runtime/src/bank/builtins/core_bpf_migration/mod.rs

@@ -20,7 +20,7 @@ use {
         instruction::InstructionError,
         pubkey::Pubkey,
     },
-    solana_svm_callback::EpochStakeCallback,
+    solana_svm_callback::InvokeContextCallback,
     solana_transaction_context::TransactionContext,
     source_buffer::SourceBuffer,
     std::{cmp::Ordering, sync::atomic::Ordering::Relaxed},
@@ -160,7 +160,7 @@ impl Bank {
             );
 
             struct MockCallback {}
-            impl EpochStakeCallback for MockCallback {}
+            impl InvokeContextCallback for MockCallback {}
 
             let mut dummy_invoke_context = InvokeContext::new(
                 &mut dummy_transaction_context,

+ 1 - 0
svm-callback/Cargo.toml

@@ -11,6 +11,7 @@ readme = false
 
 [dependencies]
 solana-account = { workspace = true }
+solana-precompile-error = { workspace = true }
 solana-pubkey = { workspace = true }
 
 [lints]

+ 23 - 5
svm-callback/src/lib.rs

@@ -1,7 +1,10 @@
-use {solana_account::AccountSharedData, solana_pubkey::Pubkey};
+use {
+    solana_account::AccountSharedData, solana_precompile_error::PrecompileError,
+    solana_pubkey::Pubkey,
+};
 
-/// Callback for obtaining the cluster's current epoch stake.
-pub trait EpochStakeCallback {
+/// Callback used by InvokeContext in SVM
+pub trait InvokeContextCallback {
     /// Returns the total current epoch stake for the network.
     fn get_epoch_stake(&self) -> u64 {
         0
@@ -11,10 +14,25 @@ pub trait EpochStakeCallback {
     fn get_epoch_stake_for_vote_account(&self, _vote_address: &Pubkey) -> u64 {
         0
     }
+
+    /// Returns true if the program_id corresponds to a precompiled program
+    fn is_precompile(&self, _program_id: &Pubkey) -> bool {
+        false
+    }
+
+    /// Calls the precompiled program corresponding to the given program ID.
+    fn process_precompile(
+        &self,
+        _program_id: &Pubkey,
+        _data: &[u8],
+        _instruction_datas: Vec<&[u8]>,
+    ) -> Result<(), PrecompileError> {
+        Err(PrecompileError::InvalidPublicKey)
+    }
 }
 
 /// Runtime callbacks for transaction processing.
-pub trait TransactionProcessingCallback: EpochStakeCallback {
+pub trait TransactionProcessingCallback: InvokeContextCallback {
     fn account_matches_owners(&self, account: &Pubkey, owners: &[Pubkey]) -> Option<usize>;
 
     fn get_account_shared_data(&self, pubkey: &Pubkey) -> Option<AccountSharedData>;
@@ -26,7 +44,7 @@ pub trait TransactionProcessingCallback: EpochStakeCallback {
 
     #[deprecated(
         since = "2.3.0",
-        note = "Use `get_epoch_stake_for_vote_account` on the `EpochStakeCallback` trait instead"
+        note = "Use `get_epoch_stake_for_vote_account` on the `InvokeContextCallback` trait instead"
     )]
     fn get_current_epoch_vote_account_stake(&self, vote_address: &Pubkey) -> u64 {
         Self::get_epoch_stake_for_vote_account(self, vote_address)

+ 2 - 2
svm/Cargo.toml

@@ -11,7 +11,6 @@ edition = { workspace = true }
 
 [dependencies]
 agave-feature-set = { workspace = true }
-agave-precompiles = { workspace = true }
 ahash = { workspace = true }
 itertools = { workspace = true }
 log = { workspace = true }
@@ -81,6 +80,7 @@ solana-fee-calculator = { workspace = true }
 solana-keypair = { workspace = true }
 solana-logger = { workspace = true }
 solana-native-token = { workspace = true }
+solana-precompile-error = { workspace = true }
 solana-program-runtime = { workspace = true, features = ["dev-context-only-utils"] }
 solana-pubkey = { workspace = true }
 solana-rent = { workspace = true }
@@ -97,7 +97,7 @@ solana-system-program = { workspace = true }
 solana-system-transaction = { workspace = true }
 solana-sysvar = { workspace = true }
 solana-transaction = { workspace = true }
-solana-transaction-context = { workspace = true, features = ["dev-context-only-utils" ] }
+solana-transaction-context = { workspace = true, features = ["dev-context-only-utils"] }
 test-case = { workspace = true }
 
 [package.metadata.docs.rs]

+ 2 - 3
svm/examples/Cargo.lock

@@ -5414,7 +5414,6 @@ name = "solana-bpf-loader-program"
 version = "2.3.0"
 dependencies = [
  "agave-feature-set",
- "agave-precompiles",
  "bincode",
  "libsecp256k1",
  "num-traits",
@@ -6971,7 +6970,6 @@ name = "solana-program-runtime"
 version = "2.3.0"
 dependencies = [
  "agave-feature-set",
- "agave-precompiles",
  "base64 0.22.1",
  "bincode",
  "enum-iterator",
@@ -7443,6 +7441,7 @@ dependencies = [
  "solana-nohash-hasher",
  "solana-nonce-account",
  "solana-perf",
+ "solana-precompile-error",
  "solana-program",
  "solana-program-runtime",
  "solana-pubkey",
@@ -7978,7 +7977,6 @@ name = "solana-svm"
 version = "2.3.0"
 dependencies = [
  "agave-feature-set",
- "agave-precompiles",
  "ahash 0.8.11",
  "itertools 0.12.1",
  "log",
@@ -8021,6 +8019,7 @@ name = "solana-svm-callback"
 version = "2.3.0"
 dependencies = [
  "solana-account",
+ "solana-precompile-error",
  "solana-pubkey",
 ]
 

+ 2 - 2
svm/examples/json-rpc/server/src/svm_bridge.rs

@@ -31,7 +31,7 @@ use {
         transaction_processing_result::TransactionProcessingResult,
         transaction_processor::TransactionBatchProcessor,
     },
-    solana_svm_callback::{EpochStakeCallback, TransactionProcessingCallback},
+    solana_svm_callback::{InvokeContextCallback, TransactionProcessingCallback},
     std::{
         collections::HashMap,
         sync::{Arc, RwLock},
@@ -59,7 +59,7 @@ pub struct MockBankCallback {
     pub account_shared_data: RwLock<HashMap<Pubkey, AccountSharedData>>,
 }
 
-impl EpochStakeCallback for MockBankCallback {}
+impl InvokeContextCallback for MockBankCallback {}
 
 impl TransactionProcessingCallback for MockBankCallback {
     fn account_matches_owners(&self, account: &Pubkey, owners: &[Pubkey]) -> Option<usize> {

+ 2 - 2
svm/examples/paytube/src/loader.rs

@@ -11,7 +11,7 @@ use {
         account::{AccountSharedData, ReadableAccount},
         pubkey::Pubkey,
     },
-    solana_svm_callback::{EpochStakeCallback, TransactionProcessingCallback},
+    solana_svm_callback::{InvokeContextCallback, TransactionProcessingCallback},
     std::{collections::HashMap, sync::RwLock},
 };
 
@@ -39,7 +39,7 @@ impl<'a> PayTubeAccountLoader<'a> {
 /// ability to load accounts.
 ///
 /// In the Agave validator, this implementation is Bank, powered by AccountsDB.
-impl EpochStakeCallback for PayTubeAccountLoader<'_> {}
+impl InvokeContextCallback for PayTubeAccountLoader<'_> {}
 impl TransactionProcessingCallback for PayTubeAccountLoader<'_> {
     fn get_account_shared_data(&self, pubkey: &Pubkey) -> Option<AccountSharedData> {
         if let Some(account) = self.cache.read().unwrap().get(pubkey) {

+ 2 - 2
svm/src/account_loader.rs

@@ -697,7 +697,7 @@ mod tests {
         },
         solana_signature::Signature,
         solana_signer::Signer,
-        solana_svm_callback::{EpochStakeCallback, TransactionProcessingCallback},
+        solana_svm_callback::{InvokeContextCallback, TransactionProcessingCallback},
         solana_system_transaction::transfer,
         solana_transaction::{sanitized::SanitizedTransaction, Transaction},
         solana_transaction_context::{TransactionAccount, TransactionContext},
@@ -713,7 +713,7 @@ mod tests {
             RefCell<HashMap<Pubkey, Vec<(Option<AccountSharedData>, /* is_writable */ bool)>>>,
     }
 
-    impl EpochStakeCallback for TestCallbacks {}
+    impl InvokeContextCallback for TestCallbacks {}
 
     impl TransactionProcessingCallback for TestCallbacks {
         fn account_matches_owners(&self, _account: &Pubkey, _owners: &[Pubkey]) -> Option<usize> {

+ 28 - 7
svm/src/message_processor.rs

@@ -1,5 +1,4 @@
 use {
-    agave_precompiles::get_precompile,
     solana_account::WritableAccount,
     solana_instructions_sysvar as instructions,
     solana_measure::measure_us,
@@ -69,11 +68,9 @@ pub(crate) fn process_message(
 
         let mut compute_units_consumed = 0;
         let (result, process_instruction_us) = measure_us!({
-            if let Some(precompile) = get_precompile(program_id, |feature_id| {
-                invoke_context.get_feature_set().is_active(feature_id)
-            }) {
+            if invoke_context.is_precompile(program_id) {
                 invoke_context.process_precompile(
-                    precompile,
+                    program_id,
                     instruction.data,
                     &instruction_accounts,
                     program_indices,
@@ -130,6 +127,7 @@ mod tests {
         solana_hash::Hash,
         solana_instruction::{error::InstructionError, AccountMeta, Instruction},
         solana_message::{AccountKeys, Message, SanitizedMessage},
+        solana_precompile_error::PrecompileError,
         solana_program_runtime::{
             declare_process_instruction,
             execution_budget::{SVMTransactionExecutionBudget, SVMTransactionExecutionCost},
@@ -142,13 +140,13 @@ mod tests {
         solana_sdk_ids::{ed25519_program, native_loader, secp256k1_program, system_program},
         solana_secp256k1_program::new_secp256k1_instruction,
         solana_secp256r1_program::new_secp256r1_instruction,
-        solana_svm_callback::EpochStakeCallback,
+        solana_svm_callback::InvokeContextCallback,
         solana_transaction_context::TransactionContext,
         std::sync::Arc,
     };
 
     struct MockCallback {}
-    impl EpochStakeCallback for MockCallback {}
+    impl InvokeContextCallback for MockCallback {}
 
     fn create_loadable_account_for_test(name: &str) -> AccountSharedData {
         let (lamports, rent_epoch) = DUMMY_INHERITABLE_ACCOUNT_FIELDS;
@@ -666,6 +664,29 @@ mod tests {
             mock_program_id,
             Arc::new(ProgramCacheEntry::new_builtin(0, 0, MockBuiltin::vm)),
         );
+
+        struct MockCallback {}
+        impl InvokeContextCallback for MockCallback {
+            fn is_precompile(&self, program_id: &Pubkey) -> bool {
+                program_id == &secp256k1_program::id()
+                    || program_id == &ed25519_program::id()
+                    || program_id == &solana_secp256r1_program::id()
+            }
+
+            fn process_precompile(
+                &self,
+                program_id: &Pubkey,
+                _data: &[u8],
+                _instruction_datas: Vec<&[u8]>,
+            ) -> std::result::Result<(), PrecompileError> {
+                if self.is_precompile(program_id) {
+                    Ok(())
+                } else {
+                    Err(PrecompileError::InvalidPublicKey)
+                }
+            }
+        }
+
         let environment_config = EnvironmentConfig::new(
             Hash::default(),
             0,

+ 2 - 2
svm/src/program_loader.rs

@@ -257,7 +257,7 @@ mod tests {
             solana_sbpf::program::BuiltinProgram,
         },
         solana_sdk_ids::{bpf_loader, bpf_loader_upgradeable},
-        solana_svm_callback::EpochStakeCallback,
+        solana_svm_callback::InvokeContextCallback,
         std::{
             cell::RefCell,
             collections::HashMap,
@@ -280,7 +280,7 @@ mod tests {
         pub(crate) account_shared_data: RefCell<HashMap<Pubkey, AccountSharedData>>,
     }
 
-    impl EpochStakeCallback for MockBankCallback {}
+    impl InvokeContextCallback for MockBankCallback {}
 
     impl TransactionProcessingCallback for MockBankCallback {
         fn account_matches_owners(&self, account: &Pubkey, owners: &[Pubkey]) -> Option<usize> {

+ 2 - 2
svm/src/transaction_processor.rs

@@ -1091,7 +1091,7 @@ mod tests {
         solana_rent_debits::RentDebits,
         solana_sdk_ids::{bpf_loader, system_program, sysvar},
         solana_signature::Signature,
-        solana_svm_callback::{AccountState, EpochStakeCallback},
+        solana_svm_callback::{AccountState, InvokeContextCallback},
         solana_transaction::{sanitized::SanitizedTransaction, Transaction},
         solana_transaction_context::TransactionContext,
         solana_transaction_error::{TransactionError, TransactionError::DuplicateInstruction},
@@ -1121,7 +1121,7 @@ mod tests {
             Arc<RwLock<HashMap<Pubkey, Vec<(Option<AccountSharedData>, /* is_writable */ bool)>>>>,
     }
 
-    impl EpochStakeCallback for MockBankCallback {}
+    impl InvokeContextCallback for MockBankCallback {}
 
     impl TransactionProcessingCallback for MockBankCallback {
         fn account_matches_owners(&self, account: &Pubkey, owners: &[Pubkey]) -> Option<usize> {

+ 2 - 2
svm/tests/mock_bank.rs

@@ -30,7 +30,7 @@ use {
         sysvar::SysvarId,
     },
     solana_svm::transaction_processor::TransactionBatchProcessor,
-    solana_svm_callback::{AccountState, EpochStakeCallback, TransactionProcessingCallback},
+    solana_svm_callback::{AccountState, InvokeContextCallback, TransactionProcessingCallback},
     solana_svm_transaction::svm_message::SVMMessage,
     solana_type_overrides::sync::{Arc, RwLock},
     std::{
@@ -67,7 +67,7 @@ pub struct MockBankCallback {
         Arc<RwLock<HashMap<Pubkey, Vec<(Option<AccountSharedData>, /* is_writable */ bool)>>>>,
 }
 
-impl EpochStakeCallback for MockBankCallback {}
+impl InvokeContextCallback for MockBankCallback {}
 
 impl TransactionProcessingCallback for MockBankCallback {
     fn account_matches_owners(&self, account: &Pubkey, owners: &[Pubkey]) -> Option<usize> {