Description
Recently, I encountered a bug that an HTLC is not claimed by either party after the channel is force-closed.
Logs indicate that one node is attempting to claim that HTLC via an htlc-timeout transaction, but failed with RPC error (400) due to dust output.
Here is part of the logs. cf3..0f4:11
is the HTLC to be swept.
2025-06-05T08:02:40.100395Z DEBUG lightning::chain::package:1062: Adding claiming input for outpoint cf3f0c985e6c130f2a3988e888d58d8cc51945efaceb7bfec70cd95ca086d0f4:11
2025-06-05T08:02:40.100719Z INFO lightning::chain::onchaintx:528: Rebroadcasting onchain HTLC claim tx (0 preimage, 1 timeout, 0 revoked) with txid 2ade336033804fe0fd619a49f7c9dd50c455cc4cbceb8118252d90158de30cca
2025-06-05T08:02:40.101883Z DEBUG ldk_node::chain:1036: Failed to broadcast due to HTTP connection error: RPC error
tx: 02000000000101f4d086a05cd90cc7fe7bebacef4519c58c8dd588e888392a0f136c5e980c3fcf0b00000000010000000200000000000000001600141dec8ff322b271c6fd27d855c2afeeacf868d9e50000000000000000226a2088aa90deac782500cbeb1787dccc9e941ea865a6511dba98f53bac3fa81135bd0347304402200a424a7942f5f7887d6e1a2a8c17430a601ac9f015c3ee974e68dffee5d07677022075b6a389adeaa661ab0ff86b21fd8027f47b5421e6beaa2cea54da913a4a95ef01008d76a914a64d88bc4137d38b7cd5bdd77806f859cacb9bfb8763ac67210299164eef8e0b0fdde0556aa98143dfd7f2ff6fd18728b01b188041b4766d279c7c8201208763a914c797839ad0401e45b721c50a695fb9d241de668a88527c2103646ebe4f487aee44dc9e585301899699cf53645aff81095522da45d7921329f052ae677502db01b175ac6851b27568b6030000
2025-06-05T08:03:09.172879Z DEBUG lightning_transaction_sync::esplora:248: Finished transaction sync at tip 0e3441163f7c09ed394e421e014ce1fb04af05f74b969d7f9c00ea71f5d0d54c in 0ms: 0 confirmed, 0 unconfirmed.
2025-06-05T08:03:09.172909Z INFO ldk_node::chain:592: Sync of Lightning wallet finished in 0ms.
2025-06-05T08:03:10.238034Z INFO lightning::chain::onchaintx:513: Triggering rebroadcast/fee-bump for request with inputs [OutPoint { txid: cf3f0c985e6c130f2a3988e888d58d8cc51945efaceb7bfec70cd95ca086d0f4, vout: 11 }]
2025-06-05T08:03:10.238073Z DEBUG lightning::chain::package:1341: Initiating fee rate bump from 1570 s/kWU (1133 s) to 253 s/kWU (182 s) using HighestOfPreviousOrNew strategy
2025-06-05T08:03:10.238076Z DEBUG lightning::chain::package:1372: new feerate 1570 is equal to previous feerate 1570
2025-06-05T08:03:10.238078Z DEBUG lightning::chain::package:1373: new fee: 1133, input amount: 1000
2025-06-05T08:03:10.238078Z DEBUG lightning::chain::package:1374: remaining output amount is 0
I guess the dust output occurred because the remote party claimed some of its inputs and the node removed them from the sweep transaction without adjusting the feerate.
The sweep transaction before its output becomes dust (ignore the OP_RETURN commitment):
tx: Transaction {
version: Version(
2,
),
lock_time: 940 blocks,
input: [
TxIn {
previous_output: OutPoint {
txid: cf3f0c985e6c130f2a3988e888d58d8cc51945efaceb7bfec70cd95ca086d0f4,
vout: 8,
},
script_sig: Script(),
sequence: Sequence(0x00000001),
witness: Witness: {
indices: 0,
indices_start: 0,
witnesses: [
],
}
,
},
TxIn {
previous_output: OutPoint {
txid: cf3f0c985e6c130f2a3988e888d58d8cc51945efaceb7bfec70cd95ca086d0f4,
vout: 11,
},
script_sig: Script(),
sequence: Sequence(0x00000001),
witness: Witness: {
indices: 0,
indices_start: 0,
witnesses: [
],
}
,
},
TxIn {
previous_output: OutPoint {
txid: cf3f0c985e6c130f2a3988e888d58d8cc51945efaceb7bfec70cd95ca086d0f4,
vout: 10,
},
script_sig: Script(),
sequence: Sequence(0x00000001),
witness: Witness: {
indices: 0,
indices_start: 0,
witnesses: [
],
}
,
},
],
output: [
TxOut {
value: 661 SAT,
script_pubkey: Script(OP_0 OP_PUSHBYTES_20 1dec8ff322b271c6fd27d855c2afeeacf868d9e5),
},
TxOut {
value: 0 SAT,
script_pubkey: Script(OP_RETURN OP_PUSHBYTES_32 0143f6b131ea8f65166dcfbe8ad9255068bd7c7459e6418d9bd0901293fca52f),
},
],
},
HTLCs at vout 8 and 10 were claimed by the remote party
2025-06-03T05:19:25.062327Z DEBUG lightning::chain::onchaintx:1036: Removing claim tracking due to maturation of claim tx for outpoints:
2025-06-03T05:19:25.062328Z DEBUG lightning::chain::onchaintx:1037: [OutPoint { txid: cf3f0c985e6c130f2a3988e888d58d8cc51945efaceb7bfec70cd95ca086d0f4, vout: 10 }]
2025-06-03T05:19:25.062331Z DEBUG lightning::chain::onchaintx:1036: Removing claim tracking due to maturation of claim tx for outpoints:
2025-06-03T05:19:25.062332Z DEBUG lightning::chain::onchaintx:1037: [OutPoint { txid: cf3f0c985e6c130f2a3988e888d58d8cc51945efaceb7bfec70cd95ca086d0f4, vout: 8 }]
2025-06-03T05:19:25.062336Z DEBUG lightning::chain::package:1341: Initiating fee rate bump from 1570 s/kWU (1133 s) to 253 s/kWU (182 s) using ForceBump strategy
2025-06-03T05:19:25.062339Z WARN lightning::chain::package:1388: Can't bump new claiming tx, output amount 0 would end up below dust threshold 294
Because the feerate is unchanged during the following feerate_bump
, it bypasses the dust check.
rust-lightning/lightning/src/chain/package.rs
Lines 1570 to 1590 in 97f0e4b
rust-lightning/lightning/src/chain/package.rs
Lines 1363 to 1374 in 97f0e4b
The HTLC sweep transaction with dust output:
{
"result": {
"txid": "2ade336033804fe0fd619a49f7c9dd50c455cc4cbceb8118252d90158de30cca",
"hash": "140c48a6b29aedc093955e43308f7078602ffdcdcbeaf9924740ca35e88d0d5b",
"version": 2,
"size": 343,
"vsize": 180,
"weight": 718,
"locktime": 950,
"vin": [
{
"txid": "cf3f0c985e6c130f2a3988e888d58d8cc51945efaceb7bfec70cd95ca086d0f4",
"vout": 11,
"scriptSig": {
"asm": "",
"hex": ""
},
"txinwitness": [
"304402200a424a7942f5f7887d6e1a2a8c17430a601ac9f015c3ee974e68dffee5d07677022075b6a389adeaa661ab0ff86b21fd8027f47b5421e6beaa2cea54da913a4a95ef01",
"",
"76a914a64d88bc4137d38b7cd5bdd77806f859cacb9bfb8763ac67210299164eef8e0b0fdde0556aa98143dfd7f2ff6fd18728b01b188041b4766d279c7c8201208763a914c797839ad0401e45b721c50a695fb9d241de668a88527c2103646ebe4f487aee44dc9e585301899699cf53645aff81095522da45d7921329f052ae677502db01b175ac6851b27568"
],
"sequence": 1
}
],
"vout": [
{
"value": "0.00000000",
"n": 0,
"scriptPubKey": {
"asm": "0 1dec8ff322b271c6fd27d855c2afeeacf868d9e5",
"desc": "addr(bc1qrhkgluezkfcudlf8mp2u9tlw4nux3k09jlxq4d)#p3wysca3",
"hex": "00141dec8ff322b271c6fd27d855c2afeeacf868d9e5",
"address": "bc1qrhkgluezkfcudlf8mp2u9tlw4nux3k09jlxq4d",
"type": "witness_v0_keyhash"
}
},
{
"value": "0.00000000",
"n": 1,
"scriptPubKey": {
"asm": "OP_RETURN 88aa90deac782500cbeb1787dccc9e941ea865a6511dba98f53bac3fa81135bd",
"desc": "raw(6a2088aa90deac782500cbeb1787dccc9e941ea865a6511dba98f53bac3fa81135bd)#pap99d6q",
"hex": "6a2088aa90deac782500cbeb1787dccc9e941ea865a6511dba98f53bac3fa81135bd",
"type": "nulldata"
}
}
]
},
"error": null
}