@@ -1727,77 +1727,69 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
17271727
17281728 when(NEGOTIATING_SIMPLE )(handleExceptions {
17291729 case Event (remoteShutdown : Shutdown , d : DATA_NEGOTIATING_SIMPLE ) =>
1730+ val localScript = d.status.localShutdown.scriptPubKey
1731+ val remoteScript = remoteShutdown.scriptPubKey
17301732 d.status match {
17311733 case status : ClosingNegotiation .WaitingForRemoteShutdown =>
17321734 // We have already sent our shutdown. Now that we've received theirs, we're ready to sign closing transactions.
1733- // If we don't have a closing feerate, we don't need to create a new version of our closing transaction (which
1734- // can happen after a reconnection for example).
1735- status.onRemoteShutdown match {
1736- case OnRemoteShutdown .SignTransaction (closingFeerate) =>
1737- val localScript = status.localShutdown.scriptPubKey
1738- val remoteScript = remoteShutdown.scriptPubKey
1739- MutualClose .makeSimpleClosingTx(nodeParams.currentBlockHeight, keyManager, d.commitments.latest, localScript, remoteScript, closingFeerate) match {
1740- case Left (f) =>
1741- log.warning(" cannot create local closing txs, waiting for remote closing_complete: {}" , f.getMessage)
1742- val status1 = ClosingNegotiation .SigningTransactions (status.localShutdown, remoteShutdown, None , None , None )
1743- stay() using d.copy(status = status1)
1744- case Right ((closingTxs, closingComplete)) =>
1745- log.debug(" signing local mutual close transactions: {}" , closingTxs)
1746- val status1 = ClosingNegotiation .SigningTransactions (status.localShutdown, remoteShutdown, Some (ClosingCompleteSent (closingComplete, closingFeerate)), None , None )
1747- stay() using d.copy(status = status1, proposedClosingTxs = d.proposedClosingTxs :+ closingTxs) storing() sending closingComplete
1748- }
1749- case OnRemoteShutdown .WaitForSigs =>
1750- val status1 = ClosingNegotiation .SigningTransactions (status.localShutdown, remoteShutdown, None , None , None )
1735+ MutualClose .makeSimpleClosingTx(nodeParams.currentBlockHeight, keyManager, d.commitments.latest, localScript, remoteScript, status.closingFeerate) match {
1736+ case Left (f) =>
1737+ log.warning(" cannot create local closing txs, waiting for remote closing_complete: {}" , f.getMessage)
1738+ val status1 = ClosingNegotiation .SigningTransactions (status.localShutdown, remoteShutdown, status.closingFeerate, None , None , None )
17511739 stay() using d.copy(status = status1)
1740+ case Right ((closingTxs, closingComplete)) =>
1741+ log.debug(" signing local mutual close transactions: {}" , closingTxs)
1742+ val status1 = ClosingNegotiation .SigningTransactions (status.localShutdown, remoteShutdown, status.closingFeerate, Some (closingComplete), None , None )
1743+ stay() using d.copy(status = status1, proposedClosingTxs = d.proposedClosingTxs :+ closingTxs) storing() sending closingComplete
17521744 }
1753- case status : ClosingNegotiation .SigningTransactions =>
1754- // We were in the middle of signing transactions: we restart a signing round from scratch.
1755- // If we were waiting for their signature, we will send closing_complete again after exchanging shutdown.
1756- val localShutdown = status.localShutdown
1757- val onRemoteShutdown = status.closingCompleteSent_opt.map(_.closingFeerate) match {
1758- case Some (closingFeerate) if status.closingSigReceived_opt.isEmpty => OnRemoteShutdown .SignTransaction (closingFeerate)
1759- case _ => OnRemoteShutdown .WaitForSigs
1760- }
1761- val status1 = ClosingNegotiation .WaitingForRemoteShutdown (localShutdown, onRemoteShutdown)
1762- self ! remoteShutdown
1763- stay() using d.copy(status = status1) sending localShutdown
1745+ case _ : ClosingNegotiation .SigningTransactions =>
1746+ // We were in the middle of signing transactions: sending shutdown is forbidden at that point.
1747+ context.system.scheduler.scheduleOnce(2 second, peer, Peer .Disconnect (remoteNodeId))
1748+ stay() sending Warning (d.channelId, ShutdownWaitingForSigs (d.channelId).getMessage)
17641749 case status : ClosingNegotiation .WaitingForConfirmation =>
17651750 // Our peer wants to create a new version of their closing transaction. We don't need to update our version of
1766- // the closing transaction: we re-send our previous shutdown and wait for their closing_complete .
1751+ // the closing transaction: we use the same parameters as we did in the previous signing round .
17671752 val localShutdown = status.localShutdown
1768- val status1 = ClosingNegotiation .SigningTransactions (localShutdown, remoteShutdown, None , None , None )
1769- stay() using d.copy(status = status1) sending localShutdown
1753+ MutualClose .makeSimpleClosingTx(nodeParams.currentBlockHeight, keyManager, d.commitments.latest, localScript, remoteScript, status.closingFeerate) match {
1754+ case Left (f) =>
1755+ log.warning(" cannot create local closing txs, waiting for remote closing_complete: {}" , f.getMessage)
1756+ val status1 = ClosingNegotiation .SigningTransactions (localShutdown, remoteShutdown, status.closingFeerate, None , None , None )
1757+ stay() using d.copy(status = status1) sending localShutdown
1758+ case Right ((closingTxs, closingComplete)) =>
1759+ log.debug(" signing local mutual close transactions: {}" , closingTxs)
1760+ val status1 = ClosingNegotiation .SigningTransactions (localShutdown, remoteShutdown, status.closingFeerate, Some (closingComplete), None , None )
1761+ stay() using d.copy(status = status1, proposedClosingTxs = d.proposedClosingTxs :+ closingTxs) storing() sending Seq (localShutdown, closingComplete)
1762+ }
17701763 }
17711764
17721765 case Event (closingComplete : ClosingComplete , d : DATA_NEGOTIATING_SIMPLE ) =>
17731766 d.status match {
17741767 case _ : ClosingNegotiation .WaitingForRemoteShutdown =>
17751768 log.info(" ignoring remote closing_complete, we've sent shutdown to initiate a new signing round" )
1776- stay()
1769+ stay() sending Warning (d.channelId, UnexpectedClosingComplete (d.channelId, closingComplete.fees, closingComplete.lockTime).getMessage)
17771770 case _ : ClosingNegotiation .WaitingForConfirmation =>
17781771 log.info(" ignoring closing_complete, we've already sent closing_sig: peer must send shutdown again before closing_complete" )
17791772 stay() sending Warning (d.channelId, UnexpectedClosingComplete (d.channelId, closingComplete.fees, closingComplete.lockTime).getMessage)
17801773 case status : ClosingNegotiation .SigningTransactions if status.closingSigSent_opt.nonEmpty =>
1781- log.info(" ignoring closing_complete, we've already sent closing_sig: peer must send shutdown again before closing_complete" )
1774+ log.info(" ignoring closing_complete, we've already sent closing_sig: peer must send closing_sig, then shutdown again before closing_complete" )
17821775 stay() sending Warning (d.channelId, UnexpectedClosingComplete (d.channelId, closingComplete.fees, closingComplete.lockTime).getMessage)
17831776 case status : ClosingNegotiation .SigningTransactions =>
17841777 val localScript = status.localShutdown.scriptPubKey
17851778 val remoteScript = status.remoteShutdown.scriptPubKey
17861779 MutualClose .signSimpleClosingTx(keyManager, d.commitments.latest, localScript, remoteScript, closingComplete) match {
17871780 case Left (f) =>
1788- // This may happen if scripts were updated concurrently, so we simply ignore failures.
17891781 log.warning(" invalid closing_complete: {}" , f.getMessage)
1790- stay()
1782+ stay() sending Warning (d.channelId, f.getMessage)
17911783 case Right ((signedClosingTx, closingSig)) =>
17921784 log.debug(" signing remote mutual close transaction: {}" , signedClosingTx.tx)
17931785 val status1 = status.closingCompleteSent_opt match {
17941786 // We've sent closing_complete: we may be waiting for their closing_sig.
17951787 case Some (_) => status.closingSigReceived_opt match {
1796- case Some (_) => ClosingNegotiation .WaitingForConfirmation (status.localShutdown, status.remoteShutdown)
1788+ case Some (_) => ClosingNegotiation .WaitingForConfirmation (status.localShutdown, status.remoteShutdown, status.closingFeerate )
17971789 case None => status.copy(closingSigSent_opt = Some (closingSig))
17981790 }
1799- // We haven't sent closing_complete: we're not waiting for their closing_sig' .
1800- case None => ClosingNegotiation .WaitingForConfirmation (status.localShutdown, status.remoteShutdown)
1791+ // We haven't sent closing_complete: we're not waiting for their closing_sig.
1792+ case None => ClosingNegotiation .WaitingForConfirmation (status.localShutdown, status.remoteShutdown, status.closingFeerate )
18011793 }
18021794 val d1 = d.copy(status = status1, publishedClosingTxs = d.publishedClosingTxs :+ signedClosingTx)
18031795 stay() using d1 storing() calling doPublish(signedClosingTx, localPaysClosingFees = false ) sending closingSig
@@ -1818,14 +1810,13 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
18181810 case status : ClosingNegotiation .SigningTransactions =>
18191811 MutualClose .receiveSimpleClosingSig(keyManager, d.commitments.latest, d.proposedClosingTxs.last, closingSig) match {
18201812 case Left (f) =>
1821- // This may happen if scripts were updated concurrently, so we simply ignore failures.
18221813 log.warning(" invalid closing_sig: {}" , f.getMessage)
1823- stay()
1814+ stay() sending Warning (d.channelId, f.getMessage)
18241815 case Right (signedClosingTx) =>
18251816 log.debug(" received signatures for local mutual close transaction: {}" , signedClosingTx.tx)
18261817 val status1 = status.closingSigSent_opt match {
18271818 // We have already signed their transaction: both local and remote closing transactions have been updated.
1828- case Some (_) => ClosingNegotiation .WaitingForConfirmation (status.localShutdown, status.remoteShutdown)
1819+ case Some (_) => ClosingNegotiation .WaitingForConfirmation (status.localShutdown, status.remoteShutdown, status.closingFeerate )
18291820 // We haven't sent closing_sig yet: they may send us closing_complete to update their closing transaction.
18301821 case None => status.copy(closingSigReceived_opt = Some (closingSig))
18311822 }
@@ -1859,17 +1850,17 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
18591850 log.info(" we're already waiting for our peer to send their shutdown message, no need to send ours again" )
18601851 handleCommandError(ClosingAlreadyInProgress (d.channelId), c)
18611852 case _ : ClosingNegotiation .SigningTransactions =>
1862- val status1 = ClosingNegotiation . WaitingForRemoteShutdown (localShutdown, OnRemoteShutdown . SignTransaction (closingFeerate) )
1863- stay() using d.copy(status = status1) storing() sending localShutdown
1853+ log.info( " we're in the middle of signing closing transactions, we should finish this round before starting a new signing session " )
1854+ handleCommandError( ClosingAlreadyInProgress (d.channelId), c)
18641855 case _ : ClosingNegotiation .WaitingForConfirmation =>
1865- val status1 = ClosingNegotiation .WaitingForRemoteShutdown (localShutdown, OnRemoteShutdown . SignTransaction ( closingFeerate) )
1856+ val status1 = ClosingNegotiation .WaitingForRemoteShutdown (localShutdown, closingFeerate)
18661857 stay() using d.copy(status = status1) storing() sending localShutdown
18671858 }
18681859
18691860 case Event (e : Error , d : DATA_NEGOTIATING_SIMPLE ) => handleRemoteError(e, d)
18701861
18711862 case Event (INPUT_DISCONNECTED , d : DATA_NEGOTIATING_SIMPLE ) =>
1872- val status1 = d.status.disconnect( )
1863+ val status1 = ClosingNegotiation . WaitingForRemoteShutdown ( d.status.localShutdown, d.status.closingFeerate )
18731864 goto(OFFLINE ) using d.copy(status = status1)
18741865
18751866 })
@@ -2526,10 +2517,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
25262517 case Event (_ : ChannelReestablish , d : DATA_NEGOTIATING_SIMPLE ) =>
25272518 // We retransmit our shutdown: we may have updated our script and they may not have received it.
25282519 val localShutdown = d.status.localShutdown
2529- val status1 = d.status match {
2530- case status : ClosingNegotiation .WaitingForRemoteShutdown => status.copy(localShutdown = localShutdown)
2531- case _ => ClosingNegotiation .WaitingForRemoteShutdown (localShutdown, OnRemoteShutdown .WaitForSigs )
2532- }
2520+ val status1 = ClosingNegotiation .WaitingForRemoteShutdown (localShutdown, d.status.closingFeerate)
25332521 goto(NEGOTIATING_SIMPLE ) using d.copy(status = status1) sending localShutdown
25342522
25352523 // This handler is a workaround for an issue in lnd: starting with versions 0.10 / 0.11, they sometimes fail to send
0 commit comments