@@ -2108,7 +2108,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
21082108 val nextFundingTlv : Set [ChannelReestablishTlv ] = Set (ChannelReestablishTlv .NextFundingTlv (d.signingSession.fundingTx.txId))
21092109 val channelReestablish = ChannelReestablish (
21102110 channelId = d.channelId,
2111- nextLocalCommitmentNumber = 1 ,
2111+ nextLocalCommitmentNumber = d.signingSession.reconnectNextLocalCommitmentNumber ,
21122112 nextRemoteRevocationNumber = 0 ,
21132113 yourLastPerCommitmentSecret = PrivateKey (ByteVector32 .Zeroes ),
21142114 myCurrentPerCommitmentPoint = myFirstPerCommitmentPoint,
@@ -2123,6 +2123,19 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
21232123 val yourLastPerCommitmentSecret = remotePerCommitmentSecrets.lastIndex.flatMap(remotePerCommitmentSecrets.getHash).getOrElse(ByteVector32 .Zeroes )
21242124 val channelKeyPath = keyManager.keyPath(d.commitments.params.localParams, d.commitments.params.channelConfig)
21252125 val myCurrentPerCommitmentPoint = keyManager.commitmentPoint(channelKeyPath, d.commitments.localCommitIndex)
2126+ // If we disconnected while signing a funding transaction, we may need our peer to retransmit their commit_sig.
2127+ val nextLocalCommitmentNumber = d match {
2128+ case d : DATA_WAIT_FOR_DUAL_FUNDING_CONFIRMED => d.status match {
2129+ case DualFundingStatus .RbfWaitingForSigs (status) => status.reconnectNextLocalCommitmentNumber
2130+ case _ => d.commitments.localCommitIndex + 1
2131+ }
2132+ case d : DATA_NORMAL => d.spliceStatus match {
2133+ case SpliceStatus .SpliceWaitingForSigs (status) => status.reconnectNextLocalCommitmentNumber
2134+ case _ => d.commitments.localCommitIndex + 1
2135+ }
2136+ case _ => d.commitments.localCommitIndex + 1
2137+ }
2138+ // If we disconnected while signing a funding transaction, we may need our peer to (re)transmit their tx_signatures.
21262139 val rbfTlv : Set [ChannelReestablishTlv ] = d match {
21272140 case d : DATA_WAIT_FOR_DUAL_FUNDING_CONFIRMED => d.status match {
21282141 case DualFundingStatus .RbfWaitingForSigs (status) => Set (ChannelReestablishTlv .NextFundingTlv (status.fundingTx.txId))
@@ -2142,7 +2155,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
21422155 }
21432156 val channelReestablish = ChannelReestablish (
21442157 channelId = d.channelId,
2145- nextLocalCommitmentNumber = d.commitments.localCommitIndex + 1 ,
2158+ nextLocalCommitmentNumber = nextLocalCommitmentNumber ,
21462159 nextRemoteRevocationNumber = d.commitments.remoteCommitIndex,
21472160 yourLastPerCommitmentSecret = PrivateKey (yourLastPerCommitmentSecret),
21482161 myCurrentPerCommitmentPoint = myCurrentPerCommitmentPoint,
@@ -2183,8 +2196,9 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
21832196
21842197 case Event (channelReestablish : ChannelReestablish , d : DATA_WAIT_FOR_DUAL_FUNDING_SIGNED ) =>
21852198 channelReestablish.nextFundingTxId_opt match {
2186- case Some (fundingTxId) if fundingTxId == d.signingSession.fundingTx.txId =>
2187- // We retransmit our commit_sig, and will send our tx_signatures once we've received their commit_sig.
2199+ case Some (fundingTxId) if fundingTxId == d.signingSession.fundingTx.txId && channelReestablish.nextLocalCommitmentNumber == 0 =>
2200+ // They haven't received our commit_sig: we retransmit it, and will send our tx_signatures once we've received
2201+ // their commit_sig or their tx_signatures (depending on who must send tx_signatures first).
21882202 val commitSig = d.signingSession.remoteCommit.sign(keyManager, d.channelParams, d.signingSession.fundingTxIndex, d.signingSession.fundingParams.remoteFundingPubKey, d.signingSession.commitInput)
21892203 goto(WAIT_FOR_DUAL_FUNDING_SIGNED ) sending commitSig
21902204 case _ => goto(WAIT_FOR_DUAL_FUNDING_SIGNED )
@@ -2195,20 +2209,25 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
21952209 case Some (fundingTxId) =>
21962210 d.status match {
21972211 case DualFundingStatus .RbfWaitingForSigs (signingSession) if signingSession.fundingTx.txId == fundingTxId =>
2198- // We retransmit our commit_sig, and will send our tx_signatures once we've received their commit_sig.
2199- val commitSig = signingSession.remoteCommit.sign(keyManager, d.commitments.params, signingSession.fundingTxIndex, signingSession.fundingParams.remoteFundingPubKey, signingSession.commitInput)
2200- goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending commitSig
2212+ if (channelReestablish.nextLocalCommitmentNumber == 0 ) {
2213+ // They haven't received our commit_sig: we retransmit it.
2214+ // We're also waiting for signatures from them, and will send our tx_signatures once we receive them.
2215+ val commitSig = signingSession.remoteCommit.sign(keyManager, d.commitments.params, signingSession.fundingTxIndex, signingSession.fundingParams.remoteFundingPubKey, signingSession.commitInput)
2216+ goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending commitSig
2217+ } else {
2218+ // They have already received our commit_sig, but we were waiting for them to send either commit_sig or
2219+ // tx_signatures first. We wait for their message before sending our tx_signatures.
2220+ goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED )
2221+ }
22012222 case _ if d.latestFundingTx.sharedTx.txId == fundingTxId =>
2202- val toSend = d.latestFundingTx.sharedTx match {
2203- case fundingTx : InteractiveTxBuilder .PartiallySignedSharedTransaction =>
2204- // We have not received their tx_signatures: we retransmit our commit_sig because we don't know if they received it.
2205- val commitSig = d.commitments.latest.remoteCommit.sign(keyManager, d.commitments.params, d.commitments.latest.fundingTxIndex, d.commitments.latest.remoteFundingPubKey, d.commitments.latest.commitInput)
2206- Seq (commitSig, fundingTx.localSigs)
2207- case fundingTx : InteractiveTxBuilder .FullySignedSharedTransaction =>
2208- // 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.
2209- Seq (fundingTx.localSigs)
2223+ // We've already received their commit_sig and sent our tx_signatures. We retransmit our tx_signatures
2224+ // and our commit_sig if they haven't received it already.
2225+ if (channelReestablish.nextLocalCommitmentNumber == 0 ) {
2226+ val commitSig = d.commitments.latest.remoteCommit.sign(keyManager, d.commitments.params, d.commitments.latest.fundingTxIndex, d.commitments.latest.remoteFundingPubKey, d.commitments.latest.commitInput)
2227+ goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending Seq (commitSig, d.latestFundingTx.sharedTx.localSigs)
2228+ } else {
2229+ goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending d.latestFundingTx.sharedTx.localSigs
22102230 }
2211- goto(WAIT_FOR_DUAL_FUNDING_CONFIRMED ) sending toSend
22122231 case _ =>
22132232 // The fundingTxId must be for an RBF attempt that we didn't store (we got disconnected before receiving
22142233 // their tx_complete): we tell them to abort that RBF attempt.
@@ -2250,23 +2269,26 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
22502269 case Some (fundingTxId) =>
22512270 d.spliceStatus match {
22522271 case SpliceStatus .SpliceWaitingForSigs (signingSession) if signingSession.fundingTx.txId == fundingTxId =>
2253- // We retransmit our commit_sig, and will send our tx_signatures once we've received their commit_sig.
2254- log.info(" re-sending commit_sig for splice attempt with fundingTxIndex={} fundingTxId={}" , signingSession.fundingTxIndex, signingSession.fundingTx.txId)
2255- val commitSig = signingSession.remoteCommit.sign(keyManager, d.commitments.params, signingSession.fundingTxIndex, signingSession.fundingParams.remoteFundingPubKey, signingSession.commitInput)
2256- sendQueue = sendQueue :+ commitSig
2272+ if (channelReestablish.nextLocalCommitmentNumber == d.commitments.remoteCommitIndex) {
2273+ // They haven't received our commit_sig: we retransmit it.
2274+ // We're also waiting for signatures from them, and will send our tx_signatures once we receive them.
2275+ log.info(" re-sending commit_sig for splice attempt with fundingTxIndex={} fundingTxId={}" , signingSession.fundingTxIndex, signingSession.fundingTx.txId)
2276+ val commitSig = signingSession.remoteCommit.sign(keyManager, d.commitments.params, signingSession.fundingTxIndex, signingSession.fundingParams.remoteFundingPubKey, signingSession.commitInput)
2277+ sendQueue = sendQueue :+ commitSig
2278+ }
22572279 d.spliceStatus
22582280 case _ if d.commitments.latest.fundingTxId == fundingTxId =>
22592281 d.commitments.latest.localFundingStatus match {
22602282 case dfu : LocalFundingStatus .DualFundedUnconfirmedFundingTx =>
2261- dfu.sharedTx match {
2262- case fundingTx : InteractiveTxBuilder . PartiallySignedSharedTransaction =>
2263- // 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
2264- log.info(" re-sending commit_sig and tx_signatures for fundingTxIndex={} fundingTxId={}" , d.commitments.latest.fundingTxIndex, d.commitments.latest.fundingTxId)
2265- val commitSig = d.commitments.latest.remoteCommit.sign(keyManager, d.commitments.params, d.commitments.latest.fundingTxIndex, d.commitments.latest.remoteFundingPubKey, d.commitments.latest.commitInput)
2266- sendQueue = sendQueue :+ commitSig :+ fundingTx .localSigs
2267- case fundingTx : InteractiveTxBuilder . FullySignedSharedTransaction =>
2268- log.info(" re-sending tx_signatures for fundingTxIndex={} fundingTxId={}" , d.commitments.latest.fundingTxIndex, d.commitments.latest.fundingTxId)
2269- sendQueue = sendQueue :+ fundingTx .localSigs
2283+ // We've already received their commit_sig and sent our tx_signatures. We retransmit our
2284+ // tx_signatures and our commit_sig if they haven't received it already.
2285+ if (channelReestablish.nextLocalCommitmentNumber == d.commitments.remoteCommitIndex) {
2286+ log.info(" re-sending commit_sig and tx_signatures for fundingTxIndex={} fundingTxId={}" , d.commitments.latest.fundingTxIndex, d.commitments.latest.fundingTxId)
2287+ val commitSig = d.commitments.latest.remoteCommit.sign(keyManager, d.commitments.params, d.commitments.latest.fundingTxIndex, d.commitments.latest.remoteFundingPubKey, d.commitments.latest.commitInput)
2288+ sendQueue = sendQueue :+ commitSig :+ dfu.sharedTx .localSigs
2289+ } else {
2290+ log.info(" re-sending tx_signatures for fundingTxIndex={} fundingTxId={}" , d.commitments.latest.fundingTxIndex, d.commitments.latest.fundingTxId)
2291+ sendQueue = sendQueue :+ dfu.sharedTx .localSigs
22702292 }
22712293 case fundingStatus =>
22722294 // 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