From bb8f36a8d3dbe966d367a082a14a783971cf22f4 Mon Sep 17 00:00:00 2001 From: Richard Myers Date: Tue, 6 Feb 2024 15:08:34 +0100 Subject: [PATCH] Test if active htlcs are failed when a revoked inactive commit is claimed This test is equivalent to the multiple splice test updated in Eclair PR# 2801. --- .../channel/states/SpliceTestsCommon.kt | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/commonTest/kotlin/fr/acinq/lightning/channel/states/SpliceTestsCommon.kt b/src/commonTest/kotlin/fr/acinq/lightning/channel/states/SpliceTestsCommon.kt index b2be8a708..c0ba7123e 100644 --- a/src/commonTest/kotlin/fr/acinq/lightning/channel/states/SpliceTestsCommon.kt +++ b/src/commonTest/kotlin/fr/acinq/lightning/channel/states/SpliceTestsCommon.kt @@ -1180,6 +1180,49 @@ class SpliceTestsCommon : LightningTestSuite() { handlePreviousRevokedRemoteClose(alice6, bobCommitTx) } + @Test + fun `force-close -- revoked previous inactive commitment after two splices`() { + val (alice, bob) = reachNormalWithConfirmedFundingTx(zeroConf = true) + val (alice0, bob0, _) = setupHtlcs(alice, bob) + val (alice1, bob1) = spliceOut(alice0, bob0, 50_000.sat) + val spliceTx = alice1.commitments.latest.localFundingStatus.signedTx!! + val (alice2, _) = alice1.process(ChannelCommand.MessageReceived(SpliceLocked(alice.channelId, spliceTx.txid))) + assertIs>(alice2) + assertEquals(alice2.commitments.active.size, 1) + assertEquals(alice2.commitments.inactive.size, 1) + val (bob2, _) = bob1.process(ChannelCommand.MessageReceived(SpliceLocked(bob.channelId, spliceTx.txid))) + assertIs>(bob2) + assertEquals(bob2.commitments.active.size, 1) + assertEquals(bob2.commitments.inactive.size, 1) + val bobCommitTx = bob2.commitments.inactive.first().localCommit.publishableTxs.commitTx.tx + + // Alice sends an HTLC to Bob, which revokes the inactive commitment. + val (nodes3, preimage, htlc) = addHtlc(25_000_000.msat, alice2, bob2) + val (alice4, bob4) = crossSign(nodes3.first, nodes3.second, commitmentsCount = 1) + val (alice5, bob5) = fulfillHtlc(htlc.id, preimage, alice4, bob4) + val (bob6, alice6) = crossSign(bob5, alice5, commitmentsCount = 1) + + val (alice7, bob7) = spliceOut(alice6, bob6, 50_000.sat) + val spliceTx1 = alice7.commitments.latest.localFundingStatus.signedTx!! + val (alice8, _) = alice7.process(ChannelCommand.MessageReceived(SpliceLocked(alice.channelId, spliceTx1.txid))) + assertIs>(alice8) + assertEquals(alice8.commitments.active.size, 1) + assertEquals(alice8.commitments.inactive.size, 2) + val (bob8, _) = bob7.process(ChannelCommand.MessageReceived(SpliceLocked(bob.channelId, spliceTx1.txid))) + assertIs>(bob8) + assertEquals(bob8.commitments.active.size, 1) + assertEquals(bob8.commitments.inactive.size, 2) + + // Alice sends an HTLC to Bob, which revokes the inactive commitment. + val (nodes9, preimage1, htlc1) = addHtlc(25_000_000.msat, alice8, bob8) + val (alice10, bob10) = crossSign(nodes9.first, nodes9.second, commitmentsCount = 1) + val (alice11, bob11) = fulfillHtlc(htlc1.id, preimage1, alice10, bob10) + val (_, alice12) = crossSign(bob11, alice11, commitmentsCount = 1) + + // Bob force-closes using the revoked commitment. + handlePreviousRevokedRemoteClose(alice12, bobCommitTx) + } + @Test fun `recv invalid htlc signatures during splice`() { val (alice, bob) = reachNormalWithConfirmedFundingTx()