1#[derive(Clone, Debug, Eq, PartialEq)]
8pub enum ProgramError {
9 Custom(u32),
11 InvalidArgument,
12 InvalidInstructionData,
13 InvalidAccountData,
14 AccountDataTooSmall,
15 InsufficientFunds,
16 IncorrectProgramId,
17 MissingRequiredSignature,
18 AccountAlreadyInitialized,
19 UninitializedAccount,
20 NotEnoughAccountKeys,
21 AccountBorrowFailed,
22 MaxSeedLengthExceeded,
23 InvalidSeeds,
24 BorshIoError,
25 AccountNotRentExempt,
26 UnsupportedSysvar,
27 IllegalOwner,
28 MaxAccountsDataAllocationsExceeded,
29 InvalidRealloc,
30 MaxInstructionTraceLengthExceeded,
31 BuiltinProgramsMustConsumeComputeUnits,
32 InvalidAccountOwner,
33 ArithmeticOverflow,
34 Immutable,
35 IncorrectAuthority,
36}
37
38impl From<ProgramError> for u64 {
41 fn from(err: ProgramError) -> u64 {
42 match err {
43 ProgramError::Custom(0) => CUSTOM_ZERO,
44 ProgramError::Custom(code) => code as u64,
45 ProgramError::InvalidArgument => to_builtin(0),
46 ProgramError::InvalidInstructionData => to_builtin(1),
47 ProgramError::InvalidAccountData => to_builtin(2),
48 ProgramError::AccountDataTooSmall => to_builtin(3),
49 ProgramError::InsufficientFunds => to_builtin(4),
50 ProgramError::IncorrectProgramId => to_builtin(5),
51 ProgramError::MissingRequiredSignature => to_builtin(6),
52 ProgramError::AccountAlreadyInitialized => to_builtin(7),
53 ProgramError::UninitializedAccount => to_builtin(8),
54 ProgramError::NotEnoughAccountKeys => to_builtin(9),
55 ProgramError::AccountBorrowFailed => to_builtin(10),
56 ProgramError::MaxSeedLengthExceeded => to_builtin(11),
57 ProgramError::InvalidSeeds => to_builtin(12),
58 ProgramError::BorshIoError => to_builtin(13),
59 ProgramError::AccountNotRentExempt => to_builtin(14),
60 ProgramError::UnsupportedSysvar => to_builtin(15),
61 ProgramError::IllegalOwner => to_builtin(16),
62 ProgramError::MaxAccountsDataAllocationsExceeded => to_builtin(17),
63 ProgramError::InvalidRealloc => to_builtin(18),
64 ProgramError::MaxInstructionTraceLengthExceeded => to_builtin(19),
65 ProgramError::BuiltinProgramsMustConsumeComputeUnits => to_builtin(20),
66 ProgramError::InvalidAccountOwner => to_builtin(21),
67 ProgramError::ArithmeticOverflow => to_builtin(22),
68 ProgramError::Immutable => to_builtin(23),
69 ProgramError::IncorrectAuthority => to_builtin(24),
70 }
71 }
72}
73
74impl From<u64> for ProgramError {
75 fn from(code: u64) -> Self {
76 if code == CUSTOM_ZERO {
77 return ProgramError::Custom(0);
78 }
79 let builtin = code >> BUILTIN_BIT_SHIFT;
80 if code & BUILTIN_LOW_MASK == 0 && builtin >= 2 {
81 match builtin - 2 {
82 0 => return ProgramError::InvalidArgument,
83 1 => return ProgramError::InvalidInstructionData,
84 2 => return ProgramError::InvalidAccountData,
85 3 => return ProgramError::AccountDataTooSmall,
86 4 => return ProgramError::InsufficientFunds,
87 5 => return ProgramError::IncorrectProgramId,
88 6 => return ProgramError::MissingRequiredSignature,
89 7 => return ProgramError::AccountAlreadyInitialized,
90 8 => return ProgramError::UninitializedAccount,
91 9 => return ProgramError::NotEnoughAccountKeys,
92 10 => return ProgramError::AccountBorrowFailed,
93 11 => return ProgramError::MaxSeedLengthExceeded,
94 12 => return ProgramError::InvalidSeeds,
95 13 => return ProgramError::BorshIoError,
96 14 => return ProgramError::AccountNotRentExempt,
97 15 => return ProgramError::UnsupportedSysvar,
98 16 => return ProgramError::IllegalOwner,
99 17 => return ProgramError::MaxAccountsDataAllocationsExceeded,
100 18 => return ProgramError::InvalidRealloc,
101 19 => return ProgramError::MaxInstructionTraceLengthExceeded,
102 20 => return ProgramError::BuiltinProgramsMustConsumeComputeUnits,
103 21 => return ProgramError::InvalidAccountOwner,
104 22 => return ProgramError::ArithmeticOverflow,
105 23 => return ProgramError::Immutable,
106 24 => return ProgramError::IncorrectAuthority,
107 _ => {}
108 }
109 }
110 ProgramError::Custom(code as u32)
111 }
112}
113
114const BUILTIN_BIT_SHIFT: usize = 32;
120const CUSTOM_ZERO: u64 = 1_u64 << BUILTIN_BIT_SHIFT;
121const BUILTIN_LOW_MASK: u64 = (1_u64 << BUILTIN_BIT_SHIFT) - 1;
122
123#[inline(always)]
124const fn to_builtin(index: u64) -> u64 {
125 (index + 2) << BUILTIN_BIT_SHIFT
126}
127
128impl core::fmt::Display for ProgramError {
129 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
130 match self {
131 ProgramError::Custom(code) => write!(f, "Custom({code})"),
132 ProgramError::InvalidArgument => write!(f, "InvalidArgument"),
133 ProgramError::InvalidInstructionData => write!(f, "InvalidInstructionData"),
134 ProgramError::InvalidAccountData => write!(f, "InvalidAccountData"),
135 ProgramError::AccountDataTooSmall => write!(f, "AccountDataTooSmall"),
136 ProgramError::InsufficientFunds => write!(f, "InsufficientFunds"),
137 ProgramError::IncorrectProgramId => write!(f, "IncorrectProgramId"),
138 ProgramError::MissingRequiredSignature => write!(f, "MissingRequiredSignature"),
139 ProgramError::AccountAlreadyInitialized => write!(f, "AccountAlreadyInitialized"),
140 ProgramError::UninitializedAccount => write!(f, "UninitializedAccount"),
141 ProgramError::NotEnoughAccountKeys => write!(f, "NotEnoughAccountKeys"),
142 ProgramError::AccountBorrowFailed => write!(f, "AccountBorrowFailed"),
143 ProgramError::MaxSeedLengthExceeded => write!(f, "MaxSeedLengthExceeded"),
144 ProgramError::InvalidSeeds => write!(f, "InvalidSeeds"),
145 ProgramError::BorshIoError => write!(f, "BorshIoError"),
146 ProgramError::AccountNotRentExempt => write!(f, "AccountNotRentExempt"),
147 ProgramError::UnsupportedSysvar => write!(f, "UnsupportedSysvar"),
148 ProgramError::IllegalOwner => write!(f, "IllegalOwner"),
149 ProgramError::MaxAccountsDataAllocationsExceeded => {
150 write!(f, "MaxAccountsDataAllocationsExceeded")
151 }
152 ProgramError::InvalidRealloc => write!(f, "InvalidRealloc"),
153 ProgramError::MaxInstructionTraceLengthExceeded => {
154 write!(f, "MaxInstructionTraceLengthExceeded")
155 }
156 ProgramError::BuiltinProgramsMustConsumeComputeUnits => {
157 write!(f, "BuiltinProgramsMustConsumeComputeUnits")
158 }
159 ProgramError::InvalidAccountOwner => write!(f, "InvalidAccountOwner"),
160 ProgramError::ArithmeticOverflow => write!(f, "ArithmeticOverflow"),
161 ProgramError::Immutable => write!(f, "Immutable"),
162 ProgramError::IncorrectAuthority => write!(f, "IncorrectAuthority"),
163 }
164 }
165}