Skip to main content

solana_instruction_view/
lib.rs

1//! Lightweight types for directing the execution of Solana programs.
2//!
3//! This crate offers views and zero-copy types to interact with program
4//! instructions and accounts. As a result, it reduces compute units
5//! consumption. This is achieved by defining types that hold references
6//! instead of owning the required data.
7
8#![no_std]
9#![cfg_attr(docsrs, feature(doc_cfg))]
10
11#[cfg(feature = "cpi")]
12pub mod cpi;
13
14use {solana_account_view::AccountView, solana_address::Address};
15
16/// Information about an instruction.
17#[derive(Debug, Clone)]
18pub struct InstructionView<'a, 'b, 'c, 'd>
19where
20    'a: 'b,
21{
22    /// Address of the program.
23    pub program_id: &'c Address,
24
25    /// Data expected by the program instruction.
26    pub data: &'d [u8],
27
28    /// Metadata describing the accounts that should be passed to the program.
29    pub accounts: &'b [InstructionAccount<'a>],
30}
31
32/// Describes an account during instruction execution.
33///
34/// When constructing an [`InstructionView`], a list of all accounts that may be
35/// signer, read or written during the execution of that instruction must be supplied.
36/// Any account that may be mutated by the program during execution, either its
37/// data or metadata such as held lamports, must be writable.
38///
39/// Note that because the Solana runtime schedules parallel transaction
40/// execution around which accounts are writable, care should be taken that only
41/// accounts which actually may be mutated are specified as writable.
42#[repr(C)]
43#[derive(Debug, Clone)]
44pub struct InstructionAccount<'a> {
45    /// Address of the account.
46    pub address: &'a Address,
47
48    /// Indicates whether the account is writable or not.
49    pub is_writable: bool,
50
51    /// Indicates whether the account signed the instruction or not.
52    pub is_signer: bool,
53}
54
55impl<'a> InstructionAccount<'a> {
56    /// Creates a new `InstructionAccount`.
57    #[inline(always)]
58    pub const fn new(address: &'a Address, is_writable: bool, is_signer: bool) -> Self {
59        Self {
60            address,
61            is_writable,
62            is_signer,
63        }
64    }
65
66    /// Creates a new read-only `InstructionAccount`.
67    #[inline(always)]
68    pub const fn readonly(address: &'a Address) -> Self {
69        Self::new(address, false, false)
70    }
71
72    /// Creates a new writable `InstructionAccount`.
73    #[inline(always)]
74    pub const fn writable(address: &'a Address) -> Self {
75        Self::new(address, true, false)
76    }
77
78    /// Creates a new read-only and signer `InstructionAccount`.
79    #[inline(always)]
80    pub const fn readonly_signer(address: &'a Address) -> Self {
81        Self::new(address, false, true)
82    }
83
84    /// Creates a new writable and signer `InstructionAccount`.
85    #[inline(always)]
86    pub const fn writable_signer(address: &'a Address) -> Self {
87        Self::new(address, true, true)
88    }
89}
90
91impl<'a> From<&'a AccountView> for InstructionAccount<'a> {
92    fn from(account: &'a AccountView) -> Self {
93        InstructionAccount::new(
94            account.address(),
95            account.is_writable(),
96            account.is_signer(),
97        )
98    }
99}