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

Add non_exhaustive compiler directive to AddressType #1011

Merged
merged 1 commit into from Jun 2, 2022

Conversation

tcharding
Copy link
Member

@tcharding tcharding commented May 26, 2022

Add non_exhaustive compiler directive to AddressType

Currently adding variants to enums is a breaking change. In an effort to
reduce the upgrade burden on users we can use the non_exhaustive
compiler directive so that adding a new variant does not cause
downstream code to break.

Add non_exhaustive to the AddressType since it may be extended in
the future.

@@ -139,6 +139,7 @@ impl From<bech32::Error> for Error {

/// The different types of addresses.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[non_exhaustive]
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, I'm a little dubious of this - I can imagine matching on this and doing...something, eg maybe I want to know if an address is a witness and map every type to a bool or something, but with non_exhaustive now you have to _ => ...panic, I guess?. There are definitely reasons to want forward compat without breaking downstream, but for "we added a new address type" kinda things is so rare that I'm not sure we need to worry about that breakage, IMO.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for the review. I'm not totally sure of the merit of this PR myself, whether we should use non_exhaustive, or whether we should use it but on some different set of types. There has been multiple folks speak up in the past positively about non_exhaustive, the intention of this PR is to bring out all the opinions and then I'll just try to shepherd them in. As such, I'll leave this sitting open for a while and see what comes of it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

There are much better ways to detect whether an address is witness (or something else) than matching each type. I think bumping the major version just because there's a new soft fork is annoying. The issue with this library is that pretty much any Bitcoin application written in Rust uses it, so it's a shitton of breakage.

IMO any public enum and struct that could be possibly extended in the future should be #[non_exhaustive]

Copy link
Member

Choose a reason for hiding this comment

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

I mean philosophically I agree with you, it'd be cool to have the library not have ballot changes for soft forks. In practice, though, that just makes the downstream code that would have broken have panics that they may hit instead, which isn't an improvement. More generally, Bitcoin does soft forks really really rarely, I'm not sure we need to worry too much about changing a few enums when a new soft fork happens - we probably have to change a ton of fields to add support for it anyway.

Copy link
Member

Choose a reason for hiding this comment

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

I tend to agree with @Kixunil here ... my feeling is that matching on these enums is a bit of a weird thing to do, and if you are doing this, you ought to have an error path for the case that some unsupported softfork has happened. (Or in some cases perhaps you could do some sane default.)

On the other hand, soft forks in Bitcoin are really rare, so this is something of an academic discussion. Maybe the time to discuss this is whenever the next fork actually seems to be happening? (My guess is that the next fork will be addition of some covenant opcodes, which won't even bump any version numbers, though it could also be APO..)

Copy link
Collaborator

Choose a reason for hiding this comment

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

The problem is it's not "just updating a few enums". Due to breaking change there needs to be a coordinated major version bump across all ecosystem. This is a huge library and it is the only (rich) Bitcoin library available in Rust today, so pretty much every Bitcoin project written in Rust depends on it. Perhaps if Address was a separate crate it'd be less painful but I guess it'd still be significant.

This is my main motivation behind trying to make the library stable as you might have noticed from my efforts.

Maybe the time to discuss this is whenever the next fork actually seems to be happening?

I don't think so, if at that time we have 1.0 it's already too late. At the latest we need to decide before making it 1.0.

Copy link
Member

@sanket1729 sanket1729 left a comment

Choose a reason for hiding this comment

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

As others have mentioned, I agree with #[non-exhuastive] for AddressType. There are known issues with many exchanges not allowing to send coins to future addresses. Adding [non-exhuastive] generally should help in these cases.

but the other two are not needed as they cannot be extended in the future.
We have to carefully reason about each case if they are really needed or not.

@@ -358,6 +359,7 @@ impl From<WitnessVersion> for opcodes::All {

/// The method used to produce an address.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[non_exhaustive]
Copy link
Member

Choose a reason for hiding this comment

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

This, I am not sure is required. This should cover all the cases of interest that could possibly be extended in the future.

@@ -870,6 +870,7 @@ impl fmt::UpperHex for FutureLeafVersion {

/// The leaf version for tapleafs.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[non_exhaustive]
Copy link
Member

Choose a reason for hiding this comment

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

This is not required. We have already modelled the leaf versions using FutureLeafVersion

Currently adding variants to enums is a breaking change. In an effort to
reduce the upgrade burden on users we can use the `non_exhaustive`
compiler directive so that adding a new variant does not cause
downstream code to break.

Add `non_exhaustive` to the `AddressType` since it may be extended in
the future.
@tcharding tcharding changed the title Add non_exhaustive compiler directive Add non_exhaustive compiler directive to AddressType Jun 2, 2022
@tcharding
Copy link
Member Author

Changes in force push:

  • Only includes AddressType now as discussed above
  • Re-wrote PR title and description

Copy link
Member

@sanket1729 sanket1729 left a comment

Choose a reason for hiding this comment

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

ACK 43b684b

Copy link
Collaborator

@Kixunil Kixunil left a comment

Choose a reason for hiding this comment

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

ACK 43b684b

Copy link
Member

@apoelstra apoelstra left a comment

Choose a reason for hiding this comment

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

ACK 43b684b

@apoelstra
Copy link
Member

Glad to see we all agree!

@apoelstra apoelstra merged commit adf3958 into rust-bitcoin:master Jun 2, 2022
@tcharding tcharding deleted the 05-26-non-exhaustive branch June 2, 2022 23:49
ChallengeDev210 pushed a commit to ChallengeDev210/rust-bitcoin that referenced this pull request Aug 1, 2022
…ective to `AddressType`

43b684b Add non_exhaustive compiler directive to AddressType (Tobin C. Harding)

Pull request description:

  Add non_exhaustive compiler directive to AddressType

  Currently adding variants to enums is a breaking change. In an effort to
  reduce the upgrade burden on users we can use the `non_exhaustive`
  compiler directive so that adding a new variant does not cause
  downstream code to break.

  Add `non_exhaustive` to the `AddressType` since it may be extended in
  the future.

ACKs for top commit:
  sanket1729:
    ACK 43b684b
  Kixunil:
    ACK 43b684b
  apoelstra:
    ACK 43b684b

Tree-SHA512: 2b2a15fb501d23058acca94318776ffcccedf463d43d07afa290fba46a7bd58b3a730f6e1f25605ef399afcfdb5de4c7ad67eaa0adff0ba39b0096cbcec10f57
@Kixunil Kixunil added the API break This PR requires a version bump for the next release label Aug 1, 2022
@Kixunil Kixunil added this to the 0.29.0 milestone Aug 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API break This PR requires a version bump for the next release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants