Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions programs/bpf/c/src/error_handling/error_handling.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ extern uint64_t entrypoint(const uint8_t *input) {
case(6):
sol_log("return unknown builtin");
return TO_BUILTIN(50);
case(9):
sol_log("return pubkey error");
return MAX_SEED_LENGTH_EXCEEDED;
default:
sol_log("Unrecognized command");
return ERROR_INVALID_INSTRUCTION_DATA;
Expand Down
6 changes: 5 additions & 1 deletion programs/bpf/rust/error_handling/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use solana_sdk::{
entrypoint::ProgramResult,
info,
program_error::{PrintProgramError, ProgramError},
pubkey::Pubkey,
pubkey::{Pubkey, PubkeyError},
};
use thiserror::Error;

Expand Down Expand Up @@ -73,6 +73,10 @@ fn process_instruction(
assert_eq!(*data, *data2);
Ok(())
}
9 => {
info!("return pubkey error");
Err(PubkeyError::MaxSeedLengthExceeded.into())
}
_ => {
info!("Unsupported");
Err(ProgramError::InvalidInstructionData)
Expand Down
8 changes: 8 additions & 0 deletions programs/bpf/tests/programs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,14 @@ mod bpf {
result.unwrap_err().unwrap(),
TransactionError::InstructionError(0, InstructionError::InvalidInstructionData)
);

let instruction = Instruction::new(program_id, &9u8, account_metas.clone());
let result = bank_client.send_instruction(&mint_keypair, instruction);
assert_eq!(
result.unwrap_err().unwrap(),
TransactionError::InstructionError(0, InstructionError::MaxSeedLengthExceeded)
);

}
}

Expand Down
3 changes: 2 additions & 1 deletion sdk/bpf/c/inc/solana_sdk.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ static_assert(sizeof(uint64_t) == 8);
#define ERROR_NOT_ENOUGH_ACCOUNT_KEYS TO_BUILTIN(11)
/** Note: Not applicable to program written in C */
#define ERROR_ACCOUNT_BORROW_FAILED TO_BUILTIN(12)
/** The length of the seed is too long for address generation */
#define MAX_SEED_LENGTH_EXCEEDED TO_BUILTIN(13)

/**
* Boolean type
Expand All @@ -129,7 +131,6 @@ void sol_log_(const char *, uint64_t);
void sol_log_64_(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
#define sol_log_64 sol_log_64_


/**
* Size of Public key in bytes
*/
Expand Down
4 changes: 4 additions & 0 deletions sdk/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ pub enum InstructionError {
/// Cross-program invocation reentrancy not allowed for this instruction
#[error("Cross-program invocation reentrancy not allowed for this instruction")]
ReentrancyNotAllowed,

/// Length of the seed is too long for address generation
#[error("Length of the seed is too long for address generation")]
MaxSeedLengthExceeded,
}

impl InstructionError {
Expand Down
18 changes: 17 additions & 1 deletion sdk/src/program_error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{decode_error::DecodeError, instruction::InstructionError};
use crate::{decode_error::DecodeError, instruction::InstructionError, pubkey::PubkeyError};
use num_traits::{FromPrimitive, ToPrimitive};
use std::convert::TryFrom;
use thiserror::Error;
Expand Down Expand Up @@ -38,6 +38,8 @@ pub enum ProgramError {
NotEnoughAccountKeys,
#[error("Failed to borrow a reference to account data, already borrowed")]
AccountBorrowFailed,
#[error("Length of the seed is too long for address generation")]
MaxSeedLengthExceeded,
}

pub trait PrintProgramError {
Expand Down Expand Up @@ -70,6 +72,7 @@ impl PrintProgramError for ProgramError {
Self::UninitializedAccount => info!("Error: UninitializedAccount"),
Self::NotEnoughAccountKeys => info!("Error: NotEnoughAccountKeys"),
Self::AccountBorrowFailed => info!("Error: AccountBorrowFailed"),
Self::MaxSeedLengthExceeded => info!("Error: MaxSeedLengthExceeded"),
}
}
}
Expand All @@ -94,6 +97,7 @@ const ACCOUNT_ALREADY_INITIALIZED: u64 = to_builtin!(9);
const UNINITIALIZED_ACCOUNT: u64 = to_builtin!(10);
const NOT_ENOUGH_ACCOUNT_KEYS: u64 = to_builtin!(11);
const ACCOUNT_BORROW_FAILED: u64 = to_builtin!(12);
const MAX_SEED_LENGTH_EXCEEDED: u64 = to_builtin!(13);

impl From<ProgramError> for u64 {
fn from(error: ProgramError) -> Self {
Expand All @@ -109,6 +113,7 @@ impl From<ProgramError> for u64 {
ProgramError::UninitializedAccount => UNINITIALIZED_ACCOUNT,
ProgramError::NotEnoughAccountKeys => NOT_ENOUGH_ACCOUNT_KEYS,
ProgramError::AccountBorrowFailed => ACCOUNT_BORROW_FAILED,
ProgramError::MaxSeedLengthExceeded => MAX_SEED_LENGTH_EXCEEDED,
ProgramError::Custom(error) => {
if error == 0 {
CUSTOM_ZERO
Expand All @@ -134,6 +139,7 @@ impl From<u64> for ProgramError {
UNINITIALIZED_ACCOUNT => ProgramError::UninitializedAccount,
NOT_ENOUGH_ACCOUNT_KEYS => ProgramError::NotEnoughAccountKeys,
ACCOUNT_BORROW_FAILED => ProgramError::AccountBorrowFailed,
MAX_SEED_LENGTH_EXCEEDED => ProgramError::MaxSeedLengthExceeded,
CUSTOM_ZERO => ProgramError::Custom(0),
_ => ProgramError::Custom(error as u32),
}
Expand All @@ -157,6 +163,7 @@ impl TryFrom<InstructionError> for ProgramError {
Self::Error::UninitializedAccount => Ok(Self::UninitializedAccount),
Self::Error::NotEnoughAccountKeys => Ok(Self::NotEnoughAccountKeys),
Self::Error::AccountBorrowFailed => Ok(Self::AccountBorrowFailed),
Self::Error::MaxSeedLengthExceeded => Ok(Self::MaxSeedLengthExceeded),
_ => Err(error),
}
}
Expand All @@ -181,6 +188,7 @@ where
UNINITIALIZED_ACCOUNT => InstructionError::UninitializedAccount,
NOT_ENOUGH_ACCOUNT_KEYS => InstructionError::NotEnoughAccountKeys,
ACCOUNT_BORROW_FAILED => InstructionError::AccountBorrowFailed,
MAX_SEED_LENGTH_EXCEEDED => InstructionError::MaxSeedLengthExceeded,
_ => {
// A valid custom error has no bits set in the upper 32
if error >> BUILTIN_BIT_SHIFT == 0 {
Expand All @@ -192,3 +200,11 @@ where
}
}
}

impl From<PubkeyError> for ProgramError {
fn from(error: PubkeyError) -> Self {
match error {
PubkeyError::MaxSeedLengthExceeded => ProgramError::MaxSeedLengthExceeded,
}
}
}
3 changes: 2 additions & 1 deletion sdk/src/pubkey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ pub const MAX_SEED_LEN: usize = 32;

#[derive(Error, Debug, Serialize, Clone, PartialEq, FromPrimitive, ToPrimitive)]
pub enum PubkeyError {
#[error("length of requested seed is too long")]
/// Length of the seed is too long for address generation
#[error("Length of the seed is too long for address generation")]
MaxSeedLengthExceeded,
}
impl<T> DecodeError<T> for PubkeyError {
Expand Down