Bläddra i källkod

TransactionBatch - hold RuntimeTransaction (#3041)

Andrew Fitzgerald 1 år sedan
förälder
incheckning
9b56f30a60
61 ändrade filer med 663 tillägg och 417 borttagningar
  1. 7 0
      Cargo.lock
  2. 1 0
      banks-server/Cargo.toml
  3. 2 1
      banks-server/src/banks_server.rs
  4. 3 2
      core/benches/consumer.rs
  5. 5 2
      core/src/banking_stage.rs
  6. 9 2
      core/src/banking_stage/committer.rs
  7. 3 4
      core/src/banking_stage/consume_worker.rs
  8. 13 9
      core/src/banking_stage/consumer.rs
  9. 17 9
      core/src/banking_stage/forward_packet_batches_by_accounts.rs
  10. 4 2
      core/src/banking_stage/forwarder.rs
  11. 22 12
      core/src/banking_stage/immutable_deserialized_packet.rs
  12. 22 21
      core/src/banking_stage/qos_service.rs
  13. 2 1
      core/src/banking_stage/scheduler_messages.rs
  14. 23 15
      core/src/banking_stage/transaction_scheduler/prio_graph_scheduler.rs
  15. 6 3
      core/src/banking_stage/transaction_scheduler/scheduler_controller.rs
  16. 3 2
      core/src/banking_stage/transaction_scheduler/transaction_state.rs
  17. 5 10
      core/src/banking_stage/transaction_scheduler/transaction_state_container.rs
  18. 17 17
      core/src/banking_stage/unprocessed_transaction_storage.rs
  19. 3 2
      core/tests/unified_scheduler.rs
  20. 3 0
      cost-model/Cargo.toml
  21. 3 2
      cost-model/benches/cost_model.rs
  22. 5 5
      cost-model/benches/cost_tracker.rs
  23. 56 60
      cost-model/src/cost_model.rs
  24. 23 18
      cost-model/src/cost_tracker.rs
  25. 20 12
      cost-model/src/transaction_cost.rs
  26. 1 0
      entry/Cargo.toml
  27. 9 8
      entry/benches/entry_sigverify.rs
  28. 28 13
      entry/src/entry.rs
  29. 1 0
      ledger-tool/Cargo.toml
  30. 3 2
      ledger-tool/src/main.rs
  31. 1 0
      ledger/Cargo.toml
  32. 3 2
      ledger/benches/blockstore_processor.rs
  33. 22 14
      ledger/src/blockstore_processor.rs
  34. 6 0
      programs/sbf/Cargo.lock
  35. 3 1
      programs/sbf/Cargo.toml
  36. 6 3
      programs/sbf/tests/programs.rs
  37. 3 2
      programs/sbf/tests/simulation.rs
  38. 3 2
      programs/sbf/tests/syscall_get_epoch_stake.rs
  39. 3 2
      programs/sbf/tests/sysvar.rs
  40. 4 0
      rpc/Cargo.toml
  41. 4 3
      rpc/src/rpc.rs
  42. 3 0
      runtime-transaction/Cargo.toml
  43. 1 0
      runtime-transaction/src/compute_budget_instruction_details.rs
  44. 1 0
      runtime-transaction/src/lib.rs
  45. 77 10
      runtime-transaction/src/runtime_transaction.rs
  46. 25 0
      runtime-transaction/src/svm_transaction_adapter.rs
  47. 1 0
      runtime-transaction/src/transaction_meta.rs
  48. 7 1
      runtime/Cargo.toml
  49. 3 2
      runtime/benches/prioritization_fee_cache.rs
  50. 39 30
      runtime/src/bank.rs
  51. 5 4
      runtime/src/bank/check_transactions.rs
  52. 8 8
      runtime/src/bank/tests.rs
  53. 2 1
      runtime/src/bank_utils.rs
  54. 10 4
      runtime/src/installed_scheduler_pool.rs
  55. 16 13
      runtime/src/prioritization_fee_cache.rs
  56. 10 9
      runtime/src/transaction_batch.rs
  57. 1 1
      sdk/program/src/message/sanitized.rs
  58. 6 0
      unified-scheduler-logic/Cargo.toml
  59. 22 20
      unified-scheduler-logic/src/lib.rs
  60. 1 0
      unified-scheduler-pool/Cargo.toml
  61. 48 51
      unified-scheduler-pool/src/lib.rs

+ 7 - 0
Cargo.lock

@@ -195,6 +195,7 @@ dependencies = [
  "solana-program-runtime",
  "solana-program-runtime",
  "solana-rpc",
  "solana-rpc",
  "solana-runtime",
  "solana-runtime",
+ "solana-runtime-transaction",
  "solana-sdk",
  "solana-sdk",
  "solana-stake-program",
  "solana-stake-program",
  "solana-storage-bigtable",
  "solana-storage-bigtable",
@@ -5928,6 +5929,7 @@ dependencies = [
  "solana-client",
  "solana-client",
  "solana-feature-set",
  "solana-feature-set",
  "solana-runtime",
  "solana-runtime",
+ "solana-runtime-transaction",
  "solana-sdk",
  "solana-sdk",
  "solana-send-transaction-service",
  "solana-send-transaction-service",
  "solana-svm",
  "solana-svm",
@@ -6681,6 +6683,7 @@ dependencies = [
  "solana-metrics",
  "solana-metrics",
  "solana-perf",
  "solana-perf",
  "solana-rayon-threadlimit",
  "solana-rayon-threadlimit",
+ "solana-runtime-transaction",
  "solana-sdk",
  "solana-sdk",
 ]
 ]
 
 
@@ -7079,6 +7082,7 @@ dependencies = [
  "solana-program-runtime",
  "solana-program-runtime",
  "solana-rayon-threadlimit",
  "solana-rayon-threadlimit",
  "solana-runtime",
  "solana-runtime",
+ "solana-runtime-transaction",
  "solana-sdk",
  "solana-sdk",
  "solana-stake-program",
  "solana-stake-program",
  "solana-storage-bigtable",
  "solana-storage-bigtable",
@@ -7805,6 +7809,7 @@ dependencies = [
  "solana-rayon-threadlimit",
  "solana-rayon-threadlimit",
  "solana-rpc-client-api",
  "solana-rpc-client-api",
  "solana-runtime",
  "solana-runtime",
+ "solana-runtime-transaction",
  "solana-sdk",
  "solana-sdk",
  "solana-send-transaction-service",
  "solana-send-transaction-service",
  "solana-stake-program",
  "solana-stake-program",
@@ -8852,6 +8857,7 @@ name = "solana-unified-scheduler-logic"
 version = "2.2.0"
 version = "2.2.0"
 dependencies = [
 dependencies = [
  "assert_matches",
  "assert_matches",
+ "solana-runtime-transaction",
  "solana-sdk",
  "solana-sdk",
  "static_assertions",
  "static_assertions",
 ]
 ]
@@ -8871,6 +8877,7 @@ dependencies = [
  "solana-ledger",
  "solana-ledger",
  "solana-logger",
  "solana-logger",
  "solana-runtime",
  "solana-runtime",
+ "solana-runtime-transaction",
  "solana-sdk",
  "solana-sdk",
  "solana-timings",
  "solana-timings",
  "solana-unified-scheduler-logic",
  "solana-unified-scheduler-logic",

+ 1 - 0
banks-server/Cargo.toml

@@ -17,6 +17,7 @@ solana-banks-interface = { workspace = true }
 solana-client = { workspace = true }
 solana-client = { workspace = true }
 solana-feature-set = { workspace = true }
 solana-feature-set = { workspace = true }
 solana-runtime = { workspace = true }
 solana-runtime = { workspace = true }
+solana-runtime-transaction = { workspace = true }
 solana-sdk = { workspace = true }
 solana-sdk = { workspace = true }
 solana-send-transaction-service = { workspace = true }
 solana-send-transaction-service = { workspace = true }
 solana-svm = { workspace = true }
 solana-svm = { workspace = true }

+ 2 - 1
banks-server/src/banks_server.rs

@@ -15,6 +15,7 @@ use {
         commitment::BlockCommitmentCache,
         commitment::BlockCommitmentCache,
         verify_precompiles::verify_precompiles,
         verify_precompiles::verify_precompiles,
     },
     },
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{
     solana_sdk::{
         account::Account,
         account::Account,
         clock::Slot,
         clock::Slot,
@@ -178,7 +179,7 @@ fn simulate_transaction(
     bank: &Bank,
     bank: &Bank,
     transaction: VersionedTransaction,
     transaction: VersionedTransaction,
 ) -> BanksTransactionResultWithSimulation {
 ) -> BanksTransactionResultWithSimulation {
-    let sanitized_transaction = match SanitizedTransaction::try_create(
+    let sanitized_transaction = match RuntimeTransaction::try_create(
         transaction,
         transaction,
         MessageHash::Compute,
         MessageHash::Compute,
         Some(false), // is_simple_vote_tx
         Some(false), // is_simple_vote_tx

+ 3 - 2
core/benches/consumer.rs

@@ -20,6 +20,7 @@ use {
         poh_service::PohService,
         poh_service::PohService,
     },
     },
     solana_runtime::{bank::Bank, bank_forks::BankForks},
     solana_runtime::{bank::Bank, bank_forks::BankForks},
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{
     solana_sdk::{
         account::{Account, ReadableAccount},
         account::{Account, ReadableAccount},
         signature::Keypair,
         signature::Keypair,
@@ -66,7 +67,7 @@ fn create_funded_accounts(bank: &Bank, num: usize) -> Vec<Keypair> {
     accounts
     accounts
 }
 }
 
 
-fn create_transactions(bank: &Bank, num: usize) -> Vec<SanitizedTransaction> {
+fn create_transactions(bank: &Bank, num: usize) -> Vec<RuntimeTransaction<SanitizedTransaction>> {
     let funded_accounts = create_funded_accounts(bank, 2 * num);
     let funded_accounts = create_funded_accounts(bank, 2 * num);
     funded_accounts
     funded_accounts
         .into_par_iter()
         .into_par_iter()
@@ -76,7 +77,7 @@ fn create_transactions(bank: &Bank, num: usize) -> Vec<SanitizedTransaction> {
             let to = &chunk[1];
             let to = &chunk[1];
             system_transaction::transfer(from, &to.pubkey(), 1, bank.last_blockhash())
             system_transaction::transfer(from, &to.pubkey(), 1, bank.last_blockhash())
         })
         })
-        .map(SanitizedTransaction::from_transaction_for_tests)
+        .map(RuntimeTransaction::from_transaction_for_tests)
         .collect()
         .collect()
 }
 }
 
 

+ 5 - 2
core/src/banking_stage.rs

@@ -841,6 +841,7 @@ mod tests {
             poh_service::PohService,
             poh_service::PohService,
         },
         },
         solana_runtime::{bank::Bank, genesis_utils::bootstrap_validator_stake_lamports},
         solana_runtime::{bank::Bank, genesis_utils::bootstrap_validator_stake_lamports},
+        solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
         solana_sdk::{
         solana_sdk::{
             hash::Hash,
             hash::Hash,
             poh_config::PohConfig,
             poh_config::PohConfig,
@@ -867,9 +868,11 @@ mod tests {
         (node, cluster_info)
         (node, cluster_info)
     }
     }
 
 
-    pub(crate) fn sanitize_transactions(txs: Vec<Transaction>) -> Vec<SanitizedTransaction> {
+    pub(crate) fn sanitize_transactions(
+        txs: Vec<Transaction>,
+    ) -> Vec<RuntimeTransaction<SanitizedTransaction>> {
         txs.into_iter()
         txs.into_iter()
-            .map(SanitizedTransaction::from_transaction_for_tests)
+            .map(RuntimeTransaction::from_transaction_for_tests)
             .collect()
             .collect()
     }
     }
 
 

+ 9 - 2
core/src/banking_stage/committer.rs

@@ -12,6 +12,7 @@ use {
         transaction_batch::TransactionBatch,
         transaction_batch::TransactionBatch,
         vote_sender_types::ReplayVoteSender,
         vote_sender_types::ReplayVoteSender,
     },
     },
+    solana_runtime_transaction::svm_transaction_adapter::SVMTransactionAdapter,
     solana_sdk::{pubkey::Pubkey, saturating_add_assign, transaction::SanitizedTransaction},
     solana_sdk::{pubkey::Pubkey, saturating_add_assign, transaction::SanitizedTransaction},
     solana_svm::{
     solana_svm::{
         transaction_commit_result::{TransactionCommitResult, TransactionCommitResultExtensions},
         transaction_commit_result::{TransactionCommitResult, TransactionCommitResultExtensions},
@@ -22,7 +23,7 @@ use {
     solana_transaction_status::{
     solana_transaction_status::{
         token_balances::TransactionTokenBalancesSet, TransactionTokenBalance,
         token_balances::TransactionTokenBalancesSet, TransactionTokenBalance,
     },
     },
-    std::{collections::HashMap, sync::Arc},
+    std::{borrow::Borrow, collections::HashMap, sync::Arc},
 };
 };
 
 
 #[derive(Clone, Debug, PartialEq, Eq)]
 #[derive(Clone, Debug, PartialEq, Eq)]
@@ -134,7 +135,13 @@ impl Committer {
         starting_transaction_index: Option<usize>,
         starting_transaction_index: Option<usize>,
     ) {
     ) {
         if let Some(transaction_status_sender) = &self.transaction_status_sender {
         if let Some(transaction_status_sender) = &self.transaction_status_sender {
-            let txs = batch.sanitized_transactions().to_vec();
+            // Clone `SanitizedTransaction` out of `RuntimeTransaction`, this is
+            // done to send over the status sender.
+            let txs = batch
+                .sanitized_transactions()
+                .iter()
+                .map(|tx| tx.as_sanitized_transaction().borrow().clone())
+                .collect_vec();
             let post_balances = bank.collect_balances(batch);
             let post_balances = bank.collect_balances(batch);
             let post_token_balances =
             let post_token_balances =
                 collect_token_balances(bank, batch, &mut pre_balance_info.mint_decimals);
                 collect_token_balances(bank, batch, &mut pre_balance_info.mint_decimals);

+ 3 - 4
core/src/banking_stage/consume_worker.rs

@@ -733,6 +733,7 @@ mod tests {
             bank_forks::BankForks, prioritization_fee_cache::PrioritizationFeeCache,
             bank_forks::BankForks, prioritization_fee_cache::PrioritizationFeeCache,
             vote_sender_types::ReplayVoteReceiver,
             vote_sender_types::ReplayVoteReceiver,
         },
         },
+        solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
         solana_sdk::{
         solana_sdk::{
             address_lookup_table::AddressLookupTableAccount,
             address_lookup_table::AddressLookupTableAccount,
             clock::{Slot, MAX_PROCESSING_AGE},
             clock::{Slot, MAX_PROCESSING_AGE},
@@ -746,9 +747,7 @@ mod tests {
             signature::Keypair,
             signature::Keypair,
             signer::Signer,
             signer::Signer,
             system_instruction, system_transaction,
             system_instruction, system_transaction,
-            transaction::{
-                MessageHash, SanitizedTransaction, TransactionError, VersionedTransaction,
-            },
+            transaction::{MessageHash, TransactionError, VersionedTransaction},
         },
         },
         solana_svm_transaction::svm_message::SVMMessage,
         solana_svm_transaction::svm_message::SVMMessage,
         std::{
         std::{
@@ -1101,7 +1100,7 @@ mod tests {
                 readonly: vec![],
                 readonly: vec![],
             };
             };
             let loader = SimpleAddressLoader::Enabled(loaded_addresses);
             let loader = SimpleAddressLoader::Enabled(loaded_addresses);
-            SanitizedTransaction::try_create(
+            RuntimeTransaction::try_create(
                 VersionedTransaction::try_new(
                 VersionedTransaction::try_new(
                     VersionedMessage::V0(
                     VersionedMessage::V0(
                         v0::Message::try_compile(
                         v0::Message::try_compile(

+ 13 - 9
core/src/banking_stage/consumer.rs

@@ -24,7 +24,10 @@ use {
         transaction_batch::TransactionBatch,
         transaction_batch::TransactionBatch,
         verify_precompiles::verify_precompiles,
         verify_precompiles::verify_precompiles,
     },
     },
-    solana_runtime_transaction::instructions_processor::process_compute_budget_instructions,
+    solana_runtime_transaction::{
+        instructions_processor::process_compute_budget_instructions,
+        runtime_transaction::RuntimeTransaction,
+    },
     solana_sdk::{
     solana_sdk::{
         clock::{FORWARD_TRANSACTIONS_TO_LEADER_AT_SLOT_OFFSET, MAX_PROCESSING_AGE},
         clock::{FORWARD_TRANSACTIONS_TO_LEADER_AT_SLOT_OFFSET, MAX_PROCESSING_AGE},
         fee::FeeBudgetLimits,
         fee::FeeBudgetLimits,
@@ -228,7 +231,7 @@ impl Consumer {
         &self,
         &self,
         bank: &Arc<Bank>,
         bank: &Arc<Bank>,
         bank_creation_time: &Instant,
         bank_creation_time: &Instant,
-        sanitized_transactions: &[SanitizedTransaction],
+        sanitized_transactions: &[RuntimeTransaction<SanitizedTransaction>],
         banking_stage_stats: &BankingStageStats,
         banking_stage_stats: &BankingStageStats,
         slot_metrics_tracker: &mut LeaderSlotMetricsTracker,
         slot_metrics_tracker: &mut LeaderSlotMetricsTracker,
     ) -> ProcessTransactionsSummary {
     ) -> ProcessTransactionsSummary {
@@ -284,7 +287,7 @@ impl Consumer {
         &self,
         &self,
         bank: &Arc<Bank>,
         bank: &Arc<Bank>,
         bank_creation_time: &Instant,
         bank_creation_time: &Instant,
-        transactions: &[SanitizedTransaction],
+        transactions: &[RuntimeTransaction<SanitizedTransaction>],
     ) -> ProcessTransactionsSummary {
     ) -> ProcessTransactionsSummary {
         let mut chunk_start = 0;
         let mut chunk_start = 0;
         let mut all_retryable_tx_indexes = vec![];
         let mut all_retryable_tx_indexes = vec![];
@@ -386,7 +389,7 @@ impl Consumer {
     pub fn process_and_record_transactions(
     pub fn process_and_record_transactions(
         &self,
         &self,
         bank: &Arc<Bank>,
         bank: &Arc<Bank>,
-        txs: &[SanitizedTransaction],
+        txs: &[RuntimeTransaction<SanitizedTransaction>],
         chunk_offset: usize,
         chunk_offset: usize,
     ) -> ProcessTransactionBatchOutput {
     ) -> ProcessTransactionBatchOutput {
         let mut error_counters = TransactionErrorMetrics::default();
         let mut error_counters = TransactionErrorMetrics::default();
@@ -429,7 +432,7 @@ impl Consumer {
     pub fn process_and_record_aged_transactions(
     pub fn process_and_record_aged_transactions(
         &self,
         &self,
         bank: &Arc<Bank>,
         bank: &Arc<Bank>,
-        txs: &[SanitizedTransaction],
+        txs: &[RuntimeTransaction<SanitizedTransaction>],
         max_ages: &[MaxAge],
         max_ages: &[MaxAge],
     ) -> ProcessTransactionBatchOutput {
     ) -> ProcessTransactionBatchOutput {
         let move_precompile_verification_to_svm = bank
         let move_precompile_verification_to_svm = bank
@@ -473,7 +476,7 @@ impl Consumer {
     fn process_and_record_transactions_with_pre_results(
     fn process_and_record_transactions_with_pre_results(
         &self,
         &self,
         bank: &Arc<Bank>,
         bank: &Arc<Bank>,
-        txs: &[SanitizedTransaction],
+        txs: &[RuntimeTransaction<SanitizedTransaction>],
         chunk_offset: usize,
         chunk_offset: usize,
         pre_results: impl Iterator<Item = Result<(), TransactionError>>,
         pre_results: impl Iterator<Item = Result<(), TransactionError>>,
     ) -> ProcessTransactionBatchOutput {
     ) -> ProcessTransactionBatchOutput {
@@ -804,7 +807,7 @@ impl Consumer {
     /// * `pending_indexes` - identifies which indexes in the `transactions` list are still pending
     /// * `pending_indexes` - identifies which indexes in the `transactions` list are still pending
     fn filter_pending_packets_from_pending_txs(
     fn filter_pending_packets_from_pending_txs(
         bank: &Bank,
         bank: &Bank,
-        transactions: &[SanitizedTransaction],
+        transactions: &[RuntimeTransaction<SanitizedTransaction>],
         pending_indexes: &[usize],
         pending_indexes: &[usize],
     ) -> Vec<usize> {
     ) -> Vec<usize> {
         let filter =
         let filter =
@@ -888,7 +891,7 @@ mod tests {
             signature::Keypair,
             signature::Keypair,
             signer::Signer,
             signer::Signer,
             system_instruction, system_program, system_transaction,
             system_instruction, system_program, system_transaction,
-            transaction::{MessageHash, Transaction, VersionedTransaction},
+            transaction::{Transaction, VersionedTransaction},
         },
         },
         solana_svm::account_loader::CheckedTransactionDetails,
         solana_svm::account_loader::CheckedTransactionDetails,
         solana_timings::ProgramTiming,
         solana_timings::ProgramTiming,
@@ -903,6 +906,7 @@ mod tests {
             thread::{Builder, JoinHandle},
             thread::{Builder, JoinHandle},
             time::Duration,
             time::Duration,
         },
         },
+        transaction::MessageHash,
     };
     };
 
 
     fn execute_transactions_with_dummy_poh_service(
     fn execute_transactions_with_dummy_poh_service(
@@ -2060,7 +2064,7 @@ mod tests {
         });
         });
 
 
         let tx = VersionedTransaction::try_new(message, &[&keypair]).unwrap();
         let tx = VersionedTransaction::try_new(message, &[&keypair]).unwrap();
-        let sanitized_tx = SanitizedTransaction::try_create(
+        let sanitized_tx = RuntimeTransaction::try_create(
             tx.clone(),
             tx.clone(),
             MessageHash::Compute,
             MessageHash::Compute,
             Some(false),
             Some(false),

+ 17 - 9
core/src/banking_stage/forward_packet_batches_by_accounts.rs

@@ -8,7 +8,7 @@ use {
     },
     },
     solana_feature_set::FeatureSet,
     solana_feature_set::FeatureSet,
     solana_perf::packet::Packet,
     solana_perf::packet::Packet,
-    solana_sdk::transaction::SanitizedTransaction,
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_svm_transaction::svm_message::SVMMessage,
     solana_svm_transaction::svm_message::SVMMessage,
     std::sync::Arc,
     std::sync::Arc,
 };
 };
@@ -106,7 +106,7 @@ impl ForwardPacketBatchesByAccounts {
 
 
     pub fn try_add_packet(
     pub fn try_add_packet(
         &mut self,
         &mut self,
-        sanitized_transaction: &SanitizedTransaction,
+        sanitized_transaction: &RuntimeTransaction<impl SVMMessage>,
         immutable_packet: Arc<ImmutableDeserializedPacket>,
         immutable_packet: Arc<ImmutableDeserializedPacket>,
         feature_set: &FeatureSet,
         feature_set: &FeatureSet,
     ) -> bool {
     ) -> bool {
@@ -171,14 +171,15 @@ mod tests {
     use {
     use {
         super::*,
         super::*,
         crate::banking_stage::unprocessed_packet_batches::DeserializedPacket,
         crate::banking_stage::unprocessed_packet_batches::DeserializedPacket,
+        lazy_static::lazy_static,
         solana_cost_model::transaction_cost::{UsageCostDetails, WritableKeysTransaction},
         solana_cost_model::transaction_cost::{UsageCostDetails, WritableKeysTransaction},
         solana_feature_set::FeatureSet,
         solana_feature_set::FeatureSet,
         solana_sdk::{
         solana_sdk::{
             compute_budget::ComputeBudgetInstruction,
             compute_budget::ComputeBudgetInstruction,
-            message::{Message, TransactionSignatureDetails},
+            message::Message,
             pubkey::Pubkey,
             pubkey::Pubkey,
             system_instruction,
             system_instruction,
-            transaction::Transaction,
+            transaction::{SanitizedTransaction, Transaction},
         },
         },
     };
     };
 
 
@@ -187,7 +188,11 @@ mod tests {
     fn build_test_transaction_and_packet(
     fn build_test_transaction_and_packet(
         priority: u64,
         priority: u64,
         write_to_account: &Pubkey,
         write_to_account: &Pubkey,
-    ) -> (SanitizedTransaction, DeserializedPacket, u32) {
+    ) -> (
+        RuntimeTransaction<SanitizedTransaction>,
+        DeserializedPacket,
+        u32,
+    ) {
         let from_account = solana_sdk::pubkey::new_rand();
         let from_account = solana_sdk::pubkey::new_rand();
 
 
         let transaction = Transaction::new_unsigned(Message::new(
         let transaction = Transaction::new_unsigned(Message::new(
@@ -198,7 +203,7 @@ mod tests {
             Some(&from_account),
             Some(&from_account),
         ));
         ));
         let sanitized_transaction =
         let sanitized_transaction =
-            SanitizedTransaction::from_transaction_for_tests(transaction.clone());
+            RuntimeTransaction::from_transaction_for_tests(transaction.clone());
         let tx_cost = CostModel::calculate_cost(&sanitized_transaction, &FeatureSet::all_enabled());
         let tx_cost = CostModel::calculate_cost(&sanitized_transaction, &FeatureSet::all_enabled());
         let cost = tx_cost.sum();
         let cost = tx_cost.sum();
         let deserialized_packet =
         let deserialized_packet =
@@ -211,7 +216,10 @@ mod tests {
     }
     }
 
 
     fn zero_transaction_cost() -> TransactionCost<'static, WritableKeysTransaction> {
     fn zero_transaction_cost() -> TransactionCost<'static, WritableKeysTransaction> {
-        static DUMMY_TRANSACTION: WritableKeysTransaction = WritableKeysTransaction(vec![]);
+        lazy_static! {
+            static ref DUMMY_TRANSACTION: RuntimeTransaction<WritableKeysTransaction> =
+                RuntimeTransaction::new_for_tests(WritableKeysTransaction(vec![]));
+        };
 
 
         TransactionCost::Transaction(UsageCostDetails {
         TransactionCost::Transaction(UsageCostDetails {
             transaction: &DUMMY_TRANSACTION,
             transaction: &DUMMY_TRANSACTION,
@@ -221,7 +229,6 @@ mod tests {
             programs_execution_cost: 0,
             programs_execution_cost: 0,
             loaded_accounts_data_size_cost: 0,
             loaded_accounts_data_size_cost: 0,
             allocated_accounts_data_size: 0,
             allocated_accounts_data_size: 0,
-            signature_details: TransactionSignatureDetails::new(0, 0, 0),
         })
         })
     }
     }
 
 
@@ -370,7 +377,8 @@ mod tests {
                 ForwardPacketBatchesByAccounts::new_with_default_batch_limits();
                 ForwardPacketBatchesByAccounts::new_with_default_batch_limits();
             forward_packet_batches_by_accounts.batch_vote_limit = test_cost + 1;
             forward_packet_batches_by_accounts.batch_vote_limit = test_cost + 1;
 
 
-            let dummy_transaction = WritableKeysTransaction(vec![]);
+            let dummy_transaction =
+                RuntimeTransaction::new_for_tests(WritableKeysTransaction(vec![]));
             let transaction_cost = TransactionCost::SimpleVote {
             let transaction_cost = TransactionCost::SimpleVote {
                 transaction: &dummy_transaction,
                 transaction: &dummy_transaction,
             };
             };

+ 4 - 2
core/src/banking_stage/forwarder.rs

@@ -19,8 +19,10 @@ use {
     solana_perf::{data_budget::DataBudget, packet::Packet},
     solana_perf::{data_budget::DataBudget, packet::Packet},
     solana_poh::poh_recorder::PohRecorder,
     solana_poh::poh_recorder::PohRecorder,
     solana_runtime::bank_forks::BankForks,
     solana_runtime::bank_forks::BankForks,
-    solana_sdk::{pubkey::Pubkey, transaction::SanitizedTransaction, transport::TransportError},
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
+    solana_sdk::{pubkey::Pubkey, transport::TransportError},
     solana_streamer::sendmmsg::batch_send,
     solana_streamer::sendmmsg::batch_send,
+    solana_svm_transaction::svm_message::SVMMessage,
     std::{
     std::{
         iter::repeat,
         iter::repeat,
         net::{SocketAddr, UdpSocket},
         net::{SocketAddr, UdpSocket},
@@ -64,7 +66,7 @@ impl<T: LikeClusterInfo> Forwarder<T> {
 
 
     pub fn try_add_packet(
     pub fn try_add_packet(
         &mut self,
         &mut self,
-        sanitized_transaction: &SanitizedTransaction,
+        sanitized_transaction: &RuntimeTransaction<impl SVMMessage>,
         immutable_packet: Arc<ImmutableDeserializedPacket>,
         immutable_packet: Arc<ImmutableDeserializedPacket>,
         feature_set: &FeatureSet,
         feature_set: &FeatureSet,
     ) -> bool {
     ) -> bool {

+ 22 - 12
core/src/banking_stage/immutable_deserialized_packet.rs

@@ -3,7 +3,10 @@ use {
     solana_compute_budget::compute_budget_limits::ComputeBudgetLimits,
     solana_compute_budget::compute_budget_limits::ComputeBudgetLimits,
     solana_perf::packet::Packet,
     solana_perf::packet::Packet,
     solana_runtime::bank::Bank,
     solana_runtime::bank::Bank,
-    solana_runtime_transaction::instructions_processor::process_compute_budget_instructions,
+    solana_runtime_transaction::{
+        instructions_processor::process_compute_budget_instructions,
+        runtime_transaction::RuntimeTransaction,
+    },
     solana_sanitize::SanitizeError,
     solana_sanitize::SanitizeError,
     solana_sdk::{
     solana_sdk::{
         clock::Slot,
         clock::Slot,
@@ -11,7 +14,9 @@ use {
         message::{v0::LoadedAddresses, AddressLoaderError, Message, SimpleAddressLoader},
         message::{v0::LoadedAddresses, AddressLoaderError, Message, SimpleAddressLoader},
         pubkey::Pubkey,
         pubkey::Pubkey,
         signature::Signature,
         signature::Signature,
-        transaction::{SanitizedTransaction, SanitizedVersionedTransaction, VersionedTransaction},
+        transaction::{
+            MessageHash, SanitizedTransaction, SanitizedVersionedTransaction, VersionedTransaction,
+        },
     },
     },
     solana_short_vec::decode_shortu16_len,
     solana_short_vec::decode_shortu16_len,
     solana_svm_transaction::{
     solana_svm_transaction::{
@@ -40,7 +45,7 @@ pub enum DeserializedPacketError {
     FailedFilter(#[from] PacketFilterFailure),
     FailedFilter(#[from] PacketFilterFailure),
 }
 }
 
 
-#[derive(Debug, Eq)]
+#[derive(Debug)]
 pub struct ImmutableDeserializedPacket {
 pub struct ImmutableDeserializedPacket {
     original_packet: Packet,
     original_packet: Packet,
     transaction: SanitizedVersionedTransaction,
     transaction: SanitizedVersionedTransaction,
@@ -118,7 +123,7 @@ impl ImmutableDeserializedPacket {
         votes_only: bool,
         votes_only: bool,
         bank: &Bank,
         bank: &Bank,
         reserved_account_keys: &HashSet<Pubkey>,
         reserved_account_keys: &HashSet<Pubkey>,
-    ) -> Option<(SanitizedTransaction, Slot)> {
+    ) -> Option<(RuntimeTransaction<SanitizedTransaction>, Slot)> {
         if votes_only && !self.is_simple_vote() {
         if votes_only && !self.is_simple_vote() {
             return None;
             return None;
         }
         }
@@ -127,14 +132,18 @@ impl ImmutableDeserializedPacket {
         let (loaded_addresses, deactivation_slot) =
         let (loaded_addresses, deactivation_slot) =
             Self::resolve_addresses_with_deactivation(self.transaction(), bank).ok()?;
             Self::resolve_addresses_with_deactivation(self.transaction(), bank).ok()?;
         let address_loader = SimpleAddressLoader::Enabled(loaded_addresses);
         let address_loader = SimpleAddressLoader::Enabled(loaded_addresses);
-
-        let tx = SanitizedTransaction::try_new(
-            self.transaction().clone(),
-            *self.message_hash(),
-            self.is_simple_vote(),
-            address_loader,
-            reserved_account_keys,
+        let tx = RuntimeTransaction::<SanitizedVersionedTransaction>::try_from(
+            self.transaction.clone(),
+            MessageHash::Precomputed(self.message_hash),
+            Some(self.is_simple_vote),
         )
         )
+        .and_then(|tx| {
+            RuntimeTransaction::<SanitizedTransaction>::try_from(
+                tx,
+                address_loader,
+                reserved_account_keys,
+            )
+        })
         .ok()?;
         .ok()?;
         Some((tx, deactivation_slot))
         Some((tx, deactivation_slot))
     }
     }
@@ -156,7 +165,8 @@ impl ImmutableDeserializedPacket {
     }
     }
 }
 }
 
 
-// PartialEq MUST be consistent with PartialOrd and Ord
+// Eq and PartialEq MUST be consistent with PartialOrd and Ord
+impl Eq for ImmutableDeserializedPacket {}
 impl PartialEq for ImmutableDeserializedPacket {
 impl PartialEq for ImmutableDeserializedPacket {
     fn eq(&self, other: &Self) -> bool {
     fn eq(&self, other: &Self) -> bool {
         self.compute_unit_price() == other.compute_unit_price()
         self.compute_unit_price() == other.compute_unit_price()

+ 22 - 21
core/src/banking_stage/qos_service.rs

@@ -11,6 +11,7 @@ use {
     solana_feature_set::FeatureSet,
     solana_feature_set::FeatureSet,
     solana_measure::measure::Measure,
     solana_measure::measure::Measure,
     solana_runtime::bank::Bank,
     solana_runtime::bank::Bank,
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{
     solana_sdk::{
         clock::Slot,
         clock::Slot,
         saturating_add_assign,
         saturating_add_assign,
@@ -43,7 +44,7 @@ impl QosService {
     pub fn select_and_accumulate_transaction_costs<'a>(
     pub fn select_and_accumulate_transaction_costs<'a>(
         &self,
         &self,
         bank: &Bank,
         bank: &Bank,
-        transactions: &'a [SanitizedTransaction],
+        transactions: &'a [RuntimeTransaction<SanitizedTransaction>],
         pre_results: impl Iterator<Item = transaction::Result<()>>,
         pre_results: impl Iterator<Item = transaction::Result<()>>,
     ) -> (
     ) -> (
         Vec<transaction::Result<TransactionCost<'a, SanitizedTransaction>>>,
         Vec<transaction::Result<TransactionCost<'a, SanitizedTransaction>>>,
@@ -73,7 +74,7 @@ impl QosService {
     fn compute_transaction_costs<'a>(
     fn compute_transaction_costs<'a>(
         &self,
         &self,
         feature_set: &FeatureSet,
         feature_set: &FeatureSet,
-        transactions: impl Iterator<Item = &'a SanitizedTransaction>,
+        transactions: impl Iterator<Item = &'a RuntimeTransaction<SanitizedTransaction>>,
         pre_results: impl Iterator<Item = transaction::Result<()>>,
         pre_results: impl Iterator<Item = transaction::Result<()>>,
     ) -> Vec<transaction::Result<TransactionCost<'a, SanitizedTransaction>>> {
     ) -> Vec<transaction::Result<TransactionCost<'a, SanitizedTransaction>>> {
         let mut compute_cost_time = Measure::start("compute_cost_time");
         let mut compute_cost_time = Measure::start("compute_cost_time");
@@ -98,7 +99,7 @@ impl QosService {
     /// and a count of the number of transactions that would fit in the block
     /// and a count of the number of transactions that would fit in the block
     fn select_transactions_per_cost<'a>(
     fn select_transactions_per_cost<'a>(
         &self,
         &self,
-        transactions: impl Iterator<Item = &'a SanitizedTransaction>,
+        transactions: impl Iterator<Item = &'a RuntimeTransaction<SanitizedTransaction>>,
         transactions_costs: impl Iterator<
         transactions_costs: impl Iterator<
             Item = transaction::Result<TransactionCost<'a, SanitizedTransaction>>,
             Item = transaction::Result<TransactionCost<'a, SanitizedTransaction>>,
         >,
         >,
@@ -628,7 +629,6 @@ mod tests {
         solana_runtime::genesis_utils::{create_genesis_config, GenesisConfigInfo},
         solana_runtime::genesis_utils::{create_genesis_config, GenesisConfigInfo},
         solana_sdk::{
         solana_sdk::{
             hash::Hash,
             hash::Hash,
-            message::TransactionSignatureDetails,
             signature::{Keypair, Signer},
             signature::{Keypair, Signer},
             system_transaction,
             system_transaction,
         },
         },
@@ -642,10 +642,10 @@ mod tests {
 
 
         // make a vec of txs
         // make a vec of txs
         let keypair = Keypair::new();
         let keypair = Keypair::new();
-        let transfer_tx = SanitizedTransaction::from_transaction_for_tests(
+        let transfer_tx = RuntimeTransaction::from_transaction_for_tests(
             system_transaction::transfer(&keypair, &keypair.pubkey(), 1, Hash::default()),
             system_transaction::transfer(&keypair, &keypair.pubkey(), 1, Hash::default()),
         );
         );
-        let vote_tx = SanitizedTransaction::from_transaction_for_tests(
+        let vote_tx = RuntimeTransaction::from_transaction_for_tests(
             vote_transaction::new_tower_sync_transaction(
             vote_transaction::new_tower_sync_transaction(
                 TowerSync::from(vec![(42, 1)]),
                 TowerSync::from(vec![(42, 1)]),
                 Hash::default(),
                 Hash::default(),
@@ -685,10 +685,10 @@ mod tests {
         let bank = Arc::new(Bank::new_for_tests(&genesis_config));
         let bank = Arc::new(Bank::new_for_tests(&genesis_config));
 
 
         let keypair = Keypair::new();
         let keypair = Keypair::new();
-        let transfer_tx = SanitizedTransaction::from_transaction_for_tests(
+        let transfer_tx = RuntimeTransaction::from_transaction_for_tests(
             system_transaction::transfer(&keypair, &keypair.pubkey(), 1, Hash::default()),
             system_transaction::transfer(&keypair, &keypair.pubkey(), 1, Hash::default()),
         );
         );
-        let vote_tx = SanitizedTransaction::from_transaction_for_tests(
+        let vote_tx = RuntimeTransaction::from_transaction_for_tests(
             vote_transaction::new_tower_sync_transaction(
             vote_transaction::new_tower_sync_transaction(
                 TowerSync::from(vec![(42, 1)]),
                 TowerSync::from(vec![(42, 1)]),
                 Hash::default(),
                 Hash::default(),
@@ -701,7 +701,6 @@ mod tests {
         let transfer_tx_cost =
         let transfer_tx_cost =
             CostModel::calculate_cost(&transfer_tx, &FeatureSet::all_enabled()).sum();
             CostModel::calculate_cost(&transfer_tx, &FeatureSet::all_enabled()).sum();
         let vote_tx_cost = CostModel::calculate_cost(&vote_tx, &FeatureSet::all_enabled()).sum();
         let vote_tx_cost = CostModel::calculate_cost(&vote_tx, &FeatureSet::all_enabled()).sum();
-
         // make a vec of txs
         // make a vec of txs
         let txs = vec![transfer_tx.clone(), vote_tx.clone(), transfer_tx, vote_tx];
         let txs = vec![transfer_tx.clone(), vote_tx.clone(), transfer_tx, vote_tx];
 
 
@@ -747,8 +746,8 @@ mod tests {
             ],
             ],
             Some(&keypair.pubkey()),
             Some(&keypair.pubkey()),
         ));
         ));
-        let transfer_tx = SanitizedTransaction::from_transaction_for_tests(transaction.clone());
-        let txs: Vec<SanitizedTransaction> = (0..transaction_count)
+        let transfer_tx = RuntimeTransaction::from_transaction_for_tests(transaction.clone());
+        let txs: Vec<_> = (0..transaction_count)
             .map(|_| transfer_tx.clone())
             .map(|_| transfer_tx.clone())
             .collect();
             .collect();
         let execute_units_adjustment: u64 = 10;
         let execute_units_adjustment: u64 = 10;
@@ -817,11 +816,15 @@ mod tests {
         // calculate their costs, apply to cost_tracker
         // calculate their costs, apply to cost_tracker
         let transaction_count = 5;
         let transaction_count = 5;
         let keypair = Keypair::new();
         let keypair = Keypair::new();
-        let transfer_tx = SanitizedTransaction::from_transaction_for_tests(
-            system_transaction::transfer(&keypair, &keypair.pubkey(), 1, Hash::default()),
-        );
-        let txs: Vec<SanitizedTransaction> = (0..transaction_count)
-            .map(|_| transfer_tx.clone())
+        let txs: Vec<_> = (0..transaction_count)
+            .map(|_| {
+                RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
+                    &keypair,
+                    &keypair.pubkey(),
+                    1,
+                    Hash::default(),
+                ))
+            })
             .collect();
             .collect();
 
 
         // assert all tx_costs should be removed from cost_tracker if all execution_results are all Not Committed
         // assert all tx_costs should be removed from cost_tracker if all execution_results are all Not Committed
@@ -867,9 +870,8 @@ mod tests {
             ],
             ],
             Some(&keypair.pubkey()),
             Some(&keypair.pubkey()),
         ));
         ));
-        let transfer_tx = SanitizedTransaction::from_transaction_for_tests(transaction.clone());
-        let txs: Vec<SanitizedTransaction> = (0..transaction_count)
-            .map(|_| transfer_tx.clone())
+        let txs: Vec<_> = (0..transaction_count)
+            .map(|_| RuntimeTransaction::from_transaction_for_tests(transaction.clone()))
             .collect();
             .collect();
         let execute_units_adjustment: u64 = 10;
         let execute_units_adjustment: u64 = 10;
         let loaded_accounts_data_size_adjustment: u32 = 32000;
         let loaded_accounts_data_size_adjustment: u32 = 32000;
@@ -951,7 +953,7 @@ mod tests {
         let programs_execution_cost = 10;
         let programs_execution_cost = 10;
         let num_txs = 4;
         let num_txs = 4;
 
 
-        let dummy_transaction = WritableKeysTransaction(vec![]);
+        let dummy_transaction = RuntimeTransaction::new_for_tests(WritableKeysTransaction(vec![]));
         let tx_cost_results: Vec<_> = (0..num_txs)
         let tx_cost_results: Vec<_> = (0..num_txs)
             .map(|n| {
             .map(|n| {
                 if n % 2 == 0 {
                 if n % 2 == 0 {
@@ -963,7 +965,6 @@ mod tests {
                         programs_execution_cost,
                         programs_execution_cost,
                         loaded_accounts_data_size_cost: 0,
                         loaded_accounts_data_size_cost: 0,
                         allocated_accounts_data_size: 0,
                         allocated_accounts_data_size: 0,
-                        signature_details: TransactionSignatureDetails::new(0, 0, 0),
                     }))
                     }))
                 } else {
                 } else {
                     Err(TransactionError::WouldExceedMaxBlockCostLimit)
                     Err(TransactionError::WouldExceedMaxBlockCostLimit)

+ 2 - 1
core/src/banking_stage/scheduler_messages.rs

@@ -1,4 +1,5 @@
 use {
 use {
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{clock::Slot, transaction::SanitizedTransaction},
     solana_sdk::{clock::Slot, transaction::SanitizedTransaction},
     std::fmt::Display,
     std::fmt::Display,
 };
 };
@@ -46,7 +47,7 @@ pub struct MaxAge {
 pub struct ConsumeWork {
 pub struct ConsumeWork {
     pub batch_id: TransactionBatchId,
     pub batch_id: TransactionBatchId,
     pub ids: Vec<TransactionId>,
     pub ids: Vec<TransactionId>,
-    pub transactions: Vec<SanitizedTransaction>,
+    pub transactions: Vec<RuntimeTransaction<SanitizedTransaction>>,
     pub max_ages: Vec<MaxAge>,
     pub max_ages: Vec<MaxAge>,
 }
 }
 
 

+ 23 - 15
core/src/banking_stage/transaction_scheduler/prio_graph_scheduler.rs

@@ -21,6 +21,7 @@ use {
     prio_graph::{AccessKind, GraphNode, PrioGraph},
     prio_graph::{AccessKind, GraphNode, PrioGraph},
     solana_cost_model::block_cost_limits::MAX_BLOCK_UNITS,
     solana_cost_model::block_cost_limits::MAX_BLOCK_UNITS,
     solana_measure::measure_us,
     solana_measure::measure_us,
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{pubkey::Pubkey, saturating_add_assign, transaction::SanitizedTransaction},
     solana_sdk::{pubkey::Pubkey, saturating_add_assign, transaction::SanitizedTransaction},
 };
 };
 
 
@@ -83,8 +84,8 @@ impl PrioGraphScheduler {
     pub(crate) fn schedule(
     pub(crate) fn schedule(
         &mut self,
         &mut self,
         container: &mut TransactionStateContainer,
         container: &mut TransactionStateContainer,
-        pre_graph_filter: impl Fn(&[&SanitizedTransaction], &mut [bool]),
-        pre_lock_filter: impl Fn(&SanitizedTransaction) -> bool,
+        pre_graph_filter: impl Fn(&[&RuntimeTransaction<SanitizedTransaction>], &mut [bool]),
+        pre_lock_filter: impl Fn(&RuntimeTransaction<SanitizedTransaction>) -> bool,
     ) -> Result<SchedulingSummary, SchedulerError> {
     ) -> Result<SchedulingSummary, SchedulerError> {
         let num_threads = self.consume_work_senders.len();
         let num_threads = self.consume_work_senders.len();
         let max_cu_per_thread = MAX_BLOCK_UNITS / num_threads as u64;
         let max_cu_per_thread = MAX_BLOCK_UNITS / num_threads as u64;
@@ -373,7 +374,7 @@ impl PrioGraphScheduler {
     fn complete_batch(
     fn complete_batch(
         &mut self,
         &mut self,
         batch_id: TransactionBatchId,
         batch_id: TransactionBatchId,
-        transactions: &[SanitizedTransaction],
+        transactions: &[RuntimeTransaction<SanitizedTransaction>],
     ) {
     ) {
         let thread_id = self.in_flight_tracker.complete_batch(batch_id);
         let thread_id = self.in_flight_tracker.complete_batch(batch_id);
         for transaction in transactions {
         for transaction in transactions {
@@ -444,7 +445,7 @@ impl PrioGraphScheduler {
         thread_set: ThreadSet,
         thread_set: ThreadSet,
         batch_cus_per_thread: &[u64],
         batch_cus_per_thread: &[u64],
         in_flight_cus_per_thread: &[u64],
         in_flight_cus_per_thread: &[u64],
-        batches_per_thread: &[Vec<SanitizedTransaction>],
+        batches_per_thread: &[Vec<RuntimeTransaction<SanitizedTransaction>>],
         in_flight_per_thread: &[usize],
         in_flight_per_thread: &[usize],
     ) -> ThreadId {
     ) -> ThreadId {
         thread_set
         thread_set
@@ -495,7 +496,7 @@ pub(crate) struct SchedulingSummary {
 
 
 struct Batches {
 struct Batches {
     ids: Vec<Vec<TransactionId>>,
     ids: Vec<Vec<TransactionId>>,
-    transactions: Vec<Vec<SanitizedTransaction>>,
+    transactions: Vec<Vec<RuntimeTransaction<SanitizedTransaction>>>,
     max_ages: Vec<Vec<MaxAge>>,
     max_ages: Vec<Vec<MaxAge>>,
     total_cus: Vec<u64>,
     total_cus: Vec<u64>,
 }
 }
@@ -504,7 +505,10 @@ impl Batches {
     fn new(num_threads: usize) -> Self {
     fn new(num_threads: usize) -> Self {
         Self {
         Self {
             ids: vec![Vec::with_capacity(TARGET_NUM_TRANSACTIONS_PER_BATCH); num_threads],
             ids: vec![Vec::with_capacity(TARGET_NUM_TRANSACTIONS_PER_BATCH); num_threads],
-            transactions: vec![Vec::with_capacity(TARGET_NUM_TRANSACTIONS_PER_BATCH); num_threads],
+
+            transactions: (0..num_threads)
+                .map(|_| Vec::with_capacity(TARGET_NUM_TRANSACTIONS_PER_BATCH))
+                .collect(),
             max_ages: vec![Vec::with_capacity(TARGET_NUM_TRANSACTIONS_PER_BATCH); num_threads],
             max_ages: vec![Vec::with_capacity(TARGET_NUM_TRANSACTIONS_PER_BATCH); num_threads],
             total_cus: vec![0; num_threads],
             total_cus: vec![0; num_threads],
         }
         }
@@ -515,7 +519,7 @@ impl Batches {
         thread_id: ThreadId,
         thread_id: ThreadId,
     ) -> (
     ) -> (
         Vec<TransactionId>,
         Vec<TransactionId>,
-        Vec<SanitizedTransaction>,
+        Vec<RuntimeTransaction<SanitizedTransaction>>,
         Vec<MaxAge>,
         Vec<MaxAge>,
         u64,
         u64,
     ) {
     ) {
@@ -540,7 +544,7 @@ impl Batches {
 /// A transaction has been scheduled to a thread.
 /// A transaction has been scheduled to a thread.
 struct TransactionSchedulingInfo {
 struct TransactionSchedulingInfo {
     thread_id: ThreadId,
     thread_id: ThreadId,
-    transaction: SanitizedTransaction,
+    transaction: RuntimeTransaction<SanitizedTransaction>,
     max_age: MaxAge,
     max_age: MaxAge,
     cost: u64,
     cost: u64,
 }
 }
@@ -556,7 +560,7 @@ enum TransactionSchedulingError {
 
 
 fn try_schedule_transaction(
 fn try_schedule_transaction(
     transaction_state: &mut TransactionState,
     transaction_state: &mut TransactionState,
-    pre_lock_filter: impl Fn(&SanitizedTransaction) -> bool,
+    pre_lock_filter: impl Fn(&RuntimeTransaction<SanitizedTransaction>) -> bool,
     blocking_locks: &mut ReadWriteAccountSet,
     blocking_locks: &mut ReadWriteAccountSet,
     account_locks: &mut ThreadAwareAccountLocks,
     account_locks: &mut ThreadAwareAccountLocks,
     num_threads: usize,
     num_threads: usize,
@@ -661,7 +665,7 @@ mod tests {
         to_pubkeys: impl IntoIterator<Item = impl Borrow<Pubkey>>,
         to_pubkeys: impl IntoIterator<Item = impl Borrow<Pubkey>>,
         lamports: u64,
         lamports: u64,
         priority: u64,
         priority: u64,
-    ) -> SanitizedTransaction {
+    ) -> RuntimeTransaction<SanitizedTransaction> {
         let to_pubkeys_lamports = to_pubkeys
         let to_pubkeys_lamports = to_pubkeys
             .into_iter()
             .into_iter()
             .map(|pubkey| *pubkey.borrow())
             .map(|pubkey| *pubkey.borrow())
@@ -673,7 +677,7 @@ mod tests {
         ixs.push(prioritization);
         ixs.push(prioritization);
         let message = Message::new(&ixs, Some(&from_keypair.pubkey()));
         let message = Message::new(&ixs, Some(&from_keypair.pubkey()));
         let tx = Transaction::new(&[from_keypair], message, Hash::default());
         let tx = Transaction::new(&[from_keypair], message, Hash::default());
-        SanitizedTransaction::from_transaction_for_tests(tx)
+        RuntimeTransaction::from_transaction_for_tests(tx)
     }
     }
 
 
     fn create_container(
     fn create_container(
@@ -735,11 +739,14 @@ mod tests {
             .unzip()
             .unzip()
     }
     }
 
 
-    fn test_pre_graph_filter(_txs: &[&SanitizedTransaction], results: &mut [bool]) {
+    fn test_pre_graph_filter(
+        _txs: &[&RuntimeTransaction<SanitizedTransaction>],
+        results: &mut [bool],
+    ) {
         results.fill(true);
         results.fill(true);
     }
     }
 
 
-    fn test_pre_lock_filter(_tx: &SanitizedTransaction) -> bool {
+    fn test_pre_lock_filter(_tx: &RuntimeTransaction<SanitizedTransaction>) -> bool {
         true
         true
     }
     }
 
 
@@ -914,8 +921,9 @@ mod tests {
         ]);
         ]);
 
 
         // 2nd transaction should be filtered out and dropped before locking.
         // 2nd transaction should be filtered out and dropped before locking.
-        let pre_lock_filter =
-            |tx: &SanitizedTransaction| tx.message().fee_payer() != &keypair.pubkey();
+        let pre_lock_filter = |tx: &RuntimeTransaction<SanitizedTransaction>| {
+            tx.message().fee_payer() != &keypair.pubkey()
+        };
         let scheduling_summary = scheduler
         let scheduling_summary = scheduler
             .schedule(&mut container, test_pre_graph_filter, pre_lock_filter)
             .schedule(&mut container, test_pre_graph_filter, pre_lock_filter)
             .unwrap();
             .unwrap();

+ 6 - 3
core/src/banking_stage/transaction_scheduler/scheduler_controller.rs

@@ -28,7 +28,10 @@ use {
     solana_cost_model::cost_model::CostModel,
     solana_cost_model::cost_model::CostModel,
     solana_measure::measure_us,
     solana_measure::measure_us,
     solana_runtime::{bank::Bank, bank_forks::BankForks},
     solana_runtime::{bank::Bank, bank_forks::BankForks},
-    solana_runtime_transaction::instructions_processor::process_compute_budget_instructions,
+    solana_runtime_transaction::{
+        instructions_processor::process_compute_budget_instructions,
+        runtime_transaction::RuntimeTransaction,
+    },
     solana_sdk::{
     solana_sdk::{
         self,
         self,
         address_lookup_table::state::estimate_last_valid_slot,
         address_lookup_table::state::estimate_last_valid_slot,
@@ -223,7 +226,7 @@ impl<T: LikeClusterInfo> SchedulerController<T> {
     }
     }
 
 
     fn pre_graph_filter(
     fn pre_graph_filter(
-        transactions: &[&SanitizedTransaction],
+        transactions: &[&RuntimeTransaction<SanitizedTransaction>],
         results: &mut [bool],
         results: &mut [bool],
         bank: &Bank,
         bank: &Bank,
         max_age: usize,
         max_age: usize,
@@ -661,7 +664,7 @@ impl<T: LikeClusterInfo> SchedulerController<T> {
     /// Any difference in the prioritization is negligible for
     /// Any difference in the prioritization is negligible for
     /// the current transaction costs.
     /// the current transaction costs.
     fn calculate_priority_and_cost(
     fn calculate_priority_and_cost(
-        transaction: &SanitizedTransaction,
+        transaction: &RuntimeTransaction<SanitizedTransaction>,
         fee_budget_limits: &FeeBudgetLimits,
         fee_budget_limits: &FeeBudgetLimits,
         bank: &Bank,
         bank: &Bank,
     ) -> (u64, u64) {
     ) -> (u64, u64) {

+ 3 - 2
core/src/banking_stage/transaction_scheduler/transaction_state.rs

@@ -2,13 +2,14 @@ use {
     crate::banking_stage::{
     crate::banking_stage::{
         immutable_deserialized_packet::ImmutableDeserializedPacket, scheduler_messages::MaxAge,
         immutable_deserialized_packet::ImmutableDeserializedPacket, scheduler_messages::MaxAge,
     },
     },
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::transaction::SanitizedTransaction,
     solana_sdk::transaction::SanitizedTransaction,
     std::sync::Arc,
     std::sync::Arc,
 };
 };
 
 
 /// Simple wrapper type to tie a sanitized transaction to max age slot.
 /// Simple wrapper type to tie a sanitized transaction to max age slot.
 pub(crate) struct SanitizedTransactionTTL {
 pub(crate) struct SanitizedTransactionTTL {
-    pub(crate) transaction: SanitizedTransaction,
+    pub(crate) transaction: RuntimeTransaction<SanitizedTransaction>,
     pub(crate) max_age: MaxAge,
     pub(crate) max_age: MaxAge,
 }
 }
 
 
@@ -232,7 +233,7 @@ mod tests {
             ImmutableDeserializedPacket::new(Packet::from_data(None, tx.clone()).unwrap()).unwrap(),
             ImmutableDeserializedPacket::new(Packet::from_data(None, tx.clone()).unwrap()).unwrap(),
         );
         );
         let transaction_ttl = SanitizedTransactionTTL {
         let transaction_ttl = SanitizedTransactionTTL {
-            transaction: SanitizedTransaction::from_transaction_for_tests(tx),
+            transaction: RuntimeTransaction::from_transaction_for_tests(tx),
             max_age: MaxAge {
             max_age: MaxAge {
                 epoch_invalidation_slot: Slot::MAX,
                 epoch_invalidation_slot: Slot::MAX,
                 alt_invalidation_slot: Slot::MAX,
                 alt_invalidation_slot: Slot::MAX,

+ 5 - 10
core/src/banking_stage/transaction_scheduler/transaction_state_container.rs

@@ -154,16 +154,11 @@ mod tests {
     use {
     use {
         super::*,
         super::*,
         crate::banking_stage::scheduler_messages::MaxAge,
         crate::banking_stage::scheduler_messages::MaxAge,
+        solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
         solana_sdk::{
         solana_sdk::{
-            compute_budget::ComputeBudgetInstruction,
-            hash::Hash,
-            message::Message,
-            packet::Packet,
-            signature::Keypair,
-            signer::Signer,
-            slot_history::Slot,
-            system_instruction,
-            transaction::{SanitizedTransaction, Transaction},
+            compute_budget::ComputeBudgetInstruction, hash::Hash, message::Message, packet::Packet,
+            signature::Keypair, signer::Signer, slot_history::Slot, system_instruction,
+            transaction::Transaction,
         },
         },
     };
     };
 
 
@@ -186,7 +181,7 @@ mod tests {
             ComputeBudgetInstruction::set_compute_unit_price(priority),
             ComputeBudgetInstruction::set_compute_unit_price(priority),
         ];
         ];
         let message = Message::new(&ixs, Some(&from_keypair.pubkey()));
         let message = Message::new(&ixs, Some(&from_keypair.pubkey()));
-        let tx = SanitizedTransaction::from_transaction_for_tests(Transaction::new(
+        let tx = RuntimeTransaction::from_transaction_for_tests(Transaction::new(
             &[&from_keypair],
             &[&from_keypair],
             message,
             message,
             Hash::default(),
             Hash::default(),

+ 17 - 17
core/src/banking_stage/unprocessed_transaction_storage.rs

@@ -21,6 +21,7 @@ use {
     solana_feature_set::FeatureSet,
     solana_feature_set::FeatureSet,
     solana_measure::measure_us,
     solana_measure::measure_us,
     solana_runtime::bank::Bank,
     solana_runtime::bank::Bank,
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{
     solana_sdk::{
         clock::FORWARD_TRANSACTIONS_TO_LEADER_AT_SLOT_OFFSET, hash::Hash, saturating_add_assign,
         clock::FORWARD_TRANSACTIONS_TO_LEADER_AT_SLOT_OFFSET, hash::Hash, saturating_add_assign,
         transaction::SanitizedTransaction,
         transaction::SanitizedTransaction,
@@ -137,7 +138,7 @@ fn filter_processed_packets<'a, F>(
 pub struct ConsumeScannerPayload<'a> {
 pub struct ConsumeScannerPayload<'a> {
     pub reached_end_of_slot: bool,
     pub reached_end_of_slot: bool,
     pub account_locks: ReadWriteAccountSet,
     pub account_locks: ReadWriteAccountSet,
-    pub sanitized_transactions: Vec<SanitizedTransaction>,
+    pub sanitized_transactions: Vec<RuntimeTransaction<SanitizedTransaction>>,
     pub slot_metrics_tracker: &'a mut LeaderSlotMetricsTracker,
     pub slot_metrics_tracker: &'a mut LeaderSlotMetricsTracker,
     pub message_hash_to_transaction: &'a mut HashMap<Hash, DeserializedPacket>,
     pub message_hash_to_transaction: &'a mut HashMap<Hash, DeserializedPacket>,
     pub error_counters: TransactionErrorMetrics,
     pub error_counters: TransactionErrorMetrics,
@@ -788,22 +789,21 @@ impl ThreadLocalUnprocessedPackets {
         packets_to_process: &[Arc<ImmutableDeserializedPacket>],
         packets_to_process: &[Arc<ImmutableDeserializedPacket>],
         bank: &Bank,
         bank: &Bank,
         total_dropped_packets: &mut usize,
         total_dropped_packets: &mut usize,
-    ) -> (Vec<SanitizedTransaction>, Vec<usize>) {
+    ) -> (Vec<RuntimeTransaction<SanitizedTransaction>>, Vec<usize>) {
         // Get ref of ImmutableDeserializedPacket
         // Get ref of ImmutableDeserializedPacket
         let deserialized_packets = packets_to_process.iter().map(|p| &**p);
         let deserialized_packets = packets_to_process.iter().map(|p| &**p);
-        let (transactions, transaction_to_packet_indexes): (Vec<SanitizedTransaction>, Vec<usize>) =
-            deserialized_packets
-                .enumerate()
-                .filter_map(|(packet_index, deserialized_packet)| {
-                    deserialized_packet
-                        .build_sanitized_transaction(
-                            bank.vote_only_bank(),
-                            bank,
-                            bank.get_reserved_account_keys(),
-                        )
-                        .map(|(transaction, _deactivation_slot)| (transaction, packet_index))
-                })
-                .unzip();
+        let (transactions, transaction_to_packet_indexes): (Vec<_>, Vec<_>) = deserialized_packets
+            .enumerate()
+            .filter_map(|(packet_index, deserialized_packet)| {
+                deserialized_packet
+                    .build_sanitized_transaction(
+                        bank.vote_only_bank(),
+                        bank,
+                        bank.get_reserved_account_keys(),
+                    )
+                    .map(|(transaction, _deactivation_slot)| (transaction, packet_index))
+            })
+            .unzip();
 
 
         let filtered_count = packets_to_process.len().saturating_sub(transactions.len());
         let filtered_count = packets_to_process.len().saturating_sub(transactions.len());
         saturating_add_assign!(*total_dropped_packets, filtered_count);
         saturating_add_assign!(*total_dropped_packets, filtered_count);
@@ -813,7 +813,7 @@ impl ThreadLocalUnprocessedPackets {
 
 
     /// Checks sanitized transactions against bank, returns valid transaction indexes
     /// Checks sanitized transactions against bank, returns valid transaction indexes
     fn filter_invalid_transactions(
     fn filter_invalid_transactions(
-        transactions: &[SanitizedTransaction],
+        transactions: &[RuntimeTransaction<SanitizedTransaction>],
         bank: &Bank,
         bank: &Bank,
         total_dropped_packets: &mut usize,
         total_dropped_packets: &mut usize,
     ) -> Vec<usize> {
     ) -> Vec<usize> {
@@ -849,7 +849,7 @@ impl ThreadLocalUnprocessedPackets {
     fn add_filtered_packets_to_forward_buffer(
     fn add_filtered_packets_to_forward_buffer(
         forward_buffer: &mut ForwardPacketBatchesByAccounts,
         forward_buffer: &mut ForwardPacketBatchesByAccounts,
         packets_to_process: &[Arc<ImmutableDeserializedPacket>],
         packets_to_process: &[Arc<ImmutableDeserializedPacket>],
-        transactions: &[SanitizedTransaction],
+        transactions: &[RuntimeTransaction<SanitizedTransaction>],
         transaction_to_packet_indexes: &[usize],
         transaction_to_packet_indexes: &[usize],
         forwardable_transaction_indexes: &[usize],
         forwardable_transaction_indexes: &[usize],
         total_dropped_packets: &mut usize,
         total_dropped_packets: &mut usize,

+ 3 - 2
core/tests/unified_scheduler.rs

@@ -19,6 +19,7 @@ use {
         accounts_background_service::AbsRequestSender, bank::Bank, bank_forks::BankForks,
         accounts_background_service::AbsRequestSender, bank::Bank, bank_forks::BankForks,
         genesis_utils::GenesisConfigInfo, prioritization_fee_cache::PrioritizationFeeCache,
         genesis_utils::GenesisConfigInfo, prioritization_fee_cache::PrioritizationFeeCache,
     },
     },
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{
     solana_sdk::{
         hash::Hash,
         hash::Hash,
         pubkey::Pubkey,
         pubkey::Pubkey,
@@ -48,7 +49,7 @@ fn test_scheduler_waited_by_drop_bank_service() {
             result: &mut Result<()>,
             result: &mut Result<()>,
             timings: &mut ExecuteTimings,
             timings: &mut ExecuteTimings,
             bank: &Arc<Bank>,
             bank: &Arc<Bank>,
-            transaction: &SanitizedTransaction,
+            transaction: &RuntimeTransaction<SanitizedTransaction>,
             index: usize,
             index: usize,
             handler_context: &HandlerContext,
             handler_context: &HandlerContext,
         ) {
         ) {
@@ -97,7 +98,7 @@ fn test_scheduler_waited_by_drop_bank_service() {
     let root_hash = root_bank.hash();
     let root_hash = root_bank.hash();
     bank_forks.write().unwrap().insert(root_bank);
     bank_forks.write().unwrap().insert(root_bank);
 
 
-    let tx = SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
+    let tx = RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
         &mint_keypair,
         &mint_keypair,
         &solana_sdk::pubkey::new_rand(),
         &solana_sdk::pubkey::new_rand(),
         2,
         2,

+ 3 - 0
cost-model/Cargo.toml

@@ -38,6 +38,9 @@ rand = "0.8.5"
 # See order-crates-for-publishing.py for using this unusual `path = "."`
 # See order-crates-for-publishing.py for using this unusual `path = "."`
 solana-cost-model = { path = ".", features = ["dev-context-only-utils"] }
 solana-cost-model = { path = ".", features = ["dev-context-only-utils"] }
 solana-logger = { workspace = true }
 solana-logger = { workspace = true }
+solana-runtime-transaction = { workspace = true, features = [
+    "dev-context-only-utils",
+] }
 solana-sdk = { workspace = true, features = ["dev-context-only-utils"] }
 solana-sdk = { workspace = true, features = ["dev-context-only-utils"] }
 solana-system-program = { workspace = true }
 solana-system-program = { workspace = true }
 static_assertions = { workspace = true }
 static_assertions = { workspace = true }

+ 3 - 2
cost-model/benches/cost_model.rs

@@ -2,6 +2,7 @@
 extern crate test;
 extern crate test;
 use {
 use {
     solana_cost_model::cost_model::CostModel,
     solana_cost_model::cost_model::CostModel,
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{
     solana_sdk::{
         feature_set::FeatureSet,
         feature_set::FeatureSet,
         hash::Hash,
         hash::Hash,
@@ -16,7 +17,7 @@ use {
 };
 };
 
 
 struct BenchSetup {
 struct BenchSetup {
-    transactions: Vec<SanitizedTransaction>,
+    transactions: Vec<RuntimeTransaction<SanitizedTransaction>>,
     feature_set: FeatureSet,
     feature_set: FeatureSet,
 }
 }
 
 
@@ -32,7 +33,7 @@ fn setup(num_transactions: usize) -> BenchSetup {
             let ixs = system_instruction::transfer_many(&from_keypair.pubkey(), &to_lamports);
             let ixs = system_instruction::transfer_many(&from_keypair.pubkey(), &to_lamports);
             let message = Message::new(&ixs, Some(&from_keypair.pubkey()));
             let message = Message::new(&ixs, Some(&from_keypair.pubkey()));
             let transaction = Transaction::new(&[from_keypair], message, Hash::default());
             let transaction = Transaction::new(&[from_keypair], message, Hash::default());
-            SanitizedTransaction::from_transaction_for_tests(transaction)
+            RuntimeTransaction::from_transaction_for_tests(transaction)
         })
         })
         .collect();
         .collect();
 
 

+ 5 - 5
cost-model/benches/cost_tracker.rs

@@ -6,13 +6,14 @@ use {
         cost_tracker::CostTracker,
         cost_tracker::CostTracker,
         transaction_cost::{TransactionCost, UsageCostDetails, WritableKeysTransaction},
         transaction_cost::{TransactionCost, UsageCostDetails, WritableKeysTransaction},
     },
     },
-    solana_sdk::{message::TransactionSignatureDetails, pubkey::Pubkey},
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
+    solana_sdk::pubkey::Pubkey,
     test::Bencher,
     test::Bencher,
 };
 };
 
 
 struct BenchSetup {
 struct BenchSetup {
     cost_tracker: CostTracker,
     cost_tracker: CostTracker,
-    transactions: Vec<WritableKeysTransaction>,
+    transactions: Vec<RuntimeTransaction<WritableKeysTransaction>>,
 }
 }
 
 
 fn setup(num_transactions: usize, contentious_transactions: bool) -> BenchSetup {
 fn setup(num_transactions: usize, contentious_transactions: bool) -> BenchSetup {
@@ -33,7 +34,7 @@ fn setup(num_transactions: usize, contentious_transactions: bool) -> BenchSetup
                 };
                 };
                 writable_accounts.push(writable_account_key)
                 writable_accounts.push(writable_account_key)
             });
             });
-            WritableKeysTransaction(writable_accounts)
+            RuntimeTransaction::new_for_tests(WritableKeysTransaction(writable_accounts))
         })
         })
         .collect_vec();
         .collect_vec();
 
 
@@ -44,7 +45,7 @@ fn setup(num_transactions: usize, contentious_transactions: bool) -> BenchSetup
 }
 }
 
 
 fn get_costs(
 fn get_costs(
-    transactions: &[WritableKeysTransaction],
+    transactions: &[RuntimeTransaction<WritableKeysTransaction>],
 ) -> Vec<TransactionCost<WritableKeysTransaction>> {
 ) -> Vec<TransactionCost<WritableKeysTransaction>> {
     transactions
     transactions
         .iter()
         .iter()
@@ -57,7 +58,6 @@ fn get_costs(
                 programs_execution_cost: 9999,
                 programs_execution_cost: 9999,
                 loaded_accounts_data_size_cost: 0,
                 loaded_accounts_data_size_cost: 0,
                 allocated_accounts_data_size: 0,
                 allocated_accounts_data_size: 0,
-                signature_details: TransactionSignatureDetails::new(0, 0, 0),
             })
             })
         })
         })
         .collect_vec()
         .collect_vec()

+ 56 - 60
cost-model/src/cost_model.rs

@@ -12,13 +12,13 @@ use {
         DEFAULT_HEAP_COST, DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT, MAX_COMPUTE_UNIT_LIMIT,
         DEFAULT_HEAP_COST, DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT, MAX_COMPUTE_UNIT_LIMIT,
     },
     },
     solana_feature_set::{self as feature_set, FeatureSet},
     solana_feature_set::{self as feature_set, FeatureSet},
-    solana_runtime_transaction::instructions_processor::process_compute_budget_instructions,
+    solana_runtime_transaction::{
+        runtime_transaction::RuntimeTransaction, transaction_meta::StaticMeta,
+    },
     solana_sdk::{
     solana_sdk::{
         borsh1::try_from_slice_unchecked,
         borsh1::try_from_slice_unchecked,
         compute_budget::{self, ComputeBudgetInstruction},
         compute_budget::{self, ComputeBudgetInstruction},
         fee::FeeStructure,
         fee::FeeStructure,
-        instruction::CompiledInstruction,
-        message::TransactionSignatureDetails,
         program_utils::limited_deserialize,
         program_utils::limited_deserialize,
         pubkey::Pubkey,
         pubkey::Pubkey,
         saturating_add_assign,
         saturating_add_assign,
@@ -27,9 +27,8 @@ use {
             MAX_PERMITTED_DATA_LENGTH,
             MAX_PERMITTED_DATA_LENGTH,
         },
         },
         system_program,
         system_program,
-        transaction::SanitizedTransaction,
     },
     },
-    solana_svm_transaction::svm_message::SVMMessage,
+    solana_svm_transaction::{instruction::SVMInstruction, svm_message::SVMMessage},
 };
 };
 
 
 pub struct CostModel;
 pub struct CostModel;
@@ -42,15 +41,14 @@ enum SystemProgramAccountAllocation {
 }
 }
 
 
 impl CostModel {
 impl CostModel {
-    pub fn calculate_cost<'a>(
-        transaction: &'a SanitizedTransaction,
+    pub fn calculate_cost<'a, Tx: SVMMessage>(
+        transaction: &'a RuntimeTransaction<Tx>,
         feature_set: &FeatureSet,
         feature_set: &FeatureSet,
-    ) -> TransactionCost<'a, SanitizedTransaction> {
+    ) -> TransactionCost<'a, Tx> {
         if transaction.is_simple_vote_transaction() {
         if transaction.is_simple_vote_transaction() {
             TransactionCost::SimpleVote { transaction }
             TransactionCost::SimpleVote { transaction }
         } else {
         } else {
-            let (signatures_count_detail, signature_cost) =
-                Self::get_signature_cost(transaction, feature_set);
+            let signature_cost = Self::get_signature_cost(transaction, feature_set);
             let write_lock_cost = Self::get_write_lock_cost(transaction, feature_set);
             let write_lock_cost = Self::get_write_lock_cost(transaction, feature_set);
             let (programs_execution_cost, loaded_accounts_data_size_cost, data_bytes_cost) =
             let (programs_execution_cost, loaded_accounts_data_size_cost, data_bytes_cost) =
                 Self::get_transaction_cost(transaction, feature_set);
                 Self::get_transaction_cost(transaction, feature_set);
@@ -65,7 +63,6 @@ impl CostModel {
                 programs_execution_cost,
                 programs_execution_cost,
                 loaded_accounts_data_size_cost,
                 loaded_accounts_data_size_cost,
                 allocated_accounts_data_size,
                 allocated_accounts_data_size,
-                signature_details: signatures_count_detail,
             };
             };
 
 
             TransactionCost::Transaction(usage_cost_details)
             TransactionCost::Transaction(usage_cost_details)
@@ -74,17 +71,16 @@ impl CostModel {
 
 
     // Calculate executed transaction CU cost, with actual execution and loaded accounts size
     // Calculate executed transaction CU cost, with actual execution and loaded accounts size
     // costs.
     // costs.
-    pub fn calculate_cost_for_executed_transaction<'a>(
-        transaction: &'a SanitizedTransaction,
+    pub fn calculate_cost_for_executed_transaction<'a, Tx: SVMMessage>(
+        transaction: &'a RuntimeTransaction<Tx>,
         actual_programs_execution_cost: u64,
         actual_programs_execution_cost: u64,
         actual_loaded_accounts_data_size_bytes: u32,
         actual_loaded_accounts_data_size_bytes: u32,
         feature_set: &FeatureSet,
         feature_set: &FeatureSet,
-    ) -> TransactionCost<'a, SanitizedTransaction> {
+    ) -> TransactionCost<'a, Tx> {
         if transaction.is_simple_vote_transaction() {
         if transaction.is_simple_vote_transaction() {
             TransactionCost::SimpleVote { transaction }
             TransactionCost::SimpleVote { transaction }
         } else {
         } else {
-            let (signatures_count_detail, signature_cost) =
-                Self::get_signature_cost(transaction, feature_set);
+            let signature_cost = Self::get_signature_cost(transaction, feature_set);
             let write_lock_cost = Self::get_write_lock_cost(transaction, feature_set);
             let write_lock_cost = Self::get_write_lock_cost(transaction, feature_set);
 
 
             let instructions_data_cost = Self::get_instructions_data_cost(transaction);
             let instructions_data_cost = Self::get_instructions_data_cost(transaction);
@@ -105,7 +101,6 @@ impl CostModel {
                 programs_execution_cost,
                 programs_execution_cost,
                 loaded_accounts_data_size_cost,
                 loaded_accounts_data_size_cost,
                 allocated_accounts_data_size,
                 allocated_accounts_data_size,
-                signature_details: signatures_count_detail,
             };
             };
 
 
             TransactionCost::Transaction(usage_cost_details)
             TransactionCost::Transaction(usage_cost_details)
@@ -114,10 +109,10 @@ impl CostModel {
 
 
     /// Returns signature details and the total signature cost
     /// Returns signature details and the total signature cost
     fn get_signature_cost(
     fn get_signature_cost(
-        transaction: &SanitizedTransaction,
+        transaction: &RuntimeTransaction<impl SVMMessage>,
         feature_set: &FeatureSet,
         feature_set: &FeatureSet,
-    ) -> (TransactionSignatureDetails, u64) {
-        let signatures_count_detail = transaction.message().get_signature_details();
+    ) -> u64 {
+        let signatures_count_detail = transaction.signature_details();
 
 
         let ed25519_verify_cost =
         let ed25519_verify_cost =
             if feature_set.is_active(&feature_set::ed25519_precompile_verify_strict::id()) {
             if feature_set.is_active(&feature_set::ed25519_precompile_verify_strict::id()) {
@@ -126,7 +121,7 @@ impl CostModel {
                 ED25519_VERIFY_COST
                 ED25519_VERIFY_COST
             };
             };
 
 
-        let signature_cost = signatures_count_detail
+        signatures_count_detail
             .num_transaction_signatures()
             .num_transaction_signatures()
             .saturating_mul(SIGNATURE_COST)
             .saturating_mul(SIGNATURE_COST)
             .saturating_add(
             .saturating_add(
@@ -138,9 +133,7 @@ impl CostModel {
                 signatures_count_detail
                 signatures_count_detail
                     .num_ed25519_instruction_signatures()
                     .num_ed25519_instruction_signatures()
                     .saturating_mul(ed25519_verify_cost),
                     .saturating_mul(ed25519_verify_cost),
-            );
-
-        (signatures_count_detail, signature_cost)
+            )
     }
     }
 
 
     fn get_writable_accounts(message: &impl SVMMessage) -> impl Iterator<Item = &Pubkey> {
     fn get_writable_accounts(message: &impl SVMMessage) -> impl Iterator<Item = &Pubkey> {
@@ -164,7 +157,7 @@ impl CostModel {
 
 
     /// Return (programs_execution_cost, loaded_accounts_data_size_cost, data_bytes_cost)
     /// Return (programs_execution_cost, loaded_accounts_data_size_cost, data_bytes_cost)
     fn get_transaction_cost(
     fn get_transaction_cost(
-        transaction: &impl SVMMessage,
+        transaction: &RuntimeTransaction<impl SVMMessage>,
         feature_set: &FeatureSet,
         feature_set: &FeatureSet,
     ) -> (u64, u64, u64) {
     ) -> (u64, u64, u64) {
         let mut programs_execution_costs = 0u64;
         let mut programs_execution_costs = 0u64;
@@ -198,15 +191,20 @@ impl CostModel {
             }
             }
         }
         }
 
 
-        // if failed to process compute_budget instructions, the transaction will not be executed
-        // by `bank`, therefore it should be considered as no execution cost by cost model.
-        match process_compute_budget_instructions(transaction.program_instructions_iter()) {
+        // if failed to process compute budget instructions, the transaction
+        // will not be executed by `bank`, therefore it should be considered
+        // as no execution cost by cost model.
+        match transaction.compute_budget_limits(feature_set) {
             Ok(compute_budget_limits) => {
             Ok(compute_budget_limits) => {
-                // if tx contained user-space instructions and a more accurate estimate available correct it,
-                // where "user-space instructions" must be specifically checked by
-                // 'compute_unit_limit_is_set' flag, because compute_budget does not distinguish
-                // builtin and bpf instructions when calculating default compute-unit-limit. (see
-                // compute_budget.rs test `test_process_mixed_instructions_without_compute_budget`)
+                // if tx contained user-space instructions and a more accurate
+                // estimate available correct it, where
+                // "user-space instructions" must be specifically checked by
+                // 'compute_unit_limit_is_set' flag, because compute_budget
+                // does not distinguish builtin and bpf instructions when
+                // calculating default compute-unit-limit.
+                //
+                // (see compute_budget.rs test
+                // `test_process_mixed_instructions_without_compute_budget`)
                 if has_user_space_instructions && compute_unit_limit_is_set {
                 if has_user_space_instructions && compute_unit_limit_is_set {
                     programs_execution_costs = u64::from(compute_budget_limits.compute_unit_limit);
                     programs_execution_costs = u64::from(compute_budget_limits.compute_unit_limit);
                 }
                 }
@@ -229,11 +227,9 @@ impl CostModel {
     }
     }
 
 
     /// Return the instruction data bytes cost.
     /// Return the instruction data bytes cost.
-    fn get_instructions_data_cost(transaction: &SanitizedTransaction) -> u64 {
+    fn get_instructions_data_cost(transaction: &impl SVMMessage) -> u64 {
         let ix_data_bytes_len_total: u64 = transaction
         let ix_data_bytes_len_total: u64 = transaction
-            .message()
-            .instructions()
-            .iter()
+            .instructions_iter()
             .map(|instruction| instruction.data.len() as u64)
             .map(|instruction| instruction.data.len() as u64)
             .sum();
             .sum();
 
 
@@ -267,10 +263,10 @@ impl CostModel {
 
 
     fn calculate_account_data_size_on_instruction(
     fn calculate_account_data_size_on_instruction(
         program_id: &Pubkey,
         program_id: &Pubkey,
-        instruction: &CompiledInstruction,
+        instruction: SVMInstruction,
     ) -> SystemProgramAccountAllocation {
     ) -> SystemProgramAccountAllocation {
         if program_id == &system_program::id() {
         if program_id == &system_program::id() {
-            if let Ok(instruction) = limited_deserialize(&instruction.data) {
+            if let Ok(instruction) = limited_deserialize(instruction.data) {
                 Self::calculate_account_data_size_on_deserialized_system_instruction(instruction)
                 Self::calculate_account_data_size_on_deserialized_system_instruction(instruction)
             } else {
             } else {
                 SystemProgramAccountAllocation::Failed
                 SystemProgramAccountAllocation::Failed
@@ -282,9 +278,9 @@ impl CostModel {
 
 
     /// eventually, potentially determine account data size of all writable accounts
     /// eventually, potentially determine account data size of all writable accounts
     /// at the moment, calculate account data size of account creation
     /// at the moment, calculate account data size of account creation
-    fn calculate_allocated_accounts_data_size(transaction: &SanitizedTransaction) -> u64 {
+    fn calculate_allocated_accounts_data_size(transaction: &impl SVMMessage) -> u64 {
         let mut tx_attempted_allocation_size: u64 = 0;
         let mut tx_attempted_allocation_size: u64 = 0;
-        for (program_id, instruction) in transaction.message().program_instructions_iter() {
+        for (program_id, instruction) in transaction.program_instructions_iter() {
             match Self::calculate_account_data_size_on_instruction(program_id, instruction) {
             match Self::calculate_account_data_size_on_instruction(program_id, instruction) {
                 SystemProgramAccountAllocation::Failed => {
                 SystemProgramAccountAllocation::Failed => {
                     // If any system program instructions can be statically
                     // If any system program instructions can be statically
@@ -351,7 +347,7 @@ mod tests {
             )],
             )],
             Some(&Pubkey::new_unique()),
             Some(&Pubkey::new_unique()),
         ));
         ));
-        let sanitized_tx = SanitizedTransaction::from_transaction_for_tests(transaction);
+        let sanitized_tx = RuntimeTransaction::from_transaction_for_tests(transaction);
 
 
         assert_eq!(
         assert_eq!(
             CostModel::calculate_allocated_accounts_data_size(&sanitized_tx),
             CostModel::calculate_allocated_accounts_data_size(&sanitized_tx),
@@ -376,7 +372,7 @@ mod tests {
             ],
             ],
             Some(&Pubkey::new_unique()),
             Some(&Pubkey::new_unique()),
         ));
         ));
-        let sanitized_tx = SanitizedTransaction::from_transaction_for_tests(transaction);
+        let sanitized_tx = RuntimeTransaction::from_transaction_for_tests(transaction);
 
 
         assert_eq!(
         assert_eq!(
             CostModel::calculate_allocated_accounts_data_size(&sanitized_tx),
             CostModel::calculate_allocated_accounts_data_size(&sanitized_tx),
@@ -417,7 +413,7 @@ mod tests {
             ],
             ],
             Some(&Pubkey::new_unique()),
             Some(&Pubkey::new_unique()),
         ));
         ));
-        let sanitized_tx = SanitizedTransaction::from_transaction_for_tests(transaction);
+        let sanitized_tx = RuntimeTransaction::from_transaction_for_tests(transaction);
 
 
         assert_eq!(
         assert_eq!(
             CostModel::calculate_allocated_accounts_data_size(&sanitized_tx),
             CostModel::calculate_allocated_accounts_data_size(&sanitized_tx),
@@ -440,7 +436,7 @@ mod tests {
             ],
             ],
             Some(&Pubkey::new_unique()),
             Some(&Pubkey::new_unique()),
         ));
         ));
-        let sanitized_tx = SanitizedTransaction::from_transaction_for_tests(transaction);
+        let sanitized_tx = RuntimeTransaction::from_transaction_for_tests(transaction);
 
 
         assert_eq!(
         assert_eq!(
             0, // SystemProgramAccountAllocation::Failed,
             0, // SystemProgramAccountAllocation::Failed,
@@ -457,7 +453,7 @@ mod tests {
             ],
             ],
             Some(&Pubkey::new_unique()),
             Some(&Pubkey::new_unique()),
         ));
         ));
-        let sanitized_tx = SanitizedTransaction::from_transaction_for_tests(transaction);
+        let sanitized_tx = RuntimeTransaction::from_transaction_for_tests(transaction);
 
 
         assert_eq!(
         assert_eq!(
             0, // SystemProgramAccountAllocation::Failed,
             0, // SystemProgramAccountAllocation::Failed,
@@ -517,7 +513,7 @@ mod tests {
         let (mint_keypair, start_hash) = test_setup();
         let (mint_keypair, start_hash) = test_setup();
 
 
         let keypair = Keypair::new();
         let keypair = Keypair::new();
-        let simple_transaction = SanitizedTransaction::from_transaction_for_tests(
+        let simple_transaction = RuntimeTransaction::from_transaction_for_tests(
             system_transaction::transfer(&mint_keypair, &keypair.pubkey(), 2, start_hash),
             system_transaction::transfer(&mint_keypair, &keypair.pubkey(), 2, start_hash),
         );
         );
         debug!(
         debug!(
@@ -552,7 +548,7 @@ mod tests {
             vec![Pubkey::new_unique()],
             vec![Pubkey::new_unique()],
             instructions,
             instructions,
         );
         );
-        let token_transaction = SanitizedTransaction::from_transaction_for_tests(tx);
+        let token_transaction = RuntimeTransaction::from_transaction_for_tests(tx);
         debug!("token_transaction {:?}", token_transaction);
         debug!("token_transaction {:?}", token_transaction);
 
 
         let (program_execution_cost, _loaded_accounts_data_size_cost, data_bytes_cost) =
         let (program_execution_cost, _loaded_accounts_data_size_cost, data_bytes_cost) =
@@ -570,7 +566,7 @@ mod tests {
 
 
         // Cannot write-lock the system program, it will be demoted when taking locks.
         // Cannot write-lock the system program, it will be demoted when taking locks.
         // However, the cost should be calculated as if it were taken.
         // However, the cost should be calculated as if it were taken.
-        let simple_transaction = SanitizedTransaction::from_transaction_for_tests(
+        let simple_transaction = RuntimeTransaction::from_transaction_for_tests(
             system_transaction::transfer(&mint_keypair, &system_program::id(), 2, start_hash),
             system_transaction::transfer(&mint_keypair, &system_program::id(), 2, start_hash),
         );
         );
 
 
@@ -614,7 +610,7 @@ mod tests {
             vec![Pubkey::new_unique(), compute_budget::id()],
             vec![Pubkey::new_unique(), compute_budget::id()],
             instructions,
             instructions,
         );
         );
-        let token_transaction = SanitizedTransaction::from_transaction_for_tests(tx);
+        let token_transaction = RuntimeTransaction::from_transaction_for_tests(tx);
 
 
         let (program_execution_cost, _loaded_accounts_data_size_cost, data_bytes_cost) =
         let (program_execution_cost, _loaded_accounts_data_size_cost, data_bytes_cost) =
             CostModel::get_transaction_cost(&token_transaction, &FeatureSet::all_enabled());
             CostModel::get_transaction_cost(&token_transaction, &FeatureSet::all_enabled());
@@ -637,10 +633,10 @@ mod tests {
                     .unwrap(),
                     .unwrap(),
                 vec![],
                 vec![],
             ),
             ),
-            // to trigger `duplicate_instruction_error` error
+            // to trigger failure in `sanitize_and_convert_to_compute_budget_limits`
             CompiledInstruction::new_from_raw_parts(
             CompiledInstruction::new_from_raw_parts(
                 4,
                 4,
-                ComputeBudgetInstruction::SetComputeUnitLimit(1_000)
+                ComputeBudgetInstruction::SetLoadedAccountsDataSizeLimit(0)
                     .pack()
                     .pack()
                     .unwrap(),
                     .unwrap(),
                 vec![],
                 vec![],
@@ -656,7 +652,7 @@ mod tests {
             vec![Pubkey::new_unique(), compute_budget::id()],
             vec![Pubkey::new_unique(), compute_budget::id()],
             instructions,
             instructions,
         );
         );
-        let token_transaction = SanitizedTransaction::from_transaction_for_tests(tx);
+        let token_transaction = RuntimeTransaction::from_transaction_for_tests(tx);
 
 
         let (program_execution_cost, _loaded_accounts_data_size_cost, _data_bytes_cost) =
         let (program_execution_cost, _loaded_accounts_data_size_cost, _data_bytes_cost) =
             CostModel::get_transaction_cost(&token_transaction, &FeatureSet::all_enabled());
             CostModel::get_transaction_cost(&token_transaction, &FeatureSet::all_enabled());
@@ -672,7 +668,7 @@ mod tests {
         let instructions =
         let instructions =
             system_instruction::transfer_many(&mint_keypair.pubkey(), &[(key1, 1), (key2, 1)]);
             system_instruction::transfer_many(&mint_keypair.pubkey(), &[(key1, 1), (key2, 1)]);
         let message = Message::new(&instructions, Some(&mint_keypair.pubkey()));
         let message = Message::new(&instructions, Some(&mint_keypair.pubkey()));
-        let tx = SanitizedTransaction::from_transaction_for_tests(Transaction::new(
+        let tx = RuntimeTransaction::from_transaction_for_tests(Transaction::new(
             &[&mint_keypair],
             &[&mint_keypair],
             message,
             message,
             start_hash,
             start_hash,
@@ -704,7 +700,7 @@ mod tests {
             CompiledInstruction::new(3, &(), vec![0, 1]),
             CompiledInstruction::new(3, &(), vec![0, 1]),
             CompiledInstruction::new(4, &(), vec![0, 2]),
             CompiledInstruction::new(4, &(), vec![0, 2]),
         ];
         ];
-        let tx = SanitizedTransaction::from_transaction_for_tests(
+        let tx = RuntimeTransaction::from_transaction_for_tests(
             Transaction::new_with_compiled_instructions(
             Transaction::new_with_compiled_instructions(
                 &[&mint_keypair],
                 &[&mint_keypair],
                 &[key1, key2],
                 &[key1, key2],
@@ -735,7 +731,7 @@ mod tests {
             CompiledInstruction::new(4, &(), vec![0, 2]),
             CompiledInstruction::new(4, &(), vec![0, 2]),
             CompiledInstruction::new(5, &(), vec![1, 3]),
             CompiledInstruction::new(5, &(), vec![1, 3]),
         ];
         ];
-        let tx = SanitizedTransaction::from_transaction_for_tests(
+        let tx = RuntimeTransaction::from_transaction_for_tests(
             Transaction::new_with_compiled_instructions(
             Transaction::new_with_compiled_instructions(
                 &[&signer1, &signer2],
                 &[&signer1, &signer2],
                 &[key1, key2],
                 &[key1, key2],
@@ -757,7 +753,7 @@ mod tests {
     #[test]
     #[test]
     fn test_cost_model_calculate_cost_all_default() {
     fn test_cost_model_calculate_cost_all_default() {
         let (mint_keypair, start_hash) = test_setup();
         let (mint_keypair, start_hash) = test_setup();
-        let tx = SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
+        let tx = RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
             &mint_keypair,
             &mint_keypair,
             &Keypair::new().pubkey(),
             &Keypair::new().pubkey(),
             2,
             2,
@@ -791,7 +787,7 @@ mod tests {
         let to_keypair = Keypair::new();
         let to_keypair = Keypair::new();
         let data_limit = 32 * 1024u32;
         let data_limit = 32 * 1024u32;
         let tx =
         let tx =
-            SanitizedTransaction::from_transaction_for_tests(Transaction::new_signed_with_payer(
+            RuntimeTransaction::from_transaction_for_tests(Transaction::new_signed_with_payer(
                 &[
                 &[
                     system_instruction::transfer(&mint_keypair.pubkey(), &to_keypair.pubkey(), 2),
                     system_instruction::transfer(&mint_keypair.pubkey(), &to_keypair.pubkey(), 2),
                     ComputeBudgetInstruction::set_loaded_accounts_data_size_limit(data_limit),
                     ComputeBudgetInstruction::set_loaded_accounts_data_size_limit(data_limit),
@@ -826,7 +822,7 @@ mod tests {
         let (mint_keypair, start_hash) = test_setup();
         let (mint_keypair, start_hash) = test_setup();
 
 
         let transaction =
         let transaction =
-            SanitizedTransaction::from_transaction_for_tests(Transaction::new_signed_with_payer(
+            RuntimeTransaction::from_transaction_for_tests(Transaction::new_signed_with_payer(
                 &[
                 &[
                     Instruction::new_with_bincode(Pubkey::new_unique(), &0_u8, vec![]),
                     Instruction::new_with_bincode(Pubkey::new_unique(), &0_u8, vec![]),
                     system_instruction::transfer(&mint_keypair.pubkey(), &Pubkey::new_unique(), 2),
                     system_instruction::transfer(&mint_keypair.pubkey(), &Pubkey::new_unique(), 2),
@@ -855,7 +851,7 @@ mod tests {
         let (mint_keypair, start_hash) = test_setup();
         let (mint_keypair, start_hash) = test_setup();
 
 
         let transaction =
         let transaction =
-            SanitizedTransaction::from_transaction_for_tests(Transaction::new_signed_with_payer(
+            RuntimeTransaction::from_transaction_for_tests(Transaction::new_signed_with_payer(
                 &[
                 &[
                     system_instruction::transfer(&mint_keypair.pubkey(), &Pubkey::new_unique(), 2),
                     system_instruction::transfer(&mint_keypair.pubkey(), &Pubkey::new_unique(), 2),
                     ComputeBudgetInstruction::set_compute_unit_limit(12_345),
                     ComputeBudgetInstruction::set_compute_unit_limit(12_345),

+ 23 - 18
cost-model/src/cost_tracker.rs

@@ -412,10 +412,8 @@ mod tests {
     use {
     use {
         super::*,
         super::*,
         crate::transaction_cost::{WritableKeysTransaction, *},
         crate::transaction_cost::{WritableKeysTransaction, *},
-        solana_sdk::{
-            message::TransactionSignatureDetails,
-            signature::{Keypair, Signer},
-        },
+        solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
+        solana_sdk::signature::{Keypair, Signer},
         std::cmp,
         std::cmp,
     };
     };
 
 
@@ -437,14 +435,16 @@ mod tests {
         Keypair::new()
         Keypair::new()
     }
     }
 
 
-    fn build_simple_transaction(mint_keypair: &Keypair) -> WritableKeysTransaction {
-        WritableKeysTransaction(vec![mint_keypair.pubkey()])
+    fn build_simple_transaction(
+        mint_keypair: &Keypair,
+    ) -> RuntimeTransaction<WritableKeysTransaction> {
+        RuntimeTransaction::new_for_tests(WritableKeysTransaction(vec![mint_keypair.pubkey()]))
     }
     }
 
 
     fn simple_usage_cost_details(
     fn simple_usage_cost_details(
-        transaction: &WritableKeysTransaction,
+        transaction: &RuntimeTransaction<WritableKeysTransaction>,
         programs_execution_cost: u64,
         programs_execution_cost: u64,
-    ) -> UsageCostDetails<WritableKeysTransaction> {
+    ) -> UsageCostDetails<RuntimeTransaction<WritableKeysTransaction>> {
         UsageCostDetails {
         UsageCostDetails {
             transaction,
             transaction,
             signature_cost: 0,
             signature_cost: 0,
@@ -453,12 +453,11 @@ mod tests {
             programs_execution_cost,
             programs_execution_cost,
             loaded_accounts_data_size_cost: 0,
             loaded_accounts_data_size_cost: 0,
             allocated_accounts_data_size: 0,
             allocated_accounts_data_size: 0,
-            signature_details: TransactionSignatureDetails::new(0, 0, 0),
         }
         }
     }
     }
 
 
     fn simple_transaction_cost(
     fn simple_transaction_cost(
-        transaction: &WritableKeysTransaction,
+        transaction: &RuntimeTransaction<WritableKeysTransaction>,
         programs_execution_cost: u64,
         programs_execution_cost: u64,
     ) -> TransactionCost<WritableKeysTransaction> {
     ) -> TransactionCost<WritableKeysTransaction> {
         TransactionCost::Transaction(simple_usage_cost_details(
         TransactionCost::Transaction(simple_usage_cost_details(
@@ -468,7 +467,7 @@ mod tests {
     }
     }
 
 
     fn simple_vote_transaction_cost(
     fn simple_vote_transaction_cost(
-        transaction: &WritableKeysTransaction,
+        transaction: &RuntimeTransaction<WritableKeysTransaction>,
     ) -> TransactionCost<WritableKeysTransaction> {
     ) -> TransactionCost<WritableKeysTransaction> {
         TransactionCost::SimpleVote { transaction }
         TransactionCost::SimpleVote { transaction }
     }
     }
@@ -755,7 +754,9 @@ mod tests {
         // | acct3 | $cost |
         // | acct3 | $cost |
         // and block_cost = $cost
         // and block_cost = $cost
         {
         {
-            let transaction = WritableKeysTransaction(vec![acct1, acct2, acct3]);
+            let transaction = RuntimeTransaction::new_for_tests(WritableKeysTransaction(vec![
+                acct1, acct2, acct3,
+            ]));
             let tx_cost = simple_transaction_cost(&transaction, cost);
             let tx_cost = simple_transaction_cost(&transaction, cost);
             assert!(testee.try_add(&tx_cost).is_ok());
             assert!(testee.try_add(&tx_cost).is_ok());
             let (_costliest_account, costliest_account_cost) = testee.find_costliest_account();
             let (_costliest_account, costliest_account_cost) = testee.find_costliest_account();
@@ -770,7 +771,8 @@ mod tests {
         // | acct3 | $cost |
         // | acct3 | $cost |
         // and block_cost = $cost * 2
         // and block_cost = $cost * 2
         {
         {
-            let transaction = WritableKeysTransaction(vec![acct2]);
+            let transaction =
+                RuntimeTransaction::new_for_tests(WritableKeysTransaction(vec![acct2]));
             let tx_cost = simple_transaction_cost(&transaction, cost);
             let tx_cost = simple_transaction_cost(&transaction, cost);
             assert!(testee.try_add(&tx_cost).is_ok());
             assert!(testee.try_add(&tx_cost).is_ok());
             let (costliest_account, costliest_account_cost) = testee.find_costliest_account();
             let (costliest_account, costliest_account_cost) = testee.find_costliest_account();
@@ -787,7 +789,8 @@ mod tests {
         // | acct3 | $cost |
         // | acct3 | $cost |
         // and block_cost = $cost * 2
         // and block_cost = $cost * 2
         {
         {
-            let transaction = WritableKeysTransaction(vec![acct1, acct2]);
+            let transaction =
+                RuntimeTransaction::new_for_tests(WritableKeysTransaction(vec![acct1, acct2]));
             let tx_cost = simple_transaction_cost(&transaction, cost);
             let tx_cost = simple_transaction_cost(&transaction, cost);
             assert!(testee.try_add(&tx_cost).is_err());
             assert!(testee.try_add(&tx_cost).is_err());
             let (costliest_account, costliest_account_cost) = testee.find_costliest_account();
             let (costliest_account, costliest_account_cost) = testee.find_costliest_account();
@@ -808,7 +811,8 @@ mod tests {
         let block_max = account_max * 3; // for three accts
         let block_max = account_max * 3; // for three accts
 
 
         let mut testee = CostTracker::new(account_max, block_max, block_max);
         let mut testee = CostTracker::new(account_max, block_max, block_max);
-        let transaction = WritableKeysTransaction(vec![acct1, acct2, acct3]);
+        let transaction =
+            RuntimeTransaction::new_for_tests(WritableKeysTransaction(vec![acct1, acct2, acct3]));
         let tx_cost = simple_transaction_cost(&transaction, cost);
         let tx_cost = simple_transaction_cost(&transaction, cost);
         let mut expected_block_cost = tx_cost.sum();
         let mut expected_block_cost = tx_cost.sum();
         let expected_tx_count = 1;
         let expected_tx_count = 1;
@@ -890,11 +894,11 @@ mod tests {
         let estimated_programs_execution_cost = 100;
         let estimated_programs_execution_cost = 100;
         let estimated_loaded_accounts_data_size_cost = 200;
         let estimated_loaded_accounts_data_size_cost = 200;
         let number_writeble_accounts = 3;
         let number_writeble_accounts = 3;
-        let transaction = WritableKeysTransaction(
+        let transaction = RuntimeTransaction::new_for_tests(WritableKeysTransaction(
             std::iter::repeat_with(Pubkey::new_unique)
             std::iter::repeat_with(Pubkey::new_unique)
                 .take(number_writeble_accounts)
                 .take(number_writeble_accounts)
                 .collect(),
                 .collect(),
-        );
+        ));
 
 
         let mut usage_cost =
         let mut usage_cost =
             simple_usage_cost_details(&transaction, estimated_programs_execution_cost);
             simple_usage_cost_details(&transaction, estimated_programs_execution_cost);
@@ -957,7 +961,8 @@ mod tests {
         let mut cost_tracker = CostTracker::default();
         let mut cost_tracker = CostTracker::default();
 
 
         let cost = 100u64;
         let cost = 100u64;
-        let transaction = WritableKeysTransaction(vec![Pubkey::new_unique()]);
+        let transaction =
+            RuntimeTransaction::new_for_tests(WritableKeysTransaction(vec![Pubkey::new_unique()]));
         let tx_cost = simple_transaction_cost(&transaction, cost);
         let tx_cost = simple_transaction_cost(&transaction, cost);
         cost_tracker.add_transaction_cost(&tx_cost);
         cost_tracker.add_transaction_cost(&tx_cost);
         // assert cost_tracker is reverted to default
         // assert cost_tracker is reverted to default

+ 20 - 12
cost-model/src/transaction_cost.rs

@@ -1,6 +1,9 @@
 use {
 use {
     crate::block_cost_limits,
     crate::block_cost_limits,
-    solana_sdk::{message::TransactionSignatureDetails, pubkey::Pubkey},
+    solana_runtime_transaction::{
+        runtime_transaction::RuntimeTransaction, transaction_meta::StaticMeta,
+    },
+    solana_sdk::pubkey::Pubkey,
     solana_svm_transaction::svm_message::SVMMessage,
     solana_svm_transaction::svm_message::SVMMessage,
 };
 };
 
 
@@ -16,8 +19,10 @@ const SIMPLE_VOTE_USAGE_COST: u64 = 3428;
 
 
 #[derive(Debug)]
 #[derive(Debug)]
 pub enum TransactionCost<'a, Tx: SVMMessage> {
 pub enum TransactionCost<'a, Tx: SVMMessage> {
-    SimpleVote { transaction: &'a Tx },
-    Transaction(UsageCostDetails<'a, Tx>),
+    SimpleVote {
+        transaction: &'a RuntimeTransaction<Tx>,
+    },
+    Transaction(UsageCostDetails<'a, RuntimeTransaction<Tx>>),
 }
 }
 
 
 impl<'a, Tx: SVMMessage> TransactionCost<'a, Tx> {
 impl<'a, Tx: SVMMessage> TransactionCost<'a, Tx> {
@@ -104,9 +109,10 @@ impl<'a, Tx: SVMMessage> TransactionCost<'a, Tx> {
     pub fn num_transaction_signatures(&self) -> u64 {
     pub fn num_transaction_signatures(&self) -> u64 {
         match self {
         match self {
             Self::SimpleVote { .. } => 1,
             Self::SimpleVote { .. } => 1,
-            Self::Transaction(usage_cost) => {
-                usage_cost.signature_details.num_transaction_signatures()
-            }
+            Self::Transaction(usage_cost) => usage_cost
+                .transaction
+                .signature_details()
+                .num_transaction_signatures(),
         }
         }
     }
     }
 
 
@@ -114,7 +120,8 @@ impl<'a, Tx: SVMMessage> TransactionCost<'a, Tx> {
         match self {
         match self {
             Self::SimpleVote { .. } => 0,
             Self::SimpleVote { .. } => 0,
             Self::Transaction(usage_cost) => usage_cost
             Self::Transaction(usage_cost) => usage_cost
-                .signature_details
+                .transaction
+                .signature_details()
                 .num_secp256k1_instruction_signatures(),
                 .num_secp256k1_instruction_signatures(),
         }
         }
     }
     }
@@ -123,7 +130,8 @@ impl<'a, Tx: SVMMessage> TransactionCost<'a, Tx> {
         match self {
         match self {
             Self::SimpleVote { .. } => 0,
             Self::SimpleVote { .. } => 0,
             Self::Transaction(usage_cost) => usage_cost
             Self::Transaction(usage_cost) => usage_cost
-                .signature_details
+                .transaction
+                .signature_details()
                 .num_ed25519_instruction_signatures(),
                 .num_ed25519_instruction_signatures(),
         }
         }
     }
     }
@@ -139,7 +147,6 @@ pub struct UsageCostDetails<'a, Tx: SVMMessage> {
     pub programs_execution_cost: u64,
     pub programs_execution_cost: u64,
     pub loaded_accounts_data_size_cost: u64,
     pub loaded_accounts_data_size_cost: u64,
     pub allocated_accounts_data_size: u64,
     pub allocated_accounts_data_size: u64,
-    pub signature_details: TransactionSignatureDetails,
 }
 }
 
 
 impl<'a, Tx: SVMMessage> UsageCostDetails<'a, Tx> {
 impl<'a, Tx: SVMMessage> UsageCostDetails<'a, Tx> {
@@ -225,12 +232,13 @@ mod tests {
         super::*,
         super::*,
         crate::cost_model::CostModel,
         crate::cost_model::CostModel,
         solana_feature_set::FeatureSet,
         solana_feature_set::FeatureSet,
+        solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
         solana_sdk::{
         solana_sdk::{
             hash::Hash,
             hash::Hash,
             message::SimpleAddressLoader,
             message::SimpleAddressLoader,
             reserved_account_keys::ReservedAccountKeys,
             reserved_account_keys::ReservedAccountKeys,
             signer::keypair::Keypair,
             signer::keypair::Keypair,
-            transaction::{MessageHash, SanitizedTransaction, VersionedTransaction},
+            transaction::{MessageHash, VersionedTransaction},
         },
         },
         solana_vote_program::{vote_state::TowerSync, vote_transaction},
         solana_vote_program::{vote_state::TowerSync, vote_transaction},
     };
     };
@@ -251,7 +259,7 @@ mod tests {
         );
         );
 
 
         // create a sanitized vote transaction
         // create a sanitized vote transaction
-        let vote_transaction = SanitizedTransaction::try_create(
+        let vote_transaction = RuntimeTransaction::try_create(
             VersionedTransaction::from(transaction.clone()),
             VersionedTransaction::from(transaction.clone()),
             MessageHash::Compute,
             MessageHash::Compute,
             Some(true),
             Some(true),
@@ -261,7 +269,7 @@ mod tests {
         .unwrap();
         .unwrap();
 
 
         // create a identical sanitized transaction, but identified as non-vote
         // create a identical sanitized transaction, but identified as non-vote
-        let none_vote_transaction = SanitizedTransaction::try_create(
+        let none_vote_transaction = RuntimeTransaction::try_create(
             VersionedTransaction::from(transaction),
             VersionedTransaction::from(transaction),
             MessageHash::Compute,
             MessageHash::Compute,
             Some(false),
             Some(false),

+ 1 - 0
entry/Cargo.toml

@@ -23,6 +23,7 @@ solana-merkle-tree = { workspace = true }
 solana-metrics = { workspace = true }
 solana-metrics = { workspace = true }
 solana-perf = { workspace = true }
 solana-perf = { workspace = true }
 solana-rayon-threadlimit = { workspace = true }
 solana-rayon-threadlimit = { workspace = true }
+solana-runtime-transaction = { workspace = true }
 solana-sdk = { workspace = true }
 solana-sdk = { workspace = true }
 
 
 [dev-dependencies]
 [dev-dependencies]

+ 9 - 8
entry/benches/entry_sigverify.rs

@@ -3,12 +3,13 @@ extern crate test;
 use {
 use {
     solana_entry::entry::{self, VerifyRecyclers},
     solana_entry::entry::{self, VerifyRecyclers},
     solana_perf::test_tx::test_tx,
     solana_perf::test_tx::test_tx,
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{
     solana_sdk::{
         hash::Hash,
         hash::Hash,
         reserved_account_keys::ReservedAccountKeys,
         reserved_account_keys::ReservedAccountKeys,
         transaction::{
         transaction::{
-            Result, SanitizedTransaction, SimpleAddressLoader, TransactionVerificationMode,
-            VersionedTransaction,
+            MessageHash, Result, SanitizedTransaction, SimpleAddressLoader,
+            TransactionVerificationMode, VersionedTransaction,
         },
         },
     },
     },
     std::sync::Arc,
     std::sync::Arc,
@@ -28,7 +29,7 @@ fn bench_gpusigverify(bencher: &mut Bencher) {
     let verify_transaction = {
     let verify_transaction = {
         move |versioned_tx: VersionedTransaction,
         move |versioned_tx: VersionedTransaction,
               verification_mode: TransactionVerificationMode|
               verification_mode: TransactionVerificationMode|
-              -> Result<SanitizedTransaction> {
+              -> Result<RuntimeTransaction<SanitizedTransaction>> {
             let sanitized_tx = {
             let sanitized_tx = {
                 let message_hash =
                 let message_hash =
                     if verification_mode == TransactionVerificationMode::FullVerification {
                     if verification_mode == TransactionVerificationMode::FullVerification {
@@ -37,9 +38,9 @@ fn bench_gpusigverify(bencher: &mut Bencher) {
                         versioned_tx.message.hash()
                         versioned_tx.message.hash()
                     };
                     };
 
 
-                SanitizedTransaction::try_create(
+                RuntimeTransaction::try_create(
                     versioned_tx,
                     versioned_tx,
-                    message_hash,
+                    MessageHash::Precomputed(message_hash),
                     None,
                     None,
                     SimpleAddressLoader::Disabled,
                     SimpleAddressLoader::Disabled,
                     &ReservedAccountKeys::empty_key_set(),
                     &ReservedAccountKeys::empty_key_set(),
@@ -78,12 +79,12 @@ fn bench_cpusigverify(bencher: &mut Bencher) {
         .collect::<Vec<_>>();
         .collect::<Vec<_>>();
 
 
     let verify_transaction = {
     let verify_transaction = {
-        move |versioned_tx: VersionedTransaction| -> Result<SanitizedTransaction> {
+        move |versioned_tx: VersionedTransaction| -> Result<RuntimeTransaction<SanitizedTransaction>> {
             let sanitized_tx = {
             let sanitized_tx = {
                 let message_hash = versioned_tx.verify_and_hash_message()?;
                 let message_hash = versioned_tx.verify_and_hash_message()?;
-                SanitizedTransaction::try_create(
+                RuntimeTransaction::try_create(
                     versioned_tx,
                     versioned_tx,
-                    message_hash,
+                    MessageHash::Precomputed(message_hash),
                     None,
                     None,
                     SimpleAddressLoader::Disabled,
                     SimpleAddressLoader::Disabled,
                     &ReservedAccountKeys::empty_key_set(),
                     &ReservedAccountKeys::empty_key_set(),

+ 28 - 13
entry/src/entry.rs

@@ -21,6 +21,7 @@ use {
         sigverify,
         sigverify,
     },
     },
     solana_rayon_threadlimit::get_max_thread_count,
     solana_rayon_threadlimit::get_max_thread_count,
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{
     solana_sdk::{
         hash::Hash,
         hash::Hash,
         packet::Meta,
         packet::Meta,
@@ -151,7 +152,7 @@ impl From<&Entry> for EntrySummary {
 
 
 /// Typed entry to distinguish between transaction and tick entries
 /// Typed entry to distinguish between transaction and tick entries
 pub enum EntryType {
 pub enum EntryType {
-    Transactions(Vec<SanitizedTransaction>),
+    Transactions(Vec<RuntimeTransaction<SanitizedTransaction>>),
     Tick(Hash),
     Tick(Hash),
 }
 }
 
 
@@ -394,7 +395,11 @@ impl EntryVerificationState {
 pub fn verify_transactions(
 pub fn verify_transactions(
     entries: Vec<Entry>,
     entries: Vec<Entry>,
     thread_pool: &ThreadPool,
     thread_pool: &ThreadPool,
-    verify: Arc<dyn Fn(VersionedTransaction) -> Result<SanitizedTransaction> + Send + Sync>,
+    verify: Arc<
+        dyn Fn(VersionedTransaction) -> Result<RuntimeTransaction<SanitizedTransaction>>
+            + Send
+            + Sync,
+    >,
 ) -> Result<Vec<EntryType>> {
 ) -> Result<Vec<EntryType>> {
     thread_pool.install(|| {
     thread_pool.install(|| {
         entries
         entries
@@ -422,7 +427,10 @@ pub fn start_verify_transactions(
     thread_pool: &ThreadPool,
     thread_pool: &ThreadPool,
     verify_recyclers: VerifyRecyclers,
     verify_recyclers: VerifyRecyclers,
     verify: Arc<
     verify: Arc<
-        dyn Fn(VersionedTransaction, TransactionVerificationMode) -> Result<SanitizedTransaction>
+        dyn Fn(
+                VersionedTransaction,
+                TransactionVerificationMode,
+            ) -> Result<RuntimeTransaction<SanitizedTransaction>>
             + Send
             + Send
             + Sync,
             + Sync,
     >,
     >,
@@ -460,7 +468,10 @@ fn start_verify_transactions_cpu(
     skip_verification: bool,
     skip_verification: bool,
     thread_pool: &ThreadPool,
     thread_pool: &ThreadPool,
     verify: Arc<
     verify: Arc<
-        dyn Fn(VersionedTransaction, TransactionVerificationMode) -> Result<SanitizedTransaction>
+        dyn Fn(
+                VersionedTransaction,
+                TransactionVerificationMode,
+            ) -> Result<RuntimeTransaction<SanitizedTransaction>>
             + Send
             + Send
             + Sync,
             + Sync,
     >,
     >,
@@ -490,13 +501,16 @@ fn start_verify_transactions_gpu(
     verify_recyclers: VerifyRecyclers,
     verify_recyclers: VerifyRecyclers,
     thread_pool: &ThreadPool,
     thread_pool: &ThreadPool,
     verify: Arc<
     verify: Arc<
-        dyn Fn(VersionedTransaction, TransactionVerificationMode) -> Result<SanitizedTransaction>
+        dyn Fn(
+                VersionedTransaction,
+                TransactionVerificationMode,
+            ) -> Result<RuntimeTransaction<SanitizedTransaction>>
             + Send
             + Send
             + Sync,
             + Sync,
     >,
     >,
 ) -> Result<EntrySigVerificationState> {
 ) -> Result<EntrySigVerificationState> {
     let verify_func = {
     let verify_func = {
-        move |versioned_tx: VersionedTransaction| -> Result<SanitizedTransaction> {
+        move |versioned_tx: VersionedTransaction| -> Result<RuntimeTransaction<SanitizedTransaction>> {
             verify(
             verify(
                 versioned_tx,
                 versioned_tx,
                 TransactionVerificationMode::HashAndVerifyPrecompiles,
                 TransactionVerificationMode::HashAndVerifyPrecompiles,
@@ -506,7 +520,7 @@ fn start_verify_transactions_gpu(
 
 
     let entries = verify_transactions(entries, thread_pool, Arc::new(verify_func))?;
     let entries = verify_transactions(entries, thread_pool, Arc::new(verify_func))?;
 
 
-    let transactions: Vec<&SanitizedTransaction> = entries
+    let transactions = entries
         .iter()
         .iter()
         .filter_map(|entry_type| match entry_type {
         .filter_map(|entry_type| match entry_type {
             EntryType::Tick(_) => None,
             EntryType::Tick(_) => None,
@@ -987,7 +1001,8 @@ mod tests {
             signature::{Keypair, Signer},
             signature::{Keypair, Signer},
             system_transaction,
             system_transaction,
             transaction::{
             transaction::{
-                Result, SanitizedTransaction, SimpleAddressLoader, VersionedTransaction,
+                MessageHash, Result, SanitizedTransaction, SimpleAddressLoader,
+                VersionedTransaction,
             },
             },
         },
         },
     };
     };
@@ -1011,7 +1026,7 @@ mod tests {
             dyn Fn(
             dyn Fn(
                     VersionedTransaction,
                     VersionedTransaction,
                     TransactionVerificationMode,
                     TransactionVerificationMode,
-                ) -> Result<SanitizedTransaction>
+                ) -> Result<RuntimeTransaction<SanitizedTransaction>>
                 + Send
                 + Send
                 + Sync,
                 + Sync,
         >,
         >,
@@ -1023,7 +1038,7 @@ mod tests {
             } else {
             } else {
                 TransactionVerificationMode::FullVerification
                 TransactionVerificationMode::FullVerification
             };
             };
-            move |versioned_tx: VersionedTransaction| -> Result<SanitizedTransaction> {
+            move |versioned_tx: VersionedTransaction| -> Result<RuntimeTransaction<SanitizedTransaction>> {
                 verify(versioned_tx, verification_mode)
                 verify(versioned_tx, verification_mode)
             }
             }
         };
         };
@@ -1072,7 +1087,7 @@ mod tests {
         let verify_transaction = {
         let verify_transaction = {
             move |versioned_tx: VersionedTransaction,
             move |versioned_tx: VersionedTransaction,
                   verification_mode: TransactionVerificationMode|
                   verification_mode: TransactionVerificationMode|
-                  -> Result<SanitizedTransaction> {
+                  -> Result<RuntimeTransaction<SanitizedTransaction>> {
                 let sanitized_tx = {
                 let sanitized_tx = {
                     let message_hash =
                     let message_hash =
                         if verification_mode == TransactionVerificationMode::FullVerification {
                         if verification_mode == TransactionVerificationMode::FullVerification {
@@ -1081,9 +1096,9 @@ mod tests {
                             versioned_tx.message.hash()
                             versioned_tx.message.hash()
                         };
                         };
 
 
-                    SanitizedTransaction::try_create(
+                    RuntimeTransaction::try_create(
                         versioned_tx,
                         versioned_tx,
-                        message_hash,
+                        MessageHash::Precomputed(message_hash),
                         None,
                         None,
                         SimpleAddressLoader::Disabled,
                         SimpleAddressLoader::Disabled,
                         &ReservedAccountKeys::empty_key_set(),
                         &ReservedAccountKeys::empty_key_set(),

+ 1 - 0
ledger-tool/Cargo.toml

@@ -45,6 +45,7 @@ solana-measure = { workspace = true }
 solana-program-runtime = { workspace = true }
 solana-program-runtime = { workspace = true }
 solana-rpc = { workspace = true }
 solana-rpc = { workspace = true }
 solana-runtime = { workspace = true, features = ["dev-context-only-utils"] }
 solana-runtime = { workspace = true, features = ["dev-context-only-utils"] }
+solana-runtime-transaction = { workspace = true }
 solana-sdk = { workspace = true }
 solana-sdk = { workspace = true }
 solana-stake-program = { workspace = true }
 solana-stake-program = { workspace = true }
 solana-storage-bigtable = { workspace = true }
 solana-storage-bigtable = { workspace = true }

+ 3 - 2
ledger-tool/src/main.rs

@@ -59,6 +59,7 @@ use {
             SUPPORTED_ARCHIVE_COMPRESSION,
             SUPPORTED_ARCHIVE_COMPRESSION,
         },
         },
     },
     },
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{
     solana_sdk::{
         account::{AccountSharedData, ReadableAccount, WritableAccount},
         account::{AccountSharedData, ReadableAccount, WritableAccount},
         account_utils::StateMut,
         account_utils::StateMut,
@@ -73,7 +74,7 @@ use {
         shred_version::compute_shred_version,
         shred_version::compute_shred_version,
         stake::{self, state::StakeStateV2},
         stake::{self, state::StakeStateV2},
         system_program,
         system_program,
-        transaction::{MessageHash, SanitizedTransaction, SimpleAddressLoader},
+        transaction::{MessageHash, SimpleAddressLoader},
     },
     },
     solana_stake_program::{points::PointValue, stake_state},
     solana_stake_program::{points::PointValue, stake_state},
     solana_transaction_status::parse_ui_instruction,
     solana_transaction_status::parse_ui_instruction,
@@ -472,7 +473,7 @@ fn compute_slot_cost(
             .transactions
             .transactions
             .into_iter()
             .into_iter()
             .filter_map(|transaction| {
             .filter_map(|transaction| {
-                SanitizedTransaction::try_create(
+                RuntimeTransaction::try_create(
                     transaction,
                     transaction,
                     MessageHash::Compute,
                     MessageHash::Compute,
                     None,
                     None,

+ 1 - 0
ledger/Cargo.toml

@@ -59,6 +59,7 @@ solana-perf = { workspace = true }
 solana-program-runtime = { workspace = true }
 solana-program-runtime = { workspace = true }
 solana-rayon-threadlimit = { workspace = true }
 solana-rayon-threadlimit = { workspace = true }
 solana-runtime = { workspace = true }
 solana-runtime = { workspace = true }
+solana-runtime-transaction = { workspace = true }
 solana-sdk = { workspace = true }
 solana-sdk = { workspace = true }
 solana-stake-program = { workspace = true }
 solana-stake-program = { workspace = true }
 solana-storage-bigtable = { workspace = true }
 solana-storage-bigtable = { workspace = true }

+ 3 - 2
ledger/benches/blockstore_processor.rs

@@ -17,6 +17,7 @@ use {
         prioritization_fee_cache::PrioritizationFeeCache,
         prioritization_fee_cache::PrioritizationFeeCache,
         transaction_batch::{OwnedOrBorrowed, TransactionBatch},
         transaction_batch::{OwnedOrBorrowed, TransactionBatch},
     },
     },
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{
     solana_sdk::{
         account::{Account, ReadableAccount},
         account::{Account, ReadableAccount},
         signature::Keypair,
         signature::Keypair,
@@ -60,7 +61,7 @@ fn create_funded_accounts(bank: &Bank, num: usize) -> Vec<Keypair> {
     accounts
     accounts
 }
 }
 
 
-fn create_transactions(bank: &Bank, num: usize) -> Vec<SanitizedTransaction> {
+fn create_transactions(bank: &Bank, num: usize) -> Vec<RuntimeTransaction<SanitizedTransaction>> {
     let funded_accounts = create_funded_accounts(bank, 2 * num);
     let funded_accounts = create_funded_accounts(bank, 2 * num);
     funded_accounts
     funded_accounts
         .into_par_iter()
         .into_par_iter()
@@ -70,7 +71,7 @@ fn create_transactions(bank: &Bank, num: usize) -> Vec<SanitizedTransaction> {
             let to = &chunk[1];
             let to = &chunk[1];
             system_transaction::transfer(from, &to.pubkey(), 1, bank.last_blockhash())
             system_transaction::transfer(from, &to.pubkey(), 1, bank.last_blockhash())
         })
         })
-        .map(SanitizedTransaction::from_transaction_for_tests)
+        .map(RuntimeTransaction::from_transaction_for_tests)
         .collect()
         .collect()
 }
 }
 
 

+ 22 - 14
ledger/src/blockstore_processor.rs

@@ -38,6 +38,9 @@ use {
         transaction_batch::{OwnedOrBorrowed, TransactionBatch},
         transaction_batch::{OwnedOrBorrowed, TransactionBatch},
         vote_sender_types::ReplayVoteSender,
         vote_sender_types::ReplayVoteSender,
     },
     },
+    solana_runtime_transaction::{
+        runtime_transaction::RuntimeTransaction, svm_transaction_adapter::SVMTransactionAdapter,
+    },
     solana_sdk::{
     solana_sdk::{
         clock::{Slot, MAX_PROCESSING_AGE},
         clock::{Slot, MAX_PROCESSING_AGE},
         genesis_config::GenesisConfig,
         genesis_config::GenesisConfig,
@@ -59,6 +62,7 @@ use {
     solana_transaction_status::token_balances::TransactionTokenBalancesSet,
     solana_transaction_status::token_balances::TransactionTokenBalancesSet,
     solana_vote::vote_account::VoteAccountsHashMap,
     solana_vote::vote_account::VoteAccountsHashMap,
     std::{
     std::{
+        borrow::Borrow,
         collections::{HashMap, HashSet},
         collections::{HashMap, HashSet},
         ops::{Index, Range},
         ops::{Index, Range},
         path::PathBuf,
         path::PathBuf,
@@ -85,7 +89,7 @@ pub struct TransactionBatchWithIndexes<'a, 'b, Tx: SVMMessage> {
 // us from nicely unwinding these with manual unlocking.
 // us from nicely unwinding these with manual unlocking.
 pub struct LockedTransactionsWithIndexes<Tx: SVMMessage> {
 pub struct LockedTransactionsWithIndexes<Tx: SVMMessage> {
     lock_results: Vec<Result<()>>,
     lock_results: Vec<Result<()>>,
-    transactions: Vec<Tx>,
+    transactions: Vec<RuntimeTransaction<Tx>>,
     starting_index: usize,
     starting_index: usize,
 }
 }
 
 
@@ -201,7 +205,11 @@ pub fn execute_batch(
     let first_err = get_first_error(batch, &commit_results);
     let first_err = get_first_error(batch, &commit_results);
 
 
     if let Some(transaction_status_sender) = transaction_status_sender {
     if let Some(transaction_status_sender) = transaction_status_sender {
-        let transactions = batch.sanitized_transactions().to_vec();
+        let transactions: Vec<SanitizedTransaction> = batch
+            .sanitized_transactions()
+            .iter()
+            .map(|tx| tx.as_sanitized_transaction().borrow().clone())
+            .collect();
         let post_token_balances = if record_token_balances {
         let post_token_balances = if record_token_balances {
             collect_token_balances(bank, batch, &mut mint_decimals)
             collect_token_balances(bank, batch, &mut mint_decimals)
         } else {
         } else {
@@ -232,7 +240,7 @@ pub fn execute_batch(
 fn check_block_cost_limits(
 fn check_block_cost_limits(
     bank: &Bank,
     bank: &Bank,
     commit_results: &[TransactionCommitResult],
     commit_results: &[TransactionCommitResult],
-    sanitized_transactions: &[SanitizedTransaction],
+    sanitized_transactions: &[RuntimeTransaction<SanitizedTransaction>],
 ) -> Result<()> {
 ) -> Result<()> {
     assert_eq!(sanitized_transactions.len(), commit_results.len());
     assert_eq!(sanitized_transactions.len(), commit_results.len());
 
 
@@ -447,13 +455,13 @@ fn schedule_batches_for_execution(
     first_err
     first_err
 }
 }
 
 
-fn rebatch_transactions<'a>(
+fn rebatch_transactions<'a, Tx: SVMMessage>(
     lock_results: &'a [Result<()>],
     lock_results: &'a [Result<()>],
     bank: &'a Arc<Bank>,
     bank: &'a Arc<Bank>,
-    sanitized_txs: &'a [SanitizedTransaction],
+    sanitized_txs: &'a [RuntimeTransaction<Tx>],
     range: Range<usize>,
     range: Range<usize>,
     transaction_indexes: &'a [usize],
     transaction_indexes: &'a [usize],
-) -> TransactionBatchWithIndexes<'a, 'a, SanitizedTransaction> {
+) -> TransactionBatchWithIndexes<'a, 'a, Tx> {
     let txs = &sanitized_txs[range.clone()];
     let txs = &sanitized_txs[range.clone()];
     let results = &lock_results[range.clone()];
     let results = &lock_results[range.clone()];
     let mut tx_batch =
     let mut tx_batch =
@@ -592,7 +600,7 @@ pub fn process_entries_for_tests(
     let replay_tx_thread_pool = create_thread_pool(1);
     let replay_tx_thread_pool = create_thread_pool(1);
     let verify_transaction = {
     let verify_transaction = {
         let bank = bank.clone_with_scheduler();
         let bank = bank.clone_with_scheduler();
-        move |versioned_tx: VersionedTransaction| -> Result<SanitizedTransaction> {
+        move |versioned_tx: VersionedTransaction| -> Result<RuntimeTransaction<SanitizedTransaction>> {
             bank.verify_transaction(versioned_tx, TransactionVerificationMode::FullVerification)
             bank.verify_transaction(versioned_tx, TransactionVerificationMode::FullVerification)
         }
         }
     };
     };
@@ -721,7 +729,7 @@ fn process_entries(
 fn queue_batches_with_lock_retry(
 fn queue_batches_with_lock_retry(
     bank: &Bank,
     bank: &Bank,
     starting_index: usize,
     starting_index: usize,
-    transactions: Vec<SanitizedTransaction>,
+    transactions: Vec<RuntimeTransaction<SanitizedTransaction>>,
     batches: &mut Vec<LockedTransactionsWithIndexes<SanitizedTransaction>>,
     batches: &mut Vec<LockedTransactionsWithIndexes<SanitizedTransaction>>,
     mut process_batches: impl FnMut(
     mut process_batches: impl FnMut(
         Drain<LockedTransactionsWithIndexes<SanitizedTransaction>>,
         Drain<LockedTransactionsWithIndexes<SanitizedTransaction>>,
@@ -1648,7 +1656,7 @@ fn confirm_slot_entries(
         let bank = bank.clone_with_scheduler();
         let bank = bank.clone_with_scheduler();
         move |versioned_tx: VersionedTransaction,
         move |versioned_tx: VersionedTransaction,
               verification_mode: TransactionVerificationMode|
               verification_mode: TransactionVerificationMode|
-              -> Result<SanitizedTransaction> {
+              -> Result<RuntimeTransaction<SanitizedTransaction>> {
             bank.verify_transaction(versioned_tx, verification_mode)
             bank.verify_transaction(versioned_tx, verification_mode)
         }
         }
     };
     };
@@ -4744,7 +4752,7 @@ pub mod tests {
     fn create_test_transactions(
     fn create_test_transactions(
         mint_keypair: &Keypair,
         mint_keypair: &Keypair,
         genesis_hash: &Hash,
         genesis_hash: &Hash,
-    ) -> Vec<SanitizedTransaction> {
+    ) -> Vec<RuntimeTransaction<SanitizedTransaction>> {
         let pubkey = solana_sdk::pubkey::new_rand();
         let pubkey = solana_sdk::pubkey::new_rand();
         let keypair2 = Keypair::new();
         let keypair2 = Keypair::new();
         let pubkey2 = solana_sdk::pubkey::new_rand();
         let pubkey2 = solana_sdk::pubkey::new_rand();
@@ -4752,19 +4760,19 @@ pub mod tests {
         let pubkey3 = solana_sdk::pubkey::new_rand();
         let pubkey3 = solana_sdk::pubkey::new_rand();
 
 
         vec![
         vec![
-            SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
+            RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
                 mint_keypair,
                 mint_keypair,
                 &pubkey,
                 &pubkey,
                 1,
                 1,
                 *genesis_hash,
                 *genesis_hash,
             )),
             )),
-            SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
+            RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
                 &keypair2,
                 &keypair2,
                 &pubkey2,
                 &pubkey2,
                 1,
                 1,
                 *genesis_hash,
                 *genesis_hash,
             )),
             )),
-            SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
+            RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
                 &keypair3,
                 &keypair3,
                 &pubkey3,
                 &pubkey3,
                 1,
                 1,
@@ -5138,7 +5146,7 @@ pub mod tests {
         } = create_genesis_config_with_leader(500, &dummy_leader_pubkey, 100);
         } = create_genesis_config_with_leader(500, &dummy_leader_pubkey, 100);
         let bank = Bank::new_for_tests(&genesis_config);
         let bank = Bank::new_for_tests(&genesis_config);
 
 
-        let tx = SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
+        let tx = RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
             &mint_keypair,
             &mint_keypair,
             &Pubkey::new_unique(),
             &Pubkey::new_unique(),
             1,
             1,

+ 6 - 0
programs/sbf/Cargo.lock

@@ -4883,6 +4883,7 @@ dependencies = [
  "solana-client",
  "solana-client",
  "solana-feature-set",
  "solana-feature-set",
  "solana-runtime",
  "solana-runtime",
+ "solana-runtime-transaction",
  "solana-sdk",
  "solana-sdk",
  "solana-send-transaction-service",
  "solana-send-transaction-service",
  "solana-svm",
  "solana-svm",
@@ -5320,6 +5321,7 @@ dependencies = [
  "solana-metrics",
  "solana-metrics",
  "solana-perf",
  "solana-perf",
  "solana-rayon-threadlimit",
  "solana-rayon-threadlimit",
+ "solana-runtime-transaction",
  "solana-sdk",
  "solana-sdk",
 ]
 ]
 
 
@@ -5606,6 +5608,7 @@ dependencies = [
  "solana-program-runtime",
  "solana-program-runtime",
  "solana-rayon-threadlimit",
  "solana-rayon-threadlimit",
  "solana-runtime",
  "solana-runtime",
+ "solana-runtime-transaction",
  "solana-sdk",
  "solana-sdk",
  "solana-stake-program",
  "solana-stake-program",
  "solana-storage-bigtable",
  "solana-storage-bigtable",
@@ -6132,6 +6135,7 @@ dependencies = [
  "solana-rayon-threadlimit",
  "solana-rayon-threadlimit",
  "solana-rpc-client-api",
  "solana-rpc-client-api",
  "solana-runtime",
  "solana-runtime",
+ "solana-runtime-transaction",
  "solana-sdk",
  "solana-sdk",
  "solana-send-transaction-service",
  "solana-send-transaction-service",
  "solana-stake-program",
  "solana-stake-program",
@@ -7346,6 +7350,7 @@ name = "solana-unified-scheduler-logic"
 version = "2.2.0"
 version = "2.2.0"
 dependencies = [
 dependencies = [
  "assert_matches",
  "assert_matches",
+ "solana-runtime-transaction",
  "solana-sdk",
  "solana-sdk",
  "static_assertions",
  "static_assertions",
 ]
 ]
@@ -7363,6 +7368,7 @@ dependencies = [
  "scopeguard",
  "scopeguard",
  "solana-ledger",
  "solana-ledger",
  "solana-runtime",
  "solana-runtime",
+ "solana-runtime-transaction",
  "solana-sdk",
  "solana-sdk",
  "solana-timings",
  "solana-timings",
  "solana-unified-scheduler-logic",
  "solana-unified-scheduler-logic",

+ 3 - 1
programs/sbf/Cargo.toml

@@ -120,7 +120,9 @@ solana-measure = { workspace = true }
 solana-program = { workspace = true }
 solana-program = { workspace = true }
 solana-program-runtime = { workspace = true }
 solana-program-runtime = { workspace = true }
 solana-runtime = { workspace = true, features = ["dev-context-only-utils"] }
 solana-runtime = { workspace = true, features = ["dev-context-only-utils"] }
-solana-runtime-transaction = { workspace = true }
+solana-runtime-transaction = { workspace = true, features = [
+    "dev-context-only-utils",
+] }
 solana-sbf-rust-invoke-dep = { workspace = true }
 solana-sbf-rust-invoke-dep = { workspace = true }
 solana-sbf-rust-realloc-dep = { workspace = true }
 solana-sbf-rust-realloc-dep = { workspace = true }
 solana-sbf-rust-realloc-invoke-dep = { workspace = true }
 solana-sbf-rust-realloc-invoke-dep = { workspace = true }

+ 6 - 3
programs/sbf/tests/programs.rs

@@ -33,7 +33,10 @@ use {
             load_upgradeable_program_wrapper, set_upgrade_authority, upgrade_program,
             load_upgradeable_program_wrapper, set_upgrade_authority, upgrade_program,
         },
         },
     },
     },
-    solana_runtime_transaction::instructions_processor::process_compute_budget_instructions,
+    solana_runtime_transaction::{
+        instructions_processor::process_compute_budget_instructions,
+        runtime_transaction::RuntimeTransaction,
+    },
     solana_sbf_rust_invoke_dep::*,
     solana_sbf_rust_invoke_dep::*,
     solana_sbf_rust_realloc_dep::*,
     solana_sbf_rust_realloc_dep::*,
     solana_sbf_rust_realloc_invoke_dep::*,
     solana_sbf_rust_realloc_invoke_dep::*,
@@ -59,7 +62,7 @@ use {
         system_instruction::{self, MAX_PERMITTED_DATA_LENGTH},
         system_instruction::{self, MAX_PERMITTED_DATA_LENGTH},
         system_program,
         system_program,
         sysvar::{self, clock},
         sysvar::{self, clock},
-        transaction::{SanitizedTransaction, Transaction, TransactionError, VersionedTransaction},
+        transaction::{Transaction, TransactionError, VersionedTransaction},
     },
     },
     solana_svm::{
     solana_svm::{
         transaction_commit_result::{CommittedTransaction, TransactionCommitResult},
         transaction_commit_result::{CommittedTransaction, TransactionCommitResult},
@@ -652,7 +655,7 @@ fn test_return_data_and_log_data_syscall() {
         let blockhash = bank.last_blockhash();
         let blockhash = bank.last_blockhash();
         let message = Message::new(&[instruction], Some(&mint_keypair.pubkey()));
         let message = Message::new(&[instruction], Some(&mint_keypair.pubkey()));
         let transaction = Transaction::new(&[&mint_keypair], message, blockhash);
         let transaction = Transaction::new(&[&mint_keypair], message, blockhash);
-        let sanitized_tx = SanitizedTransaction::from_transaction_for_tests(transaction);
+        let sanitized_tx = RuntimeTransaction::from_transaction_for_tests(transaction);
 
 
         let result = bank.simulate_transaction(&sanitized_tx, false);
         let result = bank.simulate_transaction(&sanitized_tx, false);
 
 

+ 3 - 2
programs/sbf/tests/simulation.rs

@@ -8,13 +8,14 @@ use {
         genesis_utils::{create_genesis_config, GenesisConfigInfo},
         genesis_utils::{create_genesis_config, GenesisConfigInfo},
         loader_utils::load_upgradeable_program_and_advance_slot,
         loader_utils::load_upgradeable_program_and_advance_slot,
     },
     },
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{
     solana_sdk::{
         instruction::{AccountMeta, Instruction},
         instruction::{AccountMeta, Instruction},
         message::Message,
         message::Message,
         pubkey::Pubkey,
         pubkey::Pubkey,
         signature::{Keypair, Signer},
         signature::{Keypair, Signer},
         sysvar::{clock, slot_history},
         sysvar::{clock, slot_history},
-        transaction::{SanitizedTransaction, Transaction},
+        transaction::Transaction,
     },
     },
 };
 };
 
 
@@ -50,7 +51,7 @@ fn test_no_panic_banks_client() {
     let blockhash = bank.last_blockhash();
     let blockhash = bank.last_blockhash();
     let message = Message::new(&[instruction], Some(&mint_keypair.pubkey()));
     let message = Message::new(&[instruction], Some(&mint_keypair.pubkey()));
     let transaction = Transaction::new(&[&mint_keypair], message, blockhash);
     let transaction = Transaction::new(&[&mint_keypair], message, blockhash);
-    let sanitized_tx = SanitizedTransaction::from_transaction_for_tests(transaction);
+    let sanitized_tx = RuntimeTransaction::from_transaction_for_tests(transaction);
     let result = bank.simulate_transaction(&sanitized_tx, false);
     let result = bank.simulate_transaction(&sanitized_tx, false);
     assert!(result.result.is_ok());
     assert!(result.result.is_ok());
 }
 }

+ 3 - 2
programs/sbf/tests/syscall_get_epoch_stake.rs

@@ -10,11 +10,12 @@ use {
         },
         },
         loader_utils::load_upgradeable_program_and_advance_slot,
         loader_utils::load_upgradeable_program_and_advance_slot,
     },
     },
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{
     solana_sdk::{
         instruction::{AccountMeta, Instruction},
         instruction::{AccountMeta, Instruction},
         message::Message,
         message::Message,
         signature::{Keypair, Signer},
         signature::{Keypair, Signer},
-        transaction::{SanitizedTransaction, Transaction},
+        transaction::Transaction,
     },
     },
     solana_vote::vote_account::VoteAccount,
     solana_vote::vote_account::VoteAccount,
     solana_vote_program::vote_state::create_account_with_authorized,
     solana_vote_program::vote_state::create_account_with_authorized,
@@ -90,7 +91,7 @@ fn test_syscall_get_epoch_stake() {
     let blockhash = bank.last_blockhash();
     let blockhash = bank.last_blockhash();
     let message = Message::new(&[instruction], Some(&mint_keypair.pubkey()));
     let message = Message::new(&[instruction], Some(&mint_keypair.pubkey()));
     let transaction = Transaction::new(&[&mint_keypair], message, blockhash);
     let transaction = Transaction::new(&[&mint_keypair], message, blockhash);
-    let sanitized_tx = SanitizedTransaction::from_transaction_for_tests(transaction);
+    let sanitized_tx = RuntimeTransaction::from_transaction_for_tests(transaction);
 
 
     let result = bank.simulate_transaction(&sanitized_tx, false);
     let result = bank.simulate_transaction(&sanitized_tx, false);
 
 

+ 3 - 2
programs/sbf/tests/sysvar.rs

@@ -8,6 +8,7 @@ use {
         genesis_utils::{create_genesis_config, GenesisConfigInfo},
         genesis_utils::{create_genesis_config, GenesisConfigInfo},
         loader_utils::load_upgradeable_program_and_advance_slot,
         loader_utils::load_upgradeable_program_and_advance_slot,
     },
     },
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{
     solana_sdk::{
         instruction::{AccountMeta, Instruction},
         instruction::{AccountMeta, Instruction},
         message::Message,
         message::Message,
@@ -18,7 +19,7 @@ use {
             clock, epoch_rewards, epoch_schedule, instructions, recent_blockhashes, rent,
             clock, epoch_rewards, epoch_schedule, instructions, recent_blockhashes, rent,
             slot_hashes, slot_history, stake_history,
             slot_hashes, slot_history, stake_history,
         },
         },
-        transaction::{SanitizedTransaction, Transaction},
+        transaction::Transaction,
     },
     },
 };
 };
 
 
@@ -92,7 +93,7 @@ fn test_sysvar_syscalls() {
         let blockhash = bank.last_blockhash();
         let blockhash = bank.last_blockhash();
         let message = Message::new(&[instruction], Some(&mint_keypair.pubkey()));
         let message = Message::new(&[instruction], Some(&mint_keypair.pubkey()));
         let transaction = Transaction::new(&[&mint_keypair], message, blockhash);
         let transaction = Transaction::new(&[&mint_keypair], message, blockhash);
-        let sanitized_tx = SanitizedTransaction::from_transaction_for_tests(transaction);
+        let sanitized_tx = RuntimeTransaction::from_transaction_for_tests(transaction);
         let result = bank.simulate_transaction(&sanitized_tx, false);
         let result = bank.simulate_transaction(&sanitized_tx, false);
         assert!(result.result.is_ok());
         assert!(result.result.is_ok());
     }
     }

+ 4 - 0
rpc/Cargo.toml

@@ -45,6 +45,7 @@ solana-poh = { workspace = true }
 solana-rayon-threadlimit = { workspace = true }
 solana-rayon-threadlimit = { workspace = true }
 solana-rpc-client-api = { workspace = true }
 solana-rpc-client-api = { workspace = true }
 solana-runtime = { workspace = true }
 solana-runtime = { workspace = true }
+solana-runtime-transaction = { workspace = true }
 solana-sdk = { workspace = true }
 solana-sdk = { workspace = true }
 solana-send-transaction-service = { workspace = true }
 solana-send-transaction-service = { workspace = true }
 solana-stake-program = { workspace = true }
 solana-stake-program = { workspace = true }
@@ -67,6 +68,9 @@ tokio-util = { workspace = true, features = ["codec", "compat"] }
 serial_test = { workspace = true }
 serial_test = { workspace = true }
 solana-net-utils = { workspace = true }
 solana-net-utils = { workspace = true }
 solana-runtime = { workspace = true, features = ["dev-context-only-utils"] }
 solana-runtime = { workspace = true, features = ["dev-context-only-utils"] }
+solana-runtime-transaction = { workspace = true, features = [
+    "dev-context-only-utils",
+] }
 solana-stake-program = { workspace = true }
 solana-stake-program = { workspace = true }
 spl-pod = { workspace = true }
 spl-pod = { workspace = true }
 symlink = { workspace = true }
 symlink = { workspace = true }

+ 4 - 3
rpc/src/rpc.rs

@@ -62,6 +62,7 @@ use {
         snapshot_utils,
         snapshot_utils,
         verify_precompiles::verify_precompiles,
         verify_precompiles::verify_precompiles,
     },
     },
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{
     solana_sdk::{
         account::{AccountSharedData, ReadableAccount},
         account::{AccountSharedData, ReadableAccount},
         clock::{Slot, UnixTimestamp, MAX_PROCESSING_AGE},
         clock::{Slot, UnixTimestamp, MAX_PROCESSING_AGE},
@@ -4212,8 +4213,8 @@ fn sanitize_transaction(
     transaction: VersionedTransaction,
     transaction: VersionedTransaction,
     address_loader: impl AddressLoader,
     address_loader: impl AddressLoader,
     reserved_account_keys: &HashSet<Pubkey>,
     reserved_account_keys: &HashSet<Pubkey>,
-) -> Result<SanitizedTransaction> {
-    SanitizedTransaction::try_create(
+) -> Result<RuntimeTransaction<SanitizedTransaction>> {
+    RuntimeTransaction::try_create(
         transaction,
         transaction,
         MessageHash::Compute,
         MessageHash::Compute,
         None,
         None,
@@ -4737,7 +4738,7 @@ pub mod tests {
             let prioritization_fee_cache = &self.meta.prioritization_fee_cache;
             let prioritization_fee_cache = &self.meta.prioritization_fee_cache;
             let transactions: Vec<_> = transactions
             let transactions: Vec<_> = transactions
                 .into_iter()
                 .into_iter()
-                .map(SanitizedTransaction::from_transaction_for_tests)
+                .map(RuntimeTransaction::from_transaction_for_tests)
                 .collect();
                 .collect();
             prioritization_fee_cache.update(&bank, transactions.iter());
             prioritization_fee_cache.update(&bank, transactions.iter());
         }
         }

+ 3 - 0
runtime-transaction/Cargo.toml

@@ -32,6 +32,9 @@ solana-program = { workspace = true }
 [package.metadata.docs.rs]
 [package.metadata.docs.rs]
 targets = ["x86_64-unknown-linux-gnu"]
 targets = ["x86_64-unknown-linux-gnu"]
 
 
+[features]
+dev-context-only-utils = []
+
 [[bench]]
 [[bench]]
 name = "process_compute_budget_instructions"
 name = "process_compute_budget_instructions"
 harness = false
 harness = false

+ 1 - 0
runtime-transaction/src/compute_budget_instruction_details.rs

@@ -14,6 +14,7 @@ use {
 };
 };
 
 
 #[cfg_attr(test, derive(Eq, PartialEq))]
 #[cfg_attr(test, derive(Eq, PartialEq))]
+#[cfg_attr(feature = "dev-context-only-utils", derive(Clone))]
 #[derive(Default, Debug)]
 #[derive(Default, Debug)]
 pub(crate) struct ComputeBudgetInstructionDetails {
 pub(crate) struct ComputeBudgetInstructionDetails {
     // compute-budget instruction details:
     // compute-budget instruction details:

+ 1 - 0
runtime-transaction/src/lib.rs

@@ -6,4 +6,5 @@ mod compute_budget_program_id_filter;
 pub mod instructions_processor;
 pub mod instructions_processor;
 pub mod runtime_transaction;
 pub mod runtime_transaction;
 pub mod signature_details;
 pub mod signature_details;
+pub mod svm_transaction_adapter;
 pub mod transaction_meta;
 pub mod transaction_meta;

+ 77 - 10
runtime-transaction/src/runtime_transaction.rs

@@ -24,7 +24,10 @@ use {
         pubkey::Pubkey,
         pubkey::Pubkey,
         signature::Signature,
         signature::Signature,
         simple_vote_transaction_checker::is_simple_vote_transaction,
         simple_vote_transaction_checker::is_simple_vote_transaction,
-        transaction::{Result, SanitizedTransaction, SanitizedVersionedTransaction},
+        transaction::{
+            MessageHash, Result, SanitizedTransaction, SanitizedVersionedTransaction,
+            VersionedTransaction,
+        },
     },
     },
     solana_svm_transaction::{
     solana_svm_transaction::{
         instruction::SVMInstruction, message_address_table_lookup::SVMMessageAddressTableLookup,
         instruction::SVMInstruction, message_address_table_lookup::SVMMessageAddressTableLookup,
@@ -33,6 +36,7 @@ use {
     std::collections::HashSet,
     std::collections::HashSet,
 };
 };
 
 
+#[cfg_attr(feature = "dev-context-only-utils", derive(Clone))]
 #[derive(Debug)]
 #[derive(Debug)]
 pub struct RuntimeTransaction<T> {
 pub struct RuntimeTransaction<T> {
     transaction: T,
     transaction: T,
@@ -71,13 +75,15 @@ impl<T> Deref for RuntimeTransaction<T> {
 impl RuntimeTransaction<SanitizedVersionedTransaction> {
 impl RuntimeTransaction<SanitizedVersionedTransaction> {
     pub fn try_from(
     pub fn try_from(
         sanitized_versioned_tx: SanitizedVersionedTransaction,
         sanitized_versioned_tx: SanitizedVersionedTransaction,
-        message_hash: Option<Hash>,
+        message_hash: MessageHash,
         is_simple_vote_tx: Option<bool>,
         is_simple_vote_tx: Option<bool>,
     ) -> Result<Self> {
     ) -> Result<Self> {
+        let message_hash = match message_hash {
+            MessageHash::Precomputed(hash) => hash,
+            MessageHash::Compute => sanitized_versioned_tx.get_message().message.hash(),
+        };
         let is_simple_vote_tx = is_simple_vote_tx
         let is_simple_vote_tx = is_simple_vote_tx
             .unwrap_or_else(|| is_simple_vote_transaction(&sanitized_versioned_tx));
             .unwrap_or_else(|| is_simple_vote_transaction(&sanitized_versioned_tx));
-        let message_hash =
-            message_hash.unwrap_or_else(|| sanitized_versioned_tx.get_message().message.hash());
 
 
         let precompile_signature_details = get_precompile_signature_details(
         let precompile_signature_details = get_precompile_signature_details(
             sanitized_versioned_tx
             sanitized_versioned_tx
@@ -116,6 +122,31 @@ impl RuntimeTransaction<SanitizedVersionedTransaction> {
 }
 }
 
 
 impl RuntimeTransaction<SanitizedTransaction> {
 impl RuntimeTransaction<SanitizedTransaction> {
+    /// Create a new `RuntimeTransaction<SanitizedTransaction>` from an
+    /// unsanitized `VersionedTransaction`.
+    pub fn try_create(
+        tx: VersionedTransaction,
+        message_hash: MessageHash,
+        is_simple_vote_tx: Option<bool>,
+        address_loader: impl AddressLoader,
+        reserved_account_keys: &HashSet<Pubkey>,
+    ) -> Result<Self> {
+        let statically_loaded_runtime_tx =
+            RuntimeTransaction::<SanitizedVersionedTransaction>::try_from(
+                SanitizedVersionedTransaction::try_from(tx)?,
+                message_hash,
+                is_simple_vote_tx,
+            )?;
+        Self::try_from(
+            statically_loaded_runtime_tx,
+            address_loader,
+            reserved_account_keys,
+        )
+    }
+
+    /// Create a new `RuntimeTransaction<SanitizedTransaction>` from a
+    /// `RuntimeTransaction<SanitizedVersionedTransaction>` that already has
+    /// static metadata loaded.
     pub fn try_from(
     pub fn try_from(
         statically_loaded_runtime_tx: RuntimeTransaction<SanitizedVersionedTransaction>,
         statically_loaded_runtime_tx: RuntimeTransaction<SanitizedVersionedTransaction>,
         address_loader: impl AddressLoader,
         address_loader: impl AddressLoader,
@@ -145,6 +176,38 @@ impl RuntimeTransaction<SanitizedTransaction> {
     }
     }
 }
 }
 
 
+#[cfg(feature = "dev-context-only-utils")]
+impl RuntimeTransaction<SanitizedTransaction> {
+    pub fn from_transaction_for_tests(transaction: solana_sdk::transaction::Transaction) -> Self {
+        let versioned_transaction = VersionedTransaction::from(transaction);
+        Self::try_create(
+            versioned_transaction,
+            MessageHash::Compute,
+            None,
+            solana_sdk::message::SimpleAddressLoader::Disabled,
+            &HashSet::new(),
+        )
+        .expect("failed to create RuntimeTransaction from Transaction")
+    }
+}
+
+#[cfg(feature = "dev-context-only-utils")]
+impl<Tx: SVMMessage> RuntimeTransaction<Tx> {
+    /// Create simply wrapped transaction with a `TransactionMeta` for testing.
+    /// The `TransactionMeta` is default initialized.
+    pub fn new_for_tests(transaction: Tx) -> Self {
+        Self {
+            transaction,
+            meta: TransactionMeta {
+                message_hash: Hash::default(),
+                is_simple_vote_transaction: false,
+                signature_details: TransactionSignatureDetails::new(0, 0, 0),
+                compute_budget_instruction_details: ComputeBudgetInstructionDetails::default(),
+            },
+        }
+    }
+}
+
 impl<T: SVMMessage> SVMMessage for RuntimeTransaction<T> {
 impl<T: SVMMessage> SVMMessage for RuntimeTransaction<T> {
     // override to access from the cached meta instead of re-calculating
     // override to access from the cached meta instead of re-calculating
     fn num_total_signatures(&self) -> u64 {
     fn num_total_signatures(&self) -> u64 {
@@ -302,10 +365,14 @@ mod tests {
             svt: SanitizedVersionedTransaction,
             svt: SanitizedVersionedTransaction,
             is_simple_vote: Option<bool>,
             is_simple_vote: Option<bool>,
         ) -> bool {
         ) -> bool {
-            RuntimeTransaction::<SanitizedVersionedTransaction>::try_from(svt, None, is_simple_vote)
-                .unwrap()
-                .meta
-                .is_simple_vote_transaction
+            RuntimeTransaction::<SanitizedVersionedTransaction>::try_from(
+                svt,
+                MessageHash::Compute,
+                is_simple_vote,
+            )
+            .unwrap()
+            .meta
+            .is_simple_vote_transaction
         }
         }
 
 
         assert!(!get_is_simple_vote(
         assert!(!get_is_simple_vote(
@@ -336,7 +403,7 @@ mod tests {
         let statically_loaded_transaction =
         let statically_loaded_transaction =
             RuntimeTransaction::<SanitizedVersionedTransaction>::try_from(
             RuntimeTransaction::<SanitizedVersionedTransaction>::try_from(
                 non_vote_sanitized_versioned_transaction(),
                 non_vote_sanitized_versioned_transaction(),
-                Some(hash),
+                MessageHash::Precomputed(hash),
                 None,
                 None,
             )
             )
             .unwrap();
             .unwrap();
@@ -371,7 +438,7 @@ mod tests {
                     .add_compute_unit_price(compute_unit_price)
                     .add_compute_unit_price(compute_unit_price)
                     .add_loaded_accounts_bytes(loaded_accounts_bytes)
                     .add_loaded_accounts_bytes(loaded_accounts_bytes)
                     .to_sanitized_versioned_transaction(),
                     .to_sanitized_versioned_transaction(),
-                Some(hash),
+                MessageHash::Precomputed(hash),
                 None,
                 None,
             )
             )
             .unwrap();
             .unwrap();

+ 25 - 0
runtime-transaction/src/svm_transaction_adapter.rs

@@ -0,0 +1,25 @@
+use {
+    core::borrow::Borrow,
+    solana_sdk::transaction::{SanitizedTransaction, VersionedTransaction},
+    solana_svm_transaction::svm_transaction::SVMTransaction,
+};
+
+/// Adapter trait to allow for conversion to legacy transaction types
+/// that are required by some outside interfaces.
+/// Eventually this trait should go away, but for now it is necessary.
+pub trait SVMTransactionAdapter: SVMTransaction {
+    fn as_sanitized_transaction(&self) -> impl Borrow<SanitizedTransaction>;
+    fn to_versioned_transaction(&self) -> VersionedTransaction;
+}
+
+impl SVMTransactionAdapter for SanitizedTransaction {
+    #[inline]
+    fn as_sanitized_transaction(&self) -> impl Borrow<SanitizedTransaction> {
+        self
+    }
+
+    #[inline]
+    fn to_versioned_transaction(&self) -> VersionedTransaction {
+        self.to_versioned_transaction()
+    }
+}

+ 1 - 0
runtime-transaction/src/transaction_meta.rs

@@ -36,6 +36,7 @@ pub trait StaticMeta {
 /// on-chain ALT, examples are: transaction usage costs, nonce account.
 /// on-chain ALT, examples are: transaction usage costs, nonce account.
 pub trait DynamicMeta: StaticMeta {}
 pub trait DynamicMeta: StaticMeta {}
 
 
+#[cfg_attr(feature = "dev-context-only-utils", derive(Clone))]
 #[derive(Debug)]
 #[derive(Debug)]
 pub struct TransactionMeta {
 pub struct TransactionMeta {
     pub(crate) message_hash: Hash,
     pub(crate) message_hash: Hash,

+ 7 - 1
runtime/Cargo.toml

@@ -114,6 +114,9 @@ solana-accounts-db = { workspace = true, features = ["dev-context-only-utils"] }
 solana-logger = { workspace = true }
 solana-logger = { workspace = true }
 # See order-crates-for-publishing.py for using this unusual `path = "."`
 # See order-crates-for-publishing.py for using this unusual `path = "."`
 solana-runtime = { path = ".", features = ["dev-context-only-utils"] }
 solana-runtime = { path = ".", features = ["dev-context-only-utils"] }
+solana-runtime-transaction = { workspace = true, features = [
+    "dev-context-only-utils",
+] }
 solana-sdk = { workspace = true, features = ["dev-context-only-utils"] }
 solana-sdk = { workspace = true, features = ["dev-context-only-utils"] }
 solana-svm = { workspace = true, features = ["dev-context-only-utils"] }
 solana-svm = { workspace = true, features = ["dev-context-only-utils"] }
 static_assertions = { workspace = true }
 static_assertions = { workspace = true }
@@ -123,7 +126,10 @@ test-case = { workspace = true }
 targets = ["x86_64-unknown-linux-gnu"]
 targets = ["x86_64-unknown-linux-gnu"]
 
 
 [features]
 [features]
-dev-context-only-utils = ["solana-svm/dev-context-only-utils"]
+dev-context-only-utils = [
+    "solana-svm/dev-context-only-utils",
+    "solana-runtime-transaction/dev-context-only-utils",
+]
 frozen-abi = [
 frozen-abi = [
     "dep:solana-frozen-abi",
     "dep:solana-frozen-abi",
     "dep:solana-frozen-abi-macro",
     "dep:solana-frozen-abi-macro",

+ 3 - 2
runtime/benches/prioritization_fee_cache.rs

@@ -9,6 +9,7 @@ use {
         genesis_utils::{create_genesis_config, GenesisConfigInfo},
         genesis_utils::{create_genesis_config, GenesisConfigInfo},
         prioritization_fee_cache::*,
         prioritization_fee_cache::*,
     },
     },
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{
     solana_sdk::{
         compute_budget::ComputeBudgetInstruction,
         compute_budget::ComputeBudgetInstruction,
         message::Message,
         message::Message,
@@ -25,7 +26,7 @@ fn build_sanitized_transaction(
     compute_unit_price: u64,
     compute_unit_price: u64,
     signer_account: &Pubkey,
     signer_account: &Pubkey,
     write_account: &Pubkey,
     write_account: &Pubkey,
-) -> SanitizedTransaction {
+) -> RuntimeTransaction<SanitizedTransaction> {
     let transfer_lamports = 1;
     let transfer_lamports = 1;
     let transaction = Transaction::new_unsigned(Message::new(
     let transaction = Transaction::new_unsigned(Message::new(
         &[
         &[
@@ -36,7 +37,7 @@ fn build_sanitized_transaction(
         Some(signer_account),
         Some(signer_account),
     ));
     ));
 
 
-    SanitizedTransaction::from_transaction_for_tests(transaction)
+    RuntimeTransaction::from_transaction_for_tests(transaction)
 }
 }
 
 
 #[bench]
 #[bench]

+ 39 - 30
runtime/src/bank.rs

@@ -105,7 +105,11 @@ use {
     solana_program_runtime::{
     solana_program_runtime::{
         invoke_context::BuiltinFunctionWithContext, loaded_programs::ProgramCacheEntry,
         invoke_context::BuiltinFunctionWithContext, loaded_programs::ProgramCacheEntry,
     },
     },
-    solana_runtime_transaction::instructions_processor::process_compute_budget_instructions,
+    solana_runtime_transaction::{
+        instructions_processor::process_compute_budget_instructions,
+        runtime_transaction::RuntimeTransaction, svm_transaction_adapter::SVMTransactionAdapter,
+        transaction_meta::StaticMeta,
+    },
     solana_sdk::{
     solana_sdk::{
         account::{
         account::{
             create_account_shared_data_with_fields as create_account, from_account, Account,
             create_account_shared_data_with_fields as create_account, from_account, Account,
@@ -175,7 +179,7 @@ use {
             TransactionProcessingConfig, TransactionProcessingEnvironment,
             TransactionProcessingConfig, TransactionProcessingEnvironment,
         },
         },
     },
     },
-    solana_svm_transaction::svm_message::SVMMessage,
+    solana_svm_transaction::{svm_message::SVMMessage, svm_transaction::SVMTransaction},
     solana_timings::{ExecuteTimingType, ExecuteTimings},
     solana_timings::{ExecuteTimingType, ExecuteTimings},
     solana_vote::vote_account::{VoteAccount, VoteAccountsHashMap},
     solana_vote::vote_account::{VoteAccount, VoteAccountsHashMap},
     solana_vote_program::vote_state::VoteState,
     solana_vote_program::vote_state::VoteState,
@@ -3290,7 +3294,7 @@ impl Bank {
 
 
     fn update_transaction_statuses(
     fn update_transaction_statuses(
         &self,
         &self,
-        sanitized_txs: &[SanitizedTransaction],
+        sanitized_txs: &[RuntimeTransaction<SanitizedTransaction>],
         processing_results: &[TransactionProcessingResult],
         processing_results: &[TransactionProcessingResult],
     ) {
     ) {
         let mut status_cache = self.status_cache.write().unwrap();
         let mut status_cache = self.status_cache.write().unwrap();
@@ -3300,7 +3304,7 @@ impl Bank {
                 // Add the message hash to the status cache to ensure that this message
                 // Add the message hash to the status cache to ensure that this message
                 // won't be processed again with a different signature.
                 // won't be processed again with a different signature.
                 status_cache.insert(
                 status_cache.insert(
-                    tx.message().recent_blockhash(),
+                    tx.recent_blockhash(),
                     tx.message_hash(),
                     tx.message_hash(),
                     self.slot(),
                     self.slot(),
                     processed_tx.status(),
                     processed_tx.status(),
@@ -3309,7 +3313,7 @@ impl Bank {
                 // can be queried by transaction signature over RPC. In the future, this should
                 // can be queried by transaction signature over RPC. In the future, this should
                 // only be added for API nodes because voting validators don't need to do this.
                 // only be added for API nodes because voting validators don't need to do this.
                 status_cache.insert(
                 status_cache.insert(
-                    tx.message().recent_blockhash(),
+                    tx.recent_blockhash(),
                     tx.signature(),
                     tx.signature(),
                     self.slot(),
                     self.slot(),
                     processed_tx.status(),
                     processed_tx.status(),
@@ -3452,7 +3456,7 @@ impl Bank {
         let sanitized_txs = txs
         let sanitized_txs = txs
             .into_iter()
             .into_iter()
             .map(|tx| {
             .map(|tx| {
-                SanitizedTransaction::try_create(
+                RuntimeTransaction::try_create(
                     tx,
                     tx,
                     MessageHash::Compute,
                     MessageHash::Compute,
                     None,
                     None,
@@ -3474,7 +3478,7 @@ impl Bank {
     }
     }
 
 
     /// Attempt to take locks on the accounts in a transaction batch
     /// Attempt to take locks on the accounts in a transaction batch
-    pub fn try_lock_accounts(&self, txs: &[SanitizedTransaction]) -> Vec<Result<()>> {
+    pub fn try_lock_accounts(&self, txs: &[impl SVMMessage]) -> Vec<Result<()>> {
         let tx_account_lock_limit = self.get_transaction_account_lock_limit();
         let tx_account_lock_limit = self.get_transaction_account_lock_limit();
         self.rc
         self.rc
             .accounts
             .accounts
@@ -3482,10 +3486,10 @@ impl Bank {
     }
     }
 
 
     /// Prepare a locked transaction batch from a list of sanitized transactions.
     /// Prepare a locked transaction batch from a list of sanitized transactions.
-    pub fn prepare_sanitized_batch<'a, 'b>(
+    pub fn prepare_sanitized_batch<'a, 'b, Tx: SVMMessage>(
         &'a self,
         &'a self,
-        txs: &'b [SanitizedTransaction],
-    ) -> TransactionBatch<'a, 'b, SanitizedTransaction> {
+        txs: &'b [RuntimeTransaction<Tx>],
+    ) -> TransactionBatch<'a, 'b, Tx> {
         TransactionBatch::new(
         TransactionBatch::new(
             self.try_lock_accounts(txs),
             self.try_lock_accounts(txs),
             self,
             self,
@@ -3495,11 +3499,11 @@ impl Bank {
 
 
     /// Prepare a locked transaction batch from a list of sanitized transactions, and their cost
     /// Prepare a locked transaction batch from a list of sanitized transactions, and their cost
     /// limited packing status
     /// limited packing status
-    pub fn prepare_sanitized_batch_with_results<'a, 'b>(
+    pub fn prepare_sanitized_batch_with_results<'a, 'b, Tx: SVMMessage>(
         &'a self,
         &'a self,
-        transactions: &'b [SanitizedTransaction],
+        transactions: &'b [RuntimeTransaction<Tx>],
         transaction_results: impl Iterator<Item = Result<()>>,
         transaction_results: impl Iterator<Item = Result<()>>,
-    ) -> TransactionBatch<'a, 'b, SanitizedTransaction> {
+    ) -> TransactionBatch<'a, 'b, Tx> {
         // this lock_results could be: Ok, AccountInUse, WouldExceedBlockMaxLimit or WouldExceedAccountMaxLimit
         // this lock_results could be: Ok, AccountInUse, WouldExceedBlockMaxLimit or WouldExceedAccountMaxLimit
         let tx_account_lock_limit = self.get_transaction_account_lock_limit();
         let tx_account_lock_limit = self.get_transaction_account_lock_limit();
         let lock_results = self.rc.accounts.lock_accounts_with_results(
         let lock_results = self.rc.accounts.lock_accounts_with_results(
@@ -3511,13 +3515,12 @@ impl Bank {
     }
     }
 
 
     /// Prepare a transaction batch from a single transaction without locking accounts
     /// Prepare a transaction batch from a single transaction without locking accounts
-    pub fn prepare_unlocked_batch_from_single_tx<'a>(
+    pub fn prepare_unlocked_batch_from_single_tx<'a, Tx: SVMMessage>(
         &'a self,
         &'a self,
-        transaction: &'a SanitizedTransaction,
-    ) -> TransactionBatch<'_, '_, SanitizedTransaction> {
+        transaction: &'a RuntimeTransaction<Tx>,
+    ) -> TransactionBatch<'_, '_, Tx> {
         let tx_account_lock_limit = self.get_transaction_account_lock_limit();
         let tx_account_lock_limit = self.get_transaction_account_lock_limit();
-        let lock_result =
-            validate_account_locks(transaction.message().account_keys(), tx_account_lock_limit);
+        let lock_result = validate_account_locks(transaction.account_keys(), tx_account_lock_limit);
         let mut batch = TransactionBatch::new(
         let mut batch = TransactionBatch::new(
             vec![lock_result],
             vec![lock_result],
             self,
             self,
@@ -3530,7 +3533,7 @@ impl Bank {
     /// Run transactions against a frozen bank without committing the results
     /// Run transactions against a frozen bank without committing the results
     pub fn simulate_transaction(
     pub fn simulate_transaction(
         &self,
         &self,
-        transaction: &SanitizedTransaction,
+        transaction: &RuntimeTransaction<SanitizedTransaction>,
         enable_cpi_recording: bool,
         enable_cpi_recording: bool,
     ) -> TransactionSimulationResult {
     ) -> TransactionSimulationResult {
         assert!(self.is_frozen(), "simulation bank must be frozen");
         assert!(self.is_frozen(), "simulation bank must be frozen");
@@ -3542,7 +3545,7 @@ impl Bank {
     /// is frozen, enabling use in single-Bank test frameworks
     /// is frozen, enabling use in single-Bank test frameworks
     pub fn simulate_transaction_unchecked(
     pub fn simulate_transaction_unchecked(
         &self,
         &self,
-        transaction: &SanitizedTransaction,
+        transaction: &RuntimeTransaction<SanitizedTransaction>,
         enable_cpi_recording: bool,
         enable_cpi_recording: bool,
     ) -> TransactionSimulationResult {
     ) -> TransactionSimulationResult {
         let account_keys = transaction.message().account_keys();
         let account_keys = transaction.message().account_keys();
@@ -3790,7 +3793,7 @@ impl Bank {
 
 
     fn collect_logs(
     fn collect_logs(
         &self,
         &self,
-        transactions: &[SanitizedTransaction],
+        transactions: &[RuntimeTransaction<SanitizedTransaction>],
         processing_results: &[TransactionProcessingResult],
         processing_results: &[TransactionProcessingResult],
     ) {
     ) {
         let transaction_log_collector_config =
         let transaction_log_collector_config =
@@ -3982,7 +3985,7 @@ impl Bank {
 
 
     pub fn commit_transactions(
     pub fn commit_transactions(
         &self,
         &self,
-        sanitized_txs: &[SanitizedTransaction],
+        sanitized_txs: &[RuntimeTransaction<SanitizedTransaction>],
         processing_results: Vec<TransactionProcessingResult>,
         processing_results: Vec<TransactionProcessingResult>,
         processed_counts: &ProcessedTransactionCounts,
         processed_counts: &ProcessedTransactionCounts,
         timings: &mut ExecuteTimings,
         timings: &mut ExecuteTimings,
@@ -4025,7 +4028,12 @@ impl Bank {
                 .accounts()
                 .accounts()
                 .accounts_db
                 .accounts_db
                 .has_accounts_update_notifier()
                 .has_accounts_update_notifier()
-                .then(|| sanitized_txs.iter().collect::<Vec<_>>());
+                .then(|| {
+                    sanitized_txs
+                        .iter()
+                        .map(|tx| tx.as_sanitized_transaction())
+                        .collect::<Vec<_>>()
+                });
 
 
             let (accounts_to_store, transactions) = collect_accounts_to_store(
             let (accounts_to_store, transactions) = collect_accounts_to_store(
                 sanitized_txs,
                 sanitized_txs,
@@ -5894,7 +5902,7 @@ impl Bank {
         &self,
         &self,
         tx: VersionedTransaction,
         tx: VersionedTransaction,
         verification_mode: TransactionVerificationMode,
         verification_mode: TransactionVerificationMode,
-    ) -> Result<SanitizedTransaction> {
+    ) -> Result<RuntimeTransaction<SanitizedTransaction>> {
         let sanitized_tx = {
         let sanitized_tx = {
             let size =
             let size =
                 bincode::serialized_size(&tx).map_err(|_| TransactionError::SanitizeFailure)?;
                 bincode::serialized_size(&tx).map_err(|_| TransactionError::SanitizeFailure)?;
@@ -5908,9 +5916,9 @@ impl Bank {
                 tx.message.hash()
                 tx.message.hash()
             };
             };
 
 
-            SanitizedTransaction::try_create(
+            RuntimeTransaction::try_create(
                 tx,
                 tx,
-                message_hash,
+                MessageHash::Precomputed(message_hash),
                 None,
                 None,
                 self,
                 self,
                 self.get_reserved_account_keys(),
                 self.get_reserved_account_keys(),
@@ -5933,7 +5941,7 @@ impl Bank {
     pub fn fully_verify_transaction(
     pub fn fully_verify_transaction(
         &self,
         &self,
         tx: VersionedTransaction,
         tx: VersionedTransaction,
-    ) -> Result<SanitizedTransaction> {
+    ) -> Result<RuntimeTransaction<SanitizedTransaction>> {
         self.verify_transaction(tx, TransactionVerificationMode::FullVerification)
         self.verify_transaction(tx, TransactionVerificationMode::FullVerification)
     }
     }
 
 
@@ -6287,7 +6295,7 @@ impl Bank {
     /// a bank-level cache of vote accounts and stake delegation info
     /// a bank-level cache of vote accounts and stake delegation info
     fn update_stakes_cache(
     fn update_stakes_cache(
         &self,
         &self,
-        txs: &[SanitizedTransaction],
+        txs: &[RuntimeTransaction<SanitizedTransaction>],
         processing_results: &[TransactionProcessingResult],
         processing_results: &[TransactionProcessingResult],
     ) {
     ) {
         debug_assert_eq!(txs.len(), processing_results.len());
         debug_assert_eq!(txs.len(), processing_results.len());
@@ -6306,7 +6314,7 @@ impl Bank {
             })
             })
             .filter(|(_, executed_tx)| executed_tx.was_successful())
             .filter(|(_, executed_tx)| executed_tx.was_successful())
             .flat_map(|(tx, executed_tx)| {
             .flat_map(|(tx, executed_tx)| {
-                let num_account_keys = tx.message().account_keys().len();
+                let num_account_keys = tx.account_keys().len();
                 let loaded_tx = &executed_tx.loaded_transaction;
                 let loaded_tx = &executed_tx.loaded_transaction;
                 loaded_tx.accounts.iter().take(num_account_keys)
                 loaded_tx.accounts.iter().take(num_account_keys)
             })
             })
@@ -7119,6 +7127,7 @@ impl Bank {
     }
     }
 
 
     /// Prepare a transaction batch from a list of legacy transactions. Used for tests only.
     /// Prepare a transaction batch from a list of legacy transactions. Used for tests only.
+    #[cfg(feature = "dev-context-only-utils")]
     pub fn prepare_batch_for_tests(
     pub fn prepare_batch_for_tests(
         &self,
         &self,
         txs: Vec<Transaction>,
         txs: Vec<Transaction>,
@@ -7126,7 +7135,7 @@ impl Bank {
         let transaction_account_lock_limit = self.get_transaction_account_lock_limit();
         let transaction_account_lock_limit = self.get_transaction_account_lock_limit();
         let sanitized_txs = txs
         let sanitized_txs = txs
             .into_iter()
             .into_iter()
-            .map(SanitizedTransaction::from_transaction_for_tests)
+            .map(RuntimeTransaction::from_transaction_for_tests)
             .collect::<Vec<_>>();
             .collect::<Vec<_>>();
         let lock_results = self
         let lock_results = self
             .rc
             .rc

+ 5 - 4
runtime/src/bank/check_transactions.rs

@@ -2,6 +2,7 @@ use {
     super::{Bank, BankStatusCache},
     super::{Bank, BankStatusCache},
     solana_accounts_db::blockhash_queue::BlockhashQueue,
     solana_accounts_db::blockhash_queue::BlockhashQueue,
     solana_perf::perf_libs,
     solana_perf::perf_libs,
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{
     solana_sdk::{
         account::AccountSharedData,
         account::AccountSharedData,
         account_utils::StateMut,
         account_utils::StateMut,
@@ -31,7 +32,7 @@ impl Bank {
     /// Checks a batch of sanitized transactions again bank for age and status
     /// Checks a batch of sanitized transactions again bank for age and status
     pub fn check_transactions_with_forwarding_delay(
     pub fn check_transactions_with_forwarding_delay(
         &self,
         &self,
-        transactions: &[SanitizedTransaction],
+        transactions: &[RuntimeTransaction<SanitizedTransaction>],
         filter: &[TransactionResult<()>],
         filter: &[TransactionResult<()>],
         forward_transactions_to_leader_at_slot_offset: u64,
         forward_transactions_to_leader_at_slot_offset: u64,
     ) -> Vec<TransactionCheckResult> {
     ) -> Vec<TransactionCheckResult> {
@@ -60,7 +61,7 @@ impl Bank {
 
 
     pub fn check_transactions(
     pub fn check_transactions(
         &self,
         &self,
-        sanitized_txs: &[impl core::borrow::Borrow<SanitizedTransaction>],
+        sanitized_txs: &[impl core::borrow::Borrow<RuntimeTransaction<SanitizedTransaction>>],
         lock_results: &[TransactionResult<()>],
         lock_results: &[TransactionResult<()>],
         max_age: usize,
         max_age: usize,
         error_counters: &mut TransactionErrorMetrics,
         error_counters: &mut TransactionErrorMetrics,
@@ -71,7 +72,7 @@ impl Bank {
 
 
     fn check_age(
     fn check_age(
         &self,
         &self,
-        sanitized_txs: &[impl core::borrow::Borrow<SanitizedTransaction>],
+        sanitized_txs: &[impl core::borrow::Borrow<RuntimeTransaction<SanitizedTransaction>>],
         lock_results: &[TransactionResult<()>],
         lock_results: &[TransactionResult<()>],
         max_age: usize,
         max_age: usize,
         error_counters: &mut TransactionErrorMetrics,
         error_counters: &mut TransactionErrorMetrics,
@@ -184,7 +185,7 @@ impl Bank {
 
 
     fn check_status_cache(
     fn check_status_cache(
         &self,
         &self,
-        sanitized_txs: &[impl core::borrow::Borrow<SanitizedTransaction>],
+        sanitized_txs: &[impl core::borrow::Borrow<RuntimeTransaction<SanitizedTransaction>>],
         lock_results: Vec<TransactionCheckResult>,
         lock_results: Vec<TransactionCheckResult>,
         error_counters: &mut TransactionErrorMetrics,
         error_counters: &mut TransactionErrorMetrics,
     ) -> Vec<TransactionCheckResult> {
     ) -> Vec<TransactionCheckResult> {

+ 8 - 8
runtime/src/bank/tests.rs

@@ -10040,17 +10040,17 @@ fn test_verify_and_hash_transaction_sig_len() {
     // Too few signatures: Sanitization failure
     // Too few signatures: Sanitization failure
     {
     {
         let tx = make_transaction(TestCase::RemoveSignature);
         let tx = make_transaction(TestCase::RemoveSignature);
-        assert_eq!(
+        assert_matches!(
             bank.verify_transaction(tx.into(), TransactionVerificationMode::FullVerification),
             bank.verify_transaction(tx.into(), TransactionVerificationMode::FullVerification),
-            Err(TransactionError::SanitizeFailure),
+            Err(TransactionError::SanitizeFailure)
         );
         );
     }
     }
     // Too many signatures: Sanitization failure
     // Too many signatures: Sanitization failure
     {
     {
         let tx = make_transaction(TestCase::AddSignature);
         let tx = make_transaction(TestCase::AddSignature);
-        assert_eq!(
+        assert_matches!(
             bank.verify_transaction(tx.into(), TransactionVerificationMode::FullVerification),
             bank.verify_transaction(tx.into(), TransactionVerificationMode::FullVerification),
-            Err(TransactionError::SanitizeFailure),
+            Err(TransactionError::SanitizeFailure)
         );
         );
     }
     }
 }
 }
@@ -10085,9 +10085,9 @@ fn test_verify_transactions_packet_data_size() {
     {
     {
         let tx = make_transaction(25);
         let tx = make_transaction(25);
         assert!(bincode::serialized_size(&tx).unwrap() > PACKET_DATA_SIZE as u64);
         assert!(bincode::serialized_size(&tx).unwrap() > PACKET_DATA_SIZE as u64);
-        assert_eq!(
+        assert_matches!(
             bank.verify_transaction(tx.into(), TransactionVerificationMode::FullVerification),
             bank.verify_transaction(tx.into(), TransactionVerificationMode::FullVerification),
-            Err(TransactionError::SanitizeFailure),
+            Err(TransactionError::SanitizeFailure)
         );
         );
     }
     }
     // Assert that verify fails as soon as serialized
     // Assert that verify fails as soon as serialized
@@ -12997,7 +12997,7 @@ fn test_failed_simulation_compute_units() {
     let transaction = Transaction::new(&[&mint_keypair], message, bank.last_blockhash());
     let transaction = Transaction::new(&[&mint_keypair], message, bank.last_blockhash());
 
 
     bank.freeze();
     bank.freeze();
-    let sanitized = SanitizedTransaction::from_transaction_for_tests(transaction);
+    let sanitized = RuntimeTransaction::from_transaction_for_tests(transaction);
     let simulation = bank.simulate_transaction(&sanitized, false);
     let simulation = bank.simulate_transaction(&sanitized, false);
     assert_eq!(expected_consumed_units, simulation.units_consumed);
     assert_eq!(expected_consumed_units, simulation.units_consumed);
 }
 }
@@ -13020,7 +13020,7 @@ fn test_failed_simulation_load_error() {
     let transaction = Transaction::new(&[&mint_keypair], message, bank.last_blockhash());
     let transaction = Transaction::new(&[&mint_keypair], message, bank.last_blockhash());
 
 
     bank.freeze();
     bank.freeze();
-    let sanitized = SanitizedTransaction::from_transaction_for_tests(transaction);
+    let sanitized = RuntimeTransaction::from_transaction_for_tests(transaction);
     let simulation = bank.simulate_transaction(&sanitized, false);
     let simulation = bank.simulate_transaction(&sanitized, false);
     assert_eq!(
     assert_eq!(
         simulation,
         simulation,

+ 2 - 1
runtime/src/bank_utils.rs

@@ -1,5 +1,6 @@
 use {
 use {
     crate::vote_sender_types::ReplayVoteSender,
     crate::vote_sender_types::ReplayVoteSender,
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::transaction::SanitizedTransaction,
     solana_sdk::transaction::SanitizedTransaction,
     solana_svm::transaction_commit_result::{
     solana_svm::transaction_commit_result::{
         TransactionCommitResult, TransactionCommitResultExtensions,
         TransactionCommitResult, TransactionCommitResultExtensions,
@@ -40,7 +41,7 @@ pub fn setup_bank_and_vote_pubkeys_for_tests(
 }
 }
 
 
 pub fn find_and_send_votes(
 pub fn find_and_send_votes(
-    sanitized_txs: &[SanitizedTransaction],
+    sanitized_txs: &[RuntimeTransaction<SanitizedTransaction>],
     commit_results: &[TransactionCommitResult],
     commit_results: &[TransactionCommitResult],
     vote_sender: Option<&ReplayVoteSender>,
     vote_sender: Option<&ReplayVoteSender>,
 ) {
 ) {

+ 10 - 4
runtime/src/installed_scheduler_pool.rs

@@ -23,6 +23,7 @@
 use {
 use {
     crate::bank::Bank,
     crate::bank::Bank,
     log::*,
     log::*,
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{
     solana_sdk::{
         clock::Slot,
         clock::Slot,
         hash::Hash,
         hash::Hash,
@@ -161,8 +162,11 @@ pub trait InstalledScheduler: Send + Sync + Debug + 'static {
     /// optimize the fast code-path of normal transaction scheduling to be multi-threaded at the
     /// optimize the fast code-path of normal transaction scheduling to be multi-threaded at the
     /// cost of far slower error code-path while giving implementors increased flexibility by
     /// cost of far slower error code-path while giving implementors increased flexibility by
     /// having &mut.
     /// having &mut.
-    fn schedule_execution(&self, transaction: SanitizedTransaction, index: usize)
-        -> ScheduleResult;
+    fn schedule_execution(
+        &self,
+        transaction: RuntimeTransaction<SanitizedTransaction>,
+        index: usize,
+    ) -> ScheduleResult;
 
 
     /// Return the error which caused the scheduler to abort.
     /// Return the error which caused the scheduler to abort.
     ///
     ///
@@ -440,7 +444,9 @@ impl BankWithScheduler {
     /// wait_for_termination()-ed or the unified scheduler is disabled in the first place).
     /// wait_for_termination()-ed or the unified scheduler is disabled in the first place).
     pub fn schedule_transaction_executions(
     pub fn schedule_transaction_executions(
         &self,
         &self,
-        transactions_with_indexes: impl ExactSizeIterator<Item = (SanitizedTransaction, usize)>,
+        transactions_with_indexes: impl ExactSizeIterator<
+            Item = (RuntimeTransaction<SanitizedTransaction>, usize),
+        >,
     ) -> Result<()> {
     ) -> Result<()> {
         trace!(
         trace!(
             "schedule_transaction_executions(): {} txs",
             "schedule_transaction_executions(): {} txs",
@@ -834,7 +840,7 @@ mod tests {
             mint_keypair,
             mint_keypair,
             ..
             ..
         } = create_genesis_config(10_000);
         } = create_genesis_config(10_000);
-        let tx0 = SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
+        let tx0 = RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
             &mint_keypair,
             &mint_keypair,
             &solana_sdk::pubkey::new_rand(),
             &solana_sdk::pubkey::new_rand(),
             2,
             2,

+ 16 - 13
runtime/src/prioritization_fee_cache.rs

@@ -4,11 +4,12 @@ use {
     log::*,
     log::*,
     solana_accounts_db::account_locks::validate_account_locks,
     solana_accounts_db::account_locks::validate_account_locks,
     solana_measure::measure_us,
     solana_measure::measure_us,
-    solana_runtime_transaction::instructions_processor::process_compute_budget_instructions,
+    solana_runtime_transaction::{
+        runtime_transaction::RuntimeTransaction, transaction_meta::StaticMeta,
+    },
     solana_sdk::{
     solana_sdk::{
         clock::{BankId, Slot},
         clock::{BankId, Slot},
         pubkey::Pubkey,
         pubkey::Pubkey,
-        transaction::SanitizedTransaction,
     },
     },
     solana_svm_transaction::svm_message::SVMMessage,
     solana_svm_transaction::svm_message::SVMMessage,
     std::{
     std::{
@@ -195,7 +196,11 @@ impl PrioritizationFeeCache {
     /// Update with a list of non-vote transactions' compute_budget_details and account_locks; Only
     /// Update with a list of non-vote transactions' compute_budget_details and account_locks; Only
     /// transactions have both valid compute_budget_details and account_locks will be used to update
     /// transactions have both valid compute_budget_details and account_locks will be used to update
     /// fee_cache asynchronously.
     /// fee_cache asynchronously.
-    pub fn update<'a>(&self, bank: &Bank, txs: impl Iterator<Item = &'a SanitizedTransaction>) {
+    pub fn update<'a, Tx: SVMMessage + 'a>(
+        &self,
+        bank: &Bank,
+        txs: impl Iterator<Item = &'a RuntimeTransaction<Tx>>,
+    ) {
         let (_, send_updates_us) = measure_us!({
         let (_, send_updates_us) = measure_us!({
             for sanitized_transaction in txs {
             for sanitized_transaction in txs {
                 // Vote transactions are not prioritized, therefore they are excluded from
                 // Vote transactions are not prioritized, therefore they are excluded from
@@ -204,13 +209,11 @@ impl PrioritizationFeeCache {
                     continue;
                     continue;
                 }
                 }
 
 
-                let compute_budget_limits = process_compute_budget_instructions(
-                    SVMMessage::program_instructions_iter(sanitized_transaction),
-                );
+                let compute_budget_limits =
+                    sanitized_transaction.compute_budget_limits(&bank.feature_set);
 
 
-                let message = sanitized_transaction.message();
                 let lock_result = validate_account_locks(
                 let lock_result = validate_account_locks(
-                    message.account_keys(),
+                    sanitized_transaction.account_keys(),
                     bank.get_transaction_account_lock_limit(),
                     bank.get_transaction_account_lock_limit(),
                 );
                 );
 
 
@@ -225,11 +228,11 @@ impl PrioritizationFeeCache {
                     continue;
                     continue;
                 }
                 }
 
 
-                let writable_accounts = message
+                let writable_accounts = sanitized_transaction
                     .account_keys()
                     .account_keys()
                     .iter()
                     .iter()
                     .enumerate()
                     .enumerate()
-                    .filter(|(index, _)| message.is_writable(*index))
+                    .filter(|(index, _)| sanitized_transaction.is_writable(*index))
                     .map(|(_, key)| *key)
                     .map(|(_, key)| *key)
                     .collect();
                     .collect();
 
 
@@ -440,7 +443,7 @@ mod tests {
         compute_unit_price: u64,
         compute_unit_price: u64,
         signer_account: &Pubkey,
         signer_account: &Pubkey,
         write_account: &Pubkey,
         write_account: &Pubkey,
-    ) -> SanitizedTransaction {
+    ) -> RuntimeTransaction<SanitizedTransaction> {
         let transaction = Transaction::new_unsigned(Message::new(
         let transaction = Transaction::new_unsigned(Message::new(
             &[
             &[
                 system_instruction::transfer(signer_account, write_account, 1),
                 system_instruction::transfer(signer_account, write_account, 1),
@@ -449,14 +452,14 @@ mod tests {
             Some(signer_account),
             Some(signer_account),
         ));
         ));
 
 
-        SanitizedTransaction::from_transaction_for_tests(transaction)
+        RuntimeTransaction::from_transaction_for_tests(transaction)
     }
     }
 
 
     // update fee cache is asynchronous, this test helper blocks until update is completed.
     // update fee cache is asynchronous, this test helper blocks until update is completed.
     fn sync_update<'a>(
     fn sync_update<'a>(
         prioritization_fee_cache: &PrioritizationFeeCache,
         prioritization_fee_cache: &PrioritizationFeeCache,
         bank: Arc<Bank>,
         bank: Arc<Bank>,
-        txs: impl ExactSizeIterator<Item = &'a SanitizedTransaction>,
+        txs: impl ExactSizeIterator<Item = &'a RuntimeTransaction<SanitizedTransaction>>,
     ) {
     ) {
         let expected_update_count = prioritization_fee_cache
         let expected_update_count = prioritization_fee_cache
             .metrics
             .metrics

+ 10 - 9
runtime/src/transaction_batch.rs

@@ -1,6 +1,7 @@
 use {
 use {
-    crate::bank::Bank, core::ops::Deref, solana_sdk::transaction::Result,
-    solana_svm_transaction::svm_message::SVMMessage,
+    crate::bank::Bank, core::ops::Deref,
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
+    solana_sdk::transaction::Result, solana_svm_transaction::svm_message::SVMMessage,
 };
 };
 
 
 pub enum OwnedOrBorrowed<'a, T> {
 pub enum OwnedOrBorrowed<'a, T> {
@@ -23,7 +24,7 @@ impl<T> Deref for OwnedOrBorrowed<'_, T> {
 pub struct TransactionBatch<'a, 'b, Tx: SVMMessage> {
 pub struct TransactionBatch<'a, 'b, Tx: SVMMessage> {
     lock_results: Vec<Result<()>>,
     lock_results: Vec<Result<()>>,
     bank: &'a Bank,
     bank: &'a Bank,
-    sanitized_txs: OwnedOrBorrowed<'b, Tx>,
+    sanitized_txs: OwnedOrBorrowed<'b, RuntimeTransaction<Tx>>,
     needs_unlock: bool,
     needs_unlock: bool,
 }
 }
 
 
@@ -31,7 +32,7 @@ impl<'a, 'b, Tx: SVMMessage> TransactionBatch<'a, 'b, Tx> {
     pub fn new(
     pub fn new(
         lock_results: Vec<Result<()>>,
         lock_results: Vec<Result<()>>,
         bank: &'a Bank,
         bank: &'a Bank,
-        sanitized_txs: OwnedOrBorrowed<'b, Tx>,
+        sanitized_txs: OwnedOrBorrowed<'b, RuntimeTransaction<Tx>>,
     ) -> Self {
     ) -> Self {
         assert_eq!(lock_results.len(), sanitized_txs.len());
         assert_eq!(lock_results.len(), sanitized_txs.len());
         Self {
         Self {
@@ -46,7 +47,7 @@ impl<'a, 'b, Tx: SVMMessage> TransactionBatch<'a, 'b, Tx> {
         &self.lock_results
         &self.lock_results
     }
     }
 
 
-    pub fn sanitized_transactions(&self) -> &[Tx] {
+    pub fn sanitized_transactions(&self) -> &[RuntimeTransaction<Tx>] {
         &self.sanitized_txs
         &self.sanitized_txs
     }
     }
 
 
@@ -191,7 +192,7 @@ mod tests {
         );
         );
     }
     }
 
 
-    fn setup(insert_conflicting_tx: bool) -> (Bank, Vec<SanitizedTransaction>) {
+    fn setup(insert_conflicting_tx: bool) -> (Bank, Vec<RuntimeTransaction<SanitizedTransaction>>) {
         let dummy_leader_pubkey = solana_sdk::pubkey::new_rand();
         let dummy_leader_pubkey = solana_sdk::pubkey::new_rand();
         let GenesisConfigInfo {
         let GenesisConfigInfo {
             genesis_config,
             genesis_config,
@@ -204,15 +205,15 @@ mod tests {
         let keypair2 = Keypair::new();
         let keypair2 = Keypair::new();
         let pubkey2 = solana_sdk::pubkey::new_rand();
         let pubkey2 = solana_sdk::pubkey::new_rand();
 
 
-        let mut txs = vec![SanitizedTransaction::from_transaction_for_tests(
+        let mut txs = vec![RuntimeTransaction::from_transaction_for_tests(
             system_transaction::transfer(&mint_keypair, &pubkey, 1, genesis_config.hash()),
             system_transaction::transfer(&mint_keypair, &pubkey, 1, genesis_config.hash()),
         )];
         )];
         if insert_conflicting_tx {
         if insert_conflicting_tx {
-            txs.push(SanitizedTransaction::from_transaction_for_tests(
+            txs.push(RuntimeTransaction::from_transaction_for_tests(
                 system_transaction::transfer(&mint_keypair, &pubkey2, 1, genesis_config.hash()),
                 system_transaction::transfer(&mint_keypair, &pubkey2, 1, genesis_config.hash()),
             ));
             ));
         }
         }
-        txs.push(SanitizedTransaction::from_transaction_for_tests(
+        txs.push(RuntimeTransaction::from_transaction_for_tests(
             system_transaction::transfer(&keypair2, &pubkey2, 1, genesis_config.hash()),
             system_transaction::transfer(&keypair2, &pubkey2, 1, genesis_config.hash()),
         ));
         ));
 
 

+ 1 - 1
sdk/program/src/message/sanitized.rs

@@ -406,7 +406,7 @@ impl SanitizedMessage {
 
 
 /// Transaction signature details including the number of transaction signatures
 /// Transaction signature details including the number of transaction signatures
 /// and precompile signatures.
 /// and precompile signatures.
-#[derive(Debug, Default)]
+#[derive(Clone, Debug, Default)]
 pub struct TransactionSignatureDetails {
 pub struct TransactionSignatureDetails {
     num_transaction_signatures: u64,
     num_transaction_signatures: u64,
     num_secp256k1_instruction_signatures: u64,
     num_secp256k1_instruction_signatures: u64,

+ 6 - 0
unified-scheduler-logic/Cargo.toml

@@ -11,5 +11,11 @@ edition = { workspace = true }
 
 
 [dependencies]
 [dependencies]
 assert_matches = { workspace = true }
 assert_matches = { workspace = true }
+solana-runtime-transaction = { workspace = true }
 solana-sdk = { workspace = true }
 solana-sdk = { workspace = true }
 static_assertions = { workspace = true }
 static_assertions = { workspace = true }
+
+[dev-dependencies]
+solana-runtime-transaction = { workspace = true, features = [
+    "dev-context-only-utils",
+] }

+ 22 - 20
unified-scheduler-logic/src/lib.rs

@@ -98,6 +98,7 @@
 use {
 use {
     crate::utils::{ShortCounter, Token, TokenCell},
     crate::utils::{ShortCounter, Token, TokenCell},
     assert_matches::assert_matches,
     assert_matches::assert_matches,
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{pubkey::Pubkey, transaction::SanitizedTransaction},
     solana_sdk::{pubkey::Pubkey, transaction::SanitizedTransaction},
     static_assertions::const_assert_eq,
     static_assertions::const_assert_eq,
     std::{collections::VecDeque, mem, sync::Arc},
     std::{collections::VecDeque, mem, sync::Arc},
@@ -413,7 +414,7 @@ const_assert_eq!(mem::size_of::<BlockedUsageCountToken>(), 0);
 /// Internal scheduling data about a particular task.
 /// Internal scheduling data about a particular task.
 #[derive(Debug)]
 #[derive(Debug)]
 pub struct TaskInner {
 pub struct TaskInner {
-    transaction: SanitizedTransaction,
+    transaction: RuntimeTransaction<SanitizedTransaction>,
     /// The index of a transaction in ledger entries; not used by SchedulingStateMachine by itself.
     /// The index of a transaction in ledger entries; not used by SchedulingStateMachine by itself.
     /// Carrying this along with the transaction is needed to properly record the execution result
     /// Carrying this along with the transaction is needed to properly record the execution result
     /// of it.
     /// of it.
@@ -427,7 +428,7 @@ impl TaskInner {
         self.index
         self.index
     }
     }
 
 
-    pub fn transaction(&self) -> &SanitizedTransaction {
+    pub fn transaction(&self) -> &RuntimeTransaction<SanitizedTransaction> {
         &self.transaction
         &self.transaction
     }
     }
 
 
@@ -754,8 +755,8 @@ impl SchedulingStateMachine {
         }
         }
     }
     }
 
 
-    /// Creates a new task with [`SanitizedTransaction`] with all of its corresponding
-    /// [`UsageQueue`]s preloaded.
+    /// Creates a new task with [`RuntimeTransaction<SanitizedTransaction>`] with all of
+    /// its corresponding [`UsageQueue`]s preloaded.
     ///
     ///
     /// Closure (`usage_queue_loader`) is used to delegate the (possibly multi-threaded)
     /// Closure (`usage_queue_loader`) is used to delegate the (possibly multi-threaded)
     /// implementation of [`UsageQueue`] look-up by [`pubkey`](Pubkey) to callers. It's the
     /// implementation of [`UsageQueue`] look-up by [`pubkey`](Pubkey) to callers. It's the
@@ -768,7 +769,7 @@ impl SchedulingStateMachine {
     /// after created, if `has_no_active_task()` is `true`. Also note that this is desired for
     /// after created, if `has_no_active_task()` is `true`. Also note that this is desired for
     /// separation of concern.
     /// separation of concern.
     pub fn create_task(
     pub fn create_task(
-        transaction: SanitizedTransaction,
+        transaction: RuntimeTransaction<SanitizedTransaction>,
         index: usize,
         index: usize,
         usage_queue_loader: &mut impl FnMut(Pubkey) -> UsageQueue,
         usage_queue_loader: &mut impl FnMut(Pubkey) -> UsageQueue,
     ) -> Task {
     ) -> Task {
@@ -887,21 +888,20 @@ mod tests {
             instruction::{AccountMeta, Instruction},
             instruction::{AccountMeta, Instruction},
             message::Message,
             message::Message,
             pubkey::Pubkey,
             pubkey::Pubkey,
-            signature::Signer,
-            signer::keypair::Keypair,
             transaction::{SanitizedTransaction, Transaction},
             transaction::{SanitizedTransaction, Transaction},
         },
         },
         std::{cell::RefCell, collections::HashMap, rc::Rc},
         std::{cell::RefCell, collections::HashMap, rc::Rc},
     };
     };
 
 
-    fn simplest_transaction() -> SanitizedTransaction {
-        let payer = Keypair::new();
-        let message = Message::new(&[], Some(&payer.pubkey()));
+    fn simplest_transaction() -> RuntimeTransaction<SanitizedTransaction> {
+        let message = Message::new(&[], Some(&Pubkey::new_unique()));
         let unsigned = Transaction::new_unsigned(message);
         let unsigned = Transaction::new_unsigned(message);
-        SanitizedTransaction::from_transaction_for_tests(unsigned)
+        RuntimeTransaction::from_transaction_for_tests(unsigned)
     }
     }
 
 
-    fn transaction_with_readonly_address(address: Pubkey) -> SanitizedTransaction {
+    fn transaction_with_readonly_address(
+        address: Pubkey,
+    ) -> RuntimeTransaction<SanitizedTransaction> {
         let instruction = Instruction {
         let instruction = Instruction {
             program_id: Pubkey::default(),
             program_id: Pubkey::default(),
             accounts: vec![AccountMeta::new_readonly(address, false)],
             accounts: vec![AccountMeta::new_readonly(address, false)],
@@ -909,10 +909,12 @@ mod tests {
         };
         };
         let message = Message::new(&[instruction], Some(&Pubkey::new_unique()));
         let message = Message::new(&[instruction], Some(&Pubkey::new_unique()));
         let unsigned = Transaction::new_unsigned(message);
         let unsigned = Transaction::new_unsigned(message);
-        SanitizedTransaction::from_transaction_for_tests(unsigned)
+        RuntimeTransaction::from_transaction_for_tests(unsigned)
     }
     }
 
 
-    fn transaction_with_writable_address(address: Pubkey) -> SanitizedTransaction {
+    fn transaction_with_writable_address(
+        address: Pubkey,
+    ) -> RuntimeTransaction<SanitizedTransaction> {
         let instruction = Instruction {
         let instruction = Instruction {
             program_id: Pubkey::default(),
             program_id: Pubkey::default(),
             accounts: vec![AccountMeta::new(address, false)],
             accounts: vec![AccountMeta::new(address, false)],
@@ -920,7 +922,7 @@ mod tests {
         };
         };
         let message = Message::new(&[instruction], Some(&Pubkey::new_unique()));
         let message = Message::new(&[instruction], Some(&Pubkey::new_unique()));
         let unsigned = Transaction::new_unsigned(message);
         let unsigned = Transaction::new_unsigned(message);
-        SanitizedTransaction::from_transaction_for_tests(unsigned)
+        RuntimeTransaction::from_transaction_for_tests(unsigned)
     }
     }
 
 
     fn create_address_loader(
     fn create_address_loader(
@@ -972,18 +974,18 @@ mod tests {
     #[test]
     #[test]
     fn test_create_task() {
     fn test_create_task() {
         let sanitized = simplest_transaction();
         let sanitized = simplest_transaction();
-        let task = SchedulingStateMachine::create_task(sanitized.clone(), 3, &mut |_| {
-            UsageQueue::default()
-        });
+        let signature = *sanitized.signature();
+        let task =
+            SchedulingStateMachine::create_task(sanitized, 3, &mut |_| UsageQueue::default());
         assert_eq!(task.task_index(), 3);
         assert_eq!(task.task_index(), 3);
-        assert_eq!(task.transaction(), &sanitized);
+        assert_eq!(task.transaction().signature(), &signature);
     }
     }
 
 
     #[test]
     #[test]
     fn test_non_conflicting_task_related_counts() {
     fn test_non_conflicting_task_related_counts() {
         let sanitized = simplest_transaction();
         let sanitized = simplest_transaction();
         let address_loader = &mut create_address_loader(None);
         let address_loader = &mut create_address_loader(None);
-        let task = SchedulingStateMachine::create_task(sanitized.clone(), 3, address_loader);
+        let task = SchedulingStateMachine::create_task(sanitized, 3, address_loader);
 
 
         let mut state_machine = unsafe {
         let mut state_machine = unsafe {
             SchedulingStateMachine::exclusively_initialize_current_thread_for_scheduling()
             SchedulingStateMachine::exclusively_initialize_current_thread_for_scheduling()

+ 1 - 0
unified-scheduler-pool/Cargo.toml

@@ -19,6 +19,7 @@ qualifier_attr = { workspace = true }
 scopeguard = { workspace = true }
 scopeguard = { workspace = true }
 solana-ledger = { workspace = true }
 solana-ledger = { workspace = true }
 solana-runtime = { workspace = true }
 solana-runtime = { workspace = true }
+solana-runtime-transaction = { workspace = true }
 solana-sdk = { workspace = true }
 solana-sdk = { workspace = true }
 solana-timings = { workspace = true }
 solana-timings = { workspace = true }
 solana-unified-scheduler-logic = { workspace = true }
 solana-unified-scheduler-logic = { workspace = true }

+ 48 - 51
unified-scheduler-pool/src/lib.rs

@@ -31,6 +31,7 @@ use {
         prioritization_fee_cache::PrioritizationFeeCache,
         prioritization_fee_cache::PrioritizationFeeCache,
         vote_sender_types::ReplayVoteSender,
         vote_sender_types::ReplayVoteSender,
     },
     },
+    solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{
     solana_sdk::{
         pubkey::Pubkey,
         pubkey::Pubkey,
         transaction::{Result, SanitizedTransaction, TransactionError},
         transaction::{Result, SanitizedTransaction, TransactionError},
@@ -411,7 +412,7 @@ pub trait TaskHandler: Send + Sync + Debug + Sized + 'static {
         result: &mut Result<()>,
         result: &mut Result<()>,
         timings: &mut ExecuteTimings,
         timings: &mut ExecuteTimings,
         bank: &Arc<Bank>,
         bank: &Arc<Bank>,
-        transaction: &SanitizedTransaction,
+        transaction: &RuntimeTransaction<SanitizedTransaction>,
         index: usize,
         index: usize,
         handler_context: &HandlerContext,
         handler_context: &HandlerContext,
     );
     );
@@ -425,7 +426,7 @@ impl TaskHandler for DefaultTaskHandler {
         result: &mut Result<()>,
         result: &mut Result<()>,
         timings: &mut ExecuteTimings,
         timings: &mut ExecuteTimings,
         bank: &Arc<Bank>,
         bank: &Arc<Bank>,
-        transaction: &SanitizedTransaction,
+        transaction: &RuntimeTransaction<SanitizedTransaction>,
         index: usize,
         index: usize,
         handler_context: &HandlerContext,
         handler_context: &HandlerContext,
     ) {
     ) {
@@ -1411,7 +1412,7 @@ impl<TH: TaskHandler> InstalledScheduler for PooledScheduler<TH> {
 
 
     fn schedule_execution(
     fn schedule_execution(
         &self,
         &self,
-        transaction: SanitizedTransaction,
+        transaction: RuntimeTransaction<SanitizedTransaction>,
         index: usize,
         index: usize,
     ) -> ScheduleResult {
     ) -> ScheduleResult {
         let task = SchedulingStateMachine::create_task(transaction, index, &mut |pubkey| {
         let task = SchedulingStateMachine::create_task(transaction, index, &mut |pubkey| {
@@ -1753,7 +1754,7 @@ mod tests {
                 _result: &mut Result<()>,
                 _result: &mut Result<()>,
                 timings: &mut ExecuteTimings,
                 timings: &mut ExecuteTimings,
                 _bank: &Arc<Bank>,
                 _bank: &Arc<Bank>,
-                _transaction: &SanitizedTransaction,
+                _transaction: &RuntimeTransaction<SanitizedTransaction>,
                 _index: usize,
                 _index: usize,
                 _handler_context: &HandlerContext,
                 _handler_context: &HandlerContext,
             ) {
             ) {
@@ -1777,7 +1778,7 @@ mod tests {
         pool.register_timeout_listener(bank.create_timeout_listener());
         pool.register_timeout_listener(bank.create_timeout_listener());
 
 
         let tx_before_stale =
         let tx_before_stale =
-            SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
+            RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
                 &mint_keypair,
                 &mint_keypair,
                 &solana_sdk::pubkey::new_rand(),
                 &solana_sdk::pubkey::new_rand(),
                 2,
                 2,
@@ -1789,7 +1790,7 @@ mod tests {
 
 
         sleepless_testing::at(TestCheckPoint::AfterTimeoutListenerTriggered);
         sleepless_testing::at(TestCheckPoint::AfterTimeoutListenerTriggered);
         let tx_after_stale =
         let tx_after_stale =
-            SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
+            RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
                 &mint_keypair,
                 &mint_keypair,
                 &solana_sdk::pubkey::new_rand(),
                 &solana_sdk::pubkey::new_rand(),
                 2,
                 2,
@@ -1897,7 +1898,7 @@ mod tests {
         pool.register_timeout_listener(bank.create_timeout_listener());
         pool.register_timeout_listener(bank.create_timeout_listener());
 
 
         let tx_before_stale =
         let tx_before_stale =
-            SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
+            RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
                 &mint_keypair,
                 &mint_keypair,
                 &solana_sdk::pubkey::new_rand(),
                 &solana_sdk::pubkey::new_rand(),
                 2,
                 2,
@@ -1910,7 +1911,7 @@ mod tests {
 
 
         sleepless_testing::at(TestCheckPoint::AfterTimeoutListenerTriggered);
         sleepless_testing::at(TestCheckPoint::AfterTimeoutListenerTriggered);
         let tx_after_stale =
         let tx_after_stale =
-            SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
+            RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
                 &mint_keypair,
                 &mint_keypair,
                 &solana_sdk::pubkey::new_rand(),
                 &solana_sdk::pubkey::new_rand(),
                 2,
                 2,
@@ -1936,7 +1937,7 @@ mod tests {
             result: &mut Result<()>,
             result: &mut Result<()>,
             _timings: &mut ExecuteTimings,
             _timings: &mut ExecuteTimings,
             _bank: &Arc<Bank>,
             _bank: &Arc<Bank>,
-            _transaction: &SanitizedTransaction,
+            _transaction: &RuntimeTransaction<SanitizedTransaction>,
             _index: usize,
             _index: usize,
             _handler_context: &HandlerContext,
             _handler_context: &HandlerContext,
         ) {
         ) {
@@ -1961,7 +1962,7 @@ mod tests {
             ..
             ..
         } = create_genesis_config(10_000);
         } = create_genesis_config(10_000);
 
 
-        let tx = SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
+        let tx = RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
             &mint_keypair,
             &mint_keypair,
             &solana_sdk::pubkey::new_rand(),
             &solana_sdk::pubkey::new_rand(),
             2,
             2,
@@ -2047,7 +2048,7 @@ mod tests {
                 _result: &mut Result<()>,
                 _result: &mut Result<()>,
                 _timings: &mut ExecuteTimings,
                 _timings: &mut ExecuteTimings,
                 _bank: &Arc<Bank>,
                 _bank: &Arc<Bank>,
-                _transaction: &SanitizedTransaction,
+                _transaction: &RuntimeTransaction<SanitizedTransaction>,
                 _index: usize,
                 _index: usize,
                 _handler_context: &HandlerContext,
                 _handler_context: &HandlerContext,
             ) {
             ) {
@@ -2082,13 +2083,12 @@ mod tests {
         const MAX_TASK_COUNT: usize = 100;
         const MAX_TASK_COUNT: usize = 100;
 
 
         for i in 0..MAX_TASK_COUNT {
         for i in 0..MAX_TASK_COUNT {
-            let tx =
-                SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
-                    &mint_keypair,
-                    &solana_sdk::pubkey::new_rand(),
-                    2,
-                    genesis_config.hash(),
-                ));
+            let tx = RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
+                &mint_keypair,
+                &solana_sdk::pubkey::new_rand(),
+                2,
+                genesis_config.hash(),
+            ));
             scheduler.schedule_execution(tx, i).unwrap();
             scheduler.schedule_execution(tx, i).unwrap();
         }
         }
 
 
@@ -2234,7 +2234,7 @@ mod tests {
             mint_keypair,
             mint_keypair,
             ..
             ..
         } = create_genesis_config(10_000);
         } = create_genesis_config(10_000);
-        let tx0 = SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
+        let tx0 = RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
             &mint_keypair,
             &mint_keypair,
             &solana_sdk::pubkey::new_rand(),
             &solana_sdk::pubkey::new_rand(),
             2,
             2,
@@ -2294,20 +2294,19 @@ mod tests {
         let scheduler = pool.take_scheduler(context);
         let scheduler = pool.take_scheduler(context);
 
 
         let unfunded_keypair = Keypair::new();
         let unfunded_keypair = Keypair::new();
-        let bad_tx =
-            SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
-                &unfunded_keypair,
-                &solana_sdk::pubkey::new_rand(),
-                2,
-                genesis_config.hash(),
-            ));
+        let bad_tx = RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
+            &unfunded_keypair,
+            &solana_sdk::pubkey::new_rand(),
+            2,
+            genesis_config.hash(),
+        ));
         assert_eq!(bank.transaction_count(), 0);
         assert_eq!(bank.transaction_count(), 0);
         scheduler.schedule_execution(bad_tx, 0).unwrap();
         scheduler.schedule_execution(bad_tx, 0).unwrap();
         sleepless_testing::at(TestCheckPoint::AfterTaskHandled);
         sleepless_testing::at(TestCheckPoint::AfterTaskHandled);
         assert_eq!(bank.transaction_count(), 0);
         assert_eq!(bank.transaction_count(), 0);
 
 
         let good_tx_after_bad_tx =
         let good_tx_after_bad_tx =
-            SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
+            RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
                 &mint_keypair,
                 &mint_keypair,
                 &solana_sdk::pubkey::new_rand(),
                 &solana_sdk::pubkey::new_rand(),
                 3,
                 3,
@@ -2386,7 +2385,7 @@ mod tests {
                 _result: &mut Result<()>,
                 _result: &mut Result<()>,
                 _timings: &mut ExecuteTimings,
                 _timings: &mut ExecuteTimings,
                 _bank: &Arc<Bank>,
                 _bank: &Arc<Bank>,
-                _transaction: &SanitizedTransaction,
+                _transaction: &RuntimeTransaction<SanitizedTransaction>,
                 index: usize,
                 index: usize,
                 _handler_context: &HandlerContext,
                 _handler_context: &HandlerContext,
             ) {
             ) {
@@ -2425,13 +2424,12 @@ mod tests {
 
 
         for index in 0..TX_COUNT {
         for index in 0..TX_COUNT {
             // Use 2 non-conflicting txes to exercise the channel disconnected case as well.
             // Use 2 non-conflicting txes to exercise the channel disconnected case as well.
-            let tx =
-                SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
-                    &Keypair::new(),
-                    &solana_sdk::pubkey::new_rand(),
-                    1,
-                    genesis_config.hash(),
-                ));
+            let tx = RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
+                &Keypair::new(),
+                &solana_sdk::pubkey::new_rand(),
+                1,
+                genesis_config.hash(),
+            ));
             scheduler.schedule_execution(tx, index).unwrap();
             scheduler.schedule_execution(tx, index).unwrap();
         }
         }
         // finally unblock the scheduler thread; otherwise the above schedule_execution could
         // finally unblock the scheduler thread; otherwise the above schedule_execution could
@@ -2467,7 +2465,7 @@ mod tests {
                 result: &mut Result<()>,
                 result: &mut Result<()>,
                 _timings: &mut ExecuteTimings,
                 _timings: &mut ExecuteTimings,
                 _bank: &Arc<Bank>,
                 _bank: &Arc<Bank>,
-                _transaction: &SanitizedTransaction,
+                _transaction: &RuntimeTransaction<SanitizedTransaction>,
                 index: usize,
                 index: usize,
                 _handler_context: &HandlerContext,
                 _handler_context: &HandlerContext,
             ) {
             ) {
@@ -2499,13 +2497,12 @@ mod tests {
         let scheduler = pool.do_take_scheduler(context);
         let scheduler = pool.do_take_scheduler(context);
 
 
         for i in 0..10 {
         for i in 0..10 {
-            let tx =
-                SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
-                    &mint_keypair,
-                    &solana_sdk::pubkey::new_rand(),
-                    2,
-                    genesis_config.hash(),
-                ));
+            let tx = RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
+                &mint_keypair,
+                &solana_sdk::pubkey::new_rand(),
+                2,
+                genesis_config.hash(),
+            ));
             scheduler.schedule_execution(tx, i).unwrap();
             scheduler.schedule_execution(tx, i).unwrap();
         }
         }
         // finally unblock the scheduler thread; otherwise the above schedule_execution could
         // finally unblock the scheduler thread; otherwise the above schedule_execution could
@@ -2537,7 +2534,7 @@ mod tests {
                 result: &mut Result<()>,
                 result: &mut Result<()>,
                 timings: &mut ExecuteTimings,
                 timings: &mut ExecuteTimings,
                 bank: &Arc<Bank>,
                 bank: &Arc<Bank>,
-                transaction: &SanitizedTransaction,
+                transaction: &RuntimeTransaction<SanitizedTransaction>,
                 index: usize,
                 index: usize,
                 handler_context: &HandlerContext,
                 handler_context: &HandlerContext,
             ) {
             ) {
@@ -2564,13 +2561,13 @@ mod tests {
         } = create_genesis_config(10_000);
         } = create_genesis_config(10_000);
 
 
         // tx0 and tx1 is definitely conflicting to write-lock the mint address
         // tx0 and tx1 is definitely conflicting to write-lock the mint address
-        let tx0 = SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
+        let tx0 = RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
             &mint_keypair,
             &mint_keypair,
             &solana_sdk::pubkey::new_rand(),
             &solana_sdk::pubkey::new_rand(),
             2,
             2,
             genesis_config.hash(),
             genesis_config.hash(),
         ));
         ));
-        let tx1 = SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
+        let tx1 = RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
             &mint_keypair,
             &mint_keypair,
             &solana_sdk::pubkey::new_rand(),
             &solana_sdk::pubkey::new_rand(),
             2,
             2,
@@ -2622,7 +2619,7 @@ mod tests {
                 _result: &mut Result<()>,
                 _result: &mut Result<()>,
                 _timings: &mut ExecuteTimings,
                 _timings: &mut ExecuteTimings,
                 bank: &Arc<Bank>,
                 bank: &Arc<Bank>,
-                _transaction: &SanitizedTransaction,
+                _transaction: &RuntimeTransaction<SanitizedTransaction>,
                 index: usize,
                 index: usize,
                 _handler_context: &HandlerContext,
                 _handler_context: &HandlerContext,
             ) {
             ) {
@@ -2657,7 +2654,7 @@ mod tests {
 
 
         // Create a dummy tx and two contexts
         // Create a dummy tx and two contexts
         let dummy_tx =
         let dummy_tx =
-            SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
+            RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
                 &mint_keypair,
                 &mint_keypair,
                 &solana_sdk::pubkey::new_rand(),
                 &solana_sdk::pubkey::new_rand(),
                 2,
                 2,
@@ -2717,7 +2714,7 @@ mod tests {
 
 
         fn schedule_execution(
         fn schedule_execution(
             &self,
             &self,
-            transaction: SanitizedTransaction,
+            transaction: RuntimeTransaction<SanitizedTransaction>,
             index: usize,
             index: usize,
         ) -> ScheduleResult {
         ) -> ScheduleResult {
             let transaction_and_index = (transaction, index);
             let transaction_and_index = (transaction, index);
@@ -2823,7 +2820,7 @@ mod tests {
             ..
             ..
         } = create_genesis_config(10_000);
         } = create_genesis_config(10_000);
         let very_old_valid_tx =
         let very_old_valid_tx =
-            SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
+            RuntimeTransaction::from_transaction_for_tests(system_transaction::transfer(
                 &mint_keypair,
                 &mint_keypair,
                 &solana_sdk::pubkey::new_rand(),
                 &solana_sdk::pubkey::new_rand(),
                 2,
                 2,
@@ -2921,7 +2918,7 @@ mod tests {
         );
         );
         // mangle the transfer tx to try to lock fee_payer (= mint_keypair) address twice!
         // mangle the transfer tx to try to lock fee_payer (= mint_keypair) address twice!
         tx.message.account_keys.push(tx.message.account_keys[0]);
         tx.message.account_keys.push(tx.message.account_keys[0]);
-        let tx = SanitizedTransaction::from_transaction_for_tests(tx);
+        let tx = RuntimeTransaction::from_transaction_for_tests(tx);
 
 
         // this internally should call SanitizedTransaction::get_account_locks().
         // this internally should call SanitizedTransaction::get_account_locks().
         let result = &mut Ok(());
         let result = &mut Ok(());