Skip to main content

solana_program/
lib.rs

1//! The base library for all Solana on-chain Rust programs.
2//!
3//! All Solana Rust programs that run on-chain will link to this crate, which
4//! acts as a standard library for Solana programs. Solana programs also link to
5//! the [Rust standard library][std], though it is [modified][sstd] for the
6//! Solana runtime environment. While off-chain programs that interact with the
7//! Solana network _can_ link to this crate, they typically instead use the
8//! [`solana-sdk`] crate, which reexports all modules from `solana-program`.
9//!
10//! [std]: https://doc.rust-lang.org/stable/std/
11//! [sstd]: https://solana.com/docs/programs/limitations#rust-libraries
12//! [`solana-sdk`]: https://docs.rs/solana-sdk/latest/solana_sdk/
13//!
14//! This library defines
15//!
16//! - macros for declaring the [program entrypoint][pe],
17//! - [core data types][cdt],
18//! - [logging] macros,
19//! - [serialization] methods,
20//! - methods for [cross-program instruction execution][cpi],
21//! - program IDs and instruction constructors for the system program and other
22//!   [native programs][np],
23//! - [sysvar] accessors.
24//!
25//! [pe]: #defining-a-solana-program
26//! [cdt]: #core-data-types
27//! [logging]: crate::log
28//! [serialization]: #serialization
29//! [np]: #native-programs
30//! [cpi]: #cross-program-instruction-execution
31//! [sysvar]: crate::sysvar
32//!
33//! Idiomatic examples of `solana-program` usage can be found in
34//! [the Solana Program Library][spl].
35//!
36//! [spl]: https://github.com/solana-labs/solana-program-library
37//!
38//! # Defining a solana program
39//!
40//! Solana program crates have some unique properties compared to typical Rust
41//! programs:
42//!
43//! - They are often compiled for both on-chain use and off-chain use. This is
44//!   primarily because off-chain clients may need access to data types
45//!   defined by the on-chain program.
46//! - They do not define a `main` function, but instead define their entrypoint
47//!   with the [`entrypoint!`] macro.
48//! - They are compiled as the ["cdylib"] crate type for dynamic loading
49//!   by the Solana runtime.
50//! - They run in a constrained VM environment, and while they do have access to
51//!   the [Rust standard library][std], many features of the standard library,
52//!   particularly related to OS services, will fail at runtime, will silently
53//!   do nothing, or are not defined. See the [restrictions to the Rust standard
54//!   library][sstd] in the Solana documentation for more.
55//!
56//! [std]: https://doc.rust-lang.org/std/index.html
57//! ["cdylib"]: https://doc.rust-lang.org/reference/linkage.html
58//!
59//! Because multiple crates that are linked together cannot all define
60//! program entrypoints (see the [`entrypoint!`] documentation) a common
61//! convention is to use a [Cargo feature] called `no-entrypoint` to allow
62//! the program entrypoint to be disabled.
63//!
64//! [Cargo feature]: https://doc.rust-lang.org/cargo/reference/features.html
65//!
66//! The skeleton of a Solana program typically looks like:
67//!
68//! ```
69//! #[cfg(not(feature = "no-entrypoint"))]
70//! pub mod entrypoint {
71//!     use solana_program::{
72//!         account_info::AccountInfo,
73//!         entrypoint,
74//!         entrypoint::ProgramResult,
75//!         pubkey::Pubkey,
76//!     };
77//!
78//!     entrypoint!(process_instruction);
79//!
80//!     pub fn process_instruction(
81//!         program_id: &Pubkey,
82//!         accounts: &[AccountInfo],
83//!         instruction_data: &[u8],
84//!     ) -> ProgramResult {
85//!         // Decode and dispatch instructions here.
86//!         todo!()
87//!     }
88//! }
89//!
90//! // Additional code goes here.
91//! ```
92//!
93//! With a `Cargo.toml` file that contains
94//!
95//! ```toml
96//! [lib]
97//! crate-type = ["cdylib"]
98//!
99//! [features]
100//! no-entrypoint = []
101//! ```
102//!
103//! Note that a Solana program must specify its crate-type as "cdylib", to
104//! be discovered and built by the `cargo-build-sbf` command as a deployable program.
105//! Solana programs also often have crate-type "rlib" so they can be linked to other Rust crates.
106//! Avoid using "rlib" and "cdylib" crates together, since their combined usage precludes
107//! compiler optimizations that may decrease program size and CU usage.
108//!
109//! Prefer writing a separate package if it is supposed to be used as a library for other Solana
110//! programs (i.e. a "rlib" only crate). This would be normally the case for defining account
111//! types and helpers that are used by both clients and program. When creating a Rust project
112//! intended to be a program ready for deployment, use only the "cdylib" crate type.
113//!
114//! # On-chain vs. off-chain compilation targets
115//!
116//! Solana programs run on the [rbpf] VM, which implements a variant of the
117//! [eBPF] instruction set. Because this crate can be compiled for both on-chain
118//! and off-chain execution, the environments of which are significantly
119//! different, it extensively uses [conditional compilation][cc] to tailor its
120//! implementation to the environment. The `cfg` predicate used for identifying
121//! compilation for on-chain programs is `target_os = "solana"`, as in this
122//! example from the `solana-program` codebase that logs a message via a
123//! syscall when run on-chain, and via a library call when offchain:
124//!
125//! [rbpf]: https://github.com/solana-labs/rbpf
126//! [eBPF]: https://ebpf.io/
127//! [cc]: https://doc.rust-lang.org/reference/conditional-compilation.html
128//!
129//! ```
130//! pub fn sol_log(message: &str) {
131//!     #[cfg(target_os = "solana")]
132//!     unsafe {
133//!         sol_log_(message.as_ptr(), message.len() as u64);
134//!     }
135//!
136//!     #[cfg(not(target_os = "solana"))]
137//!     program_stubs::sol_log(message);
138//! }
139//! # mod program_stubs {
140//! #     pub(crate) fn sol_log(message: &str) { }
141//! # }
142//! ```
143//!
144//! This `cfg` pattern is suitable as well for user code that needs to work both
145//! on-chain and off-chain.
146//!
147//! `solana-program` and `solana-sdk` were previously a single crate. Because of
148//! this history, and because of the dual-usage of `solana-program` for two
149//! different environments, it contains some features that are not available to
150//! on-chain programs at compile-time. It also contains some on-chain features
151//! that will fail in off-chain scenarios at runtime. This distinction is not
152//! well-reflected in the documentation.
153//!
154//! For a more complete description of Solana's implementation of eBPF and its
155//! limitations, see the main Solana documentation for [on-chain programs][ocp].
156//!
157//! [ocp]: https://solana.com/docs/programs
158//!
159//! # Core data types
160//!
161//! - [`Pubkey`] — The address of a [Solana account][acc]. Some account
162//!   addresses are [ed25519] public keys, with corresponding secret keys that
163//!   are managed off-chain. Often, though, account addresses do not have
164//!   corresponding secret keys — as with [_program derived
165//!   addresses_][pdas] — or the secret key is not relevant to the
166//!   operation of a program, and may have even been disposed of. As running
167//!   Solana programs can not safely create or manage secret keys, the full
168//!   [`Keypair`] is not defined in `solana-program` but in `solana-sdk`.
169//! - [`Hash`] — A cryptographic hash. Used to uniquely identify blocks,
170//!   and also for general purpose hashing.
171//! - [`AccountInfo`] — A description of a single Solana account. All accounts
172//!   that might be accessed by a program invocation are provided to the program
173//!   entrypoint as `AccountInfo`.
174//! - [`Instruction`] — A directive telling the runtime to execute a program,
175//!   passing it a set of accounts and program-specific data.
176//! - [`ProgramError`] and [`ProgramResult`] — The error type that all programs
177//!   must return, reported to the runtime as a `u64`.
178//! - [`Sol`] — The Solana native token type, with conversions to and from
179//!   [_lamports_], the smallest fractional unit of SOL, in the [`native_token`]
180//!   module.
181//!
182//! [acc]: https://solana.com/docs/core/accounts
183//! [`Pubkey`]: pubkey::Pubkey
184//! [`Hash`]: hash::Hash
185//! [`Instruction`]: instruction::Instruction
186//! [`AccountInfo`]: account_info::AccountInfo
187//! [`ProgramError`]: program_error::ProgramError
188//! [`ProgramResult`]: entrypoint::ProgramResult
189//! [ed25519]: https://ed25519.cr.yp.to/
190//! [`Keypair`]: https://docs.rs/solana-sdk/latest/solana_sdk/signer/keypair/struct.Keypair.html
191//! [SHA-256]: https://en.wikipedia.org/wiki/SHA-2
192//! [`Sol`]: native_token::Sol
193//! [_lamports_]: https://solana.com/docs/intro#what-are-sols
194//!
195//! # Serialization
196//!
197//! Within the Solana runtime, programs, and network, at least three different
198//! serialization formats are used, and `solana-program` provides access to
199//! those needed by programs.
200//!
201//! In user-written Solana program code, serialization is primarily used for
202//! accessing [`AccountInfo`] data and [`Instruction`] data, both of which are
203//! program-specific binary data. Every program is free to decide their own
204//! serialization format, but data received from other sources —
205//! [sysvars][sysvar] for example — must be deserialized using the methods
206//! indicated by the documentation for that data or data type.
207//!
208//! [`AccountInfo`]: account_info::AccountInfo
209//! [`Instruction`]: instruction::Instruction
210//!
211//! The three serialization formats in use in Solana are:
212//!
213//! - __[Borsh]__, a compact and well-specified format developed by the [NEAR]
214//!   project, suitable for use in protocol definitions and for archival storage.
215//!   It has a [Rust implementation][brust] and a [JavaScript implementation][bjs]
216//!   and is recommended for all purposes.
217//!
218//!   Users need to import the [`borsh`] crate themselves — it is not
219//!   re-exported by `solana-program`, though this crate provides several useful
220//!   utilities in its [`borsh1` module][borshmod] that are not available in the
221//!   `borsh` library.
222//!
223//!   The [`Instruction::new_with_borsh`] function creates an `Instruction` by
224//!   serializing a value with borsh.
225//!
226//!   [Borsh]: https://borsh.io/
227//!   [NEAR]: https://near.org/
228//!   [brust]: https://docs.rs/borsh
229//!   [bjs]: https://github.com/near/borsh-js
230//!   [`borsh`]: https://docs.rs/borsh
231//!   [borshmod]: crate::borsh1
232//!   [`Instruction::new_with_borsh`]: instruction::Instruction::new_with_borsh
233//!
234//! - __[Bincode]__, a compact serialization format that implements the [Serde]
235//!   Rust APIs. As it does not have a specification nor a JavaScript
236//!   implementation, and uses more CPU than borsh, it is not recommend for new
237//!   code.
238//!
239//!   Many system program and native program instructions are serialized with
240//!   bincode, and it is used for other purposes in the runtime. In these cases
241//!   Rust programmers are generally not directly exposed to the encoding format
242//!   as it is hidden behind APIs.
243//!
244//!   The [`Instruction::new_with_bincode`] function creates an `Instruction` by
245//!   serializing a value with bincode.
246//!   With the `wincode` feature, `Instruction::new_with_wincode` produces the
247//!   same bytes from a [wincode] schema without bincode.
248//!
249//!   [Bincode]: https://docs.rs/bincode
250//!   [Serde]: https://serde.rs/
251//!   [wincode]: https://docs.rs/wincode
252//!   [`Instruction::new_with_bincode`]: instruction::Instruction::new_with_bincode
253//!
254//! - __[`Pack`]__, a Solana-specific serialization API that is used by many
255//!   older programs in the [Solana Program Library][spl] to define their
256//!   account format. It is difficult to implement and does not define a
257//!   language-independent serialization format. It is not generally recommended
258//!   for new code.
259//!
260//!   [`Pack`]: https://docs.rs/solana-program-pack/latest/trait.Pack.html
261//!
262//! Developers should carefully consider the CPU cost of serialization, balanced
263//! against the need for correctness and ease of use: off-the-shelf
264//! serialization formats tend to be more expensive than carefully hand-written
265//! application-specific formats; but application-specific formats are more
266//! difficult to ensure the correctness of, and to provide multi-language
267//! implementations for. It is not uncommon for programs to pack and unpack
268//! their data with hand-written code.
269//!
270//! # Cross-program instruction execution
271//!
272//! Solana programs may call other programs, termed [_cross-program
273//! invocation_][cpi] (CPI), with the [`invoke`] and [`invoke_signed`]
274//! functions. When calling another program the caller must provide the
275//! [`Instruction`] to be invoked, as well as the [`AccountInfo`] for every
276//! account required by the instruction. Because the only way for a program to
277//! acquire `AccountInfo` values is by receiving them from the runtime at the
278//! [program entrypoint][entrypoint!], any account required by the callee
279//! program must transitively be required by the caller program, and provided by
280//! _its_ caller.
281//!
282//! [`invoke`]: program::invoke
283//! [`invoke_signed`]: program::invoke_signed
284//! [cpi]: https://solana.com/docs/core/cpi
285//!
286//! A simple example of transferring lamports via CPI:
287//!
288//! ```
289//! use solana_account_info::{next_account_info, AccountInfo};
290//! use solana_program_entrypoint::entrypoint;
291//! use solana_program_error::ProgramResult;
292//! use solana_cpi::invoke;
293//! use solana_pubkey::Pubkey;
294//! use solana_system_interface::instruction::transfer;
295//!
296//! entrypoint!(process_instruction);
297//!
298//! fn process_instruction(
299//!     program_id: &Pubkey,
300//!     accounts: &[AccountInfo],
301//!     instruction_data: &[u8],
302//! ) -> ProgramResult {
303//!     let account_info_iter = &mut accounts.iter();
304//!
305//!     let payer = next_account_info(account_info_iter)?;
306//!     let recipient = next_account_info(account_info_iter)?;
307//!
308//!     assert!(payer.is_writable);
309//!     assert!(payer.is_signer);
310//!     assert!(recipient.is_writable);
311//!
312//!     let lamports = 1000000;
313//!
314//!     invoke(
315//!         &transfer(payer.key, recipient.key, lamports),
316//!         &[payer.clone(), recipient.clone()],
317//!     )
318//! }
319//! ```
320//!
321//! Solana also includes a mechanism to let programs control and sign for
322//! accounts without needing to protect a corresponding secret key, called
323//! [_program derived addresses_][pdas]. PDAs are derived with the
324//! [`Pubkey::find_program_address`] function. With a PDA, a program can call
325//! `invoke_signed` to call another program while virtually "signing" for the
326//! PDA.
327//!
328//! [pdas]: https://solana.com/docs/core/cpi#program-derived-addresses
329//! [`Pubkey::find_program_address`]: pubkey::Pubkey::find_program_address
330//!
331//! A simple example of creating an account for a PDA:
332//!
333//! ```
334//! use solana_account_info::{next_account_info, AccountInfo};
335//! use solana_program_entrypoint::entrypoint;
336//! use solana_program_error::ProgramResult;
337//! use solana_cpi::invoke_signed;
338//! use solana_pubkey::Pubkey;
339//! use solana_system_interface::instruction::create_account;
340//!
341//! entrypoint!(process_instruction);
342//!
343//! fn process_instruction(
344//!     program_id: &Pubkey,
345//!     accounts: &[AccountInfo],
346//!     instruction_data: &[u8],
347//! ) -> ProgramResult {
348//!     let account_info_iter = &mut accounts.iter();
349//!     let payer = next_account_info(account_info_iter)?;
350//!     let vault_pda = next_account_info(account_info_iter)?;
351//!     let system_program = next_account_info(account_info_iter)?;
352//!
353//!     assert!(payer.is_writable);
354//!     assert!(payer.is_signer);
355//!     assert!(vault_pda.is_writable);
356//!     assert_eq!(vault_pda.owner, &solana_system_interface::program::ID);
357//!     assert!(solana_system_interface::program::check_id(system_program.key));
358//!
359//!     let vault_bump_seed = instruction_data[0];
360//!     let vault_seeds = &[b"vault", payer.key.as_ref(), &[vault_bump_seed]];
361//!     let expected_vault_pda = Pubkey::create_program_address(vault_seeds, program_id)?;
362//!
363//!     assert_eq!(vault_pda.key, &expected_vault_pda);
364//!
365//!     let lamports = 10000000;
366//!     let vault_size = 16;
367//!
368//!     invoke_signed(
369//!         &create_account(
370//!             &payer.key,
371//!             &vault_pda.key,
372//!             lamports,
373//!             vault_size,
374//!             &program_id,
375//!         ),
376//!         &[
377//!             payer.clone(),
378//!             vault_pda.clone(),
379//!         ],
380//!         &[
381//!             &[
382//!                 b"vault",
383//!                 payer.key.as_ref(),
384//!                 &[vault_bump_seed],
385//!             ],
386//!         ]
387//!     )?;
388//!     Ok(())
389//! }
390//! ```
391//!
392//! # Native programs
393//!
394//! Some solana programs are [_native programs_][np2], running native machine
395//! code that is distributed with the runtime, with well-known program IDs.
396//!
397//! [np2]: https://docs.solanalabs.com/runtime/programs
398//!
399//! Some native programs can be [invoked][cpi] by other programs, but some can
400//! only be executed as "top-level" instructions included by off-chain clients
401//! in a [`Transaction`].
402//!
403//! [`Transaction`]: https://docs.rs/solana-sdk/latest/solana_sdk/transaction/struct.Transaction.html
404//!
405//! This crate defines the program IDs for most native programs. Even though
406//! some native programs cannot be invoked by other programs, a Solana program
407//! may need access to their program IDs. For example, a program may need to
408//! verify that an ed25519 signature verification instruction was included in
409//! the same transaction as its own instruction. For many native programs, this
410//! crate also defines enums that represent the instructions they process, and
411//! constructors for building the instructions.
412//!
413//! Locations of program IDs and instruction constructors are noted in the list
414//! below, as well as whether they are invokable by other programs.
415//!
416//! While some native programs have been active since the genesis block, others
417//! are activated dynamically after a specific [slot], and some are not yet
418//! active. This documentation does not distinguish which native programs are
419//! active on any particular network. The `solana feature status` CLI command
420//! can help in determining active features.
421//!
422//! [slot]: https://solana.com/docs/terminology#slot
423//!
424//! Native programs important to Solana program authors include:
425//!
426//! - __System Program__: Creates new accounts, allocates account data, assigns
427//!   accounts to owning programs, transfers lamports from System Program owned
428//!   accounts and pays transaction fees.
429//!   - ID: [`solana_system_interface::program::ID`](https://docs.rs/solana-system-interface/latest/solana_system_interface/program/constant.ID.html)
430//!   - Instruction: [`solana_system_interface::instruction`](https://docs.rs/solana-system-interface/latest/solana_system_interface/instruction/index.html)
431//!   - Invokable by programs? yes
432//!
433//! - __Compute Budget Program__: Requests additional CPU or memory resources
434//!   for a transaction. This program does nothing when called from another
435//!   program.
436//!   - ID: [`solana_compute_budget_interface::ID`](https://docs.rs/solana-compute-budget-interface/latest/solana_compute_budget_interface/constant.ID.html)
437//!   - Instruction: [`solana_compute_budget_interface::ComputeBudgetInstruction`](https://docs.rs/solana-compute-budget-interface/latest/solana_compute_budget_interface/enum.ComputeBudgetInstruction.html)
438//!   - Invokable by programs? no
439//!
440//! - __ed25519 Program__: Verifies an ed25519 signature.
441//!   - ID: [`solana_sdk_ids::ed25519_program::ID`](https://docs.rs/solana-sdk-ids/latest/solana_sdk_ids/ed25519_program/constant.ID.html)
442//!   - Instruction: [`solana_ed25519_program::new_ed25519_instruction_with_signature`](https://docs.rs/solana-ed25519-program/latest/solana_ed25519_program/fn.new_ed25519_instruction_with_signature.html)
443//!   - Invokable by programs? no
444//!
445//! - __secp256k1 Program__: Verifies secp256k1 public key recovery operations.
446//!   - ID: [`solana_sdk_ids::secp256k1_program::ID`](https://docs.rs/solana-sdk-ids/latest/solana_sdk_ids/secp256k1_program/constant.ID.html)
447//!   - Instruction: [`solana_secp256k1_program::new_secp256k1_instruction_with_signature`](https://docs.rs/solana-secp256k1-program/latest/solana_secp256k1_program/fn.new_secp256k1_instruction_with_signature.html)
448//!   - Invokable by programs? no
449//!
450//! - __BPF Loader__: Deploys, and executes immutable programs on the chain.
451//!   - ID: [`solana_sdk_ids::bpf_loader::ID`](https://docs.rs/solana-sdk-ids/latest/solana_sdk_ids/bpf_loader/constant.ID.html)
452//!   - Instruction: [`solana_loader_v2_interface::instruction`](https://docs.rs/solana-loader-v2-interface/latest/solana_loader_v2_interface/instruction/index.html)
453//!   - Invokable by programs? yes
454//!
455//! - __Upgradable BPF Loader__: Deploys, upgrades, and executes upgradable
456//!   programs on the chain.
457//!   - ID: [`solana_sdk_ids::bpf_loader_upgradeable::ID`](https://docs.rs/solana-sdk-ids/latest/solana_sdk_ids/bpf_loader_upgradeable/constant.ID.html)
458//!   - Instruction: [`solana_loader_v3_interface::instruction`](https://docs.rs/solana-loader-v3-interface/latest/solana_loader_v3_interface/instruction/index.html)
459//!   - Invokable by programs? yes
460//!
461//! - __Deprecated BPF Loader__: Deploys, and executes immutable programs on the
462//!   chain.
463//!   - ID: [`solana_sdk_ids::bpf_loader_deprecated::ID`](https://docs.rs/solana-sdk-ids/latest/solana_sdk_ids/bpf_loader_deprecated/constant.ID.html)
464//!   - Instruction: [`solana_loader_v2_interface::instruction`](https://docs.rs/solana-loader-v2-interface/latest/solana_loader_v2_interface/instruction/index.html)
465//!   - Invokable by programs? yes
466//!
467//! [lut]: https://docs.solanalabs.com/proposals/versioned-transactions
468
469#![allow(incomplete_features)]
470#![cfg_attr(feature = "frozen-abi", feature(specialization))]
471#![cfg_attr(docsrs, feature(doc_cfg))]
472
473// Allows macro expansion of `use ::solana_program::*` to work within this crate
474extern crate self as solana_program;
475
476pub mod bpf_loader;
477pub mod bpf_loader_deprecated;
478pub mod compute_units;
479pub mod ed25519_program;
480pub mod entrypoint_deprecated;
481pub mod epoch_schedule;
482pub use solana_epoch_stake as epoch_stake;
483pub mod hash;
484pub mod incinerator;
485pub mod instruction;
486pub mod lamports;
487pub mod log;
488pub mod program;
489pub mod program_error;
490pub mod secp256k1_program;
491pub mod slot_hashes;
492pub mod slot_history;
493pub mod syscalls;
494pub mod sysvar;
495
496#[deprecated(since = "2.2.0", note = "Use `solana-big-mod-exp` crate instead")]
497pub use solana_big_mod_exp as big_mod_exp;
498#[deprecated(since = "2.2.0", note = "Use `solana-blake3-hasher` crate instead")]
499pub use solana_blake3_hasher as blake3;
500#[cfg(feature = "borsh")]
501#[deprecated(since = "2.1.0", note = "Use `solana-borsh` crate instead")]
502pub use solana_borsh::v1 as borsh1;
503#[deprecated(since = "2.1.0", note = "Use `solana-epoch-rewards` crate instead")]
504pub use solana_epoch_rewards as epoch_rewards;
505#[deprecated(since = "2.1.0", note = "Use `solana-fee-calculator` crate instead")]
506pub use solana_fee_calculator as fee_calculator;
507#[deprecated(since = "2.2.0", note = "Use `solana-keccak-hasher` crate instead")]
508pub use solana_keccak_hasher as keccak;
509#[deprecated(since = "2.1.0", note = "Use `solana-last-restart-slot` crate instead")]
510pub use solana_last_restart_slot as last_restart_slot;
511#[deprecated(since = "2.1.0", note = "Use `solana-program-memory` crate instead")]
512pub use solana_program_memory as program_memory;
513#[deprecated(since = "2.1.0", note = "Use `solana-program-pack` crate instead")]
514pub use solana_program_pack as program_pack;
515#[deprecated(since = "2.1.0", note = "Use `solana-secp256k1-recover` crate instead")]
516pub use solana_secp256k1_recover as secp256k1_recover;
517#[deprecated(since = "2.1.0", note = "Use `solana-serde-varint` crate instead")]
518pub use solana_serde_varint as serde_varint;
519#[deprecated(since = "2.1.0", note = "Use `solana-serialize-utils` crate instead")]
520pub use solana_serialize_utils as serialize_utils;
521#[deprecated(since = "2.1.0", note = "Use `solana-short-vec` crate instead")]
522pub use solana_short_vec as short_vec;
523#[deprecated(since = "2.1.0", note = "Use `solana-stable-layout` crate instead")]
524pub use solana_stable_layout as stable_layout;
525#[cfg(not(target_os = "solana"))]
526pub use solana_sysvar::program_stubs;
527pub use {
528    solana_account_info::{self as account_info, debug_account_data},
529    solana_clock as clock,
530    solana_msg::msg,
531    solana_native_token as native_token,
532    solana_program_entrypoint::{
533        self as entrypoint, custom_heap_default, custom_panic_default, entrypoint,
534        entrypoint_no_alloc,
535    },
536    solana_program_option as program_option, solana_pubkey as pubkey, solana_rent as rent,
537    solana_sysvar::impl_sysvar_get,
538};
539/// The [config native program][np].
540///
541/// [np]: https://docs.solanalabs.com/runtime/programs#config-program
542pub mod config {
543    pub mod program {
544        pub use solana_sdk_ids::config::{check_id, id, ID};
545    }
546}
547
548pub use solana_pubkey::{declare_deprecated_id, declare_id, pubkey};
549#[deprecated(since = "2.1.0", note = "Use `solana-sysvar-id` crate instead")]
550pub use solana_sysvar_id::{declare_deprecated_sysvar_id, declare_sysvar_id};
551
552/// Convenience macro for doing integer division where the operation's safety
553/// can be checked at compile-time.
554///
555/// Since `unchecked_div_by_const!()` is supposed to fail at compile-time, abuse
556/// doctests to cover failure modes
557///
558/// # Examples
559///
560/// Literal denominator div-by-zero fails:
561///
562/// ```compile_fail
563/// # use solana_program::unchecked_div_by_const;
564/// # fn main() {
565/// let _ = unchecked_div_by_const!(10, 0);
566/// # }
567/// ```
568///
569/// Const denominator div-by-zero fails:
570///
571/// ```compile_fail
572/// # use solana_program::unchecked_div_by_const;
573/// # fn main() {
574/// const D: u64 = 0;
575/// let _ = unchecked_div_by_const!(10, D);
576/// # }
577/// ```
578///
579/// Non-const denominator fails:
580///
581/// ```compile_fail
582/// # use solana_program::unchecked_div_by_const;
583/// # fn main() {
584/// let d = 0;
585/// let _ = unchecked_div_by_const!(10, d);
586/// # }
587/// ```
588///
589/// Literal denominator div-by-zero fails:
590///
591/// ```compile_fail
592/// # use solana_program::unchecked_div_by_const;
593/// # fn main() {
594/// const N: u64 = 10;
595/// let _ = unchecked_div_by_const!(N, 0);
596/// # }
597/// ```
598///
599/// Const denominator div-by-zero fails:
600///
601/// ```compile_fail
602/// # use solana_program::unchecked_div_by_const;
603/// # fn main() {
604/// const N: u64 = 10;
605/// const D: u64 = 0;
606/// let _ = unchecked_div_by_const!(N, D);
607/// # }
608/// ```
609///
610/// Non-const denominator fails:
611///
612/// ```compile_fail
613/// # use solana_program::unchecked_div_by_const;
614/// # fn main() {
615/// # const N: u64 = 10;
616/// let d = 0;
617/// let _ = unchecked_div_by_const!(N, d);
618/// # }
619/// ```
620///
621/// Literal denominator div-by-zero fails:
622///
623/// ```compile_fail
624/// # use solana_program::unchecked_div_by_const;
625/// # fn main() {
626/// let n = 10;
627/// let _ = unchecked_div_by_const!(n, 0);
628/// # }
629/// ```
630///
631/// Const denominator div-by-zero fails:
632///
633/// ```compile_fail
634/// # use solana_program::unchecked_div_by_const;
635/// # fn main() {
636/// let n = 10;
637/// const D: u64 = 0;
638/// let _ = unchecked_div_by_const!(n, D);
639/// # }
640/// ```
641///
642/// Non-const denominator fails:
643///
644/// ```compile_fail
645/// # use solana_program::unchecked_div_by_const;
646/// # fn main() {
647/// let n = 10;
648/// let d = 0;
649/// let _ = unchecked_div_by_const!(n, d);
650/// # }
651/// ```
652#[macro_export]
653macro_rules! unchecked_div_by_const {
654    ($num:expr, $den:expr) => {{
655        // Ensure the denominator is compile-time constant
656        let _ = [(); ($den - $den) as usize];
657        // Compile-time constant integer div-by-zero passes for some reason
658        // when invoked from a compilation unit other than that where this
659        // macro is defined. Do an explicit zero-check for now. Sorry about the
660        // ugly error messages!
661        // https://users.rust-lang.org/t/unexpected-behavior-of-compile-time-integer-div-by-zero-check-in-declarative-macro/56718
662        let _ = [(); ($den as usize) - 1];
663        #[allow(clippy::arithmetic_side_effects)]
664        let quotient = $num / $den;
665        quotient
666    }};
667}
668
669// This re-export is purposefully listed after all other exports: because of an
670// interaction within rustdoc between the reexports inside this module of
671// `solana_program`'s top-level modules, and `solana_sdk`'s glob re-export of
672// `solana_program`'s top-level modules, if this re-export is not lexically last
673// rustdoc fails to generate documentation for the re-exports within
674// `solana_sdk`.
675#[deprecated(since = "2.2.0", note = "Use solana-example-mocks instead")]
676#[cfg(not(target_os = "solana"))]
677pub use solana_example_mocks as example_mocks;
678
679#[cfg(test)]
680mod tests {
681    #[test]
682    fn test_unchecked_div_by_const() {
683        const D: u64 = 2;
684        const N: u64 = 10;
685        let n = 10;
686        assert_eq!(unchecked_div_by_const!(10, 2), 5);
687        assert_eq!(unchecked_div_by_const!(N, 2), 5);
688        assert_eq!(unchecked_div_by_const!(n, 2), 5);
689        assert_eq!(unchecked_div_by_const!(10, D), 5);
690        assert_eq!(unchecked_div_by_const!(N, D), 5);
691        assert_eq!(unchecked_div_by_const!(n, D), 5);
692    }
693}