Instant channels enable safe Lightning payments with unconfirmed funding

Here I get an incoming channel and spend my Lightning funds while the funding is unconfirmed.

Try it on TestNet right now:

What is going on?

When channel is funded in a special way an amount present in it can be spent immediately, without waiting for a funding transaction to become confirmed. This introduces no additional risks to either channel side, can be standardized with minor Lightning protocol changes and works on TestNet today.

This idea was brought to me by Kixunil and the gist is: if Bob the funder decides to push a certain amount to Alice the fundee on channel opening then pushed amount can be spent by Alice right away.

Pushing is essentially giving money away for free as far as LN protocol is concerned, an example: if total channel capacity is 1 BTC and Bob decides to push 0.5 BTC to Alice then initial channel funds distribution would be (0.5 Alice / 0.5 Bob).

Why would Bob do this?

Pushing may sound obscure but it’s in fact surprisingly applicable to a wide range of real-life scenarios, a few examples:

  • Alice gives fiat to Bob in person and thus purchases an incoming channel with converted amount in BTC pushed to her.
  • Alice redeems a voucher online and orders an incoming channel with voucher value pushed to her.
  • Alice the trader withdraws her exchange balance in a form of new Alice / Exchange channel with balance once again pushed to her.

This “special” case is so ubiquitous it may eventually become the way to use Lightning Network for end users.

Why is immediate spending from such a channel safe?

From Alice perspective, the pushed off-chain funds she has in an unconfirmed channel are not really her funds until a funding transaction gets included in a block. So, if anything, Alice has an incentive to spend these funds off-chain while they are unconfirmed on-chain.

From Bob perspective, he owes a pushed amount to Alice until a channel gets confirmed on-chain so he should not mind Alice spending these funds off-chain before that happens and thus clearing Bob’s debt.

Now, the central issue: what if a funding transaction gets thrown out of mempool eventually, would not Bob incur a financial loss if Alice manages to spend pushed amount off-chain before that? The answer is no, he would not, let’s analyze this edge case step by step:

  1. Alice pays 0.5 BTC to Bob with fiat, Bob opens a 1 BTC channel to Alice and pushes 0.5 BTC to her, so initial distribution is (0.5 Alice / 0.5 Bob).
  2. Bob already has a (0.6 Bob / 0.4 Carol) channel and Alice pays 0.1 BTC to Carol through Bob, so both channel states are updated and new distribution is (0.4 Alice / 0.6 Bob), (0.5 Bob / 0.5 Carol).
  3. Alice / Bob channel funding hangs in a mempool for weeks and eventually gets thrown out so there is no more an on-chain basis for their channel, so it gets removed from their wallets. Bob has lost 0.1 BTC in Bob / Carol channel while gained nothing in a by-now non-existing Alice / Bob channel, but Bob still has fiat which Alice gave him so effectively he now owes 0.4 BTC to Alice which he can refund or utilize while opening a new channel to Alice.

Can this be extended to a full blown trustless case?

Sort of yes, here’s how: Alice and Bob create a special non-RBF funding transaction which has two outputs:

  • First output is a 0.5 BTC P2WPKH transfer from Alice to Bob, this is her paying to Bob for opening of channel with a pushed amount.
  • Second output is 1 BTC channel funding from Bob with 0.5 BTC pushed to Alice off-chain.

Unlike previous case, here Bob does take risks if Alice spends her pushed amount off-chan and funding gets thrown out of mempool eventually, but Bob can always CPFP a first output if transaction starts hanging in mempool for a long time or if double spend is detected.

Is it hard to implement this?

Not at all, the currently proposed way is just a matter of introducing a new turbo bit in channel flags which would allow funder to signal an operational channel state once funding is broadcasted and fundee to accept it once it sees a funding in a mempool.

Eclair implementation (please don’t use it on MainNet yet).

BLW implementation for TestNet.