Skip to content

Commit 2559f84

Browse files
committed
Fix error codes
1 parent 8aef2d2 commit 2559f84

36 files changed

+147
-104
lines changed

interface/src/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ impl TryFrom<u32> for TokenError {
124124
17 => Ok(TokenError::AccountFrozen),
125125
18 => Ok(TokenError::MintDecimalsMismatch),
126126
19 => Ok(TokenError::NonNativeNotSupported),
127-
_ => Err(ProgramError::InvalidArgument),
127+
_ => Err(TokenError::InvalidInstruction.into()),
128128
}
129129
}
130130
}

interface/src/instruction.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
33
use pinocchio::program_error::ProgramError;
44

5+
use crate::error::TokenError;
6+
57
/// Instructions supported by the token program.
68
#[repr(u8)]
79
#[derive(Clone, Debug, PartialEq)]
@@ -531,7 +533,7 @@ impl TryFrom<u8> for TokenInstruction {
531533
match value {
532534
// SAFETY: `value` is guaranteed to be in the range of the enum variants.
533535
0..=24 | 38 | 255 => Ok(unsafe { core::mem::transmute::<u8, TokenInstruction>(value) }),
534-
_ => Err(ProgramError::InvalidInstructionData),
536+
_ => Err(TokenError::InvalidInstruction.into()),
535537
}
536538
}
537539
}
@@ -559,7 +561,7 @@ impl TryFrom<u8> for AuthorityType {
559561
match value {
560562
// SAFETY: `value` is guaranteed to be in the range of the enum variants.
561563
0..=3 => Ok(unsafe { core::mem::transmute::<u8, AuthorityType>(value) }),
562-
_ => Err(ProgramError::InvalidInstructionData),
564+
_ => Err(TokenError::InvalidInstruction.into()),
563565
}
564566
}
565567
}

interface/src/state/account.rs

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use {
22
super::{account_state::AccountState, COption, Initializable, Transmutable},
3-
pinocchio::pubkey::Pubkey,
3+
pinocchio::{program_error::ProgramError, pubkey::Pubkey},
44
};
55

