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