Skip to content

Address type dropdown, add Taproot (Receive tab) #459

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

Merged
merged 2 commits into from
Dec 22, 2021

Conversation

Sjors
Copy link
Member

@Sjors Sjors commented Oct 29, 2021

This PR replaces the Bech32 checkbox with an address type dropdown It "Use Taproot" checkbox to the receive screen for any wallet with a Taproot descriptor. The Bech32m option is hidden for wallets that don't have taproot descriptors.

Bech32 is kept as the default even for Taproot enabled wallets until it's more widely supported.

(an earlier attempt of this PR added a second checkbox)

Schermafbeelding 2021-12-21 om 11 44 05

Suggested testing

  • notice that the Bech32m entry only appears for wallet with a taproot descriptor
  • verify that it generates a bc1p instead of bc1q address
  1. Legacy wallet
  2. Default descriptor wallet (current does not have taproot descriptor)
  3. Wallet with taproot descriptor:
    • just create a new descriptor wallet

Replaces bitcoin/bitcoin#22260

@Sjors Sjors changed the title Use Taproot checkbox for receive tab Add Taproot checkbox to receive tab Oct 29, 2021
@Sjors Sjors force-pushed the 2021/10/taproot_gui branch from 943fb5e to f04337e Compare October 29, 2021 12:41
Copy link
Member

@luke-jr luke-jr left a comment

Choose a reason for hiding this comment

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

Kinda ugly to have two mutually-exclusive (logically) checkboxes between Legacy/Bech32 and ???/Bech32m...

Probably should just make the existing checkbox a combobox or something?

@Sjors
Copy link
Member Author

Sjors commented Oct 29, 2021

They're not mutually exclusive. I'm intentionally trying not to bother the user with the distinction between bech32 and bech32m (except in the tooltip). The bech32 button covers both. The new button is about using Taproot, as opposed to v0 SegWit. If you uncheck bech32 it will disable the Taproot checkbox, because there is no p2sh version of taproot.

@luke-jr
Copy link
Member

luke-jr commented Oct 29, 2021

IMO having 2 checkboxes like this is even more confusing.

@Sjors
Copy link
Member Author

Sjors commented Oct 30, 2021

We could show all address types: legacy, p2sh-segwit, SegWit v0 and Taproot. Perhaps the least confusing way to do that would be a dropdown that defaults to SegWit v0.

@ghost
Copy link

ghost commented Oct 31, 2021

We could show all address types: legacy, p2sh-segwit, SegWit v0 and Taproot. Perhaps the least confusing way to do that would be a dropdown that defaults to SegWit v0.

This makes sense

@sipa
Copy link
Contributor

sipa commented Oct 31, 2021

I think it's wrong to have it list "taproot" explicitly (or witness v0, for that matter); in descriptor wallets that's an implementation aspect the user shouldn't care about. What they care is legacy(base58) vs. bech32 vs bech32m, as those correspond to what senders supports. If a witness v2 softfork were to occur, hopefully bech32m can be reused unmodified for its addresses.

The OutputType isn't called TAPROOT for a reason; it's BECH32M because that's what senders care about. In a descriptor wallet, the wallet configuration determines which addresses are used for which outputtype.

FWIW, I think we should get rid of the LEGACY/P2SH_SEGWIT OutputTypes, and merge them into a BASE58 one or so.

