policy: correct (lower) the dust threshold for Taproot outputs #22779

pull darosior wants to merge 2 commits into bitcoin:master from darosior:taproot_dust_limit changing 2 files +42 −1
  1. darosior commented at 2:21 pm on August 23, 2021: member

    It was calculated as if it needed a compressed pubkey + a DER encoded ECDSA signature.

    Eventually i believe it would be good to prevent future overlooks by not applying the dust check to unknown witness versions and aborting if witness_version > current_version. Had a commit that starts doing that but removed it as it made this simple fix PR needlessly more complex.

  2. in src/policy/policy.cpp:45 in e49c9e12f9 outdated
    41+        if (witnessversion == 0) {
    42+            // P2WPKH spend, a compressed public key + a DER-encoded ECDSA signature
    43+            nSize += (32 + 4 + 1 + (107 / WITNESS_SCALE_FACTOR) + 4);
    44+        } else {
    45+            // Taproot key spend, a single BIP341 signature
    46+            nSize += (32 + 4 + 1 + (65 / WITNESS_SCALE_FACTOR) + 4);
    


    sipa commented at 2:25 pm on August 23, 2021:
    The outcome is the same, but I think the witness size is 66 (1 byte 0x01 to indicate the stack size, 1 byte 0x40 to indicate the size of the first element, 64 byte sig).

    darosior commented at 2:27 pm on August 23, 2021:
    Thanks, forgot the stack size byte
  3. darosior force-pushed on Aug 23, 2021
  4. DrahtBot added the label TX fees and policy on Aug 23, 2021
  5. theStack commented at 4:41 pm on August 23, 2021: member
    Concept ACK
  6. sipa commented at 4:42 pm on August 23, 2021: member
    Concept ACK
  7. policy: unit test Segwit v0 dust thresholds
    Signed-off-by: Antoine Poinsot <darosior@protonmail.com>
    f5aa6ee536
  8. in src/test/transaction_tests.cpp:960 in a7efad7cb4 outdated
    954@@ -955,6 +955,15 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
    955     BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
    956     BOOST_CHECK_EQUAL(reason, "bare-multisig");
    957     fIsBareMultisigStd = DEFAULT_PERMIT_BAREMULTISIG;
    958+
    959+    // Check Taproot outputs dust threshold
    960+    t.vout[0].scriptPubKey = CScript() << OP_1 << ParseHex("72ad3fb702bf1a2111b09c2bf1e72f4f52d4ceb2acdcfcd0c63abf70a59c36d6");
    


    MarcoFalke commented at 5:46 pm on August 23, 2021:

    You can just use a repeating hex character to allow for better compression.

    0    t.vout[0].scriptPubKey = CScript() << OP_1 << ParseHex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
    

    Also, would be nice to add a test for OP_16 (as you change this too in this pull) and OP_0, because it is missing.


    darosior commented at 7:45 am on August 24, 2021:

    Used repeating characters, tested for Segwit v0, and added test for future witness versions.

    Awkward to test something that is almost certainly wrong, comforts me in the idea that we should refactor GetDustThreshold to loudly fail rather than returning an invalid value.

  9. darosior force-pushed on Aug 24, 2021
  10. in src/policy/policy.cpp:45 in b1a8a41051 outdated
    41+        if (witnessversion == 0) {
    42+            // P2WPKH spend, a compressed public key + a DER-encoded ECDSA signature
    43+            nSize += (32 + 4 + 1 + (107 / WITNESS_SCALE_FACTOR) + 4);
    44+        } else {
    45+            // Taproot key spend, a single BIP341 signature
    46+            nSize += (32 + 4 + 1 + (66 / WITNESS_SCALE_FACTOR) + 4);
    


    Crypt-iQ commented at 3:34 pm on August 24, 2021:

    More of a meta-comment:

    If GetDustThreshold attempts to calculate the cost at which it’s economical to spend an output, why is nSize initialized to GetSerializedSize(txout)? When spending the dust output, the size of the txout isn’t in the spending tx unless the spending tx also spends to the same output type. This heuristic/initialization doesn’t make sense to me because if we take P2WSH as an example (w/ dust limit of 330), 330 - fees < 330 it is impossible to spend to the same output type unless other inputs are added. It seems to me that if witness version non-zero is being changed, this could be a place to fix or clarify this calculation for witness version non-zero.

  11. ariard commented at 9:20 pm on August 24, 2021: member

    Concept ACK

    Eventually i believe it would be good to prevent future overlooks by not applying the dust check to unknown witness versions and aborting if witness_version > current_version.

    IIUC, you’re aiming to return IsDust() == true for any transaction with witness outputs superior to current version, wouldn’t this be a revert of #15846 ? As we don’t know what would be the minimal spent or we can pick-up an arbitrary amount e.g 1000 sats, and consider the effective dust threshold for future type will be lower. And as such minimize risks of policy tightening changes.

  12. darosior commented at 9:24 pm on August 24, 2021: member

    No, i’m aiming to do the opposite: not call IsDust for witness versions >1, effectively having IsDust == false for any witness version from the future. Since, as you mention it, we can’t know the size in advance. ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ Le mardi 24 août 2021 à 11:21 PM, Antoine Riard @.***> a écrit :

    Concept ACK

    Eventually i believe it would be good to prevent future overlooks by not applying the dust check to unknown witness versions and aborting if witness_version > current_version.

    IIUC, you’re aiming to return IsDust() == true for any transaction with witness outputs superior to current version, wouldn’t this be a revert of #15846 ? As we don’t know what would be the minimal spent or we can pick-up an arbitrary amount e.g 1000 sats, and consider the effective dust threshold for future type will be lower. And as such minimize risks of policy tightening changes.

    — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android.

  13. in src/policy/policy.cpp:44 in b1a8a41051 outdated
    36@@ -37,7 +37,13 @@ CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFeeIn)
    37     if (txout.scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
    38         // sum the sizes of the parts of a transaction input
    39         // with 75% segwit discount applied to the script size.
    40-        nSize += (32 + 4 + 1 + (107 / WITNESS_SCALE_FACTOR) + 4);
    41+        if (witnessversion == 0) {
    42+            // P2WPKH spend, a compressed public key + a DER-encoded ECDSA signature
    43+            nSize += (32 + 4 + 1 + (107 / WITNESS_SCALE_FACTOR) + 4);
    44+        } else {
    45+            // Taproot key spend, a single BIP341 signature
    


    ariard commented at 9:24 pm on August 24, 2021:
    nit: If you intent to refer to the signature standard, should say BIP340 no? BIP341 describe the consensus rules applying the schnorr signature scheme.

    darosior commented at 7:24 am on August 25, 2021:
    Right, thanks. Doc-off-by-one!
  14. ariard commented at 9:26 pm on August 24, 2021: member

    No, i’m aiming to do the opposite: not call IsDust for witness versions >1, effectively having IsDust == false for any witness version from the future.

    Hmmmm so you could propagate transactions SegWit v2+ with nValue == 0 and as such freely write on the UTXO set? Unknown witness outputs are standard iirc.

  15. darosior commented at 7:30 am on August 25, 2021: member

    Hmmmm so you could propagate transactions SegWit v2+ with nValue == 0 and as such freely write on the UTXO set? Unknown witness outputs are standard iirc.

    You are right, i shouldn’t reply to Github comments at 11:21PM :p Maybe it could be made of a fixed value (this one, or another large one so we don’t tighten it when introducing a new version). Anyways i don’t intend to (address it in this PR and) modify the existing behaviour, just to refactor the code to prevent a future overlook.

  16. policy: correct (lower) the dust threshold for Taproot outputs
    It was calculated as if it needed a compressed pubkey + a DER encoded
    ECDSA signature.
    
    Note that this commit intentionally keeps the existing behaviour of
    applying the latest witness program version computation to all newer
    versions.
    
    Signed-off-by: Antoine Poinsot <darosior@protonmail.com>
    9155f6cf73
  17. darosior force-pushed on Aug 25, 2021
  18. ariard commented at 0:33 am on August 26, 2021: member

    Code Review ACK 9155f6c

    Maybe it could be made of a fixed value (this one, or another large one so we don’t tighten it when introducing a new version). Anyways i don’t intend to (address it in this PR and) modify the existing behaviour, just to refactor the code to prevent a future overlook.

    Yes honestly I think we should revamp our approach w.r.t to dust outputs, from a hard non-propagating threshold to a feerate penalty approach, that way adjustable by L2 nodes at broadcast time in function of mempool congestion. Though need to work-out a design first and discussion better left to the ML :)

  19. TheBlueMatt commented at 9:28 pm on August 30, 2021: member
    Concept NACK. I don’t think it makes sense to be lowering the dust levels in bitcoin generally. The context for the dust levels was calculated many years ago, I don’t think it applies anymore.
  20. benthecarman approved
  21. benthecarman commented at 10:49 pm on August 30, 2021: contributor
    Code Review ACK 9155f6cf738c790c389e105ce48d895634dd084f
  22. in src/policy/policy.cpp:40 in 9155f6cf73
    36@@ -37,7 +37,13 @@ CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFeeIn)
    37     if (txout.scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
    38         // sum the sizes of the parts of a transaction input
    39         // with 75% segwit discount applied to the script size.
    40-        nSize += (32 + 4 + 1 + (107 / WITNESS_SCALE_FACTOR) + 4);
    41+        if (witnessversion == 0) {
    


    JeremyRubin commented at 11:52 pm on August 30, 2021:
    nit:prefer a switch statement here
  23. JeremyRubin commented at 11:54 pm on August 30, 2021: contributor

    Concept NACK

    I think we should either remove the dust limit entirely or not muck around with it.

    Dust limits are not incentive compatible with miner preferences and if they are they can be configured by users individually.

    That said, it’s CR-Ack for me for this code, which seems to be improving the dust nSize calculation (which should be independent of any actual fee policy, the code could be cleaned up to make it have a min somewhere later but we shouldn’t confuse byte counting with thresholds).

  24. MarcoFalke commented at 8:12 am on August 31, 2021: member
    Maybe split off the added tests from the behaviour change, because they seem useful on their own?
  25. darosior commented at 3:06 pm on August 31, 2021: member

    @MarcoFalke done in #22846 @TheBlueMatt i too am of the opinion that we should not decrease the dust thresholds, but i think that if we want to keep the same dust thresholds for Taproot outputs we should instead raise DUST_RELAY_TX_FEE instead of keeping the wrong computation. But this would unfortunately be a security issue for (some) L2s relying on it..

    I don’t think the rationale of “dust threshold was calculated many years ago, let’s not fix it for a new output type unused on the network yet” holds. It was adapted for Segwit v0 and now Segwit v1 should be “penalized”? In any case, i think that even if we want to keep it larger for Taproot outputs than for Segwit v0 outputs we should document it instead of having the current “at least a 33-bytes pubkey and an ECDSA signature are required to spend” rationale for any Segwit output.

  26. TheBlueMatt commented at 11:14 pm on August 31, 2021: member

    @TheBlueMatt i too am of the opinion that we should not decrease the dust thresholds, but i think that if we want to keep the same dust thresholds for Taproot outputs we should instead raise DUST_RELAY_TX_FEE instead of keeping the wrong computation. But this would unfortunately be a security issue for (some) L2s relying on it..

    Indeed, I don’t think we can in any practical sense increase the dust threshold for deployed things, for exactly the reason you specify. I also agree with you that, ideally, we’d increase DUST_RELAY_TX_FEE, but given that we agree that we cannot, the only thing we can do is not make the problem worse for, which I’d argue this does.

    I’m not really sure why “consistency” here matters, the numbers are too low, reducing them is not great, so lets not do that :).

  27. DrahtBot commented at 9:40 am on September 1, 2021: 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:

    • #22846 (policy: unit test Segwit dust thresholds by darosior)

    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.

  28. MarcoFalke referenced this in commit 6bf706a056 on Sep 2, 2021
  29. DrahtBot added the label Needs rebase on Sep 2, 2021
  30. DrahtBot commented at 8:27 am on September 2, 2021: member

    🐙 This pull request conflicts with the target branch and needs rebase.

    Want to unsubscribe from rebase notifications on this pull request? Just convert this pull request to a “draft”.

  31. darosior referenced this in commit d873db7f8f on Sep 2, 2021
  32. darosior commented at 11:45 am on September 2, 2021: member
    I think Matt is right. Closing this one in favour of documenting the behaviour in #22863 .
  33. darosior closed this on Sep 2, 2021

  34. sidhujag referenced this in commit e84eeace45 on Sep 2, 2021
  35. luke-jr commented at 1:53 am on September 20, 2021: member

    But this would unfortunately be a security issue for (some) L2s relying on it..

    Then those L2s are broken. Policy is never a guarantee and should not be treated like one.

    IMO you should reopen this.

  36. laanwj referenced this in commit 4dbba3bac7 on Oct 15, 2021
  37. sidhujag referenced this in commit d79b962852 on Oct 15, 2021
  38. DrahtBot locked this on Oct 30, 2022

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-30 00:12 UTC

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