-
Notifications
You must be signed in to change notification settings - Fork 38.8k
Get the OutputType for a descriptor #18034
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 following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
|
Do you have a use case for these? |
Sjors
left a comment
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. After some discussion in #15590 I think adding GetOutputType() to Descriptor is preferable over the approach there of adding GetAddressType() and IsSegWit().
I don't like the use of ExtractDestination though. Let's just determine the output type from the descriptor itself similar to #15590. That also avoids the next problem:
For simplicity,
ScriptHashdestinations areLEGACYeven though they could beP2SH_SEGWIT
This assumption breaks BIP49 descriptor import with HWI. See e.g. https://github.com/bitcoin/bitcoin/pull/16546/files#diff-b2bb174788c7409b671c46ccc86034bdR4359-R4378. This current uses GetAddressType() and IsSegWit(), and if I switched it to use GetOutputType() it would import the wrapped segwit descriptor as legacy.
db1e861 to
b4fcf7a
Compare
These only apply to |
Sjors
left a comment
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.
Code review ACK b4fcf7ad56d0981797a4424f38f0524275d26e59 modulo (an explanation for) the assert.
src/script/descriptor.cpp
Outdated
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 mind, but why are you making m_name public?
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 doesn't. The default visibility is private.
You should really see this change as moving m_subdescriptor_arg into the protected area rather than moving m_mame.
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.
Oops, I misread that move. That makes sense.
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.
However there's a warning:
script/descriptor.cpp:368:176: warning: field 'm_subdescriptor_arg' will be initialized after field 'm_name' [-Wreorder]
DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, std::unique_ptr<DescriptorImpl> script, const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_subdescriptor_arg(std::move(script)), m_name(name) {}
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 should be fixed now.
b4fcf7a to
079862d
Compare
079862d to
7e80f64
Compare
Sjors
left a comment
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.
Code review ACK 7e80f64
|
ACK 7e80f64 Reviewed code, built and ran tests locally. |
jonatack
left a comment
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 7e80f64 code review/build/tests
instagibbs
left a comment
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.
For simplicity, ScriptHash destinations are LEGACY even though they could be P2SH_SEGWIT.
This is not readily apparent to me as a reviewer or reader of the code why it's that way?
| { | ||
| switch (m_destination.which()) { | ||
| case 1 /* PKHash */: | ||
| case 2 /* ScriptHash */: return OutputType::LEGACY; |
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.
motivation for having ScriptHash be "LEGACY" which I think means p2pkh in most contexts?
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.
What else would it be?
I would consider just a P2SH scriptPubKey to be legacy if I had no information about the redeemScript.
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.
ahhhh this is addr(), ignore this.
|
@instagibbs I suppose the alternative is to treat |
|
utACK 7e80f64 I guess the same kind of complaint could apply here too, that the descriptor implementation shouldn't really be the thing worrying about how the destinations are encoded. But that's okay. I assume there is a use-case, even though promag's question was never responded to? I still don't really see the point of this, could you just quickly explain where this will be used? I had a quick look at #16528 and it isn't immediately clear to me that this PR made things easier there vs doing things a different way |
|
@meshcollider I also use this to determine how to import descriptors obtained with HWI: https://github.com/Sjors/bitcoin/blob/2020/02/external_signer_scriptpubkeyman/src/wallet/wallet.cpp#L4460-L4474 (rebase WIP of #16546 which previously used #15590) |
|
@meshcollider The use case is that in #16528, we need to be able to determine the And I guess @Sjors is using it for something. |
|
cursory ACK 7e80f64 |
7e80f64 Get the OutputType for a descriptor (Andrew Chow) Pull request description: Adds a `GetOutputType()` method to get the OutputType of a descriptor. Some descriptors don't have a determinate OutputType, so we actually use an `Optional<OutputType>`. For descriptors with indeterminate OutputType, we return `nullopt`. `addr()` and `raw()` use OutputTypes as determined by the CTxDestination they have. For simplicity, `ScriptHash` destinations are `LEGACY` even though they could be `P2SH_SEGWIT`. `combo()`, `pk()`, and `multi()` are `nullopt` as they either don't have an OutputType or they have multiple. `DescriptorImpl` defaults to `nullopt`. `pkh()` is `LEGACY` as expected `wpkh()` and `wsh()` are `BECH32` as expected. `sh()` checks whether the sub-descriptor is `BECH32`. If so, it is `P2SH_SEGWIT`. Otherwise it is `LEGACY`. The descriptor tests are updated to check the OutputType too. ACKs for top commit: fjahr: ACK 7e80f64 meshcollider: utACK 7e80f64 instagibbs: cursory ACK bitcoin@7e80f64 Sjors: Code review ACK 7e80f64 jonatack: ACK 7e80f64 code review/build/tests Tree-SHA512: c5a813447b62e982435e1c948066f8d6c148c9ebffb0a5eb5a9028b173b01d5ead2f076a5ca3f7f37698538baa346f82a977ee48f583d89cb4e5ebd9111b2341
7e80f64 Get the OutputType for a descriptor (Andrew Chow) Pull request description: Adds a `GetOutputType()` method to get the OutputType of a descriptor. Some descriptors don't have a determinate OutputType, so we actually use an `Optional<OutputType>`. For descriptors with indeterminate OutputType, we return `nullopt`. `addr()` and `raw()` use OutputTypes as determined by the CTxDestination they have. For simplicity, `ScriptHash` destinations are `LEGACY` even though they could be `P2SH_SEGWIT`. `combo()`, `pk()`, and `multi()` are `nullopt` as they either don't have an OutputType or they have multiple. `DescriptorImpl` defaults to `nullopt`. `pkh()` is `LEGACY` as expected `wpkh()` and `wsh()` are `BECH32` as expected. `sh()` checks whether the sub-descriptor is `BECH32`. If so, it is `P2SH_SEGWIT`. Otherwise it is `LEGACY`. The descriptor tests are updated to check the OutputType too. ACKs for top commit: fjahr: ACK 7e80f64 meshcollider: utACK 7e80f64 instagibbs: cursory ACK bitcoin@7e80f64 Sjors: Code review ACK 7e80f64 jonatack: ACK 7e80f64 code review/build/tests Tree-SHA512: c5a813447b62e982435e1c948066f8d6c148c9ebffb0a5eb5a9028b173b01d5ead2f076a5ca3f7f37698538baa346f82a977ee48f583d89cb4e5ebd9111b2341
Summary: Backport of Core [[bitcoin/bitcoin#18034 | PR18034]] Test Plan: ninja all check Reviewers: #bitcoin_abc, Fabien, majcosta Reviewed By: #bitcoin_abc, Fabien, majcosta Differential Revision: https://reviews.bitcoinabc.org/D8395
Adds a
GetOutputType()method to get the OutputType of a descriptor. Some descriptors don't have a determinate OutputType, so we actually use anOptional<OutputType>. For descriptors with indeterminate OutputType, we returnnullopt.addr()andraw()use OutputTypes as determined by the CTxDestination they have. For simplicity,ScriptHashdestinations areLEGACYeven though they could beP2SH_SEGWIT.combo(),pk(), andmulti()arenulloptas they either don't have an OutputType or they have multiple.DescriptorImpldefaults tonullopt.pkh()isLEGACYas expectedwpkh()andwsh()areBECH32as expected.sh()checks whether the sub-descriptor isBECH32. If so, it isP2SH_SEGWIT. Otherwise it isLEGACY.The descriptor tests are updated to check the OutputType too.