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