getdescriptorinfo returns unusable descriptor #29320

issue jsarenik openend this issue on January 25, 2024
  1. jsarenik commented at 5:20 pm on January 25, 2024: none

    Is there an existing issue for this?

    • I have searched the existing issues

    Current behaviour

    NOTE: Replace bch.sh below in the code with bitcoin-cli -signet.

    Let’s have a random new testnet descriptor wallet with following private descriptors:

    0~/.bitcoin/signet$ bch.sh listdescriptors true | jq .descriptors[].desc | tail -1
    1"wpkh(tprv8ZgxMBicQKsPdpPsVvhB5XZtRfRWGqH1uwJNmG27dQgDwTS76oCd3hKbn3zERUZjG2fCgdKe8rqT2NomNbCgGSUQ829rJkTLUWvGKzyHX7Z/84h/1h/0h/1/*)#duvgfk6y"
    

    I will use just the one on the last line.

    When the prvate descriptor above is used with getdescriptorinfo RPC call I get following:

    0~/.bitcoin/signet$ bch.sh getdescriptorinfo "wpkh(tprv8ZgxMBicQKsPdpPsVvhB5XZtRfRWGqH1uwJNmG27dQgDwTS76oCd3hKbn3zERUZjG2fCgdKe8rqT2NomNbCgGSUQ829rJkTLUWvGKzyHX7Z/84h/1h/0h/1/*)#duvgfk6y"
    1{
    2  "descriptor": "wpkh(tpubD6NzVbkrYhZ4XHRfPaMmUwDzzgwSSATvVEuA3n4R3gUcmwgsjC2DEBwTxB4qBjSBoofF3xKGAsQE3GhBDSFi6b8PcDwXLdEoNxrovTFmyYt/84h/1h/0h/1/*)#9zp9fyaf",
    3  "checksum": "duvgfk6y",
    4  "isrange": true,
    5  "issolvable": true,
    6  "hasprivatekeys": true
    7}
    

    When the just-returned descriptor is used in deriveaddress it ends with an error:

    0~/.bitcoin/signet$ bch.sh deriveaddresses "wpkh(tpubD6NzVbkrYhZ4XHRfPaMmUwDzzgwSSATvVEuA3n4R3gUcmwgsjC2DEBwTxB4qBjSBoofF3xKGAsQE3GhBDSFi6b8PcDwXLdEoNxrovTFmyYt/84h/1h/0h/1/*)#9zp9fyaf"  '[0,1]'
    1error code: -5
    2error message:
    3Cannot derive script without private keys
    

    If the wallet is queried by listdescriptors, just public, I get this for the same derivation path:

    0~/.bitcoin/signet$ bch.sh listdescriptors | jq .descriptors[].desc | tail -1
    1"wpkh([823c2027/84h/1h/0h]tpubDDPGZQssk8ekvcN85aXhvz5omhZdQPWcczP21RqCHw7i5ce89zgYHoxowE8HrUUi2XUr4Vv4x48Ykhw7JBCH6G8QUfgRRR9UPgbC74DdNC4/1/*)#spvfr65h"
    

    When I use the above just-returned public descriptor it derives addresses well:

    0~/.bitcoin/signet$ bch.sh deriveaddresses "wpkh([823c2027/84h/1h/0h]tpubDDPGZQssk8ekvcN85aXhvz5omhZdQPWcczP21RqCHw7i5ce89zgYHoxowE8HrUUi2XUr4Vv4x48Ykhw7JBCH6G8QUfgRRR9UPgbC74DdNC4/1/*)#spvfr65h" '[0,1]'
    1[
    2  "tb1qegtflj2zzv6wqwh0zgh7zeztv2ek6awsvz4fpk",
    3  "tb1qslc5s8gd5zd7fa3cj64zt7kmlnw348x6q6cg28"
    4]
    

    Expected behaviour

    I would expect also the getdescriptorinfo for the private descriptor to return a valid public descriptor usable for deriving addresses.

    Steps to reproduce

    0myderive() {
    1  bitcoin-cli -signet getdescriptorinfo "$1" | jq -r .descriptor | while read a; do bitcoin-cli -signet deriveaddresses "$a" '[0,1]'; done
    2}
    3
    4myderive "wpkh(tprv8ZgxMBicQKsPdpPsVvhB5XZtRfRWGqH1uwJNmG27dQgDwTS76oCd3hKbn3zERUZjG2fCgdKe8rqT2NomNbCgGSUQ829rJkTLUWvGKzyHX7Z/84h/1h/0h/1/*)#duvgfk6y"
    5# above fails
    6
    7myderive "wpkh([823c2027/84h/1h/0h]tpubDDPGZQssk8ekvcN85aXhvz5omhZdQPWcczP21RqCHw7i5ce89zgYHoxowE8HrUUi2XUr4Vv4x48Ykhw7JBCH6G8QUfgRRR9UPgbC74DdNC4/1/*)#spvfr65h"
    

    Former errs, the latter works. Both are returned from listdescriptors, but former is the private from listdescriptors true.

    Relevant log output

    No response

    How did you obtain Bitcoin Core

    Pre-built binaries

    What version of Bitcoin Core are you using?

    v26.0.0

    Operating system and version

    Pop!_OS 22.04 LTS (like Ubuntu, just uses zram)

    Machine specifications

    x86_64 SSD big enough for Signet (proper, non-custom)

  2. pinheadmz commented at 5:32 pm on January 25, 2024: member
    Great catch! To summarize, the RPC is returning an extended PUBLIC key followed by a hardened derivation path. Which is not usable.
  3. achow101 commented at 8:14 pm on January 25, 2024: member

    The purpose of the descriptor result of getdescriptorinfo is to reflect a descriptor that basically matches the user’s input, just without including any private keys. listdescriptors specifically returns normalized descriptors so that they can be imported elsewhere.

    getdescriptorinfo could also return the normalized descriptor, but it intentionally does not do that for descriptor. I suppose a separate field containing the normalized form could be added.

  4. willcl-ark added the label Wallet on Jan 29, 2024
  5. willcl-ark added the label RPC/REST/ZMQ on Jan 29, 2024

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-12-21 15:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me