-
Notifications
You must be signed in to change notification settings - Fork 36.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add (sorted)multi_a descriptor for k-of-n multisig inside tr #24043
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a few comments, did not review the tests.
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
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. |
It seems like the distinction between the normal and |
@luke-jr I like to keep the invariant that every "function" in descriptors (and later, miniscript) refer to the same opcode construction. The reason is that while for this example it's unambiguous (multi only in toplevel/sh/wsh, multi_a only in tr), that's not going to be the case for all (or in the case of miniscript, even most) functions. So there will inevitably be constructions with variants which cannot be derived from the context, and given that it seems more consistent to keep the contextual smartness out of this. |
How about erroring if they're used in the wrong context? |
@luke-jr They do (even before this PR). |
Isn't it also suboptimal for m-of-n where the permutations are sufficiently tractable to go in separate leaves? There may even be a privacy benefit to never revealing N. Neither is an objection to this descriptor though. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
code review ACK 4828d53
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code review ACK 4828d53
// Redundant, but very fast and selective test. | ||
if (script.size() == 0 || script[0] != 32 || script.back() != OP_NUMEQUAL) return {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (script.size() > MAX_PUBKEYS_PER_MULTI_A * 34 + 3 + 1) return {};
Would also be a fast test bounding the potential number of iterations below.
++it; | ||
if (it != script.end()) return {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: any reason to not combine these two lines?
std::vector<std::unique_ptr<PubkeyProvider>> keys; | ||
keys.reserve(match->second.size()); | ||
for (const auto keyspan : match->second) { | ||
if (keyspan.size() != 32) return {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This cannot happen?
@@ -27,6 +27,7 @@ | |||
from .ripemd160 import ripemd160 | |||
|
|||
MAX_SCRIPT_ELEMENT_SIZE = 520 | |||
MAX_PUBKEYS_PER_MULTI_A = 512 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be 999
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, actually it's part of the next commit
Concept ACK, Approach ACK I'll attempt to summarize some additional context that was discussed in Friday's Core wallet meeting that may be helpful for other reviewers too. (It was helpful for me. Apologies if I get any of this wrong and it needs a correction)
If you consider descriptors and Miniscript as one thing under a single name (which one day hopefully they will be, we already consider Miniscript as an extension to descriptors) then Miniscript already has suffixes such as
Each descriptor and each Miniscript is one-to-one with a specific script. I think
As Sjors says there will be likely be many alternative Miniscripts that a Taproot |
ACK 4828d53 |
ACK 4828d53 |
No worries, they are nits that's why i acked. :)
…-------- Original Message --------
On Mar 4, 2022, 14:53, Michael Folkson wrote:
***@***.***(https://github.com/achow101): FYI there's some unresolved comments from ***@***.***(https://github.com/darosior) [above](#24043 (review)).
—
Reply to this email directly, [view it on GitHub](#24043 (comment)), or [unsubscribe](https://github.com/notifications/unsubscribe-auth/AFLK3F5CBPVX3DUXOI6WA63U6IPVNANCNFSM5LXDZV4A).
Triage notifications on the go with GitHub Mobile for [iOS](https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675) or [Android](https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub).
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
nits are non-blocking |
…ig inside tr 4828d53 Add (sorted)multi_a descriptors to doc/descriptors.md (Pieter Wuille) b5f33ac Simplify wallet_taproot.py functional test (Pieter Wuille) eb0667e Add tests for (sorted)multi_a derivation/signing (Pieter Wuille) c17c6aa Add signing support for (sorted)multi_a scripts (Pieter Wuille) 3eed6fc Add multi_a descriptor inference (Pieter Wuille) 79728c4 Add (sorted)multi_a descriptor and script derivation (Pieter Wuille) 25e95f9 Merge/generalize IsValidMultisigKeyCount/GetMultisigKeyCount (Pieter Wuille) Pull request description: This adds a new `multi_a(k,key_1,key_2,...,key_n)` (and corresponding `sortedmulti_a`) descriptor for k-of-n policies inside `tr()`. Semantically it is very similar to the existing `multi()` descriptor, but with the following changes: * The corresponding script is `<key1> OP_CHECKSIG <key2> OP_CHECKSIGADD <key3> OP_CHECKSIGADD ... <key_n> OP_CHECKSIGADD <k> OP_NUMEQUAL`, rather than the traditional `OP_CHECKMULTISIG`-based script, making it usable inside the `tr()` descriptor. * The keys can optionally be specified in x-only notation. * Both the number of keys and the threshold can be as high as 999; this is the limit due to the consensus stacksize=1000 limit I expect that this functionality will later be replaced with a miniscript-based implementation, but I don't think it's necessary to wait for that. Limitations: * The wallet code will for not estimate witness size incorrectly for script path spends, which may result in a (dramatic) fee underpayment with large multi_a scripts. * The multi_a script construction is (slightly) suboptimal for n-of-n (where a `<key1> OP_CHECKSIGVERIFY ... <key_n-1> OP_CHECKSIGVERIFY <key_n> OP_CHECKSIG` would be better). Such a construction is not included here. ACKs for top commit: achow101: ACK 4828d53 gruve-p: ACK bitcoin@4828d53 sanket1729: code review ACK 4828d53 darosior: Code review ACK 4828d53 Tree-SHA512: 5dcd434b79585f0ff830f7d501d27df5e346f5749f47a3109ec309ebf2cbbad0e1da541eec654026d911ab67fd7cf7793fab0f765628d68d81b96ef2a4d234ce
The |
I think the problem might be if different calls to |
I'm seeing it fail with other indexes too. I think it's actually that |
#24490 should fix the test failure |
Makes sense! |
@@ -33,6 +33,7 @@ Output descriptors currently support: | |||
- Pay-to-taproot outputs (P2TR), through the `tr` function. | |||
- Multisig scripts, through the `multi` function. | |||
- Multisig scripts where the public keys are sorted lexicographically, through the `sortedmulti` function. | |||
- Multisig scripts inside taproot script trees, through the `multi_a` (and `sortedmulti_a`) function. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this also be included in the 24.0 release notes?
Something like
tr()
descriptors now support multisig scripts through themulti_a
(andsortedmulti_a
) function.
…veaddresses 92a4ed0 doc: add tr() descriptor example to deriveaddresses (FractalEncrypt) Pull request description: This simple PR adds a missing tr() descriptor example to the `help deriveaddresses` examples. - The functionality added in bitcoin/bitcoin#24043 is a significant departure from legacy multisig address creation, yet there is no corresponding tr() descriptor example in the help. - Having this example in combination with the examples in the descriptors documentation will be helpful to users. I needed this information to correctly create a tr multisig address but was unable. I had to leave the software and use a 3rd party site to ask two separate questions ([1](https://bitcoin.stackexchange.com/questions/115700/how-do-i-create-a-taproot-multisig-address-requiring-21-of-210-keys-to-spend), [2](https://bitcoin.stackexchange.com/questions/115742/signing-psbts-to-spend-from-taproot-multisig-address)) to create an address using the new functionality. Note: This specific example is not provided in the [descriptors.md ](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md) documentation, though there is a similar example with `sortedmulti_a. ` ACKs for top commit: instagibbs: ACK 92a4ed0 kouloumos: ACK 92a4ed0 w0xlt: ACK bitcoin/bitcoin@92a4ed0 Tree-SHA512: 8fb052bd469718157cb64439b885f8b0ecfb5a798535a02bae0a5dc748cd554a3e5ffdd9fe4acaef16156eadb59e1b2bcde7356e811397225f2783a84c8b112f
92a4ed0 doc: add tr() descriptor example to deriveaddresses (FractalEncrypt) Pull request description: This simple PR adds a missing tr() descriptor example to the `help deriveaddresses` examples. - The functionality added in bitcoin#24043 is a significant departure from legacy multisig address creation, yet there is no corresponding tr() descriptor example in the help. - Having this example in combination with the examples in the descriptors documentation will be helpful to users. I needed this information to correctly create a tr multisig address but was unable. I had to leave the software and use a 3rd party site to ask two separate questions ([1](https://bitcoin.stackexchange.com/questions/115700/how-do-i-create-a-taproot-multisig-address-requiring-21-of-210-keys-to-spend), [2](https://bitcoin.stackexchange.com/questions/115742/signing-psbts-to-spend-from-taproot-multisig-address)) to create an address using the new functionality. Note: This specific example is not provided in the [descriptors.md ](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md) documentation, though there is a similar example with `sortedmulti_a. ` ACKs for top commit: instagibbs: ACK 92a4ed0 kouloumos: ACK 92a4ed0 w0xlt: ACK bitcoin@92a4ed0 Tree-SHA512: 8fb052bd469718157cb64439b885f8b0ecfb5a798535a02bae0a5dc748cd554a3e5ffdd9fe4acaef16156eadb59e1b2bcde7356e811397225f2783a84c8b112f
This adds a new
multi_a(k,key_1,key_2,...,key_n)
(and correspondingsortedmulti_a
) descriptor for k-of-n policies insidetr()
. Semantically it is very similar to the existingmulti()
descriptor, but with the following changes:<key1> OP_CHECKSIG <key2> OP_CHECKSIGADD <key3> OP_CHECKSIGADD ... <key_n> OP_CHECKSIGADD <k> OP_NUMEQUAL
, rather than the traditionalOP_CHECKMULTISIG
-based script, making it usable inside thetr()
descriptor.I expect that this functionality will later be replaced with a miniscript-based implementation, but I don't think it's necessary to wait for that.
Limitations:
<key1> OP_CHECKSIGVERIFY ... <key_n-1> OP_CHECKSIGVERIFY <key_n> OP_CHECKSIG
would be better). Such a construction is not included here.