From f8f3fe31d92c778d8552fa21f6b1abf4bcbca81d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= <AlexanderMeissner@gmx.net>
Date: Thu, 7 Nov 2024 21:36:42 +0100
Subject: [PATCH] Feature - disable account loader special case (#3514)

Feature gate disable_account_loader_special_case.
---
 runtime/src/bank/tests.rs | 10 ++--------
 sdk/src/feature_set.rs    |  5 +++++
 svm/src/account_loader.rs | 10 +++++++---
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/runtime/src/bank/tests.rs b/runtime/src/bank/tests.rs
index 715dd90f9d815b..3da66902e95ae8 100644
--- a/runtime/src/bank/tests.rs
+++ b/runtime/src/bank/tests.rs
@@ -7137,10 +7137,7 @@ fn test_bpf_loader_upgradeable_deploy_with_max_len() {
     );
     assert_eq!(
         bank.process_transaction(&transaction),
-        Err(TransactionError::InstructionError(
-            0,
-            InstructionError::InvalidAccountData
-        )),
+        Err(TransactionError::InvalidProgramForExecution),
     );
     {
         let program_cache = bank.transaction_processor.program_cache.read().unwrap();
@@ -7161,10 +7158,7 @@ fn test_bpf_loader_upgradeable_deploy_with_max_len() {
     let transaction = Transaction::new(&[&binding], message, bank.last_blockhash());
     assert_eq!(
         bank.process_transaction(&transaction),
-        Err(TransactionError::InstructionError(
-            0,
-            InstructionError::InvalidAccountData,
-        )),
+        Err(TransactionError::InvalidProgramForExecution),
     );
     {
         let program_cache = bank.transaction_processor.program_cache.read().unwrap();
diff --git a/sdk/src/feature_set.rs b/sdk/src/feature_set.rs
index 6c906a9f7120e9..ac5dbe6765f41e 100644
--- a/sdk/src/feature_set.rs
+++ b/sdk/src/feature_set.rs
@@ -857,6 +857,10 @@ pub mod deprecate_legacy_vote_ixs {
     solana_program::declare_id!("mustrekeyysGrhwdiwU42tCadZL8GcBb1i2GYhMopQv");
 }
 
+pub mod disable_account_loader_special_case {
+    solana_program::declare_id!("EQUMpNFr7Nacb1sva56xn1aLfBxppEoSBH8RRVdkcD1x");
+}
+
 lazy_static! {
     /// Map of feature identifiers to user-visible description
     pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
@@ -1066,6 +1070,7 @@ lazy_static! {
         (partitioned_epoch_rewards_superfeature::id(), "replaces enable_partitioned_epoch_reward to enable partitioned rewards at epoch boundary SIMD-0118"),
         (enable_turbine_extended_fanout_experiments::id(), "enable turbine extended fanout experiments #2373"),
         (deprecate_legacy_vote_ixs::id(), "Deprecate legacy vote instructions"),
+        (disable_account_loader_special_case::id(), "Disable account loader special case"),
         /*************** ADD NEW FEATURES HERE ***************/
     ]
     .iter()
diff --git a/svm/src/account_loader.rs b/svm/src/account_loader.rs
index 080433a977941a..f11fc002872da1 100644
--- a/svm/src/account_loader.rs
+++ b/svm/src/account_loader.rs
@@ -209,6 +209,8 @@ fn load_transaction_accounts<CB: TransactionProcessingCallback>(
         get_requested_loaded_accounts_data_size_limit(message)?;
     let mut accumulated_accounts_data_size: usize = 0;
 
+    let disable_account_loader_special_case =
+        feature_set.is_active(&feature_set::disable_account_loader_special_case::id());
     let instruction_accounts = message
         .instructions()
         .iter()
@@ -239,9 +241,11 @@ fn load_transaction_accounts<CB: TransactionProcessingCallback>(
                     account_overrides.and_then(|overrides| overrides.get(key))
                 {
                     (account_override.data().len(), account_override.clone(), 0)
-                } else if let Some(program) = (!instruction_account && !message.is_writable(i))
-                    .then_some(())
-                    .and_then(|_| loaded_programs.find(key))
+                } else if let Some(program) = (!disable_account_loader_special_case
+                    && !instruction_account
+                    && !message.is_writable(i))
+                .then_some(())
+                .and_then(|_| loaded_programs.find(key))
                 {
                     // Optimization to skip loading of accounts which are only used as
                     // programs in top-level instructions and not passed as instruction accounts.