Rust SDK for the Solana blockchain, used by on-chain programs and the Agave validator.
The easiest way to upgrade to v3 is:
- upgrade to the latest v2 crates
- fix all deprecation warnings
- (optional) switch to using SPL interface crates v1
- upgrade to v3-compatible crates
- (optional) upgrade SPL interface crates to v2
The following modules have been removed, please use their component crates directly:
address_lookup_table
->solana_address_lookup_table_interface
alt_bn128
->solana_bn254
bpf_loader_upgradeable
->solana_loader_v3_interface
client
->solana_client_traits
commitment_config
->solana_commitment_config
compute_budget
->solana_compute_budget_interface
decode_error
->solana_decode_error
derivation_path
->solana_derivation_path
ed25519_instruction
->solana_ed25519_program
exit
->solana_validator_exit
feature_set
->agave_feature_set
feature
->solana_feature_gate_interface
genesis_config
->solana_genesis_config
hard_forks
->solana_hard_forks
loader_instruction
->solana_loader_v2_interface
loader_upgradeable_instruction
->solana_loader_v3_interface::instruction
loader_v4
->solana_loader_v4_interface
loader_v4_instruction
->solana_loader_v4_interface::instruction
nonce
->solana_nonce
nonce_account
->solana_nonce_account
packet
->solana_packet
poh_config
->solana_poh_config
precompiles
->agave_precompiles
program_utils
->solana_bincode::limited_deserialize
quic
->solana_quic_definitions
reserved_account_keys
->agave_reserved_account_keys
reward_info
->solana_reward_info
reward_type
->solana_reward_info
sdk_ids
->solana_sdk_ids
secp256k1_instruction
->solana_secp256k1_program
secp256k1_recover
->solana_secp256k1_recover
stake
->solana_stake_interface
stake_history
->solana_stake_interface::stake_history
system_instruction
->solana_system_interface::instruction
system_program
->solana_system_interface::program
system_transaction
->solana_system_transaction
transaction_context
->solana_transaction_context
vote
->solana_vote_interface
The following modules have been removed, please use their component crates directly:
address_lookup_table
->solana_address_lookup_table_interface
bpf_loader_upgradeable
->solana_loader_v3_interface
decode_error
->solana_decode_error
feature
->solana_feature_gate_interface
loader_instruction
->solana_loader_v2_interface
loader_upgradeable_instruction
->solana_loader_v3_interface::instruction
loader_v4
->solana_loader_v4_interface
loader_v4_instruction
->solana_loader_v4_interface::instruction
message
->solana_message
nonce
->solana_nonce
program_utils
->solana_bincode::limited_deserialize
sanitize
->solana_sanitize
sdk_ids
->solana_sdk_ids
stake
->solana_stake_interface
stake_history
->solana_stake_interface::stake_history
system_instruction
->solana_system_interface::instruction
system_program
->solana_system_interface::program
vote
->solana_vote_interface
SDK v3 introduces the Address
type, a better named and more flexible version
of Pubkey
. Pubkey
is a type alias of Address
, so if you see errors related
to Address
vs Pubkey
in your build, it simply means that one of your
dependencies hasn't been upgraded to v3.
Removed rent_epoch
field, now called _unused
. This field can be completely
ignored. The final parameter in AccountInfo::new
was removed.
The inner bytes were made private, so use Hash::as_bytes()
to access them.
Moved ClusterType
to solana-cluster-type
.
Use Keypair::try_from
instead of Keypair::from_bytes
.
Changed BorshIoError(String)
-> BorshIoError
, so no more string parameter
exists in either InstructionError
or ProgramError
.
Marked all onchain memory operations usage as unsafe, so all usages of memory
operations need to be in an unsafe
block.
If you're using Sysvar::from_account_info
, you'll need to also import
solana_sysvar::SysvarSerialize
.
StakeHistory
now lives in solana_stake_interface
instead of solana_sysvar
.
VoteState
->VoteStateV3
convert_to_current
->convert_to_v3
new_current
->new_v3
SPL libraries have been broken up between an interface and program crate for lighter dependency management and to allow LTO on builds.
When upgrading to SDK v3 crates, replace the following with v2 of the corresponding interface crate:
spl-token
->spl-token-interface
spl-token-2022
->spl-token-2022-interface
spl-associated-token-account
->spl-associated-token-account-interface
spl-memo
->spl-memo-interface
For example, if you're using spl-token
v8, you should switch to
spl-token-interface
v2 when upgrading to SDK v3. The state, instruction, and
error modules mimic the program crates, so no other changes should be required.
Program crates, like spl-token
, contain a cdylib
target, so the Rust
compiler cannot run LTO. Interface crates only declare a lib
target, and
contain fewer dependencies. You can run LTO with cargo build-sbf --lto
.
NOTE: Results with --lto
are mixed, so be sure to profile your program's size
and CU usage with and without the flag.
curl https://sh.rustup.rs -sSf | sh
source $HOME/.cargo/env
rustup component add rustfmt
git clone https://github.com/anza-xyz/solana-sdk.git
cd solana-sdk
When building the master branch, please make sure you are using the version
specified in the repo's rust-toolchain.toml
by running:
rustup show
This command will download the toolchain if it is missing in the system.
cargo test
If your change to Agave also entails changes to the SDK, you will need to patch your Agave repo to use a local checkout of solana-sdk crates.
To patch all of the crates in this repo for Agave, just run:
./scripts/patch-crates-no-header.sh <AGAVE_PATH> <SOLANA_SDK_PATH>
To patch just one crate, specify its path:
./scripts/patch-crates-no-header.sh <AGAVE_PATH> <SOLANA_SDK_PATH> <RELATIVE_PATH>
For example, to patch solana-bn254
, run:
./scripts/patch-crates-no-header.sh ../agave . bn254
It's possible to run the script multiple times for different crates.
NOTE: The repo currently contains unpublished breaking changes, so please double-check before publishing any crates!
Unlike Agave, the solana-sdk crates are versioned independently, and published as needed.
If you need to publish a crate, you can use the "Publish Crate" GitHub Action.
Simply type in the path to the crate directory you want to release, ie.
program-entrypoint
, along with the kind of release, either patch
, minor
,
major
, or a specific version string.
The publish job will run checks, bump the crate version, commit and tag the bump, publish the crate to crates.io, and finally create GitHub Release with a simple changelog of all commits to the crate since the previous release.
If you would like to backport a pull request, simply add the appropriate label,
named backport <BRANCH_NAME>
.
For example, to create a backport to the maintenance/v2.x
branch, just add the
backport maintenance/v2.x
label.
Certain tests, such as rustfmt
and clippy
, require the nightly rustc
configured on the repository. To easily install it, use the ./cargo
helper
script in the root of the repository:
./cargo nightly tree
Run the test suite:
cargo test
Alternatively, there is a helper script:
./scripts/test-stable.sh
Format code for rustfmt check:
./cargo nightly fmt --all
The check can be run with a helper script:
./scripts/check-fmt.sh
To check the clippy lints:
./scripts/check-clippy.sh
Run the benchmarks:
./scripts/test-bench.sh
To generate code coverage statistics:
./scripts/test-coverage.sh
$ open target/cov/lcov-local/index.html
Code coverage requires llvm-tools-preview
for the configured nightly
toolchain. To install the component, run the command output by the script if it
fails to find the component:
rustup component add llvm-tools-preview --toolchain=<NIGHTLY_TOOLCHAIN>