Multi-party transaction protocols (e.g., dual funding, splicing) are generally vulnerable to liquidity griefing attacks that lock up the victim’s UTXOs for an extended period of time. Some forms of these attacks are difficult to prevent and can require the victim to pay a high ransom (inflated transaction fee) to unlock their funds.
What follows is my best summary and commentary on the various liquidity griefing vectors and potential defenses proposed by
@niftynei, @roasbeef, @MattCorallo,
@ariard, myself, and others. The goal is to spark some discussion about all the potential forms of these attacks (including ones I’ve missed), potential defenses and tradeoffs.
|Initiator signs first
|Delay UTXO locking until broadcast
|Require confirmed inputs
|Require p2wpkh inputs
|Low feerate ancestors
|Pinned conflicting tx
There are two main vectors for liquidity griefing:
- preventing successful broadcast of the joint transaction
- preventing or delaying confirmation of the joint transaction
For single-party transactions, wallets typically lock UTXOs while constructing the transaction to ensure that concurrent sessions do not double spend UTXOs. For multi-party transactions, such a policy is vulnerable to liquidity griefing from an attacker who can prevent the transaction from being successfully broadcast.
Once Bob shares signatures for his transaction inputs with Mallory, he can no longer safely back out of the protocol and forget about the joint transaction – he must be prepared for Mallory to broadcast the joint transaction at any point in the future. If Mallory never broadcasts the transaction and never shares her input signatures with Bob, Bob’s UTXOs will remain locked until he pays transaction fees to double spend one of his inputs.
Mallory can use inputs for the joint transaction that do not exist on-chain or in mempools, thus preventing the joint transaction from being successfully broadcast. Bob doesn’t know whether Mallory’s inputs will eventually exist on-chain, so he cannot safely forget about the transaction. So Bob’s UTXOs will remain locked until he pays transaction fees to double spend one of his inputs.
Even if a participant in a multi-party protocol chooses not to lock UTXOs during transaction construction, they generally cannot afford to leave UTXOs unlocked until transaction confirmation because that would cause lots of accidental double spends. The participant will usually need to lock UTXOs soon after the joint transaction is successfully broadcast. As a consequence, the participant is vulnerable to liquidity griefing from an attacker who can prevent or delay the joint transaction from confirming after broadcast.
If Mallory uses unconfirmed inputs in the joint transaction, she can delay confirmation of the joint transaction at least until her input transactions confirm. By making the feerate on those input transactions very low, Mallory can lock Bob’s liquidity for an extended period.
After Bob has successfully broadcast the joint transaction, Mallory can double-spend one of her unconfirmed input transactions, permanently preventing the joint transaction from confirming. If Bob fails to detect this, his UTXOs will remain locked indefinitely.
After sending her signatures to Bob, Mallory can pin a low-feerate transaction that conflicts with the joint transaction in mempools. The pinning can be done by disabling RBF for the transaction or by attaching many low-feerate descendants. If she broadcasts to the right nodes and has the good timing, Mallory can partition the network such that Bob’s mempool contains the joint transaction while the conflicting transaction is pinned in most other mempools. The joint transaction will not propagate to miners, and Bob’s liquidity will be locked up until Mallory’s conflicting transaction confirms.
Mallory can inflate the size of her witnesses to lower the effective feerate on the joint transaction and delay confirmation. Mallory may also attach many low-feerate descendants to the joint transaction in order to prevent Bob from fee bumping via CPFP or double-spending via RBF.
There are several proposed defenses against the above griefing vectors, though none are magic bullets and all have tradeoffs.
Partially fixes: withholding signatures, witness inflation
In some multi-party protocols (e.g., dual funding), the non-initiating party is more exposed to repeated griefing than the initiating party. For these protocols, a policy requiring the initiator to send their input signatures first can help prevent griefing against the non-initiator.
If Mallory is the initiator, this policy trivially prevents her from griefing Bob by withholding signatures (if she does, Bob can safely back out of the protocol).
Additionally, Bob is able to inspect Mallory’s witnesses prior to broadcast and ensure they are not inflated. Bob can also broadcast the joint transaction widely before sending Mallory his signatures, making it difficult for Mallory to construct and broadcast a competing inflated transaction successfully.
Batching multiple channel opens and/or splices into the same transaction becomes impossible for the initiator.
Does not prevent griefing against the initiator.
Fixes: withholding signatures, nonexistant inputs
If Bob keeps his UTXOs unlocked until he is able to successfully broadcast the joint transaction, it is impossible to lock up his liquidity by preventing transaction broadcast. Bob will simply use the same UTXOs for another purpose once he has a productive opportunity to do so, negating the goal of the attack.
Accidental double spending against honest counterparties can occur. Concurrent multi-party sessions could end up spending the same UTXOs, causing one of the sessions to end in failure.
When concurrent sessions are expected to be rare and conclude quickly, this approach can work well in practice. This approach is currently used for dual funding and splicing.
Fixes: nonexistant inputs, low feerate ancestors, replacing ancestors
By rejecting unconfirmed inputs, Bob can trivally prevent any attack vector that relies on unconfirmed inputs.
Transactions in the mempool must now confirm before they can be used in the joint transaction. This causes a minimum delay of 1 block (~10 minutes) before the multi-party protocol can begin.
Partially fixes: nonexistant inputs, low feerate ancestors, replacing ancestors
If Bob wants to allow unconfirmed inputs, he can inspect all unconfirmed ancestors in his mempool prior to sending his input signatures. If any ancestors are not present or have a low feerate, Bob can safely cancel the negotiation.
Once he broadcasts the joint transaction, Bob can watch the blockchain for transactions that conflict with any unconfirmed ancestor. If such a transaction is found, Bob can safely unlock all of his input UTXOs and use them for other purposes.
Bob’s mempool doesn’t necessarily match other mempools on the network, so it is possible that Mallory has pinned a low-feerate conflicting ancestor in other mempools. In that case mempool monitoring doesn’t help Bob, and Mallory can still lock up his liquidity until the conflicting ancestor confirms.
Mempool monitoring also requires access to a full node’s mempool, which may not be possible for parties with resource constraints (e.g., mobile devices).
Fixes: witness inflation
If Bob requires all inputs to be p2wpkh, there is no way for Mallory to inflate her witnesses for those inputs.
There was also some discussion at the last Lightning spec meeting about p2tr being a viable input type if a proof is provided that only key-path spends are possible. Unfortunately, I think key-path spends can still have their witnesses inflated via the annex.
Restricting inputs to p2wpkh significantly reduces usability of the multi-party protocol. For example, this restriction would make it impossible to have a single transaction splice funds from one lightning channel to another.
Partially fixes: witness inflation
If the protocol requires all but 1 output per party to be encumbered by a CSV of at least 1, CPFP carve out can be used to confirm the joint transaction when needed, regardless of pinning attempts.
CPFP carve-out only works for 2-party protocols. Therefore, batching multiple channel opens and/or splices into the same transaction becomes impossible in most cases.
Bob also must pay extra fees to perform the CPFP. If Mallory repeatedly engages in witness inflation attacks against Bob, she can force him to slowly burn his funds as transaction fees.
In addition, encumbering outputs with CSV 1 reduces on-chain efficiency and requires extra complexity to verify the encumberance.
Partially fixes: witness inflation
v3 transactions severely limit the number and size of descendants they can have. Thus if joint transactions are marked v3, pinning doesn’t work, and either party can unlock their funds by double spending one of their inputs.
Even with v3 transactions, double spending can incur a limited RBF penalty fee. If Mallory engages in repeated witness inflation attacks against Bob, she can force him to consistently pay higher-than-normal fees to double-spend his griefed UTXOs.
And, of course, v3 transactions don’t exist yet.
We have potential defenses against some liquidity griefing vectors, but they all have tradeoffs. It seems that all known defenses against witness inflation have substantial downsides, and we have no known defenses against a pinned conflicting transaction that is missing from the victim’s mempool.
Hopefully we can come up with some more ideas to address this fundamental problem in multi-party transaction protocols.