@@ -458,6 +458,11 @@ class WalletImpl : public Wallet
bool canGetAddresses() override { return m_wallet->CanGetAddresses(); }
bool hasExternalSigner() override { return m_wallet->IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER); }
bool privateKeysDisabled() override { return m_wallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS); }
bool taprootEnabled() override {
if (m_wallet->IsLegacy()) return false;
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this special case needed? Wouldn't it return nullptr below?

Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe not, but since legacy wallets don't have descriptors, it does seem cleaner.

@maflcko
Copy link
Contributor

maflcko commented Nov 1, 2021

FWIW, I think we should get rid of the LEGACY/P2SH_SEGWIT OutputTypes, and merge them into a BASE58 one or so.

In that case we should also never ever send change to LEGACY again, unless manually done so by the user?

@luke-jr
Copy link
Member

luke-jr commented Nov 1, 2021

Then how do users continue avoiding Segwit? (Perhaps there's no reason to avoid Taproot, but there isn't a Base58 option for that, and it requires a new wallet)

@Sjors
Copy link
Member Author

Sjors commented Nov 1, 2021

Based on the above discussion, I'm starting to like my own approach more :-)

In the long run, e.g. by the time there's a SegWit v2 softfork, I'm hoping the distinction between bech32 and bech32m is no longer relevant because the ecosystem supports both. But my guess is that we'll have a transitional period between when that soft-fork activates and when we feel comfortable using it by default.

On the way to that future we have this Taproot checkbox, presenting it as a new feature. In a later release we make it the default.

Then, unless there is strong opposition to using Taproot, we drop the checkbox altogether. At that point the interface is back where it was before the PR. "bech32" would then mean "bech32m" and we could even rename it. Unchecking it would produce a p2sh-segwit address which should only be needed when dealing with dinosaur exchanges.

The story then repeats for a future SegWit v2 soft fork: we first add a check-box to opt-in, make it the default and then later drop the checkbox.

@sipa
Copy link
Contributor

sipa commented Nov 1, 2021

@luke-jr I just think the choice of what script construction is used should be a wallet-level configuration option, not something selected at address creation time. In descriptor wallets the answer would be: if you want P2PKH, you use a pkh descriptor for the base58 address descriptor. For legacy wallets it could be a config option or so.

@ajtowns
Copy link
Contributor

ajtowns commented Nov 2, 2021

@sipa That sounds to me like there should be some extra wallet-level configuration option that says "for base58 addresses, I know I can sign for both pkh(X) and sh(wpkh(X)) for both receiving(non-internal) and change(internal), but I prefer pkh(X)". eg if you upgrade to segwit, receive some funds via sh(wpkh(X)) then decide you don't like segwit and want to keep using pkh(X) by preference, not having that option would mean you'd have to move the sh(wpkh(X)) descriptor to a different wallet, which would probably be pretty annoying. And I think you'd get similar scenarios if you come up with new descriptors (eg switching between 4/5 and 3/5 to sign, or a musig threshold vs a checkmultisig threshold) then decided you didn't really like them.

@Sjors Having an "address type" drop down of:

  • base58 (legacy)
  • bech32 (segwit)
  • bech32m (taproot)

(matching -addresstype) seems like it would be better to me? Implying that taproot uses bech32 is a bit misleading and seems likely to cause confusion even with a tool tip...

With the "I prefer descriptor X for bech32 addresses" option above, you don't need to do anything when "segwit v2" comes along -- that just adds a new descriptor that you won't generate addresses for until you update your config to say you prefer it.

(I don't think the gui really needs a "use this specific descriptor to generate this address"; if you want to be that fine-grained, use the deriveaddresses RPC?)

Maybe also upgrade -addresstype to be something settable in the gui as well?

@achow101
Copy link
Member

achow101 commented Nov 2, 2021

I would also prefer that this use a drop down rather than adding more boolean options.

@Rspigler
Copy link
Contributor

Rspigler commented Nov 4, 2021

tACK

  1. v22.0 Legacy: Address option is Native Segwit/Bech32 checkbox (defaults to enabled). p2sh-segwit address generated if unchecked.

  2. v22.0 Descriptor Wallet. Same options/addresses, but with external/internal pkh, sh-wpkh, and wpkh descriptors.

  3. PR wallet: Make a tr() descriptor by default bitcoin/bitcoin#22364: Again same options, but generates external/internal pkh, sh-wpkh, wpkh, and now tr descriptors (if descriptor wallet created).

  4. PR Address type dropdown, add Taproot (Receive tab) #459 + wallet: Make a tr() descriptor by default bitcoin/bitcoin#22364: Checkboxes for Native Segwit/Bech32 and Taproot (as pictured in OP). When both enabled, generates bech32m address from tr descriptor. With just Native Segwit/Bech32 enabled, bech32 address generated from wpkh descriptor, as expected. Unchecking Native Segwit/Bech32 disables 'Use Taproot', and generates p2sh-segwit address from sh-wpkh descriptor.

I also agree that a dropdown would be better. While Taproot is a segwit version, I don't think the end user needs to be burdened with this fact by how it is currently set up. I like @ajtowns suggestion for Address_Format (Soft Fork Name). But maybe it'd be better as:

base58 (Segwit)
bech32 (Native Segwit)
bech32m (Taproot)

Unless you wanted to include a legacy as well as p2sh-segwit address option.

This labeling format also allows the distinction @Sjors was looking for in a future Segwit v2 softfork, if bech32m format is reused:

...
bech32m (taproot)
bech32m (future_fork)

If @sipa wants this to be a wallet level config option, maybe the user's preference can be set there for the default, but then can still be changed at address creation time if necessary.

@Sjors
Copy link
Member Author

Sjors commented Nov 4, 2021

How about:

base58 (legacy)
base58 (p2sh-Segwit)
bech32 (Segwit)
bech32m (Taproot)

@Rspigler
Copy link
Contributor

Rspigler commented Nov 4, 2021

Should we include a legacy address option if it has already been deprecated in the GUI?

@luke-jr
Copy link
Member

luke-jr commented Nov 4, 2021

It's curious that people are treating "base58" as if it's a single address type. The difference between single-key base58 and P2SH is similar to the difference between Bech32 and Bech32m ;)

@sipa
Copy link
Contributor

sipa commented Nov 9, 2021

It's curious that people are treating "base58" as if it's a single address type. The difference between single-key base58 and P2SH is similar to the difference between Bech32 and Bech32m ;)

