-
Notifications
You must be signed in to change notification settings - Fork 831
Move witness types to the script module #1846
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
Conversation
The reason for creating two [trivial] modules is so that (with the re-exports in this PR) users who want to use the error will do so as: use bitcoin::witness_version::{self, WitnessVersion};
...
enum Error {
Witver(witness_version::Error),
Other
} And same for |
618c835
to
dde7430
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.
Concept ACK. I did think it was odd that WitnessVersion
is in address
but wasn't thinking much about it. I'm not entirely sure about script
but at least is sounds better than address
.
These are I don't feel strongly about this either way, so happy to go along with it, but IMHO these actually are address concerns.. |
Ah, I see, this creates a new |
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.
ACK dde7430f34669c936b4effddc5a25f9579b2f922
Should we put these two modules at the crate root instead? FTR this is only a code organisation issue, both modules and their types are re-exported at the crate root already. |
No, I think |
Just realized that we actually have the From the BIP:
But we have /// The segregated witness program.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct WitnessProgram {
/// The witness program version number.
version: WitnessVersion,
/// The witness program (between 2 and 40 bytes).
program: PushBytesBuf,
} The version is not part of the witness program according to the wording of the BIP. |
When "witness program" was a representation of an address, this made sense :) |
In any case, a witness program without a version is a meaningless sequence of bytes. Unless the BIP gives us a different word to use in place of "witness version + witness program" I think we should continue to use the existing structure with the existing name. |
I read your comments @apoelstra but went ahead and did an exploratory patch that pulls the version byte out of Its a separate patch so I can drop it if its disliked. |
We could call it
|
Neat. Ok, I like 97f531f19dbfa3e9eefa60d93fbcc2f1419dd576. I'm a tiny bit worried that it could confuse people who don't realize that Taproot outputs are also Segwit outputs, but it's more correct so I think it's the right move. |
I think if someone does not realise that they are in for a world of pain using our library in general. |
For good measure I added: /// Checks whether a script is a segwit scriptPubkey.
///
/// Remember, includes segwit v0 and taproot (v1) and any version to come.
#[inline]
pub fn is_segwit_script_pubkey(&self) -> bool { |
97f531f
to
cc5b649
Compare
Changes in force push:
|
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.
ACK cc5b6498b0d6de518d44ea4d0f522c855de5165f
Gentle bump. |
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.
Doesn't look terrible but I don't like losing the protection and I'm too tired to confidently ACK now, so leaving this for reconsideration.
bitcoin/src/address.rs
Outdated
/// Witness version (version byte of the scriptPubkey). | ||
version: WitnessVersion, | ||
/// Witness program (as defined by BIP141). | ||
program: WitnessProgram, |
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.
So this no longer protects the invariant. I think a struct would be better. I guess calling it Segwit
would be fine but I'm too tired to say for sure.
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 believe this is resolved but the original code that this talks about is so long ago I don't really remember it. We do have a struct variant now.
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 think Kix is right here. We can create the following invalid value for the Payload type.
let prog = WitnessProgram::new(WitnessVersion::V2, &[0x02; 31]).unwrap(); //31 bytes v2 progs are okay
let payload = Payload::Segwit {version: WitnessVersion::V0, program: prog}; // 31 bytes v0 are incorrect.
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 was happy to find that I did actually notice this when I coded it up, its in the patch description
This change makes the code more semantically correct. Note that it does
introduce a non-explicit assumption that the same version be passed to
`WitnessProgram::new` as is used in the `Payload` - is this acceptable
engineering?
After attempting to fix this I ended up creating a struct that was exactly the same as the original WitnessProgram
but with a different name. I've elected to drop the second patch and just add the following comment to the WitnessProgram
/// The segregated witness program is technically only the program bytes _excluding_ the witness
/// version, however we maintain length invariants on the `program` that are governed by the version
/// number, therefore we carry the version number around along with the program bytes.
0dde64a
to
fc42616
Compare
Rebased on master and removed the |
042dcaa Remove doc(hidden) from error conversion functions (Tobin C. Harding) Pull request description: Give people access to the error type conversion docs, its no harm and it may be useful when the compiler does not give enough information. Done based on discussion here: #1846 (comment) ACKs for top commit: Kixunil: ACK 042dcaa apoelstra: ACK 042dcaa Tree-SHA512: 9d975845ba84213b203062282b68f06f6790d03dbc88d66dce82e9bedff4696fc01da6216920de9e9e4130f6469b32ff9c168d0800d057ec0bae51702d4a139e
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.
ACK fc42616f4a37d820aa45165a9e7c778c88324d66
Converting to draft until I resolve review comments. |
fc42616
to
ab0a7f3
Compare
Brought this back to life because I started working on #1809, please see re-written PR description. |
concept ACK. I think this is an improvement. I don't mind slipping it into this release since while it's API breaking, few users are poking around inside of |
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.
ACK ab0a7f3
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 think the second commit needs another struct SegwitProgram with private fields instead of a public enum
bitcoin/src/address.rs
Outdated
/// Witness version (version byte of the scriptPubkey). | ||
version: WitnessVersion, | ||
/// Witness program (as defined by BIP141). | ||
program: WitnessProgram, |
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 think Kix is right here. We can create the following invalid value for the Payload type.
let prog = WitnessProgram::new(WitnessVersion::V2, &[0x02; 31]).unwrap(); //31 bytes v2 progs are okay
let payload = Payload::Segwit {version: WitnessVersion::V0, program: prog}; // 31 bytes v0 are incorrect.
Ah, good point. I rescind my ACK. |
Cool, will fix. Thanks |
From BIP 141: > A scriptPubKey (or redeemScript as defined in BIP16/P2SH) that > consists of a 1-byte push opcode (for 0 to 16) followed by a data push > between 2 and 40 bytes gets a new special meaning. The value of the > first push is called the "version byte". The following byte vector > pushed is called the "witness program". `WitnessVersion` and `WitnessProgram` are scriptPubkey concerns and scriptPubkey is basically synonymous with address so in one way it makes sense that these types are in `address` however we are in the process of overhauling the `Address` (and `AddressInner`) types so lets move the witness stuff to `script` and put it in individual sub-modules. This move helps simplify the address error type also. Note please, there are a bunch of formatting changes in here in the error type that I cannot explain and could not remove.
Add rustdocs to `WitnessProgram` commenting on why we carry the witness version number around with the witness program. This is mainly a dev comment but it helps document the invariants so make it a rustdoc comment.
ab0a7f3
to
552f19a
Compare
Changes in force push:
This PR is still an API breaking change because |
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.
ACK 552f19a
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.
ACK 552f19a
This is done as part of an ongoing effort to improve the
address
module andAddress
type.WitnessVersion
andWitnessProgram
to their own modules withinscript
- this is code move only except for the variant changes to theaddress::Error
enum (see note below onrustfmt
acting up).WitnessProgram
Note on
rustfmt
There are a bunch of formatting changes that shouldn't be in here, I stashed and re-ran the formatter a bunch of times but for some reason
rustfmt
wouldn't changeaddress
as it is but after I patched itrustfmt
made a bunch of changes.