@@ -2242,7 +2242,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
22422242 val nextFundingTlv : Set [ChannelReestablishTlv ] = Set (ChannelReestablishTlv .NextFundingTlv (d.signingSession.fundingTx.txId))
22432243 val channelReestablish = ChannelReestablish (
22442244 channelId = d.channelId,
2245- nextLocalCommitmentNumber = 1 ,
2245+ nextLocalCommitmentNumber = d.signingSession.reconnectNextLocalCommitmentNumber ,
22462246 nextRemoteRevocationNumber = 0 ,
22472247 yourLastPerCommitmentSecret = PrivateKey (ByteVector32 .Zeroes ),
22482248 myCurrentPerCommitmentPoint = myFirstPerCommitmentPoint,
@@ -2257,6 +2257,19 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
22572257 val yourLastPerCommitmentSecret = remotePerCommitmentSecrets.lastIndex.flatMap(remotePerCommitmentSecrets.getHash).getOrElse(ByteVector32 .Zeroes )
22582258 val channelKeyPath = keyManager.keyPath(d.commitments.params.localParams, d.commitments.params.channelConfig)
22592259 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.
22602273 val rbfTlv : Set [ChannelReestablishTlv ] = d match {
22612274 case d : DATA_WAIT_FOR_DUAL_FUNDING_CONFIRMED => d.status match {
22622275 case DualFundingStatus .RbfWaitingForSigs (status) => Set (ChannelReestablishTlv .NextFundingTlv (status.fundingTx.txId))
@@ -2280,7 +2293,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
22802293
22812294 val channelReestablish = ChannelReestablish (
22822295 channelId = d.channelId,
2283- nextLocalCommitmentNumber = d.commitments.localCommitIndex + 1 ,
2296+ nextLocalCommitmentNumber = nextLocalCommitmentNumber ,
22842297 nextRemoteRevocationNumber = d.commitments.remoteCommitIndex,
22852298 yourLastPerCommitmentSecret = PrivateKey (yourLastPerCommitmentSecret),
22862299 myCurrentPerCommitmentPoint = myCurrentPerCommitmentPoint,
@@ -2321,8 +2334,9 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
23212334
23222335 case Event (channelReestablish : ChannelReestablish , d : DATA_WAIT_FOR_DUAL_FUNDING_SIGNED ) =>
23232336 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).
23262340 val commitSig = d.signingSession.remoteCommit.sign(keyManager, d.channelParams, d.signingSession.fundingTxIndex, d.signingSession.fundingParams.remoteFundingPubKey, d.signingSession.commitInput)
23272341 goto(WAIT_FOR_DUAL_FUNDING_SIGNED ) sending commitSig
23282342 case _ => goto(WAIT_FOR_DUAL_FUNDING_SIGNED )
@@ -2333,20 +2347,25 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
23332347 case Some (fundingTxId) =>
23342348 d.status match {
23352349 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+ }
23392360 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
23482368 }
2349- goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending toSend
23502369 case _ =>
23512370 // The fundingTxId must be for an RBF attempt that we didn't store (we got disconnected before receiving
23522371 // their tx_complete): we tell them to abort that RBF attempt.
@@ -2356,14 +2375,31 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
23562375 }
23572376
23582377 case Event (_ : ChannelReestablish , d : DATA_WAIT_FOR_CHANNEL_READY ) =>
2359- log.debug(" re-sending channelReady " )
2378+ log.debug(" re-sending channel_ready " )
23602379 val channelReady = createChannelReady(d.aliases, d.commitments.params)
23612380 goto(WAIT_FOR_CHANNEL_READY ) sending channelReady
23622381
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 " )
23652384 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+ }
23672403
23682404 case Event (channelReestablish : ChannelReestablish , d : DATA_NORMAL ) =>
23692405 Syncing .checkSync(keyManager, d.commitments, channelReestablish) match {
@@ -2389,23 +2425,26 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
23892425 case Some (fundingTxId) =>
23902426 d.spliceStatus match {
23912427 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+ }
23962435 d.spliceStatus
23972436 case _ if d.commitments.latest.fundingTxId == fundingTxId =>
23982437 d.commitments.latest.localFundingStatus match {
23992438 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
24092448 }
24102449 case fundingStatus =>
24112450 // 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