You're right; they're different formats for the purpose of senders. What unites them is the fact that both have been around for nearly 10 years.

@Sjors Sjors force-pushed the 2021/10/taproot_gui branch from f04337e to e2981cc Compare November 14, 2021 18:19
@hebasto hebasto added UX All about "how to get things done" Wallet labels Nov 21, 2021
@Sjors Sjors force-pushed the 2021/10/taproot_gui branch from e2981cc to ab1e59d Compare December 8, 2021 11:10
@Sjors Sjors changed the title Add Taproot checkbox to receive tab Address type dropdown, add Taproot (Receive tab) Dec 8, 2021
@Sjors Sjors force-pushed the 2021/10/taproot_gui branch from ab1e59d to 4c87ff0 Compare December 8, 2021 11:16
Copy link
Contributor

@kristapsk kristapsk left a comment

Choose a reason for hiding this comment

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

ACK 4c87ff0 (tested on signet with both descriptors and legacy wallets).

@Sjors
Copy link
Member Author

Sjors commented Dec 9, 2021

(it's now a dropdown)

@Sjors Sjors force-pushed the 2021/10/taproot_gui branch from 4c87ff0 to f5ba3d9 Compare December 9, 2021 08:59
ui->useBech32->setCheckState(Qt::Unchecked);
// Populate address type dropdown and select default
ui->addressType->insertItem((int)OutputType::LEGACY, "Base58 (Legacy)");
ui->addressType->setItemData((int)OutputType::LEGACY, "Not recommended due to higher fees and less protection against typos.", Qt::ToolTipRole);
Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry to bike-shed, but this wasn't exposed previously through the gui. Adding Taproot addresses seems an odd reason to start offering this again for the average user. Experts that really want this can still use the gui rpc console.

For our GUI users, I expect that less options here is beneficial.

Copy link
Member Author

@Sjors Sjors Dec 10, 2021

Choose a reason for hiding this comment

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

It becomes a problem when the user sets -addresstype=legacy, because then nothing would be selected by default. Previously the checkbox would toggle between legacy and bech32 in that case. This was by design, though not well documented: bitcoin/bitcoin#11991 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

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

When unchecked, -addresstype=legacy would map to p2sh-witness in the GUI, not legacy. So I think we should preserve that, no?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think Bitcoin Core users are already above average Bitcoin users and mostly know what they are doing, don't think we should limit people from creating legacy P2PKH addresses, if they want to.

Copy link
Contributor

Choose a reason for hiding this comment

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

No one has been using this for the past 4 years, and I am not aware of anyone complaining about the lack of it? So it seems odd to add an option that has no use case.

Copy link
Contributor

Choose a reason for hiding this comment

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

I have used this by using RPC. Would have used in GUI if it would have been available.

Copy link
Member Author

@Sjors Sjors Dec 10, 2021

Choose a reason for hiding this comment

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

Correction, the checkbox is not disabled on master when using -addresstype=legacy. The original PR description was wrong (or the behavior was changed later).

On master you can test that, when launched with -addresstype=legacy, it would produce a P2PKH address, not wrapped segwit. This happened in the code below:

Schermafbeelding 2021-12-10 om 19 45 45

Notice also that this logic leads to a bug for anyone who sets -addresstype=bech32m; it would then fall back to P2PKH instead of wrapped SegWit when unchecked. So introducing this dropdown is probably a good idea in any case (or just add || address_type == OutputType::BECH32M).

IIRC @luke-jr at the time requested the ability to opt out of SegWit entirely. But I don't know how many people actually knew of this behaviour.

@bitcoin-core bitcoin-core deleted a comment Dec 9, 2021
Copy link
Contributor

@maflcko maflcko left a comment

Choose a reason for hiding this comment

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

ACK

Copy link
Contributor

@kristapsk kristapsk left a comment

Choose a reason for hiding this comment

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

re-ACK f5ba3d9

GUI changes
-----------

- The Bech32 checkbox has been replaced with a dropdown for all address types, including the new Bech32m (BIP-350) standard for Taproot enabled wallets. The default remains Bech32 (SegWit).
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
- The Bech32 checkbox has been replaced with a dropdown for all address types, including the new Bech32m (BIP-350) standard for Taproot enabled wallets. The default remains Bech32 (SegWit).
- The Bech32 checkbox has been replaced with a dropdown for all address types, including the new Bech32m (BIP-350) standard for Taproot enabled wallets.

nit: I don't think we need to mention stuff that doesn't change. Also, this is wrong? The default is whatever -addresstype is set to?

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed

@Sjors Sjors force-pushed the 2021/10/taproot_gui branch from f5ba3d9 to 79580c0 Compare December 13, 2021 11:54
Copy link
Contributor

@promag promag left a comment

Choose a reason for hiding this comment

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

Tested ACK 79580c0.

My only comment is that combo box entries are mapped to OutputType values - meaning we can't reorder. The following commit uses UserRole to store the type instead of combo box index promag@b164039 (https://github.com/promag/gui/tree/pr/459).

@Sjors
Copy link
Member Author

Sjors commented Dec 13, 2021

@promag thanks! Let's keep that commit in mind in case we actually want to reorder, which I don't think is very likely.

@Sjors Sjors force-pushed the 2021/10/taproot_gui branch from 79580c0 to 11e8024 Compare December 13, 2021 12:48
@Sjors
Copy link
Member Author

Sjors commented Dec 13, 2021

OTOH it actually looks a bit cleaner too, so I squashed it in

@Rspigler
Copy link
Contributor

Will re-test

@Rspigler
Copy link
Contributor

I like the way this looks, but there is a typo in 1 tooltip, and I think other tooltips can be improved.

Base58 (Legacy): "Not recommended due to higher fees and less protection against typos." -> "Not recommended."
It is also not recommended b/c of security issues with multisig, and scaling issues. No reason to list them all. If an advanced user wants to use an old address, they will know why they need it.

Base58 (P2SH-SegWit): "Generates an address compatible with older wallets." ✔️

Bech32 (SegWit): "Generates a native segwit addresses (BIP-173), which reduces your transaction fees later on and offers better protection against typos, but some old wallets don't support it." There is a typo: "Generates a native segwit addresses"->"Generates a native segwit address". This is also a very long tooltip and looks bad IMO. Perhaps:
"Generates a native segwit address (BIP-173) which offers various improvements."

Bech32m (Taproot): "Although Bech32m (BIP-350) looks similar to Bech32, there is a slight difference and only some newer wallets support it." I don't see a reason to take up space discussing how it looks, but I can't think of any improvement to offer right now that sounds good, other than basically what is said for SegWit 😬

Sjors and others added 2 commits December 21, 2021 11:31
Co-authored-by: João Barbosa <joao.paulo.barbosa@gmail.com>
@Sjors
Copy link
Member Author

Sjors commented Dec 21, 2021

I fixed the typos and shortened the tooltips a bit.

security issues with multisig

That's not an issue for PKH (1...) addresses.

Scaling is a problem for the ecosystem, but the two issues I put in the tooltip (fees and typo protection) are relevant to individual users. If they encounter a wallet or service insisting on this, they should be appropriately annoyed :-)

