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 transaction::Version data type #2006

Merged
merged 1 commit into from Sep 23, 2023

Conversation

tcharding
Copy link
Member

BIP-68 activated a fair while ago (circa 2019) and since then only transaction versions 1 and 2 have been considered standard.

Currently in our Transaction struct we use an i32, this means users can construct a non-standard transaction if they do not first look up what the value should be. We can help folk out here by abstracting over the version number.

Add transaction::Version data type that simply provides two consts ONE and TWO.

Add a Default impl on Version that returns Version::TWO.

In tests that used version 0, instead use Version::default because the test obviously does not care.

@apoelstra
Copy link
Member

5ae7806 looks good except that we should add a constructor for creating arbitrary version numbers. We can comment that there is no reason (on mainnet at least) to use this, but it should be possible.

Alternately we could make the inner i32 public.


impl Decodable for Version {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
Decodable::consensus_decode(r).map(Version)
Copy link
Member

Choose a reason for hiding this comment

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

Should this not check that these are the only values we support. I think we should allow for other values too, perhaps under another constructor. People are prototyping tx ver 3 in signet for mempool relay stuff.

Copy link
Member Author

Choose a reason for hiding this comment

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

Just in case you missed it, current version of this PR includes transaction::Version::non_standard constructor as requested.

@tcharding
Copy link
Member Author

Good reviewing lads, thank you. Changes in force push

  • Make the inner i32 public and document that we do not enforce any invariants on the version number.
  • Add non_standard constructor
  • Add is_standard (eg, in case folk want to check after decoding)

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 6cf6f62

apoelstra
apoelstra previously approved these changes Sep 3, 2023
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 95297f4

BIP-68 activated a fair while ago (circa 2019) and since then only
transaction versions 1 and 2 have been considered standard.

Currently in our `Transaction` struct we use an `i32`, this means users
can construct a non-standard transaction if they do not first look up
what the value should be. We can help folk out here by abstracting over
the version number.

Since the version number only governs standardness elect to make the
inner `i32` public (ie., not an invariant). The aim of the type is to
make life easy not restrict what versions are used.

Add transaction::Version data type that simply provides two consts `ONE`
and `TWO`.

Add a `Default` impl on `Version` that returns `Version::TWO`.

In tests that used version 0, instead use `Version::default` because the
test obviously does not care.
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 c950ef4

Copy link
Member

@clarkmoody clarkmoody left a comment

Choose a reason for hiding this comment

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

ACK c950ef4

@clarkmoody clarkmoody merged commit 72a7280 into rust-bitcoin:master Sep 23, 2023
29 checks passed
@apoelstra
Copy link
Member

Thanks for merging @clarkmoody!

In future though could you use the Bitcoin Core merge script (it is not actually Core-specific at all). It creates a more uniform merge commit message, gpg-signs the merge commits, does a few sanity checks, and looks for ACKs in the PR comments.

pub fn is_standard(&self) -> bool { *self == Version::ONE || *self == Version::TWO }
}

impl Default for Version {
Copy link
Member

Choose a reason for hiding this comment

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

post merge comment:

Is this a reasonable default. We are expecting transaction version 3 sometime in the future. If we silently change this to three, it will break a lot of code downstream.

I don't think this should implement Default as there is no sane default that we can represent. If we want a default I think it should be zero.

Copy link
Member

Choose a reason for hiding this comment

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

@tcharding, @apoelstra, I feel this needs to addressed/discussed.

Copy link
Member

Choose a reason for hiding this comment

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

If version 3 transactions ship and the default version changes, then we would simply release a new breaking version of the library with release notes.

I think a sane default would be what Core uses. Version zero would be nonstandard, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

Some interesting points, I could easily have changed a default value and not thought it a breaking change. I don't see a lot of negative in removing the Default so if there is the slightest concern I think we should do that.

Copy link
Member

Choose a reason for hiding this comment

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

I didn't realize that version 3 was coming down the pike. I agree, we should drop the default (though I'd like to put it back as 3 whenever 3 comes out, because that default will last for several years at least).

@clarkmoody it is a breaking change so in principle we're justified in messing with the value in any breaking release, but I think changing this value would be extremely hard to notice -- if we did this to Liquid I'd bet we'd go literally years before we noticed that we were producing transactions with a different version number, and then we'd need some forensics to see when it happened (and we'd only even notice because we happen to know that Liquid long predates tx v3 so it can't have always been 3..). Because there's no "visible" effect other than a potential change in privacy set.

In the case of Liquid it wouldn't matter at all, but if we were a user who cared for some reason, we'd be upset.

@clarkmoody
Copy link
Member

Thanks for merging @clarkmoody!

In future though could you use the Bitcoin Core merge script (it is not actually Core-specific at all). It creates a more uniform merge commit message, gpg-signs the merge commits, does a few sanity checks, and looks for ACKs in the PR comments.

Oops! Will use that script for future merges.

@tcharding
Copy link
Member Author

Clearly a sacking offence, @clarkmoody please step down and return all salary payments already received ;)

@tcharding tcharding deleted the 08-18-tx-version branch September 24, 2023 19:48
apoelstra added a commit that referenced this pull request Sep 25, 2023
f31fb08 Remove default impl from transaction version (Tobin C. Harding)

Pull request description:

  There is no logical default for the transaction version number, there is only pre-bip68 (v1) and post-bip68 (v2). Uses should specify the version they want not rely on us making the choice.

  (I originally added this impl to support testing, this was in hindsight the wrong thing to do, props to Sanket for noticing.)

  Discussed in comments here: #2006 (comment)

ACKs for top commit:
  clarkmoody:
    ACK  f31fb08
  apoelstra:
    ACK f31fb08

Tree-SHA512: 1112c35173d6b2e7d6c50f058b1964fc8b633615ae703b0c1231e701a3e322fd55d3a8377c7ea078f28f523b15b7de6e9eca844226fcd19528206161d75dcfdf
lateminer added a commit to CoinBlack/rust-blackcoinmore-rpc that referenced this pull request Oct 26, 2023
lateminer added a commit to lateminer/rust-bitcoin that referenced this pull request Oct 26, 2023
apoelstra added a commit that referenced this pull request Oct 27, 2023
2a891e0 Add a missing link to #2006 in 'bitcoin/CHANGELOG.md' (lateminer)

Pull request description:

  In the changelog, there is a wrong link to #2006.
  Additionally, a link and description for #2020 are missing.
  This PR addresses these minor issues.

ACKs for top commit:
  apoelstra:
    ACK 2a891e0
  tcharding:
    ACK 2a891e0

Tree-SHA512: c6dc1362af5bb2e5f11c2ed48371a0236ab512aeb0f6075674994c054baf606d9cf30390d7021f9c02c3b7cc59a70c60edb64799afb35cc5ac716a3582aa8cd0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants