1#[derive(Clone, Debug, Eq, PartialEq)]
11pub enum ProgramError {
12 Custom(u32),
14 InvalidArgument,
15 InvalidInstructionData,
16 InvalidAccountData,
17 AccountDataTooSmall,
18 InsufficientFunds,
19 IncorrectProgramId,
20 MissingRequiredSignature,
21 AccountAlreadyInitialized,
22 UninitializedAccount,
23 NotEnoughAccountKeys,
24 AccountBorrowFailed,
25 MaxSeedLengthExceeded,
26 InvalidSeeds,
27 BorshIoError,
28 AccountNotRentExempt,
29 UnsupportedSysvar,
30 IllegalOwner,
31 MaxAccountsDataAllocationsExceeded,
32 InvalidRealloc,
33 MaxInstructionTraceLengthExceeded,
34 BuiltinProgramsMustConsumeComputeUnits,
35 InvalidAccountOwner,
36 ArithmeticOverflow,
37 Immutable,
38 IncorrectAuthority,
39}
40
41const BUILTIN_BIT_SHIFT: usize = 32;
45const CUSTOM_ZERO: u64 = 1_u64 << BUILTIN_BIT_SHIFT;
46
47#[inline(always)]
51const fn to_builtin(index: u64) -> u64 {
52 (index + 2) << BUILTIN_BIT_SHIFT
53}
54
55impl From<ProgramError> for u64 {
56 fn from(err: ProgramError) -> u64 {
57 match err {
58 ProgramError::Custom(0) => CUSTOM_ZERO,
59 ProgramError::Custom(code) => code as u64,
60 ProgramError::InvalidArgument => to_builtin(0),
61 ProgramError::InvalidInstructionData => to_builtin(1),
62 ProgramError::InvalidAccountData => to_builtin(2),
63 ProgramError::AccountDataTooSmall => to_builtin(3),
64 ProgramError::InsufficientFunds => to_builtin(4),
65 ProgramError::IncorrectProgramId => to_builtin(5),
66 ProgramError::MissingRequiredSignature => to_builtin(6),
67 ProgramError::AccountAlreadyInitialized => to_builtin(7),
68 ProgramError::UninitializedAccount => to_builtin(8),
69 ProgramError::NotEnoughAccountKeys => to_builtin(9),
70 ProgramError::AccountBorrowFailed => to_builtin(10),
71 ProgramError::MaxSeedLengthExceeded => to_builtin(11),
72 ProgramError::InvalidSeeds => to_builtin(12),
73 ProgramError::BorshIoError => to_builtin(13),
74 ProgramError::AccountNotRentExempt => to_builtin(14),
75 ProgramError::UnsupportedSysvar => to_builtin(15),
76 ProgramError::IllegalOwner => to_builtin(16),
77 ProgramError::MaxAccountsDataAllocationsExceeded => to_builtin(17),
78 ProgramError::InvalidRealloc => to_builtin(18),
79 ProgramError::MaxInstructionTraceLengthExceeded => to_builtin(19),
80 ProgramError::BuiltinProgramsMustConsumeComputeUnits => to_builtin(20),
81 ProgramError::InvalidAccountOwner => to_builtin(21),
82 ProgramError::ArithmeticOverflow => to_builtin(22),
83 ProgramError::Immutable => to_builtin(23),
84 ProgramError::IncorrectAuthority => to_builtin(24),
85 }
86 }
87}
88
89impl From<u64> for ProgramError {
90 fn from(code: u64) -> Self {
91 match code {
92 CUSTOM_ZERO => ProgramError::Custom(0),
93 c if c == to_builtin(0) => ProgramError::InvalidArgument,
94 c if c == to_builtin(1) => ProgramError::InvalidInstructionData,
95 c if c == to_builtin(2) => ProgramError::InvalidAccountData,
96 c if c == to_builtin(3) => ProgramError::AccountDataTooSmall,
97 c if c == to_builtin(4) => ProgramError::InsufficientFunds,
98 c if c == to_builtin(5) => ProgramError::IncorrectProgramId,
99 c if c == to_builtin(6) => ProgramError::MissingRequiredSignature,
100 c if c == to_builtin(7) => ProgramError::AccountAlreadyInitialized,
101 c if c == to_builtin(8) => ProgramError::UninitializedAccount,
102 c if c == to_builtin(9) => ProgramError::NotEnoughAccountKeys,
103 c if c == to_builtin(10) => ProgramError::AccountBorrowFailed,
104 c if c == to_builtin(11) => ProgramError::MaxSeedLengthExceeded,
105 c if c == to_builtin(12) => ProgramError::InvalidSeeds,
106 c if c == to_builtin(13) => ProgramError::BorshIoError,
107 c if c == to_builtin(14) => ProgramError::AccountNotRentExempt,
108 c if c == to_builtin(15) => ProgramError::UnsupportedSysvar,
109 c if c == to_builtin(16) => ProgramError::IllegalOwner,
110 c if c == to_builtin(17) => ProgramError::MaxAccountsDataAllocationsExceeded,
111 c if c == to_builtin(18) => ProgramError::InvalidRealloc,
112 c if c == to_builtin(19) => ProgramError::MaxInstructionTraceLengthExceeded,
113 c if c == to_builtin(20) => ProgramError::BuiltinProgramsMustConsumeComputeUnits,
114 c if c == to_builtin(21) => ProgramError::InvalidAccountOwner,
115 c if c == to_builtin(22) => ProgramError::ArithmeticOverflow,
116 c if c == to_builtin(23) => ProgramError::Immutable,
117 c if c == to_builtin(24) => ProgramError::IncorrectAuthority,
118 other => ProgramError::Custom(other as u32),
119 }
120 }
121}
122
123impl core::fmt::Display for ProgramError {
124 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
125 match self {
126 ProgramError::Custom(code) => write!(f, "Custom({code})"),
127 ProgramError::InvalidArgument => write!(f, "InvalidArgument"),
128 ProgramError::InvalidInstructionData => write!(f, "InvalidInstructionData"),
129 ProgramError::InvalidAccountData => write!(f, "InvalidAccountData"),
130 ProgramError::AccountDataTooSmall => write!(f, "AccountDataTooSmall"),
131 ProgramError::InsufficientFunds => write!(f, "InsufficientFunds"),
132 ProgramError::IncorrectProgramId => write!(f, "IncorrectProgramId"),
133 ProgramError::MissingRequiredSignature => write!(f, "MissingRequiredSignature"),
134 ProgramError::AccountAlreadyInitialized => write!(f, "AccountAlreadyInitialized"),
135 ProgramError::UninitializedAccount => write!(f, "UninitializedAccount"),
136 ProgramError::NotEnoughAccountKeys => write!(f, "NotEnoughAccountKeys"),
137 ProgramError::AccountBorrowFailed => write!(f, "AccountBorrowFailed"),
138 ProgramError::MaxSeedLengthExceeded => write!(f, "MaxSeedLengthExceeded"),
139 ProgramError::InvalidSeeds => write!(f, "InvalidSeeds"),
140 ProgramError::BorshIoError => write!(f, "BorshIoError"),
141 ProgramError::AccountNotRentExempt => write!(f, "AccountNotRentExempt"),
142 ProgramError::UnsupportedSysvar => write!(f, "UnsupportedSysvar"),
143 ProgramError::IllegalOwner => write!(f, "IllegalOwner"),
144 ProgramError::MaxAccountsDataAllocationsExceeded => write!(f, "MaxAccountsDataAllocationsExceeded"),
145 ProgramError::InvalidRealloc => write!(f, "InvalidRealloc"),
146 ProgramError::MaxInstructionTraceLengthExceeded => write!(f, "MaxInstructionTraceLengthExceeded"),
147 ProgramError::BuiltinProgramsMustConsumeComputeUnits => write!(f, "BuiltinProgramsMustConsumeComputeUnits"),
148 ProgramError::InvalidAccountOwner => write!(f, "InvalidAccountOwner"),
149 ProgramError::ArithmeticOverflow => write!(f, "ArithmeticOverflow"),
150 ProgramError::Immutable => write!(f, "Immutable"),
151 ProgramError::IncorrectAuthority => write!(f, "IncorrectAuthority"),
152 }
153 }
154}
155
156#[cfg(feature = "hopper-native-backend")]
164impl From<hopper_native::error::ProgramError> for ProgramError {
165 #[inline]
166 fn from(e: hopper_native::error::ProgramError) -> Self {
167 ProgramError::from(u64::from(e))
168 }
169}
170
171#[cfg(feature = "hopper-native-backend")]
172impl From<ProgramError> for hopper_native::error::ProgramError {
173 #[inline]
174 fn from(e: ProgramError) -> Self {
175 hopper_native::error::ProgramError::from(u64::from(e))
176 }
177}
178
179impl ProgramError {
188 #[cold]
189 #[inline(never)]
190 pub fn err_data_too_small<T>() -> Result<T, Self> {
191 Err(ProgramError::AccountDataTooSmall)
192 }
193
194 #[cold]
195 #[inline(never)]
196 pub fn err_invalid_data<T>() -> Result<T, Self> {
197 Err(ProgramError::InvalidAccountData)
198 }
199
200 #[cold]
201 #[inline(never)]
202 pub fn err_missing_signer<T>() -> Result<T, Self> {
203 Err(ProgramError::MissingRequiredSignature)
204 }
205
206 #[cold]
207 #[inline(never)]
208 pub fn err_immutable<T>() -> Result<T, Self> {
209 Err(ProgramError::Immutable)
210 }
211
212 #[cold]
213 #[inline(never)]
214 pub fn err_not_enough_keys<T>() -> Result<T, Self> {
215 Err(ProgramError::NotEnoughAccountKeys)
216 }
217
218 #[cold]
219 #[inline(never)]
220 pub fn err_borrow_failed<T>() -> Result<T, Self> {
221 Err(ProgramError::AccountBorrowFailed)
222 }
223
224 #[cold]
225 #[inline(never)]
226 pub fn err_overflow<T>() -> Result<T, Self> {
227 Err(ProgramError::ArithmeticOverflow)
228 }
229
230 #[cold]
231 #[inline(never)]
232 pub fn err_invalid_argument<T>() -> Result<T, Self> {
233 Err(ProgramError::InvalidArgument)
234 }
235
236 #[cold]
237 #[inline(never)]
238 pub fn err_incorrect_program<T>() -> Result<T, Self> {
239 Err(ProgramError::IncorrectProgramId)
240 }
241}
242