Skip to content

Commit c01d2f5

Browse files
kevinheaveyjoncinque
authored andcommitted
turn BorshIoError variants into unit variants
make std optional in solana-program-error extract solana-pubkey-error crate add missing feature activation extract instruction-error crate remove unnecessary docs target from pubkey-error make num-traits optional in solana-program-error missing feature activation in solana-program move min_specialization to instruction-error missing feature activation in solana-instruction remove redundant DecodeError constraint from PrintProgramError remove unncecessary Error constraint from PrintProgramError remove num-traits dep and rename the num-traits feature to solana-msg add missing changes after removing num-traits make pubkey-error optional move instruction error codes to program-error and fix pubkey-error import fmt move PubkeyError back to solana-pubkey and move ProgramError conversion to solana-pubkey enable std if solana-msg is enabled add ToStr trait post-rebase fixes fmt toml
1 parent c7c8c60 commit c01d2f5

File tree

11 files changed

+187
-215
lines changed

11 files changed

+187
-215
lines changed

Cargo.lock

Lines changed: 14 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ members = [
3535
"hash",
3636
"inflation",
3737
"instruction",
38+
"instruction-error",
3839
"instructions-sysvar",
3940
"keccak-hasher",
4041
"keypair",
@@ -239,6 +240,7 @@ solana-hard-forks = { path = "hard-forks", version = "2.2.1", default-features =
239240
solana-hash = { path = "hash", version = "2.2.1", default-features = false }
240241
solana-inflation = { path = "inflation", version = "2.2.1" }
241242
solana-instruction = { path = "instruction", version = "2.3.0", default-features = false }
243+
solana-instruction-error = { path = "instruction-error", version = "1.0.0" }
242244
solana-instructions-sysvar = { path = "instructions-sysvar", version = "2.2.1" }
243245
solana-keccak-hasher = { path = "keccak-hasher", version = "2.2.1" }
244246
solana-keypair = { path = "keypair", version = "2.2.1" }

instruction-error/Cargo.toml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
[package]
2+
name = "solana-instruction-error"
3+
description = "Solana InstructionError type."
4+
documentation = "https://docs.rs/solana-instruction-error"
5+
version = "1.0.0"
6+
authors = { workspace = true }
7+
repository = { workspace = true }
8+
homepage = { workspace = true }
9+
license = { workspace = true }
10+
edition = { workspace = true }
11+
12+
[dependencies]
13+
num-traits = { workspace = true, optional = true }
14+
serde = { workspace = true, optional = true }
15+
serde_derive = { workspace = true, optional = true }
16+
solana-frozen-abi = { workspace = true, optional = true }
17+
solana-frozen-abi-macro = { workspace = true, optional = true }
18+
solana-program-error = { workspace = true }
19+
20+
[features]
21+
frozen-abi = [
22+
"dep:solana-frozen-abi",
23+
"dep:solana-frozen-abi-macro",
24+
"serde",
25+
"std"
26+
]
27+
num-traits = ["dep:num-traits"]
28+
serde = ["dep:serde", "dep:serde_derive"]
29+
std = []
30+
31+
[package.metadata.docs.rs]
32+
targets = ["x86_64-unknown-linux-gnu"]
33+
all-features = true
34+
rustdoc-args = ["--cfg=docsrs"]
35+
36+
[lints]
37+
workspace = true

instruction/src/error.rs renamed to instruction-error/src/lib.rs

Lines changed: 63 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,31 @@
1+
#![no_std]
2+
#![cfg_attr(feature = "frozen-abi", feature(min_specialization))]
13
use core::fmt;
4+
#[cfg(feature = "num-traits")]
5+
use num_traits::ToPrimitive;
26
#[cfg(feature = "frozen-abi")]
37
use solana_frozen_abi_macro::{AbiEnumVisitor, AbiExample};
48
#[cfg(feature = "std")]
5-
use {
6-
num_traits::ToPrimitive,
7-
std::string::{String, ToString},
9+
extern crate std;
10+
use solana_program_error::ProgramError;
11+
pub use solana_program_error::{
12+
ACCOUNT_ALREADY_INITIALIZED, ACCOUNT_BORROW_FAILED, ACCOUNT_DATA_TOO_SMALL,
13+
ACCOUNT_NOT_RENT_EXEMPT, ARITHMETIC_OVERFLOW, BORSH_IO_ERROR,
14+
BUILTIN_PROGRAMS_MUST_CONSUME_COMPUTE_UNITS, CUSTOM_ZERO, ILLEGAL_OWNER, IMMUTABLE,
15+
INCORRECT_AUTHORITY, INCORRECT_PROGRAM_ID, INSUFFICIENT_FUNDS, INVALID_ACCOUNT_DATA,
16+
INVALID_ACCOUNT_DATA_REALLOC, INVALID_ACCOUNT_OWNER, INVALID_ARGUMENT,
17+
INVALID_INSTRUCTION_DATA, INVALID_SEEDS, MAX_ACCOUNTS_DATA_ALLOCATIONS_EXCEEDED,
18+
MAX_INSTRUCTION_TRACE_LENGTH_EXCEEDED, MAX_SEED_LENGTH_EXCEEDED, MISSING_REQUIRED_SIGNATURES,
19+
NOT_ENOUGH_ACCOUNT_KEYS, UNINITIALIZED_ACCOUNT, UNSUPPORTED_SYSVAR,
820
};
921

10-
/// Builtin return values occupy the upper 32 bits
11-
const BUILTIN_BIT_SHIFT: usize = 32;
12-
macro_rules! to_builtin {
13-
($error:expr) => {
14-
($error as u64) << BUILTIN_BIT_SHIFT
15-
};
16-
}
17-
18-
pub const CUSTOM_ZERO: u64 = to_builtin!(1);
19-
pub const INVALID_ARGUMENT: u64 = to_builtin!(2);
20-
pub const INVALID_INSTRUCTION_DATA: u64 = to_builtin!(3);
21-
pub const INVALID_ACCOUNT_DATA: u64 = to_builtin!(4);
22-
pub const ACCOUNT_DATA_TOO_SMALL: u64 = to_builtin!(5);
23-
pub const INSUFFICIENT_FUNDS: u64 = to_builtin!(6);
24-
pub const INCORRECT_PROGRAM_ID: u64 = to_builtin!(7);
25-
pub const MISSING_REQUIRED_SIGNATURES: u64 = to_builtin!(8);
26-
pub const ACCOUNT_ALREADY_INITIALIZED: u64 = to_builtin!(9);
27-
pub const UNINITIALIZED_ACCOUNT: u64 = to_builtin!(10);
28-
pub const NOT_ENOUGH_ACCOUNT_KEYS: u64 = to_builtin!(11);
29-
pub const ACCOUNT_BORROW_FAILED: u64 = to_builtin!(12);
30-
pub const MAX_SEED_LENGTH_EXCEEDED: u64 = to_builtin!(13);
31-
pub const INVALID_SEEDS: u64 = to_builtin!(14);
32-
pub const BORSH_IO_ERROR: u64 = to_builtin!(15);
33-
pub const ACCOUNT_NOT_RENT_EXEMPT: u64 = to_builtin!(16);
34-
pub const UNSUPPORTED_SYSVAR: u64 = to_builtin!(17);
35-
pub const ILLEGAL_OWNER: u64 = to_builtin!(18);
36-
pub const MAX_ACCOUNTS_DATA_ALLOCATIONS_EXCEEDED: u64 = to_builtin!(19);
37-
pub const INVALID_ACCOUNT_DATA_REALLOC: u64 = to_builtin!(20);
38-
pub const MAX_INSTRUCTION_TRACE_LENGTH_EXCEEDED: u64 = to_builtin!(21);
39-
pub const BUILTIN_PROGRAMS_MUST_CONSUME_COMPUTE_UNITS: u64 = to_builtin!(22);
40-
pub const INVALID_ACCOUNT_OWNER: u64 = to_builtin!(23);
41-
pub const ARITHMETIC_OVERFLOW: u64 = to_builtin!(24);
42-
pub const IMMUTABLE: u64 = to_builtin!(25);
43-
pub const INCORRECT_AUTHORITY: u64 = to_builtin!(26);
44-
// Warning: Any new error codes added here must also be:
45-
// - Added to the below conversions
46-
// - Added as an equivalent to ProgramError and InstructionError
47-
// - Be featurized in the BPF loader to return `InstructionError::InvalidError`
48-
// until the feature is activated
49-
5022
/// Reasons the runtime might have rejected an instruction.
5123
///
5224
/// Members of this enum must not be removed, but new ones can be added.
5325
/// Also, it is crucial that meta-information if any that comes along with
5426
/// an error be consistent across software versions. For example, it is
5527
/// dangerous to include error strings from 3rd party crates because they could
5628
/// change at any time and changes to them are difficult to detect.
57-
#[cfg(feature = "std")]
5829
#[cfg_attr(feature = "frozen-abi", derive(AbiExample, AbiEnumVisitor))]
5930
#[cfg_attr(
6031
feature = "serde",
@@ -202,15 +173,7 @@ pub enum InstructionError {
202173
IncorrectAuthority,
203174

204175
/// Failed to serialize or deserialize account data
205-
///
206-
/// Warning: This error should never be emitted by the runtime.
207-
///
208-
/// This error includes strings from the underlying 3rd party Borsh crate
209-
/// which can be dangerous because the error strings could change across
210-
/// Borsh versions. Only programs can use this error because they are
211-
/// consistent across Solana software versions.
212-
///
213-
BorshIoError(String),
176+
BorshIoError,
214177

215178
/// An account does not have enough lamports to be rent-exempt
216179
AccountNotRentExempt,
@@ -245,7 +208,6 @@ pub enum InstructionError {
245208
#[cfg(feature = "std")]
246209
impl std::error::Error for InstructionError {}
247210

248-
#[cfg(feature = "std")]
249211
impl fmt::Display for InstructionError {
250212
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
251213
match self {
@@ -361,8 +323,8 @@ impl fmt::Display for InstructionError {
361323
InstructionError::ProgramFailedToCompile => f.write_str("Program failed to compile"),
362324
InstructionError::Immutable => f.write_str("Account is immutable"),
363325
InstructionError::IncorrectAuthority => f.write_str("Incorrect authority provided"),
364-
InstructionError::BorshIoError(s) => {
365-
write!(f, "Failed to serialize or deserialize account data: {s}",)
326+
InstructionError::BorshIoError => {
327+
f.write_str("Failed to serialize or deserialize account data")
366328
}
367329
InstructionError::AccountNotRentExempt => {
368330
f.write_str("An account does not have enough lamports to be rent-exempt")
@@ -385,7 +347,7 @@ impl fmt::Display for InstructionError {
385347
}
386348
}
387349

388-
#[cfg(feature = "std")]
350+
#[cfg(feature = "num-traits")]
389351
impl<T> From<T> for InstructionError
390352
where
391353
T: ToPrimitive,
@@ -407,7 +369,7 @@ where
407369
ACCOUNT_BORROW_FAILED => Self::AccountBorrowFailed,
408370
MAX_SEED_LENGTH_EXCEEDED => Self::MaxSeedLengthExceeded,
409371
INVALID_SEEDS => Self::InvalidSeeds,
410-
BORSH_IO_ERROR => Self::BorshIoError("Unknown".to_string()),
372+
BORSH_IO_ERROR => Self::BorshIoError,
411373
ACCOUNT_NOT_RENT_EXEMPT => Self::AccountNotRentExempt,
412374
UNSUPPORTED_SYSVAR => Self::UnsupportedSysvar,
413375
ILLEGAL_OWNER => Self::IllegalOwner,
@@ -423,7 +385,7 @@ where
423385
INCORRECT_AUTHORITY => Self::IncorrectAuthority,
424386
_ => {
425387
// A valid custom error has no bits set in the upper 32
426-
if error >> BUILTIN_BIT_SHIFT == 0 {
388+
if error >> solana_program_error::BUILTIN_BIT_SHIFT == 0 {
427389
Self::Custom(error as u32)
428390
} else {
429391
Self::InvalidError
@@ -453,7 +415,6 @@ impl fmt::Display for LamportsError {
453415
}
454416
}
455417

456-
#[cfg(feature = "std")]
457418
impl From<LamportsError> for InstructionError {
458419
fn from(error: LamportsError) -> Self {
459420
match error {
@@ -462,3 +423,45 @@ impl From<LamportsError> for InstructionError {
462423
}
463424
}
464425
}
426+
427+
impl TryFrom<InstructionError> for ProgramError {
428+
type Error = InstructionError;
429+
430+
fn try_from(error: InstructionError) -> Result<Self, Self::Error> {
431+
match error {
432+
Self::Error::Custom(err) => Ok(Self::Custom(err)),
433+
Self::Error::InvalidArgument => Ok(Self::InvalidArgument),
434+
Self::Error::InvalidInstructionData => Ok(Self::InvalidInstructionData),
435+
Self::Error::InvalidAccountData => Ok(Self::InvalidAccountData),
436+
Self::Error::AccountDataTooSmall => Ok(Self::AccountDataTooSmall),
437+
Self::Error::InsufficientFunds => Ok(Self::InsufficientFunds),
438+
Self::Error::IncorrectProgramId => Ok(Self::IncorrectProgramId),
439+
Self::Error::MissingRequiredSignature => Ok(Self::MissingRequiredSignature),
440+
Self::Error::AccountAlreadyInitialized => Ok(Self::AccountAlreadyInitialized),
441+
Self::Error::UninitializedAccount => Ok(Self::UninitializedAccount),
442+
Self::Error::NotEnoughAccountKeys => Ok(Self::NotEnoughAccountKeys),
443+
Self::Error::AccountBorrowFailed => Ok(Self::AccountBorrowFailed),
444+
Self::Error::MaxSeedLengthExceeded => Ok(Self::MaxSeedLengthExceeded),
445+
Self::Error::InvalidSeeds => Ok(Self::InvalidSeeds),
446+
Self::Error::BorshIoError => Ok(Self::BorshIoError),
447+
Self::Error::AccountNotRentExempt => Ok(Self::AccountNotRentExempt),
448+
Self::Error::UnsupportedSysvar => Ok(Self::UnsupportedSysvar),
449+
Self::Error::IllegalOwner => Ok(Self::IllegalOwner),
450+
Self::Error::MaxAccountsDataAllocationsExceeded => {
451+
Ok(Self::MaxAccountsDataAllocationsExceeded)
452+
}
453+
Self::Error::InvalidRealloc => Ok(Self::InvalidRealloc),
454+
Self::Error::MaxInstructionTraceLengthExceeded => {
455+
Ok(Self::MaxInstructionTraceLengthExceeded)
456+
}
457+
Self::Error::BuiltinProgramsMustConsumeComputeUnits => {
458+
Ok(Self::BuiltinProgramsMustConsumeComputeUnits)
459+
}
460+
Self::Error::InvalidAccountOwner => Ok(Self::InvalidAccountOwner),
461+
Self::Error::ArithmeticOverflow => Ok(Self::ArithmeticOverflow),
462+
Self::Error::Immutable => Ok(Self::Immutable),
463+
Self::Error::IncorrectAuthority => Ok(Self::IncorrectAuthority),
464+
_ => Err(error),
465+
}
466+
}
467+
}

instruction/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ frozen-abi = [
2424
"serde",
2525
"std",
2626
]
27-
serde = ["dep:serde", "dep:serde_derive", "solana-pubkey/serde"]
28-
std = []
27+
serde = ["dep:serde", "dep:serde_derive", "solana-instruction-error/serde", "solana-pubkey/serde"]
28+
std = ["solana-instruction-error/std"]
2929
syscalls = ["std"]
3030

3131
[dependencies]
@@ -36,6 +36,7 @@ serde = { workspace = true, optional = true }
3636
serde_derive = { workspace = true, optional = true }
3737
solana-frozen-abi = { workspace = true, optional = true }
3838
solana-frozen-abi-macro = { workspace = true, optional = true }
39+
solana-instruction-error = { workspace = true, features = ["num-traits"] }
3940
solana-pubkey = { workspace = true, default-features = false }
4041

4142
[target.'cfg(target_arch = "wasm32")'.dependencies]

instruction/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
//! [`AccountMeta`] values. The runtime uses this information to efficiently
1212
//! schedule execution of transactions.
1313
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
14-
#![cfg_attr(feature = "frozen-abi", feature(min_specialization))]
1514
#![allow(clippy::arithmetic_side_effects)]
1615
#![no_std]
1716

@@ -23,7 +22,7 @@ use std::vec::Vec;
2322
pub mod account_meta;
2423
#[cfg(feature = "std")]
2524
pub use account_meta::AccountMeta;
26-
pub mod error;
25+
pub use solana_instruction_error as error;
2726
#[cfg(any(feature = "syscalls", target_os = "solana"))]
2827
pub mod syscalls;
2928
#[cfg(all(feature = "std", target_arch = "wasm32"))]

program-error/Cargo.toml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,12 @@ rustdoc-args = ["--cfg=docsrs"]
1717
[features]
1818
borsh = ["dep:borsh"]
1919
serde = ["dep:serde", "dep:serde_derive"]
20+
std = []
2021

2122
[dependencies]
2223
borsh = { workspace = true, optional = true }
23-
num-traits = { workspace = true }
2424
serde = { workspace = true, optional = true }
2525
serde_derive = { workspace = true, optional = true }
26-
solana-instruction = { workspace = true, default-features = false, features = [
27-
"std",
28-
] }
29-
solana-msg = { workspace = true }
30-
solana-pubkey = { workspace = true, default-features = false }
3126

3227
[dev-dependencies]
3328
num_enum = { workspace = true }

0 commit comments

Comments
 (0)