Skip to content

Commit 59a7972

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 e882792 commit 59a7972

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

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -27,29 +27,37 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent:
2727
Pair(state, listOf())
2828
}
2929
is WaitForFundingSigned -> {
30-
when (cmd.message.nextFundingTxId) {
31-
// We retransmit our commit_sig, and will send our tx_signatures once we've received their commit_sig.
32-
state.signingSession.fundingTx.txId -> {
30+
val actions = buildList {
31+
if (cmd.message.nextFundingTxId == state.signingSession.fundingTx.txId && cmd.message.nextLocalCommitmentNumber == 0L) {
32+
// They haven't received our commit_sig: we retransmit it, and will send our tx_signatures once we've received
33+
// their commit_sig or their tx_signatures (depending on who must send tx_signatures first).
34+
logger.info { "re-sending commit_sig for channel creation with fundingTxId=${state.signingSession.fundingTx.txId}" }
3335
val commitSig = state.signingSession.remoteCommit.sign(channelKeys(), state.channelParams, state.signingSession)
34-
Pair(state, listOf(ChannelAction.Message.Send(commitSig)))
36+
add(ChannelAction.Message.Send(commitSig))
3537
}
36-
else -> Pair(state, listOf())
3738
}
39+
Pair(state, actions)
3840
}
3941
is WaitForFundingConfirmed -> {
4042
when (cmd.message.nextFundingTxId) {
4143
null -> Pair(state, listOf())
4244
else -> {
4345
if (state.rbfStatus is RbfStatus.WaitingForSigs && state.rbfStatus.session.fundingTx.txId == cmd.message.nextFundingTxId) {
44-
// We retransmit our commit_sig, and will send our tx_signatures once we've received their commit_sig.
45-
logger.info { "re-sending commit_sig for rbf attempt with fundingTxId=${cmd.message.nextFundingTxId}" }
46-
val commitSig = state.rbfStatus.session.remoteCommit.sign(channelKeys(), state.commitments.params, state.rbfStatus.session)
47-
val actions = listOf(ChannelAction.Message.Send(commitSig))
46+
val actions = buildList {
47+
if (cmd.message.nextLocalCommitmentNumber == 0L) {
48+
// They haven't received our commit_sig: we retransmit it.
49+
// We're waiting for signatures from them, and will send our tx_signatures once we receive them.
50+
logger.info { "re-sending commit_sig for rbf attempt with fundingTxId=${cmd.message.nextFundingTxId}" }
51+
val commitSig = state.rbfStatus.session.remoteCommit.sign(channelKeys(), state.commitments.params, state.rbfStatus.session)
52+
add(ChannelAction.Message.Send(commitSig))
53+
}
54+
}
4855
Pair(state, actions)
4956
} else if (state.latestFundingTx.txId == cmd.message.nextFundingTxId) {
57+
// We've already received their commit_sig and sent our tx_signatures. We retransmit our tx_signatures
58+
// and our commit_sig if they haven't received it already.
5059
val actions = buildList {
51-
if (state.latestFundingTx.sharedTx is PartiallySignedSharedTransaction) {
52-
// We have not received their tx_signatures: we retransmit our commit_sig because we don't know if they received it.
60+
if (cmd.message.nextLocalCommitmentNumber == 0L) {
5361
logger.info { "re-sending commit_sig for fundingTxId=${cmd.message.nextFundingTxId}" }
5462
val commitSig = state.commitments.latest.remoteCommit.sign(
5563
channelKeys(),
@@ -75,11 +83,11 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent:
7583
}
7684
is WaitForChannelReady -> {
7785
val actions = ArrayList<ChannelAction>()
78-
86+
// We've already received their commit_sig and sent our tx_signatures. We retransmit our tx_signatures
87+
// and our commit_sig if they haven't received it already.
7988
if (state.commitments.latest.fundingTxId == cmd.message.nextFundingTxId) {
8089
if (state.commitments.latest.localFundingStatus is LocalFundingStatus.UnconfirmedFundingTx) {
81-
if (state.commitments.latest.localFundingStatus.sharedTx is PartiallySignedSharedTransaction) {
82-
// 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
90+
if (cmd.message.nextLocalCommitmentNumber == 0L) {
8391
logger.info { "re-sending commit_sig for fundingTxId=${state.commitments.latest.fundingTxId}" }
8492
val commitSig = state.commitments.latest.remoteCommit.sign(
8593
channelKeys(),
@@ -99,12 +107,10 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent:
99107
logger.warning { "cannot re-send tx_signatures for fundingTxId=${cmd.message.nextFundingTxId}, transaction is already confirmed" }
100108
}
101109
}
102-
103110
logger.debug { "re-sending channel_ready" }
104111
val nextPerCommitmentPoint = channelKeys().commitmentPoint(1)
105112
val channelReady = ChannelReady(state.commitments.channelId, nextPerCommitmentPoint)
106113
actions.add(ChannelAction.Message.Send(channelReady))
107-
108114
Pair(state, actions)
109115
}
110116
is LegacyWaitForFundingLocked -> {
@@ -132,16 +138,20 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent:
132138

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

0 commit comments

Comments
 (0)