From: Peter Todd <pete@petertodd•org>
To: Antoine Riard <antoine.riard@gmail•com>,
Bitcoin Protocol Discussion
<bitcoin-dev@lists•linuxfoundation.org>
Cc: security@ariard•me,
"lightning-dev\\\\@lists.linuxfoundation.org"
<lightning-dev@lists•linuxfoundation.org>
Subject: [bitcoin-dev] OP_Expire and Coinbase-Like Behavior: Making HTLCs Safer by Letting Transactions Expire Safely
Date: Sat, 21 Oct 2023 00:09:16 +0000 [thread overview]
Message-ID: <ZTMWrJ6DjxtslJBn@petertodd.org> (raw)
In-Reply-To: <CALZpt+GdyfDotdhrrVkjTALg5DbxJyiS8ruO2S7Ggmi9Ra5B9g@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 5996 bytes --]
On Mon, Oct 16, 2023 at 05:57:36PM +0100, Antoine Riard via bitcoin-dev wrote:
> Here enter a replacement cycling attack. A malicious channel counterparty
> can broadcast its HTLC-preimage transaction with a higher absolute fee and
> higher feerate than the honest HTLC-timeout of the victim lightning node
> and triggers a replacement. Both for legacy and anchor output channels, a
> HTLC-preimage on a counterparty commitment transaction is malleable, i.e
> additional inputs or outputs can be added. The HTLC-preimage spends an
> unconfirmed and unrelated to the channel parent transaction M and conflicts
> its child.
The basic problem here is after the HTLC-timeout path becomes spendable, the
HTLC-preimage path remains spendable. That's bad, because in this case we want
spending the HTLC-preimage - if possible - to have an urgency attached to it to
ensure that it happens before the previous HTLC-timeout is mined.
So, why can't we make the HTLC-preimage path expire? Traditionally, we've tried
to ensure that transactions - once valid - remain valid forever. We do this
because we don't want transactions to become impossible to mine in the event of
a large reorganization.
A notable example of this design philosophy is seen in Bitcoin's rules around
coinbase outputs: they only become spendable after 100 more blocks have been
found; a 100 block reorg is quite unlikely.
Enter the OP_Expire and the Coinbase Bit soft-fork upgrade.
# Coinbase Bit
By redefining a bit of the nVersion field, eg the most significant bit, we can
apply coinbase-like txout handling to arbitrary transactions. Such a
transaction's outputs would be treated similarly to a coinbase transaction, and
would be spendable only after 100 more blocks had been mined. Due to this
requirement, these transactions will pose no greater risk to reorg safety than
the existing hazard of coinbase transactions themselves becoming invalid.
Note how such a transaction is non-standard right now, ensuring compatibility
with existing nodes in a soft-fork upgrade.
# OP_Expire
Redefining an existing OP_Nop opcode, OP_Expire would terminate script
evaluation with an error if:
1) the Coinbase Bit was not set; or
2) the stack is empty; or
3) the top item on the stack was >= the block height of the containing block
This is conceptually an AntiCheckLockTimeVerify: where CLTV _allows_ a txout to
become spendable in a particular way in the future, Expire _prevents_ a txout
from being spent in a particular way.
Since OP_Expire requires the Coinbase Bit to be set, the reorg security of
OP_Expire-using transactions is no worse than transactions spending miner
coinbases.
# How HTLC's Would Use OP_Expire
Whenever revealing the preimage on-chain is necessary to the secure functioning
of the HTLC-using protocol, we simply add an appropriate OP_Expire to the
pre-image branch of the script along the lines of:
If
<expiry height> Expire Drop
Hash <digest> EqualVerify
<pubkey> CheckSig
ElseIf
# HTLC Expiration conditions
...
EndIf
Now the party receiving the pre-image has a deadline. Either they get a
transaction spending the preimage mined, notifying the other party via the
blockchain itself, or they fail to get the preimage mined in time, reverting
control to the other party who can spend the HTLC output at their leisure,
without strict time constraints.
Since the HTLC-expired branch does *not* execute OP_Expire, the transaction
spending the HTLC-expired branch does *not* need to set the Coinbase Bit. Thus
it can be spent in a perfectly normal transaction, without restrictions.
# Delta Encoding Expiration
Rather than having a specific Coinbase Bit, it may also be feasible to encode
the expiration height as a delta against a block-height nLockTime. In this
variant, OP_Expire would work similarly to OP_CheckLockTimeVerify, by checking
that the absolute expiration height was <= the requested expiration, allowing
multiple HTLC preimage outputs to be spent in one transaction.
If the top 16-bits were used, the maximum period a transaction could be valid
would be:
2^16 blocks / 144 blocks/day = 455 days
In this variant, a non-zero expiration delta would enable expiration behavior,
as well as the coinbase-like output spending restriction. The remaining 16-bits
of nVersion would remain available for other meanings.
Similar to how CLTV and CSV verified nLockTime and nSequence respectively,
verifying an expiration height encoded in the nVersion has the advantage of
making an expiration height easy to detect without validating scripts.
While Lightning's HTLC-success transactions currently use nLockTime=0, AFAIK
there is no reason why they could not set nLockTime to be valid in the next
block, allowing delta encoding to be used.
## Reusing Time-Based nLockTime
Reusing time-based nLockTime's prior to some pre-2009 genesis point for
expiration is another possibility (similar to how Lightning makes use of
time-based nLockTime for signalling). However I believe this is not as
desirable as delta encoding or a coinbase bit, as it would prevent transactions
from using block nLockTime and expiration at the same time. It would also still
require a coinbase bit or nVersion increase to ensure expiration-using
transactions are non-standard.
# Mempool Behavior
Obviously, mempool logic will need to handle transactions that can expire
differently than non-expiring transactions. One notable consideration is that
nodes should require higher minimum relay fees for transactions close to their
expiration height to ensure we don't waste bandwidth on transactions that have
no potential to be mined. Considering the primary use-case, it is probably
acceptable to always require a fee rate high enough to be mined in the next
block.
--
https://petertodd.org 'peter'[:-1]@petertodd.org
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
next prev parent reply other threads:[~2023-10-21 0:09 UTC|newest]
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-16 16:57 [bitcoin-dev] Full Disclosure: CVE-2023-40231 / CVE-2023-40232 / CVE-2023-40233 / CVE-2023-40234 "All your mempool are belong to us" Antoine Riard
2023-10-16 19:13 ` Peter Todd
2023-10-16 22:10 ` Matt Morehouse
2023-10-17 1:11 ` Antoine Riard
2023-10-20 10:47 ` Peter Todd
2023-10-20 11:18 ` Jochen Hoenicke
2023-10-16 22:51 ` Olaoluwa Osuntokun
2023-10-17 7:21 ` [bitcoin-dev] [Lightning-dev] " ziggie1984
2023-10-17 10:34 ` ZmnSCPxj
2023-10-17 18:34 ` Antoine Riard
2023-10-20 10:31 ` Peter Todd
2023-10-20 11:03 ` Peter Todd
2023-10-20 18:35 ` Matt Morehouse
2023-10-20 21:05 ` Matt Corallo
2023-10-21 0:15 ` Peter Todd
2023-10-21 1:03 ` Matt Corallo
2023-10-21 1:25 ` Peter Todd
2023-10-21 1:55 ` Matt Corallo
2023-10-21 2:43 ` Peter Todd
2023-10-23 16:09 ` Matt Corallo
2023-10-17 17:47 ` Antoine Riard
2023-10-17 18:47 ` Antoine Riard
2023-10-18 0:17 ` Matt Corallo
2023-10-18 2:57 ` Antoine Riard
2023-10-19 8:12 ` Bastien TEINTURIER
2023-10-19 16:23 ` Matt Morehouse
2023-10-19 17:22 ` Antoine Riard
2023-10-19 17:53 ` Matt Morehouse
2023-10-19 19:33 ` Antoine Riard
2023-10-21 0:18 ` Olaoluwa Osuntokun
2023-11-17 22:36 ` Antoine Riard
2023-10-19 18:02 ` Matt Corallo
2023-10-20 6:56 ` [bitcoin-dev] " Antoine Riard
2023-10-21 20:05 ` Antoine Riard
2023-10-27 0:43 ` Peter Todd
2023-11-02 4:46 ` Antoine Riard
2023-10-21 0:09 ` Peter Todd [this message]
2023-10-21 8:58 ` [bitcoin-dev] OP_Expire and Coinbase-Like Behavior: Making HTLCs Safer by Letting Transactions Expire Safely David A. Harding
2023-10-21 10:31 ` Peter Todd
2023-10-22 8:30 ` vjudeu
2023-10-23 11:10 ` [bitcoin-dev] [Lightning-dev] " ZmnSCPxj
2023-10-23 15:45 ` Peter Todd
2023-11-02 5:24 ` [bitcoin-dev] " Antoine Riard
2023-11-02 6:26 ` Peter Todd
2023-11-02 17:07 ` Matt Morehouse
2023-11-03 5:27 ` Antoine Riard
2023-11-03 5:25 ` Antoine Riard
2023-11-04 7:26 ` Peter Todd
2023-11-06 18:45 ` Antoine Riard
2023-11-07 11:11 ` [bitcoin-dev] [Lightning-dev] " ZmnSCPxj
2023-11-07 15:44 ` Antoine Riard
2023-11-08 0:51 ` [bitcoin-dev] " Peter Todd
2023-11-08 2:06 ` Peter Todd
2023-11-13 2:18 ` Antoine Riard
2023-11-14 19:50 ` Peter Todd
[not found] ` <CALZpt+H38cU9L8kq0mSYCDirzL39fxhdoz4pAPiS8dGJP8akKg@mail.gmail.com>
2023-11-15 17:53 ` [bitcoin-dev] Fwd: " Antoine Riard
2023-10-22 4:49 ` [bitcoin-dev] Full Disclosure: CVE-2023-40231 / CVE-2023-40232 / CVE-2023-40233 / CVE-2023-40234 "All your mempool are belong to us" Nadav Ivgi
2023-10-23 8:49 ` David A. Harding
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZTMWrJ6DjxtslJBn@petertodd.org \
--to=pete@petertodd$(echo .)org \
--cc=antoine.riard@gmail$(echo .)com \
--cc=bitcoin-dev@lists$(echo .)linuxfoundation.org \
--cc=lightning-dev@lists$(echo .)linuxfoundation.org \
--cc=security@ariard$(echo .)me \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox