Skip to content

Conversation

Sjors
Copy link
Member

@Sjors Sjors commented Feb 10, 2022

  • HWI returns the requested address: as a sanity check, we now compare that to what we expected
    • external signer documentation now reflects that HWI alternatives must implement this check
  • both RPC and GUI will now return an error text, rather than just fail (the GUI even failed silently in some cases)

@DrahtBot
Copy link
Contributor

DrahtBot commented Feb 11, 2022

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage

For detailed information about the code coverage, see the test coverage report.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK brunoerg, achow101
Approach ACK jonatack

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #bitcoin-core/gui/700 (Dialog for allowing the user to choose the change output when bumping a tx by achow101)

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.

Copy link
Member

@jonatack jonatack left a comment

Choose a reason for hiding this comment

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

Approach ACK


if (ret_address.getValStr() != EncodeDestination(dest)) {
return strprintf(_("Signer echoed unexpected address %s"), ret_address.getValStr());
}
Copy link
Member

@jonatack jonatack Feb 11, 2022

Choose a reason for hiding this comment

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

Tests of these new errors would be nice, not sure how feasible this would be.

Copy link
Member Author

Choose a reason for hiding this comment

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

This particular one should be doable.

Copy link
Member Author

Choose a reason for hiding this comment

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

Added.

Comment on lines 66 to 70
const UniValue& ret_address = find_value(result, "address");
if (!ret_address.isStr()) return _("Signer did not echo address");
Copy link
Member

Choose a reason for hiding this comment

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

Won't this break older external signers?

Copy link
Member Author

Choose a reason for hiding this comment

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

HWI has always done this, we just didn't check. That said, it's not (yet) in the spec (which may be a bit outdated) so other signer software might not do this. Do you know of any? cc @achow101

https://github.com/bitcoin/bitcoin/blob/master/doc/external-signer.md#displayaddress-optional

Copy link
Member

Choose a reason for hiding this comment

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

AFAIK there aren't any other external signer software yet.

@Sjors
Copy link
Member Author

Sjors commented Jun 23, 2022

Rebased and addressed comments.

I could change "Signer did not echo address" from an error to a warning. However I'd rather only do this is we know there is an HWI clone out there that relies on the (less safe) earlier behavior. I updated the documentation. See also #24313 (comment).

@Sjors
Copy link
Member Author

Sjors commented Oct 26, 2022

Rebased after #23578.

@Sjors
Copy link
Member Author

Sjors commented May 8, 2023

Rebased and tested that it still works.

@brunoerg
Copy link
Contributor

Concept ACK

@DrahtBot DrahtBot requested a review from jonatack December 18, 2023 14:41
@@ -52,15 +53,19 @@ ExternalSigner ExternalSignerScriptPubKeyMan::GetExternalSigner() {
return signers[0];
}

bool ExternalSignerScriptPubKeyMan::DisplayAddress(const CScript scriptPubKey, const ExternalSigner &signer) const
bool ExternalSignerScriptPubKeyMan::DisplayAddress(const CTxDestination& dest, const ExternalSigner &signer) const
{
// TODO: avoid the need to infer a descriptor from inside a descriptor wallet
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you intend to address this TODO?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not in this PR, unless someone else gives me the code for it :-)

@@ -2644,7 +2644,7 @@ bool CWallet::DisplayAddress(const CTxDestination& dest)
ExternalSigner signer = ExternalSignerScriptPubKeyMan::GetExternalSigner();
return signer_spk_man->DisplayAddress(dest, signer);
}
return false;
return util::Error{_("No external signer ScriptPubKeyManager")};
Copy link
Contributor

Choose a reason for hiding this comment

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

In 5536ace: I think we can improve the "No external signer ScriptPubKeyManager" message, it doesn't sound intuitive. First time I tested it prior reading the code, I got this error and I thought I didn't have any external signer, so I checked it with enumerate.

Perhaps: "There is no ScriptPubKeyManager for this address".

Copy link
Member Author

Choose a reason for hiding this comment

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

Will consider new wording if I need to touch / rebase.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

@brunoerg
Copy link
Contributor

brunoerg commented Dec 22, 2023

I tested it with HWI and Ledger Nano S Plus.


  • I created a wallet:
