News

A splice input that claimed to belong to one side

On 21 August 2026 LDK merged a fix for splice negotiation. Presenting the shared channel input as a wholly owned one let the other side be credited with money it did not bring, and the transaction was signed anyway.

4 min readSplicing
A splice input that claimed to belong to one side

What happened

On 21 August 2026 the Lightning Development Kit merged two commits that make a node refuse a splice input presented as one peer's own when it belongs to both. The first states the problem in its own words: "A malicious splice initiator can encode the expected shared funding outpoint using prevtx while omitting shared_input_txid. The receiver then accounts the entire previous funding output as initiator-owned, allowing additional initiator outputs to consume the transaction's intended fee budget while still passing the per-party feerate check" (commit 972a25c1). The commit credits the report to the Bitcoin Red Team.

What it changes

Splicing resizes a Lightning channel without closing it. The splice transaction spends the channel's current funding output and pays to a new one of a different size. That funding output is a 2-of-2, so it is the one input both peers have to sign: the shared input.

The two peers build the transaction together, each adding inputs and outputs, and BOLT 2 splits the bill. The initiator pays for the common fields; "the rest of the transaction bytes' fees are the responsibility of the peer who contributed that input or output". When the exchange ends, each side checks the other and must abort if "the peer's paid feerate does not meet or exceed the agreed feerate", or if the peer's inputs are worth less than its outputs.

The shared input is announced differently from an owned one. The initiator "MUST add the current channel input to the splice transaction by sending tx_add_input with shared_input_txid" and "MUST NOT include prevtx for that shared input", because prevtx is there to prove the value and script of an input the receiver has never seen, and both sides already know their own funding output.

LDK read the other branch of that message first. An input carrying a prevtx and no shared_input_txid was taken as wholly owned by the sender, whatever it pointed at, so an initiator that sent the entire previous funding transaction was credited with the whole channel balance, the receiver's half included. That extra credit is what paid for the initiator's own outputs while its arithmetic still passed.

The signature followed the transaction rather than the negotiation. At construction time LDK found the shared input by scanning for the funding outpoint, "independently of how that input had been accounted for during the negotiation" (commit 65ca961e), so the receiver put its key on the input it had just booked as somebody else's. The result "may therefore be fully signed and consensus-valid while paying less than the negotiated fee". The fix rejects a prevtx naming the shared funding outpoint, and takes the shared input from how the negotiation classified it.

What it does not change

It is not a route to the channel balance. What the initiator gains is the fee budget: the transaction confirms at a lower rate than the one both sides agreed, and until it confirms the channel sits mid-splice. That is a real cost and it is not theft of the counterparty's funds, and the commit message claims no more than that.

It only reaches nodes that accept splices from peers they have no reason to trust. LDK gates that behind UserConfig::reject_inbound_splices, which has existed since splicing shipped in version 0.2 on 2 December 2025.

Nothing installed anywhere is fixed by it. The commits are on the main development branch, which carries version 0.3.0. Neither the 0.3 branch nor the 0.2 branch, whose most recent release is 0.2.5 of 4 August 2026, contains them, and the same unguarded prevtx branch is still in the 0.2 code. And it says nothing about the other implementations: each one has written its own interactive transaction construction, and a bug in one of them is not evidence about the rest.

Context

Splicing is young and the complexity is in this exact machinery. LDK's own 0.2 series already carried a fix in the neighbourhood: a channel with exactly zero balance and zero-fee commitments let "the counterparty splice all of their balance out, violating the reserve requirements they'd otherwise be forced to keep".

The other pattern worth noting is who found it. The same release notes that fix thank Project Loupe for reported security issues, and this one credits the Bitcoin Red Team. Bitcoin's implementations are being read at a rate they have not been read at before, and the visible result is a queue of small, specific, well-described patches rather than an incident. LND's cap on gossip memory landed the same way earlier this month: not funds, but something a node was doing that it should not have been.

Newsletter

Bitcoin, without the noise

What happened in Bitcoin, what it actually changes, and the sources so you can check us. One issue at a time, straight to your inbox.

  • One email per issue, never a drip campaign
  • No tracking pixels and no shared addresses
  • Unsubscribe from any issue in one click

Get the next issue

One email per issue, no tracking pixels, and unsubscribe from any of them. We do not share your address. Privacy policy