Good morning lisa,

This is a good observation.

Before, I'd already considered the rationale, for why channels have a single 
2-of-2 UTXO as funding output.  And it seems I should have considered this, 
prior to accepting the "parallel" construction as feasible.

For sake of posterity, I leave the below writeup as a tangential to the design 
of splice (and to the design of Lightning having a single 2-of-2 UTXOs):

# 0-conf is Unsafe, Yet Lightning is Safe; Why?

To accept a 0-conf transaction output, is known to be unsafe.  Replace-by-fee 
is always a possibility, regardless of whether the transaction opts in to RBF 
or not: a rational miner will always accept the higher feerate, disregarding 
any "opt-in" flag that is set or not set on the transaction.  Thus we reject 
any advice that claims that 0-conf is tenable, even for tiny amounts.

Yet when viewed solely in terms of transactions, Lightning protocol uses 
transactions that are not on any block (are kept offchain).  Since they are not 
in a block, they are indistinguishable from 0-conf transactions, which are 
accepted by the receiver, yet are also not on any block.  One might argue the 
distinction, that a "real" 0-conf transaction exists on some mempool somewhere, 
and thus has a chance to be on a block in the future, but mempools have no 
consensus, and the existence of a transaction on some mempool is not a safe 
assurance of it existing in the mempool of the next winning miner.

So why is Lightning safe, when 0-conf transactions are in general not safe?

Again, we should focus on why 0-conf transactions in general are not safe: 
transaction replacement.  Thus, 0-conf transactions can be made safe, if you 
are somehow able to ensure that replacement transactions cannot be made.

For example, if you are part of an n-of-n federation that signs the 
transaction, you can always safely accept a 0-conf transaction from that 
federation paying only to you, because you can always veto any replacement (by 
simply refusing to sign) that is not in your interests.

This is in fact how Lightning works: a 2-of-2 federation (the channel 
counterparties) are the signatories of the 0-conf transactions that are the 
commitment transactions of the Lightning protocol.  Replacement of the 
commitment transactions is strictly guided by the protocol; both sides have 
veto rights, since the source transaction output is 2-of-2.

Thus, Lightning, though it uses 0-conf transactions, is safe, because it 
prevents the replacement of a 0-conf transaction without the receiver allowing 
it, by the simple expedient of including the receiver in the 2-of-2 multisig 
guarding its single funding TXO.

##  The Implications for Splice Proposals

Some splice proposals involve creating the equivalent of multiple funding TXOs 
for a single channel.  Such constructions are unsafe-by-default on Poon-Dryja.

In reality, every commitment transaction (or update transaction in 
Decker-Osuntokun-Russell) is replaceable by any other commitment (or update) 
transaction for that channel.  Under Poon-Dryja older transactions are revoked 
(and hence one side risks loss of their collateral) while under 
Decker-Osuntokun-Russell older transactions may be "gainsaid" (i.e. newer 
update transactions may be reanchored to consume the TXO of the older update 
transaction, thus preventing that update from truly being committed to).

This is relevant since before a splice, the channel has a single funding TXO, 
while after the splice, the channel has multiple.

In particular, a commitment (or update) transaction, that has multiple inputs 
(to consume the multiple funding TXOs), can be replaced with a commitment (or 
update) transaction that was created before the splice.  Under Poon-Dryja, such 
a commitment transaction may be revoked, but this leaves the other funding TXOs 
unuseable.  Under Decker-Osuntokun-Russell, as long as the sequence number is 
preserved across the splice, it is possible for a later update transaction with 
multiple inputs to simply gainsay the old single-input update with the new 
multiple-input update transaction. (I suppose, that this is another advantage 
that Decker-Osuntokun-Russell has).


Sent with [ProtonMail]( Secure Email.

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Wednesday, October 17, 2018 9:09 AM, lisa neigut <> wrote:

> To add some context to this, if you start accepting HTLC's for the new 
> balance after the parallel commitment is made, but before the re-anchor is 
> buried, there's the potential for a race condition between a unilateral close 
> (or any revoked commitment transaction) and the re-anchoring commitment 
> transaction, that spends the 'pre-committed' UTXO of splicing in funds and 
> the original funding transaction.
> You can get around this by waiting until both the pre-commitment UTXO and the 
> re-anchor have cleared a minimum depth before accepting HTLC's for the new 
> balance totals, but that's twice as long of a wait as the first, synchronized 
> re-commitment scheme that Rusty originally proposed.
> It also makes leaving the original funding transaction 'exposed' (ie Rene's 
> version of parallel splice) untenable, as there's always the risk of an old 
> state being published to consume that input. This foobars your current HTLC 
> commitments.
> On Tue, Oct 16, 2018 at 3:31 PM Rusty Russell <> wrote:
>> Rusty Russell <> writes:
>>> If we're going to do side splice-in like this, I would use a very
>>> different protocol: the reason for this protocol was to treat splice-in
>>> and splice-out the same, and inline splice-in requires wait time.  Since
>>> splice-out doesn't, we don't need this at all.
>>> It would look much more like:
>>> 1. Prepare any output with script of specific form. eg:
>>>         OP_DEPTH 3 OP_EQUAL OP_IF
>>>                 <funding_pubkey1> <funding_pubkey2> OP_CHECKMULTISIG
>>>         OP_ELSE
>>>                 <blockheight> OP_CHECKLOCKTIMEVERIFY OP_DROP
>>>                 <myrescue_pubkey> OP_CHECKSIG
>>>         OP_ENDIF
>>> 1. type: 40 (`splice_in`) (`option_splice`)
>>> 2. data:
>>>    * [`32`:`channel_id`]
>>>    * [`8`: `satoshis`]
>>>    * [`32`: `txid`]
>>>    * [`4`: `txoutnum`]
>>>    * [`4`: `blockheight`]
>>>    * [`33`: `myrescue_pubkey`]
>>> 1. type: 137 (`update_splice_in_accept`) (`option_splice`)
>>>    data:
>>>    * [`32`:`channel_id`]
>>>    * [`32`: `txid`]
>>>    * [`4`: `txoutnum`]
>>> 1. type: 138 (`update_splice_in_reject`) (`option_splice`)
>>>    data:
>>>    * [`32`:`channel_id`]
>>>    * [`32`: `txid`]
>>>    * [`2`:`len`]
>>>    * [`len`:`errorstr`]
>>> The recipient of `splice_in` checks that it's happy with the
>>> `blockheight` (far enough in future).  Once it sees the tx referred to
>>> buried to its own `minimum_depth`, it checks output is what they
>>> claimed, then sends `update_splice_in_accept`; it's followed up
>>> `commitment_signed` like normal, but from this point onwards, all
>>> commitment txs signatures have one extra sig.
>> Lisa started asking pointed questions, and so I noticed that parallel
>> splice doesn't work with Poon-Dryja channels.
>> The counterparty can spend the old funding txout with a revoked spend.
>> Sure, I can take all the money from that, but what about the spliced
>> input?
>> I came up with increasingly elaborate workarounds, but nothing stuck.
>> Back to Plan A...
>> Rusty.
>> _______________________________________________
>> Lightning-dev mailing list
Lightning-dev mailing list

Reply via email to