Bladeren bron

Refactor ComputeBudget and ComputeBudgetLimits (#5127)

* Refactor ComputeBudget and ComputeBudgetLimits

* split ComputeBudget into budget and cost structs

* Move relevant structs into SVM boundaries
Pankaj Garg 8 maanden geleden
bovenliggende
commit
a7092a20bb
44 gewijzigde bestanden met toevoegingen van 878 en 486 verwijderingen
  1. 8 11
      Cargo.lock
  2. 1 1
      cli/src/compute_budget.rs
  3. 10 5
      cli/src/program.rs
  4. 4 3
      cli/src/program_v4.rs
  5. 8 0
      compute-budget-instruction/src/instructions_processor.rs
  6. 1 1
      compute-budget/Cargo.toml
  7. 136 104
      compute-budget/src/compute_budget.rs
  8. 44 17
      compute-budget/src/compute_budget_limits.rs
  9. 0 1
      core/src/banking_stage/consumer.rs
  10. 1 1
      core/tests/scheduler_cost_adjustment.rs
  11. 2 3
      program-runtime/Cargo.toml
  12. 251 0
      program-runtime/src/execution_budget.rs
  13. 25 18
      program-runtime/src/invoke_context.rs
  14. 2 0
      program-runtime/src/lib.rs
  15. 3 3
      program-runtime/src/mem_pool.rs
  16. 1 1
      program-test/src/lib.rs
  17. 0 1
      programs/bpf_loader/Cargo.toml
  18. 2 2
      programs/bpf_loader/src/lib.rs
  19. 6 6
      programs/bpf_loader/src/syscalls/cpi.rs
  20. 7 7
      programs/bpf_loader/src/syscalls/logging.rs
  21. 3 3
      programs/bpf_loader/src/syscalls/mem_ops.rs
  22. 108 102
      programs/bpf_loader/src/syscalls/mod.rs
  23. 4 4
      programs/bpf_loader/src/syscalls/sysvar.rs
  24. 0 1
      programs/loader-v4/Cargo.toml
  25. 1 5
      programs/sbf/Cargo.lock
  26. 8 6
      programs/sbf/benches/bpf_loader.rs
  27. 6 6
      runtime/src/account_saver.rs
  28. 8 5
      runtime/src/bank.rs
  29. 2 1
      runtime/src/bank/builtins/core_bpf_migration/mod.rs
  30. 17 7
      runtime/src/bank/check_transactions.rs
  31. 22 13
      runtime/src/bank/tests.rs
  32. 1 3
      svm/Cargo.toml
  33. 1 5
      svm/examples/Cargo.lock
  34. 5 6
      svm/examples/json-rpc/server/src/rpc_process.rs
  35. 1 1
      svm/examples/paytube/Cargo.toml
  36. 3 6
      svm/examples/paytube/src/lib.rs
  37. 6 5
      svm/examples/paytube/src/processor.rs
  38. 54 30
      svm/src/account_loader.rs
  39. 15 8
      svm/src/message_processor.rs
  40. 79 68
      svm/src/transaction_processor.rs
  41. 5 3
      svm/tests/concurrent_tests.rs
  42. 5 4
      svm/tests/conformance.rs
  43. 10 7
      svm/tests/integration_test.rs
  44. 2 2
      svm/tests/mock_bank.rs

+ 8 - 11
Cargo.lock

@@ -1332,9 +1332,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
 
 [[package]]
 name = "bytes"
-version = "1.10.1"
+version = "1.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
+checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9"
 
 [[package]]
 name = "bytesize"
@@ -5065,9 +5065,9 @@ dependencies = [
 
 [[package]]
 name = "quote"
-version = "1.0.40"
+version = "1.0.39"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
+checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801"
 dependencies = [
  "proc-macro2",
 ]
@@ -6713,7 +6713,6 @@ dependencies = [
  "solana-bn254",
  "solana-bpf-loader-program",
  "solana-clock",
- "solana-compute-budget",
  "solana-cpi",
  "solana-curve25519",
  "solana-epoch-rewards",
@@ -7219,7 +7218,7 @@ dependencies = [
  "qualifier_attr",
  "solana-fee-structure",
  "solana-frozen-abi",
- "solana-program-entrypoint",
+ "solana-program-runtime",
 ]
 
 [[package]]
@@ -8378,7 +8377,6 @@ dependencies = [
  "solana-bincode",
  "solana-bpf-loader-program",
  "solana-clock",
- "solana-compute-budget",
  "solana-instruction",
  "solana-loader-v3-interface",
  "solana-loader-v4-interface",
@@ -8972,7 +8970,6 @@ dependencies = [
  "solana-account",
  "solana-account-info",
  "solana-clock",
- "solana-compute-budget",
  "solana-epoch-rewards",
  "solana-epoch-schedule",
  "solana-feature-set",
@@ -8986,6 +8983,7 @@ dependencies = [
  "solana-metrics",
  "solana-precompiles",
  "solana-program-entrypoint",
+ "solana-program-runtime",
  "solana-pubkey",
  "solana-rent",
  "solana-sbpf",
@@ -10138,7 +10136,6 @@ dependencies = [
  "solana-account",
  "solana-bpf-loader-program",
  "solana-clock",
- "solana-compute-budget",
  "solana-compute-budget-instruction",
  "solana-compute-budget-interface",
  "solana-compute-budget-program",
@@ -12078,9 +12075,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
 
 [[package]]
 name = "tokio"
-version = "1.44.0"
+version = "1.44.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9975ea0f48b5aa3972bf2d888c238182458437cc2a19374b81b25cdf1023fb3a"
+checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a"
 dependencies = [
  "backtrace",
  "bytes",

+ 1 - 1
cli/src/compute_budget.rs

@@ -1,10 +1,10 @@
 use {
     solana_borsh::v1::try_from_slice_unchecked,
     solana_clap_utils::compute_budget::ComputeUnitLimit,
-    solana_compute_budget::compute_budget_limits::MAX_COMPUTE_UNIT_LIMIT,
     solana_compute_budget_interface::{self as compute_budget, ComputeBudgetInstruction},
     solana_instruction::Instruction,
     solana_message::Message,
+    solana_program_runtime::execution_budget::MAX_COMPUTE_UNIT_LIMIT,
     solana_rpc_client::rpc_client::RpcClient,
     solana_rpc_client_api::config::RpcSimulateTransactionConfig,
     solana_transaction::Transaction,

+ 10 - 5
cli/src/program.rs

@@ -41,7 +41,6 @@ use {
         tpu_client::{TpuClient, TpuClientConfig},
     },
     solana_commitment_config::CommitmentConfig,
-    solana_compute_budget::compute_budget::ComputeBudget,
     solana_feature_set::{FeatureSet, FEATURE_NAMES},
     solana_instruction::{error::InstructionError, Instruction},
     solana_keypair::{keypair_from_seed, read_keypair_file, Keypair},
@@ -51,7 +50,9 @@ use {
     },
     solana_message::Message,
     solana_packet::PACKET_DATA_SIZE,
-    solana_program_runtime::invoke_context::InvokeContext,
+    solana_program_runtime::{
+        execution_budget::SVMTransactionExecutionBudget, invoke_context::InvokeContext,
+    },
     solana_pubkey::Pubkey,
     solana_remote_wallet::remote_wallet::RemoteWalletManager,
     solana_rpc_client::rpc_client::RpcClient,
@@ -3026,9 +3027,13 @@ fn verify_elf(
     feature_set: FeatureSet,
 ) -> Result<(), Box<dyn std::error::Error>> {
     // Verify the program
-    let program_runtime_environment =
-        create_program_runtime_environment_v1(&feature_set, &ComputeBudget::default(), true, false)
-            .unwrap();
+    let program_runtime_environment = create_program_runtime_environment_v1(
+        &feature_set,
+        &SVMTransactionExecutionBudget::default(),
+        true,
+        false,
+    )
+    .unwrap();
     let executable =
         Executable::<InvokeContext>::from_elf(program_data, Arc::new(program_runtime_environment))
             .map_err(|err| format!("ELF error: {err}"))?;

+ 4 - 3
cli/src/program_v4.rs

@@ -26,7 +26,6 @@ use {
         },
         tpu_client::{TpuClient, TpuClientConfig},
     },
-    solana_compute_budget::compute_budget::ComputeBudget,
     solana_feature_set::{FeatureSet, FEATURE_NAMES},
     solana_instruction::Instruction,
     solana_loader_v4_interface::{
@@ -37,7 +36,9 @@ use {
         },
     },
     solana_message::Message,
-    solana_program_runtime::invoke_context::InvokeContext,
+    solana_program_runtime::{
+        execution_budget::SVMTransactionExecutionBudget, invoke_context::InvokeContext,
+    },
     solana_pubkey::Pubkey,
     solana_remote_wallet::remote_wallet::RemoteWalletManager,
     solana_rpc_client::rpc_client::RpcClient,
@@ -632,7 +633,7 @@ pub fn process_deploy_program(
     let program_runtime_environment =
         solana_bpf_loader_program::syscalls::create_program_runtime_environment_v1(
             &feature_set,
-            &ComputeBudget::default(),
+            &SVMTransactionExecutionBudget::default(),
             true,
             false,
         )

+ 8 - 0
compute-budget-instruction/src/instructions_processor.rs

@@ -279,6 +279,14 @@ mod tests {
             Err(TransactionError::DuplicateInstruction(2))
         );
 
+        test!(
+            &[
+                ComputeBudgetInstruction::set_compute_unit_limit(2000u32),
+                ComputeBudgetInstruction::set_compute_unit_limit(42u32),
+            ],
+            Err(TransactionError::DuplicateInstruction(1))
+        );
+
         test!(
             &[
                 Instruction::new_with_bincode(Pubkey::new_unique(), &0_u8, vec![]),

+ 1 - 1
compute-budget/Cargo.toml

@@ -15,7 +15,7 @@ solana-fee-structure = { workspace = true }
 solana-frozen-abi = { workspace = true, optional = true, features = [
     "frozen-abi",
 ] }
-solana-program-entrypoint = { workspace = true }
+solana-program-runtime = { workspace = true }
 
 [features]
 dev-context-only-utils = ["dep:qualifier_attr"]

+ 136 - 104
compute-budget/src/compute_budget.rs

@@ -1,24 +1,11 @@
-use crate::compute_budget_limits::{self, ComputeBudgetLimits, DEFAULT_HEAP_COST};
-#[cfg(feature = "dev-context-only-utils")]
-use qualifier_attr::qualifiers;
-
-#[cfg(feature = "frozen-abi")]
-impl ::solana_frozen_abi::abi_example::AbiExample for ComputeBudget {
-    fn example() -> Self {
-        // ComputeBudget is not Serialize so just rely on Default.
-        ComputeBudget::default()
-    }
-}
-
-/// Max instruction stack depth. This is the maximum nesting of instructions that can happen during
-/// a transaction.
-pub const MAX_INSTRUCTION_STACK_DEPTH: usize = 5;
-
-/// Max call depth. This is the maximum nesting of SBF to SBF call that can happen within a program.
-pub const MAX_CALL_DEPTH: usize = 64;
-
-/// The size of one SBF stack frame.
-pub const STACK_FRAME_SIZE: usize = 4096;
+pub use solana_program_runtime::execution_budget::{
+    SVMTransactionExecutionBudget, SVMTransactionExecutionCost, MAX_CALL_DEPTH,
+    MAX_INSTRUCTION_STACK_DEPTH, STACK_FRAME_SIZE,
+};
+use {
+    crate::compute_budget_limits::ComputeBudgetLimits, solana_fee_structure::FeeBudgetLimits,
+    solana_program_runtime::execution_budget::SVMTransactionExecutionAndFeeBudgetLimits,
+};
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub struct ComputeBudget {
@@ -133,98 +120,143 @@ pub struct ComputeBudget {
 
 impl Default for ComputeBudget {
     fn default() -> Self {
-        Self::new(compute_budget_limits::MAX_COMPUTE_UNIT_LIMIT as u64)
+        Self::from_budget_and_cost(
+            &SVMTransactionExecutionBudget::default(),
+            &SVMTransactionExecutionCost::default(),
+        )
     }
 }
 
-impl From<ComputeBudgetLimits> for ComputeBudget {
-    fn from(compute_budget_limits: ComputeBudgetLimits) -> Self {
-        ComputeBudget {
-            compute_unit_limit: u64::from(compute_budget_limits.compute_unit_limit),
-            heap_size: compute_budget_limits.updated_heap_bytes,
-            ..ComputeBudget::default()
+impl ComputeBudget {
+    pub fn from_budget_and_cost(
+        budget: &SVMTransactionExecutionBudget,
+        cost: &SVMTransactionExecutionCost,
+    ) -> Self {
+        Self {
+            compute_unit_limit: budget.compute_unit_limit,
+            log_64_units: cost.log_64_units,
+            create_program_address_units: cost.create_program_address_units,
+            invoke_units: cost.invoke_units,
+            max_instruction_stack_depth: budget.max_instruction_stack_depth,
+            max_instruction_trace_length: budget.max_instruction_trace_length,
+            sha256_base_cost: cost.sha256_base_cost,
+            sha256_byte_cost: cost.sha256_byte_cost,
+            sha256_max_slices: budget.sha256_max_slices,
+            max_call_depth: budget.max_call_depth,
+            stack_frame_size: budget.stack_frame_size,
+            log_pubkey_units: cost.log_pubkey_units,
+            max_cpi_instruction_size: budget.max_cpi_instruction_size,
+            cpi_bytes_per_unit: cost.cpi_bytes_per_unit,
+            sysvar_base_cost: cost.sysvar_base_cost,
+            secp256k1_recover_cost: cost.secp256k1_recover_cost,
+            syscall_base_cost: cost.syscall_base_cost,
+            curve25519_edwards_validate_point_cost: cost.curve25519_edwards_validate_point_cost,
+            curve25519_edwards_add_cost: cost.curve25519_edwards_add_cost,
+            curve25519_edwards_subtract_cost: cost.curve25519_edwards_subtract_cost,
+            curve25519_edwards_multiply_cost: cost.curve25519_edwards_multiply_cost,
+            curve25519_edwards_msm_base_cost: cost.curve25519_edwards_msm_base_cost,
+            curve25519_edwards_msm_incremental_cost: cost.curve25519_edwards_msm_incremental_cost,
+            curve25519_ristretto_validate_point_cost: cost.curve25519_ristretto_validate_point_cost,
+            curve25519_ristretto_add_cost: cost.curve25519_ristretto_add_cost,
+            curve25519_ristretto_subtract_cost: cost.curve25519_ristretto_subtract_cost,
+            curve25519_ristretto_multiply_cost: cost.curve25519_ristretto_multiply_cost,
+            curve25519_ristretto_msm_base_cost: cost.curve25519_ristretto_msm_base_cost,
+            curve25519_ristretto_msm_incremental_cost: cost
+                .curve25519_ristretto_msm_incremental_cost,
+            heap_size: budget.heap_size,
+            heap_cost: cost.heap_cost,
+            mem_op_base_cost: cost.mem_op_base_cost,
+            alt_bn128_addition_cost: cost.alt_bn128_addition_cost,
+            alt_bn128_multiplication_cost: cost.alt_bn128_multiplication_cost,
+            alt_bn128_pairing_one_pair_cost_first: cost.alt_bn128_pairing_one_pair_cost_first,
+            alt_bn128_pairing_one_pair_cost_other: cost.alt_bn128_pairing_one_pair_cost_other,
+            big_modular_exponentiation_base_cost: cost.big_modular_exponentiation_base_cost,
+            big_modular_exponentiation_cost_divisor: cost.big_modular_exponentiation_cost_divisor,
+            poseidon_cost_coefficient_a: cost.poseidon_cost_coefficient_a,
+            poseidon_cost_coefficient_c: cost.poseidon_cost_coefficient_c,
+            get_remaining_compute_units_cost: cost.get_remaining_compute_units_cost,
+            alt_bn128_g1_compress: cost.alt_bn128_g1_compress,
+            alt_bn128_g1_decompress: cost.alt_bn128_g1_decompress,
+            alt_bn128_g2_compress: cost.alt_bn128_g2_compress,
+            alt_bn128_g2_decompress: cost.alt_bn128_g2_decompress,
         }
     }
-}
 
-impl ComputeBudget {
-    #[cfg_attr(feature = "dev-context-only-utils", qualifiers(pub))]
-    fn new(compute_unit_limit: u64) -> Self {
-        ComputeBudget {
-            compute_unit_limit,
-            log_64_units: 100,
-            create_program_address_units: 1500,
-            invoke_units: 1000,
-            max_instruction_stack_depth: MAX_INSTRUCTION_STACK_DEPTH,
-            max_instruction_trace_length: 64,
-            sha256_base_cost: 85,
-            sha256_byte_cost: 1,
-            sha256_max_slices: 20_000,
-            max_call_depth: MAX_CALL_DEPTH,
-            stack_frame_size: STACK_FRAME_SIZE,
-            log_pubkey_units: 100,
-            max_cpi_instruction_size: 1280, // IPv6 Min MTU size
-            cpi_bytes_per_unit: 250,        // ~50MB at 200,000 units
-            sysvar_base_cost: 100,
-            secp256k1_recover_cost: 25_000,
-            syscall_base_cost: 100,
-            curve25519_edwards_validate_point_cost: 159,
-            curve25519_edwards_add_cost: 473,
-            curve25519_edwards_subtract_cost: 475,
-            curve25519_edwards_multiply_cost: 2_177,
-            curve25519_edwards_msm_base_cost: 2_273,
-            curve25519_edwards_msm_incremental_cost: 758,
-            curve25519_ristretto_validate_point_cost: 169,
-            curve25519_ristretto_add_cost: 521,
-            curve25519_ristretto_subtract_cost: 519,
-            curve25519_ristretto_multiply_cost: 2_208,
-            curve25519_ristretto_msm_base_cost: 2303,
-            curve25519_ristretto_msm_incremental_cost: 788,
-            heap_size: u32::try_from(solana_program_entrypoint::HEAP_LENGTH).unwrap(),
-            heap_cost: DEFAULT_HEAP_COST,
-            mem_op_base_cost: 10,
-            alt_bn128_addition_cost: 334,
-            alt_bn128_multiplication_cost: 3_840,
-            alt_bn128_pairing_one_pair_cost_first: 36_364,
-            alt_bn128_pairing_one_pair_cost_other: 12_121,
-            big_modular_exponentiation_base_cost: 190,
-            big_modular_exponentiation_cost_divisor: 2,
-            poseidon_cost_coefficient_a: 61,
-            poseidon_cost_coefficient_c: 542,
-            get_remaining_compute_units_cost: 100,
-            alt_bn128_g1_compress: 30,
-            alt_bn128_g1_decompress: 398,
-            alt_bn128_g2_compress: 86,
-            alt_bn128_g2_decompress: 13610,
+    pub fn to_budget(&self) -> SVMTransactionExecutionBudget {
+        SVMTransactionExecutionBudget {
+            compute_unit_limit: self.compute_unit_limit,
+            max_instruction_stack_depth: self.max_instruction_stack_depth,
+            max_instruction_trace_length: self.max_instruction_trace_length,
+            sha256_max_slices: self.sha256_max_slices,
+            max_call_depth: self.max_call_depth,
+            stack_frame_size: self.stack_frame_size,
+            max_cpi_instruction_size: self.max_cpi_instruction_size,
+            heap_size: self.heap_size,
+        }
+    }
+
+    pub fn to_cost(&self) -> SVMTransactionExecutionCost {
+        SVMTransactionExecutionCost {
+            log_64_units: self.log_64_units,
+            create_program_address_units: self.create_program_address_units,
+            invoke_units: self.invoke_units,
+            sha256_base_cost: self.sha256_base_cost,
+            sha256_byte_cost: self.sha256_byte_cost,
+            log_pubkey_units: self.log_pubkey_units,
+            cpi_bytes_per_unit: self.cpi_bytes_per_unit,
+            sysvar_base_cost: self.sysvar_base_cost,
+            secp256k1_recover_cost: self.secp256k1_recover_cost,
+            syscall_base_cost: self.syscall_base_cost,
+            curve25519_edwards_validate_point_cost: self.curve25519_edwards_validate_point_cost,
+            curve25519_edwards_add_cost: self.curve25519_edwards_add_cost,
+            curve25519_edwards_subtract_cost: self.curve25519_edwards_subtract_cost,
+            curve25519_edwards_multiply_cost: self.curve25519_edwards_multiply_cost,
+            curve25519_edwards_msm_base_cost: self.curve25519_edwards_msm_base_cost,
+            curve25519_edwards_msm_incremental_cost: self.curve25519_edwards_msm_incremental_cost,
+            curve25519_ristretto_validate_point_cost: self.curve25519_ristretto_validate_point_cost,
+            curve25519_ristretto_add_cost: self.curve25519_ristretto_add_cost,
+            curve25519_ristretto_subtract_cost: self.curve25519_ristretto_subtract_cost,
+            curve25519_ristretto_multiply_cost: self.curve25519_ristretto_multiply_cost,
+            curve25519_ristretto_msm_base_cost: self.curve25519_ristretto_msm_base_cost,
+            curve25519_ristretto_msm_incremental_cost: self
+                .curve25519_ristretto_msm_incremental_cost,
+            heap_cost: self.heap_cost,
+            mem_op_base_cost: self.mem_op_base_cost,
+            alt_bn128_addition_cost: self.alt_bn128_addition_cost,
+            alt_bn128_multiplication_cost: self.alt_bn128_multiplication_cost,
+            alt_bn128_pairing_one_pair_cost_first: self.alt_bn128_pairing_one_pair_cost_first,
+            alt_bn128_pairing_one_pair_cost_other: self.alt_bn128_pairing_one_pair_cost_other,
+            big_modular_exponentiation_base_cost: self.big_modular_exponentiation_base_cost,
+            big_modular_exponentiation_cost_divisor: self.big_modular_exponentiation_cost_divisor,
+            poseidon_cost_coefficient_a: self.poseidon_cost_coefficient_a,
+            poseidon_cost_coefficient_c: self.poseidon_cost_coefficient_c,
+            get_remaining_compute_units_cost: self.get_remaining_compute_units_cost,
+            alt_bn128_g1_compress: self.alt_bn128_g1_compress,
+            alt_bn128_g1_decompress: self.alt_bn128_g1_decompress,
+            alt_bn128_g2_compress: self.alt_bn128_g2_compress,
+            alt_bn128_g2_decompress: self.alt_bn128_g2_decompress,
         }
     }
 
-    /// Returns cost of the Poseidon hash function for the given number of
-    /// inputs is determined by the following quadratic function:
-    ///
-    /// 61*n^2 + 542
-    ///
-    /// Which aproximates the results of benchmarks of light-posiedon
-    /// library[0]. These results assume 1 CU per 33 ns. Examples:
-    ///
-    /// * 1 input
-    ///   * light-poseidon benchmark: `18,303 / 33 ≈ 555`
-    ///   * function: `61*1^2 + 542 = 603`
-    /// * 2 inputs
-    ///   * light-poseidon benchmark: `25,866 / 33 ≈ 784`
-    ///   * function: `61*2^2 + 542 = 786`
-    /// * 3 inputs
-    ///   * light-poseidon benchmark: `37,549 / 33 ≈ 1,138`
-    ///   * function; `61*3^2 + 542 = 1091`
-    ///
-    /// [0] https://github.com/Lightprotocol/light-poseidon#performance
-    pub fn poseidon_cost(&self, nr_inputs: u64) -> Option<u64> {
-        let squared_inputs = nr_inputs.checked_pow(2)?;
-        let mul_result = self
-            .poseidon_cost_coefficient_a
-            .checked_mul(squared_inputs)?;
-        let final_result = mul_result.checked_add(self.poseidon_cost_coefficient_c)?;
+    pub fn get_compute_budget_and_limits(
+        &self,
+        compute_budget_limits: &ComputeBudgetLimits,
+    ) -> SVMTransactionExecutionAndFeeBudgetLimits {
+        let fee_budget = FeeBudgetLimits::from(compute_budget_limits);
+        SVMTransactionExecutionAndFeeBudgetLimits {
+            budget: self.to_budget(),
+            loaded_accounts_data_size_limit: fee_budget.loaded_accounts_data_size_limit,
+            priority_fee: fee_budget.prioritization_fee,
+        }
+    }
+}
 
-        Some(final_result)
+impl From<ComputeBudgetLimits> for ComputeBudget {
+    fn from(compute_budget_limits: ComputeBudgetLimits) -> Self {
+        ComputeBudget {
+            compute_unit_limit: u64::from(compute_budget_limits.compute_unit_limit),
+            heap_size: compute_budget_limits.updated_heap_bytes,
+            ..ComputeBudget::default()
+        }
     }
 }

+ 44 - 17
compute-budget/src/compute_budget_limits.rs

@@ -1,29 +1,23 @@
+#[cfg(feature = "dev-context-only-utils")]
+use qualifier_attr::qualifiers;
+pub use solana_program_runtime::execution_budget::{
+    DEFAULT_HEAP_COST, DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT,
+    MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT, MAX_COMPUTE_UNIT_LIMIT, MAX_HEAP_FRAME_BYTES,
+    MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES, MIN_HEAP_FRAME_BYTES,
+};
 use {
-    solana_fee_structure::FeeBudgetLimits, solana_program_entrypoint::HEAP_LENGTH,
+    solana_fee_structure::FeeBudgetLimits,
+    solana_program_runtime::execution_budget::{
+        SVMTransactionExecutionAndFeeBudgetLimits, SVMTransactionExecutionBudget,
+    },
     std::num::NonZeroU32,
 };
 
-/// Roughly 0.5us/page, where page is 32K; given roughly 15CU/us, the
-/// default heap page cost = 0.5 * 15 ~= 8CU/page
-pub const DEFAULT_HEAP_COST: u64 = 8;
-pub const DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT: u32 = 200_000;
-// SIMD-170 defines max CUs to be allocated for any builtin program instructions, that
-// have not been migrated to sBPF programs.
-pub const MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT: u32 = 3_000;
-pub const MAX_COMPUTE_UNIT_LIMIT: u32 = 1_400_000;
-pub const MAX_HEAP_FRAME_BYTES: u32 = 256 * 1024;
-pub const MIN_HEAP_FRAME_BYTES: u32 = HEAP_LENGTH as u32;
-
 type MicroLamports = u128;
 
 /// There are 10^6 micro-lamports in one lamport
 const MICRO_LAMPORTS_PER_LAMPORT: u64 = 1_000_000;
 
-/// The total accounts data a transaction can load is limited to 64MiB to not break
-/// anyone in Mainnet-beta today. It can be set by set_loaded_accounts_data_size_limit instruction
-pub const MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES: NonZeroU32 =
-    unsafe { NonZeroU32::new_unchecked(64 * 1024 * 1024) };
-
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub struct ComputeBudgetLimits {
     pub updated_heap_bytes: u32,
@@ -43,6 +37,25 @@ impl Default for ComputeBudgetLimits {
     }
 }
 
+impl ComputeBudgetLimits {
+    pub fn default_compute_budget_and_limits() -> SVMTransactionExecutionAndFeeBudgetLimits {
+        Self::get_compute_budget_and_limits(&ComputeBudgetLimits::default())
+    }
+
+    pub fn get_compute_budget_and_limits(&self) -> SVMTransactionExecutionAndFeeBudgetLimits {
+        let fee_budget = FeeBudgetLimits::from(self);
+        SVMTransactionExecutionAndFeeBudgetLimits {
+            budget: SVMTransactionExecutionBudget {
+                compute_unit_limit: u64::from(self.compute_unit_limit),
+                heap_size: self.updated_heap_bytes,
+                ..SVMTransactionExecutionBudget::default()
+            },
+            loaded_accounts_data_size_limit: fee_budget.loaded_accounts_data_size_limit,
+            priority_fee: fee_budget.prioritization_fee,
+        }
+    }
+}
+
 fn get_prioritization_fee(compute_unit_price: u64, compute_unit_limit: u64) -> u64 {
     let micro_lamport_fee: MicroLamports =
         (compute_unit_price as u128).saturating_mul(compute_unit_limit as u128);
@@ -67,6 +80,20 @@ impl From<ComputeBudgetLimits> for FeeBudgetLimits {
     }
 }
 
+impl From<&ComputeBudgetLimits> for FeeBudgetLimits {
+    fn from(val: &ComputeBudgetLimits) -> Self {
+        let prioritization_fee =
+            get_prioritization_fee(val.compute_unit_price, u64::from(val.compute_unit_limit));
+
+        FeeBudgetLimits {
+            loaded_accounts_data_size_limit: val.loaded_accounts_bytes,
+            heap_cost: DEFAULT_HEAP_COST,
+            compute_unit_limit: u64::from(val.compute_unit_limit),
+            prioritization_fee,
+        }
+    }
+}
+
 #[cfg(test)]
 mod test {
     use super::*;

+ 0 - 1
core/src/banking_stage/consumer.rs

@@ -631,7 +631,6 @@ impl Consumer {
                 TransactionProcessingConfig {
                     account_overrides: None,
                     check_program_modification_slot: bank.check_program_modification_slot(),
-                    compute_budget: bank.compute_budget(),
                     log_messages_bytes_limit: self.log_messages_bytes_limit,
                     limit_to_load_programs: true,
                     recording_config: ExecutionRecordingConfig::new_single_setting(

+ 1 - 1
core/tests/scheduler_cost_adjustment.rs

@@ -4,7 +4,7 @@ use {
         DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT, MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT,
     },
     solana_cost_model::cost_model::CostModel,
-    solana_feature_set::{self as feature_set},
+    solana_feature_set as feature_set,
     solana_runtime::{bank::Bank, bank_forks::BankForks},
     solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
     solana_sdk::{

+ 2 - 3
program-runtime/Cargo.toml

@@ -20,7 +20,6 @@ rand = { workspace = true }
 serde = { workspace = true }
 solana-account = { workspace = true, features = ["bincode"] }
 solana-clock = { workspace = true }
-solana-compute-budget = { workspace = true }
 solana-epoch-rewards = { workspace = true }
 solana-epoch-schedule = { workspace = true }
 solana-feature-set = { workspace = true }
@@ -55,8 +54,8 @@ thiserror = { workspace = true }
 [dev-dependencies]
 assert_matches = { workspace = true }
 solana-account-info = { workspace = true }
-solana-compute-budget = { workspace = true, features = ["dev-context-only-utils"] }
 solana-instruction = { workspace = true, features = ["bincode"] }
+solana-program-runtime = { path = ".", features = ["dev-context-only-utils"] }
 solana-pubkey = { workspace = true, features = ["rand"] }
 solana-transaction-context = { workspace = true, features = [
     "dev-context-only-utils",
@@ -71,11 +70,11 @@ name = "solana_program_runtime"
 targets = ["x86_64-unknown-linux-gnu"]
 
 [features]
+dev-context-only-utils = []
 dummy-for-ci-check = ["metrics"]
 frozen-abi = [
     "dep:solana-frozen-abi",
     "dep:solana-frozen-abi-macro",
-    "solana-compute-budget/frozen-abi",
 ]
 metrics = ["dep:solana-metrics"]
 shuttle-test = [

+ 251 - 0
program-runtime/src/execution_budget.rs

@@ -0,0 +1,251 @@
+use {solana_program_entrypoint::HEAP_LENGTH, std::num::NonZeroU32};
+
+/// Max instruction stack depth. This is the maximum nesting of instructions that can happen during
+/// a transaction.
+pub const MAX_INSTRUCTION_STACK_DEPTH: usize = 5;
+
+/// Max call depth. This is the maximum nesting of SBF to SBF call that can happen within a program.
+pub const MAX_CALL_DEPTH: usize = 64;
+
+/// The size of one SBF stack frame.
+pub const STACK_FRAME_SIZE: usize = 4096;
+
+pub const MAX_COMPUTE_UNIT_LIMIT: u32 = 1_400_000;
+
+/// Roughly 0.5us/page, where page is 32K; given roughly 15CU/us, the
+/// default heap page cost = 0.5 * 15 ~= 8CU/page
+pub const DEFAULT_HEAP_COST: u64 = 8;
+pub const DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT: u32 = 200_000;
+// SIMD-170 defines max CUs to be allocated for any builtin program instructions, that
+// have not been migrated to sBPF programs.
+pub const MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT: u32 = 3_000;
+pub const MAX_HEAP_FRAME_BYTES: u32 = 256 * 1024;
+pub const MIN_HEAP_FRAME_BYTES: u32 = HEAP_LENGTH as u32;
+
+/// The total accounts data a transaction can load is limited to 64MiB to not break
+/// anyone in Mainnet-beta today. It can be set by set_loaded_accounts_data_size_limit instruction
+pub const MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES: NonZeroU32 =
+    unsafe { NonZeroU32::new_unchecked(64 * 1024 * 1024) };
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub struct SVMTransactionExecutionBudget {
+    /// Number of compute units that a transaction or individual instruction is
+    /// allowed to consume. Compute units are consumed by program execution,
+    /// resources they use, etc...
+    pub compute_unit_limit: u64,
+    /// Maximum program instruction invocation stack depth. Invocation stack
+    /// depth starts at 1 for transaction instructions and the stack depth is
+    /// incremented each time a program invokes an instruction and decremented
+    /// when a program returns.
+    pub max_instruction_stack_depth: usize,
+    /// Maximum cross-program invocation and instructions per transaction
+    pub max_instruction_trace_length: usize,
+    /// Maximum number of slices hashed per syscall
+    pub sha256_max_slices: u64,
+    /// Maximum SBF to BPF call depth
+    pub max_call_depth: usize,
+    /// Size of a stack frame in bytes, must match the size specified in the LLVM SBF backend
+    pub stack_frame_size: usize,
+    /// Maximum cross-program invocation instruction size
+    pub max_cpi_instruction_size: usize,
+    /// program heap region size, default: solana_sdk::entrypoint::HEAP_LENGTH
+    pub heap_size: u32,
+}
+
+impl Default for SVMTransactionExecutionBudget {
+    fn default() -> Self {
+        SVMTransactionExecutionBudget {
+            compute_unit_limit: u64::from(MAX_COMPUTE_UNIT_LIMIT),
+            max_instruction_stack_depth: MAX_INSTRUCTION_STACK_DEPTH,
+            max_instruction_trace_length: 64,
+            sha256_max_slices: 20_000,
+            max_call_depth: MAX_CALL_DEPTH,
+            stack_frame_size: STACK_FRAME_SIZE,
+            max_cpi_instruction_size: 1280, // IPv6 Min MTU size
+            heap_size: u32::try_from(solana_program_entrypoint::HEAP_LENGTH).unwrap(),
+        }
+    }
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub struct SVMTransactionExecutionCost {
+    /// Number of compute units consumed by a log_u64 call
+    pub log_64_units: u64,
+    /// Number of compute units consumed by a create_program_address call
+    pub create_program_address_units: u64,
+    /// Number of compute units consumed by an invoke call (not including the cost incurred by
+    /// the called program)
+    pub invoke_units: u64,
+    /// Base number of compute units consumed to call SHA256
+    pub sha256_base_cost: u64,
+    /// Incremental number of units consumed by SHA256 (based on bytes)
+    pub sha256_byte_cost: u64,
+    /// Number of compute units consumed by logging a `Pubkey`
+    pub log_pubkey_units: u64,
+    /// Number of account data bytes per compute unit charged during a cross-program invocation
+    pub cpi_bytes_per_unit: u64,
+    /// Base number of compute units consumed to get a sysvar
+    pub sysvar_base_cost: u64,
+    /// Number of compute units consumed to call secp256k1_recover
+    pub secp256k1_recover_cost: u64,
+    /// Number of compute units consumed to do a syscall without any work
+    pub syscall_base_cost: u64,
+    /// Number of compute units consumed to validate a curve25519 edwards point
+    pub curve25519_edwards_validate_point_cost: u64,
+    /// Number of compute units consumed to add two curve25519 edwards points
+    pub curve25519_edwards_add_cost: u64,
+    /// Number of compute units consumed to subtract two curve25519 edwards points
+    pub curve25519_edwards_subtract_cost: u64,
+    /// Number of compute units consumed to multiply a curve25519 edwards point
+    pub curve25519_edwards_multiply_cost: u64,
+    /// Number of compute units consumed for a multiscalar multiplication (msm) of edwards points.
+    /// The total cost is calculated as `msm_base_cost + (length - 1) * msm_incremental_cost`.
+    pub curve25519_edwards_msm_base_cost: u64,
+    /// Number of compute units consumed for a multiscalar multiplication (msm) of edwards points.
+    /// The total cost is calculated as `msm_base_cost + (length - 1) * msm_incremental_cost`.
+    pub curve25519_edwards_msm_incremental_cost: u64,
+    /// Number of compute units consumed to validate a curve25519 ristretto point
+    pub curve25519_ristretto_validate_point_cost: u64,
+    /// Number of compute units consumed to add two curve25519 ristretto points
+    pub curve25519_ristretto_add_cost: u64,
+    /// Number of compute units consumed to subtract two curve25519 ristretto points
+    pub curve25519_ristretto_subtract_cost: u64,
+    /// Number of compute units consumed to multiply a curve25519 ristretto point
+    pub curve25519_ristretto_multiply_cost: u64,
+    /// Number of compute units consumed for a multiscalar multiplication (msm) of ristretto points.
+    /// The total cost is calculated as `msm_base_cost + (length - 1) * msm_incremental_cost`.
+    pub curve25519_ristretto_msm_base_cost: u64,
+    /// Number of compute units consumed for a multiscalar multiplication (msm) of ristretto points.
+    /// The total cost is calculated as `msm_base_cost + (length - 1) * msm_incremental_cost`.
+    pub curve25519_ristretto_msm_incremental_cost: u64,
+    /// Number of compute units per additional 32k heap above the default (~.5
+    /// us per 32k at 15 units/us rounded up)
+    pub heap_cost: u64,
+    /// Memory operation syscall base cost
+    pub mem_op_base_cost: u64,
+    /// Number of compute units consumed to call alt_bn128_addition
+    pub alt_bn128_addition_cost: u64,
+    /// Number of compute units consumed to call alt_bn128_multiplication.
+    pub alt_bn128_multiplication_cost: u64,
+    /// Total cost will be alt_bn128_pairing_one_pair_cost_first
+    /// + alt_bn128_pairing_one_pair_cost_other * (num_elems - 1)
+    pub alt_bn128_pairing_one_pair_cost_first: u64,
+    pub alt_bn128_pairing_one_pair_cost_other: u64,
+    /// Big integer modular exponentiation base cost
+    pub big_modular_exponentiation_base_cost: u64,
+    /// Big integer moduler exponentiation cost divisor
+    /// The modular exponentiation cost is computed as
+    /// `input_length`/`big_modular_exponentiation_cost_divisor` + `big_modular_exponentiation_base_cost`
+    pub big_modular_exponentiation_cost_divisor: u64,
+    /// Coefficient `a` of the quadratic function which determines the number
+    /// of compute units consumed to call poseidon syscall for a given number
+    /// of inputs.
+    pub poseidon_cost_coefficient_a: u64,
+    /// Coefficient `c` of the quadratic function which determines the number
+    /// of compute units consumed to call poseidon syscall for a given number
+    /// of inputs.
+    pub poseidon_cost_coefficient_c: u64,
+    /// Number of compute units consumed for accessing the remaining compute units.
+    pub get_remaining_compute_units_cost: u64,
+    /// Number of compute units consumed to call alt_bn128_g1_compress.
+    pub alt_bn128_g1_compress: u64,
+    /// Number of compute units consumed to call alt_bn128_g1_decompress.
+    pub alt_bn128_g1_decompress: u64,
+    /// Number of compute units consumed to call alt_bn128_g2_compress.
+    pub alt_bn128_g2_compress: u64,
+    /// Number of compute units consumed to call alt_bn128_g2_decompress.
+    pub alt_bn128_g2_decompress: u64,
+}
+
+impl Default for SVMTransactionExecutionCost {
+    fn default() -> Self {
+        Self {
+            log_64_units: 100,
+            create_program_address_units: 1500,
+            invoke_units: 1000,
+            sha256_base_cost: 85,
+            sha256_byte_cost: 1,
+            log_pubkey_units: 100,
+            cpi_bytes_per_unit: 250, // ~50MB at 200,000 units
+            sysvar_base_cost: 100,
+            secp256k1_recover_cost: 25_000,
+            syscall_base_cost: 100,
+            curve25519_edwards_validate_point_cost: 159,
+            curve25519_edwards_add_cost: 473,
+            curve25519_edwards_subtract_cost: 475,
+            curve25519_edwards_multiply_cost: 2_177,
+            curve25519_edwards_msm_base_cost: 2_273,
+            curve25519_edwards_msm_incremental_cost: 758,
+            curve25519_ristretto_validate_point_cost: 169,
+            curve25519_ristretto_add_cost: 521,
+            curve25519_ristretto_subtract_cost: 519,
+            curve25519_ristretto_multiply_cost: 2_208,
+            curve25519_ristretto_msm_base_cost: 2303,
+            curve25519_ristretto_msm_incremental_cost: 788,
+            heap_cost: DEFAULT_HEAP_COST,
+            mem_op_base_cost: 10,
+            alt_bn128_addition_cost: 334,
+            alt_bn128_multiplication_cost: 3_840,
+            alt_bn128_pairing_one_pair_cost_first: 36_364,
+            alt_bn128_pairing_one_pair_cost_other: 12_121,
+            big_modular_exponentiation_base_cost: 190,
+            big_modular_exponentiation_cost_divisor: 2,
+            poseidon_cost_coefficient_a: 61,
+            poseidon_cost_coefficient_c: 542,
+            get_remaining_compute_units_cost: 100,
+            alt_bn128_g1_compress: 30,
+            alt_bn128_g1_decompress: 398,
+            alt_bn128_g2_compress: 86,
+            alt_bn128_g2_decompress: 13610,
+        }
+    }
+}
+
+impl SVMTransactionExecutionCost {
+    /// Returns cost of the Poseidon hash function for the given number of
+    /// inputs is determined by the following quadratic function:
+    ///
+    /// 61*n^2 + 542
+    ///
+    /// Which aproximates the results of benchmarks of light-posiedon
+    /// library[0]. These results assume 1 CU per 33 ns. Examples:
+    ///
+    /// * 1 input
+    ///   * light-poseidon benchmark: `18,303 / 33 ≈ 555`
+    ///   * function: `61*1^2 + 542 = 603`
+    /// * 2 inputs
+    ///   * light-poseidon benchmark: `25,866 / 33 ≈ 784`
+    ///   * function: `61*2^2 + 542 = 786`
+    /// * 3 inputs
+    ///   * light-poseidon benchmark: `37,549 / 33 ≈ 1,138`
+    ///   * function; `61*3^2 + 542 = 1091`
+    ///
+    /// [0] https://github.com/Lightprotocol/light-poseidon#performance
+    pub fn poseidon_cost(&self, nr_inputs: u64) -> Option<u64> {
+        let squared_inputs = nr_inputs.checked_pow(2)?;
+        let mul_result = self
+            .poseidon_cost_coefficient_a
+            .checked_mul(squared_inputs)?;
+        let final_result = mul_result.checked_add(self.poseidon_cost_coefficient_c)?;
+
+        Some(final_result)
+    }
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub struct SVMTransactionExecutionAndFeeBudgetLimits {
+    pub budget: SVMTransactionExecutionBudget,
+    pub loaded_accounts_data_size_limit: NonZeroU32,
+    pub priority_fee: u64,
+}
+
+#[cfg(feature = "dev-context-only-utils")]
+impl Default for SVMTransactionExecutionAndFeeBudgetLimits {
+    fn default() -> Self {
+        Self {
+            budget: SVMTransactionExecutionBudget::default(),
+            loaded_accounts_data_size_limit: MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES,
+            priority_fee: 0,
+        }
+    }
+}

+ 25 - 18
program-runtime/src/invoke_context.rs

@@ -1,5 +1,6 @@
 use {
     crate::{
+        execution_budget::{SVMTransactionExecutionBudget, SVMTransactionExecutionCost},
         loaded_programs::{
             ProgramCacheEntry, ProgramCacheEntryType, ProgramCacheForTxBatch,
             ProgramRuntimeEnvironments,
@@ -9,7 +10,6 @@ use {
     },
     solana_account::{create_account_shared_data_for_test, AccountSharedData},
     solana_clock::Slot,
-    solana_compute_budget::compute_budget::ComputeBudget,
     solana_epoch_schedule::EpochSchedule,
     solana_feature_set::{
         lift_cpi_caller_restriction, move_precompile_verification_to_svm,
@@ -196,7 +196,9 @@ pub struct InvokeContext<'a> {
     /// Runtime configurations used to provision the invocation environment.
     pub environment_config: EnvironmentConfig<'a>,
     /// The compute budget for the current invocation.
-    compute_budget: ComputeBudget,
+    compute_budget: SVMTransactionExecutionBudget,
+    /// The compute cost for the current invocation.
+    execution_cost: SVMTransactionExecutionCost,
     /// Instruction compute meter, for tracking compute units consumed against
     /// the designated compute budget during program execution.
     compute_meter: RefCell<u64>,
@@ -215,7 +217,8 @@ impl<'a> InvokeContext<'a> {
         program_cache_for_tx_batch: &'a mut ProgramCacheForTxBatch,
         environment_config: EnvironmentConfig<'a>,
         log_collector: Option<Rc<RefCell<LogCollector>>>,
-        compute_budget: ComputeBudget,
+        compute_budget: SVMTransactionExecutionBudget,
+        execution_cost: SVMTransactionExecutionCost,
     ) -> Self {
         Self {
             transaction_context,
@@ -223,6 +226,7 @@ impl<'a> InvokeContext<'a> {
             environment_config,
             log_collector,
             compute_budget,
+            execution_cost,
             compute_meter: RefCell::new(compute_budget.compute_unit_limit),
             execute_time: None,
             timings: ExecuteDetailsTimings::default(),
@@ -642,10 +646,15 @@ impl<'a> InvokeContext<'a> {
     }
 
     /// Get this invocation's compute budget
-    pub fn get_compute_budget(&self) -> &ComputeBudget {
+    pub fn get_compute_budget(&self) -> &SVMTransactionExecutionBudget {
         &self.compute_budget
     }
 
+    /// Get this invocation's compute budget
+    pub fn get_execution_cost(&self) -> &SVMTransactionExecutionCost {
+        &self.execution_cost
+    }
+
     /// Get the current feature set.
     pub fn get_feature_set(&self) -> &FeatureSet {
         &self.environment_config.feature_set
@@ -731,18 +740,18 @@ macro_rules! with_mock_invoke_context {
         $transaction_accounts:expr $(,)?
     ) => {
         use {
-            solana_compute_budget::compute_budget::ComputeBudget,
             solana_feature_set::FeatureSet,
             solana_log_collector::LogCollector,
             solana_type_overrides::sync::Arc,
             $crate::{
                 __private::{Hash, ReadableAccount, Rent, TransactionContext},
+                execution_budget::{SVMTransactionExecutionBudget, SVMTransactionExecutionCost},
                 invoke_context::{EnvironmentConfig, InvokeContext},
                 loaded_programs::ProgramCacheForTxBatch,
                 sysvar_cache::SysvarCache,
             },
         };
-        let compute_budget = ComputeBudget::default();
+        let compute_budget = SVMTransactionExecutionBudget::default();
         let mut $transaction_context = TransactionContext::new(
             $transaction_accounts,
             Rent::default(),
@@ -782,6 +791,7 @@ macro_rules! with_mock_invoke_context {
             environment_config,
             Some(LogCollector::new_ref()),
             compute_budget,
+            SVMTransactionExecutionCost::default(),
         );
     };
 }
@@ -867,9 +877,9 @@ pub fn mock_process_instruction<F: FnMut(&mut InvokeContext), G: FnMut(&mut Invo
 mod tests {
     use {
         super::*,
+        crate::execution_budget::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT,
         serde::{Deserialize, Serialize},
         solana_account::WritableAccount,
-        solana_compute_budget::compute_budget_limits,
         solana_instruction::Instruction,
         solana_rent::Rent,
     };
@@ -996,7 +1006,7 @@ mod tests {
 
     #[test]
     fn test_instruction_stack_height() {
-        let one_more_than_max_depth = ComputeBudget::default()
+        let one_more_than_max_depth = SVMTransactionExecutionBudget::default()
             .max_instruction_stack_depth
             .saturating_add(1);
         let mut invoke_stack = vec![];
@@ -1032,7 +1042,7 @@ mod tests {
         with_mock_invoke_context!(invoke_context, transaction_context, transaction_accounts);
 
         // Check call depth increases and has a limit
-        let mut depth_reached = 0;
+        let mut depth_reached: usize = 0;
         for _ in 0..invoke_stack.len() {
             invoke_context
                 .transaction_context
@@ -1194,11 +1204,13 @@ mod tests {
     #[test]
     fn test_invoke_context_compute_budget() {
         let transaction_accounts = vec![(solana_pubkey::new_rand(), AccountSharedData::default())];
+        let execution_budget = SVMTransactionExecutionBudget {
+            compute_unit_limit: u64::from(DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT),
+            ..SVMTransactionExecutionBudget::default()
+        };
 
         with_mock_invoke_context!(invoke_context, transaction_context, transaction_accounts);
-        invoke_context.compute_budget = ComputeBudget::new(
-            compute_budget_limits::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT as u64,
-        );
+        invoke_context.compute_budget = execution_budget;
 
         invoke_context
             .transaction_context
@@ -1206,12 +1218,7 @@ mod tests {
             .unwrap()
             .configure(&[0], &[], &[]);
         invoke_context.push().unwrap();
-        assert_eq!(
-            *invoke_context.get_compute_budget(),
-            ComputeBudget::new(
-                compute_budget_limits::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT as u64
-            )
-        );
+        assert_eq!(*invoke_context.get_compute_budget(), execution_budget);
         invoke_context.pop().unwrap();
     }
 

+ 2 - 0
program-runtime/src/lib.rs

@@ -7,12 +7,14 @@
 extern crate solana_metrics;
 
 pub use solana_sbpf;
+pub mod execution_budget;
 pub mod invoke_context;
 pub mod loaded_programs;
 pub mod mem_pool;
 pub mod serialization;
 pub mod stable_log;
 pub mod sysvar_cache;
+
 // re-exports for macros
 pub mod __private {
     pub use {

+ 3 - 3
program-runtime/src/mem_pool.rs

@@ -1,7 +1,7 @@
 use {
-    solana_compute_budget::{
-        compute_budget::{MAX_CALL_DEPTH, MAX_INSTRUCTION_STACK_DEPTH, STACK_FRAME_SIZE},
-        compute_budget_limits::{MAX_HEAP_FRAME_BYTES, MIN_HEAP_FRAME_BYTES},
+    crate::execution_budget::{
+        MAX_CALL_DEPTH, MAX_HEAP_FRAME_BYTES, MAX_INSTRUCTION_STACK_DEPTH, MIN_HEAP_FRAME_BYTES,
+        STACK_FRAME_SIZE,
     },
     solana_sbpf::{aligned_memory::AlignedMemory, ebpf::HOST_ALIGN},
     std::array,

+ 1 - 1
program-test/src/lib.rs

@@ -218,7 +218,7 @@ fn get_sysvar<T: Default + Sysvar + Sized + serde::de::DeserializeOwned + Clone>
 ) -> u64 {
     let invoke_context = get_invoke_context();
     if invoke_context
-        .consume_checked(invoke_context.get_compute_budget().sysvar_base_cost + T::size_of() as u64)
+        .consume_checked(invoke_context.get_execution_cost().sysvar_base_cost + T::size_of() as u64)
         .is_err()
     {
         panic!("Exceeded compute budget");

+ 0 - 1
programs/bpf_loader/Cargo.toml

@@ -22,7 +22,6 @@ solana-bincode = { workspace = true }
 solana-blake3-hasher = { workspace = true }
 solana-bn254 = { workspace = true }
 solana-clock = { workspace = true }
-solana-compute-budget = { workspace = true }
 solana-cpi = { workspace = true }
 solana-curve25519 = { workspace = true }
 solana-feature-set = { workspace = true }

+ 2 - 2
programs/bpf_loader/src/lib.rs

@@ -9,7 +9,6 @@ use {
     solana_account::WritableAccount,
     solana_bincode::limited_deserialize,
     solana_clock::Slot,
-    solana_compute_budget::compute_budget::MAX_INSTRUCTION_STACK_DEPTH,
     solana_feature_set::{
         bpf_account_data_direct_mapping, disable_new_loader_v3_deployments,
         enable_bpf_loader_set_authority_checked_ix, enable_loader_v4,
@@ -23,6 +22,7 @@ use {
     solana_measure::measure::Measure,
     solana_program_entrypoint::{MAX_PERMITTED_DATA_INCREASE, SUCCESS},
     solana_program_runtime::{
+        execution_budget::MAX_INSTRUCTION_STACK_DEPTH,
         invoke_context::{BpfAllocator, InvokeContext, SerializedAccountMetadata, SyscallContext},
         loaded_programs::{
             LoadProgramMetrics, ProgramCacheEntry, ProgramCacheEntryOwner, ProgramCacheEntryType,
@@ -299,7 +299,7 @@ macro_rules! create_vm {
         let heap_size = invoke_context.get_compute_budget().heap_size;
         let heap_cost_result = invoke_context.consume_checked($crate::calculate_heap_cost(
             heap_size,
-            invoke_context.get_compute_budget().heap_cost,
+            invoke_context.get_execution_cost().heap_cost,
         ));
         let $vm = heap_cost_result.and_then(|_| {
             let (mut stack, mut heap) = $crate::MEMORY_POOL

+ 6 - 6
programs/bpf_loader/src/syscalls/cpi.rs

@@ -195,7 +195,7 @@ impl<'a, 'b> CallerAccount<'a, 'b> {
             consume_compute_meter(
                 invoke_context,
                 (data.len() as u64)
-                    .checked_div(invoke_context.get_compute_budget().cpi_bytes_per_unit)
+                    .checked_div(invoke_context.get_execution_cost().cpi_bytes_per_unit)
                     .unwrap_or(u64::MAX),
             )?;
 
@@ -319,7 +319,7 @@ impl<'a, 'b> CallerAccount<'a, 'b> {
             invoke_context,
             account_info
                 .data_len
-                .checked_div(invoke_context.get_compute_budget().cpi_bytes_per_unit)
+                .checked_div(invoke_context.get_execution_cost().cpi_bytes_per_unit)
                 .unwrap_or(u64::MAX),
         )?;
 
@@ -468,7 +468,7 @@ impl SyscallInvokeSigned for SyscallInvokeSignedRust {
             consume_compute_meter(
                 invoke_context,
                 (data.len() as u64)
-                    .checked_div(invoke_context.get_compute_budget().cpi_bytes_per_unit)
+                    .checked_div(invoke_context.get_execution_cost().cpi_bytes_per_unit)
                     .unwrap_or(u64::MAX),
             )?;
         }
@@ -686,7 +686,7 @@ impl SyscallInvokeSigned for SyscallInvokeSignedC {
             consume_compute_meter(
                 invoke_context,
                 (data.len() as u64)
-                    .checked_div(invoke_context.get_compute_budget().cpi_bytes_per_unit)
+                    .checked_div(invoke_context.get_execution_cost().cpi_bytes_per_unit)
                     .unwrap_or(u64::MAX),
             )?;
         }
@@ -910,7 +910,7 @@ where
             consume_compute_meter(
                 invoke_context,
                 (callee_account.get_data().len() as u64)
-                    .checked_div(invoke_context.get_compute_budget().cpi_bytes_per_unit)
+                    .checked_div(invoke_context.get_execution_cost().cpi_bytes_per_unit)
                     .unwrap_or(u64::MAX),
             )?;
 
@@ -1094,7 +1094,7 @@ fn cpi_common<S: SyscallInvokeSigned>(
     // changes so the callee can see them.
     consume_compute_meter(
         invoke_context,
-        invoke_context.get_compute_budget().invoke_units,
+        invoke_context.get_execution_cost().invoke_units,
     )?;
     if let Some(execute_time) = invoke_context.execute_time.as_mut() {
         execute_time.stop();

+ 7 - 7
programs/bpf_loader/src/syscalls/logging.rs

@@ -13,7 +13,7 @@ declare_builtin_function!(
         memory_mapping: &mut MemoryMapping,
     ) -> Result<u64, Error> {
         let cost = invoke_context
-            .get_compute_budget()
+            .get_execution_cost()
             .syscall_base_cost
             .max(len);
         consume_compute_meter(invoke_context, cost)?;
@@ -44,7 +44,7 @@ declare_builtin_function!(
         arg5: u64,
         _memory_mapping: &mut MemoryMapping,
     ) -> Result<u64, Error> {
-        let cost = invoke_context.get_compute_budget().log_64_units;
+        let cost = invoke_context.get_execution_cost().log_64_units;
         consume_compute_meter(invoke_context, cost)?;
 
         stable_log::program_log(
@@ -67,7 +67,7 @@ declare_builtin_function!(
         _arg5: u64,
         _memory_mapping: &mut MemoryMapping,
     ) -> Result<u64, Error> {
-        let cost = invoke_context.get_compute_budget().syscall_base_cost;
+        let cost = invoke_context.get_execution_cost().syscall_base_cost;
         consume_compute_meter(invoke_context, cost)?;
 
         ic_logger_msg!(
@@ -91,7 +91,7 @@ declare_builtin_function!(
         _arg5: u64,
         memory_mapping: &mut MemoryMapping,
     ) -> Result<u64, Error> {
-        let cost = invoke_context.get_compute_budget().log_pubkey_units;
+        let cost = invoke_context.get_execution_cost().log_pubkey_units;
         consume_compute_meter(invoke_context, cost)?;
 
         let pubkey = translate_type::<Pubkey>(
@@ -116,9 +116,9 @@ declare_builtin_function!(
         _arg5: u64,
         memory_mapping: &mut MemoryMapping,
     ) -> Result<u64, Error> {
-        let budget = invoke_context.get_compute_budget();
+        let execution_cost = invoke_context.get_execution_cost();
 
-        consume_compute_meter(invoke_context, budget.syscall_base_cost)?;
+        consume_compute_meter(invoke_context, execution_cost.syscall_base_cost)?;
 
         let untranslated_fields = translate_slice_of_slices::<u8>(
             memory_mapping,
@@ -129,7 +129,7 @@ declare_builtin_function!(
 
         consume_compute_meter(
             invoke_context,
-            budget
+            execution_cost
                 .syscall_base_cost
                 .saturating_mul(untranslated_fields.len() as u64),
         )?;

+ 3 - 3
programs/bpf_loader/src/syscalls/mem_ops.rs

@@ -6,9 +6,9 @@ use {
 };
 
 fn mem_op_consume(invoke_context: &mut InvokeContext, n: u64) -> Result<(), Error> {
-    let compute_budget = invoke_context.get_compute_budget();
-    let cost = compute_budget.mem_op_base_cost.max(
-        n.checked_div(compute_budget.cpi_bytes_per_unit)
+    let compute_cost = invoke_context.get_execution_cost();
+    let cost = compute_cost.mem_op_base_cost.max(
+        n.checked_div(compute_cost.cpi_bytes_per_unit)
             .unwrap_or(u64::MAX),
     );
     consume_compute_meter(invoke_context, cost)

+ 108 - 102
programs/bpf_loader/src/syscalls/mod.rs

@@ -22,7 +22,6 @@ use {
         ALT_BN128_MULTIPLICATION_OUTPUT_LEN, ALT_BN128_PAIRING_ELEMENT_LEN,
         ALT_BN128_PAIRING_OUTPUT_LEN,
     },
-    solana_compute_budget::compute_budget::ComputeBudget,
     solana_cpi::MAX_RETURN_DATA,
     solana_feature_set::{
         self as feature_set, abort_on_invalid_curve, blake3_syscall_enabled,
@@ -42,7 +41,11 @@ use {
     solana_poseidon as poseidon,
     solana_precompiles::is_precompile,
     solana_program_entrypoint::{BPF_ALIGN_OF_U128, MAX_PERMITTED_DATA_INCREASE, SUCCESS},
-    solana_program_runtime::{invoke_context::InvokeContext, stable_log},
+    solana_program_runtime::{
+        execution_budget::{SVMTransactionExecutionBudget, SVMTransactionExecutionCost},
+        invoke_context::InvokeContext,
+        stable_log,
+    },
     solana_pubkey::{Pubkey, PubkeyError, MAX_SEEDS, MAX_SEED_LEN, PUBKEY_BYTES},
     solana_sbpf::{
         declare_builtin_function,
@@ -140,9 +143,9 @@ trait HasherImpl {
     fn create_hasher() -> Self;
     fn hash(&mut self, val: &[u8]);
     fn result(self) -> Self::Output;
-    fn get_base_cost(compute_budget: &ComputeBudget) -> u64;
-    fn get_byte_cost(compute_budget: &ComputeBudget) -> u64;
-    fn get_max_slices(compute_budget: &ComputeBudget) -> u64;
+    fn get_base_cost(compute_cost: &SVMTransactionExecutionCost) -> u64;
+    fn get_byte_cost(compute_cost: &SVMTransactionExecutionCost) -> u64;
+    fn get_max_slices(compute_budget: &SVMTransactionExecutionBudget) -> u64;
 }
 
 struct Sha256Hasher(Hasher);
@@ -165,13 +168,13 @@ impl HasherImpl for Sha256Hasher {
         self.0.result()
     }
 
-    fn get_base_cost(compute_budget: &ComputeBudget) -> u64 {
-        compute_budget.sha256_base_cost
+    fn get_base_cost(compute_cost: &SVMTransactionExecutionCost) -> u64 {
+        compute_cost.sha256_base_cost
     }
-    fn get_byte_cost(compute_budget: &ComputeBudget) -> u64 {
-        compute_budget.sha256_byte_cost
+    fn get_byte_cost(compute_cost: &SVMTransactionExecutionCost) -> u64 {
+        compute_cost.sha256_byte_cost
     }
-    fn get_max_slices(compute_budget: &ComputeBudget) -> u64 {
+    fn get_max_slices(compute_budget: &SVMTransactionExecutionBudget) -> u64 {
         compute_budget.sha256_max_slices
     }
 }
@@ -192,13 +195,13 @@ impl HasherImpl for Blake3Hasher {
         self.0.result()
     }
 
-    fn get_base_cost(compute_budget: &ComputeBudget) -> u64 {
-        compute_budget.sha256_base_cost
+    fn get_base_cost(compute_cost: &SVMTransactionExecutionCost) -> u64 {
+        compute_cost.sha256_base_cost
     }
-    fn get_byte_cost(compute_budget: &ComputeBudget) -> u64 {
-        compute_budget.sha256_byte_cost
+    fn get_byte_cost(compute_cost: &SVMTransactionExecutionCost) -> u64 {
+        compute_cost.sha256_byte_cost
     }
-    fn get_max_slices(compute_budget: &ComputeBudget) -> u64 {
+    fn get_max_slices(compute_budget: &SVMTransactionExecutionBudget) -> u64 {
         compute_budget.sha256_max_slices
     }
 }
@@ -219,13 +222,13 @@ impl HasherImpl for Keccak256Hasher {
         self.0.result()
     }
 
-    fn get_base_cost(compute_budget: &ComputeBudget) -> u64 {
-        compute_budget.sha256_base_cost
+    fn get_base_cost(compute_cost: &SVMTransactionExecutionCost) -> u64 {
+        compute_cost.sha256_base_cost
     }
-    fn get_byte_cost(compute_budget: &ComputeBudget) -> u64 {
-        compute_budget.sha256_byte_cost
+    fn get_byte_cost(compute_cost: &SVMTransactionExecutionCost) -> u64 {
+        compute_cost.sha256_byte_cost
     }
-    fn get_max_slices(compute_budget: &ComputeBudget) -> u64 {
+    fn get_max_slices(compute_budget: &SVMTransactionExecutionBudget) -> u64 {
         compute_budget.sha256_max_slices
     }
 }
@@ -331,7 +334,7 @@ pub(crate) fn morph_into_deployment_environment_v1(
 
 pub fn create_program_runtime_environment_v1<'a>(
     feature_set: &FeatureSet,
-    compute_budget: &ComputeBudget,
+    compute_budget: &SVMTransactionExecutionBudget,
     reject_deployment_of_broken_elfs: bool,
     debugging_features: bool,
 ) -> Result<BuiltinProgram<InvokeContext<'a>>, Error> {
@@ -568,7 +571,7 @@ pub fn create_program_runtime_environment_v1<'a>(
 }
 
 pub fn create_program_runtime_environment_v2<'a>(
-    compute_budget: &ComputeBudget,
+    compute_budget: &SVMTransactionExecutionBudget,
     debugging_features: bool,
 ) -> BuiltinProgram<InvokeContext<'a>> {
     let config = Config {
@@ -886,7 +889,7 @@ declare_builtin_function!(
         memory_mapping: &mut MemoryMapping,
     ) -> Result<u64, Error> {
         let cost = invoke_context
-            .get_compute_budget()
+            .get_execution_cost()
             .create_program_address_units;
         consume_compute_meter(invoke_context, cost)?;
 
@@ -925,7 +928,7 @@ declare_builtin_function!(
         memory_mapping: &mut MemoryMapping,
     ) -> Result<u64, Error> {
         let cost = invoke_context
-            .get_compute_budget()
+            .get_execution_cost()
             .create_program_address_units;
         consume_compute_meter(invoke_context, cost)?;
 
@@ -989,7 +992,7 @@ declare_builtin_function!(
         _arg5: u64,
         memory_mapping: &mut MemoryMapping,
     ) -> Result<u64, Error> {
-        let cost = invoke_context.get_compute_budget().secp256k1_recover_cost;
+        let cost = invoke_context.get_execution_cost().secp256k1_recover_cost;
         consume_compute_meter(invoke_context, cost)?;
 
         let hash = translate_slice::<u8>(
@@ -1054,7 +1057,7 @@ declare_builtin_function!(
         match curve_id {
             CURVE25519_EDWARDS => {
                 let cost = invoke_context
-                    .get_compute_budget()
+                    .get_execution_cost()
                     .curve25519_edwards_validate_point_cost;
                 consume_compute_meter(invoke_context, cost)?;
 
@@ -1072,7 +1075,7 @@ declare_builtin_function!(
             }
             CURVE25519_RISTRETTO => {
                 let cost = invoke_context
-                    .get_compute_budget()
+                    .get_execution_cost()
                     .curve25519_ristretto_validate_point_cost;
                 consume_compute_meter(invoke_context, cost)?;
 
@@ -1121,7 +1124,7 @@ declare_builtin_function!(
             CURVE25519_EDWARDS => match group_op {
                 ADD => {
                     let cost = invoke_context
-                        .get_compute_budget()
+                        .get_execution_cost()
                         .curve25519_edwards_add_cost;
                     consume_compute_meter(invoke_context, cost)?;
 
@@ -1149,7 +1152,7 @@ declare_builtin_function!(
                 }
                 SUB => {
                     let cost = invoke_context
-                        .get_compute_budget()
+                        .get_execution_cost()
                         .curve25519_edwards_subtract_cost;
                     consume_compute_meter(invoke_context, cost)?;
 
@@ -1177,7 +1180,7 @@ declare_builtin_function!(
                 }
                 MUL => {
                     let cost = invoke_context
-                        .get_compute_budget()
+                        .get_execution_cost()
                         .curve25519_edwards_multiply_cost;
                     consume_compute_meter(invoke_context, cost)?;
 
@@ -1218,7 +1221,7 @@ declare_builtin_function!(
             CURVE25519_RISTRETTO => match group_op {
                 ADD => {
                     let cost = invoke_context
-                        .get_compute_budget()
+                        .get_execution_cost()
                         .curve25519_ristretto_add_cost;
                     consume_compute_meter(invoke_context, cost)?;
 
@@ -1246,7 +1249,7 @@ declare_builtin_function!(
                 }
                 SUB => {
                     let cost = invoke_context
-                        .get_compute_budget()
+                        .get_execution_cost()
                         .curve25519_ristretto_subtract_cost;
                     consume_compute_meter(invoke_context, cost)?;
 
@@ -1276,7 +1279,7 @@ declare_builtin_function!(
                 }
                 MUL => {
                     let cost = invoke_context
-                        .get_compute_budget()
+                        .get_execution_cost()
                         .curve25519_ristretto_multiply_cost;
                     consume_compute_meter(invoke_context, cost)?;
 
@@ -1351,11 +1354,11 @@ declare_builtin_function!(
         match curve_id {
             CURVE25519_EDWARDS => {
                 let cost = invoke_context
-                    .get_compute_budget()
+                    .get_execution_cost()
                     .curve25519_edwards_msm_base_cost
                     .saturating_add(
                         invoke_context
-                            .get_compute_budget()
+                            .get_execution_cost()
                             .curve25519_edwards_msm_incremental_cost
                             .saturating_mul(points_len.saturating_sub(1)),
                     );
@@ -1389,11 +1392,11 @@ declare_builtin_function!(
 
             CURVE25519_RISTRETTO => {
                 let cost = invoke_context
-                    .get_compute_budget()
+                    .get_execution_cost()
                     .curve25519_ristretto_msm_base_cost
                     .saturating_add(
                         invoke_context
-                            .get_compute_budget()
+                            .get_execution_cost()
                             .curve25519_ristretto_msm_incremental_cost
                             .saturating_mul(points_len.saturating_sub(1)),
                     );
@@ -1453,12 +1456,12 @@ declare_builtin_function!(
         _arg5: u64,
         memory_mapping: &mut MemoryMapping,
     ) -> Result<u64, Error> {
-        let budget = invoke_context.get_compute_budget();
+        let execution_cost = invoke_context.get_execution_cost();
 
         let cost = len
-            .checked_div(budget.cpi_bytes_per_unit)
+            .checked_div(execution_cost.cpi_bytes_per_unit)
             .unwrap_or(u64::MAX)
-            .saturating_add(budget.syscall_base_cost);
+            .saturating_add(execution_cost.syscall_base_cost);
         consume_compute_meter(invoke_context, cost)?;
 
         if len > MAX_RETURN_DATA as u64 {
@@ -1501,16 +1504,16 @@ declare_builtin_function!(
         _arg5: u64,
         memory_mapping: &mut MemoryMapping,
     ) -> Result<u64, Error> {
-        let budget = invoke_context.get_compute_budget();
+        let execution_cost = invoke_context.get_execution_cost();
 
-        consume_compute_meter(invoke_context, budget.syscall_base_cost)?;
+        consume_compute_meter(invoke_context, execution_cost.syscall_base_cost)?;
 
         let (program_id, return_data) = invoke_context.transaction_context.get_return_data();
         let length = length.min(return_data.len() as u64);
         if length != 0 {
             let cost = length
                 .saturating_add(size_of::<Pubkey>() as u64)
-                .checked_div(budget.cpi_bytes_per_unit)
+                .checked_div(execution_cost.cpi_bytes_per_unit)
                 .unwrap_or(u64::MAX);
             consume_compute_meter(invoke_context, cost)?;
 
@@ -1565,9 +1568,9 @@ declare_builtin_function!(
         accounts_addr: u64,
         memory_mapping: &mut MemoryMapping,
     ) -> Result<u64, Error> {
-        let budget = invoke_context.get_compute_budget();
+        let execution_cost = invoke_context.get_execution_cost();
 
-        consume_compute_meter(invoke_context, budget.syscall_base_cost)?;
+        consume_compute_meter(invoke_context, execution_cost.syscall_base_cost)?;
 
         // Reverse iterate through the instruction trace,
         // ignoring anything except instructions on the same level
@@ -1703,9 +1706,9 @@ declare_builtin_function!(
         _arg5: u64,
         _memory_mapping: &mut MemoryMapping,
     ) -> Result<u64, Error> {
-        let budget = invoke_context.get_compute_budget();
+        let execution_cost = invoke_context.get_execution_cost();
 
-        consume_compute_meter(invoke_context, budget.syscall_base_cost)?;
+        consume_compute_meter(invoke_context, execution_cost.syscall_base_cost)?;
 
         Ok(invoke_context.get_stack_height() as u64)
     }
@@ -1724,28 +1727,28 @@ declare_builtin_function!(
         memory_mapping: &mut MemoryMapping,
     ) -> Result<u64, Error> {
         use solana_bn254::prelude::{ALT_BN128_ADD, ALT_BN128_MUL, ALT_BN128_PAIRING};
-        let budget = invoke_context.get_compute_budget();
+        let execution_cost = invoke_context.get_execution_cost();
         let (cost, output): (u64, usize) = match group_op {
             ALT_BN128_ADD => (
-                budget.alt_bn128_addition_cost,
+                execution_cost.alt_bn128_addition_cost,
                 ALT_BN128_ADDITION_OUTPUT_LEN,
             ),
             ALT_BN128_MUL => (
-                budget.alt_bn128_multiplication_cost,
+                execution_cost.alt_bn128_multiplication_cost,
                 ALT_BN128_MULTIPLICATION_OUTPUT_LEN,
             ),
             ALT_BN128_PAIRING => {
                 let ele_len = input_size
                     .checked_div(ALT_BN128_PAIRING_ELEMENT_LEN as u64)
                     .expect("div by non-zero constant");
-                let cost = budget
+                let cost = execution_cost
                     .alt_bn128_pairing_one_pair_cost_first
                     .saturating_add(
-                        budget
+                        execution_cost
                             .alt_bn128_pairing_one_pair_cost_other
                             .saturating_mul(ele_len.saturating_sub(1)),
                     )
-                    .saturating_add(budget.sha256_base_cost)
+                    .saturating_add(execution_cost.sha256_base_cost)
                     .saturating_add(input_size)
                     .saturating_add(ALT_BN128_PAIRING_OUTPUT_LEN as u64);
                 (cost, ALT_BN128_PAIRING_OUTPUT_LEN)
@@ -1843,16 +1846,16 @@ declare_builtin_function!(
         let input_len: u64 = std::cmp::max(params.base_len, params.exponent_len);
         let input_len: u64 = std::cmp::max(input_len, params.modulus_len);
 
-        let budget = invoke_context.get_compute_budget();
+        let execution_cost = invoke_context.get_execution_cost();
         // the compute units are calculated by the quadratic equation `0.5 input_len^2 + 190`
         consume_compute_meter(
             invoke_context,
-            budget.syscall_base_cost.saturating_add(
+            execution_cost.syscall_base_cost.saturating_add(
                 input_len
                     .saturating_mul(input_len)
-                    .checked_div(budget.big_modular_exponentiation_cost_divisor)
+                    .checked_div(execution_cost.big_modular_exponentiation_cost_divisor)
                     .unwrap_or(u64::MAX)
-                    .saturating_add(budget.big_modular_exponentiation_base_cost),
+                    .saturating_add(execution_cost.big_modular_exponentiation_base_cost),
             ),
         )?;
 
@@ -1915,8 +1918,8 @@ declare_builtin_function!(
             return Err(SyscallError::InvalidLength.into());
         }
 
-        let budget = invoke_context.get_compute_budget();
-        let Some(cost) = budget.poseidon_cost(vals_len) else {
+        let execution_cost = invoke_context.get_execution_cost();
+        let Some(cost) = execution_cost.poseidon_cost(vals_len) else {
             ic_msg!(
                 invoke_context,
                 "Overflow while calculating the compute cost"
@@ -1974,8 +1977,8 @@ declare_builtin_function!(
         _arg5: u64,
         _memory_mapping: &mut MemoryMapping,
     ) -> Result<u64, Error> {
-        let budget = invoke_context.get_compute_budget();
-        consume_compute_meter(invoke_context, budget.syscall_base_cost)?;
+        let execution_cost = invoke_context.get_execution_cost();
+        consume_compute_meter(invoke_context, execution_cost.syscall_base_cost)?;
 
         use solana_sbpf::vm::ContextObject;
         Ok(invoke_context.get_remaining())
@@ -1999,22 +2002,22 @@ declare_builtin_function!(
             alt_bn128_g2_decompress, ALT_BN128_G1_COMPRESS, ALT_BN128_G1_DECOMPRESS,
             ALT_BN128_G2_COMPRESS, ALT_BN128_G2_DECOMPRESS, G1, G1_COMPRESSED, G2, G2_COMPRESSED,
         };
-        let budget = invoke_context.get_compute_budget();
-        let base_cost = budget.syscall_base_cost;
+        let execution_cost = invoke_context.get_execution_cost();
+        let base_cost = execution_cost.syscall_base_cost;
         let (cost, output): (u64, usize) = match op {
             ALT_BN128_G1_COMPRESS => (
-                base_cost.saturating_add(budget.alt_bn128_g1_compress),
+                base_cost.saturating_add(execution_cost.alt_bn128_g1_compress),
                 G1_COMPRESSED,
             ),
             ALT_BN128_G1_DECOMPRESS => {
-                (base_cost.saturating_add(budget.alt_bn128_g1_decompress), G1)
+                (base_cost.saturating_add(execution_cost.alt_bn128_g1_decompress), G1)
             }
             ALT_BN128_G2_COMPRESS => (
-                base_cost.saturating_add(budget.alt_bn128_g2_compress),
+                base_cost.saturating_add(execution_cost.alt_bn128_g2_compress),
                 G2_COMPRESSED,
             ),
             ALT_BN128_G2_DECOMPRESS => {
-                (base_cost.saturating_add(budget.alt_bn128_g2_decompress), G2)
+                (base_cost.saturating_add(execution_cost.alt_bn128_g2_decompress), G2)
             }
             _ => {
                 return Err(SyscallError::InvalidAttribute.into());
@@ -2116,8 +2119,9 @@ declare_builtin_function!(
         memory_mapping: &mut MemoryMapping,
     ) -> Result<u64, Error> {
         let compute_budget = invoke_context.get_compute_budget();
-        let hash_base_cost = H::get_base_cost(compute_budget);
-        let hash_byte_cost = H::get_byte_cost(compute_budget);
+        let compute_cost = invoke_context.get_execution_cost();
+        let hash_base_cost = H::get_base_cost(compute_cost);
+        let hash_byte_cost = H::get_byte_cost(compute_cost);
         let hash_max_slices = H::get_max_slices(compute_budget);
         if hash_max_slices < vals_len {
             ic_msg!(
@@ -2149,7 +2153,7 @@ declare_builtin_function!(
 
             for val in vals.iter() {
                 let bytes = val.translate(memory_mapping, invoke_context.get_check_aligned())?;
-                let cost = compute_budget.mem_op_base_cost.max(
+                let cost = compute_cost.mem_op_base_cost.max(
                     hash_byte_cost.saturating_mul(
                         val.len()
                             .checked_div(2)
@@ -2177,7 +2181,7 @@ declare_builtin_function!(
         _arg5: u64,
         memory_mapping: &mut MemoryMapping,
     ) -> Result<u64, Error> {
-        let compute_budget = invoke_context.get_compute_budget();
+        let compute_cost = invoke_context.get_execution_cost();
 
         if var_addr == 0 {
             // As specified by SIMD-0133: If `var_addr` is a null pointer:
@@ -2187,7 +2191,7 @@ declare_builtin_function!(
             // ```
             // syscall_base
             // ```
-            let compute_units = compute_budget.syscall_base_cost;
+            let compute_units = compute_cost.syscall_base_cost;
             consume_compute_meter(invoke_context, compute_units)?;
             //
             // Control flow:
@@ -2205,14 +2209,14 @@ declare_builtin_function!(
             // ```
             // syscall_base + floor(PUBKEY_BYTES/cpi_bytes_per_unit) + mem_op_base
             // ```
-            let compute_units = compute_budget
+            let compute_units = compute_cost
                 .syscall_base_cost
                 .saturating_add(
                     (PUBKEY_BYTES as u64)
-                        .checked_div(compute_budget.cpi_bytes_per_unit)
+                        .checked_div(compute_cost.cpi_bytes_per_unit)
                         .unwrap_or(u64::MAX),
                 )
-                .saturating_add(compute_budget.mem_op_base_cost);
+                .saturating_add(compute_cost.mem_op_base_cost);
             consume_compute_meter(invoke_context, compute_units)?;
             //
             // Control flow:
@@ -2613,7 +2617,7 @@ mod tests {
     #[test]
     fn test_syscall_sol_log_u64() {
         prepare_mockup!(invoke_context, program_id, bpf_loader::id());
-        let cost = invoke_context.get_compute_budget().log_64_units;
+        let cost = invoke_context.get_execution_cost().log_64_units;
 
         invoke_context.mock_set_remaining(cost);
         let config = Config::default();
@@ -2634,7 +2638,7 @@ mod tests {
     #[test]
     fn test_syscall_sol_pubkey() {
         prepare_mockup!(invoke_context, program_id, bpf_loader::id());
-        let cost = invoke_context.get_compute_budget().log_pubkey_units;
+        let cost = invoke_context.get_execution_cost().log_pubkey_units;
 
         let pubkey = Pubkey::from_str("MoqiU1vryuCGQSxFKA1SZ316JdLEFFhoAu6cKUNk7dN").unwrap();
         let config = Config::default();
@@ -2829,10 +2833,10 @@ mod tests {
         .unwrap();
 
         invoke_context.mock_set_remaining(
-            (invoke_context.get_compute_budget().sha256_base_cost
-                + invoke_context.get_compute_budget().mem_op_base_cost.max(
+            (invoke_context.get_execution_cost().sha256_base_cost
+                + invoke_context.get_execution_cost().mem_op_base_cost.max(
                     invoke_context
-                        .get_compute_budget()
+                        .get_execution_cost()
                         .sha256_byte_cost
                         .saturating_mul((bytes1.len() + bytes2.len()) as u64 / 2),
                 ))
@@ -2928,7 +2932,7 @@ mod tests {
 
         invoke_context.mock_set_remaining(
             (invoke_context
-                .get_compute_budget()
+                .get_execution_cost()
                 .curve25519_edwards_validate_point_cost)
                 * 2,
         );
@@ -3001,7 +3005,7 @@ mod tests {
 
         invoke_context.mock_set_remaining(
             (invoke_context
-                .get_compute_budget()
+                .get_execution_cost()
                 .curve25519_ristretto_validate_point_cost)
                 * 2,
         );
@@ -3088,13 +3092,13 @@ mod tests {
 
         invoke_context.mock_set_remaining(
             (invoke_context
-                .get_compute_budget()
+                .get_execution_cost()
                 .curve25519_edwards_add_cost
                 + invoke_context
-                    .get_compute_budget()
+                    .get_execution_cost()
                     .curve25519_edwards_subtract_cost
                 + invoke_context
-                    .get_compute_budget()
+                    .get_execution_cost()
                     .curve25519_edwards_multiply_cost)
                 * 2,
         );
@@ -3243,13 +3247,13 @@ mod tests {
 
         invoke_context.mock_set_remaining(
             (invoke_context
-                .get_compute_budget()
+                .get_execution_cost()
                 .curve25519_ristretto_add_cost
                 + invoke_context
-                    .get_compute_budget()
+                    .get_execution_cost()
                     .curve25519_ristretto_subtract_cost
                 + invoke_context
-                    .get_compute_budget()
+                    .get_execution_cost()
                     .curve25519_ristretto_multiply_cost)
                 * 2,
         );
@@ -3413,16 +3417,16 @@ mod tests {
 
         invoke_context.mock_set_remaining(
             invoke_context
-                .get_compute_budget()
+                .get_execution_cost()
                 .curve25519_edwards_msm_base_cost
                 + invoke_context
-                    .get_compute_budget()
+                    .get_execution_cost()
                     .curve25519_edwards_msm_incremental_cost
                 + invoke_context
-                    .get_compute_budget()
+                    .get_execution_cost()
                     .curve25519_ristretto_msm_base_cost
                 + invoke_context
-                    .get_compute_budget()
+                    .get_execution_cost()
                     .curve25519_ristretto_msm_incremental_cost,
         );
 
@@ -4511,7 +4515,7 @@ mod tests {
             }
         }
 
-        let syscall_base_cost = invoke_context.get_compute_budget().syscall_base_cost;
+        let syscall_base_cost = invoke_context.get_execution_cost().syscall_base_cost;
 
         const VM_BASE_ADDRESS: u64 = 0x100000000;
         const META_OFFSET: usize = 0;
@@ -4722,7 +4726,7 @@ mod tests {
     fn test_find_program_address() {
         prepare_mockup!(invoke_context, program_id, bpf_loader::id());
         let cost = invoke_context
-            .get_compute_budget()
+            .get_execution_cost()
             .create_program_address_units;
         let address = bpf_loader_upgradeable::id();
         let max_tries = 256; // one per seed
@@ -4835,7 +4839,7 @@ mod tests {
             )
             .unwrap();
 
-            let budget = invoke_context.get_compute_budget();
+            let budget = invoke_context.get_execution_cost();
             invoke_context.mock_set_remaining(
                 budget.syscall_base_cost
                     + (MAX_LEN * MAX_LEN) / budget.big_modular_exponentiation_cost_divisor
@@ -4877,7 +4881,7 @@ mod tests {
             )
             .unwrap();
 
-            let budget = invoke_context.get_compute_budget();
+            let budget = invoke_context.get_execution_cost();
             invoke_context.mock_set_remaining(
                 budget.syscall_base_cost
                     + (INV_LEN * INV_LEN) / budget.big_modular_exponentiation_cost_divisor
@@ -4904,13 +4908,14 @@ mod tests {
     #[test]
     fn test_syscall_get_epoch_stake_total_stake() {
         let config = Config::default();
-        let mut compute_budget = ComputeBudget::default();
+        let compute_cost = SVMTransactionExecutionCost::default();
+        let mut compute_budget = SVMTransactionExecutionBudget::default();
         let sysvar_cache = Arc::<SysvarCache>::default();
 
         let expected_total_stake = 200_000_000_000_000u64;
         // Compute units, as specified by SIMD-0133.
         // cu = syscall_base_cost
-        let expected_cus = compute_budget.syscall_base_cost;
+        let expected_cus = compute_cost.syscall_base_cost;
 
         // Set the compute budget to the expected CUs to ensure the syscall
         // doesn't exceed the expected usage.
@@ -4947,7 +4952,8 @@ mod tests {
     #[test]
     fn test_syscall_get_epoch_stake_vote_account_stake() {
         let config = Config::default();
-        let mut compute_budget = ComputeBudget::default();
+        let mut compute_budget = SVMTransactionExecutionBudget::default();
+        let compute_cost = SVMTransactionExecutionCost::default();
         let sysvar_cache = Arc::<SysvarCache>::default();
 
         let expected_epoch_stake = 55_000_000_000u64;
@@ -4955,9 +4961,9 @@ mod tests {
         // cu = syscall_base_cost
         //     + floor(32/cpi_bytes_per_unit)
         //     + mem_op_base_cost
-        let expected_cus = compute_budget.syscall_base_cost
-            + (PUBKEY_BYTES as u64) / compute_budget.cpi_bytes_per_unit
-            + compute_budget.mem_op_base_cost;
+        let expected_cus = compute_cost.syscall_base_cost
+            + (PUBKEY_BYTES as u64) / compute_cost.cpi_bytes_per_unit
+            + compute_cost.mem_op_base_cost;
 
         // Set the compute budget to the expected CUs to ensure the syscall
         // doesn't exceed the expected usage.

+ 4 - 4
programs/bpf_loader/src/syscalls/sysvar.rs

@@ -1,4 +1,4 @@
-use super::*;
+use {super::*, solana_program_runtime::execution_budget::SVMTransactionExecutionCost};
 
 fn get_sysvar<T: std::fmt::Debug + Sysvar + SysvarId + Clone>(
     sysvar: Result<Arc<T>, InstructionError>,
@@ -10,7 +10,7 @@ fn get_sysvar<T: std::fmt::Debug + Sysvar + SysvarId + Clone>(
     consume_compute_meter(
         invoke_context,
         invoke_context
-            .get_compute_budget()
+            .get_execution_cost()
             .sysvar_base_cost
             .saturating_add(size_of::<T>() as u64),
     )?;
@@ -179,12 +179,12 @@ declare_builtin_function!(
         memory_mapping: &mut MemoryMapping,
     ) -> Result<u64, Error> {
         let check_aligned = invoke_context.get_check_aligned();
-        let ComputeBudget {
+        let SVMTransactionExecutionCost {
             sysvar_base_cost,
             cpi_bytes_per_unit,
             mem_op_base_cost,
             ..
-        } = *invoke_context.get_compute_budget();
+        } = *invoke_context.get_execution_cost();
 
         // Abort: "Compute budget is exceeded."
         let sysvar_id_cost = 32_u64.checked_div(cpi_bytes_per_unit).unwrap_or(0);

+ 0 - 1
programs/loader-v4/Cargo.toml

@@ -14,7 +14,6 @@ qualifier_attr = { workspace = true }
 solana-account = { workspace = true }
 solana-bincode = { workspace = true }
 solana-bpf-loader-program = { workspace = true, features = ["svm-internal"] }
-solana-compute-budget = { workspace = true }
 solana-instruction = { workspace = true }
 solana-loader-v3-interface = { workspace = true }
 solana-loader-v4-interface = { workspace = true, features = ["serde"] }

+ 1 - 5
programs/sbf/Cargo.lock

@@ -5447,7 +5447,6 @@ dependencies = [
  "solana-blake3-hasher",
  "solana-bn254",
  "solana-clock",
- "solana-compute-budget",
  "solana-cpi",
  "solana-curve25519",
  "solana-feature-set",
@@ -5723,7 +5722,7 @@ name = "solana-compute-budget"
 version = "2.3.0"
 dependencies = [
  "solana-fee-structure",
- "solana-program-entrypoint",
+ "solana-program-runtime",
 ]
 
 [[package]]
@@ -6607,7 +6606,6 @@ dependencies = [
  "solana-account",
  "solana-bincode",
  "solana-bpf-loader-program",
- "solana-compute-budget",
  "solana-instruction",
  "solana-loader-v3-interface",
  "solana-loader-v4-interface",
@@ -7046,7 +7044,6 @@ dependencies = [
  "serde",
  "solana-account",
  "solana-clock",
- "solana-compute-budget",
  "solana-epoch-rewards",
  "solana-epoch-schedule",
  "solana-feature-set",
@@ -8531,7 +8528,6 @@ dependencies = [
  "solana-account",
  "solana-bpf-loader-program",
  "solana-clock",
- "solana-compute-budget",
  "solana-feature-set",
  "solana-fee-structure",
  "solana-hash",

+ 8 - 6
programs/sbf/benches/bpf_loader.rs

@@ -17,10 +17,12 @@ extern crate test;
 use {
     byteorder::{ByteOrder, LittleEndian, WriteBytesExt},
     solana_bpf_loader_program::{create_vm, syscalls::create_program_runtime_environment_v1},
-    solana_compute_budget::compute_budget::ComputeBudget,
     solana_feature_set::FeatureSet,
     solana_measure::measure::Measure,
-    solana_program_runtime::{invoke_context::InvokeContext, serialization::serialize_parameters},
+    solana_program_runtime::{
+        execution_budget::SVMTransactionExecutionBudget, invoke_context::InvokeContext,
+        serialization::serialize_parameters,
+    },
     solana_runtime::{
         bank::Bank,
         bank_client::BankClient,
@@ -91,7 +93,7 @@ fn bench_program_create_executable(bencher: &mut Bencher) {
 
     let program_runtime_environment = create_program_runtime_environment_v1(
         &FeatureSet::default(),
-        &ComputeBudget::default(),
+        &SVMTransactionExecutionBudget::default(),
         true,
         false,
     );
@@ -117,7 +119,7 @@ fn bench_program_alu(bencher: &mut Bencher) {
 
     let program_runtime_environment = create_program_runtime_environment_v1(
         invoke_context.get_feature_set(),
-        &ComputeBudget::default(),
+        &SVMTransactionExecutionBudget::default(),
         true,
         false,
     );
@@ -236,7 +238,7 @@ fn bench_create_vm(bencher: &mut Bencher) {
         .is_active(&bpf_account_data_direct_mapping::id());
     let program_runtime_environment = create_program_runtime_environment_v1(
         invoke_context.get_feature_set(),
-        &ComputeBudget::default(),
+        &SVMTransactionExecutionBudget::default(),
         true,
         false,
     );
@@ -293,7 +295,7 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
 
     let program_runtime_environment = create_program_runtime_environment_v1(
         invoke_context.get_feature_set(),
-        &ComputeBudget::default(),
+        &SVMTransactionExecutionBudget::default(),
         true,
         false,
     );

+ 6 - 6
runtime/src/account_saver.rs

@@ -177,7 +177,7 @@ fn collect_accounts_for_failed_tx<'a, T: SVMMessage>(
 mod tests {
     use {
         super::*,
-        solana_compute_budget::compute_budget_limits::ComputeBudgetLimits,
+        solana_program_runtime::execution_budget::SVMTransactionExecutionBudget,
         solana_sdk::{
             account::{AccountSharedData, ReadableAccount},
             fee::FeeDetails,
@@ -279,7 +279,7 @@ mod tests {
             program_indices: vec![],
             fee_details: FeeDetails::default(),
             rollback_accounts: RollbackAccounts::default(),
-            compute_budget_limits: ComputeBudgetLimits::default(),
+            compute_budget: SVMTransactionExecutionBudget::default(),
             rent: 0,
             rent_debits: RentDebits::default(),
             loaded_accounts_data_size: 0,
@@ -290,7 +290,7 @@ mod tests {
             program_indices: vec![],
             fee_details: FeeDetails::default(),
             rollback_accounts: RollbackAccounts::default(),
-            compute_budget_limits: ComputeBudgetLimits::default(),
+            compute_budget: SVMTransactionExecutionBudget::default(),
             rent: 0,
             rent_debits: RentDebits::default(),
             loaded_accounts_data_size: 0,
@@ -353,7 +353,7 @@ mod tests {
             rollback_accounts: RollbackAccounts::FeePayerOnly {
                 fee_payer_account: from_account_pre.clone(),
             },
-            compute_budget_limits: ComputeBudgetLimits::default(),
+            compute_budget: SVMTransactionExecutionBudget::default(),
             rent: 0,
             rent_debits: RentDebits::default(),
             loaded_accounts_data_size: 0,
@@ -448,7 +448,7 @@ mod tests {
                 nonce: nonce.clone(),
                 fee_payer_account: from_account_pre.clone(),
             },
-            compute_budget_limits: ComputeBudgetLimits::default(),
+            compute_budget: SVMTransactionExecutionBudget::default(),
             rent: 0,
             rent_debits: RentDebits::default(),
             loaded_accounts_data_size: 0,
@@ -556,7 +556,7 @@ mod tests {
             rollback_accounts: RollbackAccounts::SameNonceAndFeePayer {
                 nonce: nonce.clone(),
             },
-            compute_budget_limits: ComputeBudgetLimits::default(),
+            compute_budget: SVMTransactionExecutionBudget::default(),
             rent: 0,
             rent_debits: RentDebits::default(),
             loaded_accounts_data_size: 0,

+ 8 - 5
runtime/src/bank.rs

@@ -1436,7 +1436,7 @@ impl Bank {
             .prepare_program_cache_for_upcoming_feature_set(
                 &new,
                 &new.compute_active_feature_set(true).0,
-                &new.compute_budget.unwrap_or_default(),
+                &new.compute_budget.unwrap_or_default().to_budget(),
                 slot_index,
                 slots_in_epoch,
             ));
@@ -3228,7 +3228,6 @@ impl Bank {
             TransactionProcessingConfig {
                 account_overrides: Some(&account_overrides),
                 check_program_modification_slot: self.check_program_modification_slot,
-                compute_budget: self.compute_budget(),
                 log_messages_bytes_limit: None,
                 limit_to_load_programs: true,
                 recording_config: ExecutionRecordingConfig {
@@ -4575,7 +4574,6 @@ impl Bank {
             TransactionProcessingConfig {
                 account_overrides: None,
                 check_program_modification_slot: self.check_program_modification_slot,
-                compute_budget: self.compute_budget(),
                 log_messages_bytes_limit,
                 limit_to_load_programs: false,
                 recording_config,
@@ -4827,6 +4825,11 @@ impl Bank {
         additional_builtins: Option<&[BuiltinPrototype]>,
         debug_do_not_add_builtins: bool,
     ) {
+        if let Some(compute_budget) = self.compute_budget {
+            self.transaction_processor
+                .set_execution_cost(compute_budget.to_cost());
+        }
+
         self.rewards_pool_pubkeys =
             Arc::new(genesis_config.rewards_pools.keys().cloned().collect());
 
@@ -4895,14 +4898,14 @@ impl Bank {
                 Some(Arc::new(
                     create_program_runtime_environment_v1(
                         &self.feature_set,
-                        &self.compute_budget().unwrap_or_default(),
+                        &self.compute_budget().unwrap_or_default().to_budget(),
                         false, /* deployment */
                         false, /* debugging_features */
                     )
                     .unwrap(),
                 )),
                 Some(Arc::new(create_program_runtime_environment_v2(
-                    &self.compute_budget().unwrap_or_default(),
+                    &self.compute_budget().unwrap_or_default().to_budget(),
                     false, /* debugging_features */
                 ))),
             );

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

@@ -170,7 +170,8 @@ impl Bank {
                     &sysvar_cache,
                 ),
                 None,
-                compute_budget,
+                compute_budget.to_budget(),
+                compute_budget.to_cost(),
             );
 
             let environments = dummy_invoke_context

+ 17 - 7
runtime/src/bank/check_transactions.rs

@@ -1,9 +1,9 @@
 use {
     super::{Bank, BankStatusCache},
     solana_accounts_db::blockhash_queue::BlockhashQueue,
-    solana_compute_budget::compute_budget_limits::ComputeBudgetLimits,
     solana_compute_budget_instruction::instructions_processor::process_compute_budget_instructions,
     solana_perf::perf_libs,
+    solana_program_runtime::execution_budget::SVMTransactionExecutionAndFeeBudgetLimits,
     solana_runtime_transaction::transaction_with_meta::TransactionWithMeta,
     solana_sdk::{
         account::AccountSharedData,
@@ -97,10 +97,20 @@ impl Bank {
             .zip(lock_results)
             .map(|(tx, lock_res)| match lock_res {
                 Ok(()) => {
-                    let compute_budget_limits = process_compute_budget_instructions(
+                    let compute_budget_and_limits = process_compute_budget_instructions(
                         tx.borrow().program_instructions_iter(),
                         &self.feature_set,
-                    );
+                    )
+                    .map(|limit| {
+                        if let Some(compute_budget) = self.compute_budget {
+                            // This block of code is only necessary to retain legacy behavior of the code.
+                            // It should be removed along with the change to favor transaction's compute budget limits
+                            // over configured compute budget in Bank.
+                            compute_budget.get_compute_budget_and_limits(&limit)
+                        } else {
+                            limit.get_compute_budget_and_limits()
+                        }
+                    });
                     self.check_transaction_age(
                         tx.borrow(),
                         max_age,
@@ -108,7 +118,7 @@ impl Bank {
                         &hash_queue,
                         next_lamports_per_signature,
                         error_counters,
-                        compute_budget_limits,
+                        compute_budget_and_limits,
                     )
                 }
                 Err(e) => Err(e.clone()),
@@ -124,14 +134,14 @@ impl Bank {
         hash_queue: &BlockhashQueue,
         next_lamports_per_signature: u64,
         error_counters: &mut TransactionErrorMetrics,
-        compute_budget_limits: Result<ComputeBudgetLimits, TransactionError>,
+        compute_budget: Result<SVMTransactionExecutionAndFeeBudgetLimits, TransactionError>,
     ) -> TransactionCheckResult {
         let recent_blockhash = tx.recent_blockhash();
         if let Some(hash_info) = hash_queue.get_hash_info_if_valid(recent_blockhash, max_age) {
             Ok(CheckedTransactionDetails::new(
                 None,
                 hash_info.lamports_per_signature(),
-                compute_budget_limits,
+                compute_budget,
             ))
         } else if let Some((nonce, previous_lamports_per_signature)) = self
             .check_load_and_advance_message_nonce_account(
@@ -143,7 +153,7 @@ impl Bank {
             Ok(CheckedTransactionDetails::new(
                 Some(nonce),
                 previous_lamports_per_signature,
-                compute_budget_limits,
+                compute_budget,
             ))
         } else {
             error_counters.blockhash_not_found += 1;

+ 22 - 13
runtime/src/bank/tests.rs

@@ -36,8 +36,7 @@ use {
         ancestors::Ancestors,
     },
     solana_compute_budget::{
-        compute_budget::ComputeBudget,
-        compute_budget_limits::{self, ComputeBudgetLimits, MAX_COMPUTE_UNIT_LIMIT},
+        compute_budget::ComputeBudget, compute_budget_limits::ComputeBudgetLimits,
     },
     solana_cost_model::block_cost_limits::{MAX_BLOCK_UNITS, MAX_BLOCK_UNITS_SIMD_0207},
     solana_feature_set::{self as feature_set, FeatureSet},
@@ -45,6 +44,7 @@ use {
     solana_logger,
     solana_program_runtime::{
         declare_process_instruction,
+        execution_budget::{self, MAX_COMPUTE_UNIT_LIMIT},
         loaded_programs::{ProgramCacheEntry, ProgramCacheEntryType},
     },
     solana_sdk::{
@@ -10003,12 +10003,15 @@ fn test_compute_budget_program_noop() {
         Bank::new_with_mockup_builtin_for_tests(&genesis_config, program_id, MockBuiltin::vm);
 
     declare_process_instruction!(MockBuiltin, 1, |invoke_context| {
-        let compute_budget = invoke_context.get_compute_budget();
+        let compute_budget = ComputeBudget::from_budget_and_cost(
+            invoke_context.get_compute_budget(),
+            invoke_context.get_execution_cost(),
+        );
         assert_eq!(
-            *compute_budget,
+            compute_budget,
             ComputeBudget {
                 compute_unit_limit: u64::from(
-                    compute_budget_limits::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT
+                    execution_budget::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT
                 ),
                 heap_size: 48 * 1024,
                 ..ComputeBudget::default()
@@ -10020,7 +10023,7 @@ fn test_compute_budget_program_noop() {
     let message = Message::new(
         &[
             ComputeBudgetInstruction::set_compute_unit_limit(
-                compute_budget_limits::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT,
+                execution_budget::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT,
             ),
             ComputeBudgetInstruction::request_heap_frame(48 * 1024),
             Instruction::new_with_bincode(program_id, &0, vec![]),
@@ -10048,12 +10051,15 @@ fn test_compute_request_instruction() {
         Bank::new_with_mockup_builtin_for_tests(&genesis_config, program_id, MockBuiltin::vm);
 
     declare_process_instruction!(MockBuiltin, 1, |invoke_context| {
-        let compute_budget = invoke_context.get_compute_budget();
+        let compute_budget = ComputeBudget::from_budget_and_cost(
+            invoke_context.get_compute_budget(),
+            invoke_context.get_execution_cost(),
+        );
         assert_eq!(
-            *compute_budget,
+            compute_budget,
             ComputeBudget {
                 compute_unit_limit: u64::from(
-                    compute_budget_limits::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT
+                    execution_budget::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT
                 ),
                 heap_size: 48 * 1024,
                 ..ComputeBudget::default()
@@ -10065,7 +10071,7 @@ fn test_compute_request_instruction() {
     let message = Message::new(
         &[
             ComputeBudgetInstruction::set_compute_unit_limit(
-                compute_budget_limits::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT,
+                execution_budget::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT,
             ),
             ComputeBudgetInstruction::request_heap_frame(48 * 1024),
             Instruction::new_with_bincode(program_id, &0, vec![]),
@@ -10101,12 +10107,15 @@ fn test_failed_compute_request_instruction() {
         .unwrap();
 
     declare_process_instruction!(MockBuiltin, 1, |invoke_context| {
-        let compute_budget = invoke_context.get_compute_budget();
+        let compute_budget = ComputeBudget::from_budget_and_cost(
+            invoke_context.get_compute_budget(),
+            invoke_context.get_execution_cost(),
+        );
         assert_eq!(
-            *compute_budget,
+            compute_budget,
             ComputeBudget {
                 compute_unit_limit: u64::from(
-                    compute_budget_limits::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT
+                    execution_budget::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT
                 ),
                 heap_size: 48 * 1024,
                 ..ComputeBudget::default()

+ 1 - 3
svm/Cargo.toml

@@ -20,7 +20,6 @@ serde_derive = { workspace = true }
 solana-account = { workspace = true }
 solana-bpf-loader-program = { workspace = true }
 solana-clock = { workspace = true }
-solana-compute-budget = { workspace = true }
 solana-feature-set = { workspace = true }
 solana-fee-structure = { workspace = true }
 solana-frozen-abi = { workspace = true, optional = true, features = [
@@ -69,7 +68,6 @@ prost = { workspace = true }
 rand0-7 = { workspace = true }
 shuttle = { workspace = true }
 solana-clock = { workspace = true }
-solana-compute-budget = { workspace = true, features = ["dev-context-only-utils"] }
 solana-compute-budget-instruction = { workspace = true }
 solana-compute-budget-interface = { workspace = true }
 solana-compute-budget-program = { workspace = true }
@@ -79,6 +77,7 @@ solana-fee-calculator = { workspace = true }
 solana-keypair = { workspace = true }
 solana-logger = { workspace = true }
 solana-native-token = { workspace = true }
+solana-program-runtime = { workspace = true, features = ["dev-context-only-utils"] }
 solana-pubkey = { workspace = true }
 solana-rent = { workspace = true }
 solana-reserved-account-keys = { workspace = true }
@@ -106,7 +105,6 @@ dev-context-only-utils = ["dep:qualifier_attr"]
 frozen-abi = [
     "dep:solana-frozen-abi",
     "dep:solana-frozen-abi-macro",
-    "solana-compute-budget/frozen-abi",
     "solana-program-runtime/frozen-abi",
     "solana-sdk/frozen-abi",
 ]

+ 1 - 5
svm/examples/Cargo.lock

@@ -5305,7 +5305,6 @@ dependencies = [
  "solana-blake3-hasher",
  "solana-bn254",
  "solana-clock",
- "solana-compute-budget",
  "solana-cpi",
  "solana-curve25519",
  "solana-feature-set",
@@ -5581,7 +5580,7 @@ name = "solana-compute-budget"
 version = "2.3.0"
 dependencies = [
  "solana-fee-structure",
- "solana-program-entrypoint",
+ "solana-program-runtime",
 ]
 
 [[package]]
@@ -6431,7 +6430,6 @@ dependencies = [
  "solana-account",
  "solana-bincode",
  "solana-bpf-loader-program",
- "solana-compute-budget",
  "solana-instruction",
  "solana-loader-v3-interface",
  "solana-loader-v4-interface",
@@ -6870,7 +6868,6 @@ dependencies = [
  "serde",
  "solana-account",
  "solana-clock",
- "solana-compute-budget",
  "solana-epoch-rewards",
  "solana-epoch-schedule",
  "solana-feature-set",
@@ -7853,7 +7850,6 @@ dependencies = [
  "solana-account",
  "solana-bpf-loader-program",
  "solana-clock",
- "solana-compute-budget",
  "solana-feature-set",
  "solana-fee-structure",
  "solana-hash",

+ 5 - 6
svm/examples/json-rpc/server/src/rpc_process.rs

@@ -15,11 +15,11 @@ use {
         parse_token::{get_token_account_mint, is_known_spl_token_id},
         UiAccount, UiAccountEncoding, UiDataSliceConfig, MAX_BASE58_BYTES,
     },
-    solana_compute_budget::{
-        compute_budget::ComputeBudget, compute_budget_limits::ComputeBudgetLimits,
-    },
     solana_perf::packet::PACKET_DATA_SIZE,
-    solana_program_runtime::loaded_programs::ProgramCacheEntry,
+    solana_program_runtime::{
+        execution_budget::SVMTransactionExecutionAndFeeBudgetLimits,
+        loaded_programs::ProgramCacheEntry,
+    },
     solana_rpc_client_api::{
         config::*,
         response::{Response as RpcResponse, *},
@@ -326,7 +326,6 @@ impl JsonRpcRequestProcessor {
             TransactionProcessingConfig {
                 account_overrides: Some(&account_overrides),
                 check_program_modification_slot: false,
-                compute_budget: Some(ComputeBudget::default()),
                 log_messages_bytes_limit: None,
                 limit_to_load_programs: true,
                 recording_config: ExecutionRecordingConfig {
@@ -428,7 +427,7 @@ impl JsonRpcRequestProcessor {
         Ok(CheckedTransactionDetails::new(
             None,
             u64::default(),
-            Ok(ComputeBudgetLimits::default()),
+            Ok(SVMTransactionExecutionAndFeeBudgetLimits::default()),
         ))
     }
 

+ 1 - 1
svm/examples/paytube/Cargo.toml

@@ -10,7 +10,7 @@ solana-bpf-loader-program = { workspace = true }
 solana-client = { workspace = true }
 solana-compute-budget = { workspace = true }
 solana-logger = { workspace = true }
-solana-program-runtime = { workspace = true }
+solana-program-runtime = { workspace = true, features = ["dev-context-only-utils"] }
 solana-sdk = { workspace = true }
 solana-svm = { workspace = true }
 solana-system-program = { workspace = true }

+ 3 - 6
svm/examples/paytube/src/lib.rs

@@ -67,7 +67,7 @@ use {
         create_transaction_batch_processor, get_transaction_check_results, PayTubeForkGraph,
     },
     solana_client::rpc_client::RpcClient,
-    solana_compute_budget::compute_budget::ComputeBudget,
+    solana_program_runtime::execution_budget::SVMTransactionExecutionBudget,
     solana_sdk::{
         feature_set::FeatureSet, fee::FeeStructure, hash::Hash, rent_collector::RentCollector,
         signature::Keypair,
@@ -114,7 +114,7 @@ impl PayTubeChannel {
         // would likely be hoisted from the cluster.
         //
         // For example purposes, they are provided as defaults here.
-        let compute_budget = ComputeBudget::default();
+        let compute_budget = SVMTransactionExecutionBudget::default();
         let feature_set = FeatureSet::all_enabled();
         let fee_structure = FeeStructure::default();
         let rent_collector = RentCollector::default();
@@ -157,10 +157,7 @@ impl PayTubeChannel {
         // The PayTube transaction processing config for Solana SVM.
         //
         // Extended configurations for even more customization of the SVM API.
-        let processing_config = TransactionProcessingConfig {
-            compute_budget: Some(compute_budget),
-            ..Default::default()
-        };
+        let processing_config = TransactionProcessingConfig::default();
 
         // Step 1: Convert the batch of PayTube transactions into
         // SVM-compatible transactions for processing.

+ 6 - 5
svm/examples/paytube/src/processor.rs

@@ -2,10 +2,11 @@
 
 use {
     solana_bpf_loader_program::syscalls::create_program_runtime_environment_v1,
-    solana_compute_budget::{
-        compute_budget::ComputeBudget, compute_budget_limits::ComputeBudgetLimits,
+    solana_compute_budget::compute_budget_limits::ComputeBudgetLimits,
+    solana_program_runtime::{
+        execution_budget::SVMTransactionExecutionBudget,
+        loaded_programs::{BlockRelation, ForkGraph, ProgramCacheEntry},
     },
-    solana_program_runtime::loaded_programs::{BlockRelation, ForkGraph, ProgramCacheEntry},
     solana_sdk::{clock::Slot, feature_set::FeatureSet, transaction},
     solana_svm::{
         account_loader::CheckedTransactionDetails,
@@ -37,7 +38,7 @@ impl ForkGraph for PayTubeForkGraph {
 pub(crate) fn create_transaction_batch_processor<CB: TransactionProcessingCallback>(
     callbacks: &CB,
     feature_set: &FeatureSet,
-    compute_budget: &ComputeBudget,
+    compute_budget: &SVMTransactionExecutionBudget,
     fork_graph: Arc<RwLock<PayTubeForkGraph>>,
 ) -> TransactionBatchProcessor<PayTubeForkGraph> {
     // Create a new transaction batch processor.
@@ -98,7 +99,7 @@ pub(crate) fn get_transaction_check_results(
         transaction::Result::Ok(CheckedTransactionDetails::new(
             None,
             lamports_per_signature,
-            Ok(ComputeBudgetLimits::default())
+            Ok(ComputeBudgetLimits::default_compute_budget_and_limits())
         ));
         len
     ]

+ 54 - 30
svm/src/account_loader.rs

@@ -13,13 +13,15 @@ use {
     solana_account::{
         Account, AccountSharedData, ReadableAccount, WritableAccount, PROGRAM_OWNERS,
     },
-    solana_compute_budget::compute_budget_limits::ComputeBudgetLimits,
     solana_feature_set::{self as feature_set, FeatureSet},
     solana_fee_structure::FeeDetails,
     solana_instruction::{BorrowedAccountMeta, BorrowedInstruction},
     solana_instructions_sysvar::construct_instructions_data,
     solana_nonce::state::State as NonceState,
     solana_nonce_account::{get_system_account_kind, SystemAccountKind},
+    solana_program_runtime::execution_budget::{
+        SVMTransactionExecutionAndFeeBudgetLimits, SVMTransactionExecutionBudget,
+    },
     solana_pubkey::Pubkey,
     solana_rent::RentDue,
     solana_rent_debits::RentDebits,
@@ -65,7 +67,7 @@ pub(crate) enum TransactionLoadResult {
 pub struct CheckedTransactionDetails {
     pub(crate) nonce: Option<NonceInfo>,
     pub(crate) lamports_per_signature: u64,
-    pub(crate) compute_budget_limits: Result<ComputeBudgetLimits>,
+    pub(crate) compute_budget_and_limits: Result<SVMTransactionExecutionAndFeeBudgetLimits>,
 }
 
 #[cfg(feature = "dev-context-only-utils")]
@@ -74,7 +76,12 @@ impl Default for CheckedTransactionDetails {
         Self {
             nonce: None,
             lamports_per_signature: 0,
-            compute_budget_limits: Ok(ComputeBudgetLimits::default()),
+            compute_budget_and_limits: Ok(SVMTransactionExecutionAndFeeBudgetLimits {
+                budget: SVMTransactionExecutionBudget::default(),
+                loaded_accounts_data_size_limit: NonZeroU32::new(32)
+                    .expect("Failed to set loaded_accounts_bytes"),
+                priority_fee: 0,
+            }),
         }
     }
 }
@@ -83,25 +90,39 @@ impl CheckedTransactionDetails {
     pub fn new(
         nonce: Option<NonceInfo>,
         lamports_per_signature: u64,
-        compute_budget_limits: Result<ComputeBudgetLimits>,
+        compute_budget_and_limits: Result<SVMTransactionExecutionAndFeeBudgetLimits>,
     ) -> Self {
         Self {
             nonce,
             lamports_per_signature,
-            compute_budget_limits,
+            compute_budget_and_limits,
         }
     }
 }
 
 #[derive(PartialEq, Eq, Debug, Clone)]
-#[cfg_attr(feature = "dev-context-only-utils", derive(Default))]
 pub(crate) struct ValidatedTransactionDetails {
     pub(crate) rollback_accounts: RollbackAccounts,
-    pub(crate) compute_budget_limits: ComputeBudgetLimits,
+    pub(crate) compute_budget: SVMTransactionExecutionBudget,
+    pub(crate) loaded_accounts_bytes_limit: NonZeroU32,
     pub(crate) fee_details: FeeDetails,
     pub(crate) loaded_fee_payer_account: LoadedTransactionAccount,
 }
 
+#[cfg(feature = "dev-context-only-utils")]
+impl Default for ValidatedTransactionDetails {
+    fn default() -> Self {
+        Self {
+            rollback_accounts: RollbackAccounts::default(),
+            compute_budget: SVMTransactionExecutionBudget::default(),
+            loaded_accounts_bytes_limit:
+                solana_program_runtime::execution_budget::MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES,
+            fee_details: FeeDetails::default(),
+            loaded_fee_payer_account: LoadedTransactionAccount::default(),
+        }
+    }
+}
+
 #[derive(PartialEq, Eq, Debug, Clone)]
 #[cfg_attr(feature = "dev-context-only-utils", derive(Default))]
 pub(crate) struct LoadedTransactionAccount {
@@ -116,8 +137,8 @@ pub(crate) struct LoadedTransactionAccount {
     feature = "dev-context-only-utils",
     field_qualifiers(
         program_indices(pub),
-        compute_budget_limits(pub),
-        loaded_accounts_data_size(pub)
+        loaded_accounts_data_size(pub),
+        compute_budget(pub)
     )
 )]
 pub struct LoadedTransaction {
@@ -125,7 +146,7 @@ pub struct LoadedTransaction {
     pub(crate) program_indices: TransactionProgramIndices,
     pub fee_details: FeeDetails,
     pub rollback_accounts: RollbackAccounts,
-    pub(crate) compute_budget_limits: ComputeBudgetLimits,
+    pub(crate) compute_budget: SVMTransactionExecutionBudget,
     pub rent: TransactionRent,
     pub rent_debits: RentDebits,
     pub(crate) loaded_accounts_data_size: u32,
@@ -375,7 +396,7 @@ pub(crate) fn load_transaction<CB: TransactionProcessingCallback>(
                 account_loader,
                 message,
                 tx_details.loaded_fee_payer_account,
-                &tx_details.compute_budget_limits,
+                tx_details.loaded_accounts_bytes_limit,
                 error_metrics,
                 rent_collector,
             );
@@ -388,7 +409,7 @@ pub(crate) fn load_transaction<CB: TransactionProcessingCallback>(
                     rent: loaded_tx_accounts.rent,
                     rent_debits: loaded_tx_accounts.rent_debits,
                     rollback_accounts: tx_details.rollback_accounts,
-                    compute_budget_limits: tx_details.compute_budget_limits,
+                    compute_budget: tx_details.compute_budget,
                     loaded_accounts_data_size: loaded_tx_accounts.loaded_accounts_data_size,
                 }),
                 Err(err) => TransactionLoadResult::FeesOnly(FeesOnlyTransaction {
@@ -414,7 +435,7 @@ fn load_transaction_accounts<CB: TransactionProcessingCallback>(
     account_loader: &mut AccountLoader<CB>,
     message: &impl SVMMessage,
     loaded_fee_payer_account: LoadedTransactionAccount,
-    compute_budget_limits: &ComputeBudgetLimits,
+    loaded_accounts_bytes_limit: NonZeroU32,
     error_metrics: &mut TransactionErrorMetrics,
     rent_collector: &dyn SVMRentCollector,
 ) -> Result<LoadedTransactionAccounts> {
@@ -435,7 +456,7 @@ fn load_transaction_accounts<CB: TransactionProcessingCallback>(
         accumulate_and_check_loaded_account_data_size(
             &mut accumulated_accounts_data_size,
             loaded_size,
-            compute_budget_limits.loaded_accounts_bytes,
+            loaded_accounts_bytes_limit,
             error_metrics,
         )?;
 
@@ -531,7 +552,7 @@ fn load_transaction_accounts<CB: TransactionProcessingCallback>(
                     accumulate_and_check_loaded_account_data_size(
                         &mut accumulated_accounts_data_size,
                         owner_size,
-                        compute_budget_limits.loaded_accounts_bytes,
+                        loaded_accounts_bytes_limit,
                         error_metrics,
                     )?;
                     validated_loaders.insert(*owner_id);
@@ -662,7 +683,6 @@ mod tests {
             transaction_processing_callback::TransactionProcessingCallback,
         },
         solana_account::{Account, AccountSharedData, ReadableAccount, WritableAccount},
-        solana_compute_budget::{compute_budget::ComputeBudget, compute_budget_limits},
         solana_epoch_schedule::EpochSchedule,
         solana_feature_set::FeatureSet,
         solana_hash::Hash,
@@ -676,6 +696,9 @@ mod tests {
         solana_native_token::{sol_to_lamports, LAMPORTS_PER_SOL},
         solana_nonce::{self as nonce, versions::Versions as NonceVersions},
         solana_program::bpf_loader_upgradeable::UpgradeableLoaderState,
+        solana_program_runtime::execution_budget::{
+            DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT, MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES,
+        },
         solana_pubkey::Pubkey,
         solana_rent::Rent,
         solana_rent_debits::RentDebits,
@@ -1350,7 +1373,7 @@ mod tests {
                 account: fee_payer_account.clone(),
                 rent_collected: fee_payer_rent_debit,
             },
-            &ComputeBudgetLimits::default(),
+            MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES,
             &mut error_metrics,
             &RentCollector::default(),
         );
@@ -1412,7 +1435,7 @@ mod tests {
                 account: fee_payer_account.clone(),
                 ..LoadedTransactionAccount::default()
             },
-            &ComputeBudgetLimits::default(),
+            MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES,
             &mut error_metrics,
             &RentCollector::default(),
         );
@@ -1469,7 +1492,7 @@ mod tests {
             &mut account_loader,
             sanitized_transaction.message(),
             LoadedTransactionAccount::default(),
-            &ComputeBudgetLimits::default(),
+            MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES,
             &mut error_metrics,
             &RentCollector::default(),
         );
@@ -1511,7 +1534,7 @@ mod tests {
             &mut account_loader,
             sanitized_transaction.message(),
             LoadedTransactionAccount::default(),
-            &ComputeBudgetLimits::default(),
+            MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES,
             &mut error_metrics,
             &RentCollector::default(),
         );
@@ -1567,7 +1590,7 @@ mod tests {
                 account: fee_payer_account.clone(),
                 ..LoadedTransactionAccount::default()
             },
-            &ComputeBudgetLimits::default(),
+            MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES,
             &mut error_metrics,
             &RentCollector::default(),
         );
@@ -1628,7 +1651,7 @@ mod tests {
             &mut account_loader,
             sanitized_transaction.message(),
             LoadedTransactionAccount::default(),
-            &ComputeBudgetLimits::default(),
+            MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES,
             &mut error_metrics,
             &RentCollector::default(),
         );
@@ -1680,7 +1703,7 @@ mod tests {
             &mut account_loader,
             sanitized_transaction.message(),
             LoadedTransactionAccount::default(),
-            &ComputeBudgetLimits::default(),
+            MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES,
             &mut error_metrics,
             &RentCollector::default(),
         );
@@ -1743,7 +1766,7 @@ mod tests {
                 account: fee_payer_account.clone(),
                 ..LoadedTransactionAccount::default()
             },
-            &ComputeBudgetLimits::default(),
+            MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES,
             &mut error_metrics,
             &RentCollector::default(),
         );
@@ -1826,7 +1849,7 @@ mod tests {
                 account: fee_payer_account.clone(),
                 ..LoadedTransactionAccount::default()
             },
-            &ComputeBudgetLimits::default(),
+            MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES,
             &mut error_metrics,
             &RentCollector::default(),
         );
@@ -1894,9 +1917,10 @@ mod tests {
             panic!("transaction loading failed");
         };
 
-        let compute_budget = ComputeBudget::new(u64::from(
-            compute_budget_limits::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT,
-        ));
+        let compute_budget = SVMTransactionExecutionBudget {
+            compute_unit_limit: u64::from(DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT),
+            ..SVMTransactionExecutionBudget::default()
+        };
         let rent_collector = RentCollector::default();
         let transaction_context = TransactionContext::new(
             loaded_transaction.accounts,
@@ -2008,7 +2032,7 @@ mod tests {
                 program_indices: vec![vec![1], vec![1]],
                 fee_details: FeeDetails::default(),
                 rollback_accounts: RollbackAccounts::default(),
-                compute_budget_limits: ComputeBudgetLimits::default(),
+                compute_budget: SVMTransactionExecutionBudget::default(),
                 rent: 0,
                 rent_debits: RentDebits::default(),
                 loaded_accounts_data_size: 0,
@@ -2340,7 +2364,7 @@ mod tests {
                     loaded_size: fee_payer_size as usize,
                     rent_collected: 0,
                 },
-                &ComputeBudgetLimits::default(),
+                MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES,
                 &mut TransactionErrorMetrics::default(),
                 &RentCollector::default(),
             )

+ 15 - 8
svm/src/message_processor.rs

@@ -122,7 +122,6 @@ mod tests {
         },
         rand0_7::thread_rng,
         solana_account::{AccountSharedData, ReadableAccount},
-        solana_compute_budget::compute_budget::ComputeBudget,
         solana_ed25519_program::new_ed25519_instruction,
         solana_feature_set::FeatureSet,
         solana_hash::Hash,
@@ -130,6 +129,7 @@ mod tests {
         solana_message::{AccountKeys, Message, SanitizedMessage},
         solana_program_runtime::{
             declare_process_instruction,
+            execution_budget::{SVMTransactionExecutionBudget, SVMTransactionExecutionCost},
             invoke_context::EnvironmentConfig,
             loaded_programs::{ProgramCacheEntry, ProgramCacheForTxBatch},
             sysvar_cache::SysvarCache,
@@ -252,7 +252,8 @@ mod tests {
             &mut program_cache_for_tx_batch,
             environment_config,
             None,
-            ComputeBudget::default(),
+            SVMTransactionExecutionBudget::default(),
+            SVMTransactionExecutionCost::default(),
         );
         let result = process_message(
             &message,
@@ -306,7 +307,8 @@ mod tests {
             &mut program_cache_for_tx_batch,
             environment_config,
             None,
-            ComputeBudget::default(),
+            SVMTransactionExecutionBudget::default(),
+            SVMTransactionExecutionCost::default(),
         );
         let result = process_message(
             &message,
@@ -350,7 +352,8 @@ mod tests {
             &mut program_cache_for_tx_batch,
             environment_config,
             None,
-            ComputeBudget::default(),
+            SVMTransactionExecutionBudget::default(),
+            SVMTransactionExecutionCost::default(),
         );
         let result = process_message(
             &message,
@@ -485,7 +488,8 @@ mod tests {
             &mut program_cache_for_tx_batch,
             environment_config,
             None,
-            ComputeBudget::default(),
+            SVMTransactionExecutionBudget::default(),
+            SVMTransactionExecutionCost::default(),
         );
         let result = process_message(
             &message,
@@ -524,7 +528,8 @@ mod tests {
             &mut program_cache_for_tx_batch,
             environment_config,
             None,
-            ComputeBudget::default(),
+            SVMTransactionExecutionBudget::default(),
+            SVMTransactionExecutionCost::default(),
         );
         let result = process_message(
             &message,
@@ -560,7 +565,8 @@ mod tests {
             &mut program_cache_for_tx_batch,
             environment_config,
             None,
-            ComputeBudget::default(),
+            SVMTransactionExecutionBudget::default(),
+            SVMTransactionExecutionCost::default(),
         );
         let result = process_message(
             &message,
@@ -663,7 +669,8 @@ mod tests {
             &mut program_cache_for_tx_batch,
             environment_config,
             None,
-            ComputeBudget::default(),
+            SVMTransactionExecutionBudget::default(),
+            SVMTransactionExecutionCost::default(),
         );
         let result = process_message(
             &message,

+ 79 - 68
svm/src/transaction_processor.rs

@@ -25,11 +25,10 @@ use {
         create_program_runtime_environment_v1, create_program_runtime_environment_v2,
     },
     solana_clock::{Epoch, Slot},
-    solana_compute_budget::compute_budget::ComputeBudget,
     solana_feature_set::{
         enable_transaction_loading_failure_fees, remove_accounts_executable_flag_checks, FeatureSet,
     },
-    solana_fee_structure::{FeeBudgetLimits, FeeDetails, FeeStructure},
+    solana_fee_structure::{FeeDetails, FeeStructure},
     solana_hash::Hash,
     solana_instruction::TRANSACTION_LEVEL_STACK_HEIGHT,
     solana_log_collector::LogCollector,
@@ -40,6 +39,7 @@ use {
         versions::Versions as NonceVersions,
     },
     solana_program_runtime::{
+        execution_budget::{SVMTransactionExecutionBudget, SVMTransactionExecutionCost},
         invoke_context::{EnvironmentConfig, InvokeContext},
         loaded_programs::{
             ForkGraph, ProgramCache, ProgramCacheEntry, ProgramCacheForTxBatch,
@@ -111,8 +111,6 @@ pub struct TransactionProcessingConfig<'a> {
     /// Whether or not to check a program's modification slot when replenishing
     /// a program cache instance.
     pub check_program_modification_slot: bool,
-    /// The compute budget to use for transaction execution.
-    pub compute_budget: Option<ComputeBudget>,
     /// The maximum number of bytes that log messages can consume.
     pub log_messages_bytes_limit: Option<usize>,
     /// Whether to limit the number of programs loaded for the transaction
@@ -180,6 +178,8 @@ pub struct TransactionBatchProcessor<FG: ForkGraph> {
 
     /// Builtin program ids
     pub builtin_program_ids: RwLock<HashSet<Pubkey>>,
+
+    execution_cost: SVMTransactionExecutionCost,
 }
 
 impl<FG: ForkGraph> Debug for TransactionBatchProcessor<FG> {
@@ -204,6 +204,7 @@ impl<FG: ForkGraph> Default for TransactionBatchProcessor<FG> {
                 Epoch::default(),
             ))),
             builtin_program_ids: RwLock::new(HashSet::new()),
+            execution_cost: SVMTransactionExecutionCost::default(),
         }
     }
 }
@@ -268,9 +269,16 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
             sysvar_cache: RwLock::<SysvarCache>::default(),
             program_cache: self.program_cache.clone(),
             builtin_program_ids: RwLock::new(self.builtin_program_ids.read().unwrap().clone()),
+            execution_cost: self.execution_cost,
         }
     }
 
+    /// Sets the base execution cost for the transactions that this instance of transaction processor
+    /// will execute.
+    pub fn set_execution_cost(&mut self, cost: SVMTransactionExecutionCost) {
+        self.execution_cost = cost;
+    }
+
     fn configure_program_runtime_environments_inner(
         &self,
         program_cache: &mut ProgramCache<FG>,
@@ -526,7 +534,7 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
         if let CheckedTransactionDetails {
             nonce: Some(ref nonce_info),
             lamports_per_signature: _,
-            compute_budget_limits: _,
+            compute_budget_and_limits: _,
         } = checked_details
         {
             let next_durable_nonce = DurableNonce::from_blockhash(environment_blockhash);
@@ -566,10 +574,10 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
         let CheckedTransactionDetails {
             nonce,
             lamports_per_signature,
-            compute_budget_limits,
+            compute_budget_and_limits,
         } = checked_details;
 
-        let compute_budget_limits = compute_budget_limits.inspect_err(|_err| {
+        let compute_budget_and_limits = compute_budget_and_limits.inspect_err(|_err| {
             error_counters.invalid_compute_budget += 1;
         })?;
 
@@ -590,14 +598,13 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
         )
         .rent_amount;
 
-        let fee_budget_limits = FeeBudgetLimits::from(compute_budget_limits);
         let fee_details = if lamports_per_signature == 0 {
             FeeDetails::default()
         } else {
             callbacks.calculate_fee(
                 message,
                 fee_lamports_per_signature,
-                fee_budget_limits.prioritization_fee,
+                compute_budget_and_limits.priority_fee,
                 account_loader.feature_set.as_ref(),
             )
         };
@@ -625,7 +632,8 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
         Ok(ValidatedTransactionDetails {
             fee_details,
             rollback_accounts,
-            compute_budget_limits,
+            loaded_accounts_bytes_limit: compute_budget_and_limits.loaded_accounts_data_size_limit,
+            compute_budget: compute_budget_and_limits.budget,
             loaded_fee_payer_account: loaded_fee_payer,
         })
     }
@@ -822,7 +830,7 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
         &self,
         callbacks: &CB,
         upcoming_feature_set: &FeatureSet,
-        compute_budget: &ComputeBudget,
+        compute_budget: &SVMTransactionExecutionBudget,
         slot_index: u64,
         slots_in_epoch: u64,
     ) {
@@ -941,9 +949,7 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
         let lamports_before_tx =
             transaction_accounts_lamports_sum(&transaction_accounts).unwrap_or(0);
 
-        let compute_budget = config
-            .compute_budget
-            .unwrap_or_else(|| ComputeBudget::from(loaded_transaction.compute_budget_limits));
+        let compute_budget = loaded_transaction.compute_budget;
 
         let mut transaction_context = TransactionContext::new(
             transaction_accounts,
@@ -991,6 +997,7 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
             ),
             log_collector.clone(),
             compute_budget,
+            self.execution_cost,
         );
 
         let mut process_message_time = Measure::start("process_message_time");
@@ -1204,8 +1211,6 @@ mod tests {
         },
         solana_account::{create_account_shared_data_for_test, WritableAccount},
         solana_clock::Clock,
-        solana_compute_budget::compute_budget_limits::ComputeBudgetLimits,
-        solana_compute_budget_instruction::instructions_processor::process_compute_budget_instructions,
         solana_compute_budget_interface::ComputeBudgetInstruction,
         solana_epoch_schedule::EpochSchedule,
         solana_feature_set::FeatureSet,
@@ -1215,7 +1220,10 @@ mod tests {
         solana_keypair::Keypair,
         solana_message::{LegacyMessage, Message, MessageHeader, SanitizedMessage},
         solana_nonce as nonce,
-        solana_program_runtime::loaded_programs::{BlockRelation, ProgramCacheEntryType},
+        solana_program_runtime::{
+            execution_budget::SVMTransactionExecutionAndFeeBudgetLimits,
+            loaded_programs::{BlockRelation, ProgramCacheEntryType},
+        },
         solana_rent::Rent,
         solana_rent_debits::RentDebits,
         solana_reserved_account_keys::ReservedAccountKeys,
@@ -1224,7 +1232,7 @@ mod tests {
         solana_signature::Signature,
         solana_transaction::{sanitized::SanitizedTransaction, Transaction},
         solana_transaction_context::TransactionContext,
-        solana_transaction_error::TransactionError,
+        solana_transaction_error::{TransactionError, TransactionError::DuplicateInstruction},
         test_case::test_case,
     };
 
@@ -1451,7 +1459,7 @@ mod tests {
             program_indices: vec![vec![0]],
             fee_details: FeeDetails::default(),
             rollback_accounts: RollbackAccounts::default(),
-            compute_budget_limits: ComputeBudgetLimits::default(),
+            compute_budget: SVMTransactionExecutionBudget::default(),
             rent: 0,
             rent_debits: RentDebits::default(),
             loaded_accounts_data_size: 32,
@@ -1548,7 +1556,7 @@ mod tests {
             program_indices: vec![vec![0]],
             fee_details: FeeDetails::default(),
             rollback_accounts: RollbackAccounts::default(),
-            compute_budget_limits: ComputeBudgetLimits::default(),
+            compute_budget: SVMTransactionExecutionBudget::default(),
             rent: 0,
             rent_debits: RentDebits::default(),
             loaded_accounts_data_size: 0,
@@ -2140,11 +2148,6 @@ mod tests {
             Some(&Pubkey::new_unique()),
             &Hash::new_unique(),
         ));
-        let compute_budget_limits = process_compute_budget_instructions(
-            SVMMessage::program_instructions_iter(&message),
-            &FeatureSet::default(),
-        )
-        .unwrap();
         let fee_payer_address = message.fee_payer();
         let current_epoch = 42;
         let rent_collector = RentCollector {
@@ -2160,7 +2163,7 @@ mod tests {
         assert!(
             starting_balance > min_balance,
             "we're testing that a rent exempt fee payer can be fully drained, \
-        so ensure that the starting balance is more than the min balance"
+                so ensure that the starting balance is more than the min balance"
         );
 
         let fee_payer_rent_epoch = current_epoch;
@@ -2180,6 +2183,14 @@ mod tests {
         let mut account_loader = (&mock_bank).into();
 
         let mut error_counters = TransactionErrorMetrics::default();
+        let compute_budget_and_limits = SVMTransactionExecutionAndFeeBudgetLimits {
+            budget: SVMTransactionExecutionBudget {
+                compute_unit_limit: 2000,
+                ..SVMTransactionExecutionBudget::default()
+            },
+            priority_fee,
+            ..SVMTransactionExecutionAndFeeBudgetLimits::default()
+        };
         let result =
             TransactionBatchProcessor::<TestForkGraph>::validate_transaction_nonce_and_fee_payer(
                 &mut account_loader,
@@ -2187,7 +2198,7 @@ mod tests {
                 CheckedTransactionDetails::new(
                     None,
                     lamports_per_signature,
-                    Ok(compute_budget_limits),
+                    Ok(compute_budget_and_limits),
                 ),
                 &Hash::default(),
                 FeeStructure::default().lamports_per_signature,
@@ -2213,7 +2224,9 @@ mod tests {
                     fee_payer_rent_debit,
                     fee_payer_rent_epoch
                 ),
-                compute_budget_limits,
+                compute_budget: compute_budget_and_limits.budget,
+                loaded_accounts_bytes_limit: compute_budget_and_limits
+                    .loaded_accounts_data_size_limit,
                 fee_details: FeeDetails::new(transaction_fee, priority_fee),
                 loaded_fee_payer_account: LoadedTransactionAccount {
                     loaded_size: fee_payer_account.data().len(),
@@ -2232,11 +2245,6 @@ mod tests {
             Some(&Pubkey::new_unique()),
             &Hash::new_unique(),
         ));
-        let compute_budget_limits = process_compute_budget_instructions(
-            SVMMessage::program_instructions_iter(&message),
-            &FeatureSet::default(),
-        )
-        .unwrap();
         let fee_payer_address = message.fee_payer();
         let mut rent_collector = RentCollector::default();
         rent_collector.rent.lamports_per_byte_year = 1_000_000;
@@ -2262,6 +2270,7 @@ mod tests {
         let mut account_loader = (&mock_bank).into();
 
         let mut error_counters = TransactionErrorMetrics::default();
+        let compute_budget_and_limits = SVMTransactionExecutionAndFeeBudgetLimits::default();
         let result =
             TransactionBatchProcessor::<TestForkGraph>::validate_transaction_nonce_and_fee_payer(
                 &mut account_loader,
@@ -2269,7 +2278,7 @@ mod tests {
                 CheckedTransactionDetails::new(
                     None,
                     lamports_per_signature,
-                    Ok(compute_budget_limits),
+                    Ok(compute_budget_and_limits),
                 ),
                 &Hash::default(),
                 FeeStructure::default().lamports_per_signature,
@@ -2295,7 +2304,9 @@ mod tests {
                     fee_payer_rent_debit,
                     0, // rent epoch
                 ),
-                compute_budget_limits,
+                compute_budget: compute_budget_and_limits.budget,
+                loaded_accounts_bytes_limit: compute_budget_and_limits
+                    .loaded_accounts_data_size_limit,
                 fee_details: FeeDetails::new(transaction_fee, 0),
                 loaded_fee_payer_account: LoadedTransactionAccount {
                     loaded_size: fee_payer_account.data().len(),
@@ -2322,7 +2333,7 @@ mod tests {
                 CheckedTransactionDetails::new(
                     None,
                     lamports_per_signature,
-                    Ok(ComputeBudgetLimits::default()),
+                    Ok(SVMTransactionExecutionAndFeeBudgetLimits::default()),
                 ),
                 &Hash::default(),
                 FeeStructure::default().lamports_per_signature,
@@ -2358,7 +2369,7 @@ mod tests {
                 CheckedTransactionDetails::new(
                     None,
                     lamports_per_signature,
-                    Ok(ComputeBudgetLimits::default()),
+                    Ok(SVMTransactionExecutionAndFeeBudgetLimits::default()),
                 ),
                 &Hash::default(),
                 FeeStructure::default().lamports_per_signature,
@@ -2398,7 +2409,7 @@ mod tests {
                 CheckedTransactionDetails::new(
                     None,
                     lamports_per_signature,
-                    Ok(ComputeBudgetLimits::default()),
+                    Ok(SVMTransactionExecutionAndFeeBudgetLimits::default()),
                 ),
                 &Hash::default(),
                 FeeStructure::default().lamports_per_signature,
@@ -2436,7 +2447,7 @@ mod tests {
                 CheckedTransactionDetails::new(
                     None,
                     lamports_per_signature,
-                    Ok(ComputeBudgetLimits::default()),
+                    Ok(SVMTransactionExecutionAndFeeBudgetLimits::default()),
                 ),
                 &Hash::default(),
                 FeeStructure::default().lamports_per_signature,
@@ -2459,10 +2470,6 @@ mod tests {
             ],
             Some(&Pubkey::new_unique()),
         ));
-        let compute_budget_limits = process_compute_budget_instructions(
-            SVMMessage::program_instructions_iter(&message),
-            &FeatureSet::default(),
-        );
 
         let mock_bank = MockBankCallback::default();
         let mut account_loader = (&mock_bank).into();
@@ -2471,7 +2478,11 @@ mod tests {
             TransactionBatchProcessor::<TestForkGraph>::validate_transaction_nonce_and_fee_payer(
                 &mut account_loader,
                 &message,
-                CheckedTransactionDetails::new(None, lamports_per_signature, compute_budget_limits),
+                CheckedTransactionDetails::new(
+                    None,
+                    lamports_per_signature,
+                    Err(DuplicateInstruction(1)),
+                ),
                 &Hash::default(),
                 FeeStructure::default().lamports_per_signature,
                 &RentCollector::default(),
@@ -2497,11 +2508,10 @@ mod tests {
             Some(&Pubkey::new_unique()),
             &last_blockhash,
         ));
-        let compute_budget_limits = process_compute_budget_instructions(
-            SVMMessage::program_instructions_iter(&message),
-            &FeatureSet::default(),
-        )
-        .unwrap();
+        let compute_budget_and_limits = SVMTransactionExecutionAndFeeBudgetLimits {
+            priority_fee: compute_unit_limit,
+            ..SVMTransactionExecutionAndFeeBudgetLimits::default()
+        };
         let fee_payer_address = message.fee_payer();
         let min_balance = Rent::default().minimum_balance(nonce::state::State::size());
         let transaction_fee = lamports_per_signature;
@@ -2542,19 +2552,19 @@ mod tests {
             let tx_details = CheckedTransactionDetails::new(
                 Some(future_nonce.clone()),
                 lamports_per_signature,
-                Ok(compute_budget_limits),
+                Ok(compute_budget_and_limits),
             );
 
             let result = TransactionBatchProcessor::<TestForkGraph>::validate_transaction_nonce_and_fee_payer(
-                &mut account_loader,
-                &message,
-                tx_details,
-                &environment_blockhash,
-                FeeStructure::default().lamports_per_signature,
-                &rent_collector,
-                &mut error_counters,
-                &mock_bank,
-            );
+                   &mut account_loader,
+                   &message,
+                   tx_details,
+                   &environment_blockhash,
+                   FeeStructure::default().lamports_per_signature,
+                   &rent_collector,
+                   &mut error_counters,
+                   &mock_bank,
+               );
 
             let post_validation_fee_payer_account = {
                 let mut account = fee_payer_account.clone();
@@ -2573,7 +2583,9 @@ mod tests {
                         0, // fee_payer_rent_debit
                         0, // fee_payer_rent_epoch
                     ),
-                    compute_budget_limits,
+                    compute_budget: compute_budget_and_limits.budget,
+                    loaded_accounts_bytes_limit: compute_budget_and_limits
+                        .loaded_accounts_data_size_limit,
                     fee_details: FeeDetails::new(transaction_fee, priority_fee),
                     loaded_fee_payer_account: LoadedTransactionAccount {
                         loaded_size: fee_payer_account.data().len(),
@@ -2607,13 +2619,13 @@ mod tests {
             let result = TransactionBatchProcessor::<TestForkGraph>::validate_transaction_nonce_and_fee_payer(
                 &mut account_loader,
                 &message,
-                CheckedTransactionDetails::new(None, lamports_per_signature, Ok(compute_budget_limits)),
+                CheckedTransactionDetails::new(None, lamports_per_signature, Ok(compute_budget_and_limits)),
                 &Hash::default(),
                 FeeStructure::default().lamports_per_signature,
                 &rent_collector,
                 &mut error_counters,
                 &mock_bank,
-            );
+               );
 
             assert_eq!(error_counters.insufficient_funds.0, 1);
             assert_eq!(result, Err(TransactionError::InsufficientFundsForFee));
@@ -2647,15 +2659,14 @@ mod tests {
             Some(&fee_payer_address),
             &Hash::new_unique(),
         ));
-        let compute_budget_limits = process_compute_budget_instructions(
-            SVMMessage::program_instructions_iter(&message),
-            &FeatureSet::default(),
-        )
-        .unwrap();
         TransactionBatchProcessor::<TestForkGraph>::validate_transaction_nonce_and_fee_payer(
             &mut account_loader,
             &message,
-            CheckedTransactionDetails::new(None, 5000, Ok(compute_budget_limits)),
+            CheckedTransactionDetails::new(
+                None,
+                5000,
+                Ok(SVMTransactionExecutionAndFeeBudgetLimits::default()),
+            ),
             &Hash::default(),
             FeeStructure::default().lamports_per_signature,
             &RentCollector::default(),

+ 5 - 3
svm/tests/concurrent_tests.rs

@@ -11,8 +11,10 @@ use {
         sync::{Arc, RwLock},
         thread, Runner,
     },
-    solana_compute_budget::compute_budget_limits::ComputeBudgetLimits,
-    solana_program_runtime::loaded_programs::ProgramCacheEntryType,
+    solana_program_runtime::{
+        execution_budget::SVMTransactionExecutionAndFeeBudgetLimits,
+        loaded_programs::ProgramCacheEntryType,
+    },
     solana_sdk::{
         account::{AccountSharedData, ReadableAccount, WritableAccount},
         bpf_loader_upgradeable,
@@ -243,7 +245,7 @@ fn svm_concurrent() {
                 Ok(CheckedTransactionDetails::new(
                     None,
                     20,
-                    Ok(ComputeBudgetLimits::default())
+                    Ok(SVMTransactionExecutionAndFeeBudgetLimits::default())
                 )) as TransactionCheckResult;
                 TRANSACTIONS_PER_THREAD
             ];

+ 5 - 4
svm/tests/conformance.rs

@@ -6,10 +6,10 @@ use {
     lazy_static::lazy_static,
     prost::Message,
     solana_bpf_loader_program::syscalls::create_program_runtime_environment_v1,
-    solana_compute_budget::compute_budget::ComputeBudget,
     solana_feature_set::{FeatureSet, FEATURE_NAMES},
     solana_log_collector::LogCollector,
     solana_program_runtime::{
+        execution_budget::{SVMTransactionExecutionBudget, SVMTransactionExecutionCost},
         invoke_context::{EnvironmentConfig, InvokeContext},
         loaded_programs::{ProgramCacheEntry, ProgramCacheForTxBatch},
     },
@@ -215,9 +215,9 @@ fn run_fixture(fixture: InstrFixture, filename: OsString) {
 
     let transactions = vec![transaction];
 
-    let compute_budget = ComputeBudget {
+    let compute_budget = SVMTransactionExecutionBudget {
         compute_unit_limit: input.cu_avail,
-        ..ComputeBudget::default()
+        ..SVMTransactionExecutionBudget::default()
     };
 
     let v1_environment =
@@ -278,7 +278,7 @@ fn execute_fixture_as_instr(
     mock_bank: &MockBankCallback,
     batch_processor: &TransactionBatchProcessor<MockForkGraph>,
     sanitized_message: &SanitizedMessage,
-    compute_budget: ComputeBudget,
+    compute_budget: SVMTransactionExecutionBudget,
     output: &InstrEffects,
     filename: OsString,
     cu_avail: u64,
@@ -365,6 +365,7 @@ fn execute_fixture_as_instr(
         env_config,
         Some(log_collector.clone()),
         compute_budget,
+        SVMTransactionExecutionCost::default(),
     );
 
     let mut instruction_accounts: Vec<InstructionAccount> =

+ 10 - 7
svm/tests/integration_test.rs

@@ -8,8 +8,8 @@ use {
         WALLCLOCK_TIME,
     },
     solana_account::PROGRAM_OWNERS,
-    solana_compute_budget::compute_budget_limits::ComputeBudgetLimits,
     solana_compute_budget_instruction::instructions_processor::process_compute_budget_instructions,
+    solana_program_runtime::execution_budget::SVMTransactionExecutionAndFeeBudgetLimits,
     solana_sdk::{
         account::{AccountSharedData, ReadableAccount, WritableAccount},
         bpf_loader_upgradeable,
@@ -436,13 +436,16 @@ impl SvmTestEntry {
             .map(|item| {
                 let message = SanitizedTransaction::from_transaction_for_tests(item.transaction);
                 let check_result = item.check_result.map(|tx_details| {
+                    let compute_budget_limits = process_compute_budget_instructions(
+                        SVMMessage::program_instructions_iter(&message),
+                        &FeatureSet::default(),
+                    );
+                    let compute_budget =
+                        compute_budget_limits.map(|v| v.get_compute_budget_and_limits());
                     CheckedTransactionDetails::new(
                         tx_details.nonce,
                         tx_details.lamports_per_signature,
-                        process_compute_budget_instructions(
-                            SVMMessage::program_instructions_iter(&message),
-                            &FeatureSet::default(),
-                        ),
+                        compute_budget,
                     )
                 });
 
@@ -475,7 +478,7 @@ impl TransactionBatchItem {
             check_result: Ok(CheckedTransactionDetails::new(
                 Some(nonce_info),
                 LAMPORTS_PER_SIGNATURE,
-                Ok(ComputeBudgetLimits::default()),
+                Ok(SVMTransactionExecutionAndFeeBudgetLimits::default()),
             )),
             ..Self::default()
         }
@@ -489,7 +492,7 @@ impl Default for TransactionBatchItem {
             check_result: Ok(CheckedTransactionDetails::new(
                 None,
                 LAMPORTS_PER_SIGNATURE,
-                Ok(ComputeBudgetLimits::default()),
+                Ok(SVMTransactionExecutionAndFeeBudgetLimits::default()),
             )),
             asserts: TransactionBatchItemAsserts::default(),
         }

+ 2 - 2
svm/tests/mock_bank.rs

@@ -6,10 +6,10 @@ use {
         SyscallAbort, SyscallGetClockSysvar, SyscallGetRentSysvar, SyscallInvokeSignedRust,
         SyscallLog, SyscallMemcpy, SyscallMemset, SyscallSetReturnData,
     },
-    solana_compute_budget::compute_budget::ComputeBudget,
     solana_feature_set::FeatureSet,
     solana_fee_structure::FeeDetails,
     solana_program_runtime::{
+        execution_budget::{SVMTransactionExecutionBudget, SVMTransactionExecutionCost},
         invoke_context::InvokeContext,
         loaded_programs::{BlockRelation, ForkGraph, ProgramCacheEntry},
         solana_sbpf::{
@@ -350,7 +350,7 @@ pub fn register_builtins(
 }
 
 pub fn create_custom_loader<'a>() -> BuiltinProgram<InvokeContext<'a>> {
-    let compute_budget = ComputeBudget::default();
+    let compute_budget = SVMTransactionExecutionBudget::default();
     let vm_config = Config {
         max_call_depth: compute_budget.max_call_depth,
         stack_frame_size: compute_budget.stack_frame_size,