Bech32 (SegWit)
This is also a very long tooltip and looks bad IMO

I agree it looks ugly, but that's mainly because I wasn't able to add line breaks. That might be fixable though.

It's a bit shorter now.

I don't see a reason to take up space discussing how it looks

I reworded it a bit. The problem is that a user will put the bech32m address into a different wallet / exchange and get an error message like "Invalid (bech32) address".

@Sjors Sjors force-pushed the 2021/10/taproot_gui branch from 11e8024 to c9a77e2 Compare December 21, 2021 04:45
@Rspigler
Copy link
Contributor

tACK c9a77e2. I like the changes made now, thanks!

Copy link
Contributor

@kristapsk kristapsk left a comment

Choose a reason for hiding this comment

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

re-ACK c9a77e2

@maflcko maflcko merged commit 63b5dfa into bitcoin-core:master Dec 22, 2021
ui->addressType->setItemData(index, tooltip, Qt::ToolTipRole);
if (model->wallet().getDefaultAddressType() == type) ui->addressType->setCurrentIndex(index);
};
add_address_type(OutputType::LEGACY, "Base58 (Legacy)", "Not recommended due to higher fees and less protection against typos.");
Copy link
Contributor

Choose a reason for hiding this comment

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

This is missing a check (like the one for taproot)?

Locally, I am getting:

Screenshot from 2021-12-22 12-26-46

Copy link
Member Author

Choose a reason for hiding this comment

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