66
/// Incinerator address.
@@ -27,7 +27,7 @@ pub struct Account {
2727
delegate: COption<Pubkey>,
2828

2929
/// The account's state.
30-
pub state: AccountState,
30+
state: u8,
3131

3232
/// Indicates whether this account represents a native token or not.
3333
is_native: [u8; 4],
@@ -46,6 +46,16 @@ pub struct Account {
4646
}
4747

4848
impl Account {
49+
#[inline(always)]
50+
pub fn set_account_state(&mut self, state: AccountState) {
51+
self.state = state as u8;
52+
}
53+
54+
#[inline(always)]
55+
pub fn account_state(&self) -> Result<AccountState, ProgramError> {
56+
AccountState::try_from(self.state)
57+
}
58+
4959
#[inline(always)]
5060
pub fn set_amount(&mut self, amount: u64) {
5161
self.amount = amount.to_le_bytes();
@@ -68,11 +78,11 @@ impl Account {
6878
}
6979

7080
#[inline(always)]
71-
pub fn delegate(&self) -> Option<&Pubkey> {
72-
if self.delegate.0[0] == 1 {
73-
Some(&self.delegate.1)
74-
} else {
75-
None
81+
pub fn delegate(&self) -> Result<Option<&Pubkey>, ProgramError> {
82+
match self.delegate.0 {
83+
[0, 0, 0, 0] => Ok(None),
84+
[1, 0, 0, 0] => Ok(Some(&self.delegate.1)),
85+
_ => Err(ProgramError::InvalidAccountData),
7686
}
7787
}
7888

@@ -122,17 +132,17 @@ impl Account {
122132
}
123133

124134
#[inline(always)]
125-
pub fn close_authority(&self) -> Option<&Pubkey> {
126-
if self.close_authority.0[0] == 1 {
127-
Some(&self.close_authority.1)
128-
} else {
129-
None
135+
pub fn close_authority(&self) -> Result<Option<&Pubkey>, ProgramError> {
136+
match self.close_authority.0 {
137+
[0, 0, 0, 0] => Ok(None),
138+
[1, 0, 0, 0] => Ok(Some(&self.close_authority.1)),
139+
_ => Err(ProgramError::InvalidAccountData),
130140
}
131141
}
132142

133143
#[inline(always)]
134-
pub fn is_frozen(&self) -> bool {
135-
self.state == AccountState::Frozen
144+
pub fn is_frozen(&self) -> Result<bool, ProgramError> {
145+
Ok(AccountState::try_from(self.state)? == AccountState::Frozen)
136146
}
137147

138148
#[inline(always)]
@@ -147,7 +157,7 @@ impl Transmutable for Account {
147157

148158
impl Initializable for Account {
149159
#[inline(always)]
150-
fn is_initialized(&self) -> bool {
151-
self.state != AccountState::Uninitialized
160+
fn is_initialized(&self) -> Result<bool, ProgramError> {
161+
Ok(AccountState::try_from(self.state)? != AccountState::Uninitialized)
152162
}
153163
}

interface/src/state/account_state.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use pinocchio::program_error::ProgramError;
2+
13
#[repr(u8)]
24
#[derive(Clone, Copy, Debug, PartialEq)]
35
pub enum AccountState {
@@ -13,3 +15,16 @@ pub enum AccountState {
1315
/// this account.
1416
Frozen,
1517
}
18+
19+
impl TryFrom<u8> for AccountState {
20+
type Error = ProgramError;
21+
22+
#[inline(always)]
23+
fn try_from(value: u8) -> Result<Self, Self::Error> {
24+
match value {
25+
// SAFETY: `value` is guaranteed to be in the range of the enum variants.
26+
0..=2 => Ok(unsafe { core::mem::transmute::<u8, AccountState>(value) }),
27+
_ => Err(ProgramError::InvalidAccountData),
28+
}
29+
}
30+
}

interface/src/state/mint.rs

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use {
22
super::{COption, Initializable, Transmutable},
3-
pinocchio::pubkey::Pubkey,
3+
pinocchio::{program_error::ProgramError, pubkey::Pubkey},
44
};
55

66
/// Internal representation of a mint data.
@@ -10,7 +10,7 @@ pub struct Mint {
1010
/// be provided during mint creation. If no mint authority is present
1111
/// then the mint has a fixed supply and no further tokens may be
1212
/// minted.
13-
pub mint_authority: COption<Pubkey>,
13+
mint_authority: COption<Pubkey>,
1414

1515
/// Total supply of tokens.
1616
supply: [u8; 8],
@@ -24,7 +24,7 @@ pub struct Mint {
2424
// Indicates whether the freeze authority is present or not.
2525
//freeze_authority_option: [u8; 4],
2626
/// Optional authority to freeze token accounts.
27-
pub freeze_authority: COption<Pubkey>,
27+
freeze_authority: COption<Pubkey>,
2828
}
2929

3030
impl Mint {
@@ -55,11 +55,11 @@ impl Mint {
5555
}
5656

5757
#[inline(always)]
58-
pub fn mint_authority(&self) -> Option<&Pubkey> {
59-
if self.mint_authority.0[0] == 1 {
60-
Some(&self.mint_authority.1)
61-
} else {
62-
None
58+
pub fn mint_authority(&self) -> Result<Option<&Pubkey>, ProgramError> {
59+
match self.mint_authority.0 {
60+
[0, 0, 0, 0] => Ok(None),
61+
[1, 0, 0, 0] => Ok(Some(&self.mint_authority.1)),
62+
_ => Err(ProgramError::InvalidAccountData),
6363
}
6464
}
6565

@@ -75,11 +75,11 @@ impl Mint {
7575
}
7676

7777
#[inline(always)]
78-
pub fn freeze_authority(&self) -> Option<&Pubkey> {
79-
if self.freeze_authority.0[0] == 1 {
80-
Some(&self.freeze_authority.1)
81-
} else {
82-
None
78+
pub fn freeze_authority(&self) -> Result<Option<&Pubkey>, ProgramError> {
79+
match self.freeze_authority.0 {
80+
[0, 0, 0, 0] => Ok(None),
81+
[1, 0, 0, 0] => Ok(Some(&self.freeze_authority.1)),
82+
_ => Err(ProgramError::InvalidAccountData),
8383
}
8484
}
8585
}
@@ -91,7 +91,11 @@ impl Transmutable for Mint {
9191

9292
impl Initializable for Mint {
9393
#[inline(always)]
94-
fn is_initialized(&self) -> bool {
95-
self.is_initialized == 1
94+
fn is_initialized(&self) -> Result<bool, ProgramError> {
95+
match self.is_initialized {
96+
0 => Ok(false),
97+
1 => Ok(true),
98+
_ => Err(ProgramError::InvalidAccountData),
99+
}
96100
}
97101
}

interface/src/state/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub trait Transmutable {
2323
/// Trait to represent a type that can be initialized.
2424
pub trait Initializable {
2525
/// Return `true` if the object is initialized.
26-
fn is_initialized(&self) -> bool;
26+
fn is_initialized(&self) -> Result<bool, ProgramError>;
2727
}
2828

2929
/// Return a reference for an initialized `T` from the given bytes.
@@ -35,7 +35,7 @@ pub trait Initializable {
3535
pub unsafe fn load<T: Initializable + Transmutable>(bytes: &[u8]) -> Result<&T, ProgramError> {
3636
load_unchecked(bytes).and_then(|t: &T| {
3737
// checks if the data is initialized
38-
if t.is_initialized() {
38+
if t.is_initialized()? {
3939
Ok(t)
4040
} else {
4141
Err(ProgramError::UninitializedAccount)
@@ -69,7 +69,7 @@ pub unsafe fn load_mut<T: Initializable + Transmutable>(
6969
) -> Result<&mut T, ProgramError> {
7070
load_mut_unchecked(bytes).and_then(|t: &mut T| {
7171
// checks if the data is initialized
72-
if t.is_initialized() {
72+
if t.is_initialized()? {
7373
Ok(t)
7474
} else {
7575
Err(ProgramError::UninitializedAccount)

interface/src/state/multisig.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use {
22
super::{Initializable, Transmutable},
3-
pinocchio::pubkey::Pubkey,
3+
pinocchio::{program_error::ProgramError, pubkey::Pubkey},
44
};
55

66
/// Minimum number of multisignature signers (min N)
@@ -18,10 +18,10 @@ pub struct Multisig {
1818
/// Number of valid signers.
1919
pub n: u8,
2020

21-
/// Is `true` if this structure has been initialized
21+
/// Is `true` if this structure has been initialized.
2222
is_initialized: u8,
2323

24-
/// Signer public keys
24+
/// Signer public keys.
2525
pub signers: [Pubkey; MAX_SIGNERS as usize],
2626
}
2727

@@ -45,7 +45,11 @@ impl Transmutable for Multisig {
4545

4646
impl Initializable for Multisig {
4747
#[inline(always)]
48-
fn is_initialized(&self) -> bool {
49-
self.is_initialized == 1
48+
fn is_initialized(&self) -> Result<bool, ProgramError> {
49+
match self.is_initialized {
50+
0 => Ok(false),
51+
1 => Ok(true),
52+
_ => Err(ProgramError::InvalidAccountData),
53+
}
5054
}
5155
}

p-token/src/entrypoint.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub fn process_instruction(
3636
instruction_data: &[u8],
3737
) -> ProgramResult {
3838
let [discriminator, remaining @ ..] = instruction_data else {
39-
return Err(ProgramError::InvalidInstructionData);
39+
return Err(TokenError::InvalidInstruction.into());
4040
};
4141

4242
let result = if *discriminator == 255 {
@@ -78,7 +78,7 @@ pub(crate) fn inner_process_instruction(
7878
instruction_data: &[u8],
7979
) -> ProgramResult {
8080
let [discriminator, instruction_data @ ..] = instruction_data else {
81-
return Err(ProgramError::InvalidInstructionData);
81+
return Err(TokenError::InvalidInstruction.into());
8282
};
8383

8484
match *discriminator {
@@ -280,6 +280,6 @@ fn inner_process_remaining_instruction(
280280

281281
process_withdraw_excess_lamports(accounts)
282282
}
283-
_ => Err(ProgramError::InvalidInstructionData),
283+
_ => Err(TokenError::InvalidInstruction.into()),
284284
}
285285
}

p-token/src/processor/amount_to_ui_amount.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub fn process_amount_to_ui_amount(
1919
let amount = u64::from_le_bytes(
2020
instruction_data
2121
.try_into()
22-
.map_err(|_error| ProgramError::InvalidInstructionData)?,
22+
.map_err(|_error| TokenError::InvalidInstruction)?,
2323
);
2424

2525
let mint_info = accounts.first().ok_or(ProgramError::NotEnoughAccountKeys)?;

p-token/src/processor/approve.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
use {
22
super::shared,
3-
pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult},
3+
pinocchio::{account_info::AccountInfo, ProgramResult},
4+
spl_token_interface::error::TokenError,
45
};
56

67
#[inline(always)]
78
pub fn process_approve(accounts: &[AccountInfo], instruction_data: &[u8]) -> ProgramResult {
89
let amount = u64::from_le_bytes(
910
instruction_data
1011
.try_into()
11-
.map_err(|_error| ProgramError::InvalidInstructionData)?,
12+
.map_err(|_error| TokenError::InvalidInstruction)?,
1213
);
1314

1415
shared::approve::process_approve(accounts, amount, None)

0 commit comments

Comments
 (0)