rpc: remove stale "canonical form" claim from getdescriptorinfo help #36136

pull craigraw wants to merge 1 commits into bitcoin:master from craigraw:fix-canonical-wording changing 1 files +1 −1
  1. craigraw commented at 7:45 AM on September 1, 2026: none

    getdescriptorinfo describes its descriptor result as:

    The descriptor in canonical form, without private keys.

    The returned string is a re-serialisation of the parsed descriptor with private keys removed. It is not a canonical form: descriptors that describe the same wallet routinely come back as different strings with different checksums, and this is deliberate.

    Three things the RPC does not canonicalise:

    • The hardened derivation marker. #26076 added m_apostrophe so that the marker the caller used is preserved rather than rewritten (src/script/descriptor.cpp:262, :512); it first shipped in v26.0. Before that, FormatHDKeypath() emitted ' unconditionally (v25.0, src/util/bip32.cpp:54), so h supplied by the caller was rewritten — the behaviour #15740 objected to under the name "canonicalize". Where a single key expression mixes both markers, the style of its last hardened element is applied to the whole expression, which is still input-dependent.
    • Key order in multi() / sortedmulti(). The order is preserved as given. For sortedmulti() the written order carries no meaning at all, since BIP 383 sorts the derived keys when the output script is built, so the same wallet has n! equally valid descriptors.
    • The checksum. The checksum field is computed over the input string (src/rpc/output_script.cpp:215), so it can differ from the checksum embedded in the returned descriptor — e.g. when a private key was supplied.
    $ bitcoin-cli getdescriptorinfo "sortedmulti(1,03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd,04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235)" | jq -r .descriptor
    sortedmulti(1,03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd,04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235)#fne5696l
    
    $ bitcoin-cli getdescriptorinfo "sortedmulti(1,04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235,03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)" | jq -r .descriptor
    sortedmulti(1,04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235,03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)#w5gau8hw
    

    Both produce the same output script; neither is more canonical than the other. The same applies to the marker:

    $ bitcoin-cli getdescriptorinfo "wpkh([f6bb4c63/0h/0h/30h]028429a37c3f09c8c5cc1fab58df32d1a7da7616c748a40eeb1aae1d64acb9c5cc)" | jq -r .descriptor
    wpkh([f6bb4c63/0h/0h/30h]028429a37c3f09c8c5cc1fab58df32d1a7da7616c748a40eeb1aae1d64acb9c5cc)#vk9vfu0h
    
    $ bitcoin-cli getdescriptorinfo "wpkh([f6bb4c63/0'/0'/30']028429a37c3f09c8c5cc1fab58df32d1a7da7616c748a40eeb1aae1d64acb9c5cc)" | jq -r .descriptor
    wpkh([f6bb4c63/0'/0'/30']028429a37c3f09c8c5cc1fab58df32d1a7da7616c748a40eeb1aae1d64acb9c5cc)#5wdxpxcx
    

    The wording dates from v0.18.0 (src/rpc/misc.cpp:153), where it did describe the behaviour, and has been carried forward unchanged since. Whether the RPC should canonicalise was settled in #15740 in favour of round-tripping what the caller supplied; this only brings the description into line with that outcome.

    I have deliberately not replaced the phrase with "normal form" or "normalized". Those terms already denote a different transformation in this codebase — BIP 380's "Normalization of Key Expressions with Hardened Derivation", implemented as Descriptor::ToNormalizedString() ("Normalized descriptors have the xpub at the last hardened step", src/script/descriptor.h:140) — which getdescriptorinfo does not perform. Dropping the qualifier avoids the collision.

    Documentation only; no behaviour change. The phrase occurs nowhere else in the repo.

    -{RPCResult::Type::STR, "descriptor", "The descriptor in canonical form, without private keys. For a multipath descriptor, only the first will be returned."},
    +{RPCResult::Type::STR, "descriptor", "The descriptor, without private keys. For a multipath descriptor, only the first will be returned."},
    

    If reviewers would rather the help positively state what is preserved (hardened marker and key order as supplied, checksum recomputed), I am happy to expand it; I have kept the change minimal.

  2. remove stale canonical form claim from getdescriptorinfo help 1dad06eff3
  3. DrahtBot added the label RPC/REST/ZMQ on Sep 1, 2026
  4. DrahtBot commented at 7:45 AM on September 1, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--006a51241073e994b41acfe9ec718e94-->

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/36136.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline and AI policy for information on the review process.

    Type Reviewers
    ACK Eunovo

    If your review is incorrectly listed, please copy-paste <code>&lt;!--meta-tag:bot-skip--&gt;</code> into the comment that the bot should ignore.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  5. maflcko added the label Docs on Sep 1, 2026
  6. Eunovo approved
  7. Eunovo commented at 11:09 AM on September 1, 2026: contributor

    ACK https://github.com/bitcoin/bitcoin/pull/36136/commits/1dad06eff3d564a56b72d35b7984ce868957daa7:

    "canonical" refers to the "standard" or "unique" way of representing something, which getdescriptorinfo does not do. I'm satisfied with the proposed update.


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: 2026-09-04 07:51 UTC

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