@@ -2023,7 +2023,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
20232023 // we watch it in order to extract payment preimage if funds are pulled by the counterparty
20242024 // we can then use these preimages to fulfill origin htlcs
20252025 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)
20272027 extracted.foreach { case (htlc, preimage) =>
20282028 d.commitments.originChannels.get(htlc.id) match {
20292029 case Some (origin) =>
@@ -2243,7 +2243,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
22432243 val nextFundingTlv : Set [ChannelReestablishTlv ] = Set (ChannelReestablishTlv .NextFundingTlv (d.signingSession.fundingTx.txId))
22442244 val channelReestablish = ChannelReestablish (
22452245 channelId = d.channelId,
2246- nextLocalCommitmentNumber = 1 ,
2246+ nextLocalCommitmentNumber = d.signingSession.nextLocalCommitmentNumber ,
22472247 nextRemoteRevocationNumber = 0 ,
22482248 yourLastPerCommitmentSecret = PrivateKey (ByteVector32 .Zeroes ),
22492249 myCurrentPerCommitmentPoint = myFirstPerCommitmentPoint,
@@ -2258,6 +2258,19 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
22582258 val yourLastPerCommitmentSecret = remotePerCommitmentSecrets.lastIndex.flatMap(remotePerCommitmentSecrets.getHash).getOrElse(ByteVector32 .Zeroes )
22592259 val channelKeyPath = keyManager.keyPath(d.commitments.params.localParams, d.commitments.params.channelConfig)
22602260 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.
22612274 val rbfTlv : Set [ChannelReestablishTlv ] = d match {
22622275 case d : DATA_WAIT_FOR_DUAL_FUNDING_CONFIRMED => d.status match {
22632276 case DualFundingStatus .RbfWaitingForSigs (status) => Set (ChannelReestablishTlv .NextFundingTlv (status.fundingTx.txId))
@@ -2282,7 +2295,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
22822295
22832296 val channelReestablish = ChannelReestablish (
22842297 channelId = d.channelId,
2285- nextLocalCommitmentNumber = d.commitments.localCommitIndex + 1 ,
2298+ nextLocalCommitmentNumber = nextLocalCommitmentNumber ,
22862299 nextRemoteRevocationNumber = d.commitments.remoteCommitIndex,
22872300 yourLastPerCommitmentSecret = PrivateKey (yourLastPerCommitmentSecret),
22882301 myCurrentPerCommitmentPoint = myCurrentPerCommitmentPoint,
@@ -2323,8 +2336,9 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
23232336
23242337 case Event (channelReestablish : ChannelReestablish , d : DATA_WAIT_FOR_DUAL_FUNDING_SIGNED ) =>
23252338 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).
23282342 val commitSig = d.signingSession.remoteCommit.sign(keyManager, d.channelParams, d.signingSession.fundingTxIndex, d.signingSession.fundingParams.remoteFundingPubKey, d.signingSession.commitInput)
23292343 goto(WAIT_FOR_DUAL_FUNDING_SIGNED ) sending commitSig
23302344 case _ => goto(WAIT_FOR_DUAL_FUNDING_SIGNED )
@@ -2335,20 +2349,25 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
23352349 case Some (fundingTxId) =>
23362350 d.status match {
23372351 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+ }
23412362 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
23502370 }
2351- goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending toSend
23522371 case _ =>
23532372 // The fundingTxId must be for an RBF attempt that we didn't store (we got disconnected before receiving
23542373 // their tx_complete): we tell them to abort that RBF attempt.
@@ -2362,10 +2381,27 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
23622381 val channelReady = createChannelReady(d.aliases, d.commitments.params)
23632382 goto(WAIT_FOR_CHANNEL_READY ) sending channelReady
23642383
2365- case Event (_ : ChannelReestablish , d : DATA_WAIT_FOR_DUAL_FUNDING_READY ) =>
2384+ case Event (channelReestablish : ChannelReestablish , d : DATA_WAIT_FOR_DUAL_FUNDING_READY ) =>
23662385 log.debug(" re-sending channel_ready" )
23672386 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+ }
23692405
23702406 case Event (channelReestablish : ChannelReestablish , d : DATA_NORMAL ) =>
23712407 Syncing .checkSync(keyManager, d.commitments, channelReestablish) match {
@@ -2413,23 +2449,26 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
24132449 case Some (fundingTxId) =>
24142450 d.spliceStatus match {
24152451 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+ }
24202459 d.spliceStatus
24212460 case _ if d.commitments.latest.fundingTxId == fundingTxId =>
24222461 d.commitments.latest.localFundingStatus match {
24232462 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
24332472 }
24342473 case fundingStatus =>
24352474 // 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