@@ -53,7 +53,9 @@ class CommitmentsSpec extends TestkitBaseClass with StateTestsHelperMethods {
53
53
54
54
test(" take additional HTLC fee into account" ) { f =>
55
55
import f ._
56
- val htlcOutputFee = 1720000 msat
56
+ // The fee for a single HTLC is 1720000 msat but the funder keeps an extra reserve to make sure we're able to handle
57
+ // an additional HTLC at twice the feerate (hence the multiplier).
58
+ val htlcOutputFee = 3 * 1720000 msat
57
59
val a = 772760000 msat // initial balance alice
58
60
val ac0 = alice.stateData.asInstanceOf [DATA_NORMAL ].commitments
59
61
val bc0 = bob.stateData.asInstanceOf [DATA_NORMAL ].commitments
@@ -75,7 +77,8 @@ class CommitmentsSpec extends TestkitBaseClass with StateTestsHelperMethods {
75
77
import f ._
76
78
77
79
val fee = 1720000 msat // fee due to the additional htlc output
78
- val a = (772760000 msat) - fee // initial balance alice
80
+ val funderFeeReserve = fee * 2 // extra reserve to handle future fee increase
81
+ val a = (772760000 msat) - fee - funderFeeReserve // initial balance alice
79
82
val b = 190000000 msat // initial balance bob
80
83
val p = 42000000 msat // a->b payment
81
84
@@ -159,7 +162,8 @@ class CommitmentsSpec extends TestkitBaseClass with StateTestsHelperMethods {
159
162
import f ._
160
163
161
164
val fee = 1720000 msat // fee due to the additional htlc output
162
- val a = (772760000 msat) - fee // initial balance alice
165
+ val funderFeeReserve = fee * 2 // extra reserve to handle future fee increase
166
+ val a = (772760000 msat) - fee - funderFeeReserve // initial balance alice
163
167
val b = 190000000 msat // initial balance bob
164
168
val p = 42000000 msat // a->b payment
165
169
@@ -243,7 +247,8 @@ class CommitmentsSpec extends TestkitBaseClass with StateTestsHelperMethods {
243
247
import f ._
244
248
245
249
val fee = 1720000 msat // fee due to the additional htlc output
246
- val a = (772760000 msat) - fee // initial balance alice
250
+ val funderFeeReserve = fee * 2 // extra reserve to handle future fee increase
251
+ val a = (772760000 msat) - fee - funderFeeReserve // initial balance alice
247
252
val b = 190000000 msat // initial balance bob
248
253
val p1 = 10000000 msat // a->b payment
249
254
val p2 = 20000000 msat // a->b payment
@@ -386,6 +391,23 @@ class CommitmentsSpec extends TestkitBaseClass with StateTestsHelperMethods {
386
391
assert(ac16.availableBalanceForReceive == b + p1 - p3)
387
392
}
388
393
394
+ // See https://github.com/lightningnetwork/lightning-rfc/issues/728
395
+ test(" funder keeps additional reserve to avoid channel being stuck" ) { f =>
396
+ val isFunder = true
397
+ val c = CommitmentsSpec .makeCommitments(100000000 msat, 50000000 msat, 2500 , 546 sat, isFunder)
398
+ val (_, cmdAdd) = makeCmdAdd(c.availableBalanceForSend, randomKey.publicKey, f.currentBlockHeight)
399
+ val Right ((c1, _)) = sendAdd(c, cmdAdd, Local (UUID .randomUUID, None ), f.currentBlockHeight)
400
+ assert(c1.availableBalanceForSend === 0 .msat)
401
+
402
+ // We should be able to handle a fee increase.
403
+ val (c2, _) = sendFee(c1, CMD_UPDATE_FEE (3000 ))
404
+
405
+ // Now we shouldn't be able to send until we receive enough to handle the updated commit tx fee (even trimmed HTLCs shouldn't be sent).
406
+ val (_, cmdAdd1) = makeCmdAdd(100 msat, randomKey.publicKey, f.currentBlockHeight)
407
+ val Left (e) = sendAdd(c2, cmdAdd1, Local (UUID .randomUUID, None ), f.currentBlockHeight)
408
+ assert(e.isInstanceOf [InsufficientFunds ])
409
+ }
410
+
389
411
test(" can send availableForSend" ) { f =>
390
412
for (isFunder <- Seq (true , false )) {
391
413
val c = CommitmentsSpec .makeCommitments(702000000 msat, 52000000 msat, 2679 , 546 sat, isFunder)
0 commit comments