1+ #![ no_std]
2+ #![ cfg_attr( feature = "frozen-abi" , feature( min_specialization) ) ]
13use core:: fmt;
4+ #[ cfg( feature = "num-traits" ) ]
5+ use num_traits:: ToPrimitive ;
26#[ cfg( feature = "frozen-abi" ) ]
37use 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" ) ]
246209impl std:: error:: Error for InstructionError { }
247210
248- #[ cfg( feature = "std" ) ]
249211impl 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 " ) ]
389351impl < T > From < T > for InstructionError
390352where
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" ) ]
457418impl 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+ }
0 commit comments