diff --git a/modules/core/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Syncing.kt b/modules/core/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Syncing.kt index 645a53396..694dc1102 100644 --- a/modules/core/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Syncing.kt +++ b/modules/core/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Syncing.kt @@ -27,29 +27,37 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent: Pair(state, listOf()) } is WaitForFundingSigned -> { - when (cmd.message.nextFundingTxId) { - // We retransmit our commit_sig, and will send our tx_signatures once we've received their commit_sig. - state.signingSession.fundingTx.txId -> { + val actions = buildList { + if (cmd.message.nextFundingTxId == state.signingSession.fundingTx.txId && cmd.message.nextLocalCommitmentNumber == 0L) { + // They haven't received our commit_sig: we retransmit it, and will send our tx_signatures once we've received + // their commit_sig or their tx_signatures (depending on who must send tx_signatures first). + logger.info { "re-sending commit_sig for channel creation with fundingTxId=${state.signingSession.fundingTx.txId}" } val commitSig = state.signingSession.remoteCommit.sign(channelKeys(), state.channelParams, state.signingSession) - Pair(state, listOf(ChannelAction.Message.Send(commitSig))) + add(ChannelAction.Message.Send(commitSig)) } - else -> Pair(state, listOf()) } + Pair(state, actions) } is WaitForFundingConfirmed -> { when (cmd.message.nextFundingTxId) { null -> Pair(state, listOf()) else -> { if (state.rbfStatus is RbfStatus.WaitingForSigs && state.rbfStatus.session.fundingTx.txId == cmd.message.nextFundingTxId) { - // We retransmit our commit_sig, and will send our tx_signatures once we've received their commit_sig. - logger.info { "re-sending commit_sig for rbf attempt with fundingTxId=${cmd.message.nextFundingTxId}" } - val commitSig = state.rbfStatus.session.remoteCommit.sign(channelKeys(), state.commitments.params, state.rbfStatus.session) - val actions = listOf(ChannelAction.Message.Send(commitSig)) + val actions = buildList { + if (cmd.message.nextLocalCommitmentNumber == 0L) { + // They haven't received our commit_sig: we retransmit it. + // We're waiting for signatures from them, and will send our tx_signatures once we receive them. + logger.info { "re-sending commit_sig for rbf attempt with fundingTxId=${cmd.message.nextFundingTxId}" } + val commitSig = state.rbfStatus.session.remoteCommit.sign(channelKeys(), state.commitments.params, state.rbfStatus.session) + add(ChannelAction.Message.Send(commitSig)) + } + } Pair(state, actions) } else if (state.latestFundingTx.txId == cmd.message.nextFundingTxId) { + // We've already received their commit_sig and sent our tx_signatures. We retransmit our tx_signatures + // and our commit_sig if they haven't received it already. val actions = buildList { - if (state.latestFundingTx.sharedTx is PartiallySignedSharedTransaction) { - // We have not received their tx_signatures: we retransmit our commit_sig because we don't know if they received it. + if (cmd.message.nextLocalCommitmentNumber == 0L) { logger.info { "re-sending commit_sig for fundingTxId=${cmd.message.nextFundingTxId}" } val commitSig = state.commitments.latest.remoteCommit.sign( channelKeys(), @@ -75,11 +83,11 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent: } is WaitForChannelReady -> { val actions = ArrayList() - + // We've already received their commit_sig and sent our tx_signatures. We retransmit our tx_signatures + // and our commit_sig if they haven't received it already. if (state.commitments.latest.fundingTxId == cmd.message.nextFundingTxId) { if (state.commitments.latest.localFundingStatus is LocalFundingStatus.UnconfirmedFundingTx) { - if (state.commitments.latest.localFundingStatus.sharedTx is PartiallySignedSharedTransaction) { - // If we have not received their tx_signatures, we can't tell whether they had received our commit_sig, so we need to retransmit it + if (cmd.message.nextLocalCommitmentNumber == 0L) { logger.info { "re-sending commit_sig for fundingTxId=${state.commitments.latest.fundingTxId}" } val commitSig = state.commitments.latest.remoteCommit.sign( channelKeys(), @@ -99,12 +107,10 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent: logger.warning { "cannot re-send tx_signatures for fundingTxId=${cmd.message.nextFundingTxId}, transaction is already confirmed" } } } - logger.debug { "re-sending channel_ready" } val nextPerCommitmentPoint = channelKeys().commitmentPoint(1) val channelReady = ChannelReady(state.commitments.channelId, nextPerCommitmentPoint) actions.add(ChannelAction.Message.Send(channelReady)) - Pair(state, actions) } is LegacyWaitForFundingLocked -> { @@ -132,16 +138,20 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent: // resume splice signing session if any val spliceStatus1 = if (state.spliceStatus is SpliceStatus.WaitingForSigs && state.spliceStatus.session.fundingTx.txId == cmd.message.nextFundingTxId) { - // We retransmit our commit_sig, and will send our tx_signatures once we've received their commit_sig. - logger.info { "re-sending commit_sig for splice attempt with fundingTxIndex=${state.spliceStatus.session.fundingTxIndex} fundingTxId=${state.spliceStatus.session.fundingTx.txId}" } - val commitSig = state.spliceStatus.session.remoteCommit.sign(channelKeys(), state.commitments.params, state.spliceStatus.session) - actions.add(ChannelAction.Message.Send(commitSig)) + if (cmd.message.nextLocalCommitmentNumber == state.commitments.remoteCommitIndex) { + // They haven't received our commit_sig: we retransmit it. + // We're waiting for signatures from them, and will send our tx_signatures once we receive them. + logger.info { "re-sending commit_sig for splice attempt with fundingTxIndex=${state.spliceStatus.session.fundingTxIndex} fundingTxId=${state.spliceStatus.session.fundingTx.txId}" } + val commitSig = state.spliceStatus.session.remoteCommit.sign(channelKeys(), state.commitments.params, state.spliceStatus.session) + actions.add(ChannelAction.Message.Send(commitSig)) + } state.spliceStatus } else if (state.commitments.latest.fundingTxId == cmd.message.nextFundingTxId) { when (val localFundingStatus = state.commitments.latest.localFundingStatus) { is LocalFundingStatus.UnconfirmedFundingTx -> { - if (localFundingStatus.sharedTx is PartiallySignedSharedTransaction) { - // If we have not received their tx_signatures, we can't tell whether they had received our commit_sig, so we need to retransmit it + // We've already received their commit_sig and sent our tx_signatures. We retransmit our tx_signatures + // and our commit_sig if they haven't received it already. + if (cmd.message.nextLocalCommitmentNumber == state.commitments.remoteCommitIndex) { logger.info { "re-sending commit_sig for fundingTxIndex=${state.commitments.latest.fundingTxIndex} fundingTxId=${state.commitments.latest.fundingTxId}" } val commitSig = state.commitments.latest.remoteCommit.sign( channelKeys(), diff --git a/modules/core/src/commonTest/kotlin/fr/acinq/lightning/channel/states/SpliceTestsCommon.kt b/modules/core/src/commonTest/kotlin/fr/acinq/lightning/channel/states/SpliceTestsCommon.kt index fe3bbe8e9..bcf7ab4a3 100644 --- a/modules/core/src/commonTest/kotlin/fr/acinq/lightning/channel/states/SpliceTestsCommon.kt +++ b/modules/core/src/commonTest/kotlin/fr/acinq/lightning/channel/states/SpliceTestsCommon.kt @@ -755,9 +755,9 @@ class SpliceTestsCommon : LightningTestSuite() { assertEquals(channelReestablishAlice.nextFundingTxId, spliceTxId) assertEquals(channelReestablishAlice.nextLocalCommitmentNumber, aliceCommitIndex + 1) val (bob4, actionsBob4) = bob3.process(ChannelCommand.MessageReceived(channelReestablishAlice)) - assertEquals(actionsBob4.size, 4) + assertEquals(actionsBob4.size, 3) val channelReestablishBob = actionsBob4.findOutgoingMessage() - actionsBob4.hasOutgoingMessage() + assertNull(actionsBob4.findOutgoingMessageOpt()) assertEquals(htlcs.aliceToBob.map { it.second }.toSet(), actionsBob4.filterIsInstance().map { it.add }.toSet()) assertEquals(channelReestablishBob.nextFundingTxId, spliceTxId) assertEquals(channelReestablishBob.nextLocalCommitmentNumber, bobCommitIndex) @@ -798,8 +798,8 @@ class SpliceTestsCommon : LightningTestSuite() { val (alice0, bob0, htlcs) = setupHtlcs(alice, bob) val aliceCommitIndex = alice0.commitments.localCommitIndex val bobCommitIndex = bob0.commitments.localCommitIndex - val (alice1, commitSigAlice1, bob1, _) = spliceInAndOutWithoutSigs(alice0, bob0, inAmounts = listOf(80_000.sat), outAmount = 50_000.sat) - val (bob2, actionsBob2) = bob1.process(ChannelCommand.MessageReceived(commitSigAlice1)) + val (alice1, commitSigAlice, bob1, _) = spliceInAndOutWithoutSigs(alice0, bob0, inAmounts = listOf(80_000.sat), outAmount = 50_000.sat) + val (bob2, actionsBob2) = bob1.process(ChannelCommand.MessageReceived(commitSigAlice)) assertIs>(bob2) val spliceTxId = actionsBob2.hasOutgoingMessage().txId assertEquals(bob2.state.spliceStatus, SpliceStatus.None) @@ -810,17 +810,17 @@ class SpliceTestsCommon : LightningTestSuite() { val (bob4, actionsBob4) = bob3.process(ChannelCommand.MessageReceived(channelReestablishAlice)) assertEquals(actionsBob4.size, 5) val channelReestablishBob = actionsBob4.findOutgoingMessage() - val commitSigBob2 = actionsBob4.findOutgoingMessage() + val commitSigBob = actionsBob4.findOutgoingMessage() assertEquals(htlcs.aliceToBob.map { it.second }.toSet(), actionsBob4.filterIsInstance().map { it.add }.toSet()) val txSigsBob = actionsBob4.findOutgoingMessage() assertEquals(channelReestablishBob.nextFundingTxId, spliceTxId) assertEquals(channelReestablishBob.nextLocalCommitmentNumber, bobCommitIndex + 1) val (alice3, actionsAlice3) = alice2.process(ChannelCommand.MessageReceived(channelReestablishBob)) - assertEquals(actionsAlice3.size, 3) + assertEquals(actionsAlice3.size, 2) assertEquals(htlcs.bobToAlice.map { it.second }.toSet(), actionsAlice3.filterIsInstance().map { it.add }.toSet()) - val commitSigAlice2 = actionsAlice3.findOutgoingMessage() + assertNull(actionsAlice3.findOutgoingMessageOpt()) - val (alice4, actionsAlice4) = alice3.process(ChannelCommand.MessageReceived(commitSigBob2)) + val (alice4, actionsAlice4) = alice3.process(ChannelCommand.MessageReceived(commitSigBob)) assertTrue(actionsAlice4.isEmpty()) val (alice5, actionsAlice5) = alice4.process(ChannelCommand.MessageReceived(txSigsBob)) assertIs>(alice5) @@ -834,24 +834,22 @@ class SpliceTestsCommon : LightningTestSuite() { actionsAlice5.has() val txSigsAlice = actionsAlice5.findOutgoingMessage() - val (bob5, actionsBob5) = bob4.process(ChannelCommand.MessageReceived(commitSigAlice2)) - assertTrue(actionsBob5.isEmpty()) - val (bob6, actionsBob6) = bob5.process(ChannelCommand.MessageReceived(txSigsAlice)) - assertIs>(bob6) - assertEquals(bob6.state.commitments.active.size, 2) - assertEquals(actionsBob6.size, 2) - assertEquals(actionsBob6.hasPublishTx(ChannelAction.Blockchain.PublishTx.Type.FundingTx).txid, spliceTxId) - actionsBob6.has() + val (bob5, actionsBob5) = bob4.process(ChannelCommand.MessageReceived(txSigsAlice)) + assertIs>(bob5) + assertEquals(bob5.state.commitments.active.size, 2) + assertEquals(actionsBob5.size, 2) + assertEquals(actionsBob5.hasPublishTx(ChannelAction.Blockchain.PublishTx.Type.FundingTx).txid, spliceTxId) + actionsBob5.has() - resolveHtlcs(alice5, bob6, htlcs, commitmentsCount = 2) + resolveHtlcs(alice5, bob5, htlcs, commitmentsCount = 2) } @Test fun `disconnect -- commit_sig received by bob -- zero-conf`() { val (alice, bob) = reachNormalWithConfirmedFundingTx(zeroConf = true) val (alice0, bob0, htlcs) = setupHtlcs(alice, bob) - val (alice1, commitSigAlice1, bob1, _) = spliceInAndOutWithoutSigs(alice0, bob0, inAmounts = listOf(75_000.sat), outAmount = 120_000.sat) - val (bob2, actionsBob2) = bob1.process(ChannelCommand.MessageReceived(commitSigAlice1)) + val (alice1, commitSigAlice, bob1, _) = spliceInAndOutWithoutSigs(alice0, bob0, inAmounts = listOf(75_000.sat), outAmount = 120_000.sat) + val (bob2, actionsBob2) = bob1.process(ChannelCommand.MessageReceived(commitSigAlice)) assertIs>(bob2) val spliceTxId = actionsBob2.hasOutgoingMessage().txId actionsBob2.hasOutgoingMessage() @@ -862,7 +860,7 @@ class SpliceTestsCommon : LightningTestSuite() { val (bob4, actionsBob4) = bob3.process(ChannelCommand.MessageReceived(channelReestablishAlice)) assertEquals(actionsBob4.size, 6) val channelReestablishBob = actionsBob4.findOutgoingMessage() - val commitSigBob2 = actionsBob4.findOutgoingMessage() + val commitSigBob = actionsBob4.findOutgoingMessage() val txSigsBob = actionsBob4.findOutgoingMessage() // splice_locked must always be sent *after* tx_signatures assertIs(actionsBob4.filterIsInstance().last().message) @@ -870,12 +868,11 @@ class SpliceTestsCommon : LightningTestSuite() { assertEquals(htlcs.aliceToBob.map { it.second }.toSet(), actionsBob4.filterIsInstance().map { it.add }.toSet()) assertEquals(channelReestablishBob.nextFundingTxId, spliceTxId) val (alice3, actionsAlice3) = alice2.process(ChannelCommand.MessageReceived(channelReestablishBob)) - assertEquals(actionsAlice3.size, 3) - val commitSigAlice2 = actionsAlice3.findOutgoingMessage() + assertEquals(actionsAlice3.size, 2) assertEquals(htlcs.bobToAlice.map { it.second }.toSet(), actionsAlice3.filterIsInstance().map { it.add }.toSet()) - assertEquals(commitSigAlice1.signature, commitSigAlice2.signature) + assertNull(actionsAlice3.findOutgoingMessageOpt()) - val (alice4, actionsAlice4) = alice3.process(ChannelCommand.MessageReceived(commitSigBob2)) + val (alice4, actionsAlice4) = alice3.process(ChannelCommand.MessageReceived(commitSigBob)) assertTrue(actionsAlice4.isEmpty()) val (alice5, actionsAlice5) = alice4.process(ChannelCommand.MessageReceived(txSigsBob)) assertIs>(alice5) @@ -896,37 +893,35 @@ class SpliceTestsCommon : LightningTestSuite() { actionsAlice6.find().also { assertEquals(it.txId, spliceTxId) } actionsAlice6.has() - val (bob5, actionsBob5) = bob4.process(ChannelCommand.MessageReceived(commitSigAlice2)) - assertTrue(actionsBob5.isEmpty()) - val (bob6, actionsBob6) = bob5.process(ChannelCommand.MessageReceived(txSigsAlice)) + val (bob5, actionsBob5) = bob4.process(ChannelCommand.MessageReceived(txSigsAlice)) + assertIs>(bob5) + assertEquals(bob5.state.commitments.active.size, 2) + assertEquals(actionsBob5.size, 2) + assertEquals(actionsBob5.hasPublishTx(ChannelAction.Blockchain.PublishTx.Type.FundingTx).txid, spliceTxId) + actionsBob5.has() + val (bob6, actionsBob6) = bob5.process(ChannelCommand.MessageReceived(spliceLockedAlice)) assertIs>(bob6) - assertEquals(bob6.state.commitments.active.size, 2) + assertEquals(bob6.state.commitments.active.size, 1) assertEquals(actionsBob6.size, 2) - assertEquals(actionsBob6.hasPublishTx(ChannelAction.Blockchain.PublishTx.Type.FundingTx).txid, spliceTxId) + actionsBob6.find().also { assertEquals(it.txId, spliceTxId) } actionsBob6.has() - val (bob7, actionsBob7) = bob6.process(ChannelCommand.MessageReceived(spliceLockedAlice)) - assertIs>(bob7) - assertEquals(bob7.state.commitments.active.size, 1) - assertEquals(actionsBob7.size, 2) - actionsBob7.find().also { assertEquals(it.txId, spliceTxId) } - actionsBob7.has() - resolveHtlcs(alice6, bob7, htlcs, commitmentsCount = 1) + resolveHtlcs(alice6, bob6, htlcs, commitmentsCount = 1) } @Test fun `disconnect -- tx_signatures received by alice -- confirms while bob is offline`() { val (alice, bob) = reachNormalWithConfirmedFundingTx() val (alice0, bob0, htlcs) = setupHtlcs(alice, bob) - val (alice1, commitSigAlice1, bob1, commitSigBob1) = spliceInAndOutWithoutSigs(alice0, bob0, inAmounts = listOf(70_000.sat, 60_000.sat), outAmount = 150_000.sat) + val (alice1, commitSigAlice, bob1, commitSigBob) = spliceInAndOutWithoutSigs(alice0, bob0, inAmounts = listOf(70_000.sat, 60_000.sat), outAmount = 150_000.sat) // Bob completes the splice, but is missing Alice's tx_signatures. - val (bob2, actionsBob2) = bob1.process(ChannelCommand.MessageReceived(commitSigAlice1)) + val (bob2, actionsBob2) = bob1.process(ChannelCommand.MessageReceived(commitSigAlice)) assertIs>(bob2) val txSigsBob = actionsBob2.hasOutgoingMessage() assertEquals(bob2.state.spliceStatus, SpliceStatus.None) // Alice completes the splice, but Bob doesn't receive her tx_signatures. - val (alice2, actionsAlice2) = alice1.process(ChannelCommand.MessageReceived(commitSigBob1)) + val (alice2, actionsAlice2) = alice1.process(ChannelCommand.MessageReceived(commitSigBob)) assertTrue(actionsAlice2.isEmpty()) val (alice3, actionsAlice3) = alice2.process(ChannelCommand.MessageReceived(txSigsBob)) assertIs>(alice3) diff --git a/modules/core/src/commonTest/kotlin/fr/acinq/lightning/channel/states/SyncingTestsCommon.kt b/modules/core/src/commonTest/kotlin/fr/acinq/lightning/channel/states/SyncingTestsCommon.kt index 9d06669c2..081c87384 100644 --- a/modules/core/src/commonTest/kotlin/fr/acinq/lightning/channel/states/SyncingTestsCommon.kt +++ b/modules/core/src/commonTest/kotlin/fr/acinq/lightning/channel/states/SyncingTestsCommon.kt @@ -134,23 +134,22 @@ class SyncingTestsCommon : LightningTestSuite() { assertEquals(channelReestablishBob.nextLocalCommitmentNumber, 0) val (bob2, actionsBob2) = bob1.process(ChannelCommand.MessageReceived(channelReestablishAlice)) - val commitSigBob1 = actionsBob2.hasOutgoingMessage() - assertNull(actionsBob2.findOutgoingMessageOpt()) + // Bob is waiting for Alice's commit_sig before sending his tx_signatures. + assertTrue(actionsBob2.isEmpty()) val (alice3, actionsAlice3) = alice2.process(ChannelCommand.MessageReceived(channelReestablishBob)) assertEquals(actionsAlice3.size, 1) val commitSigAlice = actionsAlice3.hasOutgoingMessage() - val (alice4, _) = alice3.process(ChannelCommand.MessageReceived(commitSigBob1)) val (bob3, actionsBob3) = bob2.process(ChannelCommand.MessageReceived(commitSigAlice)) assertIs(bob3.state) val txSigsBob = actionsBob3.findOutgoingMessage() - val (alice5, actionsAlice5) = alice4.process(ChannelCommand.MessageReceived(txSigsBob)) - assertIs(alice5.state) - val txSigsAlice = actionsAlice5.hasOutgoingMessage() - actionsAlice5.has() - assertEquals(actionsAlice5.find().tx.txid, fundingTxId) + val (alice4, actionsAlice4) = alice3.process(ChannelCommand.MessageReceived(txSigsBob)) + assertIs(alice4.state) + val txSigsAlice = actionsAlice4.hasOutgoingMessage() + actionsAlice4.has() + assertEquals(actionsAlice4.find().tx.txid, fundingTxId) val (bob4, actionsBob4) = bob3.process(ChannelCommand.MessageReceived(txSigsAlice)) assertIs(bob4.state) @@ -178,8 +177,7 @@ class SyncingTestsCommon : LightningTestSuite() { val txSigsBob = actionsBob3.hasOutgoingMessage() val (alice2, actionsAlice2) = alice1.process(ChannelCommand.MessageReceived(channelReestablishBob)) - assertEquals(actionsAlice2.size, 1) - actionsAlice2.hasOutgoingMessage() + assertTrue(actionsAlice2.isEmpty()) val (alice3, actionsAlice3) = alice2.process(ChannelCommand.MessageReceived(commitSigBob)) assertTrue(actionsAlice3.isEmpty()) val (alice4, actionsAlice4) = alice3.process(ChannelCommand.MessageReceived(txSigsBob)) @@ -213,25 +211,23 @@ class SyncingTestsCommon : LightningTestSuite() { val channelReestablishBob = actionsBob3.hasOutgoingMessage() assertEquals(channelReestablishBob.nextFundingTxId, fundingTxId) assertEquals(channelReestablishBob.nextLocalCommitmentNumber, 1) - actionsBob3.hasOutgoingMessage() + assertNull(actionsBob3.findOutgoingMessageOpt()) val txSigsBob = actionsBob3.hasOutgoingMessage() val (alice3, actionsAlice3) = alice2.process(ChannelCommand.MessageReceived(channelReestablishBob)) - assertEquals(actionsAlice3.size, 1) - actionsAlice3.hasOutgoingMessage() - val (alice4, _) = alice3.process(ChannelCommand.MessageReceived(commitSigBob)) + assertTrue(actionsAlice3.isEmpty()) + val (alice4, actionsAlice4) = alice3.process(ChannelCommand.MessageReceived(commitSigBob)) + assertTrue(actionsAlice4.isEmpty()) val (alice5, actionsAlice5) = alice4.process(ChannelCommand.MessageReceived(txSigsBob)) assertIs(alice5.state) val txSigsAlice = actionsAlice5.hasOutgoingMessage() actionsAlice5.has() assertEquals(actionsAlice5.find().tx.txid, fundingTxId) - val (bob4, actionsBob4) = bob3.process(ChannelCommand.MessageReceived(commitSigAlice)) - assertTrue(actionsBob4.isEmpty()) - val (bob5, actionsBob5) = bob4.process(ChannelCommand.MessageReceived(txSigsAlice)) - assertIs(bob5.state) - actionsBob5.has() - assertEquals(actionsBob5.find().tx.txid, fundingTxId) + val (bob4, actionsBob4) = bob3.process(ChannelCommand.MessageReceived(txSigsAlice)) + assertIs(bob4.state) + actionsBob4.has() + assertEquals(actionsBob4.find().tx.txid, fundingTxId) } @Test @@ -256,6 +252,8 @@ class SyncingTestsCommon : LightningTestSuite() { val (bob3, actionsBob3) = bob2.process(ChannelCommand.MessageReceived(channelReestablishAlice)) assertEquals(actionsBob3.size, 1) val channelReestablishBob = actionsBob3.hasOutgoingMessage() + assertNull(actionsBob3.findOutgoingMessageOpt()) + assertNull(actionsBob3.findOutgoingMessageOpt()) assertEquals(channelReestablishBob.nextFundingTxId, fundingTxId) assertEquals(channelReestablishBob.nextLocalCommitmentNumber, 1) @@ -321,16 +319,15 @@ class SyncingTestsCommon : LightningTestSuite() { val (bob3, actionsBob3) = bob2.process(ChannelCommand.MessageReceived(channelReestablishAlice)) assertIs(bob3.state) assertEquals(bob3.state.rbfStatus, RbfStatus.None) - assertEquals(actionsBob3.size, 3) + assertEquals(actionsBob3.size, 2) val channelReestablishBob = actionsBob3.hasOutgoingMessage() assertEquals(channelReestablishBob.nextFundingTxId, rbfFundingTxId) assertEquals(channelReestablishBob.nextLocalCommitmentNumber, 1) - actionsBob3.hasOutgoingMessage() + assertNull(actionsBob3.findOutgoingMessageOpt()) val txSigsBob = actionsBob3.hasOutgoingMessage() val (alice3, actionsAlice3) = alice2.process(ChannelCommand.MessageReceived(channelReestablishBob)) - assertEquals(actionsAlice3.size, 1) - actionsAlice3.hasOutgoingMessage() + assertTrue(actionsAlice3.isEmpty()) val (bob4, actionsBob4) = bob3.process(ChannelCommand.MessageReceived(commitSigAlice)) assertIs(bob4.state)