-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
SPL errors from hashes #5169
Conversation
1fdd959
to
4db16b2
Compare
4db16b2
to
4ef69d7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation looks perfect! I did just realize though... we'll need a way for someone at the top-level to get more information about the error, since they're essentially random numbers 😓
Ok, hear me out, what if instead of giving each error a random number, we give the first error a random hashed number of namespace:error_name
, and everything counts up from there? That way someone just needs to find out that first number, which we force people to add to the source code somewhere to make it easier to discover, similar to solana-frozen-abi
, ie:
#[spl_program_error(hash_error_codes = true, error_start = 42)]
pub enum MyError {
OhNoes,
}
Where 42
is hash('spl_program_error:MyError')[13..17]
. If it's incorrect, the macro tells you what number to set as error_start
.
We could maybe condense those two into one arg, but I can't come up with any good names. Maybe just have expected_error_start
? Or expose a new macro, like spl_program_error_with_unique_error_codes
which does the hashing and also takes in the expected start number? These names all stink, so I'll noodle on something better.
This was a concern of mine on the approach as well. I felt like a unique error per variant was overkill, and posed a higher collision risk. On the topic of collisions, I felt like it was probably also overkill, but I have one particular concern about a hash randomly resulting in, say
Ha, this is cool and would totally work! It smells a bit like a macro anti-pattern to me, but I guess it really doesn't do any harm, and it will help with readability for sure! I'm in for this change as well. |
Ah right, that's a good point. Rather than remove a whole byte from the randomness, how about we just make sure that the number is >= 256 to be totally safe? and if it happens to be 0 <= x < 256, just shift over 1 byte until you get to a valid set of bytes.
If you have a better way of surfacing that number easily for people looking at the source, I'm game! But I couldn't come up with anything else |
smh, I meant
Which number are you referring to? The entire
Nah I think it's okay. Unless I find some Rustaceans barking about it online, it's going in |
4ef69d7
to
5da0e02
Compare
Sorry, yeah I mean the whole 4 bytes interpreted as a little-endian u32. Does Anchor start at 5000 for all programs? That seems very odd. If that's the case, we can just do 6000 or something, right? And that's already being plenty generous I'd say. If people use their own start, that's similar to just grinding a bunch of error names until you get something you like. |
They use the first digit as a category https://docs.rs/anchor-lang/latest/anchor_lang/error/enum.ErrorCode.html I have 10,000 in my latest commit, I guess we could get away with 7,000 ? Besides our offset, this is ready for another look. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just few tiny last little questions, this is extremely close!
Comments resolved! This is a breaking change for anything using these libraries downstream. I'm thinking:
wdyt? |
9cee796
to
be9683a
Compare
@@ -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; |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah! my bad
Sorry, maybe I'm missing something, but how is this change breaking? It passes CI without any changes to other libraries that are using it currently |
Is it not technically breaking since the underlying error codes are changing? CI is passing because I included changes to the tests where the expected error changed. For example, anyone expecting |
But that's only if you use |
I'm thinking about if I'm working with |
Ah yes, that's a breaking change in those libraries for sure. I'm planning on cutting a new minor release for all of these anyway. I'll do it once this lands |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lmao Lennon would approve |
* master: (719 commits) release: Bump token-2022 and all dependencies (solana-labs#5189) SPL errors from hashes (solana-labs#5169) stake-pool: Add comments about unnecessary ownership checks (HAL-01) (solana-labs#5084) stake-pool: Enforce that pool mint uses 9 decimal places (HAL-03) (solana-labs#5085) build(deps-dev): bump tsx from 3.12.7 to 3.12.8 in /single-pool/js (solana-labs#5188) account-compression: Fixup sdk doc deployment (solana-labs#5187) token-js: renamed `getExtraAccountMetaAccount` to `getExtraAccountMetaAddress` (solana-labs#5186) token-js: added an e2e test for transferring using a mint with a transfer hook extension (solana-labs#5138) Serde optional dependencies clean-up (solana-labs#5181) build(deps): bump chrono from 0.4.27 to 0.4.28 (solana-labs#5180) stake-pool: Use unaligned types for safe pointer cast (solana-labs#5179) spl-pod: make code docs more explicit (solana-labs#5178) token-js: added extra account resolution for transfer hook extension (solana-labs#5112) Fix incorrect code doc (solana-labs#5177) Move Pod types to separate library (solana-labs#5119) build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.4.1 to 6.5.0 in /memo/js (solana-labs#5176) build(deps): bump chrono from 0.4.26 to 0.4.27 (solana-labs#5171) build(deps-dev): bump prettier from 3.0.2 to 3.0.3 in /token-swap/js (solana-labs#5174) build(deps-dev): bump prettier from 3.0.2 to 3.0.3 in /token/js (solana-labs#5172) build(deps-dev): bump prettier from 3.0.2 to 3.0.3 in /token-lending/js (solana-labs#5173) ...
This PR adds unique, custom error codes to every error in SPL libraries - including the two interfaces
transfer-hook
andtoken-metadata
.The ability to derive unique
u32
error codes from hash inputs is powered by these changes to thespl-program-error
crate, which simply hashes the following combination of inputs and takes bytes 13 through 16 as the little-endianu32
:This creates unique error codes for each error, as requested in this comment
Closes #5042
Solves discussions in #5168