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/solana-foundation/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 mod 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/// Bump seed for program derived addresses.
426pub trait Bump {
427 fn seed(&self) -> u8;
428}
429
430/// Defines an address expected to own an account.
431pub trait Owner {
432 fn owner() -> Pubkey;
433}
434
435/// Defines a list of addresses expected to own an account.
436pub trait Owners {
437 fn owners() -> &'static [Pubkey];
438}
439
440/// Defines a trait for checking the owner of a program.
441pub trait CheckOwner {
442 fn check_owner(owner: &Pubkey) -> Result<()>;
443}
444
445impl<T: Owners> CheckOwner for T {
446 fn check_owner(owner: &Pubkey) -> Result<()> {
447 if !Self::owners().contains(owner) {
448 Err(
449 error::Error::from(error::ErrorCode::AccountOwnedByWrongProgram)
450 .with_account_name(*owner),
451 )
452 } else {
453 Ok(())
454 }
455 }
456}
457
458/// Defines the id of a program.
459pub trait Id {
460 fn id() -> Pubkey;
461}
462
463/// Defines the possible ids of a program.
464pub trait Ids {
465 fn ids() -> &'static [Pubkey];
466}
467
468/// Defines a trait for checking the id of a program.
469pub trait CheckId {
470 fn check_id(id: &Pubkey) -> Result<()>;
471}
472
473impl<T: Ids> CheckId for T {
474 fn check_id(id: &Pubkey) -> Result<()> {
475 if !Self::ids().contains(id) {
476 Err(error::Error::from(error::ErrorCode::InvalidProgramId).with_account_name(*id))
477 } else {
478 Ok(())
479 }
480 }
481}
482
483/// Defines the Pubkey of an account.
484pub trait Key {
485 fn key(&self) -> Pubkey;
486}
487
488impl Key for Pubkey {
489 fn key(&self) -> Pubkey {
490 *self
491 }
492}
493
494/// The prelude contains all commonly used components of the crate.
495/// All programs should include it via `anchor_lang::prelude::*;`.
496pub mod prelude {
497 #[cfg(feature = "lazy-account")]
498 pub use super::accounts::lazy_account::LazyAccount;
499 #[cfg(feature = "idl-build")]
500 pub use super::idl::IdlBuild;
501 #[cfg(feature = "event-cpi")]
502 pub use super::{emit_cpi, event_cpi};
503 // Re-export the crate as anchor_lang for declare_program! macro
504 pub use crate as anchor_lang;
505 pub use {
506 super::{
507 access_control, account,
508 accounts::{
509 account::Account, account_loader::AccountLoader, interface::Interface,
510 interface_account::InterfaceAccount, migration::Migration, program::Program,
511 signer::Signer, system_account::SystemAccount, sysvar::Sysvar,
512 unchecked_account::UncheckedAccount,
513 },
514 constant,
515 context::{Context, CpiContext},
516 declare_id, declare_program, emit, err, error, event, instruction, program, pubkey,
517 require, require_eq, require_gt, require_gte, require_keys_eq, require_keys_neq,
518 require_neq,
519 solana_program::bpf_loader_upgradeable::UpgradeableLoaderState,
520 source,
521 system_program::System,
522 zero_copy, AccountDeserialize, AccountSerialize, Accounts, AccountsClose, AccountsExit,
523 AnchorDeserialize, AnchorSerialize, Discriminator, DuplicateMutableAccountKeys, Id,
524 InitSpace, Key, Lamports, Owner, Owners, ProgramData, Result, Space, ToAccountInfo,
525 ToAccountInfos, ToAccountMetas,
526 },
527 crate::solana_program::{
528 account_info::{next_account_info, AccountInfo},
529 instruction::AccountMeta,
530 program_error::ProgramError,
531 pubkey::Pubkey,
532 *,
533 },
534 anchor_attribute_error::*,
535 borsh,
536 error::*,
537 solana_clock::Clock,
538 solana_instructions_sysvar::Instructions,
539 solana_stake_interface::stake_history::StakeHistory,
540 solana_sysvar::{
541 epoch_schedule::EpochSchedule, rent::Rent, rewards::Rewards, slot_hashes::SlotHashes,
542 slot_history::SlotHistory, Sysvar as SolanaSysvar,
543 },
544 thiserror,
545 };
546}
547
548/// Internal module used by macros and unstable apis.
549#[doc(hidden)]
550pub mod __private {
551 use crate::solana_program::pubkey::Pubkey;
552 pub use {
553 crate::{bpf_writer::BpfWriter, common::is_closed},
554 anchor_attribute_account::ZeroCopyAccessor,
555 base64, bytemuck,
556 };
557
558 // Used to calculate the maximum between two expressions.
559 // It is necessary for the calculation of the enum space.
560 #[doc(hidden)]
561 pub const fn max(a: usize, b: usize) -> usize {
562 [a, b][(a < b) as usize]
563 }
564
565 // Very experimental trait.
566 #[doc(hidden)]
567 pub trait ZeroCopyAccessor<Ty> {
568 fn get(&self) -> Ty;
569 fn set(input: &Ty) -> Self;
570 }
571
572 #[doc(hidden)]
573 impl ZeroCopyAccessor<Pubkey> for [u8; 32] {
574 fn get(&self) -> Pubkey {
575 Pubkey::from(*self)
576 }
577 fn set(input: &Pubkey) -> [u8; 32] {
578 input.to_bytes()
579 }
580 }
581
582 #[cfg(feature = "lazy-account")]
583 pub use crate::lazy::Lazy;
584 #[cfg(feature = "lazy-account")]
585 pub use anchor_derive_serde::Lazy;
586
587 /// Trait for compile-time type equality checking.
588 /// Used to enforce that instruction argument types match the `#[instruction(...)]` attribute types.
589 #[doc(hidden)]
590 #[diagnostic::on_unimplemented(
591 message = "instruction handler argument type `{Self}` does not match \
592 `#[instruction(...)]` attribute type `{T}`",
593 label = "expected `{T}` here based on `#[instruction(...)]` attribute, found `{Self}`",
594 note = "ensure `#[instruction(..)]` argument types match those of the instruction handler"
595 )]
596 pub trait IsSameType<T> {}
597
598 impl<T> IsSameType<T> for T {}
599}
600
601/// Ensures a condition is true, otherwise returns with the given error.
602/// Use this with or without a custom error type.
603///
604/// # Example
605/// ```ignore
606/// // Instruction function
607/// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
608/// require!(ctx.accounts.data.mutation_allowed, MyError::MutationForbidden);
609/// ctx.accounts.data.data = data;
610/// Ok(())
611/// }
612///
613/// // An enum for custom error codes
614/// #[error_code]
615/// pub enum MyError {
616/// MutationForbidden
617/// }
618///
619/// // An account definition
620/// #[account]
621/// #[derive(Default)]
622/// pub struct MyData {
623/// mutation_allowed: bool,
624/// data: u64
625/// }
626///
627/// // An account validation struct
628/// #[derive(Accounts)]
629/// pub struct SetData<'info> {
630/// #[account(mut)]
631/// pub data: Account<'info, MyData>
632/// }
633/// ```
634#[macro_export]
635macro_rules! require {
636 ($invariant:expr, $error:tt $(,)?) => {
637 if !($invariant) {
638 return Err(anchor_lang::error!($crate::ErrorCode::$error));
639 }
640 };
641 ($invariant:expr, $error:expr $(,)?) => {
642 if !($invariant) {
643 return Err(anchor_lang::error!($error));
644 }
645 };
646}
647
648/// Ensures two NON-PUBKEY values are equal.
649///
650/// Use [require_keys_eq](crate::prelude::require_keys_eq)
651/// to compare two pubkeys.
652///
653/// Can be used with or without a custom error code.
654///
655/// # Example
656/// ```rust,ignore
657/// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
658/// require_eq!(ctx.accounts.data.data, 0);
659/// ctx.accounts.data.data = data;
660/// Ok(())
661/// }
662/// ```
663#[macro_export]
664macro_rules! require_eq {
665 ($value1: expr, $value2: expr, $error_code:expr $(,)?) => {
666 if $value1 != $value2 {
667 return Err(error!($error_code).with_values(($value1, $value2)));
668 }
669 };
670 ($value1: expr, $value2: expr $(,)?) => {
671 if $value1 != $value2 {
672 return Err(error!(anchor_lang::error::ErrorCode::RequireEqViolated)
673 .with_values(($value1, $value2)));
674 }
675 };
676}
677
678/// Ensures two NON-PUBKEY values are not equal.
679///
680/// Use [require_keys_neq](crate::prelude::require_keys_neq)
681/// to compare two pubkeys.
682///
683/// Can be used with or without a custom error code.
684///
685/// # Example
686/// ```rust,ignore
687/// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
688/// require_neq!(ctx.accounts.data.data, 0);
689/// ctx.accounts.data.data = data;
690/// Ok(());
691/// }
692/// ```
693#[macro_export]
694macro_rules! require_neq {
695 ($value1: expr, $value2: expr, $error_code: expr $(,)?) => {
696 if $value1 == $value2 {
697 return Err(error!($error_code).with_values(($value1, $value2)));
698 }
699 };
700 ($value1: expr, $value2: expr $(,)?) => {
701 if $value1 == $value2 {
702 return Err(error!(anchor_lang::error::ErrorCode::RequireNeqViolated)
703 .with_values(($value1, $value2)));
704 }
705 };
706}
707
708/// Ensures two pubkeys values are equal.
709///
710/// Use [require_eq](crate::prelude::require_eq)
711/// to compare two non-pubkey values.
712///
713/// Can be used with or without a custom error code.
714///
715/// # Example
716/// ```rust,ignore
717/// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
718/// require_keys_eq!(ctx.accounts.data.authority.key(), ctx.accounts.authority.key());
719/// ctx.accounts.data.data = data;
720/// Ok(())
721/// }
722/// ```
723#[macro_export]
724macro_rules! require_keys_eq {
725 ($value1: expr, $value2: expr, $error_code:expr $(,)?) => {
726 if $value1 != $value2 {
727 return Err(error!($error_code).with_pubkeys(($value1, $value2)));
728 }
729 };
730 ($value1: expr, $value2: expr $(,)?) => {
731 if $value1 != $value2 {
732 return Err(error!(anchor_lang::error::ErrorCode::RequireKeysEqViolated)
733 .with_pubkeys(($value1, $value2)));
734 }
735 };
736}
737
738/// Ensures two pubkeys are not equal.
739///
740/// Use [require_neq](crate::prelude::require_neq)
741/// to compare two non-pubkey values.
742///
743/// Can be used with or without a custom error code.
744///
745/// # Example
746/// ```rust,ignore
747/// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
748/// require_keys_neq!(ctx.accounts.data.authority.key(), ctx.accounts.other.key());
749/// ctx.accounts.data.data = data;
750/// Ok(())
751/// }
752/// ```
753#[macro_export]
754macro_rules! require_keys_neq {
755 ($value1: expr, $value2: expr, $error_code: expr $(,)?) => {
756 if $value1 == $value2 {
757 return Err(error!($error_code).with_pubkeys(($value1, $value2)));
758 }
759 };
760 ($value1: expr, $value2: expr $(,)?) => {
761 if $value1 == $value2 {
762 return Err(
763 error!(anchor_lang::error::ErrorCode::RequireKeysNeqViolated)
764 .with_pubkeys(($value1, $value2)),
765 );
766 }
767 };
768}
769
770/// Ensures the first NON-PUBKEY value is greater than the second
771/// NON-PUBKEY value.
772///
773/// To include an equality check, use [require_gte](crate::require_gte).
774///
775/// Can be used with or without a custom error code.
776///
777/// # Example
778/// ```rust,ignore
779/// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
780/// require_gt!(ctx.accounts.data.data, 0);
781/// ctx.accounts.data.data = data;
782/// Ok(());
783/// }
784/// ```
785#[macro_export]
786macro_rules! require_gt {
787 ($value1: expr, $value2: expr, $error_code: expr $(,)?) => {
788 if $value1 <= $value2 {
789 return Err(error!($error_code).with_values(($value1, $value2)));
790 }
791 };
792 ($value1: expr, $value2: expr $(,)?) => {
793 if $value1 <= $value2 {
794 return Err(error!(anchor_lang::error::ErrorCode::RequireGtViolated)
795 .with_values(($value1, $value2)));
796 }
797 };
798}
799
800/// Ensures the first NON-PUBKEY value is greater than or equal
801/// to the second NON-PUBKEY value.
802///
803/// Can be used with or without a custom error code.
804///
805/// # Example
806/// ```rust,ignore
807/// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
808/// require_gte!(ctx.accounts.data.data, 1);
809/// ctx.accounts.data.data = data;
810/// Ok(());
811/// }
812/// ```
813#[macro_export]
814macro_rules! require_gte {
815 ($value1: expr, $value2: expr, $error_code: expr $(,)?) => {
816 if $value1 < $value2 {
817 return Err(error!($error_code).with_values(($value1, $value2)));
818 }
819 };
820 ($value1: expr, $value2: expr $(,)?) => {
821 if $value1 < $value2 {
822 return Err(error!(anchor_lang::error::ErrorCode::RequireGteViolated)
823 .with_values(($value1, $value2)));
824 }
825 };
826}
827
828/// Returns with the given error.
829/// Use this with a custom error type.
830///
831/// # Example
832/// ```ignore
833/// // Instruction function
834/// pub fn example(ctx: Context<Example>) -> Result<()> {
835/// err!(MyError::SomeError)
836/// }
837///
838/// // An enum for custom error codes
839/// #[error_code]
840/// pub enum MyError {
841/// SomeError
842/// }
843/// ```
844#[macro_export]
845macro_rules! err {
846 ($error:tt $(,)?) => {
847 Err(anchor_lang::error!($crate::ErrorCode::$error))
848 };
849 ($error:expr $(,)?) => {
850 Err(anchor_lang::error!($error))
851 };
852}
853
854/// Creates a [`Source`](crate::error::Source)
855#[macro_export]
856macro_rules! source {
857 () => {
858 anchor_lang::error::Source {
859 filename: file!(),
860 line: line!(),
861 }
862 };
863}