@@ -2242,7 +2242,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
2242
2242
val nextFundingTlv : Set [ChannelReestablishTlv ] = Set (ChannelReestablishTlv .NextFundingTlv (d.signingSession.fundingTx.txId))
2243
2243
val channelReestablish = ChannelReestablish (
2244
2244
channelId = d.channelId,
2245
- nextLocalCommitmentNumber = 1 ,
2245
+ nextLocalCommitmentNumber = d.signingSession.reconnectNextLocalCommitmentNumber ,
2246
2246
nextRemoteRevocationNumber = 0 ,
2247
2247
yourLastPerCommitmentSecret = PrivateKey (ByteVector32 .Zeroes ),
2248
2248
myCurrentPerCommitmentPoint = myFirstPerCommitmentPoint,
@@ -2257,6 +2257,19 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
2257
2257
val yourLastPerCommitmentSecret = remotePerCommitmentSecrets.lastIndex.flatMap(remotePerCommitmentSecrets.getHash).getOrElse(ByteVector32 .Zeroes )
2258
2258
val channelKeyPath = keyManager.keyPath(d.commitments.params.localParams, d.commitments.params.channelConfig)
2259
2259
val myCurrentPerCommitmentPoint = keyManager.commitmentPoint(channelKeyPath, d.commitments.localCommitIndex)
2260
+ // If we disconnected while signing a funding transaction, we may need our peer to retransmit their commit_sig.
2261
+ val nextLocalCommitmentNumber = d match {
2262
+ case d : DATA_WAIT_FOR_DUAL_FUNDING_CONFIRMED => d.status match {
2263
+ case DualFundingStatus .RbfWaitingForSigs (status) => status.reconnectNextLocalCommitmentNumber
2264
+ case _ => d.commitments.localCommitIndex + 1
2265
+ }
2266
+ case d : DATA_NORMAL => d.spliceStatus match {
2267
+ case SpliceStatus .SpliceWaitingForSigs (status) => status.reconnectNextLocalCommitmentNumber
2268
+ case _ => d.commitments.localCommitIndex + 1
2269
+ }
2270
+ case _ => d.commitments.localCommitIndex + 1
2271
+ }
2272
+ // If we disconnected while signing a funding transaction, we may need our peer to (re)transmit their tx_signatures.
2260
2273
val rbfTlv : Set [ChannelReestablishTlv ] = d match {
2261
2274
case d : DATA_WAIT_FOR_DUAL_FUNDING_CONFIRMED => d.status match {
2262
2275
case DualFundingStatus .RbfWaitingForSigs (status) => Set (ChannelReestablishTlv .NextFundingTlv (status.fundingTx.txId))
@@ -2280,7 +2293,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
2280
2293
2281
2294
val channelReestablish = ChannelReestablish (
2282
2295
channelId = d.channelId,
2283
- nextLocalCommitmentNumber = d.commitments.localCommitIndex + 1 ,
2296
+ nextLocalCommitmentNumber = nextLocalCommitmentNumber ,
2284
2297
nextRemoteRevocationNumber = d.commitments.remoteCommitIndex,
2285
2298
yourLastPerCommitmentSecret = PrivateKey (yourLastPerCommitmentSecret),
2286
2299
myCurrentPerCommitmentPoint = myCurrentPerCommitmentPoint,
@@ -2321,8 +2334,9 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
2321
2334
2322
2335
case Event (channelReestablish : ChannelReestablish , d : DATA_WAIT_FOR_DUAL_FUNDING_SIGNED ) =>
2323
2336
channelReestablish.nextFundingTxId_opt match {
2324
- case Some (fundingTxId) if fundingTxId == d.signingSession.fundingTx.txId =>
2325
- // We retransmit our commit_sig, and will send our tx_signatures once we've received their commit_sig.
2337
+ case Some (fundingTxId) if fundingTxId == d.signingSession.fundingTx.txId && channelReestablish.nextLocalCommitmentNumber == 0 =>
2338
+ // They haven't received our commit_sig: we retransmit it, and will send our tx_signatures once we've received
2339
+ // their commit_sig or their tx_signatures (depending on who must send tx_signatures first).
2326
2340
val commitSig = d.signingSession.remoteCommit.sign(keyManager, d.channelParams, d.signingSession.fundingTxIndex, d.signingSession.fundingParams.remoteFundingPubKey, d.signingSession.commitInput)
2327
2341
goto(WAIT_FOR_DUAL_FUNDING_SIGNED ) sending commitSig
2328
2342
case _ => goto(WAIT_FOR_DUAL_FUNDING_SIGNED )
@@ -2333,20 +2347,25 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
2333
2347
case Some (fundingTxId) =>
2334
2348
d.status match {
2335
2349
case DualFundingStatus .RbfWaitingForSigs (signingSession) if signingSession.fundingTx.txId == fundingTxId =>
2336
- // We retransmit our commit_sig, and will send our tx_signatures once we've received their commit_sig.
2337
- val commitSig = signingSession.remoteCommit.sign(keyManager, d.commitments.params, signingSession.fundingTxIndex, signingSession.fundingParams.remoteFundingPubKey, signingSession.commitInput)
2338
- goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending commitSig
2350
+ if (channelReestablish.nextLocalCommitmentNumber == 0 ) {
2351
+ // They haven't received our commit_sig: we retransmit it.
2352
+ // We're also waiting for signatures from them, and will send our tx_signatures once we receive them.
2353
+ val commitSig = signingSession.remoteCommit.sign(keyManager, d.commitments.params, signingSession.fundingTxIndex, signingSession.fundingParams.remoteFundingPubKey, signingSession.commitInput)
2354
+ goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending commitSig
2355
+ } else {
2356
+ // They have already received our commit_sig, but we were waiting for them to send either commit_sig or
2357
+ // tx_signatures first. We wait for their message before sending our tx_signatures.
2358
+ goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED )
2359
+ }
2339
2360
case _ if d.latestFundingTx.sharedTx.txId == fundingTxId =>
2340
- val toSend = d.latestFundingTx.sharedTx match {
2341
- case fundingTx : InteractiveTxBuilder .PartiallySignedSharedTransaction =>
2342
- // We have not received their tx_signatures: we retransmit our commit_sig because we don't know if they received it.
2343
- val commitSig = d.commitments.latest.remoteCommit.sign(keyManager, d.commitments.params, d.commitments.latest.fundingTxIndex, d.commitments.latest.remoteFundingPubKey, d.commitments.latest.commitInput)
2344
- Seq (commitSig, fundingTx.localSigs)
2345
- case fundingTx : InteractiveTxBuilder .FullySignedSharedTransaction =>
2346
- // 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.
2347
- Seq (fundingTx.localSigs)
2361
+ // We've already received their commit_sig and sent our tx_signatures. We retransmit our tx_signatures
2362
+ // and our commit_sig if they haven't received it already.
2363
+ if (channelReestablish.nextLocalCommitmentNumber == 0 ) {
2364
+ val commitSig = d.commitments.latest.remoteCommit.sign(keyManager, d.commitments.params, d.commitments.latest.fundingTxIndex, d.commitments.latest.remoteFundingPubKey, d.commitments.latest.commitInput)
2365
+ goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending Seq (commitSig, d.latestFundingTx.sharedTx.localSigs)
2366
+ } else {
2367
+ goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending d.latestFundingTx.sharedTx.localSigs
2348
2368
}
2349
- goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending toSend
2350
2369
case _ =>
2351
2370
// The fundingTxId must be for an RBF attempt that we didn't store (we got disconnected before receiving
2352
2371
// their tx_complete): we tell them to abort that RBF attempt.
@@ -2356,14 +2375,31 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
2356
2375
}
2357
2376
2358
2377
case Event (_ : ChannelReestablish , d : DATA_WAIT_FOR_CHANNEL_READY ) =>
2359
- log.debug(" re-sending channelReady " )
2378
+ log.debug(" re-sending channel_ready " )
2360
2379
val channelReady = createChannelReady(d.aliases, d.commitments.params)
2361
2380
goto(WAIT_FOR_CHANNEL_READY ) sending channelReady
2362
2381
2363
- case Event (_ : ChannelReestablish , d : DATA_WAIT_FOR_DUAL_FUNDING_READY ) =>
2364
- log.debug(" re-sending channelReady " )
2382
+ case Event (channelReestablish : ChannelReestablish , d : DATA_WAIT_FOR_DUAL_FUNDING_READY ) =>
2383
+ log.debug(" re-sending channel_ready " )
2365
2384
val channelReady = createChannelReady(d.aliases, d.commitments.params)
2366
- goto(WAIT_FOR_DUAL_FUNDING_READY ) sending channelReady
2385
+ // We've already received their commit_sig and sent our tx_signatures. We retransmit our tx_signatures
2386
+ // and our commit_sig if they haven't received it already.
2387
+ channelReestablish.nextFundingTxId_opt match {
2388
+ case Some (fundingTxId) if fundingTxId == d.commitments.latest.fundingTxId =>
2389
+ d.commitments.latest.localFundingStatus.localSigs_opt match {
2390
+ case Some (txSigs) if channelReestablish.nextLocalCommitmentNumber == 0 =>
2391
+ log.info(" re-sending commit_sig and tx_signatures for fundingTxIndex={} fundingTxId={}" , d.commitments.latest.fundingTxIndex, d.commitments.latest.fundingTxId)
2392
+ val commitSig = d.commitments.latest.remoteCommit.sign(keyManager, d.commitments.params, d.commitments.latest.fundingTxIndex, d.commitments.latest.remoteFundingPubKey, d.commitments.latest.commitInput)
2393
+ goto(WAIT_FOR_DUAL_FUNDING_READY ) sending Seq (commitSig, txSigs, channelReady)
2394
+ case Some (txSigs) =>
2395
+ log.info(" re-sending tx_signatures for fundingTxIndex={} fundingTxId={}" , d.commitments.latest.fundingTxIndex, d.commitments.latest.fundingTxId)
2396
+ goto(WAIT_FOR_DUAL_FUNDING_READY ) sending Seq (txSigs, channelReady)
2397
+ case None =>
2398
+ log.warning(" cannot retransmit tx_signatures, we don't have them (status={})" , d.commitments.latest.localFundingStatus)
2399
+ goto(WAIT_FOR_DUAL_FUNDING_READY ) sending channelReady
2400
+ }
2401
+ case _ => goto(WAIT_FOR_DUAL_FUNDING_READY ) sending channelReady
2402
+ }
2367
2403
2368
2404
case Event (channelReestablish : ChannelReestablish , d : DATA_NORMAL ) =>
2369
2405
Syncing .checkSync(keyManager, d.commitments, channelReestablish) match {
@@ -2389,23 +2425,26 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
2389
2425
case Some (fundingTxId) =>
2390
2426
d.spliceStatus match {
2391
2427
case SpliceStatus .SpliceWaitingForSigs (signingSession) if signingSession.fundingTx.txId == fundingTxId =>
2392
- // We retransmit our commit_sig, and will send our tx_signatures once we've received their commit_sig.
2393
- log.info(" re-sending commit_sig for splice attempt with fundingTxIndex={} fundingTxId={}" , signingSession.fundingTxIndex, signingSession.fundingTx.txId)
2394
- val commitSig = signingSession.remoteCommit.sign(keyManager, d.commitments.params, signingSession.fundingTxIndex, signingSession.fundingParams.remoteFundingPubKey, signingSession.commitInput)
2395
- sendQueue = sendQueue :+ commitSig
2428
+ if (channelReestablish.nextLocalCommitmentNumber == d.commitments.remoteCommitIndex) {
2429
+ // They haven't received our commit_sig: we retransmit it.
2430
+ // We're also waiting for signatures from them, and will send our tx_signatures once we receive them.
2431
+ log.info(" re-sending commit_sig for splice attempt with fundingTxIndex={} fundingTxId={}" , signingSession.fundingTxIndex, signingSession.fundingTx.txId)
2432
+ val commitSig = signingSession.remoteCommit.sign(keyManager, d.commitments.params, signingSession.fundingTxIndex, signingSession.fundingParams.remoteFundingPubKey, signingSession.commitInput)
2433
+ sendQueue = sendQueue :+ commitSig
2434
+ }
2396
2435
d.spliceStatus
2397
2436
case _ if d.commitments.latest.fundingTxId == fundingTxId =>
2398
2437
d.commitments.latest.localFundingStatus match {
2399
2438
case dfu : LocalFundingStatus .DualFundedUnconfirmedFundingTx =>
2400
- dfu.sharedTx match {
2401
- case fundingTx : InteractiveTxBuilder . PartiallySignedSharedTransaction =>
2402
- // 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
2403
- log.info(" re-sending commit_sig and tx_signatures for fundingTxIndex={} fundingTxId={}" , d.commitments.latest.fundingTxIndex, d.commitments.latest.fundingTxId)
2404
- val commitSig = d.commitments.latest.remoteCommit.sign(keyManager, d.commitments.params, d.commitments.latest.fundingTxIndex, d.commitments.latest.remoteFundingPubKey, d.commitments.latest.commitInput)
2405
- sendQueue = sendQueue :+ commitSig :+ fundingTx .localSigs
2406
- case fundingTx : InteractiveTxBuilder . FullySignedSharedTransaction =>
2407
- log.info(" re-sending tx_signatures for fundingTxIndex={} fundingTxId={}" , d.commitments.latest.fundingTxIndex, d.commitments.latest.fundingTxId)
2408
- sendQueue = sendQueue :+ fundingTx .localSigs
2439
+ // We've already received their commit_sig and sent our tx_signatures. We retransmit our
2440
+ // tx_signatures and our commit_sig if they haven't received it already.
2441
+ if (channelReestablish.nextLocalCommitmentNumber == d.commitments.remoteCommitIndex) {
2442
+ log.info(" re-sending commit_sig and tx_signatures for fundingTxIndex={} fundingTxId={}" , d.commitments.latest.fundingTxIndex, d.commitments.latest.fundingTxId)
2443
+ val commitSig = d.commitments.latest.remoteCommit.sign(keyManager, d.commitments.params, d.commitments.latest.fundingTxIndex, d.commitments.latest.remoteFundingPubKey, d.commitments.latest.commitInput)
2444
+ sendQueue = sendQueue :+ commitSig :+ dfu.sharedTx .localSigs
2445
+ } else {
2446
+ log.info(" re-sending tx_signatures for fundingTxIndex={} fundingTxId={}" , d.commitments.latest.fundingTxIndex, d.commitments.latest.fundingTxId)
2447
+ sendQueue = sendQueue :+ dfu.sharedTx .localSigs
2409
2448
}
2410
2449
case fundingStatus =>
2411
2450
// 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