I assume you manually created a wallet without a pkh() descriptor? We could add checks for the existence of each output type to the interface and then remove them from the dropdown. However, if someone manually creates a wallet, they would also understand the error message, and it might even better than a missing item?

};
add_address_type(OutputType::LEGACY, "Base58 (Legacy)", "Not recommended due to higher fees and less protection against typos.");
add_address_type(OutputType::P2SH_SEGWIT, "Base58 (P2SH-SegWit)", "Generates an address compatible with older wallets.");
add_address_type(OutputType::BECH32, "Bech32 (SegWit)", "Generates a native segwit address (BIP-173). Some old wallets don't support it.");
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: maybe replace "wallets" with "services" or "third-party services" or "third-party wallets".

Otherwise the user might get confused into thinking that an old wallet.dat can't generate this, which is not true?

Copy link
Member Author

@Sjors Sjors Dec 23, 2021

Choose a reason for hiding this comment

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

I'm not sure if they're more likely to think of an upgrade scenario than about receiving coins from another wallet they have? "third-party" is a bit of an tech industry term, and probably doesn't translate well. Paging @jonatack.

("other, old, wallets" is more clear perhaps, though maybe not pretty)

sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Dec 22, 2021
…ve tab)

c9a77e2 gui: address type dropdown, add bech32m (Sjors Provoost)
56113da wallet: add taprootEnabled() to interface (Sjors Provoost)

Pull request description:

  This PR replaces the Bech32 checkbox with an address type dropdown It "Use Taproot" checkbox to the receive screen for any wallet with a Taproot descriptor. The Bech32m option is hidden for wallets that don't have taproot descriptors.

  Bech32 is kept as the default even for Taproot enabled wallets until it's more widely supported.

  (an earlier attempt of this PR added a second checkbox)

  <img width="469" alt="Schermafbeelding 2021-12-21 om 11 44 05" src="https://user-images.githubusercontent.com/10217/146872660-339fae1f-c0b8-4673-b8be-33c25f3933fd.png">

  **Suggested testing**
  * notice that the Bech32m entry only appears for wallet with a taproot descriptor
  * verify that it generates a bc1p instead of bc1q address
  1. Legacy wallet
  2. Default descriptor wallet (current does not have taproot descriptor)
  3. Wallet with taproot descriptor:
     * just create a new descriptor wallet

  Replaces bitcoin#22260

ACKs for top commit:
  Rspigler:
    tACK  c9a77e2.  I like the changes made now, thanks!
  kristapsk:
    re-ACK c9a77e2

Tree-SHA512: bae66ac90ed55372e6c94878db0e37d32b7b5c24ed00c0f2ebb10fd127dddce3a061162df915d67e92d7b35b3da093137db17b73931a0ae1a470fff20be1f30b
@Sjors Sjors deleted the 2021/10/taproot_gui branch December 23, 2021 02:36
RandyMcMillan pushed a commit to RandyMcMillan/gui that referenced this pull request Jan 27, 2022
c9a77e2 gui: address type dropdown, add bech32m (Sjors Provoost)
56113da wallet: add taprootEnabled() to interface (Sjors Provoost)

Pull request description:

  This PR replaces the Bech32 checkbox with an address type dropdown It "Use Taproot" checkbox to the receive screen for any wallet with a Taproot descriptor. The Bech32m option is hidden for wallets that don't have taproot descriptors.

  Bech32 is kept as the default even for Taproot enabled wallets until it's more widely supported.

  (an earlier attempt of this PR added a second checkbox)

  <img width="469" alt="Schermafbeelding 2021-12-21 om 11 44 05" src="https://user-images.githubusercontent.com/10217/146872660-339fae1f-c0b8-4673-b8be-33c25f3933fd.png">

  **Suggested testing**
  * notice that the Bech32m entry only appears for wallet with a taproot descriptor
  * verify that it generates a bc1p instead of bc1q address
  1. Legacy wallet
  2. Default descriptor wallet (current does not have taproot descriptor)
  3. Wallet with taproot descriptor:
     * just create a new descriptor wallet

  Replaces bitcoin/bitcoin#22260

ACKs for top commit:
  Rspigler:
    tACK  c9a77e2.  I like the changes made now, thanks!
  kristapsk:
    re-ACK c9a77e2

Tree-SHA512: bae66ac90ed55372e6c94878db0e37d32b7b5c24ed00c0f2ebb10fd127dddce3a061162df915d67e92d7b35b3da093137db17b73931a0ae1a470fff20be1f30b
@bitcoin-core bitcoin-core locked and limited conversation to collaborators Dec 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Feature UX All about "how to get things done" Wallet
Projects
None yet
Development

Successfully merging this pull request may close these issues.