@@ -1915,6 +1915,21 @@ class NormalStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with
1915
1915
awaitCond(alice.stateName == NORMAL )
1916
1916
}
1917
1917
1918
+ test(" recv CMD_FORCECLOSE (with pending unsigned htlcs)" ) { f =>
1919
+ import f ._
1920
+ val sender = TestProbe ()
1921
+ val (_, htlc1) = addHtlc(10000 msat, alice, bob, alice2bob, bob2alice, sender.ref)
1922
+ sender.expectMsgType[RES_SUCCESS [CMD_ADD_HTLC ]]
1923
+ val aliceData = alice.stateData.asInstanceOf [DATA_NORMAL ]
1924
+ assert(aliceData.commitments.localChanges.proposed.size == 1 )
1925
+
1926
+ // actual test starts here
1927
+ alice ! CMD_FORCECLOSE (sender.ref)
1928
+ sender.expectMsgType[RES_SUCCESS [CMD_FORCECLOSE ]]
1929
+ val addSettled = relayerA.expectMsgType[RES_ADD_SETTLED [Origin , HtlcResult .ChannelFailureBeforeSigned .type ]]
1930
+ assert(addSettled.htlc == htlc1)
1931
+ }
1932
+
1918
1933
def testShutdown (f : FixtureParam , script_opt : Option [ByteVector ]): Unit = {
1919
1934
import f ._
1920
1935
val bobParams = bob.stateData.asInstanceOf [DATA_NORMAL ].commitments.localParams
@@ -2395,6 +2410,22 @@ class NormalStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with
2395
2410
assert(claimFee == expectedFee)
2396
2411
}
2397
2412
2413
+ test(" recv WatchFundingSpentTriggered (their commit w/ pending unsigned htlcs)" ) { f =>
2414
+ import f ._
2415
+ val sender = TestProbe ()
2416
+ val (_, htlc1) = addHtlc(10000 msat, alice, bob, alice2bob, bob2alice, sender.ref)
2417
+ sender.expectMsgType[RES_SUCCESS [CMD_ADD_HTLC ]]
2418
+ val aliceData = alice.stateData.asInstanceOf [DATA_NORMAL ]
2419
+ assert(aliceData.commitments.localChanges.proposed.size == 1 )
2420
+
2421
+ // actual test starts here
2422
+ // bob publishes his current commit tx
2423
+ val bobCommitTx = bob.stateData.asInstanceOf [DATA_NORMAL ].commitments.localCommit.commitTxAndRemoteSig.commitTx.tx
2424
+ alice ! WatchFundingSpentTriggered (bobCommitTx)
2425
+ val addSettled = relayerA.expectMsgType[RES_ADD_SETTLED [Origin , HtlcResult .ChannelFailureBeforeSigned .type ]]
2426
+ assert(addSettled.htlc == htlc1)
2427
+ }
2428
+
2398
2429
test(" recv WatchFundingSpentTriggered (their *next* commit w/ htlc)" ) { f =>
2399
2430
import f ._
2400
2431
@@ -2456,6 +2487,29 @@ class NormalStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with
2456
2487
assert(getClaimHtlcTimeoutTxs(rcp).length === 2 )
2457
2488
}
2458
2489
2490
+ test(" recv WatchFundingSpentTriggered (their *next* commit w/ pending unsigned htlcs)" ) { f =>
2491
+ import f ._
2492
+ val sender = TestProbe ()
2493
+ addHtlc(10000 msat, alice, bob, alice2bob, bob2alice, sender.ref)
2494
+ sender.expectMsgType[RES_SUCCESS [CMD_ADD_HTLC ]]
2495
+ // alice sign but we intercept bob's revocation
2496
+ alice ! CMD_SIGN ()
2497
+ alice2bob.expectMsgType[CommitSig ]
2498
+ alice2bob.forward(bob)
2499
+ bob2alice.expectMsgType[RevokeAndAck ]
2500
+ val (_, htlc2) = addHtlc(10000 msat, alice, bob, alice2bob, bob2alice, sender.ref)
2501
+ sender.expectMsgType[RES_SUCCESS [CMD_ADD_HTLC ]]
2502
+ val aliceData = alice.stateData.asInstanceOf [DATA_NORMAL ]
2503
+ assert(aliceData.commitments.localChanges.proposed.size == 1 )
2504
+
2505
+ // actual test starts here
2506
+ // bob publishes his current commit tx
2507
+ val bobCommitTx = bob.stateData.asInstanceOf [DATA_NORMAL ].commitments.localCommit.commitTxAndRemoteSig.commitTx.tx
2508
+ alice ! WatchFundingSpentTriggered (bobCommitTx)
2509
+ val addSettled = relayerA.expectMsgType[RES_ADD_SETTLED [Origin , HtlcResult .ChannelFailureBeforeSigned .type ]]
2510
+ assert(addSettled.htlc == htlc2)
2511
+ }
2512
+
2459
2513
test(" recv WatchFundingSpentTriggered (revoked commit)" ) { f =>
2460
2514
import f ._
2461
2515
// initially we have :
@@ -2566,6 +2620,29 @@ class NormalStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with
2566
2620
htlcPenaltyTxs.foreach(htlcPenaltyTx => Transaction .correctlySpends(htlcPenaltyTx, Seq (revokedTx), ScriptFlags .STANDARD_SCRIPT_VERIFY_FLAGS ))
2567
2621
}
2568
2622
2623
+ test(" recv WatchFundingSpentTriggered (revoked commit w/ pending unsigned htlcs)" ) { f =>
2624
+ import f ._
2625
+ val sender = TestProbe ()
2626
+ addHtlc(10000 msat, alice, bob, alice2bob, bob2alice, sender.ref)
2627
+ sender.expectMsgType[RES_SUCCESS [CMD_ADD_HTLC ]]
2628
+ crossSign(alice, bob, alice2bob, bob2alice)
2629
+ val bobRevokedCommitTx = bob.stateData.asInstanceOf [DATA_NORMAL ].commitments.localCommit.commitTxAndRemoteSig.commitTx.tx
2630
+ addHtlc(10000 msat, alice, bob, alice2bob, bob2alice, sender.ref)
2631
+ sender.expectMsgType[RES_SUCCESS [CMD_ADD_HTLC ]]
2632
+ crossSign(alice, bob, alice2bob, bob2alice)
2633
+ val (_, htlc3) = addHtlc(10000 msat, alice, bob, alice2bob, bob2alice, sender.ref)
2634
+ sender.expectMsgType[RES_SUCCESS [CMD_ADD_HTLC ]]
2635
+ val aliceData = alice.stateData.asInstanceOf [DATA_NORMAL ]
2636
+ assert(aliceData.commitments.localChanges.proposed.size == 1 )
2637
+
2638
+ // actual test starts here
2639
+ // bob publishes his current commit tx
2640
+
2641
+ alice ! WatchFundingSpentTriggered (bobRevokedCommitTx)
2642
+ val addSettled = relayerA.expectMsgType[RES_ADD_SETTLED [Origin , HtlcResult .ChannelFailureBeforeSigned .type ]]
2643
+ assert(addSettled.htlc == htlc3)
2644
+ }
2645
+
2569
2646
test(" recv Error" ) { f =>
2570
2647
import f ._
2571
2648
val (ra1, htlca1) = addHtlc(250000000 msat, alice, bob, alice2bob, bob2alice)
@@ -2654,6 +2731,20 @@ class NormalStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with
2654
2731
assert(localCommitPublished.commitTx.txid == bobCommitTx.txid)
2655
2732
}
2656
2733
2734
+ test(" recv Error (with pending unsigned htlcs)" ) { f =>
2735
+ import f ._
2736
+ val sender = TestProbe ()
2737
+ val (_, htlc1) = addHtlc(10000 msat, alice, bob, alice2bob, bob2alice, sender.ref)
2738
+ sender.expectMsgType[RES_SUCCESS [CMD_ADD_HTLC ]]
2739
+ val aliceData = alice.stateData.asInstanceOf [DATA_NORMAL ]
2740
+ assert(aliceData.commitments.localChanges.proposed.size == 1 )
2741
+
2742
+ // actual test starts here
2743
+ alice ! Error (ByteVector32 .Zeroes , " oops" )
2744
+ val addSettled = relayerA.expectMsgType[RES_ADD_SETTLED [Origin , HtlcResult .ChannelFailureBeforeSigned .type ]]
2745
+ assert(addSettled.htlc == htlc1)
2746
+ }
2747
+
2657
2748
test(" recv WatchFundingDeeplyBuriedTriggered" , Tag (StateTestsTags .ChannelsPublic )) { f =>
2658
2749
import f ._
2659
2750
alice ! WatchFundingDeeplyBuriedTriggered (400000 , 42 , null )
@@ -2808,8 +2899,12 @@ class NormalStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with
2808
2899
// actual test starts here
2809
2900
Thread .sleep(1100 )
2810
2901
alice ! INPUT_DISCONNECTED
2811
- assert(relayerA.expectMsgType[RES_ADD_SETTLED [Origin , HtlcResult .Disconnected ]].htlc.paymentHash === htlc1.paymentHash)
2812
- assert(relayerA.expectMsgType[RES_ADD_SETTLED [Origin , HtlcResult .Disconnected ]].htlc.paymentHash === htlc2.paymentHash)
2902
+ val addSettled1 = relayerA.expectMsgType[RES_ADD_SETTLED [Origin , HtlcResult ]]
2903
+ assert(addSettled1.htlc == htlc1)
2904
+ assert(addSettled1.result.isInstanceOf [HtlcResult .DisconnectedBeforeSigned ])
2905
+ val addSettled2 = relayerA.expectMsgType[RES_ADD_SETTLED [Origin , HtlcResult ]]
2906
+ assert(addSettled2.htlc == htlc2)
2907
+ assert(addSettled2.result.isInstanceOf [HtlcResult .DisconnectedBeforeSigned ])
2813
2908
assert(! Announcements .isEnabled(channelUpdateListener.expectMsgType[LocalChannelUpdate ].channelUpdate.channelFlags))
2814
2909
awaitCond(alice.stateName == OFFLINE )
2815
2910
}
@@ -2851,8 +2946,8 @@ class NormalStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with
2851
2946
// actual test starts here
2852
2947
Thread .sleep(1100 )
2853
2948
alice ! INPUT_DISCONNECTED
2854
- assert(relayerA.expectMsgType[RES_ADD_SETTLED [Origin , HtlcResult .Disconnected ]].htlc.paymentHash === htlc1.paymentHash)
2855
- assert(relayerA.expectMsgType[RES_ADD_SETTLED [Origin , HtlcResult .Disconnected ]].htlc.paymentHash === htlc2.paymentHash)
2949
+ assert(relayerA.expectMsgType[RES_ADD_SETTLED [Origin , HtlcResult .DisconnectedBeforeSigned ]].htlc.paymentHash === htlc1.paymentHash)
2950
+ assert(relayerA.expectMsgType[RES_ADD_SETTLED [Origin , HtlcResult .DisconnectedBeforeSigned ]].htlc.paymentHash === htlc2.paymentHash)
2856
2951
val update2a = channelUpdateListener.expectMsgType[LocalChannelUpdate ]
2857
2952
assert(update1a.channelUpdate.timestamp < update2a.channelUpdate.timestamp)
2858
2953
assert(! Announcements .isEnabled(update2a.channelUpdate.channelFlags))
0 commit comments