@@ -25,7 +25,7 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent:
2525 val (nextState, actions) = when (state) {
2626 is WaitForFundingSigned -> {
2727 val actions = buildList {
28- if (cmd.message.nextFundingTxId == state.signingSession.fundingTx.txId && cmd.message.nextLocalCommitmentNumber == 0L ) {
28+ if (cmd.message.nextFundingTxId == state.signingSession.fundingTx.txId && cmd.message.retransmitInteractiveTxCommitSig ) {
2929 // They haven't received our commit_sig: we retransmit it, and will send our tx_signatures once we've received
3030 // their commit_sig or their tx_signatures (depending on who must send tx_signatures first).
3131 logger.info { " re-sending commit_sig for channel creation with fundingTxId=${state.signingSession.fundingTx.txId} " }
@@ -44,7 +44,7 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent:
4444 else -> {
4545 if (state.rbfStatus is RbfStatus .WaitingForSigs && state.rbfStatus.session.fundingTx.txId == cmd.message.nextFundingTxId) {
4646 val actions = buildList {
47- if (cmd.message.nextLocalCommitmentNumber == 0L ) {
47+ if (cmd.message.retransmitInteractiveTxCommitSig ) {
4848 // They haven't received our commit_sig: we retransmit it.
4949 // We're waiting for signatures from them, and will send our tx_signatures once we receive them.
5050 logger.info { " re-sending commit_sig for rbf attempt with fundingTxId=${cmd.message.nextFundingTxId} " }
@@ -59,7 +59,7 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent:
5959 // We've already received their commit_sig and sent our tx_signatures. We retransmit our tx_signatures
6060 // and our commit_sig if they haven't received it already.
6161 val actions = buildList {
62- if (cmd.message.nextLocalCommitmentNumber == 0L ) {
62+ if (cmd.message.retransmitInteractiveTxCommitSig ) {
6363 logger.info { " re-sending commit_sig for fundingTxId=${cmd.message.nextFundingTxId} " }
6464 when (val commitSig = state.commitments.latest.remoteCommit.sign(
6565 state.commitments.channelParams,
@@ -91,11 +91,10 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent:
9191 }
9292 is WaitForChannelReady -> {
9393 val actions = ArrayList <ChannelAction >()
94- // We've already received their commit_sig and sent our tx_signatures. We retransmit our tx_signatures
95- // and our commit_sig if they haven't received it already.
94+ // If they haven't received our signatures for the channel funding transaction, we retransmit them.
9695 if (state.commitments.latest.fundingTxId == cmd.message.nextFundingTxId) {
9796 if (state.commitments.latest.localFundingStatus is LocalFundingStatus .UnconfirmedFundingTx ) {
98- if (cmd.message.nextLocalCommitmentNumber == 0L ) {
97+ if (cmd.message.retransmitInteractiveTxCommitSig ) {
9998 logger.info { " re-sending commit_sig for fundingTxId=${state.commitments.latest.fundingTxId} " }
10099 when (val commitSig = state.commitments.latest.remoteCommit.sign(
101100 state.commitments.channelParams,
@@ -143,7 +142,7 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent:
143142
144143 // resume splice signing session if any
145144 val spliceStatus1 = if (state.spliceStatus is SpliceStatus .WaitingForSigs && state.spliceStatus.session.fundingTx.txId == cmd.message.nextFundingTxId) {
146- if (cmd.message.nextLocalCommitmentNumber == state.commitments.remoteCommitIndex ) {
145+ if (cmd.message.retransmitInteractiveTxCommitSig ) {
147146 // They haven't received our commit_sig: we retransmit it.
148147 // We're waiting for signatures from them, and will send our tx_signatures once we receive them.
149148 logger.info { " re-sending commit_sig for splice attempt with fundingTxIndex=${state.spliceStatus.session.fundingParams.fundingTxIndex} fundingTxId=${state.spliceStatus.session.fundingTx.txId} " }
@@ -158,7 +157,7 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent:
158157 is LocalFundingStatus .UnconfirmedFundingTx -> {
159158 // We've already received their commit_sig and sent our tx_signatures. We retransmit our tx_signatures
160159 // and our commit_sig if they haven't received it already.
161- if (cmd.message.nextLocalCommitmentNumber == state.commitments.remoteCommitIndex ) {
160+ if (cmd.message.retransmitInteractiveTxCommitSig ) {
162161 logger.info { " re-sending commit_sig for fundingTxIndex=${state.commitments.latest.fundingTxIndex} fundingTxId=${state.commitments.latest.fundingTxId} " }
163162 when (val commitSig = state.commitments.latest.remoteCommit.sign(
164163 state.commitments.channelParams,
@@ -177,6 +176,8 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent:
177176 }
178177 logger.info { " re-sending tx_signatures for fundingTxId=${cmd.message.nextFundingTxId} " }
179178 actions.add(ChannelAction .Message .Send (localFundingStatus.sharedTx.localSigs))
179+ // If we're using 0-conf, we also retransmit our splice_locked.
180+ if (staticParams.useZeroConf) actions.add(ChannelAction .Message .Send (SpliceLocked (channelId, cmd.message.nextFundingTxId)))
180181 }
181182 is LocalFundingStatus .ConfirmedFundingTx -> {
182183 // The funding tx is confirmed, and they have not received our tx_signatures, but they must have received our commit_sig, otherwise they
@@ -195,26 +196,27 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent:
195196 state.spliceStatus
196197 }
197198
198- // Re-send splice_locked (must come *after* potentially retransmitting tx_signatures).
199- // NB: there is a key difference between channel_ready and splice_locked:
200- // - channel_ready: a non-zero commitment index implies that both sides have seen the channel_ready
201- // - splice_locked: the commitment index can be updated as long as it is compatible with all splices, so
202- // we must keep sending our most recent splice_locked at each reconnection
203- state.commitments.active
204- .filter { it.fundingTxIndex > 0L } // only consider splice txs
205- .firstOrNull { staticParams.useZeroConf || it.localFundingStatus is LocalFundingStatus .ConfirmedFundingTx }
206- ?.let {
207- logger.debug { " re-sending splice_locked for fundingTxId=${it.fundingTxId} " }
208- val spliceLocked = SpliceLocked (channelId, it.fundingTxId)
209- actions.add(ChannelAction .Message .Send (spliceLocked))
199+ // Prune previous funding transactions and RBF attempts if we already sent splice_locked for the last funding
200+ // transaction that is also locked by our counterparty; we either missed their splice_locked or it confirmed
201+ // while disconnected.
202+ val commitments1 = run {
203+ val withRemoteLocked = when (val remoteFundingTxLocked = cmd.message.myCurrentFundingLocked) {
204+ null -> state.commitments
205+ else -> when (val commitments1 = state.commitments.run { updateRemoteFundingStatus(remoteFundingTxLocked) }) {
206+ is Either .Left -> state.commitments
207+ is Either .Right -> {
208+ state.run { newlyLocked(state.commitments, commitments1.value.first) }.forEach { actions.add(ChannelAction .Storage .SetLocked (it.fundingTxId)) }
209+ commitments1.value.first
210+ }
211+ }
210212 }
213+ // Then we clean up unsigned updates.
214+ discardUnsignedUpdates(withRemoteLocked)
215+ }
211216
212217 // we may need to retransmit updates and/or commit_sig and/or revocation
213218 actions.addAll(syncResult.retransmit.map { ChannelAction .Message .Send (it) })
214219
215- // then we clean up unsigned updates
216- val commitments1 = discardUnsignedUpdates(state.commitments)
217-
218220 if (commitments1.changes.localHasChanges()) {
219221 actions.add(ChannelAction .Message .SendToSelf (ChannelCommand .Commitment .Sign ))
220222 }
0 commit comments