./src/bitcoin-cli -named createwallet wallet_name=ledger3 disable_private_keys=true descriptors=true external_signer=true`
  • Got a new address:
$ ./src/bitcoin-cli -rpcwallet=ledger3 getnewaddress
bc1qfshzjl770c6qz560cade6ynswj2a3scqzm4a4m
  • Ran walletdisplayaddress:
$ ./src/bitcoin-cli -rpcwallet=ledger3 walletdisplayaddress "bc1qfshzjl770c6qz560cade6ynswj2a3scqzm4a4m"
  • Checked it in the Ledger device:
  • I locked the Ledger device and tried walletdisplayaddress to check the error message:

This PR:
'/Users/bg/projects/HWI/hwi.py' error: Could not open client or get fingerprint information: Exception: invalid status 0x6982

Master:
'/Users/brunogarcia/projects/HWI/hwi.py' error: Could not open client or get fingerprint information: Exception: invalid status 0x6982


  • Ran walletdisplayaddress with a random address:

On master:

error code: -1
error message:
Failed to display address

This PR:

error code: -1
error message:
No external signer ScriptPubKeyManager

@Sjors
Copy link
Member Author

Sjors commented Dec 22, 2023

Mmm, on the bright side, both the master and this PR have a really unclear message when the device is not connected or locked :-)

I'll try to improve that.

@Sjors
Copy link
Member Author

Sjors commented Dec 22, 2023

@achow101 any thoughts on having HWI catch this cryptic 0x6982 status code and throw a more clear error (that we can then just pass on to the user)?

@brunoerg
Copy link
Contributor

@achow101 any thoughts on having HWI catch this cryptic 0x6982 status code and throw a more clear error (that we can then just pass on to the user)?

Not sure, but this status code is specific from Ledger?

@Sjors
Copy link
Member Author

Sjors commented Dec 22, 2023

@brunoerg most likely yes, but I can't find a full list anywhere.

@brunoerg
Copy link
Contributor

brunoerg commented Dec 22, 2023

@brunoerg most likely yes, but I can't find a full list anywhere.

Me either. I've some of them but I manually mapped.


edit: I found them in HWI:

class DeviceException(Exception):  # pylint: disable=too-few-public-methods
    exc: Dict[int, Any] = {
        0x6985: DenyError,
        0x6982: SecurityStatusNotSatisfiedError,
        0x6A80: IncorrectDataError,
        0x6A82: NotSupportedError,
        0x6A86: WrongP1P2Error,
        0x6A87: WrongDataLengthError,
        0x6D00: InsNotSupportedError,
        0x6E00: ClaNotSupportedError,
        0xB000: WrongResponseLengthError,
        0xB007: BadStateError,
        0xB008: SignatureFailError,
        0xE000: InterruptedExecution,  # not an error
    }

achow101 added a commit to bitcoin-core/HWI that referenced this pull request Jan 17, 2024
0d5412a Improve error handle for `Ledger` devices (Bruno Garcia)

Pull request description:

  Discovered it while reviewing [#bitcoin/24313](bitcoin/bitcoin#24313). The `ledger_exception` function was not dealing with `ApduException` exceptions. It's basically similar to `BTChipException` and we can use its "error code" to return friendly error messages.

  e.g for `displayaddress`:

  **before**:
  `{"error": "Exception: invalid status 0x6985", "code": -13}`
  **after**:
  `{"error": "display_singlesig_address canceled", "code": -14}`

ACKs for top commit:
  achow101:
    ACK 0d5412a

Tree-SHA512: f4dbe57e5f41c67a19ce6e9c0f4b4af8184ff360cfc3709f4fb15f55014906c0a6c04a869a9315083aac18175dd8b921c022d18826d3e1f31d4bdb4a736b6171
@Sjors Sjors force-pushed the 2022/02/displayaddress branch from 5536ace to d38ddc1 Compare February 13, 2024 12:35
@Sjors
Copy link
Member Author

Sjors commented Feb 13, 2024

Rebased to give CI another try.

HWI now returns better errors, though I have not yet tested it here.

@Sjors
Copy link
Member Author

Sjors commented Feb 16, 2024

Tested with HWI 2.4.0

When a Ledger Nano X is in screen saver mode, I now get the following error:

'...hwi' error: Could not open client or get fingerprint information: ('0x5515', 'Error in <DefaultInsType.GET_VERSION: 1> command', '')

That's what HWI returns, so can't make it much better...

When the Bitcoin app is not opened on the device the error is more clear:

'...hwi' error: Could not open client or get fingerprint information: Ledger is not in either the Bitcoin or Bitcoin Testnet app

Sjors added 3 commits April 16, 2024 17:47
Update external signer documentation to reflect this requirement, which HWI already implements.
Both RPC and GUI now render a useful error message instead of (silently) failing.

Replace bool with util::Result<void> to clarify that this either succeeds or returns an error message.
@Sjors Sjors force-pushed the 2022/02/displayaddress branch from d38ddc1 to 4357158 Compare April 16, 2024 16:00
@Sjors
Copy link
Member Author

Sjors commented Apr 16, 2024

Rebased after #28981 (I previously already tested on top of that).

Briefly tested with HWI 3.0 as well on a Ledger Nano X.

@Sjors Sjors requested a review from brunoerg April 16, 2024 16:01
@brunoerg
Copy link
Contributor

brunoerg commented Apr 17, 2024

ACK 4357158

I did same test as #24313 (comment) but with the latest version of HWI.

./src/bitcoin-cli -rpcwallet=ledger7 walletdisplayaddress "bc1qfshzjl770c6qz560cade6ynswj2a3scqzm4a4m"
error code: -1
error message:
'/Users/brunogarcia/projects/HWI/hwi.py' error: Could not open client or get fingerprint information: Ledger is not in either the Bitcoin or Bitcoin Testnet app
./src/bitcoin-cli -rpcwallet=ledger7 walletdisplayaddress "randomaddresshere"
error code: -1
error message:
There is no ScriptPubKeyManager for this address

@DrahtBot DrahtBot requested a review from achow101 April 17, 2024 18:06
@achow101
Copy link
Member

ACK 4357158

@achow101 achow101 merged commit a7129f8 into bitcoin:master Apr 23, 2024
@Sjors Sjors deleted the 2022/02/displayaddress branch May 6, 2024 12:47
@bitcoin bitcoin locked and limited conversation to collaborators May 6, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants