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/lang-rust#restrictions
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", "rlib"]
98//!
99//! [features]
100//! no-entrypoint = []
101//! ```
102//!
103//! Note that a Solana program must specify its crate-type as "cdylib", and
104//! "cdylib" crates will automatically be discovered and built by the `cargo
105//! build-bpf` command. Solana programs also often have crate-type "rlib" so
106//! they can be linked to other Rust crates.
107//!
108//! # On-chain vs. off-chain compilation targets
109//!
110//! Solana programs run on the [rbpf] VM, which implements a variant of the
111//! [eBPF] instruction set. Because this crate can be compiled for both on-chain
112//! and off-chain execution, the environments of which are significantly
113//! different, it extensively uses [conditional compilation][cc] to tailor its
114//! implementation to the environment. The `cfg` predicate used for identifying
115//! compilation for on-chain programs is `target_os = "solana"`, as in this
116//! example from the `solana-program` codebase that logs a message via a
117//! syscall when run on-chain, and via a library call when offchain:
118//!
119//! [rbpf]: https://github.com/solana-labs/rbpf
120//! [eBPF]: https://ebpf.io/
121//! [cc]: https://doc.rust-lang.org/reference/conditional-compilation.html
122//!
123//! ```
124//! pub fn sol_log(message: &str) {
125//!     #[cfg(target_os = "solana")]
126//!     unsafe {
127//!         sol_log_(message.as_ptr(), message.len() as u64);
128//!     }
129//!
130//!     #[cfg(not(target_os = "solana"))]
131//!     program_stubs::sol_log(message);
132//! }
133//! # mod program_stubs {
134//! #     pub(crate) fn sol_log(message: &str) { }
135//! # }
136//! ```
137//!
138//! This `cfg` pattern is suitable as well for user code that needs to work both
139//! on-chain and off-chain.
140//!
141//! `solana-program` and `solana-sdk` were previously a single crate. Because of
142//! this history, and because of the dual-usage of `solana-program` for two
143//! different environments, it contains some features that are not available to
144//! on-chain programs at compile-time. It also contains some on-chain features
145//! that will fail in off-chain scenarios at runtime. This distinction is not
146//! well-reflected in the documentation.
147//!
148//! For a more complete description of Solana's implementation of eBPF and its
149//! limitations, see the main Solana documentation for [on-chain programs][ocp].
150//!
151//! [ocp]: https://solana.com/docs/programs
152//!
153//! # Core data types
154//!
155//! - [`Pubkey`] — The address of a [Solana account][acc]. Some account
156//!   addresses are [ed25519] public keys, with corresponding secret keys that
157//!   are managed off-chain. Often, though, account addresses do not have
158//!   corresponding secret keys — as with [_program derived
159//!   addresses_][pdas] — or the secret key is not relevant to the
160//!   operation of a program, and may have even been disposed of. As running
161//!   Solana programs can not safely create or manage secret keys, the full
162//!   [`Keypair`] is not defined in `solana-program` but in `solana-sdk`.
163//! - [`Hash`] — A cryptographic hash. Used to uniquely identify blocks,
164//!   and also for general purpose hashing.
165//! - [`AccountInfo`] — A description of a single Solana account. All accounts
166//!   that might be accessed by a program invocation are provided to the program
167//!   entrypoint as `AccountInfo`.
168//! - [`Instruction`] — A directive telling the runtime to execute a program,
169//!   passing it a set of accounts and program-specific data.
170//! - [`ProgramError`] and [`ProgramResult`] — The error type that all programs
171//!   must return, reported to the runtime as a `u64`.
172//! - [`Sol`] — The Solana native token type, with conversions to and from
173//!   [_lamports_], the smallest fractional unit of SOL, in the [`native_token`]
174//!   module.
175//!
176//! [acc]: https://solana.com/docs/core/accounts
177//! [`Pubkey`]: pubkey::Pubkey
178//! [`Hash`]: hash::Hash
179//! [`Instruction`]: instruction::Instruction
180//! [`AccountInfo`]: account_info::AccountInfo
181//! [`ProgramError`]: program_error::ProgramError
182//! [`ProgramResult`]: entrypoint::ProgramResult
183//! [ed25519]: https://ed25519.cr.yp.to/
184//! [`Keypair`]: https://docs.rs/solana-sdk/latest/solana_sdk/signer/keypair/struct.Keypair.html
185//! [SHA-256]: https://en.wikipedia.org/wiki/SHA-2
186//! [`Sol`]: native_token::Sol
187//! [_lamports_]: https://solana.com/docs/intro#what-are-sols
188//!
189//! # Serialization
190//!
191//! Within the Solana runtime, programs, and network, at least three different
192//! serialization formats are used, and `solana-program` provides access to
193//! those needed by programs.
194//!
195//! In user-written Solana program code, serialization is primarily used for
196//! accessing [`AccountInfo`] data and [`Instruction`] data, both of which are
197//! program-specific binary data. Every program is free to decide their own
198//! serialization format, but data received from other sources —
199//! [sysvars][sysvar] for example — must be deserialized using the methods
200//! indicated by the documentation for that data or data type.
201//!
202//! [`AccountInfo`]: account_info::AccountInfo
203//! [`Instruction`]: instruction::Instruction
204//!
205//! The three serialization formats in use in Solana are:
206//!
207//! - __[Borsh]__, a compact and well-specified format developed by the [NEAR]
208//!   project, suitable for use in protocol definitions and for archival storage.
209//!   It has a [Rust implementation][brust] and a [JavaScript implementation][bjs]
210//!   and is recommended for all purposes.
211//!
212//!   Users need to import the [`borsh`] crate themselves — it is not
213//!   re-exported by `solana-program`, though this crate provides several useful
214//!   utilities in its [`borsh` module][borshmod] that are not available in the
215//!   `borsh` library.
216//!
217//!   The [`Instruction::new_with_borsh`] function creates an `Instruction` by
218//!   serializing a value with borsh.
219//!
220//!   [Borsh]: https://borsh.io/
221//!   [NEAR]: https://near.org/
222//!   [brust]: https://docs.rs/borsh
223//!   [bjs]: https://github.com/near/borsh-js
224//!   [`borsh`]: https://docs.rs/borsh
225//!   [borshmod]: crate::borsh
226//!   [`Instruction::new_with_borsh`]: instruction::Instruction::new_with_borsh
227//!
228//! - __[Bincode]__, a compact serialization format that implements the [Serde]
229//!   Rust APIs. As it does not have a specification nor a JavaScript
230//!   implementation, and uses more CPU than borsh, it is not recommend for new
231//!   code.
232//!
233//!   Many system program and native program instructions are serialized with
234//!   bincode, and it is used for other purposes in the runtime. In these cases
235//!   Rust programmers are generally not directly exposed to the encoding format
236//!   as it is hidden behind APIs.
237//!
238//!   The [`Instruction::new_with_bincode`] function creates an `Instruction` by
239//!   serializing a value with bincode.
240//!
241//!   [Bincode]: https://docs.rs/bincode
242//!   [Serde]: https://serde.rs/
243//!   [`Instruction::new_with_bincode`]: instruction::Instruction::new_with_bincode
244//!
245//! - __[`Pack`]__, a Solana-specific serialization API that is used by many
246//!   older programs in the [Solana Program Library][spl] to define their
247//!   account format. It is difficult to implement and does not define a
248//!   language-independent serialization format. It is not generally recommended
249//!   for new code.
250//!
251//!   [`Pack`]: https://docs.rs/solana-program-pack/latest/trait.Pack.html
252//!
253//! Developers should carefully consider the CPU cost of serialization, balanced
254//! against the need for correctness and ease of use: off-the-shelf
255//! serialization formats tend to be more expensive than carefully hand-written
256//! application-specific formats; but application-specific formats are more
257//! difficult to ensure the correctness of, and to provide multi-language
258//! implementations for. It is not uncommon for programs to pack and unpack
259//! their data with hand-written code.
260//!
261//! # Cross-program instruction execution
262//!
263//! Solana programs may call other programs, termed [_cross-program
264//! invocation_][cpi] (CPI), with the [`invoke`] and [`invoke_signed`]
265//! functions. When calling another program the caller must provide the
266//! [`Instruction`] to be invoked, as well as the [`AccountInfo`] for every
267//! account required by the instruction. Because the only way for a program to
268//! acquire `AccountInfo` values is by receiving them from the runtime at the
269//! [program entrypoint][entrypoint!], any account required by the callee
270//! program must transitively be required by the caller program, and provided by
271//! _its_ caller.
272//!
273//! [`invoke`]: program::invoke
274//! [`invoke_signed`]: program::invoke_signed
275//! [cpi]: https://solana.com/docs/core/cpi
276//!
277//! A simple example of transferring lamports via CPI:
278//!
279//! ```
280//! use solana_program::{
281//!     account_info::{next_account_info, AccountInfo},
282//!     entrypoint,
283//!     entrypoint::ProgramResult,
284//!     program::invoke,
285//!     pubkey::Pubkey,
286//!     system_instruction,
287//!     system_program,
288//! };
289//!
290//! entrypoint!(process_instruction);
291//!
292//! fn process_instruction(
293//!     program_id: &Pubkey,
294//!     accounts: &[AccountInfo],
295//!     instruction_data: &[u8],
296//! ) -> ProgramResult {
297//!     let account_info_iter = &mut accounts.iter();
298//!
299//!     let payer = next_account_info(account_info_iter)?;
300//!     let recipient = next_account_info(account_info_iter)?;
301//!
302//!     assert!(payer.is_writable);
303//!     assert!(payer.is_signer);
304//!     assert!(recipient.is_writable);
305//!
306//!     let lamports = 1000000;
307//!
308//!     invoke(
309//!         &system_instruction::transfer(payer.key, recipient.key, lamports),
310//!         &[payer.clone(), recipient.clone()],
311//!     )
312//! }
313//! ```
314//!
315//! Solana also includes a mechanism to let programs control and sign for
316//! accounts without needing to protect a corresponding secret key, called
317//! [_program derived addresses_][pdas]. PDAs are derived with the
318//! [`Pubkey::find_program_address`] function. With a PDA, a program can call
319//! `invoke_signed` to call another program while virtually "signing" for the
320//! PDA.
321//!
322//! [pdas]: https://solana.com/docs/core/cpi#program-derived-addresses
323//! [`Pubkey::find_program_address`]: pubkey::Pubkey::find_program_address
324//!
325//! A simple example of creating an account for a PDA:
326//!
327//! ```
328//! use solana_program::{
329//!     account_info::{next_account_info, AccountInfo},
330//!     entrypoint,
331//!     entrypoint::ProgramResult,
332//!     program::invoke_signed,
333//!     pubkey::Pubkey,
334//!     system_instruction,
335//!     system_program,
336//! };
337//!
338//! entrypoint!(process_instruction);
339//!
340//! fn process_instruction(
341//!     program_id: &Pubkey,
342//!     accounts: &[AccountInfo],
343//!     instruction_data: &[u8],
344//! ) -> ProgramResult {
345//!     let account_info_iter = &mut accounts.iter();
346//!     let payer = next_account_info(account_info_iter)?;
347//!     let vault_pda = next_account_info(account_info_iter)?;
348//!     let system_program = next_account_info(account_info_iter)?;
349//!
350//!     assert!(payer.is_writable);
351//!     assert!(payer.is_signer);
352//!     assert!(vault_pda.is_writable);
353//!     assert_eq!(vault_pda.owner, &system_program::ID);
354//!     assert!(system_program::check_id(system_program.key));
355//!
356//!     let vault_bump_seed = instruction_data[0];
357//!     let vault_seeds = &[b"vault", payer.key.as_ref(), &[vault_bump_seed]];
358//!     let expected_vault_pda = Pubkey::create_program_address(vault_seeds, program_id)?;
359//!
360//!     assert_eq!(vault_pda.key, &expected_vault_pda);
361//!
362//!     let lamports = 10000000;
363//!     let vault_size = 16;
364//!
365//!     invoke_signed(
366//!         &system_instruction::create_account(
367//!             &payer.key,
368//!             &vault_pda.key,
369//!             lamports,
370//!             vault_size,
371//!             &program_id,
372//!         ),
373//!         &[
374//!             payer.clone(),
375//!             vault_pda.clone(),
376//!         ],
377//!         &[
378//!             &[
379//!                 b"vault",
380//!                 payer.key.as_ref(),
381//!                 &[vault_bump_seed],
382//!             ],
383//!         ]
384//!     )?;
385//!     Ok(())
386//! }
387//! ```
388//!
389//! # Native programs
390//!
391//! Some solana programs are [_native programs_][np2], running native machine
392//! code that is distributed with the runtime, with well-known program IDs.
393//!
394//! [np2]: https://docs.solanalabs.com/runtime/programs
395//!
396//! Some native programs can be [invoked][cpi] by other programs, but some can
397//! only be executed as "top-level" instructions included by off-chain clients
398//! in a [`Transaction`].
399//!
400//! [`Transaction`]: https://docs.rs/solana-sdk/latest/solana_sdk/transaction/struct.Transaction.html
401//!
402//! This crate defines the program IDs for most native programs. Even though
403//! some native programs cannot be invoked by other programs, a Solana program
404//! may need access to their program IDs. For example, a program may need to
405//! verify that an ed25519 signature verification instruction was included in
406//! the same transaction as its own instruction. For many native programs, this
407//! crate also defines enums that represent the instructions they process, and
408//! constructors for building the instructions.
409//!
410//! Locations of program IDs and instruction constructors are noted in the list
411//! below, as well as whether they are invokable by other programs.
412//!
413//! While some native programs have been active since the genesis block, others
414//! are activated dynamically after a specific [slot], and some are not yet
415//! active. This documentation does not distinguish which native programs are
416//! active on any particular network. The `solana feature status` CLI command
417//! can help in determining active features.
418//!
419//! [slot]: https://solana.com/docs/terminology#slot
420//!
421//! Native programs important to Solana program authors include:
422//!
423//! - __System Program__: Creates new accounts, allocates account data, assigns
424//!   accounts to owning programs, transfers lamports from System Program owned
425//!   accounts and pays transaction fees.
426//!   - ID: [`solana_program::system_program`]
427//!   - Instruction: [`solana_program::system_instruction`]
428//!   - Invokable by programs? yes
429//!
430//! - __Compute Budget Program__: Requests additional CPU or memory resources
431//!   for a transaction. This program does nothing when called from another
432//!   program.
433//!   - ID: [`solana_sdk::compute_budget`](https://docs.rs/solana-sdk/latest/solana_sdk/compute_budget/index.html)
434//!   - Instruction: [`solana_sdk::compute_budget`](https://docs.rs/solana-sdk/latest/solana_sdk/compute_budget/index.html)
435//!   - Invokable by programs? no
436//!
437//! - __ed25519 Program__: Verifies an ed25519 signature.
438//!   - ID: [`solana_program::ed25519_program`]
439//!   - Instruction: [`solana_sdk::ed25519_instruction`](https://docs.rs/solana-sdk/latest/solana_sdk/ed25519_instruction/index.html)
440//!   - Invokable by programs? no
441//!
442//! - __secp256k1 Program__: Verifies secp256k1 public key recovery operations.
443//!   - ID: [`solana_program::secp256k1_program`]
444//!   - Instruction: [`solana_sdk::secp256k1_instruction`](https://docs.rs/solana-sdk/latest/solana_sdk/secp256k1_instruction/index.html)
445//!   - Invokable by programs? no
446//!
447//! - __BPF Loader__: Deploys, and executes immutable programs on the chain.
448//!   - ID: [`solana_program::bpf_loader`]
449//!   - Instruction: [`solana_program::loader_instruction`]
450//!   - Invokable by programs? yes
451//!
452//! - __Upgradable BPF Loader__: Deploys, upgrades, and executes upgradable
453//!   programs on the chain.
454//!   - ID: [`solana_program::bpf_loader_upgradeable`]
455//!   - Instruction: [`solana_program::loader_upgradeable_instruction`]
456//!   - Invokable by programs? yes
457//!
458//! - __Deprecated BPF Loader__: Deploys, and executes immutable programs on the
459//!   chain.
460//!   - ID: [`solana_program::bpf_loader_deprecated`]
461//!   - Instruction: [`solana_program::loader_instruction`]
462//!   - Invokable by programs? yes
463//!
464//! [lut]: https://docs.solanalabs.com/proposals/versioned-transactions
465
466#![allow(incomplete_features)]
467#![cfg_attr(feature = "frozen-abi", feature(specialization))]
468#![cfg_attr(docsrs, feature(doc_auto_cfg))]
469
470// Allows macro expansion of `use ::solana_program::*` to work within this crate
471extern crate self as solana_program;
472
473pub mod address_lookup_table;
474pub mod bpf_loader;
475pub mod bpf_loader_deprecated;
476pub mod bpf_loader_upgradeable;
477pub mod compute_units;
478pub mod ed25519_program;
479pub mod entrypoint_deprecated;
480pub mod epoch_schedule;
481pub mod epoch_stake;
482pub mod hash;
483pub mod incinerator;
484pub mod instruction;
485pub mod lamports;
486#[deprecated(
487    since = "2.3.0",
488    note = "Use solana_loader_v3_interface::instruction instead"
489)]
490pub mod loader_upgradeable_instruction {
491    pub use solana_loader_v3_interface::instruction::UpgradeableLoaderInstruction;
492}
493pub mod loader_v4;
494#[deprecated(
495    since = "2.3.0",
496    note = "Use solana_loader_v4_interface::instruction instead"
497)]
498pub mod loader_v4_instruction {
499    pub use solana_loader_v4_interface::instruction::LoaderV4Instruction;
500}
501pub mod log;
502pub mod nonce;
503pub mod program;
504pub mod program_error;
505#[deprecated(
506    since = "2.3.0",
507    note = "Use `solana_bincode::limited_deserialize` instead"
508)]
509pub mod program_utils;
510pub mod secp256k1_program;
511pub mod slot_hashes;
512pub mod slot_history;
513pub mod stake;
514pub mod stake_history;
515pub mod syscalls;
516pub mod system_instruction;
517pub mod system_program;
518pub mod sysvar;
519pub mod wasm;
520
521#[deprecated(since = "2.2.0", note = "Use `solana-big-mod-exp` crate instead")]
522pub use solana_big_mod_exp as big_mod_exp;
523#[deprecated(since = "2.2.0", note = "Use `solana-blake3-hasher` crate instead")]
524pub use solana_blake3_hasher as blake3;
525#[cfg(feature = "borsh")]
526#[deprecated(since = "2.1.0", note = "Use `solana-borsh` crate instead")]
527pub use solana_borsh::deprecated as borsh;
528#[cfg(feature = "borsh")]
529#[deprecated(since = "2.1.0", note = "Use `solana-borsh` crate instead")]
530pub use solana_borsh::v0_10 as borsh0_10;
531#[cfg(feature = "borsh")]
532#[deprecated(since = "2.1.0", note = "Use `solana-borsh` crate instead")]
533pub use solana_borsh::v1 as borsh1;
534#[deprecated(since = "2.1.0", note = "Use `solana-epoch-rewards` crate instead")]
535pub use solana_epoch_rewards as epoch_rewards;
536#[deprecated(
537    since = "2.3.0",
538    note = "Use `solana-feature-gate-interface` crate instead"
539)]
540pub mod feature {
541    pub use solana_feature_gate_interface::*;
542}
543#[deprecated(since = "2.1.0", note = "Use `solana-fee-calculator` crate instead")]
544pub use solana_fee_calculator as fee_calculator;
545#[deprecated(since = "2.2.0", note = "Use `solana-keccak-hasher` crate instead")]
546pub use solana_keccak_hasher as keccak;
547#[deprecated(since = "2.1.0", note = "Use `solana-last-restart-slot` crate instead")]
548pub use solana_last_restart_slot as last_restart_slot;
549#[deprecated(
550    since = "2.3.0",
551    note = "Use `solana-loader-v2-interface` crate instead"
552)]
553pub mod loader_instruction {
554    pub use solana_loader_v2_interface::*;
555}
556#[deprecated(since = "2.3.0", note = "Use `solana-message` crate instead")]
557pub mod message {
558    pub use solana_message::*;
559}
560#[deprecated(since = "2.1.0", note = "Use `solana-program-memory` crate instead")]
561pub use solana_program_memory as program_memory;
562#[deprecated(since = "2.1.0", note = "Use `solana-program-pack` crate instead")]
563pub use solana_program_pack as program_pack;
564#[deprecated(since = "2.3.0", note = "Use `solana-sanitize` crate instead")]
565pub mod sanitize {
566    pub use solana_sanitize::*;
567}
568#[deprecated(since = "2.1.0", note = "Use `solana-secp256k1-recover` crate instead")]
569pub use solana_secp256k1_recover as secp256k1_recover;
570#[deprecated(since = "2.1.0", note = "Use `solana-serde-varint` crate instead")]
571pub use solana_serde_varint as serde_varint;
572#[deprecated(since = "2.1.0", note = "Use `solana-serialize-utils` crate instead")]
573pub use solana_serialize_utils as serialize_utils;
574#[deprecated(since = "2.1.0", note = "Use `solana-short-vec` crate instead")]
575pub use solana_short_vec as short_vec;
576#[deprecated(since = "2.1.0", note = "Use `solana-stable-layout` crate instead")]
577pub use solana_stable_layout as stable_layout;
578#[cfg(not(target_os = "solana"))]
579pub use solana_sysvar::program_stubs;
580#[deprecated(since = "2.3.0", note = "Use `solana-vote-interface` crate instead")]
581pub mod vote {
582    pub use solana_vote_interface::*;
583}
584#[cfg(target_arch = "wasm32")]
585pub use wasm_bindgen::prelude::wasm_bindgen;
586pub use {
587    solana_account_info::{self as account_info, debug_account_data},
588    solana_clock as clock,
589    solana_msg::msg,
590    solana_native_token as native_token,
591    solana_program_entrypoint::{
592        self as entrypoint, custom_heap_default, custom_panic_default, entrypoint,
593        entrypoint_no_alloc,
594    },
595    solana_program_option as program_option, solana_pubkey as pubkey, solana_rent as rent,
596    solana_sysvar::impl_sysvar_get,
597};
598/// The [config native program][np].
599///
600/// [np]: https://docs.solanalabs.com/runtime/programs#config-program
601pub mod config {
602    pub mod program {
603        pub use solana_sdk_ids::config::{check_id, id, ID};
604    }
605}
606
607/// A vector of Solana SDK IDs.
608#[deprecated(
609    since = "2.0.0",
610    note = "Please use `solana_sdk::reserved_account_keys::ReservedAccountKeys` instead"
611)]
612#[allow(deprecated)]
613pub mod sdk_ids {
614    use {
615        crate::{
616            address_lookup_table, bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable,
617            config, ed25519_program, feature, incinerator, loader_v4, secp256k1_program,
618            solana_program::pubkey::Pubkey, stake, system_program, sysvar, vote,
619        },
620        lazy_static::lazy_static,
621    };
622
623    lazy_static! {
624        pub static ref SDK_IDS: Vec<Pubkey> = {
625            let mut sdk_ids = vec![
626                ed25519_program::id(),
627                secp256k1_program::id(),
628                system_program::id(),
629                sysvar::id(),
630                bpf_loader::id(),
631                bpf_loader_upgradeable::id(),
632                incinerator::id(),
633                config::program::id(),
634                vote::program::id(),
635                feature::id(),
636                bpf_loader_deprecated::id(),
637                address_lookup_table::program::id(),
638                loader_v4::id(),
639                stake::program::id(),
640                #[allow(deprecated)]
641                stake::config::id(),
642            ];
643            sdk_ids.extend(sysvar::ALL_IDS.iter());
644            sdk_ids
645        };
646    }
647}
648
649#[deprecated(since = "2.3.0", note = "Use `num_traits::FromPrimitive` instead")]
650pub mod decode_error {
651    pub use solana_decode_error::*;
652}
653pub use solana_pubkey::{declare_deprecated_id, declare_id, pubkey};
654#[deprecated(since = "2.1.0", note = "Use `solana-sysvar-id` crate instead")]
655pub use solana_sysvar_id::{declare_deprecated_sysvar_id, declare_sysvar_id};
656
657/// Convenience macro for doing integer division where the operation's safety
658/// can be checked at compile-time.
659///
660/// Since `unchecked_div_by_const!()` is supposed to fail at compile-time, abuse
661/// doctests to cover failure modes
662///
663/// # Examples
664///
665/// Literal denominator div-by-zero fails:
666///
667/// ```compile_fail
668/// # use solana_program::unchecked_div_by_const;
669/// # fn main() {
670/// let _ = unchecked_div_by_const!(10, 0);
671/// # }
672/// ```
673///
674/// Const denominator div-by-zero fails:
675///
676/// ```compile_fail
677/// # use solana_program::unchecked_div_by_const;
678/// # fn main() {
679/// const D: u64 = 0;
680/// let _ = unchecked_div_by_const!(10, D);
681/// # }
682/// ```
683///
684/// Non-const denominator fails:
685///
686/// ```compile_fail
687/// # use solana_program::unchecked_div_by_const;
688/// # fn main() {
689/// let d = 0;
690/// let _ = unchecked_div_by_const!(10, d);
691/// # }
692/// ```
693///
694/// Literal denominator div-by-zero fails:
695///
696/// ```compile_fail
697/// # use solana_program::unchecked_div_by_const;
698/// # fn main() {
699/// const N: u64 = 10;
700/// let _ = unchecked_div_by_const!(N, 0);
701/// # }
702/// ```
703///
704/// Const denominator div-by-zero fails:
705///
706/// ```compile_fail
707/// # use solana_program::unchecked_div_by_const;
708/// # fn main() {
709/// const N: u64 = 10;
710/// const D: u64 = 0;
711/// let _ = unchecked_div_by_const!(N, D);
712/// # }
713/// ```
714///
715/// Non-const denominator fails:
716///
717/// ```compile_fail
718/// # use solana_program::unchecked_div_by_const;
719/// # fn main() {
720/// # const N: u64 = 10;
721/// let d = 0;
722/// let _ = unchecked_div_by_const!(N, d);
723/// # }
724/// ```
725///
726/// Literal denominator div-by-zero fails:
727///
728/// ```compile_fail
729/// # use solana_program::unchecked_div_by_const;
730/// # fn main() {
731/// let n = 10;
732/// let _ = unchecked_div_by_const!(n, 0);
733/// # }
734/// ```
735///
736/// Const denominator div-by-zero fails:
737///
738/// ```compile_fail
739/// # use solana_program::unchecked_div_by_const;
740/// # fn main() {
741/// let n = 10;
742/// const D: u64 = 0;
743/// let _ = unchecked_div_by_const!(n, D);
744/// # }
745/// ```
746///
747/// Non-const denominator fails:
748///
749/// ```compile_fail
750/// # use solana_program::unchecked_div_by_const;
751/// # fn main() {
752/// let n = 10;
753/// let d = 0;
754/// let _ = unchecked_div_by_const!(n, d);
755/// # }
756/// ```
757#[macro_export]
758macro_rules! unchecked_div_by_const {
759    ($num:expr, $den:expr) => {{
760        // Ensure the denominator is compile-time constant
761        let _ = [(); ($den - $den) as usize];
762        // Compile-time constant integer div-by-zero passes for some reason
763        // when invoked from a compilation unit other than that where this
764        // macro is defined. Do an explicit zero-check for now. Sorry about the
765        // ugly error messages!
766        // https://users.rust-lang.org/t/unexpected-behavior-of-compile-time-integer-div-by-zero-check-in-declarative-macro/56718
767        let _ = [(); ($den as usize) - 1];
768        #[allow(clippy::arithmetic_side_effects)]
769        let quotient = $num / $den;
770        quotient
771    }};
772}
773
774// This re-export is purposefully listed after all other exports: because of an
775// interaction within rustdoc between the reexports inside this module of
776// `solana_program`'s top-level modules, and `solana_sdk`'s glob re-export of
777// `solana_program`'s top-level modules, if this re-export is not lexically last
778// rustdoc fails to generate documentation for the re-exports within
779// `solana_sdk`.
780#[deprecated(since = "2.2.0", note = "Use solana-example-mocks instead")]
781#[cfg(not(target_os = "solana"))]
782pub use solana_example_mocks as example_mocks;
783
784#[cfg(test)]
785mod tests {
786    use super::unchecked_div_by_const;
787
788    #[test]
789    fn test_unchecked_div_by_const() {
790        const D: u64 = 2;
791        const N: u64 = 10;
792        let n = 10;
793        assert_eq!(unchecked_div_by_const!(10, 2), 5);
794        assert_eq!(unchecked_div_by_const!(N, 2), 5);
795        assert_eq!(unchecked_div_by_const!(n, 2), 5);
796        assert_eq!(unchecked_div_by_const!(10, D), 5);
797        assert_eq!(unchecked_div_by_const!(N, D), 5);
798        assert_eq!(unchecked_div_by_const!(n, D), 5);
799    }
800}