Skip to content

Commit db84516

Browse files
committed
Add support for zero-fee commitment format
We add support for the zero-fee commitment format specified in lightning/bolts#1228. Channels using this commitment format benefit from better protection against pinning attacks (thanks to TRUC/v3 transactions), don't need the `update_fee` mechanism, have less dust exposure risk, and use an overall simpler state machine. In this commit, we simply introduce the commitment format and create the corresponding transactions.
1 parent 546028f commit db84516

File tree

16 files changed

+685
-72
lines changed

16 files changed

+685
-72
lines changed

eclair-core/src/main/resources/reference.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ eclair {
7676
option_quiesce = optional
7777
option_attribution_data = optional
7878
option_onion_messages = optional
79+
zero_fee_commitments = disabled
7980
// This feature should only be enabled when acting as an LSP for mobile wallets.
8081
// When activating this feature, the peer-storage section should be customized to match desired SLAs.
8182
option_provide_storage = disabled

eclair-core/src/main/scala/fr/acinq/eclair/Features.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,12 @@ object Features {
277277
val mandatory = 38
278278
}
279279

280+
// TODO: once the spec is final, set feature bit to 40 and activate in reference.conf
281+
case object ZeroFeeCommitments extends Feature with InitFeature with NodeFeature with ChannelTypeFeature {
282+
val rfcName = "zero_fee_commitments"
283+
val mandatory = 140
284+
}
285+
280286
case object ProvideStorage extends Feature with InitFeature with NodeFeature {
281287
val rfcName = "option_provide_storage"
282288
val mandatory = 42
@@ -392,6 +398,7 @@ object Features {
392398
Quiescence,
393399
AttributionData,
394400
OnionMessages,
401+
ZeroFeeCommitments,
395402
ProvideStorage,
396403
ChannelType,
397404
ScidAlias,

eclair-core/src/main/scala/fr/acinq/eclair/blockchain/fee/OnChainFeeConf.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ case class OnChainFeeConf(feeTargets: FeeTargets,
9393
case Transactions.ZeroFeeHtlcTxAnchorOutputsCommitmentFormat | Transactions.ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat =>
9494
// If the fee has a large enough change, we update the fee.
9595
currentFeeratePerKw.toLong == 0 || Math.abs((currentFeeratePerKw.toLong - nextFeeratePerKw.toLong).toDouble / currentFeeratePerKw.toLong) > updateFeeMinDiffRatio
96+
case Transactions.ZeroFeeCommitmentFormat =>
97+
// We never send update_fee when using zero-fee commitments.
98+
false
9699
}
97100
}
98101

@@ -111,6 +114,7 @@ case class OnChainFeeConf(feeTargets: FeeTargets,
111114
val networkFeerate = feerates.fast
112115
val networkMinFee = feerates.minimum
113116
commitmentFormat match {
117+
case Transactions.ZeroFeeCommitmentFormat => FeeratePerKw(0 sat)
114118
case Transactions.UnsafeLegacyAnchorOutputsCommitmentFormat | Transactions.PhoenixSimpleTaprootChannelCommitmentFormat =>
115119
// Since Bitcoin Core v28, 1-parent-1-child package relay has been deployed: it should be ok if the commit tx
116120
// doesn't propagate on its own.

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,15 @@ object ChannelTypes {
9595
override def commitmentFormat: CommitmentFormat = ZeroFeeHtlcTxAnchorOutputsCommitmentFormat
9696
override def toString: String = s"anchor_outputs_zero_fee_htlc_tx${if (scidAlias) "+scid_alias" else ""}${if (zeroConf) "+zeroconf" else ""}"
9797
}
98+
case class ZeroFeeCommitments(scidAlias: Boolean = false, zeroConf: Boolean = false) extends SupportedChannelType {
99+
override def features: Set[ChannelTypeFeature] = Set(
100+
if (scidAlias) Some(Features.ScidAlias) else None,
101+
if (zeroConf) Some(Features.ZeroConf) else None,
102+
Some(Features.ZeroFeeCommitments)
103+
).flatten
104+
override def commitmentFormat: CommitmentFormat = ZeroFeeCommitmentFormat
105+
override def toString: String = s"zero_fee_commitments${if (scidAlias) "+scid_alias" else ""}${if (zeroConf) "+zeroconf" else ""}"
106+
}
98107
case class SimpleTaprootChannelsStaging(scidAlias: Boolean = false, zeroConf: Boolean = false) extends SupportedChannelType {
99108
override def features: Set[ChannelTypeFeature] = Set(
100109
if (scidAlias) Some(Features.ScidAlias) else None,
@@ -131,6 +140,10 @@ object ChannelTypes {
131140
SimpleTaprootChannelsStaging(zeroConf = true),
132141
SimpleTaprootChannelsStaging(scidAlias = true),
133142
SimpleTaprootChannelsStaging(scidAlias = true, zeroConf = true),
143+
ZeroFeeCommitments(),
144+
ZeroFeeCommitments(zeroConf = true),
145+
ZeroFeeCommitments(scidAlias = true),
146+
ZeroFeeCommitments(scidAlias = true, zeroConf = true),
134147
SimpleTaprootChannelsPhoenix,
135148
).map {
136149
channelType => Features(channelType.features.map(_ -> FeatureSupport.Mandatory).toMap) -> channelType
@@ -150,7 +163,9 @@ object ChannelTypes {
150163

151164
/** Returns our preferred channel type for public channels, if supported by our peer. */
152165
def preferredForPublicChannels(localFeatures: Features[InitFeature], remoteFeatures: Features[InitFeature], announceChannel: Boolean): Option[SupportedChannelType] = {
153-
if (Features.canUseFeature(localFeatures, remoteFeatures, Features.AnchorOutputsZeroFeeHtlcTx)) {
166+
if (Features.canUseFeature(localFeatures, remoteFeatures, Features.ZeroFeeCommitments)) {
167+
Some(ZeroFeeCommitments(scidAlias = !announceChannel && Features.canUseFeature(localFeatures, remoteFeatures, Features.ScidAlias)))
168+
} else if (Features.canUseFeature(localFeatures, remoteFeatures, Features.AnchorOutputsZeroFeeHtlcTx)) {
154169
Some(AnchorOutputsZeroFeeHtlcTx(scidAlias = !announceChannel && Features.canUseFeature(localFeatures, remoteFeatures, Features.ScidAlias)))
155170
} else {
156171
None

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -721,8 +721,8 @@ object Commitment {
721721
commitmentInput: InputInfo,
722722
commitmentFormat: CommitmentFormat,
723723
spec: CommitmentSpec): (CommitTx, Seq[UnsignedHtlcTx]) = {
724-
val outputs = makeCommitTxOutputs(localFundingKey.publicKey, remoteFundingPubKey, commitKeys.publicKeys, channelParams.localParams.paysCommitTxFees, commitParams.dustLimit, commitParams.toSelfDelay, spec, commitmentFormat)
725-
val commitTx = makeCommitTx(commitmentInput, commitTxNumber, commitKeys.ourPaymentBasePoint, channelParams.remoteParams.paymentBasepoint, channelParams.localParams.isChannelOpener, outputs)
724+
val outputs = makeCommitTxOutputs(localFundingKey.publicKey, remoteFundingPubKey, commitmentInput, commitKeys.publicKeys, channelParams.localParams.paysCommitTxFees, commitParams.dustLimit, commitParams.toSelfDelay, spec, commitmentFormat)
725+
val commitTx = makeCommitTx(commitmentInput, commitTxNumber, commitKeys.ourPaymentBasePoint, channelParams.remoteParams.paymentBasepoint, channelParams.localParams.isChannelOpener, commitmentFormat, outputs)
726726
val htlcTxs = makeHtlcTxs(commitTx.tx, outputs, commitmentFormat)
727727
(commitTx, htlcTxs)
728728
}
@@ -736,8 +736,8 @@ object Commitment {
736736
commitmentInput: InputInfo,
737737
commitmentFormat: CommitmentFormat,
738738
spec: CommitmentSpec): (CommitTx, Seq[UnsignedHtlcTx]) = {
739-
val outputs = makeCommitTxOutputs(remoteFundingPubKey, localFundingKey.publicKey, commitKeys.publicKeys, !channelParams.localParams.paysCommitTxFees, commitParams.dustLimit, commitParams.toSelfDelay, spec, commitmentFormat)
740-
val commitTx = makeCommitTx(commitmentInput, commitTxNumber, channelParams.remoteParams.paymentBasepoint, commitKeys.ourPaymentBasePoint, !channelParams.localParams.isChannelOpener, outputs)
739+
val outputs = makeCommitTxOutputs(remoteFundingPubKey, localFundingKey.publicKey, commitmentInput, commitKeys.publicKeys, !channelParams.localParams.paysCommitTxFees, commitParams.dustLimit, commitParams.toSelfDelay, spec, commitmentFormat)
740+
val commitTx = makeCommitTx(commitmentInput, commitTxNumber, channelParams.remoteParams.paymentBasepoint, commitKeys.ourPaymentBasePoint, !channelParams.localParams.isChannelOpener, commitmentFormat, outputs)
741741
val htlcTxs = makeHtlcTxs(commitTx.tx, outputs, commitmentFormat)
742742
(commitTx, htlcTxs)
743743
}

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ object Helpers {
140140
val channelFeatures = ChannelFeatures(channelType, localFeatures, remoteFeatures, open.channelFlags.announceChannel)
141141
channelType.commitmentFormat match {
142142
case _: SimpleTaprootChannelCommitmentFormat => if (open.commitNonce_opt.isEmpty) return Left(MissingCommitNonce(open.temporaryChannelId, TxId(ByteVector32.Zeroes), commitmentNumber = 0))
143-
case _: AnchorOutputsCommitmentFormat => ()
143+
case _: SegwitV0CommitmentFormat => ()
144144
}
145145

146146
// BOLT #2: The receiving node MUST fail the channel if: it considers feerate_per_kw too small for timely processing or unreasonably large.
@@ -244,7 +244,7 @@ object Helpers {
244244
val channelFeatures = ChannelFeatures(channelType, localFeatures, remoteFeatures, open.channelFlags.announceChannel)
245245
channelType.commitmentFormat match {
246246
case _: SimpleTaprootChannelCommitmentFormat => if (accept.commitNonce_opt.isEmpty) return Left(MissingCommitNonce(open.temporaryChannelId, TxId(ByteVector32.Zeroes), commitmentNumber = 0))
247-
case _: AnchorOutputsCommitmentFormat => ()
247+
case _: SegwitV0CommitmentFormat => ()
248248
}
249249
extractShutdownScript(accept.temporaryChannelId, localFeatures, remoteFeatures, accept.upfrontShutdownScript_opt).map(script_opt => (channelFeatures, script_opt))
250250
}
@@ -778,7 +778,7 @@ object Helpers {
778778
dummyClosingTxs.preferred_opt match {
779779
case Some(dummyTx) =>
780780
commitment.commitmentFormat match {
781-
case _: AnchorOutputsCommitmentFormat =>
781+
case _: SegwitV0CommitmentFormat =>
782782
val dummyPubkey = commitment.remoteFundingPubKey
783783
val dummySig = IndividualSignature(Transactions.PlaceHolderSig)
784784
val dummySignedTx = dummyTx.aggregateSigs(dummyPubkey, dummyPubkey, dummySig, dummySig)
@@ -816,7 +816,7 @@ object Helpers {
816816
closingTxs.remoteOnly_opt.flatMap(tx => localSig(tx, localNonces.remoteOnly)).map(ClosingCompleteTlv.CloseeOutputOnlyPartialSignature(_)),
817817
).flatten[ClosingCompleteTlv])
818818
}
819-
case _: AnchorOutputsCommitmentFormat => TlvStream(Set(
819+
case _: SegwitV0CommitmentFormat => TlvStream(Set(
820820
closingTxs.localAndRemote_opt.map(tx => ClosingTlv.CloserAndCloseeOutputs(tx.sign(localFundingKey, commitment.remoteFundingPubKey).sig)),
821821
closingTxs.localOnly_opt.map(tx => ClosingTlv.CloserOutputOnly(tx.sign(localFundingKey, commitment.remoteFundingPubKey).sig)),
822822
closingTxs.remoteOnly_opt.map(tx => ClosingTlv.CloseeOutputOnly(tx.sign(localFundingKey, commitment.remoteFundingPubKey).sig)),
@@ -870,7 +870,7 @@ object Helpers {
870870
case None => Left(MissingCloseSignature(commitment.channelId))
871871
}
872872
}
873-
case _: AnchorOutputsCommitmentFormat =>
873+
case _: SegwitV0CommitmentFormat =>
874874
(closingTxs.localAndRemote_opt, closingTxs.localOnly_opt) match {
875875
case (Some(_), Some(_)) if closingComplete.closerAndCloseeOutputsSig_opt.isEmpty && closingComplete.closeeOutputOnlySig_opt.isEmpty => return Left(MissingCloseSignature(commitment.channelId))
876876
case (Some(_), None) if closingComplete.closerAndCloseeOutputsSig_opt.isEmpty => return Left(MissingCloseSignature(commitment.channelId))
@@ -1054,7 +1054,7 @@ object Helpers {
10541054
/** Create outputs of the local commitment transaction, allowing us for example to identify HTLC outputs. */
10551055
def makeLocalCommitTxOutputs(channelKeys: ChannelKeys, commitKeys: LocalCommitmentKeys, commitment: FullCommitment): Seq[CommitmentOutput] = {
10561056
val fundingKey = channelKeys.fundingKey(commitment.fundingTxIndex)
1057-
makeCommitTxOutputs(fundingKey.publicKey, commitment.remoteFundingPubKey, commitKeys.publicKeys, commitment.localChannelParams.paysCommitTxFees, commitment.localCommitParams.dustLimit, commitment.localCommitParams.toSelfDelay, commitment.localCommit.spec, commitment.commitmentFormat)
1057+
makeCommitTxOutputs(fundingKey.publicKey, commitment.remoteFundingPubKey, commitment.commitInput(channelKeys), commitKeys.publicKeys, commitment.localChannelParams.paysCommitTxFees, commitment.localCommitParams.dustLimit, commitment.localCommitParams.toSelfDelay, commitment.localCommit.spec, commitment.commitmentFormat)
10581058
}
10591059

10601060
/**
@@ -1226,7 +1226,7 @@ object Helpers {
12261226
/** Claim our main output from the remote commitment transaction, if available. */
12271227
def claimMainOutput(commitKeys: RemoteCommitmentKeys, commitTx: Transaction, dustLimit: Satoshi, commitmentFormat: CommitmentFormat, feerate: FeeratePerKw, finalScriptPubKey: ByteVector)(implicit log: LoggingAdapter): Option[ClaimRemoteDelayedOutputTx] = {
12281228
commitmentFormat match {
1229-
case _: AnchorOutputsCommitmentFormat | _: SimpleTaprootChannelCommitmentFormat => withTxGenerationLog("remote-main-delayed") {
1229+
case _: AnchorOutputsCommitmentFormat | _: SimpleTaprootChannelCommitmentFormat | ZeroFeeCommitmentFormat => withTxGenerationLog("remote-main-delayed") {
12301230
ClaimRemoteDelayedOutputTx.createUnsignedTx(commitKeys, commitTx, dustLimit, finalScriptPubKey, feerate, commitmentFormat)
12311231
}
12321232
}
@@ -1235,7 +1235,7 @@ object Helpers {
12351235
/** Create outputs of the remote commitment transaction, allowing us for example to identify HTLC outputs. */
12361236
def makeRemoteCommitTxOutputs(channelKeys: ChannelKeys, commitKeys: RemoteCommitmentKeys, commitment: FullCommitment, remoteCommit: RemoteCommit): Seq[CommitmentOutput] = {
12371237
val fundingKey = channelKeys.fundingKey(commitment.fundingTxIndex)
1238-
makeCommitTxOutputs(commitment.remoteFundingPubKey, fundingKey.publicKey, commitKeys.publicKeys, !commitment.localChannelParams.paysCommitTxFees, commitment.remoteCommitParams.dustLimit, commitment.remoteCommitParams.toSelfDelay, remoteCommit.spec, commitment.commitmentFormat)
1238+
makeCommitTxOutputs(commitment.remoteFundingPubKey, fundingKey.publicKey, commitment.commitInput(channelKeys), commitKeys.publicKeys, !commitment.localChannelParams.paysCommitTxFees, commitment.remoteCommitParams.dustLimit, commitment.remoteCommitParams.toSelfDelay, remoteCommit.spec, commitment.commitmentFormat)
12391239
}
12401240

12411241
/**
@@ -1394,7 +1394,7 @@ object Helpers {
13941394

13951395
// First we will claim our main output right away.
13961396
val mainTx_opt = commitmentFormat match {
1397-
case _: AnchorOutputsCommitmentFormat | _: SimpleTaprootChannelCommitmentFormat => withTxGenerationLog("remote-main-delayed") {
1397+
case _: AnchorOutputsCommitmentFormat | _: SimpleTaprootChannelCommitmentFormat | ZeroFeeCommitmentFormat => withTxGenerationLog("remote-main-delayed") {
13981398
ClaimRemoteDelayedOutputTx.createUnsignedTx(commitKeys, commitTx, dustLimit, finalScriptPubKey, feerateMain, commitmentFormat)
13991399
}
14001400
}

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import fr.acinq.eclair.crypto.keymanager.{LocalCommitmentKeys, RemoteCommitmentK
3232
import fr.acinq.eclair.crypto.{NonceGenerator, ShaChain}
3333
import fr.acinq.eclair.io.Peer.OpenChannelResponse
3434
import fr.acinq.eclair.transactions.Transactions
35-
import fr.acinq.eclair.transactions.Transactions.{AnchorOutputsCommitmentFormat, SimpleTaprootChannelCommitmentFormat}
35+
import fr.acinq.eclair.transactions.Transactions.{SegwitV0CommitmentFormat, SimpleTaprootChannelCommitmentFormat}
3636
import fr.acinq.eclair.wire.protocol.{AcceptChannel, AcceptChannelTlv, AnnouncementSignatures, ChannelReady, ChannelTlv, Error, FundingCreated, FundingSigned, OpenChannel, OpenChannelTlv, TlvStream}
3737
import fr.acinq.eclair.{MilliSatoshiLong, randomKey, toLongId}
3838
import scodec.bits.ByteVector
@@ -79,7 +79,7 @@ trait ChannelOpenSingleFunded extends SingleFundingHandlers with ErrorHandlers {
7979
val localShutdownScript = input.localChannelParams.upfrontShutdownScript_opt.getOrElse(ByteVector.empty)
8080
val localNonce = input.channelType.commitmentFormat match {
8181
case _: SimpleTaprootChannelCommitmentFormat => Some(NonceGenerator.verificationNonce(NonceGenerator.dummyFundingTxId, fundingKey, NonceGenerator.dummyRemoteFundingPubKey, 0).publicNonce)
82-
case _: AnchorOutputsCommitmentFormat => None
82+
case _: SegwitV0CommitmentFormat => None
8383
}
8484
val open = OpenChannel(
8585
chainHash = nodeParams.chainHash,
@@ -134,7 +134,7 @@ trait ChannelOpenSingleFunded extends SingleFundingHandlers with ErrorHandlers {
134134
val localShutdownScript = d.initFundee.localChannelParams.upfrontShutdownScript_opt.getOrElse(ByteVector.empty)
135135
val localNonce = d.initFundee.channelType.commitmentFormat match {
136136
case _: SimpleTaprootChannelCommitmentFormat => Some(NonceGenerator.verificationNonce(NonceGenerator.dummyFundingTxId, fundingKey, NonceGenerator.dummyRemoteFundingPubKey, 0).publicNonce)
137-
case _: AnchorOutputsCommitmentFormat => None
137+
case _: SegwitV0CommitmentFormat => None
138138
}
139139
val accept = AcceptChannel(temporaryChannelId = open.temporaryChannelId,
140140
dustLimitSatoshis = localCommitParams.dustLimit,
@@ -233,7 +233,7 @@ trait ChannelOpenSingleFunded extends SingleFundingHandlers with ErrorHandlers {
233233
}
234234
case None => Left(MissingCommitNonce(d.channelId, NonceGenerator.dummyFundingTxId, commitmentNumber = 0))
235235
}
236-
case _: AnchorOutputsCommitmentFormat => Right(remoteCommitTx.sign(fundingKey, d.remoteFundingPubKey))
236+
case _: SegwitV0CommitmentFormat => Right(remoteCommitTx.sign(fundingKey, d.remoteFundingPubKey))
237237
}
238238
localSigOfRemoteTx match {
239239
case Left(f) => handleLocalError(f, d, None)
@@ -303,7 +303,7 @@ trait ChannelOpenSingleFunded extends SingleFundingHandlers with ErrorHandlers {
303303
}
304304
case None => Left(MissingCommitNonce(channelId, NonceGenerator.dummyFundingTxId, commitmentNumber = 0))
305305
}
306-
case _: AnchorOutputsCommitmentFormat => Right(remoteCommitTx.sign(fundingKey, d.remoteFundingPubKey))
306+
case _: SegwitV0CommitmentFormat => Right(remoteCommitTx.sign(fundingKey, d.remoteFundingPubKey))
307307
}
308308
localSigOfRemoteTx match {
309309
case Left(f) => handleLocalError(f, d, Some(fc))

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import fr.acinq.eclair.channel._
2626
import fr.acinq.eclair.channel.fsm.Channel.{BroadcastChannelUpdate, PeriodicRefresh, REFRESH_CHANNEL_UPDATE_INTERVAL}
2727
import fr.acinq.eclair.crypto.NonceGenerator
2828
import fr.acinq.eclair.db.RevokedHtlcInfoCleaner
29-
import fr.acinq.eclair.transactions.Transactions.{AnchorOutputsCommitmentFormat, SimpleTaprootChannelCommitmentFormat}
29+
import fr.acinq.eclair.transactions.Transactions.{SegwitV0CommitmentFormat, SimpleTaprootChannelCommitmentFormat}
3030
import fr.acinq.eclair.wire.protocol._
3131
import fr.acinq.eclair.{RealShortChannelId, ShortChannelId}
3232

@@ -136,7 +136,7 @@ trait CommonFundingHandlers extends CommonHandlers {
136136
val localFundingKey = channelKeys.fundingKey(fundingTxIndex = 0)
137137
val nextLocalNonce = NonceGenerator.verificationNonce(commitments.latest.fundingTxId, localFundingKey, commitments.latest.remoteFundingPubKey, 1)
138138
ChannelReady(params.channelId, nextPerCommitmentPoint, aliases.localAlias, nextLocalNonce.publicNonce)
139-
case _: AnchorOutputsCommitmentFormat =>
139+
case _: SegwitV0CommitmentFormat =>
140140
ChannelReady(params.channelId, nextPerCommitmentPoint, aliases.localAlias)
141141
}
142142
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import fr.acinq.eclair.channel._
2424
import fr.acinq.eclair.crypto.NonceGenerator
2525
import fr.acinq.eclair.db.PendingCommandsDb
2626
import fr.acinq.eclair.io.Peer
27-
import fr.acinq.eclair.transactions.Transactions.{AnchorOutputsCommitmentFormat, SimpleTaprootChannelCommitmentFormat}
27+
import fr.acinq.eclair.transactions.Transactions.{SegwitV0CommitmentFormat, SimpleTaprootChannelCommitmentFormat}
2828
import fr.acinq.eclair.wire.protocol.{ClosingComplete, HtlcSettlementMessage, LightningMessage, Shutdown, UpdateMessage}
2929
import scodec.bits.ByteVector
3030

@@ -142,7 +142,7 @@ trait CommonHandlers {
142142
val localCloseeNonce = NonceGenerator.signingNonce(localFundingPubKey, commitments.latest.remoteFundingPubKey, commitments.latest.fundingTxId)
143143
localCloseeNonce_opt = Some(localCloseeNonce)
144144
Shutdown(commitments.channelId, finalScriptPubKey, localCloseeNonce.publicNonce)
145-
case _: AnchorOutputsCommitmentFormat =>
145+
case _: SegwitV0CommitmentFormat =>
146146
Shutdown(commitments.channelId, finalScriptPubKey)
147147
}
148148
}

0 commit comments

Comments
 (0)