Inconsistent hardened derivation marker in listdescriptors output #31694

issue jp1ac4 openend this issue on January 20, 2025
  1. jp1ac4 commented at 9:05 pm on January 20, 2025: none

    Is there an existing issue for this?

    • I have searched the existing issues

    Current behaviour

    If I use importdescriptors to import a descriptor that uses only ' as the hardened derivation marker, the corresponding output of listdescriptors sometimes uses a mix of ' and h.

    Expected behaviour

    I would expect the output for a given imported descriptor to either match my input or otherwise use only one of ' and h.

    I would also expect the behaviour to be consistent across different descriptors.

    Steps to reproduce

    1. Create wallet:
    0$ bitcoin-cli -regtest createwallet test_h_vs_apostrophe true
    1{
    2  "name": "test_h_vs_apostrophe"
    3}
    
    1. Import tr descriptor:
    0$ bitcoin-cli -regtest -rpcwallet=test_h_vs_apostrophe importdescriptors "[{\"desc\": \"tr([1dce71b2/48'/1'/0'/2']tpubDEeP3GefjqbaDTTaVAF5JkXWhoFxFDXQ9KuhVrMBViFXXNR2B3Lvme2d2AoyiKfzRFZChq2AGMNbU1qTbkBMfNv7WGVXLt2pnYXY87gXqcs/0/*,and_v(v:pk([1dce71b2/48'/1'/0'/2']tpubDEeP3GefjqbaDTTaVAF5JkXWhoFxFDXQ9KuhVrMBViFXXNR2B3Lvme2d2AoyiKfzRFZChq2AGMNbU1qTbkBMfNv7WGVXLt2pnYXY87gXqcs/2/*),older(65535)))#xhrh0cvn\", \"timestamp\": \"now\"}]"
    1[
    2  {
    3    "success": true,
    4    "warnings": [
    5      "Range not given, using default keypool range"
    6    ]
    7  }
    8]
    
    1. Import wsh descriptor:
    0$ bitcoin-cli -regtest -rpcwallet=test_h_vs_apostrophe importdescriptors "[{\"desc\": \"wsh(or_d(pk([a233d117/48'/1'/0'/2']tpubDF8d1Q2U8WWfxUHMiqqrYiavBReX2r7hwD7oQsEuq1AiXj5nJcLBkoh1uTLZVx66VrbRfeHyg5bSFvRKzesa1yzYuXDvawZeRi9m97a2Qzd/0/*),and_v(v:pkh([a233d117/48'/1'/0'/2']tpubDF8d1Q2U8WWfxUHMiqqrYiavBReX2r7hwD7oQsEuq1AiXj5nJcLBkoh1uTLZVx66VrbRfeHyg5bSFvRKzesa1yzYuXDvawZeRi9m97a2Qzd/2/*),older(65535))))#segwrd5h\", \"timestamp\": \"now\"}]"
    1[
    2  {
    3    "success": true,
    4    "warnings": [
    5      "Range not given, using default keypool range"
    6    ]
    7  }
    8]
    

    When calling listdescriptors, the tr descriptor uses a mix of h and ' (and checksum has changed), while wsh uses only ' (and has same checksum):

     0$ bitcoin-cli -regtest -rpcwallet=test_h_vs_apostrophe listdescriptors
     1{
     2  "wallet_name": "test_h_vs_apostrophe",
     3  "descriptors": [
     4    {
     5      "desc": "tr([1dce71b2/48h/1h/0h/2h]tpubDEeP3GefjqbaDTTaVAF5JkXWhoFxFDXQ9KuhVrMBViFXXNR2B3Lvme2d2AoyiKfzRFZChq2AGMNbU1qTbkBMfNv7WGVXLt2pnYXY87gXqcs/0/*,and_v(v:pk([1dce71b2/48'/1'/0'/2']tpubDEeP3GefjqbaDTTaVAF5JkXWhoFxFDXQ9KuhVrMBViFXXNR2B3Lvme2d2AoyiKfzRFZChq2AGMNbU1qTbkBMfNv7WGVXLt2pnYXY87gXqcs/2/*),older(65535)))#2h7g2wme",
     6      "timestamp": 1296688602,
     7      "active": false,
     8      "range": [
     9        0,
    10        999
    11      ],
    12      "next": 0,
    13      "next_index": 0
    14    },
    15    {
    16      "desc": "wsh(or_d(pk([a233d117/48'/1'/0'/2']tpubDF8d1Q2U8WWfxUHMiqqrYiavBReX2r7hwD7oQsEuq1AiXj5nJcLBkoh1uTLZVx66VrbRfeHyg5bSFvRKzesa1yzYuXDvawZeRi9m97a2Qzd/0/*),and_v(v:pkh([a233d117/48'/1'/0'/2']tpubDF8d1Q2U8WWfxUHMiqqrYiavBReX2r7hwD7oQsEuq1AiXj5nJcLBkoh1uTLZVx66VrbRfeHyg5bSFvRKzesa1yzYuXDvawZeRi9m97a2Qzd/2/*),older(65535))))#segwrd5h",
    17      "timestamp": 1296688602,
    18      "active": false,
    19      "range": [
    20        0,
    21        999
    22      ],
    23      "next": 0,
    24      "next_index": 0
    25    }
    26  ]
    27}
    

    Relevant log output

    No response

    How did you obtain Bitcoin Core

    Pre-built binaries

    What version of Bitcoin Core are you using?

    v28.0.0

    Operating system and version

    Ubuntu 24.04

    Machine specifications

    No response

  2. brunoerg commented at 1:56 pm on January 21, 2025: contributor

    If I use importdescriptors to import a descriptor that uses only ’ as the hardened derivation marker, the corresponding output of listdescriptors sometimes uses a mix of ’ and h.

    I think this is due to ToNormalizedString called by GetDescriptorString fromlistdescriptors:

     0bool ToNormalizedString(const SigningProvider& arg, std::string& ret, const DescriptorCache* cache) const override
     1{
     2    std::string sub;
     3    if (!m_provider->ToNormalizedString(arg, sub, cache)) return false;
     4    // If m_provider is a BIP32PubkeyProvider, we may get a string formatted like a OriginPubkeyProvider
     5    // In that case, we need to strip out the leading square bracket and fingerprint from the substring,
     6    // and append that to our own origin string.
     7    if (sub[0] == '[') {
     8        sub = sub.substr(9);
     9        ret = "[" + OriginString(StringType::PUBLIC, /*normalized=*/true) + std::move(sub);
    10    } else {
    11        ret = "[" + OriginString(StringType::PUBLIC, /*normalized=*/true) + "]" + std::move(sub);
    12    }
    13    return true;
    14}
    
  3. pythcoiner commented at 6:42 am on January 24, 2025: none
    it looks I got a fix, will write tests & PR

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: 2025-02-22 21:13 UTC

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