-
Notifications
You must be signed in to change notification settings - Fork 36.2k
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
Descriptor: add GetAddressType() and IsSegWit() #15590
Conversation
f79d057
to
3d63978
Compare
3d63978
to
4371f3a
Compare
The |
I don't think this makes sense. The address type is a property of a scriptPubKey, not of a descriptor (in particular, it's not well defined for You can already determine the address type of a scriptPubKey using ExtractDestination(). |
c73ff9f
to
5efb75e
Compare
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. |
5efb75e
to
5e0913d
Compare
5e0913d
to
44a2e1f
Compare
44a2e1f
to
73d62d8
Compare
@Sjors can you respond to sipa? I agree with him that this isn't really a property of descriptors, but I haven't looked into whether this makes your future work heaps easier or not. If not, let's close this :) |
I still use this inside #16546 for external signer support. However that PR is built on top of descriptor wallet support #15764 which is still in flux. So it's probably more useful to discuss again when that's ready. The use case here is that we obtain descriptors from a hardware wallet, e.g. via the HWI getdescriptors call. This might be a mix of BIP44/49/84 descriptors. We then need to match those to the right output type in our wallet. That way if a user requests a legacy address, we give them a BIP44 derived address, vs. when they request a native segwit address, we'll give them a BIP84 derived address. In order to match the right descriptor with the the right output type we need to parse it. I don't think it makes sense to start with a descriptor string, derive a random destination, get its script and then analyse that script to figure out if it's SegWit. The information is already in the descriptor string, so I think we should just use that. |
Perhaps in that case, it would be better to make a "CanProvideAddressTypeX" which takes a descriptor and an address type and returns a bool. Roughly provides the same functionality but makes more logical sense to me. Can't HWI just tell the wallet which descriptor it wants to use for which address type though? |
The first suggestions seems doable, but not sure why it's better. By address type you mean OutputType? It seems less flexible though, as in the longer run I don't know if we really want to hold on to OutputType. E.g. multisig would likely only use bech32 and wrapped segwit, not legacy p2sh or bare multisig. All we need is the new AddressType to distinguish those. I can also imagine adding IsTaproot later, at which point our OutputType bech32 would be ambiguous. I'd like to keep HWI universal, not too Core specific. The only universal way we currently have to describe an address type is a descriptor. |
What exactly is the utility of knowing whether the address type is base58 or bech32? I don't think we have many things that depend on the encoding. Rather what we care about is the OutputType. |
@achow101 my initial thinking was to stuff OutputType in the legacy box, along with its When sharing an address, the distinction between base58 and bech32 is all that matters. So ideally I'd like to see a world where A standard wallet would have two descriptors instead of three: native segwit and wrapped segwit. If someone doesn't want to use SegWit, they can create a wallet with a single P2PKH descriptor; such a wallet can only generate a base58 address. |
While it would be nice to just have the distinction be between base58 and bech32, I don't think we are going to lose the "legacy" distinction any time soon. Besides the whole backwards compatibility thing, there are still holdouts who insist on legacy addresses. This also gets more complicated with taproot which don't allow for P2SH wrapped addresses. Even with just a base58 or bech32 address distinction, we would still need to distinguish between segwit v0 and segwit v1 addresses because inevitably someone will have implemented segwit incorrectly and can't send to v1 addresses. |
Yikes, there are services that refuse to send to p2sh? Do you have an example?
Sadly that's conceivable... Especially since early on there was a recommendation to only allow v0. |
Closing in favor of #18034 |
In preparation for descriptor based wallets (e.g. #15487) it's useful to distinguish between base58 and base32 addresses. One descriptor could be associated with
getnewaddress "" bech32
and another withgetnewaddress "" legacy
(which is interpreted as "base58", rather than as non-SegWit).This PR introduces a new enum
AddressType
, along with a parser that returns an Optional. A new methodGetAddressType()
is added toDescriptor
instances. The only purpose ofAddressType
is compatibility with other wallets, not a way to toggle SegWit.Reusing
OutputType
would not be ideal for this, because the distinction betweenOutputType::LEGACY
(-addresstype=legacy
) andOutputType::P2SH_SEGWIT
(-addresstype=p2sh-segwit
) is irrelevant in descriptor based wallets. Instead, if someone does not wish to use SegWit, they can create a wallet with only a non-SegWit descriptor.This is also useful for importing keys from a hardware wallet. In the current WIP #14912 there is a method
signerfetchkeys
which asks the device (driver) to return a set of descriptors. This returns e.g. three descriptors: one for BIP44 (legacy), one for BIP49 (p2sh-segwit) and one for BIP84 (native segwit). It can then associate the BIP84 descriptor withgetnewaddress "" bech32
.It can then use either the BIP44 or BIP49 descriptor with
getnewaddress "" legacy
. To distinguish those, this PR addsIsSegWit()
to Descriptor instances.The
boost/optional/optional_io.hpp
IO include allows for a more compact notation in the tests:BOOST_CHECK_EQUAL(ParseAddressType("bech32"), AddressType::BECH32)
.