descriptors: Introduce sortedmulti descriptor #17056

pull achow101 wants to merge 4 commits into bitcoin:master from achow101:sortedmulti-desc changing 6 files +105 −7
  1. achow101 commented at 7:49 pm on October 4, 2019: member

    Adds a sortedmulti() descriptor as mentioned in #17023 (comment).

    sortedmulti() works in the same way as multi does but sorts the pubkeys in the resulting scripts in lexicographic order as described in BIP67. Note that this does not add support for BIP67 nor is BIP67 fully supported by this descriptor (which is why it is not named multi67()) as it does not require compressed pubkeys.

    Tests from BIP67 were added and documentation was updated.

  2. fanquake added the label Descriptors on Oct 4, 2019
  3. fanquake requested review from sipa on Oct 4, 2019
  4. DrahtBot commented at 8:56 pm on October 4, 2019: member

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

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #17023 (doc: warn that ranged multi() descriptors are not BIP67 compatible by Sjors)
    • #16889 (Add some general std::vector utility functions by sipa)
    • #16800 (Basic Miniscript support in output descriptors by sipa)
    • #15590 (Descriptor: add GetAddressType() and IsSegWit() by Sjors)

    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.

  5. in src/script/descriptor.cpp:600 in d5a925be31 outdated
    592@@ -593,15 +593,23 @@ class ComboDescriptor final : public DescriptorImpl
    593     ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Singleton(std::move(prov)), {}, "combo") {}
    594 };
    595 
    596-/** A parsed multi(...) descriptor. */
    597+/** A parsed multi(...) or sortedmulti(...) descriptor */
    598 class MultisigDescriptor final : public DescriptorImpl
    599 {
    600     const int m_threshold;
    601+    bool m_sorted;
    


    promag commented at 8:03 am on October 5, 2019:
    Also const?

    achow101 commented at 6:06 pm on October 7, 2019:
    Done
  6. in src/script/descriptor.cpp:842 in d5a925be31 outdated
    835@@ -827,7 +836,10 @@ std::unique_ptr<DescriptorImpl> ParseScript(Span<const char>& sp, ParseScriptCon
    836         error = "Cannot have combo in non-top level";
    837         return nullptr;
    838     }
    839-    if (Func("multi", expr)) {
    840+    if (Func("sortedmulti", expr)) {
    841+        sorted_multi = true;
    842+    }
    843+    if (Func("multi", expr) || sorted_multi) {
    


    promag commented at 8:11 am on October 5, 2019:
    Swap operands?

    achow101 commented at 6:06 pm on October 7, 2019:
    Done
  7. MarcoFalke renamed this:
    Introduce sortedmulti descriptor
    descriptors: Introduce sortedmulti descriptor
    on Oct 5, 2019
  8. Sjors commented at 11:33 am on October 5, 2019: member
  9. in test/functional/rpc_createmultisig.py:84 in 4bb67aad0a outdated
    79+        with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data/rpc_bip67.json'), encoding='utf-8') as f:
    80+            vectors = json.load(f)
    81+
    82+        for t in vectors:
    83+            key_str = ','.join(t['keys'])
    84+            self.nodes[0].deriveaddresses(descsum_create('sh(sortedmulti(2,' + key_str + '))'))[0] == t['address']
    


    Sjors commented at 9:07 am on October 6, 2019:
    This just returns false without failing the test. In fact all these addresses are incorrect; you either have to run the node in mainnet (like feature_config_args), or replace the test vectors for regtest. I manually verified with a mainnet node that the vectors do pass.

    achow101 commented at 3:19 pm on October 6, 2019:
    Whoops. Fixed. Changed the addresses to regtest ones. You can check they still map to the same scriptPubKey using getaddressinfo and decodescript.
  10. Sjors changes_requested
  11. Sjors commented at 9:21 am on October 6, 2019: member

    I tested with https://github.com/cryptoadvance/specter-desktop/pull/8 that ColdCard simulator no longer complains about a change address that it complained about before.

    Code review ACK d5a925b except for the functional test issue.

  12. achow101 force-pushed on Oct 6, 2019
  13. Sjors commented at 7:01 pm on October 6, 2019: member
    ACK a6dd441cb2d8325dd968897776e7f8389cda359c
  14. in doc/descriptors.md:41 in a6dd441cb2 outdated
    37@@ -37,12 +38,14 @@ Output descriptors currently support:
    38 - `sh(wsh(pkh(02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13)))` describes an (overly complicated) P2SH-P2WSH-P2PKH output with the specified public key.
    39 - `multi(1,022f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4,025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc)` describes a bare *1-of-2* multisig output with keys in the specified order.
    40 - `sh(multi(2,022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01,03acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe))` describes a P2SH *2-of-2* multisig output with keys in the specified order.
    41+- `sh(sortedmulti(2,03acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe,022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01))` describes a P2SH *2-of-2* multisig output with keys in the sorted lexicographically in the resulting redeemScript.
    


    bitcoinhodler commented at 10:13 pm on October 6, 2019:
    s/keys in the sorted/keys sorted/

    achow101 commented at 6:06 pm on October 7, 2019:
    Done
  15. in doc/descriptors.md:48 in a6dd441cb2 outdated
    43 - `sh(wsh(multi(1,03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8,03499fdf9e895e719cfd64e67f07d38e3226aa7b63678949e6e49b241a60e823e4,02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e)))` describes a P2SH-P2WSH *1-of-3* multisig output with keys in the specified order.
    44 - `pk(xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8)` describes a P2PK output with the public key of the specified xpub.
    45 - `pkh(xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw/1'/2)` describes a P2PKH output with child key *1'/2* of the specified xpub.
    46 - `pkh([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*)` describes a set of P2PKH outputs, but additionally specifies that the specified xpub is a child of a master with fingerprint `d34db33f`, and derived using path `44'/0'/0'`.
    47 - `wsh(multi(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*))` describes a set of *1-of-2* P2WSH multisig outputs where the first multisig key is the *1/0/`i`* child of the first specified xpub and the second multisig key is the *0/0/`i`* child of the second specified xpub, and `i` is any number in a configurable range (`0-1000` by default).
    48+- `wsh(sortedmulti(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*))` describes a set of *1-of-2* P2WSH multisig outputs where the one multisig key is the *1/0/`i`* child of the first specified xpub and the other multisig key is the *0/0/`i`* child of the second specified xpub, and `i` is any number in a configurable range (`0-1000` by default). The order of public keys in the resulting witnessScripts is determined by the lexicographic order of the public keys at that index.
    


    bitcoinhodler commented at 10:14 pm on October 6, 2019:
    s/where the one multisig key/where one multisig key/

    achow101 commented at 6:07 pm on October 7, 2019:
    Done
  16. in doc/descriptors.md:109 in a6dd441cb2 outdated
    104@@ -101,11 +105,12 @@ not contain "p2" for brevity.
    105 
    106 Several pieces of software use multi-signature (multisig) scripts based
    107 on Bitcoin's OP_CHECKMULTISIG opcode. To support these, we introduce the
    108-`multi(k,key_1,key_2,...,key_n)` function. It represents a *k-of-n*
    109+`multi(k,key_1,key_2,...,key_n)` and `sortedmulti(k,key_1,key_2,...,key_n)`
    110+functions. It represents a *k-of-n*
    


    bitcoinhodler commented at 10:16 pm on October 6, 2019:
    s/It represents/They represent/ (?)

    achow101 commented at 6:07 pm on October 7, 2019:
    Done
  17. bitcoinhodler changes_requested
  18. bitcoinhodler commented at 10:19 pm on October 6, 2019: contributor
    Love this.
  19. achow101 force-pushed on Oct 7, 2019
  20. in test/functional/rpc_createmultisig.py:84 in 9214dd6f91 outdated
    79+        with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data/rpc_bip67.json'), encoding='utf-8') as f:
    80+            vectors = json.load(f)
    81+
    82+        for t in vectors:
    83+            key_str = ','.join(t['keys'])
    84+            assert_equal(self.nodes[0].deriveaddresses(descsum_create('sh(sortedmulti(2,' + key_str + '))'))[0], t['address'])
    


    promag commented at 10:22 pm on October 7, 2019:

    nit, in order to make this shorter:

    0            keys = ','.join(t['keys'])
    1            desc = descsum_create('sh(sortedmulti(2,{}))'.format(keys))
    2            assert_equal(self.nodes[0].deriveaddresses(desc)[0], t['address'])
    

    achow101 commented at 11:03 pm on October 7, 2019:
    Done
  21. promag commented at 10:24 pm on October 7, 2019: member
    ACK 9214dd6f91, add release notes and call it a day.
  22. achow101 force-pushed on Oct 7, 2019
  23. achow101 commented at 11:03 pm on October 7, 2019: member
    Added a release note.
  24. achow101 force-pushed on Oct 7, 2019
  25. in doc/release-notes-17056.md:4 in 0080a85f87 outdated
    0@@ -0,0 +1,4 @@
    1+Low-level RPC Changes
    2+===
    3+
    4+- A new descriptor type `sortedmulti(...)` has been added to support multisig scripst where the public keys are sorted lexicographically in the resulting script.
    


    bitcoinhodler commented at 3:53 am on October 8, 2019:
    s/scripst/scripts/

    achow101 commented at 4:03 am on October 8, 2019:
    Done
  26. achow101 force-pushed on Oct 8, 2019
  27. achow101 force-pushed on Oct 8, 2019
  28. laanwj added the label Feature on Oct 8, 2019
  29. promag commented at 1:59 pm on October 8, 2019: member
    ACK 2638791a4f25394dc241367c933a2d27ed981197, only changes are the suggestion in the test and added the release note.
  30. fanquake requested review from Sjors on Oct 8, 2019
  31. Sjors approved
  32. Sjors commented at 4:44 pm on October 8, 2019: member
    re-ACK 2638791a4f25394dc241367c933a2d27ed981197
  33. in test/functional/rpc_createmultisig.py:84 in 2638791a4f outdated
    79+        with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data/rpc_bip67.json'), encoding='utf-8') as f:
    80+            vectors = json.load(f)
    81+
    82+        for t in vectors:
    83+            key_str = ','.join(t['keys'])
    84+            desc = descsum_create('sh(sortedmulti(2,{}))'.format(key_str))
    


    sipa commented at 5:10 pm on October 8, 2019:
    You could check whether a sh(multi(2,{})) descriptor with the json’s “sorted_keys” gives the same result.

    achow101 commented at 5:57 pm on October 8, 2019:
    Done
  34. in src/script/descriptor.cpp:842 in 2638791a4f outdated
    835@@ -827,7 +836,10 @@ std::unique_ptr<DescriptorImpl> ParseScript(Span<const char>& sp, ParseScriptCon
    836         error = "Cannot have combo in non-top level";
    837         return nullptr;
    838     }
    839-    if (Func("multi", expr)) {
    840+    if (Func("sortedmulti", expr)) {
    841+        sorted_multi = true;
    842+    }
    843+    if (sorted_multi || Func("multi", expr)) {
    


    sipa commented at 5:11 pm on October 8, 2019:
    I very slightly prefer if ((sorted_multi = Func("sortedmulti", expr)) || Func("multi", expr)) {

    achow101 commented at 5:57 pm on October 8, 2019:
    Done
  35. sipa commented at 5:12 pm on October 8, 2019: member
    ACK 2638791a4f25394dc241367c933a2d27ed981197. Agree on calling it sortedmulti as it’s indeed more generic than bip67.
  36. Add sortedmulti descriptor and unit tests 6f588fd227
  37. Test sortedmulti descriptor using BIP 67 tests 80be78ea75
  38. Update descriptors.md to include sortedmulti ed96b295d7
  39. Add release note 4bb660be90
  40. achow101 force-pushed on Oct 8, 2019
  41. fanquake requested review from sipa on Oct 8, 2019
  42. fanquake requested review from Sjors on Oct 8, 2019
  43. fanquake requested review from promag on Oct 8, 2019
  44. fanquake requested review from instagibbs on Oct 8, 2019
  45. Sjors approved
  46. Sjors commented at 6:08 pm on October 8, 2019: member
    re-ACK 4bb660be90a2811b53855bf1fd33a8dd9ba3db47
  47. fanquake referenced this in commit 520d140e6e on Oct 8, 2019
  48. fanquake merged this on Oct 8, 2019
  49. fanquake closed this on Oct 8, 2019

  50. luke-jr referenced this in commit 22b06f0bd7 on Nov 15, 2019
  51. luke-jr referenced this in commit 13d4e903b2 on Nov 15, 2019
  52. jasonbcox referenced this in commit 4931365316 on Oct 8, 2020
  53. DrahtBot locked this on Dec 16, 2021

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-10-06 16:12 UTC

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