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}