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