solana_compute_budget_interface/
lib.rs

1//! Instructions for the compute budget native program.
2#![cfg_attr(docsrs, feature(doc_auto_cfg))]
3#![cfg_attr(feature = "frozen-abi", feature(min_specialization))]
4
5#[cfg(feature = "borsh")]
6use borsh::{BorshDeserialize, BorshSerialize};
7use solana_instruction::Instruction;
8pub use solana_sdk_ids::compute_budget::{check_id, id, ID};
9
10/// Compute Budget Instructions
11#[cfg_attr(
12    feature = "frozen-abi",
13    derive(
14        solana_frozen_abi_macro::AbiExample,
15        solana_frozen_abi_macro::AbiEnumVisitor
16    )
17)]
18#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
19#[cfg_attr(
20    feature = "serde",
21    derive(serde_derive::Deserialize, serde_derive::Serialize)
22)]
23#[derive(Clone, Debug, PartialEq, Eq)]
24pub enum ComputeBudgetInstruction {
25    Unused, // deprecated variant, reserved value.
26    /// Request a specific transaction-wide program heap region size in bytes.
27    /// The value requested must be a multiple of 1024. This new heap region
28    /// size applies to each program executed in the transaction, including all
29    /// calls to CPIs.
30    RequestHeapFrame(u32),
31    /// Set a specific compute unit limit that the transaction is allowed to consume.
32    SetComputeUnitLimit(u32),
33    /// Set a compute unit price in "micro-lamports" to pay a higher transaction
34    /// fee for higher transaction prioritization.
35    SetComputeUnitPrice(u64),
36    /// Set a specific transaction-wide account data size limit, in bytes, is allowed to load.
37    SetLoadedAccountsDataSizeLimit(u32),
38}
39
40macro_rules! to_instruction {
41    ($discriminator: expr, $num: expr, $num_type: ty) => {{
42        let mut data = [0u8; ::core::mem::size_of::<$num_type>() + 1];
43        data[0] = $discriminator;
44        data[1..].copy_from_slice(&$num.to_le_bytes());
45        Instruction {
46            program_id: id(),
47            data: data.to_vec(),
48            accounts: vec![],
49        }
50    }};
51}
52
53impl ComputeBudgetInstruction {
54    /// Create a `ComputeBudgetInstruction::RequestHeapFrame` `Instruction`
55    pub fn request_heap_frame(bytes: u32) -> Instruction {
56        to_instruction!(1, bytes, u32)
57    }
58
59    /// Create a `ComputeBudgetInstruction::SetComputeUnitLimit` `Instruction`
60    pub fn set_compute_unit_limit(units: u32) -> Instruction {
61        to_instruction!(2, units, u32)
62    }
63
64    /// Create a `ComputeBudgetInstruction::SetComputeUnitPrice` `Instruction`
65    pub fn set_compute_unit_price(micro_lamports: u64) -> Instruction {
66        to_instruction!(3, micro_lamports, u64)
67    }
68
69    /// Serialize Instruction using borsh, this is only used in runtime::cost_model::tests but compilation
70    /// can't be restricted as it's used across packages
71    #[cfg(feature = "dev-context-only-utils")]
72    pub fn pack(self) -> Result<Vec<u8>, borsh::io::Error> {
73        borsh::to_vec(&self)
74    }
75
76    /// Create a `ComputeBudgetInstruction::SetLoadedAccountsDataSizeLimit` `Instruction`
77    pub fn set_loaded_accounts_data_size_limit(bytes: u32) -> Instruction {
78        to_instruction!(4, bytes, u32)
79    }
80}
81
82#[cfg(test)]
83mod tests {
84    use super::*;
85
86    #[test]
87    fn test_to_instruction() {
88        let ix = ComputeBudgetInstruction::set_compute_unit_limit(257);
89        assert_eq!(ix.data, vec![2, 1, 1, 0, 0]);
90        let ix = ComputeBudgetInstruction::set_compute_unit_price(u64::MAX);
91        assert_eq!(ix.data, vec![3, 255, 255, 255, 255, 255, 255, 255, 255]);
92    }
93}