BIP 326: Anti-fee-sniping protection with nSequence in taproot transactions to improve privacy for off-chain protocols #1269

pull chris-belcher wants to merge 1 commits into bitcoin:master from chris-belcher:bip-nsequence-anti-fee-snipe changing 2 files +129 −0
  1. chris-belcher commented at 3:36 pm on January 8, 2022: contributor

    This adds a BIP for improve could the privacy of certain off-chain protocols like Lightning, CoinSwap or DLCs.

    It has already been implemented by Sparrow wallet.

  2. kallewoof commented at 7:11 am on January 9, 2022: member

    ML discussion dated June 10 2021. No objections that I can see.

    Ping @luke-jr.

    Edit: June, not July.

  3. in bip-nsequence-anti-fee-snipe.mediawiki:9 in 509b2e0ca1 outdated
    0@@ -0,0 +1,112 @@
    1+<pre>
    2+  BIP: TBD
    3+  Layer: Applications
    4+  Title: Anti-fee-sniping protection with nSequence in taproot transactions to improve privacy for off-chain protocols
    5+  Author: Chris Belcher <belcher at riseup dot net>
    6+  Status: Draft
    7+  Type: Standards Track
    8+  Created: 2021-06-10
    9+  License: PD
    


    MarcoFalke commented at 8:46 am on January 9, 2022:
  4. in bip-nsequence-anti-fee-snipe.mediawiki:10 in 509b2e0ca1 outdated
     5+  Author: Chris Belcher <belcher at riseup dot net>
     6+  Status: Draft
     7+  Type: Standards Track
     8+  Created: 2021-06-10
     9+  License: PD
    10+  Post-History: 2021-7-10: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-June/019048.html
    


    MarcoFalke commented at 8:48 am on January 9, 2022:
    0  Post-History: 2021-6-10: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-June/019048.html
    
  5. in bip-nsequence-anti-fee-snipe.mediawiki:60 in 509b2e0ca1 outdated
    55+    transaction.version = 2
    56+    # always set nlocktime if any of the transaction inputs have more
    57+    # confirmations than 65535 or are not taproot inputs
    58+    # otherwise choose either nlocktime or nsequence with 50% probability
    59+    if any(map(lambda input: input.confirmations() > 65535
    60+        || !input.is_taproot(), transaction.inputs))\
    


    MarcoFalke commented at 8:49 am on January 9, 2022:
    nit: python doesn’t have || and ! operators. Maybe replace them or remove the mention of “python” and only say “pseudocode”?
  6. in bip-nsequence-anti-fee-snipe.mediawiki:69 in 509b2e0ca1 outdated
    64+        transaction.nlocktime = max(0, transaction.nlocktime
    65+        - randint(0, 99))
    66+    # nsequence must be set in order for nlocktime to take effect
    67+    # this value also enables RBF
    68+    for input in transaction.inputs:
    69+        input.nsequence = 2**32 - 3
    


    MarcoFalke commented at 8:51 am on January 9, 2022:

    Some wallets provide an option to the user to “opt-out” of RBF. It would be good to clarify how they should handle this BIP.

    Edit: Presumably, just setting to 2**32 - 2 should still work to enable locktime and “disable” rbf.


    Jelboy15 commented at 7:23 am on February 3, 2022:

    Algumas carteiras fornecem uma opção para o usuário “opt-out” da RBF. Seria bom esclarecer como eles devem lidar com esse BIP.

    Editar: Presumivelmente, apenas configurar para 2**32 - 2ainda deve funcionar para habilitar o tempo de bloqueio e “desabilitar” o rbf.

  7. in bip-nsequence-anti-fee-snipe.mediawiki:62 in 509b2e0ca1 outdated
    57+    # confirmations than 65535 or are not taproot inputs
    58+    # otherwise choose either nlocktime or nsequence with 50% probability
    59+    if any(map(lambda input: input.confirmations() > 65535
    60+        || !input.is_taproot(), transaction.inputs))\
    61+        || randint(2) == 0:
    62+    transaction.nlocktime = blockchain.height()
    


    MarcoFalke commented at 8:52 am on January 9, 2022:
    nit: missing indent?
  8. MarcoFalke commented at 8:52 am on January 9, 2022: member
    left some nits/questions
  9. MarcoFalke commented at 11:04 am on January 9, 2022: member

    Is there an intuition how much this will help in practice?

    I expect smart contract implementations to use “magic numbers” for nsequence, such as 144. Or at the least use an nsequence that is biased toward such magic numbers. This will make it easier to tell them apart from “normal” transactions. I don’t have any data, but I think a tx output is (still) most likely to be spent in the block that created it (or in the few next ones that follow it). Such inputs would get marked with a small nsequence, for example 0 or 1. Those values don’t really make sense for smart contracts, so it will be easy to tell them apart.

    Maybe for small nsequence, it could make sense to also fall back to nlocktime?

  10. chris-belcher force-pushed on Jan 9, 2022
  11. chris-belcher commented at 3:36 pm on January 9, 2022: contributor

    Thanks so much for the reviews. I can’t believe I got the date of the mailing list post wrong.

    If fixed locktimes are used then a coinswap peer in a routed coinswap can tell their own position in the route from the locktime. Randomizing locktimes can be used to avoid this, and randomized locktimes will also blend into on-chain traffic a lot better. So this BIP will certainly help the privacy of CoinSwap/Teleport, which intends to eventually use a slightly randomized locktime.

    The same privacy leak applies to Lightning, and the Lightning community might also decide to implement randomized locktimes in some form. The discussion is more complicated admittedly since public channel transactions are broadcasted to everyone in the LN.

    NSequence values of 1 could be used as an alternative to OP_CSV 1 which is today being discussed as a way to stop transaction pinning.

    Because off-chain tech is so much more efficient in block space than on-chain tech, we can expect that the vast majority of block space will be used by on-chain tech for a long time, so it’s not a bad thing that this BIP marks on-chain transactions. The purpose of this BIP is to provide cover traffic for the rare occasion when an off-chain contract is closed with the timelock branch. This BIP aims to make that situation not immediately stand out. So I don’t think it’s worth changing anything for small nsequence values.

  12. MarcoFalke commented at 4:50 pm on January 9, 2022: member

    Thanks for the context and providing an example of why an nsequence of 1 makes sense. I guess an nsequence value of 0 doesn’t really make sense in practice? Moreover, in a (theoretical) edge case where a wallet spends untrusted unconfirmed coins, it might reduce the anti-fee-snipe guarantee. Assuming the incoming tx from another wallet didn’t have any anti-fee-snipe mechanism set, then a miner could re-mine the current block while including both the incoming tx and the one just created by the (theoretical) wallet?

    Also, I am wondering if the locktime and nsequence should remain unspecified in this BIP if they don’t need to be set to achieve anti-fee-snipe? Given that smart contracts in practise will usually use either locktime or nsequence, shouldn’t this BIP recommend to set them to their “default” value if not used? (see https://github.com/chris-belcher/bips/pull/2) Otherwise it will again be easy to tell “normal” and “smart” txs apart.

  13. chris-belcher commented at 6:52 pm on January 9, 2022: contributor
    Yes you’re right on both counts. I’ve edited the pseudocode to also only use nlocktime if the transaction has any unconfirmed inputs. And I’ve merged your pull request.
  14. MarcoFalke approved
  15. MarcoFalke commented at 7:14 pm on January 9, 2022: member
    ACK
  16. in bip-nsequence-anti-fee-snipe.mediawiki:4 in e79508c25c outdated
    0@@ -0,0 +1,116 @@
    1+<pre>
    2+  BIP: TBD
    3+  Layer: Applications
    4+  Title: Anti-fee-sniping protection with nSequence in taproot transactions to improve privacy for off-chain protocols
    


    MarcoFalke commented at 9:55 am on January 11, 2022:
    I think the title is a bit too specific and might discourage wallets that have not or will not implement taproot to implement anti-fee-snipe at all. Maybe make the BIP a bit more general and remove “taproot” from the title? Also, the body could mention: “Any wallets that can not or do not want to implement the more complex nSequence based anti-fee-sniping may implement only nLockTime based anti-fee-snipe” (first if branch in the pseudocode)?

    chris-belcher commented at 3:10 pm on January 12, 2022:
    The BIP only applies for taproot spends so I think it’s not a good idea to remove the word taproot. It’s no big deal if some wallets decide to not implement it, because the amount of cover traffic needed isn’t very large, and we’ve got at least a decade or two until the anti-fee-sniping becomes important (if ever)
  17. in bip-nsequence-anti-fee-snipe.mediawiki:7 in e79508c25c outdated
    0@@ -0,0 +1,116 @@
    1+<pre>
    2+  BIP: TBD
    3+  Layer: Applications
    4+  Title: Anti-fee-sniping protection with nSequence in taproot transactions to improve privacy for off-chain protocols
    5+  Author: Chris Belcher <belcher at riseup dot net>
    6+  Status: Draft
    7+  Type: Standards Track
    


    luke-jr commented at 11:21 pm on January 15, 2022:
    This feels more like an Informational BIP IMO.
  18. in bip-nsequence-anti-fee-snipe.mediawiki:97 in e79508c25c outdated
    92+
    93+Thanks to craigraw for suggesting a new value for input nsequence in the absolute locktime case[7].
    94+
    95+== Copyright ==
    96+
    97+This document is placed in the public domain.
    


    luke-jr commented at 11:22 pm on January 15, 2022:
    Public domain is not an acceptable license for new BIPs (see BIP 2)
  19. luke-jr changes_requested
  20. luke-jr commented at 11:24 pm on January 15, 2022: member
    Let’s use BIP number 326 for this
  21. luke-jr renamed this:
    Add BIP nsequence anti-fee-snipe
    BIP 326: Anti-fee-sniping protection with nSequence in taproot transactions to improve privacy for off-chain protocols
    on Jan 15, 2022
  22. luke-jr added the label New BIP on Jan 15, 2022
  23. chris-belcher force-pushed on Jan 16, 2022
  24. chris-belcher force-pushed on Jan 16, 2022
  25. chris-belcher force-pushed on Jan 16, 2022
  26. chris-belcher force-pushed on Jan 16, 2022
  27. chris-belcher commented at 3:48 pm on January 16, 2022: contributor

    Thanks Luke!

    I have dealt with your comments, edited the file name and other places to include the bip number, added an entry to the README, and squished all the commits into one.

  28. in bip-0326.mediawiki:84 in 388bca531c outdated
    75+        input_index = randint(len(transaction.inputs))
    76+        transaction.inputs[input_index].nsequence = transaction.inputs\
    77+            [input_index].confirmations()
    78+        if randint(10) == 0:
    79+            transaction.inputs[input_index].nsequence = max(0,
    80+                transaction.inputs[input_index].nsequence - randint(0, 99))
    


    MarcoFalke commented at 12:38 pm on January 21, 2022:

    This might again drop the nSequence below 1. Can be fixed by

    0nseq -= randint(0, nseq)
    1nseq -= randint(0, nseq - 1)
    

    Depending on whether randint is inclusive or exclusive.

    0            transaction.inputs[input_index].nsequence -= randint(0, transaction.inputs[input_index].nsequence))
    

    chris-belcher commented at 6:13 pm on January 21, 2022:

    What do you think of max(1, transaction.inputs[input_index].nsequence - randint(0, 99)) ?

    i.e. Changing max(0, into max(1, ?

    The max stops the nseq going below 1. It also doesnt make assumptions about randint being exclusive or inclusive

  29. MarcoFalke approved
  30. MarcoFalke commented at 3:04 pm on January 22, 2022: member
    Created a draft implementation for Bitcoin Core: https://github.com/bitcoin/bitcoin/pull/24128
  31. in bip-0326.mediawiki:46 in 388bca531c outdated
    41+
    42+When wallets create transactions spending UTXOs protected by BIP341 taproot, they should set either an nLockTime value or nSequence values to discourage fee sniping, by allowing the transaction to only be mined in the next block after the tip, not the current block. This BIP suggests 50% probability for using nLockTime and 50% for nSequence. If nSequence is set it should apply to at least one of the inputs of the transaction, if it has multiple inputs. It is suggested that on-chain wallets pick an input randomly.
    43+
    44+Wallets should also have a second random branch which sets the nLockTime or nSequence value even further back, so that transactions that are delayed after signing for whatever reason (e.g. high-latency mix networks) have better privacy. Existing behaviour is that with a probability of 10%, choose a random number between 0 and 99, and subtract it from the current block height. See the Bitcoin Core and Electrum source codes linked in the references for an example.
    45+
    46+nSequence can only encode up to a max of 65535 for the block distance, see BIP68[5], so if the UTXOs being spent have more confirmations than that then the wallet should use nLockTime instead.
    


    unknown commented at 3:42 pm on January 22, 2022:

    than that then looks weird even if grammatically correct:

    0nSequence can only encode up to 65535 for the block distance, see BIP68[5], so if the UTXOs being spent have more than 65535 confirmations, then the wallet should use nLockTime instead.
    
  32. in bip-0326.mediawiki:22 in 388bca531c outdated
    17+
    18+== Motivation ==
    19+
    20+With taproot recently added to bitcoin, and wallet software about to implement taproot wallets, we are in a unique position to improve the privacy of off-chain protocols if we act soon.
    21+
    22+Taproot allows for point-time-locked contracts (PTLC) as a more private replacement for hash-time-locked contracts (HTLCs). If an off-chain contract (for example a Lightning channel) is closed using a PTLC instead of an HTLC, then the blockchain will just see a regular taproot script instead of a hash value and preimage. However, if a contract is closed using the timelock path, then the blockchain will either see a OP_CHECKSEQUENCEVERIFY opcode or a nSequence value in the transaction, neither of which are very common today, and this would mark the closing transaction as something special and unusual.
    


    yahiheb commented at 6:47 pm on January 22, 2022:
    0Taproot allows for point-time-locked contracts (PTLCs) as a more private replacement for hash-time-locked contracts (HTLCs). If an off-chain contract (for example a Lightning channel) is closed using a PTLC instead of an HTLC, then the blockchain will just see a regular taproot script instead of a hash value and preimage. However, if a contract is closed using the timelock path, then the blockchain will either see a OP_CHECKSEQUENCEVERIFY opcode or a nSequence value in the transaction, neither of which are very common today, and this would mark the closing transaction as something special and unusual.
    
  33. in bip-0326.mediawiki:85 in 388bca531c outdated
    80+                transaction.inputs[input_index].nsequence - randint(0, 99))
    81+</source>
    82+
    83+== Compatibility ==
    84+
    85+This BIP doesnt need any consensus changes. It can be adopted unilaterally and gradually by wallets. Although for greater privacy it would be good for software to adopt it as soon as possible. Ideally during the process of developers implementing their taproot wallets, so that when taproot starts to be used it will already include the nSequence code.
    


    yahiheb commented at 7:12 pm on January 22, 2022:
    0This BIP doesn't need any consensus changes. It can be adopted unilaterally and gradually by wallets. Although for greater privacy it would be good for software to adopt it as soon as possible. Ideally during the process of developers implementing their taproot wallets, so that when taproot starts to be used it will already include the nSequence code.
    
  34. yahiheb changes_requested
  35. in bip-0326.mediawiki:24 in 388bca531c outdated
    19+
    20+With taproot recently added to bitcoin, and wallet software about to implement taproot wallets, we are in a unique position to improve the privacy of off-chain protocols if we act soon.
    21+
    22+Taproot allows for point-time-locked contracts (PTLC) as a more private replacement for hash-time-locked contracts (HTLCs). If an off-chain contract (for example a Lightning channel) is closed using a PTLC instead of an HTLC, then the blockchain will just see a regular taproot script instead of a hash value and preimage. However, if a contract is closed using the timelock path, then the blockchain will either see a OP_CHECKSEQUENCEVERIFY opcode or a nSequence value in the transaction, neither of which are very common today, and this would mark the closing transaction as something special and unusual.
    23+
    24+This BIP proposes to improve the privacy and fungibility of off-chain protocols by having on-chain wallets like Bitcoin Core also set the nSequence field in their taproot transactions as in BIP68. This would be in place of their regular nLockTime anti-fee-sniping protection. The end result is that, if an observer of the blockchain sees a taproot spend with an nSequence value, then that could be either: a regular spend from a wallet, or an off-chain settlement transaction spent with a timelock. The two cases would be indistinguishable, and this could greatly improve the privacy and fungibility of bitcoin. The community and wallet developers should act now to implement this so that the anonymity set of nSequence transactions starts to be built up as soon as taproot itself becomes adopted by wallets.
    


    w0xlt commented at 11:19 am on January 23, 2022:
    0This BIP proposes to improve the privacy and fungibility of off-chain protocols by having on-chain wallets like Bitcoin Core also set the nSequence field in their taproot transactions as in BIP68[5]. This would be in place of their regular nLockTime anti-fee-sniping protection. The end result is that, if an observer of the blockchain sees a taproot spend with an nSequence value, then that could be either: a regular spend from a wallet, or an off-chain settlement transaction spent with a timelock. The two cases would be indistinguishable, and this could greatly improve the privacy and fungibility of bitcoin. The community and wallet developers should act now to implement this so that the anonymity set of nSequence transactions starts to be built up as soon as taproot itself becomes adopted by wallets.
    
  36. in bip-0326.mediawiki:68 in 388bca531c outdated
    59+        else:
    60+            input.nsequence = 2**32 - 2
    61+    # always set nlocktime if any of the transaction inputs have more
    62+    # confirmations than 65535 or are not taproot inputs, or have
    63+    # unconfirmed inputs
    64+    # otherwise choose either nlocktime or nsequence with 50% probability
    


    w0xlt commented at 11:24 am on January 23, 2022:
    Could you elaborate further why these conditions imply choosing 100% nlocktime or 50% nlocktime and 50% nsequence?

    chris-belcher commented at 2:59 pm on January 23, 2022:
    I don’t understand your question, please elaborate
  37. chris-belcher force-pushed on Jan 23, 2022
  38. in bip-0326.mediawiki:46 in 4760942da2 outdated
    41+
    42+When wallets create transactions spending UTXOs protected by BIP341 taproot, they should set either an nLockTime value or nSequence values to discourage fee sniping, by allowing the transaction to only be mined in the next block after the tip, not the current block. This BIP suggests 50% probability for using nLockTime and 50% for nSequence. If nSequence is set it should apply to at least one of the inputs of the transaction, if it has multiple inputs. It is suggested that on-chain wallets pick an input randomly.
    43+
    44+Wallets should also have a second random branch which sets the nLockTime or nSequence value even further back, so that transactions that are delayed after signing for whatever reason (e.g. high-latency mix networks) have better privacy. Existing behaviour is that with a probability of 10%, choose a random number between 0 and 99, and subtract it from the current block height. See the Bitcoin Core and Electrum source codes linked in the references for an example.
    45+
    46+nSequence can only encode up to 65535 for the block distance[5] so if the UTXOs being spent have more 65535 confirmations, then the wallet should use nLockTime instead.
    


    unknown commented at 12:05 pm on January 23, 2022:
    0nSequence can only encode up to 65535 for the block distance[5] so if the UTXOs being spent have more than 65535 confirmations, then the wallet should use nLockTime instead.
    
  39. chris-belcher force-pushed on Jan 24, 2022
  40. chris-belcher requested review from luke-jr on Jan 24, 2022
  41. chris-belcher force-pushed on Jan 28, 2022
  42. chris-belcher commented at 2:21 pm on January 28, 2022: contributor
    I added a small paragraph explaining how this BIP relates to transaction pinning and nSequence=1 values. It’s a brief retelling of the discussion between @MarcoFalke and me, which I think is worth saying in the document too.
  43. in bip-0326.mediawiki:69 in cd6b3fd020 outdated
    64+            input.nsequence = 2**32 - 2
    65+    # always set nlocktime if any of the transaction inputs have more
    66+    # confirmations than 65535 or are not taproot inputs, or have
    67+    # unconfirmed inputs
    68+    # otherwise choose either nlocktime or nsequence with 50% probability
    69+    if any(map(lambda input: input.confirmations() > 65535
    


    MarcoFalke commented at 3:27 pm on February 1, 2022:
    0    if not rbf_set or any(map(lambda input: input.confirmations() > 65535
    

    The wallet must use tx.locktime when the user asks for the bip125 opt-out sequence number


    chris-belcher commented at 12:21 pm on February 2, 2022:
    Done
  44. bitcoin deleted a comment on Feb 2, 2022
  45. chris-belcher force-pushed on Feb 2, 2022
  46. MarcoFalke approved
  47. MarcoFalke commented at 12:27 pm on February 2, 2022: member
    ACK. RFM?
  48. in bip-0326.mediawiki:42 in b86ae635c5 outdated
    37+
    38+Absolute locktimes are also still used, so we should keep using nLockTime, but also often use nSequence.
    39+
    40+=== Transaction pinning ===
    41+
    42+Transaction pinning[8] is a method for making fee bumping prohibitively expensive by abusing node protections against attacks that can waste bandwidth, CPU, and memory. This can make fee management more difficult in multipart contract protocols (such as Lightning Network or CoinSwap). One possible way of solving the problem is to include a 1-block relative timelock `1 OP_CSV` to all spend paths, making it impossible to spend the unconfirmed UTXO. Such a 1-block locktime can also be created with an nSeqeuence value of 1. Many on-chain transactions in bitcoin spend inputs that were created just one or two blocks ago, following this BIP such transactions with `nSequence=1` would also provide cover traffic for off-chain transactions which disable transaction pinning.
    


    div72 commented at 1:15 pm on March 4, 2022:
    0Transaction pinning[8] is a method for making fee bumping prohibitively expensive by abusing node protections against attacks that can waste bandwidth, CPU, and memory. This can make fee management more difficult in multipart contract protocols (such as Lightning Network or CoinSwap). One possible way of solving the problem is to include a 1-block relative timelock `1 OP_CSV` to all spend paths, making it impossible to spend the unconfirmed UTXO. Such a 1-block locktime can also be created with an nSequence value of 1. Many on-chain transactions in bitcoin spend inputs that were created just one or two blocks ago, following this BIP such transactions with `nSequence=1` would also provide cover traffic for off-chain transactions which disable transaction pinning.
    

    nit: typo


    chris-belcher commented at 9:39 pm on March 4, 2022:
    Fixed. Thanks for the review
  49. Specify BIP 326: Anti-fee-sniping protection with nSequence in taproot
    To improve privacy for off-chain protocols
    4d5e1cc162
  50. chris-belcher force-pushed on Mar 4, 2022
  51. MarcoFalke commented at 8:49 am on March 7, 2022: member
  52. kallewoof merged this on Mar 8, 2022
  53. kallewoof closed this on Mar 8, 2022

  54. chris-belcher deleted the branch on Mar 8, 2022
  55. ajtowns cross-referenced this on Apr 7, 2022 from issue bip-326: avoid errors from scripts/buildtable.pl by ajtowns

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bips. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-12-26 18:10 UTC

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