Skip to content

Commit a01cde4

Browse files
committed
Address @sstone comments
1 parent a9c08e7 commit a01cde4

File tree

6 files changed

+16
-13
lines changed

6 files changed

+16
-13
lines changed

docs/release-notes/eclair-vnext.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
### Simplified mutual close
88

9-
This release includes support for the latest [mutual close protocol](https://github.com/lightning/bolts/pull/1096).
9+
This release includes support for the latest [mutual close protocol](https://github.com/lightning/bolts/pull/1205).
1010
This protocol allows both channel participants to decide exactly how much fees they're willing to pay to close the channel.
1111
Each participant obtains a channel closing transaction where they are paying the fees.
1212

eclair-core/src/main/scala/fr/acinq/eclair/channel/Helpers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ object Helpers {
635635
case Success(OP_0 :: OP_PUSHDATA(pubkeyHash, _) :: Nil) if pubkeyHash.size == 20 => true
636636
case Success(OP_0 :: OP_PUSHDATA(scriptHash, _) :: Nil) if scriptHash.size == 32 => true
637637
case Success((OP_1 | OP_2 | OP_3 | OP_4 | OP_5 | OP_6 | OP_7 | OP_8 | OP_9 | OP_10 | OP_11 | OP_12 | OP_13 | OP_14 | OP_15 | OP_16) :: OP_PUSHDATA(program, _) :: Nil) if allowAnySegwit && 2 <= program.length && program.length <= 40 => true
638-
case Success(OP_RETURN :: _) if allowOpReturn => true
638+
case Success(OP_RETURN :: OP_PUSHDATA(data, code) :: Nil) if allowOpReturn => OP_PUSHDATA.isMinimal(data, code) && data.size >= 6 && data.size <= 80
639639
case _ => false
640640
}
641641
}

eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/Channel.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,8 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
752752
if (d.commitments.hasNoPendingHtlcsOrFeeUpdate) {
753753
// there are no pending signed changes, let's directly negotiate a closing transaction
754754
if (Features.canUseFeature(d.commitments.params.localParams.initFeatures, d.commitments.params.remoteParams.initFeatures, Features.SimpleClose)) {
755-
startSimpleClose(d.commitments, localShutdown, remoteShutdown, d.closingFeerates, sendList)
755+
val (d1, closingComplete_opt) = startSimpleClose(d.commitments, localShutdown, remoteShutdown, d.closingFeerates)
756+
goto(NEGOTIATING_SIMPLE) using d1 storing() sending sendList ++ closingComplete_opt.toSeq
756757
} else if (d.commitments.params.localParams.paysClosingFees) {
757758
// we pay the closing fees, so we initiate the negotiation by sending the first closing_signed
758759
val (closingTx, closingSigned) = MutualClose.makeFirstClosingTx(keyManager, d.commitments.latest, localShutdown.scriptPubKey, remoteShutdownScript, nodeParams.currentFeeratesForFundingClosing, nodeParams.onChainFeeConf, d.closingFeerates)
@@ -1536,7 +1537,8 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
15361537
context.system.eventStream.publish(ChannelSignatureReceived(self, commitments1))
15371538
if (commitments1.hasNoPendingHtlcsOrFeeUpdate) {
15381539
if (Features.canUseFeature(d.commitments.params.localParams.initFeatures, d.commitments.params.remoteParams.initFeatures, Features.SimpleClose)) {
1539-
startSimpleClose(d.commitments, localShutdown, remoteShutdown, d.closingFeerates, revocation :: Nil)
1540+
val (d1, closingComplete_opt) = startSimpleClose(d.commitments, localShutdown, remoteShutdown, d.closingFeerates)
1541+
goto(NEGOTIATING_SIMPLE) using d1 storing() sending revocation +: closingComplete_opt.toSeq
15401542
} else if (d.commitments.params.localParams.paysClosingFees) {
15411543
// we pay the closing fees, so we initiate the negotiation by sending the first closing_signed
15421544
val (closingTx, closingSigned) = MutualClose.makeFirstClosingTx(keyManager, commitments1.latest, localShutdown.scriptPubKey, remoteShutdown.scriptPubKey, nodeParams.currentFeeratesForFundingClosing, nodeParams.onChainFeeConf, closingFeerates)
@@ -1580,7 +1582,8 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
15801582
if (commitments1.hasNoPendingHtlcsOrFeeUpdate) {
15811583
log.debug("switching to NEGOTIATING spec:\n{}", commitments1.latest.specs2String)
15821584
if (Features.canUseFeature(d.commitments.params.localParams.initFeatures, d.commitments.params.remoteParams.initFeatures, Features.SimpleClose)) {
1583-
startSimpleClose(d.commitments, localShutdown, remoteShutdown, d.closingFeerates, Nil)
1585+
val (d1, closingComplete_opt) = startSimpleClose(d.commitments, localShutdown, remoteShutdown, d.closingFeerates)
1586+
goto(NEGOTIATING_SIMPLE) using d1 storing() sending closingComplete_opt.toSeq
15841587
} else if (d.commitments.params.localParams.paysClosingFees) {
15851588
// we pay the closing fees, so we initiate the negotiation by sending the first closing_signed
15861589
val (closingTx, closingSigned) = MutualClose.makeFirstClosingTx(keyManager, commitments1.latest, localShutdown.scriptPubKey, remoteShutdown.scriptPubKey, nodeParams.currentFeeratesForFundingClosing, nodeParams.onChainFeeConf, closingFeerates)

eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/CommonHandlers.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import fr.acinq.eclair.channel.Helpers.Closing.MutualClose
2323
import fr.acinq.eclair.channel._
2424
import fr.acinq.eclair.db.PendingCommandsDb
2525
import fr.acinq.eclair.io.Peer
26-
import fr.acinq.eclair.wire.protocol.{HtlcSettlementMessage, LightningMessage, Shutdown, UpdateMessage}
26+
import fr.acinq.eclair.wire.protocol.{ClosingComplete, HtlcSettlementMessage, LightningMessage, Shutdown, UpdateMessage}
2727
import scodec.bits.ByteVector
2828

2929
import scala.concurrent.duration.DurationInt
@@ -132,19 +132,19 @@ trait CommonHandlers {
132132
finalScriptPubKey
133133
}
134134

135-
def startSimpleClose(commitments: Commitments, localShutdown: Shutdown, remoteShutdown: Shutdown, closingFeerates: Option[ClosingFeerates], toSend: List[LightningMessage]) = {
135+
def startSimpleClose(commitments: Commitments, localShutdown: Shutdown, remoteShutdown: Shutdown, closingFeerates: Option[ClosingFeerates]): (DATA_NEGOTIATING_SIMPLE, Option[ClosingComplete]) = {
136136
val localScript = localShutdown.scriptPubKey
137137
val remoteScript = remoteShutdown.scriptPubKey
138138
val closingFeerate = closingFeerates.map(_.preferred).getOrElse(nodeParams.onChainFeeConf.getClosingFeerate(nodeParams.currentBitcoinCoreFeerates))
139139
MutualClose.makeSimpleClosingTx(nodeParams.currentBlockHeight, keyManager, commitments.latest, localScript, remoteScript, closingFeerate) match {
140140
case Left(f) =>
141141
log.warning("cannot create local closing txs, waiting for remote closing_complete: {}", f.getMessage)
142142
val d = DATA_NEGOTIATING_SIMPLE(commitments, closingFeerate, localScript, remoteScript, Nil, Nil)
143-
goto(NEGOTIATING_SIMPLE) using d storing() sending toSend
143+
(d, None)
144144
case Right((closingTxs, closingComplete)) =>
145145
log.debug("signing local mutual close transactions: {}", closingTxs)
146146
val d = DATA_NEGOTIATING_SIMPLE(commitments, closingFeerate, localScript, remoteScript, closingTxs :: Nil, Nil)
147-
goto(NEGOTIATING_SIMPLE) using d storing() sending toSend :+ closingComplete
147+
(d, Some(closingComplete))
148148
}
149149
}
150150

eclair-core/src/main/scala/fr/acinq/eclair/transactions/Transactions.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -923,9 +923,9 @@ object Transactions {
923923
(toLocalOutput_opt, toRemoteOutput_opt) match {
924924
case (Some(toLocalOutput), Some(toRemoteOutput)) =>
925925
val txLocalAndRemote = LexicographicalOrdering.sort(txNoOutput.copy(txOut = Seq(toLocalOutput, toRemoteOutput)))
926-
val toLocalOutputInfo = findPubKeyScriptIndex(txLocalAndRemote, localScriptPubKey).map(index => OutputInfo(index, toLocalOutput.amount, localScriptPubKey)).toOption
926+
val Right(toLocalOutputInfo) = findPubKeyScriptIndex(txLocalAndRemote, localScriptPubKey).map(index => OutputInfo(index, toLocalOutput.amount, localScriptPubKey))
927927
ClosingTxs(
928-
localAndRemote_opt = Some(ClosingTx(input, txLocalAndRemote, toLocalOutputInfo)),
928+
localAndRemote_opt = Some(ClosingTx(input, txLocalAndRemote, Some(toLocalOutputInfo))),
929929
// We also provide a version of the transaction without the remote output, which they may want to omit if not economical to spend.
930930
localOnly_opt = Some(ClosingTx(input, txNoOutput.copy(txOut = Seq(toLocalOutput)), Some(OutputInfo(0, toLocalOutput.amount, localScriptPubKey)))),
931931
remoteOnly_opt = None

eclair-core/src/test/scala/fr/acinq/eclair/payment/relay/AsyncPaymentTriggererSpec.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import com.typesafe.config.ConfigFactory
1010
import fr.acinq.bitcoin.scalacompat.ByteVector32
1111
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
1212
import fr.acinq.eclair.blockchain.CurrentBlockHeight
13-
import fr.acinq.eclair.channel.{NEGOTIATING, NEGOTIATING_SIMPLE}
13+
import fr.acinq.eclair.channel.NEGOTIATING
1414
import fr.acinq.eclair.io.Switchboard.GetPeerInfo
1515
import fr.acinq.eclair.io.{Peer, PeerConnected, PeerReadyManager, Switchboard}
1616
import fr.acinq.eclair.payment.relay.AsyncPaymentTriggerer._
@@ -166,7 +166,7 @@ class AsyncPaymentTriggererSpec extends ScalaTestWithActorTestKit(ConfigFactory.
166166
system.eventStream ! EventStream.Publish(PeerConnected(peer.ref.toClassic, remoteNodeId, null))
167167
val request2 = switchboard.expectMessageType[Switchboard.GetPeerInfo]
168168
request2.replyTo ! Peer.PeerInfo(peer.ref.toClassic, remoteNodeId, Peer.CONNECTED, None, None, Set(TestProbe().ref.toClassic))
169-
peer.expectMessageType[Peer.GetPeerChannels].replyTo ! Peer.PeerChannels(remoteNodeId, Seq(Peer.ChannelInfo(null, NEGOTIATING_SIMPLE, null)))
169+
peer.expectMessageType[Peer.GetPeerChannels].replyTo ! Peer.PeerChannels(remoteNodeId, Seq(Peer.ChannelInfo(null, NEGOTIATING, null)))
170170
probe.expectNoMessage(100 millis)
171171
probe2.expectMessage(AsyncPaymentTriggered)
172172
}

0 commit comments

Comments
 (0)