-
Notifications
You must be signed in to change notification settings - Fork 73
Make ProgramError compatible with pinocchio #12
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
base: master
Are you sure you want to change the base?
Make ProgramError compatible with pinocchio #12
Conversation
CI error is as expected given the breaking change |
f625acf
to
bc3494a
Compare
any outstanding issues with this? |
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.
Really great work! I'm a big fan of the change overall, mostly small things and questions to consider
/// consistent across Solana software versions. | ||
/// | ||
BorshIoError(String), | ||
BorshIoError, |
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.
Confirming that this change is good from the runtime side too -- the error text is never used or stored anywhere
@@ -385,7 +347,7 @@ impl fmt::Display for InstructionError { | |||
} | |||
} | |||
|
|||
#[cfg(feature = "std")] | |||
#[cfg(feature = "num-traits")] |
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.
I looked around to see if there was a standard feature name for num-traits. The highest downloaded crate that has it optional uses num-traits
https://github.com/starkat99/half-rs, and the second just uses num
https://github.com/jhpratt/deranged.
All that to say, I'm good with num-traits
program-error/Cargo.toml
Outdated
|
||
[features] | ||
borsh = ["dep:borsh"] | ||
pubkey-error = ["dep:solana-pubkey-error"] |
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.
I don't want to cause too much whiplash, but I'm not sure this feature adds too much value, especially considering solana-pubkey-error is such a light crate.
My vote would be to move the From<PubkeyError> for ProgramError
implementation to solana-pubkey-error
instead.
@febo thoughts?
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.
Makes sense to me. I think it is simpler to import solana-pubkey-error
directly if you want to use it.
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.
that would add an indirect solana-program-error dep to solana-pubkey unless we add a program-error feature to solana-pubkey-error
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.
Sorry, I think I'm missing something about the dependency graph -- is there an issue with having solana-pubkey depend on solana-program-error? Or is it the problem of adding any dependencies to solana-pubkey?
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.
It's more bloaty than having program-error depend on pubkey-error, since if you have to choose a superfluous dep, pubkey-error is the smaller one. I would just have program-error depend on pubkey-error without a feature flag if @febo is ok with Pinocchio depending unnecessarily on pubkey-error
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.
Hmmm, I think it will be a bit strange to have it that way. In a way ProgramError
is the "root" error type generated by programs, so the direction of the dependency looks more natural if PubkeyError
depends on ProgramError
for cases where it will be wrapped as a ProgramError
. This is what usually will happen to any other custom error type defined that can be wrapped as a ProgramError
.
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.
ok i'm moving PubkeyError back to solana-pubkey
} | ||
|
||
#[cfg(feature = "solana-msg")] |
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.
We can figure this out in follow-up work, but since this isn't actually doing any string formatting, we can probably get by with using the syscall directly and completely avoid pulling in solana-msg
and format!
, which is typically the source of bloat.
And that way, we don't need the solana-msg
feature.
What do you think @febo ?
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.
Agree – another option is to use a trait that just converts a ProgramError
to a &str
, like here.
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.
If @febo is fine with it I suggest we just remove the feature and make solana-msg a regular dependency. It causes no measurable increase in build time and I doubt the solana-msg crate is going to have any major version bumps
This comment was marked as off-topic.
This comment was marked as off-topic.
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.
This looks good to me, but let's see what @febo thinks before merging
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.
This works as a drop in replacement for pinocchio, which is great! We could pull in solana-msg
but we need to make that crate no_std
first, otherwise it will bring std
because of the format!
– something we can address in a separate PR.
Ideally I would deprecate the PrintProgramError
trait in favour of one that just returns a static &str
. Feels more useful than "bundling" the msg!
inside the trait implementation. Thoughts?
Does anyone use PrintProgramError outside of SPL? We could move it somewhere else. What's the big deal with having unused std code in a dependency? |
Messes around with the panic handler implementation when |
I think programs tend to use it since SPL programs do. We could add a |
I'm not following - isn't std always available to the linker if the platform supports it? And |
It might be a specific behaviour of platform-tools toolchain, but this is the difference (full details here): std:
no_std:
This changes which panic handler to include in your program, since for |
If that's true that's a bug in platform-tools rust right? In normal Rust adding a dependency on a crate that uses std doesn't change the behaviour of other crates. Anyway I've now made it so the std feature is enabled if the solana-msg feature is enabled |
I think this is the "normal" behaviour. When the You can quickly test this in Rust. Create a new crate (
Now add All that to say that it is better to "mark" crates as EDIT: A better example is to use |
Interesting, that's really annoying! Not to go on a tangent but is there a downside to removing the root AFAICT Rust tooling provides no good ways of ensuring that all a project's dependencies are no-std, so this is going to be a footgun for users |
Not a lot of downside, but it would prevent someone to completely replace the panic handler with a custom implementation if they wanted to. I imagine most users won't see this issue, since you need to be explicitly writing a I think this will eventually go away when we bump to Rust |
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.
Looks great and works great as well! Here it is how this is integrated in pinocchio: anza-xyz/pinocchio#112
#### Problem As part of the breaking change to unite pinocchio's program error with the sdk's program error in anza-xyz#12, we are introducing a new `ToStr` trait that doesn't rely on any particular logging. To go with that, we want to deprecate `PrintProgramError`. #### Summary of changes Before landing the breaking change, let's deprecate `PrintProgramError` properly and add `ToStr` as an alternative for downstream users. Once this lands, we'll do the patch release with the deprecation, then we can finally land anza-xyz#12.
I'm thinking we should land the deprecation of |
#### Problem As part of the breaking change to unite pinocchio's program error with the sdk's program error in #12, we are introducing a new `ToStr` trait that doesn't rely on any particular logging. To go with that, we want to deprecate `PrintProgramError`. #### Summary of changes Before landing the breaking change, let's deprecate `PrintProgramError` properly and add `ToStr` as an alternative for downstream users. Once this lands, we'll do the patch release with the deprecation, then we can finally land #12.
…on to solana-pubkey
1943002
to
d5cd36e
Compare
Problem: solana-program-error and pinocchio define ProgramError enums that are identical except for the BorshIoError variant, which looks like
BorshIoError(String)
in solana-program-error and is fieldless (justBorshIoError
) in pinocchio.It is going to be a significant source of grief for users to have two almost-identical ProgramError types in their dependency tree. People will accidentally import the wrong one a lot
Solution: make solana_program_error::ProgramError the same as the pinocchio one so pinocchio can replace its definition with a re-export.
Breaking changes:
impl std::error::Error for ProgramError {}
Other changes: