Skip to main content

anchor_lang/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2
3//! Anchor ⚓ is a framework for Solana's Sealevel runtime providing several
4//! convenient developer tools.
5//!
6//! - Rust eDSL for writing safe, secure, and high level Solana programs
7//! - [IDL](https://en.wikipedia.org/wiki/Interface_description_language) specification
8//! - TypeScript package for generating clients from IDL
9//! - CLI and workspace management for developing complete applications
10//!
11//! If you're familiar with developing in Ethereum's
12//! [Solidity](https://docs.soliditylang.org/en/v0.7.4/),
13//! [Truffle](https://www.trufflesuite.com/),
14//! [web3.js](https://github.com/ethereum/web3.js) or Parity's
15//! [Ink!](https://github.com/paritytech/ink), then the experience will be
16//! familiar. Although the syntax and semantics are targeted at Solana, the high
17//! level workflow of writing RPC request handlers, emitting an IDL, and
18//! generating clients from IDL is the same.
19//!
20//! For detailed tutorials and examples on how to use Anchor, see the guided
21//! [tutorials](https://anchor-lang.com) or examples in the GitHub
22//! [repository](https://github.com/otter-sec/anchor).
23//!
24//! Presented here are the Rust primitives for building on Solana.
25
26extern crate self as anchor_lang;
27
28use {
29    crate::solana_program::{
30        account_info::AccountInfo, instruction::AccountMeta, program_error::ProgramError,
31        pubkey::Pubkey,
32    },
33    bytemuck::{Pod, Zeroable},
34    std::{collections::BTreeSet, fmt::Debug, io::Write},
35};
36
37mod account_meta;
38pub mod accounts;
39mod bpf_upgradeable_state;
40mod bpf_writer;
41mod common;
42#[doc(hidden)]
43pub mod compat;
44pub mod context;
45pub use anchor_lang_error as error;
46#[doc(hidden)]
47pub mod event;
48#[doc(hidden)]
49pub mod idl;
50pub mod system_program;
51mod vec;
52
53#[cfg(feature = "lazy-account")]
54mod lazy;
55
56/// Borsh is the default serialization format for instructions and accounts.
57pub use borsh::de::BorshDeserialize as AnchorDeserialize;
58pub use {
59    crate::bpf_upgradeable_state::*,
60    anchor_attribute_access_control::access_control,
61    anchor_attribute_account::{account, declare_id, pubkey, zero_copy},
62    anchor_attribute_constant::constant,
63    anchor_attribute_error::*,
64    anchor_attribute_event::{emit, event},
65    anchor_attribute_program::{declare_program, instruction, program},
66    anchor_derive_accounts::Accounts,
67    anchor_derive_serde::{__erase, AnchorDeserialize, AnchorSerialize},
68    anchor_derive_space::InitSpace,
69    borsh::ser::BorshSerialize as AnchorSerialize,
70    const_crypto::ed25519::derive_program_address,
71};
72
73pub mod solana_program {
74    pub use {
75        crate::compat::{
76            solana_clock as clock, solana_feature_gate_interface as feature,
77            solana_pubkey as pubkey,
78        },
79        solana_account_info as account_info,
80        solana_msg::msg,
81        solana_program_entrypoint::{self as entrypoint, entrypoint},
82        solana_program_error as program_error, solana_program_memory as program_memory,
83        solana_program_option as program_option, solana_program_pack as program_pack,
84        solana_sdk_ids::system_program,
85        solana_system_interface::instruction as system_instruction,
86    };
87    pub mod instruction {
88        pub use solana_instruction::*;
89        /// Get the current stack height, transaction-level instructions are height
90        /// TRANSACTION_LEVEL_STACK_HEIGHT, fist invoked inner instruction is height
91        /// TRANSACTION_LEVEL_STACK_HEIGHT + 1, etc...
92        pub fn get_stack_height() -> usize {
93            #[cfg(target_os = "solana")]
94            unsafe {
95                solana_instruction::syscalls::sol_get_stack_height() as usize
96            }
97
98            #[cfg(not(target_os = "solana"))]
99            {
100                crate::compat::solana_sysvar::program_stubs::sol_get_stack_height() as usize
101            }
102        }
103    }
104    pub mod rent {
105        pub use crate::compat::solana_sysvar::rent::*;
106    }
107    pub mod program {
108        pub use {
109            solana_cpi::*,
110            solana_invoke::{invoke, invoke_signed, invoke_signed_unchecked, invoke_unchecked},
111        };
112    }
113
114    pub mod bpf_loader_upgradeable {
115        #[allow(deprecated)]
116        pub use crate::compat::solana_loader_v3_interface::{
117            get_program_data_address,
118            instruction::{
119                close, close_any, create_buffer, deploy_with_max_program_len, extend_program,
120                is_close_instruction, is_set_authority_checked_instruction,
121                is_set_authority_instruction, is_upgrade_instruction, set_buffer_authority,
122                set_buffer_authority_checked, set_upgrade_authority, set_upgrade_authority_checked,
123                upgrade, write,
124            },
125            state::UpgradeableLoaderState,
126        };
127        pub use solana_sdk_ids::bpf_loader_upgradeable::{check_id, id, ID};
128    }
129
130    pub mod log {
131        pub use solana_msg::{msg, sol_log};
132        /// Print some slices as base64.
133        pub fn sol_log_data(data: &[&[u8]]) {
134            #[cfg(target_os = "solana")]
135            unsafe {
136                crate::compat::solana_define_syscall::definitions::sol_log_data(
137                    data as *const _ as *const u8,
138                    data.len() as u64,
139                )
140            };
141
142            #[cfg(not(target_os = "solana"))]
143            core::hint::black_box(data);
144        }
145    }
146    pub mod sysvar {
147        pub use solana_sysvar_id::{declare_deprecated_sysvar_id, declare_sysvar_id, SysvarId};
148        pub mod instructions {
149            #[cfg(not(target_os = "solana"))]
150            pub use crate::compat::solana_instructions_sysvar::construct_instructions_data;
151            pub use solana_instruction::{BorrowedAccountMeta, BorrowedInstruction};
152        }
153    }
154}
155
156#[cfg(feature = "event-cpi")]
157pub use anchor_attribute_event::{emit_cpi, event_cpi};
158#[cfg(feature = "idl-build")]
159pub use idl::IdlBuild;
160
161pub type Result<T> = std::result::Result<T, error::Error>;
162
163// Deprecated message for AccountInfo usage in Accounts struct
164#[deprecated(
165    note = "Use `UncheckedAccount` instead of `AccountInfo` for safer unchecked accounts."
166)]
167pub fn deprecated_account_info_usage() {}
168
169/// A data structure of validated accounts that can be deserialized from the
170/// input to a Solana program. Implementations of this trait should perform any
171/// and all requisite constraint checks on accounts to ensure the accounts
172/// maintain any invariants required for the program to run securely. In most
173/// cases, it's recommended to use the [`Accounts`](./derive.Accounts.html)
174/// derive macro to implement this trait.
175///
176/// Generics:
177/// -   `B`: the type of the PDA bumps cache struct generated by the `Accounts` struct.
178///     For example,
179/// ```rust,ignore
180/// pub struct Example<'info> {
181///     #[account(
182///         init,
183///         seeds = [...],
184///         bump,
185///     )]
186///     pub pda_1: UncheckedAccount<'info>,
187///     pub not_pda: UncheckedAccount<'info>,
188/// }
189/// ```
190///
191///    generates:
192///
193/// ```rust,ignore
194/// pub struct ExampleBumps {
195///     pub pda_1: u8,
196/// }
197/// ```
198pub trait Accounts<'info, B>: ToAccountMetas + ToAccountInfos<'info> + Sized {
199    /// Returns the validated accounts struct. What constitutes "valid" is
200    /// program dependent. However, users of these types should never have to
201    /// worry about account substitution attacks. For example, if a program
202    /// expects a `Mint` account from the SPL token program  in a particular
203    /// field, then it should be impossible for this method to return `Ok` if
204    /// any other account type is given--from the SPL token program or elsewhere.
205    ///
206    /// `program_id` is the currently executing program. `accounts` is the
207    /// set of accounts to construct the type from. For every account used,
208    /// the implementation should mutate the slice, consuming the used entry
209    /// so that it cannot be used again.
210    fn try_accounts(
211        program_id: &Pubkey,
212        accounts: &mut &'info [AccountInfo<'info>],
213        ix_data: &[u8],
214        bumps: &mut B,
215        reallocs: &mut BTreeSet<Pubkey>,
216    ) -> Result<Self>;
217}
218
219/// Associated bump seeds for `Accounts`.
220pub trait Bumps {
221    /// Struct to hold account bump seeds.
222    type Bumps: Sized + Debug;
223}
224
225/// The exit procedure for an account. Any cleanup or persistence to storage
226/// should be done here.
227pub trait AccountsExit<'info>: ToAccountMetas + ToAccountInfos<'info> {
228    /// `program_id` is the currently executing program.
229    fn exit(&self, _program_id: &Pubkey) -> Result<()> {
230        // no-op
231        Ok(())
232    }
233}
234
235/// Returns the pubkeys of mutable accounts that serialize on exit.
236/// Used by the duplicate mutable account validation to check across
237/// composite (nested) account struct boundaries.
238pub trait DuplicateMutableAccountKeys {
239    fn duplicate_mutable_account_keys(&self) -> Vec<Pubkey>;
240}
241
242/// The close procedure to initiate garbage collection of an account, allowing
243/// one to retrieve the rent exemption.
244pub trait AccountsClose<'info>: ToAccountInfos<'info> {
245    fn close(&self, sol_destination: AccountInfo<'info>) -> Result<()>;
246}
247
248/// Transformation to
249/// [`AccountMeta`](../solana_program/instruction/struct.AccountMeta.html)
250/// structs.
251pub trait ToAccountMetas {
252    /// `is_signer` is given as an optional override for the signer meta field.
253    /// This covers the edge case when a program-derived-address needs to relay
254    /// a transaction from a client to another program but sign the transaction
255    /// before the relay. The client cannot mark the field as a signer, and so
256    /// we have to override the is_signer meta field given by the client.
257    fn to_account_metas(&self, is_signer: Option<bool>) -> Vec<AccountMeta>;
258}
259
260/// Transformation to
261/// [`AccountInfo`](../solana_program/account_info/struct.AccountInfo.html)
262/// structs.
263pub trait ToAccountInfos<'info> {
264    fn to_account_infos(&self) -> Vec<AccountInfo<'info>>;
265}
266
267/// Transformation to an `AccountInfo` struct.
268pub trait ToAccountInfo<'info> {
269    fn to_account_info(&self) -> AccountInfo<'info>;
270}
271
272impl<'info, T> ToAccountInfo<'info> for T
273where
274    T: AsRef<AccountInfo<'info>>,
275{
276    fn to_account_info(&self) -> AccountInfo<'info> {
277        self.as_ref().clone()
278    }
279}
280
281/// Lamports related utility methods for accounts.
282pub trait Lamports<'info>: AsRef<AccountInfo<'info>> {
283    /// Get the lamports of the account.
284    fn get_lamports(&self) -> u64 {
285        self.as_ref().lamports()
286    }
287
288    /// Add lamports to the account.
289    ///
290    /// This method is useful for transferring lamports from a PDA.
291    ///
292    /// # Requirements
293    ///
294    /// 1. The account must be marked `mut`.
295    /// 2. The total lamports **before** the transaction must equal to total lamports **after**
296    ///    the transaction.
297    /// 3. `lamports` field of the account info should not currently be borrowed.
298    ///
299    /// See [`Lamports::sub_lamports`] for subtracting lamports.
300    fn add_lamports(&self, amount: u64) -> Result<&Self> {
301        **self.as_ref().try_borrow_mut_lamports()? = self
302            .get_lamports()
303            .checked_add(amount)
304            .ok_or(ProgramError::ArithmeticOverflow)?;
305        Ok(self)
306    }
307
308    /// Subtract lamports from the account.
309    ///
310    /// This method is useful for transferring lamports from a PDA.
311    ///
312    /// # Requirements
313    ///
314    /// 1. The account must be owned by the executing program.
315    /// 2. The account must be marked `mut`.
316    /// 3. The total lamports **before** the transaction must equal to total lamports **after**
317    ///    the transaction.
318    /// 4. `lamports` field of the account info should not currently be borrowed.
319    ///
320    /// See [`Lamports::add_lamports`] for adding lamports.
321    fn sub_lamports(&self, amount: u64) -> Result<&Self> {
322        **self.as_ref().try_borrow_mut_lamports()? = self
323            .get_lamports()
324            .checked_sub(amount)
325            .ok_or(ProgramError::ArithmeticOverflow)?;
326        Ok(self)
327    }
328}
329
330impl<'info, T: AsRef<AccountInfo<'info>>> Lamports<'info> for T {}
331
332/// A data structure that can be serialized and stored into account storage,
333/// i.e. an
334/// [`AccountInfo`](../solana_program/account_info/struct.AccountInfo.html#structfield.data)'s
335/// mutable data slice.
336///
337/// Implementors of this trait should ensure that any subsequent usage of the
338/// `AccountDeserialize` trait succeeds if and only if the account is of the
339/// correct type.
340///
341/// In most cases, one can use the default implementation provided by the
342/// [`#[account]`](./attr.account.html) attribute.
343pub trait AccountSerialize {
344    /// Serializes the account data into `writer`.
345    fn try_serialize<W: Write>(&self, _writer: &mut W) -> Result<()> {
346        Ok(())
347    }
348}
349
350/// A data structure that can be deserialized and stored into account storage,
351/// i.e. an
352/// [`AccountInfo`](../solana_program/account_info/struct.AccountInfo.html#structfield.data)'s
353/// mutable data slice.
354pub trait AccountDeserialize: Sized {
355    /// Deserializes previously initialized account data. Should fail for all
356    /// uninitialized accounts, where the bytes are zeroed. Implementations
357    /// should be unique to a particular account type so that one can never
358    /// successfully deserialize the data of one account type into another.
359    /// For example, if the SPL token program were to implement this trait,
360    /// it should be impossible to deserialize a `Mint` account into a token
361    /// `Account`.
362    fn try_deserialize(buf: &mut &[u8]) -> Result<Self> {
363        Self::try_deserialize_unchecked(buf)
364    }
365
366    /// Deserializes account data without checking the account discriminator.
367    /// This should only be used on account initialization, when the bytes of
368    /// the account are zeroed.
369    fn try_deserialize_unchecked(buf: &mut &[u8]) -> Result<Self>;
370}
371
372/// An account data structure capable of zero copy deserialization.
373pub trait ZeroCopy: Discriminator + Copy + Clone + Zeroable + Pod {}
374
375/// Calculates the data for an instruction invocation, where the data is
376/// `Discriminator + BorshSerialize(args)`. `args` is a borsh serialized
377/// struct of named fields for each argument given to an instruction.
378pub trait InstructionData: Discriminator + AnchorSerialize {
379    fn data(&self) -> Vec<u8> {
380        let mut data = Vec::with_capacity(256);
381        data.extend_from_slice(Self::DISCRIMINATOR);
382        self.serialize(&mut data).unwrap();
383        data
384    }
385
386    /// Clears `data` and writes instruction data to it.
387    ///
388    /// We use a `Vec<u8>` here because of the additional flexibility of re-allocation (only if
389    /// necessary), and because the data field in `Instruction` expects a `Vec<u8>`.
390    fn write_to(&self, mut data: &mut Vec<u8>) {
391        data.clear();
392        data.extend_from_slice(Self::DISCRIMINATOR);
393        self.serialize(&mut data).unwrap()
394    }
395}
396
397/// An event that can be emitted via a Solana log. See [`emit!`](crate::prelude::emit) for an example.
398pub trait Event: AnchorSerialize + AnchorDeserialize + Discriminator {
399    fn data(&self) -> Vec<u8>;
400}
401
402/// Unique identifier for a type.
403///
404/// This is not a trait you should derive manually, as various Anchor macros already derive it
405/// internally.
406///
407/// Prior to Anchor v0.31, discriminators were always 8 bytes in size. However, starting with Anchor
408/// v0.31, it is possible to override the default discriminators, and discriminator length is no
409/// longer fixed, which means this trait can also be implemented for non-Anchor programs.
410///
411/// It's important that the discriminator is always unique for the type you're implementing it
412/// for. While the discriminator can be at any length (including zero), the IDL generation does not
413/// currently allow empty discriminators for safety and convenience reasons. However, the trait
414/// definition still allows empty discriminators because some non-Anchor programs, e.g. the SPL
415/// Token program, don't have account discriminators. In that case, safety checks should never
416/// depend on the discriminator.
417pub trait Discriminator {
418    /// Discriminator slice.
419    ///
420    /// See [`Discriminator`] trait documentation for more information.
421    const DISCRIMINATOR: &'static [u8];
422}
423
424/// Defines the space of an account for initialization.
425pub trait Space {
426    const INIT_SPACE: usize;
427}
428
429// Implement Space for primitive types
430impl Space for bool {
431    const INIT_SPACE: usize = 1;
432}
433
434impl Space for u8 {
435    const INIT_SPACE: usize = 1;
436}
437
438impl Space for u16 {
439    const INIT_SPACE: usize = 2;
440}
441
442impl Space for u32 {
443    const INIT_SPACE: usize = 4;
444}
445
446impl Space for u64 {
447    const INIT_SPACE: usize = 8;
448}
449
450impl Space for u128 {
451    const INIT_SPACE: usize = 16;
452}
453
454impl Space for i8 {
455    const INIT_SPACE: usize = 1;
456}
457
458impl Space for i16 {
459    const INIT_SPACE: usize = 2;
460}
461
462impl Space for i32 {
463    const INIT_SPACE: usize = 4;
464}
465
466impl Space for i64 {
467    const INIT_SPACE: usize = 8;
468}
469
470impl Space for i128 {
471    const INIT_SPACE: usize = 16;
472}
473
474impl Space for f32 {
475    const INIT_SPACE: usize = 4;
476}
477
478impl Space for f64 {
479    const INIT_SPACE: usize = 8;
480}
481
482impl Space for Pubkey {
483    const INIT_SPACE: usize = 32;
484}
485
486/// Bump seed for program derived addresses.
487pub trait Bump {
488    fn seed(&self) -> u8;
489}
490
491/// Defines an address expected to own an account.
492pub trait Owner {
493    fn owner() -> Pubkey;
494}
495
496/// Defines a list of addresses expected to own an account.
497pub trait Owners {
498    fn owners() -> &'static [Pubkey];
499}
500
501/// Defines a trait for checking the owner of a program.
502pub trait CheckOwner {
503    fn check_owner(owner: &Pubkey) -> Result<()>;
504}
505
506impl<T: Owners> CheckOwner for T {
507    fn check_owner(owner: &Pubkey) -> Result<()> {
508        if !Self::owners().contains(owner) {
509            Err(
510                error::Error::from(error::ErrorCode::AccountOwnedByWrongProgram)
511                    .with_account_name(*owner),
512            )
513        } else {
514            Ok(())
515        }
516    }
517}
518
519/// Defines the id of a program.
520pub trait Id {
521    fn id() -> Pubkey;
522}
523
524/// Defines the possible ids of a program.
525pub trait Ids {
526    fn ids() -> &'static [Pubkey];
527}
528
529/// Defines a trait for checking the id of a program.
530pub trait CheckId {
531    fn check_id(id: &Pubkey) -> Result<()>;
532}
533
534impl<T: Ids> CheckId for T {
535    fn check_id(id: &Pubkey) -> Result<()> {
536        if !Self::ids().contains(id) {
537            Err(error::Error::from(error::ErrorCode::InvalidProgramId).with_account_name(*id))
538        } else {
539            Ok(())
540        }
541    }
542}
543
544/// Defines the Pubkey of an account.
545pub trait Key {
546    fn key(&self) -> Pubkey;
547}
548
549impl Key for Pubkey {
550    fn key(&self) -> Pubkey {
551        *self
552    }
553}
554
555/// The prelude contains all commonly used components of the crate.
556/// All programs should include it via `anchor_lang::prelude::*;`.
557pub mod prelude {
558    #[cfg(feature = "lazy-account")]
559    pub use super::accounts::lazy_account::LazyAccount;
560    #[cfg(feature = "idl-build")]
561    pub use super::idl::IdlBuild;
562    #[cfg(feature = "event-cpi")]
563    pub use super::{emit_cpi, event_cpi};
564    // Re-export the crate as anchor_lang for declare_program! macro
565    pub use crate as anchor_lang;
566    pub use {
567        super::{
568            access_control, account,
569            accounts::{
570                account::Account, account_loader::AccountLoader, interface::Interface,
571                interface_account::InterfaceAccount, migration::Migration, program::Program,
572                signer::Signer, system_account::SystemAccount, sysvar::Sysvar,
573                unchecked_account::UncheckedAccount,
574            },
575            constant,
576            context::{Context, CpiContext},
577            declare_id, declare_program, emit, err, error, event, instruction, program, pubkey,
578            require, require_eq, require_gt, require_gte, require_keys_eq, require_keys_neq,
579            require_neq,
580            solana_program::bpf_loader_upgradeable::UpgradeableLoaderState,
581            source,
582            system_program::System,
583            zero_copy, AccountDeserialize, AccountSerialize, Accounts, AccountsClose, AccountsExit,
584            AnchorDeserialize, AnchorSerialize, Discriminator, DuplicateMutableAccountKeys, Id,
585            InitSpace, Key, Lamports, Owner, Owners, ProgramData, Result, Space, ToAccountInfo,
586            ToAccountInfos, ToAccountMetas,
587        },
588        crate::{
589            compat::{
590                solana_clock::Clock,
591                solana_instructions_sysvar::Instructions,
592                solana_stake_interface::stake_history::StakeHistory,
593                solana_sysvar::{
594                    epoch_schedule::EpochSchedule, rent::Rent, rewards::Rewards,
595                    slot_hashes::SlotHashes, slot_history::SlotHistory, Sysvar as SolanaSysvar,
596                },
597            },
598            solana_program::{
599                account_info::{next_account_info, AccountInfo},
600                instruction::AccountMeta,
601                program_error::ProgramError,
602                pubkey::Pubkey,
603                *,
604            },
605        },
606        anchor_attribute_error::*,
607        borsh,
608        error::*,
609        thiserror,
610    };
611}
612
613/// Internal module used by macros and unstable apis.
614#[doc(hidden)]
615pub mod __private {
616    use crate::solana_program::pubkey::Pubkey;
617    pub use {
618        crate::{bpf_writer::BpfWriter, common::is_closed},
619        anchor_attribute_account::ZeroCopyAccessor,
620        base64, bytemuck,
621    };
622
623    // Used to calculate the maximum between two expressions.
624    // It is necessary for the calculation of the enum space.
625    #[doc(hidden)]
626    pub const fn max(a: usize, b: usize) -> usize {
627        [a, b][(a < b) as usize]
628    }
629
630    // Very experimental trait.
631    #[doc(hidden)]
632    pub trait ZeroCopyAccessor<Ty> {
633        fn get(&self) -> Ty;
634        fn set(input: &Ty) -> Self;
635    }
636
637    #[doc(hidden)]
638    impl ZeroCopyAccessor<Pubkey> for [u8; 32] {
639        fn get(&self) -> Pubkey {
640            Pubkey::from(*self)
641        }
642        fn set(input: &Pubkey) -> [u8; 32] {
643            input.to_bytes()
644        }
645    }
646
647    #[cfg(feature = "lazy-account")]
648    pub use crate::lazy::Lazy;
649    #[cfg(feature = "lazy-account")]
650    pub use anchor_derive_serde::Lazy;
651
652    /// Trait for compile-time type equality checking.
653    /// Used to enforce that instruction argument types match the `#[instruction(...)]` attribute types.
654    #[doc(hidden)]
655    #[diagnostic::on_unimplemented(
656        message = "instruction handler argument type `{Self}` does not match \
657                   `#[instruction(...)]` attribute type `{T}`",
658        label = "expected `{T}` here based on `#[instruction(...)]` attribute, found `{Self}`",
659        note = "ensure `#[instruction(..)]` argument types match those of the instruction handler"
660    )]
661    pub trait IsSameType<T> {}
662
663    impl<T> IsSameType<T> for T {}
664
665    #[doc(hidden)]
666    #[derive(Debug, Clone, Copy)]
667    pub struct CpiReturnData {
668        program_id: Option<Pubkey>,
669        data_len: usize,
670        data: [u8; crate::solana_program::program::MAX_RETURN_DATA],
671    }
672
673    impl CpiReturnData {
674        #[doc(hidden)]
675        pub fn new(return_data: Option<(Pubkey, Vec<u8>)>) -> Self {
676            let mut snapshot = Self {
677                program_id: None,
678                data_len: 0,
679                data: [0u8; crate::solana_program::program::MAX_RETURN_DATA],
680            };
681
682            if let Some((program_id, data)) = return_data {
683                let data_len = data.len();
684                snapshot.data[..data_len].copy_from_slice(&data);
685                snapshot.program_id = Some(program_id);
686                snapshot.data_len = data_len;
687            }
688
689            snapshot
690        }
691
692        #[doc(hidden)]
693        pub fn snapshot() -> Self {
694            Self::new(crate::solana_program::program::get_return_data())
695        }
696
697        #[doc(hidden)]
698        pub fn get<T: crate::AnchorDeserialize>(&self, expected_program_id: Pubkey) -> T {
699            let program_id = self.program_id.unwrap();
700            if program_id != expected_program_id {
701                crate::solana_program::log::sol_log("CPI return data program_id mismatch");
702                panic!();
703            }
704
705            T::try_from_slice(&self.data[..self.data_len]).unwrap()
706        }
707
708        #[doc(hidden)]
709        pub fn return_data(&self) -> Option<(Pubkey, &[u8])> {
710            self.program_id
711                .map(|program_id| (program_id, &self.data[..self.data_len]))
712        }
713    }
714}
715
716/// Ensures a condition is true, otherwise returns with the given error.
717/// Use this with or without a custom error type.
718///
719/// # Example
720/// ```ignore
721/// // Instruction function
722/// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
723///     require!(ctx.accounts.data.mutation_allowed, MyError::MutationForbidden);
724///     ctx.accounts.data.data = data;
725///     Ok(())
726/// }
727///
728/// // An enum for custom error codes
729/// #[error_code]
730/// pub enum MyError {
731///     MutationForbidden
732/// }
733///
734/// // An account definition
735/// #[account]
736/// #[derive(Default)]
737/// pub struct MyData {
738///     mutation_allowed: bool,
739///     data: u64
740/// }
741///
742/// // An account validation struct
743/// #[derive(Accounts)]
744/// pub struct SetData<'info> {
745///     #[account(mut)]
746///     pub data: Account<'info, MyData>
747/// }
748/// ```
749#[macro_export]
750macro_rules! require {
751    ($invariant:expr, $error:tt $(,)?) => {
752        if !($invariant) {
753            return Err(anchor_lang::error!($crate::ErrorCode::$error));
754        }
755    };
756    ($invariant:expr, $error:expr $(,)?) => {
757        if !($invariant) {
758            return Err(anchor_lang::error!($error));
759        }
760    };
761}
762
763/// Ensures two NON-PUBKEY values are equal.
764///
765/// Use [require_keys_eq](crate::prelude::require_keys_eq)
766/// to compare two pubkeys.
767///
768/// Can be used with or without a custom error code.
769///
770/// # Example
771/// ```rust,ignore
772/// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
773///     require_eq!(ctx.accounts.data.data, 0);
774///     ctx.accounts.data.data = data;
775///     Ok(())
776/// }
777/// ```
778#[macro_export]
779macro_rules! require_eq {
780    ($value1: expr, $value2: expr, $error_code:expr $(,)?) => {
781        if $value1 != $value2 {
782            return Err(anchor_lang::error!($error_code).with_values(($value1, $value2)));
783        }
784    };
785    ($value1: expr, $value2: expr $(,)?) => {
786        if $value1 != $value2 {
787            return Err(error!(anchor_lang::error::ErrorCode::RequireEqViolated)
788                .with_values(($value1, $value2)));
789        }
790    };
791}
792
793/// Ensures two NON-PUBKEY values are not equal.
794///
795/// Use [require_keys_neq](crate::prelude::require_keys_neq)
796/// to compare two pubkeys.
797///
798/// Can be used with or without a custom error code.
799///
800/// # Example
801/// ```rust,ignore
802/// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
803///     require_neq!(ctx.accounts.data.data, 0);
804///     ctx.accounts.data.data = data;
805///     Ok(());
806/// }
807/// ```
808#[macro_export]
809macro_rules! require_neq {
810    ($value1: expr, $value2: expr, $error_code: expr $(,)?) => {
811        if $value1 == $value2 {
812            return Err(anchor_lang::error!($error_code).with_values(($value1, $value2)));
813        }
814    };
815    ($value1: expr, $value2: expr $(,)?) => {
816        if $value1 == $value2 {
817            return Err(error!(anchor_lang::error::ErrorCode::RequireNeqViolated)
818                .with_values(($value1, $value2)));
819        }
820    };
821}
822
823/// Ensures two pubkeys values are equal.
824///
825/// Use [require_eq](crate::prelude::require_eq)
826/// to compare two non-pubkey values.
827///
828/// Can be used with or without a custom error code.
829///
830/// # Example
831/// ```rust,ignore
832/// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
833///     require_keys_eq!(ctx.accounts.data.authority.key(), ctx.accounts.authority.key());
834///     ctx.accounts.data.data = data;
835///     Ok(())
836/// }
837/// ```
838#[macro_export]
839macro_rules! require_keys_eq {
840    ($value1: expr, $value2: expr, $error_code:expr $(,)?) => {
841        if $value1 != $value2 {
842            return Err(anchor_lang::error!($error_code).with_pubkeys(($value1, $value2)));
843        }
844    };
845    ($value1: expr, $value2: expr $(,)?) => {
846        if $value1 != $value2 {
847            return Err(error!(anchor_lang::error::ErrorCode::RequireKeysEqViolated)
848                .with_pubkeys(($value1, $value2)));
849        }
850    };
851}
852
853/// Ensures two pubkeys are not equal.
854///
855/// Use [require_neq](crate::prelude::require_neq)
856/// to compare two non-pubkey values.
857///
858/// Can be used with or without a custom error code.
859///
860/// # Example
861/// ```rust,ignore
862/// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
863///     require_keys_neq!(ctx.accounts.data.authority.key(), ctx.accounts.other.key());
864///     ctx.accounts.data.data = data;
865///     Ok(())
866/// }
867/// ```
868#[macro_export]
869macro_rules! require_keys_neq {
870    ($value1: expr, $value2: expr, $error_code: expr $(,)?) => {
871        if $value1 == $value2 {
872            return Err(anchor_lang::error!($error_code).with_pubkeys(($value1, $value2)));
873        }
874    };
875    ($value1: expr, $value2: expr $(,)?) => {
876        if $value1 == $value2 {
877            return Err(
878                error!(anchor_lang::error::ErrorCode::RequireKeysNeqViolated)
879                    .with_pubkeys(($value1, $value2)),
880            );
881        }
882    };
883}
884
885/// Ensures the first NON-PUBKEY value is greater than the second
886/// NON-PUBKEY value.
887///
888/// To include an equality check, use [require_gte](crate::require_gte).
889///
890/// Can be used with or without a custom error code.
891///
892/// # Example
893/// ```rust,ignore
894/// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
895///     require_gt!(ctx.accounts.data.data, 0);
896///     ctx.accounts.data.data = data;
897///     Ok(());
898/// }
899/// ```
900#[macro_export]
901macro_rules! require_gt {
902    ($value1: expr, $value2: expr, $error_code: expr $(,)?) => {
903        if $value1 <= $value2 {
904            return Err(anchor_lang::error!($error_code).with_values(($value1, $value2)));
905        }
906    };
907    ($value1: expr, $value2: expr $(,)?) => {
908        if $value1 <= $value2 {
909            return Err(error!(anchor_lang::error::ErrorCode::RequireGtViolated)
910                .with_values(($value1, $value2)));
911        }
912    };
913}
914
915/// Ensures the first NON-PUBKEY value is greater than or equal
916/// to the second NON-PUBKEY value.
917///
918/// Can be used with or without a custom error code.
919///
920/// # Example
921/// ```rust,ignore
922/// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
923///     require_gte!(ctx.accounts.data.data, 1);
924///     ctx.accounts.data.data = data;
925///     Ok(());
926/// }
927/// ```
928#[macro_export]
929macro_rules! require_gte {
930    ($value1: expr, $value2: expr, $error_code: expr $(,)?) => {
931        if $value1 < $value2 {
932            return Err(anchor_lang::error!($error_code).with_values(($value1, $value2)));
933        }
934    };
935    ($value1: expr, $value2: expr $(,)?) => {
936        if $value1 < $value2 {
937            return Err(error!(anchor_lang::error::ErrorCode::RequireGteViolated)
938                .with_values(($value1, $value2)));
939        }
940    };
941}
942
943/// Returns with the given error.
944/// Use this with a custom error type.
945///
946/// # Example
947/// ```ignore
948/// // Instruction function
949/// pub fn example(ctx: Context<Example>) -> Result<()> {
950///     err!(MyError::SomeError)
951/// }
952///
953/// // An enum for custom error codes
954/// #[error_code]
955/// pub enum MyError {
956///     SomeError
957/// }
958///
959/// #[derive(Accounts)]
960/// pub struct Example {}
961/// ```
962#[macro_export]
963macro_rules! err {
964    ($error:tt $(,)?) => {
965        Err(anchor_lang::error!($crate::ErrorCode::$error))
966    };
967    ($error:expr $(,)?) => {
968        Err(anchor_lang::error!($error))
969    };
970}
971
972/// Creates a [`Source`](crate::error::Source)
973#[macro_export]
974macro_rules! source {
975    () => {
976        anchor_lang::error::Source {
977            filename: file!(),
978            line: line!(),
979        }
980    };
981}