Skip to content

Commit 1c3be14

Browse files
committed
Remove spurious interactive-tx commit_sig retransmission
We fully implement lightning/bolts#1214 to stop retransmitting `commit_sig` when our peer has already received it. We also correctly set `next_commitment_number` to let our peer know whether we have received their `commit_sig` or not.
1 parent fac5406 commit 1c3be14

File tree

3 files changed

+87
-85
lines changed

3 files changed

+87
-85
lines changed

modules/core/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Syncing.kt

+32-22
Original file line numberDiff line numberDiff line change
@@ -29,29 +29,37 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent:
2929
Pair(state, listOf())
3030
}
3131
is WaitForFundingSigned -> {
32-
when (cmd.message.nextFundingTxId) {
33-
// We retransmit our commit_sig, and will send our tx_signatures once we've received their commit_sig.
34-
state.signingSession.fundingTx.txId -> {
32+
val actions = buildList {
33+
if (cmd.message.nextFundingTxId == state.signingSession.fundingTx.txId && cmd.message.nextLocalCommitmentNumber == 0L) {
34+
// They haven't received our commit_sig: we retransmit it, and will send our tx_signatures once we've received
35+
// their commit_sig or their tx_signatures (depending on who must send tx_signatures first).
36+
logger.info { "re-sending commit_sig for channel creation with fundingTxId=${state.signingSession.fundingTx.txId}" }
3537
val commitSig = state.signingSession.remoteCommit.sign(channelKeys(), state.channelParams, state.signingSession)
36-
Pair(state, listOf(ChannelAction.Message.Send(commitSig)))
38+
add(ChannelAction.Message.Send(commitSig))
3739
}
38-
else -> Pair(state, listOf())
3940
}
41+
Pair(state, actions)
4042
}
4143
is WaitForFundingConfirmed -> {
4244
when (cmd.message.nextFundingTxId) {
4345
null -> Pair(state, listOf())
4446
else -> {
4547
if (state.rbfStatus is RbfStatus.WaitingForSigs && state.rbfStatus.session.fundingTx.txId == cmd.message.nextFundingTxId) {
46-
// We retransmit our commit_sig, and will send our tx_signatures once we've received their commit_sig.
47-
logger.info { "re-sending commit_sig for rbf attempt with fundingTxId=${cmd.message.nextFundingTxId}" }
48-
val commitSig = state.rbfStatus.session.remoteCommit.sign(channelKeys(), state.commitments.params, state.rbfStatus.session)
49-
val actions = listOf(ChannelAction.Message.Send(commitSig))
48+
val actions = buildList {
49+
if (cmd.message.nextLocalCommitmentNumber == 0L) {
50+
// They haven't received our commit_sig: we retransmit it.
51+
// We're waiting for signatures from them, and will send our tx_signatures once we receive them.
52+
logger.info { "re-sending commit_sig for rbf attempt with fundingTxId=${cmd.message.nextFundingTxId}" }
53+
val commitSig = state.rbfStatus.session.remoteCommit.sign(channelKeys(), state.commitments.params, state.rbfStatus.session)
54+
add(ChannelAction.Message.Send(commitSig))
55+
}
56+
}
5057
Pair(state, actions)
5158
} else if (state.latestFundingTx.txId == cmd.message.nextFundingTxId) {
59+
// We've already received their commit_sig and sent our tx_signatures. We retransmit our tx_signatures
60+
// and our commit_sig if they haven't received it already.
5261
val actions = buildList {
53-
if (state.latestFundingTx.sharedTx is PartiallySignedSharedTransaction) {
54-
// We have not received their tx_signatures: we retransmit our commit_sig because we don't know if they received it.
62+
if (cmd.message.nextLocalCommitmentNumber == 0L) {
5563
logger.info { "re-sending commit_sig for fundingTxId=${cmd.message.nextFundingTxId}" }
5664
val commitSig = state.commitments.latest.remoteCommit.sign(
5765
channelKeys(),
@@ -77,11 +85,11 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent:
7785
}
7886
is WaitForChannelReady -> {
7987
val actions = ArrayList<ChannelAction>()
80-
88+
// We've already received their commit_sig and sent our tx_signatures. We retransmit our tx_signatures
89+
// and our commit_sig if they haven't received it already.
8190
if (state.commitments.latest.fundingTxId == cmd.message.nextFundingTxId) {
8291
if (state.commitments.latest.localFundingStatus is LocalFundingStatus.UnconfirmedFundingTx) {
83-
if (state.commitments.latest.localFundingStatus.sharedTx is PartiallySignedSharedTransaction) {
84-
// 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
92+
if (cmd.message.nextLocalCommitmentNumber == 0L) {
8593
logger.info { "re-sending commit_sig for fundingTxId=${state.commitments.latest.fundingTxId}" }
8694
val commitSig = state.commitments.latest.remoteCommit.sign(
8795
channelKeys(),
@@ -101,12 +109,10 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent:
101109
logger.warning { "cannot re-send tx_signatures for fundingTxId=${cmd.message.nextFundingTxId}, transaction is already confirmed" }
102110
}
103111
}
104-
105112
logger.debug { "re-sending channel_ready" }
106113
val nextPerCommitmentPoint = channelKeys().commitmentPoint(1)
107114
val channelReady = ChannelReady(state.commitments.channelId, nextPerCommitmentPoint)
108115
actions.add(ChannelAction.Message.Send(channelReady))
109-
110116
Pair(state, actions)
111117
}
112118
is LegacyWaitForFundingLocked -> {
@@ -134,16 +140,20 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent:
134140

135141
// resume splice signing session if any
136142
val spliceStatus1 = if (state.spliceStatus is SpliceStatus.WaitingForSigs && state.spliceStatus.session.fundingTx.txId == cmd.message.nextFundingTxId) {
137-
// We retransmit our commit_sig, and will send our tx_signatures once we've received their commit_sig.
138-
logger.info { "re-sending commit_sig for splice attempt with fundingTxIndex=${state.spliceStatus.session.fundingTxIndex} fundingTxId=${state.spliceStatus.session.fundingTx.txId}" }
139-
val commitSig = state.spliceStatus.session.remoteCommit.sign(channelKeys(), state.commitments.params, state.spliceStatus.session)
140-
actions.add(ChannelAction.Message.Send(commitSig))
143+
if (cmd.message.nextLocalCommitmentNumber == state.commitments.remoteCommitIndex) {
144+
// They haven't received our commit_sig: we retransmit it.
145+
// We're waiting for signatures from them, and will send our tx_signatures once we receive them.
146+
logger.info { "re-sending commit_sig for splice attempt with fundingTxIndex=${state.spliceStatus.session.fundingTxIndex} fundingTxId=${state.spliceStatus.session.fundingTx.txId}" }
147+
val commitSig = state.spliceStatus.session.remoteCommit.sign(channelKeys(), state.commitments.params, state.spliceStatus.session)
148+
actions.add(ChannelAction.Message.Send(commitSig))
149+
}
141150
state.spliceStatus
142151
} else if (state.commitments.latest.fundingTxId == cmd.message.nextFundingTxId) {
143152
when (val localFundingStatus = state.commitments.latest.localFundingStatus) {
144153
is LocalFundingStatus.UnconfirmedFundingTx -> {
145-
if (localFundingStatus.sharedTx is PartiallySignedSharedTransaction) {
146-
// 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
154+
// We've already received their commit_sig and sent our tx_signatures. We retransmit our tx_signatures
155+
// and our commit_sig if they haven't received it already.
156+
if (cmd.message.nextLocalCommitmentNumber == state.commitments.remoteCommitIndex) {
147157
logger.info { "re-sending commit_sig for fundingTxIndex=${state.commitments.latest.fundingTxIndex} fundingTxId=${state.commitments.latest.fundingTxId}" }
148158
val commitSig = state.commitments.latest.remoteCommit.sign(
149159
channelKeys(),

0 commit comments

Comments
 (0)