@@ -2023,7 +2023,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
2023
2023
// we watch it in order to extract payment preimage if funds are pulled by the counterparty
2024
2024
// we can then use these preimages to fulfill origin htlcs
2025
2025
log.debug(s " processing bitcoin output spent by txid= ${tx.txid} tx= $tx" )
2026
- val extracted = Closing .extractPreimages(d.commitments.latest.localCommit , tx)
2026
+ val extracted = Closing .extractPreimages(d.commitments.latest, tx)
2027
2027
extracted.foreach { case (htlc, preimage) =>
2028
2028
d.commitments.originChannels.get(htlc.id) match {
2029
2029
case Some (origin) =>
@@ -2243,7 +2243,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
2243
2243
val nextFundingTlv : Set [ChannelReestablishTlv ] = Set (ChannelReestablishTlv .NextFundingTlv (d.signingSession.fundingTx.txId))
2244
2244
val channelReestablish = ChannelReestablish (
2245
2245
channelId = d.channelId,
2246
- nextLocalCommitmentNumber = 1 ,
2246
+ nextLocalCommitmentNumber = d.signingSession.nextLocalCommitmentNumber ,
2247
2247
nextRemoteRevocationNumber = 0 ,
2248
2248
yourLastPerCommitmentSecret = PrivateKey (ByteVector32 .Zeroes ),
2249
2249
myCurrentPerCommitmentPoint = myFirstPerCommitmentPoint,
@@ -2258,6 +2258,19 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
2258
2258
val yourLastPerCommitmentSecret = remotePerCommitmentSecrets.lastIndex.flatMap(remotePerCommitmentSecrets.getHash).getOrElse(ByteVector32 .Zeroes )
2259
2259
val channelKeyPath = keyManager.keyPath(d.commitments.params.localParams, d.commitments.params.channelConfig)
2260
2260
val myCurrentPerCommitmentPoint = keyManager.commitmentPoint(channelKeyPath, d.commitments.localCommitIndex)
2261
+ // If we disconnected while signing a funding transaction, we may need our peer to retransmit their commit_sig.
2262
+ val nextLocalCommitmentNumber = d match {
2263
+ case d : DATA_WAIT_FOR_DUAL_FUNDING_CONFIRMED => d.status match {
2264
+ case DualFundingStatus .RbfWaitingForSigs (status) => status.nextLocalCommitmentNumber
2265
+ case _ => d.commitments.localCommitIndex + 1
2266
+ }
2267
+ case d : DATA_NORMAL => d.spliceStatus match {
2268
+ case SpliceStatus .SpliceWaitingForSigs (status) => status.nextLocalCommitmentNumber
2269
+ case _ => d.commitments.localCommitIndex + 1
2270
+ }
2271
+ case _ => d.commitments.localCommitIndex + 1
2272
+ }
2273
+ // If we disconnected while signing a funding transaction, we may need our peer to (re)transmit their tx_signatures.
2261
2274
val rbfTlv : Set [ChannelReestablishTlv ] = d match {
2262
2275
case d : DATA_WAIT_FOR_DUAL_FUNDING_CONFIRMED => d.status match {
2263
2276
case DualFundingStatus .RbfWaitingForSigs (status) => Set (ChannelReestablishTlv .NextFundingTlv (status.fundingTx.txId))
@@ -2282,7 +2295,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
2282
2295
2283
2296
val channelReestablish = ChannelReestablish (
2284
2297
channelId = d.channelId,
2285
- nextLocalCommitmentNumber = d.commitments.localCommitIndex + 1 ,
2298
+ nextLocalCommitmentNumber = nextLocalCommitmentNumber ,
2286
2299
nextRemoteRevocationNumber = d.commitments.remoteCommitIndex,
2287
2300
yourLastPerCommitmentSecret = PrivateKey (yourLastPerCommitmentSecret),
2288
2301
myCurrentPerCommitmentPoint = myCurrentPerCommitmentPoint,
@@ -2323,8 +2336,9 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
2323
2336
2324
2337
case Event (channelReestablish : ChannelReestablish , d : DATA_WAIT_FOR_DUAL_FUNDING_SIGNED ) =>
2325
2338
channelReestablish.nextFundingTxId_opt match {
2326
- case Some (fundingTxId) if fundingTxId == d.signingSession.fundingTx.txId =>
2327
- // We retransmit our commit_sig, and will send our tx_signatures once we've received their commit_sig.
2339
+ case Some (fundingTxId) if fundingTxId == d.signingSession.fundingTx.txId && channelReestablish.nextLocalCommitmentNumber == 0 =>
2340
+ // They haven't received our commit_sig: we retransmit it, and will send our tx_signatures once we've received
2341
+ // their commit_sig or their tx_signatures (depending on who must send tx_signatures first).
2328
2342
val commitSig = d.signingSession.remoteCommit.sign(keyManager, d.channelParams, d.signingSession.fundingTxIndex, d.signingSession.fundingParams.remoteFundingPubKey, d.signingSession.commitInput)
2329
2343
goto(WAIT_FOR_DUAL_FUNDING_SIGNED ) sending commitSig
2330
2344
case _ => goto(WAIT_FOR_DUAL_FUNDING_SIGNED )
@@ -2335,20 +2349,25 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
2335
2349
case Some (fundingTxId) =>
2336
2350
d.status match {
2337
2351
case DualFundingStatus .RbfWaitingForSigs (signingSession) if signingSession.fundingTx.txId == fundingTxId =>
2338
- // We retransmit our commit_sig, and will send our tx_signatures once we've received their commit_sig.
2339
- val commitSig = signingSession.remoteCommit.sign(keyManager, d.commitments.params, signingSession.fundingTxIndex, signingSession.fundingParams.remoteFundingPubKey, signingSession.commitInput)
2340
- goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending commitSig
2352
+ if (channelReestablish.nextLocalCommitmentNumber == 0 ) {
2353
+ // They haven't received our commit_sig: we retransmit it.
2354
+ // We're also waiting for signatures from them, and will send our tx_signatures once we receive them.
2355
+ val commitSig = signingSession.remoteCommit.sign(keyManager, d.commitments.params, signingSession.fundingTxIndex, signingSession.fundingParams.remoteFundingPubKey, signingSession.commitInput)
2356
+ goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending commitSig
2357
+ } else {
2358
+ // They have already received our commit_sig, but we were waiting for them to send either commit_sig or
2359
+ // tx_signatures first. We wait for their message before sending our tx_signatures.
2360
+ goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED )
2361
+ }
2341
2362
case _ if d.latestFundingTx.sharedTx.txId == fundingTxId =>
2342
- val toSend = d.latestFundingTx.sharedTx match {
2343
- case fundingTx : InteractiveTxBuilder .PartiallySignedSharedTransaction =>
2344
- // We have not received their tx_signatures: we retransmit our commit_sig because we don't know if they received it.
2345
- val commitSig = d.commitments.latest.remoteCommit.sign(keyManager, d.commitments.params, d.commitments.latest.fundingTxIndex, d.commitments.latest.remoteFundingPubKey, d.commitments.latest.commitInput)
2346
- Seq (commitSig, fundingTx.localSigs)
2347
- case fundingTx : InteractiveTxBuilder .FullySignedSharedTransaction =>
2348
- // 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.
2349
- Seq (fundingTx.localSigs)
2363
+ // We've already received their commit_sig and sent our tx_signatures. We retransmit our tx_signatures
2364
+ // and our commit_sig if they haven't received it already.
2365
+ if (channelReestablish.nextLocalCommitmentNumber == 0 ) {
2366
+ val commitSig = d.commitments.latest.remoteCommit.sign(keyManager, d.commitments.params, d.commitments.latest.fundingTxIndex, d.commitments.latest.remoteFundingPubKey, d.commitments.latest.commitInput)
2367
+ goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending Seq (commitSig, d.latestFundingTx.sharedTx.localSigs)
2368
+ } else {
2369
+ goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending d.latestFundingTx.sharedTx.localSigs
2350
2370
}
2351
- goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending toSend
2352
2371
case _ =>
2353
2372
// The fundingTxId must be for an RBF attempt that we didn't store (we got disconnected before receiving
2354
2373
// their tx_complete): we tell them to abort that RBF attempt.
@@ -2362,10 +2381,27 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
2362
2381
val channelReady = createChannelReady(d.aliases, d.commitments.params)
2363
2382
goto(WAIT_FOR_CHANNEL_READY ) sending channelReady
2364
2383
2365
- case Event (_ : ChannelReestablish , d : DATA_WAIT_FOR_DUAL_FUNDING_READY ) =>
2384
+ case Event (channelReestablish : ChannelReestablish , d : DATA_WAIT_FOR_DUAL_FUNDING_READY ) =>
2366
2385
log.debug(" re-sending channel_ready" )
2367
2386
val channelReady = createChannelReady(d.aliases, d.commitments.params)
2368
- goto(WAIT_FOR_DUAL_FUNDING_READY ) sending channelReady
2387
+ // We've already received their commit_sig and sent our tx_signatures. We retransmit our tx_signatures
2388
+ // and our commit_sig if they haven't received it already.
2389
+ channelReestablish.nextFundingTxId_opt match {
2390
+ case Some (fundingTxId) if fundingTxId == d.commitments.latest.fundingTxId =>
2391
+ d.commitments.latest.localFundingStatus.localSigs_opt match {
2392
+ case Some (txSigs) if channelReestablish.nextLocalCommitmentNumber == 0 =>
2393
+ log.info(" re-sending commit_sig and tx_signatures for fundingTxIndex={} fundingTxId={}" , d.commitments.latest.fundingTxIndex, d.commitments.latest.fundingTxId)
2394
+ val commitSig = d.commitments.latest.remoteCommit.sign(keyManager, d.commitments.params, d.commitments.latest.fundingTxIndex, d.commitments.latest.remoteFundingPubKey, d.commitments.latest.commitInput)
2395
+ goto(WAIT_FOR_DUAL_FUNDING_READY ) sending Seq (commitSig, txSigs, channelReady)
2396
+ case Some (txSigs) =>
2397
+ log.info(" re-sending tx_signatures for fundingTxIndex={} fundingTxId={}" , d.commitments.latest.fundingTxIndex, d.commitments.latest.fundingTxId)
2398
+ goto(WAIT_FOR_DUAL_FUNDING_READY ) sending Seq (txSigs, channelReady)
2399
+ case None =>
2400
+ log.warning(" cannot retransmit tx_signatures, we don't have them (status={})" , d.commitments.latest.localFundingStatus)
2401
+ goto(WAIT_FOR_DUAL_FUNDING_READY ) sending channelReady
2402
+ }
2403
+ case _ => goto(WAIT_FOR_DUAL_FUNDING_READY ) sending channelReady
2404
+ }
2369
2405
2370
2406
case Event (channelReestablish : ChannelReestablish , d : DATA_NORMAL ) =>
2371
2407
Syncing .checkSync(keyManager, d.commitments, channelReestablish) match {
@@ -2413,23 +2449,26 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
2413
2449
case Some (fundingTxId) =>
2414
2450
d.spliceStatus match {
2415
2451
case SpliceStatus .SpliceWaitingForSigs (signingSession) if signingSession.fundingTx.txId == fundingTxId =>
2416
- // We retransmit our commit_sig, and will send our tx_signatures once we've received their commit_sig.
2417
- log.info(" re-sending commit_sig for splice attempt with fundingTxIndex={} fundingTxId={}" , signingSession.fundingTxIndex, signingSession.fundingTx.txId)
2418
- val commitSig = signingSession.remoteCommit.sign(keyManager, d.commitments.params, signingSession.fundingTxIndex, signingSession.fundingParams.remoteFundingPubKey, signingSession.commitInput)
2419
- sendQueue = sendQueue :+ commitSig
2452
+ if (channelReestablish.nextLocalCommitmentNumber == d.commitments.remoteCommitIndex) {
2453
+ // They haven't received our commit_sig: we retransmit it.
2454
+ // We're also waiting for signatures from them, and will send our tx_signatures once we receive them.
2455
+ log.info(" re-sending commit_sig for splice attempt with fundingTxIndex={} fundingTxId={}" , signingSession.fundingTxIndex, signingSession.fundingTx.txId)
2456
+ val commitSig = signingSession.remoteCommit.sign(keyManager, d.commitments.params, signingSession.fundingTxIndex, signingSession.fundingParams.remoteFundingPubKey, signingSession.commitInput)
2457
+ sendQueue = sendQueue :+ commitSig
2458
+ }
2420
2459
d.spliceStatus
2421
2460
case _ if d.commitments.latest.fundingTxId == fundingTxId =>
2422
2461
d.commitments.latest.localFundingStatus match {
2423
2462
case dfu : LocalFundingStatus .DualFundedUnconfirmedFundingTx =>
2424
- dfu.sharedTx match {
2425
- case fundingTx : InteractiveTxBuilder . PartiallySignedSharedTransaction =>
2426
- // 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
2427
- log.info(" re-sending commit_sig and tx_signatures for fundingTxIndex={} fundingTxId={}" , d.commitments.latest.fundingTxIndex, d.commitments.latest.fundingTxId)
2428
- val commitSig = d.commitments.latest.remoteCommit.sign(keyManager, d.commitments.params, d.commitments.latest.fundingTxIndex, d.commitments.latest.remoteFundingPubKey, d.commitments.latest.commitInput)
2429
- sendQueue = sendQueue :+ commitSig :+ fundingTx .localSigs
2430
- case fundingTx : InteractiveTxBuilder . FullySignedSharedTransaction =>
2431
- log.info(" re-sending tx_signatures for fundingTxIndex={} fundingTxId={}" , d.commitments.latest.fundingTxIndex, d.commitments.latest.fundingTxId)
2432
- sendQueue = sendQueue :+ fundingTx .localSigs
2463
+ // We've already received their commit_sig and sent our tx_signatures. We retransmit our
2464
+ // tx_signatures and our commit_sig if they haven't received it already.
2465
+ if (channelReestablish.nextLocalCommitmentNumber == d.commitments.remoteCommitIndex) {
2466
+ log.info(" re-sending commit_sig and tx_signatures for fundingTxIndex={} fundingTxId={}" , d.commitments.latest.fundingTxIndex, d.commitments.latest.fundingTxId)
2467
+ val commitSig = d.commitments.latest.remoteCommit.sign(keyManager, d.commitments.params, d.commitments.latest.fundingTxIndex, d.commitments.latest.remoteFundingPubKey, d.commitments.latest.commitInput)
2468
+ sendQueue = sendQueue :+ commitSig :+ dfu.sharedTx .localSigs
2469
+ } else {
2470
+ log.info(" re-sending tx_signatures for fundingTxIndex={} fundingTxId={}" , d.commitments.latest.fundingTxIndex, d.commitments.latest.fundingTxId)
2471
+ sendQueue = sendQueue :+ dfu.sharedTx .localSigs
2433
2472
}
2434
2473
case fundingStatus =>
2435
2474
// 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