@@ -2195,7 +2195,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
2195
2195
val nextFundingTlv : Set [ChannelReestablishTlv ] = Set (ChannelReestablishTlv .NextFundingTlv (d.signingSession.fundingTx.txId))
2196
2196
val channelReestablish = ChannelReestablish (
2197
2197
channelId = d.channelId,
2198
- nextLocalCommitmentNumber = 1 ,
2198
+ nextLocalCommitmentNumber = d.signingSession.reconnectNextLocalCommitmentNumber ,
2199
2199
nextRemoteRevocationNumber = 0 ,
2200
2200
yourLastPerCommitmentSecret = PrivateKey (ByteVector32 .Zeroes ),
2201
2201
myCurrentPerCommitmentPoint = myFirstPerCommitmentPoint,
@@ -2210,6 +2210,19 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
2210
2210
val yourLastPerCommitmentSecret = remotePerCommitmentSecrets.lastIndex.flatMap(remotePerCommitmentSecrets.getHash).getOrElse(ByteVector32 .Zeroes )
2211
2211
val channelKeyPath = keyManager.keyPath(d.commitments.params.localParams, d.commitments.params.channelConfig)
2212
2212
val myCurrentPerCommitmentPoint = keyManager.commitmentPoint(channelKeyPath, d.commitments.localCommitIndex)
2213
+ // If we disconnected while signing a funding transaction, we may need our peer to retransmit their commit_sig.
2214
+ val nextLocalCommitmentNumber = d match {
2215
+ case d : DATA_WAIT_FOR_DUAL_FUNDING_CONFIRMED => d.status match {
2216
+ case DualFundingStatus .RbfWaitingForSigs (status) => status.reconnectNextLocalCommitmentNumber
2217
+ case _ => d.commitments.localCommitIndex + 1
2218
+ }
2219
+ case d : DATA_NORMAL => d.spliceStatus match {
2220
+ case SpliceStatus .SpliceWaitingForSigs (status) => status.reconnectNextLocalCommitmentNumber
2221
+ case _ => d.commitments.localCommitIndex + 1
2222
+ }
2223
+ case _ => d.commitments.localCommitIndex + 1
2224
+ }
2225
+ // If we disconnected while signing a funding transaction, we may need our peer to (re)transmit their tx_signatures.
2213
2226
val rbfTlv : Set [ChannelReestablishTlv ] = d match {
2214
2227
case d : DATA_WAIT_FOR_DUAL_FUNDING_CONFIRMED => d.status match {
2215
2228
case DualFundingStatus .RbfWaitingForSigs (status) => Set (ChannelReestablishTlv .NextFundingTlv (status.fundingTx.txId))
@@ -2229,7 +2242,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
2229
2242
}
2230
2243
val channelReestablish = ChannelReestablish (
2231
2244
channelId = d.channelId,
2232
- nextLocalCommitmentNumber = d.commitments.localCommitIndex + 1 ,
2245
+ nextLocalCommitmentNumber = nextLocalCommitmentNumber ,
2233
2246
nextRemoteRevocationNumber = d.commitments.remoteCommitIndex,
2234
2247
yourLastPerCommitmentSecret = PrivateKey (yourLastPerCommitmentSecret),
2235
2248
myCurrentPerCommitmentPoint = myCurrentPerCommitmentPoint,
@@ -2270,8 +2283,9 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
2270
2283
2271
2284
case Event (channelReestablish : ChannelReestablish , d : DATA_WAIT_FOR_DUAL_FUNDING_SIGNED ) =>
2272
2285
channelReestablish.nextFundingTxId_opt match {
2273
- case Some (fundingTxId) if fundingTxId == d.signingSession.fundingTx.txId =>
2274
- // We retransmit our commit_sig, and will send our tx_signatures once we've received their commit_sig.
2286
+ case Some (fundingTxId) if fundingTxId == d.signingSession.fundingTx.txId && channelReestablish.nextLocalCommitmentNumber == 0 =>
2287
+ // They haven't received our commit_sig: we retransmit it, and will send our tx_signatures once we've received
2288
+ // their commit_sig or their tx_signatures (depending on who must send tx_signatures first).
2275
2289
val commitSig = d.signingSession.remoteCommit.sign(keyManager, d.channelParams, d.signingSession.fundingTxIndex, d.signingSession.fundingParams.remoteFundingPubKey, d.signingSession.commitInput)
2276
2290
goto(WAIT_FOR_DUAL_FUNDING_SIGNED ) sending commitSig
2277
2291
case _ => goto(WAIT_FOR_DUAL_FUNDING_SIGNED )
@@ -2282,20 +2296,25 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
2282
2296
case Some (fundingTxId) =>
2283
2297
d.status match {
2284
2298
case DualFundingStatus .RbfWaitingForSigs (signingSession) if signingSession.fundingTx.txId == fundingTxId =>
2285
- // We retransmit our commit_sig, and will send our tx_signatures once we've received their commit_sig.
2286
- val commitSig = signingSession.remoteCommit.sign(keyManager, d.commitments.params, signingSession.fundingTxIndex, signingSession.fundingParams.remoteFundingPubKey, signingSession.commitInput)
2287
- goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending commitSig
2299
+ if (channelReestablish.nextLocalCommitmentNumber == 0 ) {
2300
+ // They haven't received our commit_sig: we retransmit it.
2301
+ // We're also waiting for signatures from them, and will send our tx_signatures once we receive them.
2302
+ val commitSig = signingSession.remoteCommit.sign(keyManager, d.commitments.params, signingSession.fundingTxIndex, signingSession.fundingParams.remoteFundingPubKey, signingSession.commitInput)
2303
+ goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending commitSig
2304
+ } else {
2305
+ // They have already received our commit_sig, but we were waiting for them to send either commit_sig or
2306
+ // tx_signatures first. We wait for their message before sending our tx_signatures.
2307
+ goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED )
2308
+ }
2288
2309
case _ if d.latestFundingTx.sharedTx.txId == fundingTxId =>
2289
- val toSend = d.latestFundingTx.sharedTx match {
2290
- case fundingTx : InteractiveTxBuilder .PartiallySignedSharedTransaction =>
2291
- // We have not received their tx_signatures: we retransmit our commit_sig because we don't know if they received it.
2292
- val commitSig = d.commitments.latest.remoteCommit.sign(keyManager, d.commitments.params, d.commitments.latest.fundingTxIndex, d.commitments.latest.remoteFundingPubKey, d.commitments.latest.commitInput)
2293
- Seq (commitSig, fundingTx.localSigs)
2294
- case fundingTx : InteractiveTxBuilder .FullySignedSharedTransaction =>
2295
- // We've already received their tx_signatures, which means they've received and stored our commit_sig, we only need to retransmit our tx_signatures.
2296
- Seq (fundingTx.localSigs)
2310
+ // We've already received their commit_sig and sent our tx_signatures. We retransmit our tx_signatures
2311
+ // and our commit_sig if they haven't received it already.
2312
+ if (channelReestablish.nextLocalCommitmentNumber == 0 ) {
2313
+ val commitSig = d.commitments.latest.remoteCommit.sign(keyManager, d.commitments.params, d.commitments.latest.fundingTxIndex, d.commitments.latest.remoteFundingPubKey, d.commitments.latest.commitInput)
2314
+ goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending Seq (commitSig, d.latestFundingTx.sharedTx.localSigs)
2315
+ } else {
2316
+ goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending d.latestFundingTx.sharedTx.localSigs
2297
2317
}
2298
- goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending toSend
2299
2318
case _ =>
2300
2319
// The fundingTxId must be for an RBF attempt that we didn't store (we got disconnected before receiving
2301
2320
// their tx_complete): we tell them to abort that RBF attempt.
@@ -2337,23 +2356,26 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
2337
2356
case Some (fundingTxId) =>
2338
2357
d.spliceStatus match {
2339
2358
case SpliceStatus .SpliceWaitingForSigs (signingSession) if signingSession.fundingTx.txId == fundingTxId =>
2340
- // We retransmit our commit_sig, and will send our tx_signatures once we've received their commit_sig.
2341
- log.info(" re-sending commit_sig for splice attempt with fundingTxIndex={} fundingTxId={}" , signingSession.fundingTxIndex, signingSession.fundingTx.txId)
2342
- val commitSig = signingSession.remoteCommit.sign(keyManager, d.commitments.params, signingSession.fundingTxIndex, signingSession.fundingParams.remoteFundingPubKey, signingSession.commitInput)
2343
- sendQueue = sendQueue :+ commitSig
2359
+ if (channelReestablish.nextLocalCommitmentNumber == d.commitments.remoteCommitIndex) {
2360
+ // They haven't received our commit_sig: we retransmit it.
2361
+ // We're also waiting for signatures from them, and will send our tx_signatures once we receive them.
2362
+ log.info(" re-sending commit_sig for splice attempt with fundingTxIndex={} fundingTxId={}" , signingSession.fundingTxIndex, signingSession.fundingTx.txId)
2363
+ val commitSig = signingSession.remoteCommit.sign(keyManager, d.commitments.params, signingSession.fundingTxIndex, signingSession.fundingParams.remoteFundingPubKey, signingSession.commitInput)
2364
+ sendQueue = sendQueue :+ commitSig
2365
+ }
2344
2366
d.spliceStatus
2345
2367
case _ if d.commitments.latest.fundingTxId == fundingTxId =>
2346
2368
d.commitments.latest.localFundingStatus match {
2347
2369
case dfu : LocalFundingStatus .DualFundedUnconfirmedFundingTx =>
2348
- dfu.sharedTx match {
2349
- case fundingTx : InteractiveTxBuilder . PartiallySignedSharedTransaction =>
2350
- // 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
2351
- log.info(" re-sending commit_sig and tx_signatures for fundingTxIndex={} fundingTxId={}" , d.commitments.latest.fundingTxIndex, d.commitments.latest.fundingTxId)
2352
- val commitSig = d.commitments.latest.remoteCommit.sign(keyManager, d.commitments.params, d.commitments.latest.fundingTxIndex, d.commitments.latest.remoteFundingPubKey, d.commitments.latest.commitInput)
2353
- sendQueue = sendQueue :+ commitSig :+ fundingTx .localSigs
2354
- case fundingTx : InteractiveTxBuilder . FullySignedSharedTransaction =>
2355
- log.info(" re-sending tx_signatures for fundingTxIndex={} fundingTxId={}" , d.commitments.latest.fundingTxIndex, d.commitments.latest.fundingTxId)
2356
- sendQueue = sendQueue :+ fundingTx .localSigs
2370
+ // We've already received their commit_sig and sent our tx_signatures. We retransmit our
2371
+ // tx_signatures and our commit_sig if they haven't received it already.
2372
+ if (channelReestablish.nextLocalCommitmentNumber == d.commitments.remoteCommitIndex) {
2373
+ log.info(" re-sending commit_sig and tx_signatures for fundingTxIndex={} fundingTxId={}" , d.commitments.latest.fundingTxIndex, d.commitments.latest.fundingTxId)
2374
+ val commitSig = d.commitments.latest.remoteCommit.sign(keyManager, d.commitments.params, d.commitments.latest.fundingTxIndex, d.commitments.latest.remoteFundingPubKey, d.commitments.latest.commitInput)
2375
+ sendQueue = sendQueue :+ commitSig :+ dfu.sharedTx .localSigs
2376
+ } else {
2377
+ log.info(" re-sending tx_signatures for fundingTxIndex={} fundingTxId={}" , d.commitments.latest.fundingTxIndex, d.commitments.latest.fundingTxId)
2378
+ sendQueue = sendQueue :+ dfu.sharedTx .localSigs
2357
2379
}
2358
2380
case fundingStatus =>
2359
2381
// They have not received our tx_signatures, but they must have received our commit_sig, otherwise we would be in the case above.
0 commit comments