lib.rs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. //! Anchor ⚓ is a framework for Solana's Sealevel runtime providing several
  2. //! convenient developer tools.
  3. //!
  4. //! - Rust eDSL for writing safe, secure, and high level Solana programs
  5. //! - [IDL](https://en.wikipedia.org/wiki/Interface_description_language) specification
  6. //! - TypeScript package for generating clients from IDL
  7. //! - CLI and workspace management for developing complete applications
  8. //!
  9. //! If you're familiar with developing in Ethereum's
  10. //! [Solidity](https://docs.soliditylang.org/en/v0.7.4/),
  11. //! [Truffle](https://www.trufflesuite.com/),
  12. //! [web3.js](https://github.com/ethereum/web3.js) or Parity's
  13. //! [Ink!](https://github.com/paritytech/ink), then the experience will be
  14. //! familiar. Although the syntax and semantics are targeted at Solana, the high
  15. //! level workflow of writing RPC request handlers, emitting an IDL, and
  16. //! generating clients from IDL is the same.
  17. //!
  18. //! For detailed tutorials and examples on how to use Anchor, see the guided
  19. //! [tutorials](https://anchor-lang.com) or examples in the GitHub
  20. //! [repository](https://github.com/coral-xyz/anchor).
  21. //!
  22. //! Presented here are the Rust primitives for building on Solana.
  23. extern crate self as anchor_lang;
  24. use bytemuck::{Pod, Zeroable};
  25. use solana_program::account_info::AccountInfo;
  26. use solana_program::instruction::AccountMeta;
  27. use solana_program::pubkey::Pubkey;
  28. use std::collections::{BTreeMap, BTreeSet};
  29. use std::io::Write;
  30. mod account_meta;
  31. pub mod accounts;
  32. mod bpf_upgradeable_state;
  33. mod bpf_writer;
  34. mod common;
  35. pub mod context;
  36. pub mod error;
  37. #[doc(hidden)]
  38. pub mod event;
  39. #[doc(hidden)]
  40. pub mod idl;
  41. pub mod system_program;
  42. mod vec;
  43. pub use crate::bpf_upgradeable_state::*;
  44. pub use anchor_attribute_access_control::access_control;
  45. pub use anchor_attribute_account::{account, declare_id, zero_copy};
  46. pub use anchor_attribute_constant::constant;
  47. pub use anchor_attribute_error::*;
  48. pub use anchor_attribute_event::{emit, event};
  49. pub use anchor_attribute_program::program;
  50. pub use anchor_derive_accounts::Accounts;
  51. pub use anchor_derive_serde::{AnchorDeserialize, AnchorSerialize};
  52. pub use anchor_derive_space::InitSpace;
  53. /// Borsh is the default serialization format for instructions and accounts.
  54. pub use borsh::de::BorshDeserialize as AnchorDeserialize;
  55. pub use borsh::ser::BorshSerialize as AnchorSerialize;
  56. pub use solana_program;
  57. #[cfg(feature = "event-cpi")]
  58. pub use anchor_attribute_event::{emit_cpi, event_cpi};
  59. #[cfg(feature = "idl-build")]
  60. pub use anchor_syn::{self, idl::build::IdlBuild};
  61. pub type Result<T> = std::result::Result<T, error::Error>;
  62. /// A data structure of validated accounts that can be deserialized from the
  63. /// input to a Solana program. Implementations of this trait should perform any
  64. /// and all requisite constraint checks on accounts to ensure the accounts
  65. /// maintain any invariants required for the program to run securely. In most
  66. /// cases, it's recommended to use the [`Accounts`](./derive.Accounts.html)
  67. /// derive macro to implement this trait.
  68. pub trait Accounts<'info>: ToAccountMetas + ToAccountInfos<'info> + Sized {
  69. /// Returns the validated accounts struct. What constitutes "valid" is
  70. /// program dependent. However, users of these types should never have to
  71. /// worry about account substitution attacks. For example, if a program
  72. /// expects a `Mint` account from the SPL token program in a particular
  73. /// field, then it should be impossible for this method to return `Ok` if
  74. /// any other account type is given--from the SPL token program or elsewhere.
  75. ///
  76. /// `program_id` is the currently executing program. `accounts` is the
  77. /// set of accounts to construct the type from. For every account used,
  78. /// the implementation should mutate the slice, consuming the used entry
  79. /// so that it cannot be used again.
  80. fn try_accounts(
  81. program_id: &Pubkey,
  82. accounts: &mut &[AccountInfo<'info>],
  83. ix_data: &[u8],
  84. bumps: &mut BTreeMap<String, u8>,
  85. reallocs: &mut BTreeSet<Pubkey>,
  86. ) -> Result<Self>;
  87. }
  88. /// The exit procedure for an account. Any cleanup or persistence to storage
  89. /// should be done here.
  90. pub trait AccountsExit<'info>: ToAccountMetas + ToAccountInfos<'info> {
  91. /// `program_id` is the currently executing program.
  92. fn exit(&self, _program_id: &Pubkey) -> Result<()> {
  93. // no-op
  94. Ok(())
  95. }
  96. }
  97. /// The close procedure to initiate garabage collection of an account, allowing
  98. /// one to retrieve the rent exemption.
  99. pub trait AccountsClose<'info>: ToAccountInfos<'info> {
  100. fn close(&self, sol_destination: AccountInfo<'info>) -> Result<()>;
  101. }
  102. /// Transformation to
  103. /// [`AccountMeta`](../solana_program/instruction/struct.AccountMeta.html)
  104. /// structs.
  105. pub trait ToAccountMetas {
  106. /// `is_signer` is given as an optional override for the signer meta field.
  107. /// This covers the edge case when a program-derived-address needs to relay
  108. /// a transaction from a client to another program but sign the transaction
  109. /// before the relay. The client cannot mark the field as a signer, and so
  110. /// we have to override the is_signer meta field given by the client.
  111. fn to_account_metas(&self, is_signer: Option<bool>) -> Vec<AccountMeta>;
  112. }
  113. /// Transformation to
  114. /// [`AccountInfo`](../solana_program/account_info/struct.AccountInfo.html)
  115. /// structs.
  116. pub trait ToAccountInfos<'info> {
  117. fn to_account_infos(&self) -> Vec<AccountInfo<'info>>;
  118. }
  119. /// Transformation to an `AccountInfo` struct.
  120. pub trait ToAccountInfo<'info> {
  121. fn to_account_info(&self) -> AccountInfo<'info>;
  122. }
  123. impl<'info, T> ToAccountInfo<'info> for T
  124. where
  125. T: AsRef<AccountInfo<'info>>,
  126. {
  127. fn to_account_info(&self) -> AccountInfo<'info> {
  128. self.as_ref().clone()
  129. }
  130. }
  131. /// Lamports related utility methods for accounts.
  132. pub trait Lamports<'info>: AsRef<AccountInfo<'info>> {
  133. /// Get the lamports of the account.
  134. fn get_lamports(&self) -> u64 {
  135. self.as_ref().lamports()
  136. }
  137. /// Add lamports to the account.
  138. ///
  139. /// This method is useful for transfering lamports from a PDA.
  140. ///
  141. /// # Requirements
  142. ///
  143. /// 1. The account must be marked `mut`.
  144. /// 2. The total lamports **before** the transaction must equal to total lamports **after**
  145. /// the transaction.
  146. /// 3. `lamports` field of the account info should not currently be borrowed.
  147. ///
  148. /// See [`Lamports::sub_lamports`] for subtracting lamports.
  149. fn add_lamports(&self, amount: u64) -> Result<&Self> {
  150. **self.as_ref().try_borrow_mut_lamports()? += amount;
  151. Ok(self)
  152. }
  153. /// Subtract lamports from the account.
  154. ///
  155. /// This method is useful for transfering lamports from a PDA.
  156. ///
  157. /// # Requirements
  158. ///
  159. /// 1. The account must be owned by the executing program.
  160. /// 2. The account must be marked `mut`.
  161. /// 3. The total lamports **before** the transaction must equal to total lamports **after**
  162. /// the transaction.
  163. /// 4. `lamports` field of the account info should not currently be borrowed.
  164. ///
  165. /// See [`Lamports::add_lamports`] for adding lamports.
  166. fn sub_lamports(&self, amount: u64) -> Result<&Self> {
  167. **self.as_ref().try_borrow_mut_lamports()? -= amount;
  168. Ok(self)
  169. }
  170. }
  171. impl<'info, T: AsRef<AccountInfo<'info>>> Lamports<'info> for T {}
  172. /// A data structure that can be serialized and stored into account storage,
  173. /// i.e. an
  174. /// [`AccountInfo`](../solana_program/account_info/struct.AccountInfo.html#structfield.data)'s
  175. /// mutable data slice.
  176. ///
  177. /// Implementors of this trait should ensure that any subsequent usage of the
  178. /// `AccountDeserialize` trait succeeds if and only if the account is of the
  179. /// correct type.
  180. ///
  181. /// In most cases, one can use the default implementation provided by the
  182. /// [`#[account]`](./attr.account.html) attribute.
  183. pub trait AccountSerialize {
  184. /// Serializes the account data into `writer`.
  185. fn try_serialize<W: Write>(&self, _writer: &mut W) -> Result<()> {
  186. Ok(())
  187. }
  188. }
  189. /// A data structure that can be deserialized and stored into account storage,
  190. /// i.e. an
  191. /// [`AccountInfo`](../solana_program/account_info/struct.AccountInfo.html#structfield.data)'s
  192. /// mutable data slice.
  193. pub trait AccountDeserialize: Sized {
  194. /// Deserializes previously initialized account data. Should fail for all
  195. /// uninitialized accounts, where the bytes are zeroed. Implementations
  196. /// should be unique to a particular account type so that one can never
  197. /// successfully deserialize the data of one account type into another.
  198. /// For example, if the SPL token program were to implement this trait,
  199. /// it should be impossible to deserialize a `Mint` account into a token
  200. /// `Account`.
  201. fn try_deserialize(buf: &mut &[u8]) -> Result<Self> {
  202. Self::try_deserialize_unchecked(buf)
  203. }
  204. /// Deserializes account data without checking the account discriminator.
  205. /// This should only be used on account initialization, when the bytes of
  206. /// the account are zeroed.
  207. fn try_deserialize_unchecked(buf: &mut &[u8]) -> Result<Self>;
  208. }
  209. /// An account data structure capable of zero copy deserialization.
  210. pub trait ZeroCopy: Discriminator + Copy + Clone + Zeroable + Pod {}
  211. /// Calculates the data for an instruction invocation, where the data is
  212. /// `Sha256(<namespace>:<method_name>)[..8] || BorshSerialize(args)`.
  213. /// `args` is a borsh serialized struct of named fields for each argument given
  214. /// to an instruction.
  215. pub trait InstructionData: Discriminator + AnchorSerialize {
  216. fn data(&self) -> Vec<u8> {
  217. let mut d = Self::discriminator().to_vec();
  218. d.append(&mut self.try_to_vec().expect("Should always serialize"));
  219. d
  220. }
  221. }
  222. /// An event that can be emitted via a Solana log. See [`emit!`](crate::prelude::emit) for an example.
  223. pub trait Event: AnchorSerialize + AnchorDeserialize + Discriminator {
  224. fn data(&self) -> Vec<u8>;
  225. }
  226. // The serialized event data to be emitted via a Solana log.
  227. // TODO: remove this on the next major version upgrade.
  228. #[doc(hidden)]
  229. #[deprecated(since = "0.4.2", note = "Please use Event instead")]
  230. pub trait EventData: AnchorSerialize + Discriminator {
  231. fn data(&self) -> Vec<u8>;
  232. }
  233. /// 8 byte unique identifier for a type.
  234. pub trait Discriminator {
  235. const DISCRIMINATOR: [u8; 8];
  236. fn discriminator() -> [u8; 8] {
  237. Self::DISCRIMINATOR
  238. }
  239. }
  240. /// Defines the space of an account for initialization.
  241. pub trait Space {
  242. const INIT_SPACE: usize;
  243. }
  244. /// Bump seed for program derived addresses.
  245. pub trait Bump {
  246. fn seed(&self) -> u8;
  247. }
  248. /// Defines an address expected to own an account.
  249. pub trait Owner {
  250. fn owner() -> Pubkey;
  251. }
  252. /// Defines a list of addresses expected to own an account.
  253. pub trait Owners {
  254. fn owners() -> &'static [Pubkey];
  255. }
  256. /// Defines a trait for checking the owner of a program.
  257. pub trait CheckOwner {
  258. fn check_owner(owner: &Pubkey) -> Result<()>;
  259. }
  260. impl<T: Owners> CheckOwner for T {
  261. fn check_owner(owner: &Pubkey) -> Result<()> {
  262. if !Self::owners().contains(owner) {
  263. Err(
  264. error::Error::from(error::ErrorCode::AccountOwnedByWrongProgram)
  265. .with_account_name(*owner),
  266. )
  267. } else {
  268. Ok(())
  269. }
  270. }
  271. }
  272. /// Defines the id of a program.
  273. pub trait Id {
  274. fn id() -> Pubkey;
  275. }
  276. /// Defines the possible ids of a program.
  277. pub trait Ids {
  278. fn ids() -> &'static [Pubkey];
  279. }
  280. /// Defines a trait for checking the id of a program.
  281. pub trait CheckId {
  282. fn check_id(id: &Pubkey) -> Result<()>;
  283. }
  284. impl<T: Ids> CheckId for T {
  285. fn check_id(id: &Pubkey) -> Result<()> {
  286. if !Self::ids().contains(id) {
  287. Err(error::Error::from(error::ErrorCode::InvalidProgramId).with_account_name(*id))
  288. } else {
  289. Ok(())
  290. }
  291. }
  292. }
  293. /// Defines the Pubkey of an account.
  294. pub trait Key {
  295. fn key(&self) -> Pubkey;
  296. }
  297. impl Key for Pubkey {
  298. fn key(&self) -> Pubkey {
  299. *self
  300. }
  301. }
  302. /// The prelude contains all commonly used components of the crate.
  303. /// All programs should include it via `anchor_lang::prelude::*;`.
  304. pub mod prelude {
  305. pub use super::{
  306. access_control, account, accounts::account::Account,
  307. accounts::account_loader::AccountLoader, accounts::interface::Interface,
  308. accounts::interface_account::InterfaceAccount, accounts::program::Program,
  309. accounts::signer::Signer, accounts::system_account::SystemAccount,
  310. accounts::sysvar::Sysvar, accounts::unchecked_account::UncheckedAccount, constant,
  311. context::Context, context::CpiContext, declare_id, emit, err, error, event, program,
  312. require, require_eq, require_gt, require_gte, require_keys_eq, require_keys_neq,
  313. require_neq, solana_program::bpf_loader_upgradeable::UpgradeableLoaderState, source,
  314. system_program::System, zero_copy, AccountDeserialize, AccountSerialize, Accounts,
  315. AccountsClose, AccountsExit, AnchorDeserialize, AnchorSerialize, Id, InitSpace, Key,
  316. Lamports, Owner, ProgramData, Result, Space, ToAccountInfo, ToAccountInfos, ToAccountMetas,
  317. };
  318. pub use anchor_attribute_error::*;
  319. pub use borsh;
  320. pub use error::*;
  321. pub use solana_program::account_info::{next_account_info, AccountInfo};
  322. pub use solana_program::instruction::AccountMeta;
  323. pub use solana_program::msg;
  324. pub use solana_program::program_error::ProgramError;
  325. pub use solana_program::pubkey::Pubkey;
  326. pub use solana_program::sysvar::clock::Clock;
  327. pub use solana_program::sysvar::epoch_schedule::EpochSchedule;
  328. pub use solana_program::sysvar::instructions::Instructions;
  329. pub use solana_program::sysvar::rent::Rent;
  330. pub use solana_program::sysvar::rewards::Rewards;
  331. pub use solana_program::sysvar::slot_hashes::SlotHashes;
  332. pub use solana_program::sysvar::slot_history::SlotHistory;
  333. pub use solana_program::sysvar::stake_history::StakeHistory;
  334. pub use solana_program::sysvar::Sysvar as SolanaSysvar;
  335. pub use thiserror;
  336. #[cfg(feature = "event-cpi")]
  337. pub use super::{emit_cpi, event_cpi};
  338. #[cfg(feature = "idl-build")]
  339. pub use super::IdlBuild;
  340. }
  341. /// Internal module used by macros and unstable apis.
  342. #[doc(hidden)]
  343. pub mod __private {
  344. /// The discriminator anchor uses to mark an account as closed.
  345. pub const CLOSED_ACCOUNT_DISCRIMINATOR: [u8; 8] = [255, 255, 255, 255, 255, 255, 255, 255];
  346. pub use anchor_attribute_account::ZeroCopyAccessor;
  347. pub use anchor_attribute_event::EventIndex;
  348. pub use base64;
  349. pub use bytemuck;
  350. use solana_program::pubkey::Pubkey;
  351. // Used to calculate the maximum between two expressions.
  352. // It is necessary for the calculation of the enum space.
  353. #[doc(hidden)]
  354. pub const fn max(a: usize, b: usize) -> usize {
  355. [a, b][(a < b) as usize]
  356. }
  357. // Very experimental trait.
  358. #[doc(hidden)]
  359. pub trait ZeroCopyAccessor<Ty> {
  360. fn get(&self) -> Ty;
  361. fn set(input: &Ty) -> Self;
  362. }
  363. #[doc(hidden)]
  364. impl ZeroCopyAccessor<Pubkey> for [u8; 32] {
  365. fn get(&self) -> Pubkey {
  366. Pubkey::from(*self)
  367. }
  368. fn set(input: &Pubkey) -> [u8; 32] {
  369. input.to_bytes()
  370. }
  371. }
  372. }
  373. /// Ensures a condition is true, otherwise returns with the given error.
  374. /// Use this with or without a custom error type.
  375. ///
  376. /// # Example
  377. /// ```ignore
  378. /// // Instruction function
  379. /// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
  380. /// require!(ctx.accounts.data.mutation_allowed, MyError::MutationForbidden);
  381. /// ctx.accounts.data.data = data;
  382. /// Ok(())
  383. /// }
  384. ///
  385. /// // An enum for custom error codes
  386. /// #[error_code]
  387. /// pub enum MyError {
  388. /// MutationForbidden
  389. /// }
  390. ///
  391. /// // An account definition
  392. /// #[account]
  393. /// #[derive(Default)]
  394. /// pub struct MyData {
  395. /// mutation_allowed: bool,
  396. /// data: u64
  397. /// }
  398. ///
  399. /// // An account validation struct
  400. /// #[derive(Accounts)]
  401. /// pub struct SetData<'info> {
  402. /// #[account(mut)]
  403. /// pub data: Account<'info, MyData>
  404. /// }
  405. /// ```
  406. #[macro_export]
  407. macro_rules! require {
  408. ($invariant:expr, $error:tt $(,)?) => {
  409. if !($invariant) {
  410. return Err(anchor_lang::error!($crate::ErrorCode::$error));
  411. }
  412. };
  413. ($invariant:expr, $error:expr $(,)?) => {
  414. if !($invariant) {
  415. return Err(anchor_lang::error!($error));
  416. }
  417. };
  418. }
  419. /// Ensures two NON-PUBKEY values are equal.
  420. ///
  421. /// Use [require_keys_eq](crate::prelude::require_keys_eq)
  422. /// to compare two pubkeys.
  423. ///
  424. /// Can be used with or without a custom error code.
  425. ///
  426. /// # Example
  427. /// ```rust,ignore
  428. /// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
  429. /// require_eq!(ctx.accounts.data.data, 0);
  430. /// ctx.accounts.data.data = data;
  431. /// Ok(())
  432. /// }
  433. /// ```
  434. #[macro_export]
  435. macro_rules! require_eq {
  436. ($value1: expr, $value2: expr, $error_code:expr $(,)?) => {
  437. if $value1 != $value2 {
  438. return Err(error!($error_code).with_values(($value1, $value2)));
  439. }
  440. };
  441. ($value1: expr, $value2: expr $(,)?) => {
  442. if $value1 != $value2 {
  443. return Err(error!(anchor_lang::error::ErrorCode::RequireEqViolated)
  444. .with_values(($value1, $value2)));
  445. }
  446. };
  447. }
  448. /// Ensures two NON-PUBKEY values are not equal.
  449. ///
  450. /// Use [require_keys_neq](crate::prelude::require_keys_neq)
  451. /// to compare two pubkeys.
  452. ///
  453. /// Can be used with or without a custom error code.
  454. ///
  455. /// # Example
  456. /// ```rust,ignore
  457. /// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
  458. /// require_neq!(ctx.accounts.data.data, 0);
  459. /// ctx.accounts.data.data = data;
  460. /// Ok(());
  461. /// }
  462. /// ```
  463. #[macro_export]
  464. macro_rules! require_neq {
  465. ($value1: expr, $value2: expr, $error_code: expr $(,)?) => {
  466. if $value1 == $value2 {
  467. return Err(error!($error_code).with_values(($value1, $value2)));
  468. }
  469. };
  470. ($value1: expr, $value2: expr $(,)?) => {
  471. if $value1 == $value2 {
  472. return Err(error!(anchor_lang::error::ErrorCode::RequireNeqViolated)
  473. .with_values(($value1, $value2)));
  474. }
  475. };
  476. }
  477. /// Ensures two pubkeys values are equal.
  478. ///
  479. /// Use [require_eq](crate::prelude::require_eq)
  480. /// to compare two non-pubkey values.
  481. ///
  482. /// Can be used with or without a custom error code.
  483. ///
  484. /// # Example
  485. /// ```rust,ignore
  486. /// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
  487. /// require_keys_eq!(ctx.accounts.data.authority.key(), ctx.accounts.authority.key());
  488. /// ctx.accounts.data.data = data;
  489. /// Ok(())
  490. /// }
  491. /// ```
  492. #[macro_export]
  493. macro_rules! require_keys_eq {
  494. ($value1: expr, $value2: expr, $error_code:expr $(,)?) => {
  495. if $value1 != $value2 {
  496. return Err(error!($error_code).with_pubkeys(($value1, $value2)));
  497. }
  498. };
  499. ($value1: expr, $value2: expr $(,)?) => {
  500. if $value1 != $value2 {
  501. return Err(error!(anchor_lang::error::ErrorCode::RequireKeysEqViolated)
  502. .with_pubkeys(($value1, $value2)));
  503. }
  504. };
  505. }
  506. /// Ensures two pubkeys are not equal.
  507. ///
  508. /// Use [require_neq](crate::prelude::require_neq)
  509. /// to compare two non-pubkey values.
  510. ///
  511. /// Can be used with or without a custom error code.
  512. ///
  513. /// # Example
  514. /// ```rust,ignore
  515. /// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
  516. /// require_keys_neq!(ctx.accounts.data.authority.key(), ctx.accounts.other.key());
  517. /// ctx.accounts.data.data = data;
  518. /// Ok(())
  519. /// }
  520. /// ```
  521. #[macro_export]
  522. macro_rules! require_keys_neq {
  523. ($value1: expr, $value2: expr, $error_code: expr $(,)?) => {
  524. if $value1 == $value2 {
  525. return Err(error!($error_code).with_pubkeys(($value1, $value2)));
  526. }
  527. };
  528. ($value1: expr, $value2: expr $(,)?) => {
  529. if $value1 == $value2 {
  530. return Err(
  531. error!(anchor_lang::error::ErrorCode::RequireKeysNeqViolated)
  532. .with_pubkeys(($value1, $value2)),
  533. );
  534. }
  535. };
  536. }
  537. /// Ensures the first NON-PUBKEY value is greater than the second
  538. /// NON-PUBKEY value.
  539. ///
  540. /// To include an equality check, use [require_gte](crate::require_gte).
  541. ///
  542. /// Can be used with or without a custom error code.
  543. ///
  544. /// # Example
  545. /// ```rust,ignore
  546. /// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
  547. /// require_gt!(ctx.accounts.data.data, 0);
  548. /// ctx.accounts.data.data = data;
  549. /// Ok(());
  550. /// }
  551. /// ```
  552. #[macro_export]
  553. macro_rules! require_gt {
  554. ($value1: expr, $value2: expr, $error_code: expr $(,)?) => {
  555. if $value1 <= $value2 {
  556. return Err(error!($error_code).with_values(($value1, $value2)));
  557. }
  558. };
  559. ($value1: expr, $value2: expr $(,)?) => {
  560. if $value1 <= $value2 {
  561. return Err(error!(anchor_lang::error::ErrorCode::RequireGtViolated)
  562. .with_values(($value1, $value2)));
  563. }
  564. };
  565. }
  566. /// Ensures the first NON-PUBKEY value is greater than or equal
  567. /// to the second NON-PUBKEY value.
  568. ///
  569. /// Can be used with or without a custom error code.
  570. ///
  571. /// # Example
  572. /// ```rust,ignore
  573. /// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
  574. /// require_gte!(ctx.accounts.data.data, 1);
  575. /// ctx.accounts.data.data = data;
  576. /// Ok(());
  577. /// }
  578. /// ```
  579. #[macro_export]
  580. macro_rules! require_gte {
  581. ($value1: expr, $value2: expr, $error_code: expr $(,)?) => {
  582. if $value1 < $value2 {
  583. return Err(error!($error_code).with_values(($value1, $value2)));
  584. }
  585. };
  586. ($value1: expr, $value2: expr $(,)?) => {
  587. if $value1 < $value2 {
  588. return Err(error!(anchor_lang::error::ErrorCode::RequireGteViolated)
  589. .with_values(($value1, $value2)));
  590. }
  591. };
  592. }
  593. /// Returns with the given error.
  594. /// Use this with a custom error type.
  595. ///
  596. /// # Example
  597. /// ```ignore
  598. /// // Instruction function
  599. /// pub fn example(ctx: Context<Example>) -> Result<()> {
  600. /// err!(MyError::SomeError)
  601. /// }
  602. ///
  603. /// // An enum for custom error codes
  604. /// #[error_code]
  605. /// pub enum MyError {
  606. /// SomeError
  607. /// }
  608. /// ```
  609. #[macro_export]
  610. macro_rules! err {
  611. ($error:tt $(,)?) => {
  612. Err(anchor_lang::error!($crate::ErrorCode::$error))
  613. };
  614. ($error:expr $(,)?) => {
  615. Err(anchor_lang::error!($error))
  616. };
  617. }
  618. /// Creates a [`Source`](crate::error::Source)
  619. #[macro_export]
  620. macro_rules! source {
  621. () => {
  622. anchor_lang::error::Source {
  623. filename: file!(),
  624. line: line!(),
  625. }
  626. };
  627. }