Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SPL errors from hashes #5169

Merged
merged 5 commits into from
Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
20 changes: 11 additions & 9 deletions libraries/program-error/derive/src/macro_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use {
};

const SPL_ERROR_HASH_NAMESPACE: &str = "spl_program_error";
const SPL_ERROR_HASH_MIN_VALUE: u32 = 10_0000;
const SPL_ERROR_HASH_MIN_VALUE: u32 = 7_0000;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha I just realized that this has an extra 0, should be 7_000. Good thing we have multiple rounds of reviews

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah! my bad


/// The type of macro being called, thus directing which tokens to generate
#[allow(clippy::enum_variant_names)]
Expand Down Expand Up @@ -154,8 +154,11 @@ pub fn spl_program_error(
/// See https://docs.rs/syn/latest/syn/struct.Variant.html
fn set_first_discriminant(item_enum: &mut ItemEnum, error_code_start: u32) {
let enum_ident = &item_enum.ident;
if item_enum.variants.is_empty() {
panic!("Enum must have at least one variant");
}
let first_variant = &mut item_enum.variants[0];
let discriminant = u32_from_hash(enum_ident, &first_variant.ident);
let discriminant = u32_from_hash(enum_ident);
if discriminant == error_code_start {
let eq = Token![=](Span::call_site());
let expr = Expr::Lit(ExprLit {
Expand All @@ -165,21 +168,20 @@ fn set_first_discriminant(item_enum: &mut ItemEnum, error_code_start: u32) {
first_variant.discriminant = Some((eq, expr));
} else {
panic!(
"Error code start value from hash is {}. Update your macro attribute.",
"Error code start value from hash must be {0}. Update your macro attribute to \
`#[spl_program_error(hash_error_code_start = {0})]`.",
discriminant
);
}
}

/// Hashes the `SPL_ERROR_HASH_NAMESPACE` constant, the enum name and variant
/// name and returns four middle bytes (13 through 16) as a u32.
fn u32_from_hash(enum_ident: &Ident, variant_ident: &Ident) -> u32 {
let hash_input = format!(
"{}:{}:{}",
SPL_ERROR_HASH_NAMESPACE, enum_ident, variant_ident
);
fn u32_from_hash(enum_ident: &Ident) -> u32 {
let hash_input = format!("{}:{}", SPL_ERROR_HASH_NAMESPACE, enum_ident);

// We don't want our error code to start at any number below `10_0000`!
// We don't want our error code to start at any number below
// `SPL_ERROR_HASH_MIN_VALUE`!
let mut nonce: u32 = 0;
buffalojoec marked this conversation as resolved.
Show resolved Hide resolved
loop {
let hash = solana_program::hash::hashv(&[hash_input.as_bytes(), &nonce.to_le_bytes()]);
Expand Down
4 changes: 2 additions & 2 deletions libraries/program-error/tests/spl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ fn test_macros_compile() {
}

/// Example library error with namespace
#[spl_program_error(hash_error_code_start = 3_234_444_947)]
#[spl_program_error(hash_error_code_start = 2_056_342_880)]
enum ExampleLibraryError {
/// This is a very informative error
#[error("This is a very informative error")]
Expand Down Expand Up @@ -57,7 +57,7 @@ fn test_library_error_codes() {

assert_eq!(
ExampleLibraryError::VeryInformativeError as u32,
get_error_code_check("spl_program_error:ExampleLibraryError:VeryInformativeError"),
get_error_code_check("spl_program_error:ExampleLibraryError"),
);
assert_eq!(
ExampleLibraryError::SuperImportantError as u32,
Expand Down
2 changes: 1 addition & 1 deletion libraries/tlv-account-resolution/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use spl_program_error::*;

/// Errors that may be returned by the Account Resolution library.
#[spl_program_error(hash_error_code_start = 2_127_734_810)]
#[spl_program_error(hash_error_code_start = 2_724_315_840)]
pub enum AccountResolutionError {
/// Incorrect account provided
#[error("Incorrect account provided")]
Expand Down
2 changes: 1 addition & 1 deletion libraries/type-length-value/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use spl_program_error::*;

/// Errors that may be returned by the Token program.
#[spl_program_error(hash_error_code_start = 3_787_709_112)]
#[spl_program_error(hash_error_code_start = 1_202_666_432)]
pub enum TlvError {
/// Type not found in TLV data
#[error("Type not found in TLV data")]
Expand Down
2 changes: 1 addition & 1 deletion token-metadata/interface/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use spl_program_error::*;

/// Errors that may be returned by the interface.
#[spl_program_error(hash_error_code_start = 933_549_204)]
#[spl_program_error(hash_error_code_start = 901_952_957)]
pub enum TokenMetadataError {
/// Incorrect account provided
#[error("Incorrect account provided")]
Expand Down
2 changes: 1 addition & 1 deletion token/transfer-hook-interface/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use spl_program_error::*;

/// Errors that may be returned by the interface.
#[spl_program_error(hash_error_code_start = 528_258_895)]
#[spl_program_error(hash_error_code_start = 2_110_272_652)]
pub enum TransferHookError {
/// Incorrect account provided
#[error("Incorrect account provided")]
Expand Down
Loading