Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions docs/release-notes/eclair-vnext.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,28 @@

## Major changes

### Taproot Channels (without announcements)

This release adds support for taproot channels, as specified in [the BOLTs](https://github.com/lightning/bolts/pull/995).
Taproot channels improve privacy and cost less on-chain fees by using musig2 for the channel output.
This release is fully compatible with the `lnd` implementation of taproot channels.

We don't support public taproot channels yet, as the gossip mechanism for this isn't finalized yet.
It is thus only possible to open "private" (unannounced) taproot channels.
You may follow progress on the specification for public taproot channels [here](https://github.com/lightning/bolts/pull/1059).

This feature is active by default. To disable it, add the following to your `eclair.conf`:

```conf
eclair.features.option_simple_taproot = disabled
```

To open a taproot channel with a node that supports the `option_simple_taproot` feature, use the following command:

```sh
$ eclair-cli open --nodeId=<node_id> --fundingSatoshis=<funding_amount> --channelType=simple_taproot_channel --announceChannel=false
```

### Remove support for non-anchor channels

We remove the code used to support legacy channels that don't use anchor outputs or taproot.
Expand Down
1 change: 1 addition & 0 deletions eclair-core/src/main/resources/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ eclair {
option_zeroconf = disabled
keysend = disabled
option_simple_close = optional
option_simple_taproot = optional
trampoline_payment_prototype = disabled
async_payment_prototype = disabled
on_the_fly_funding = disabled
Expand Down
13 changes: 7 additions & 6 deletions eclair-core/src/main/scala/fr/acinq/eclair/Features.scala
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,11 @@ object Features {
val mandatory = 60
}

case object SimpleTaprootChannels extends Feature with InitFeature with NodeFeature with ChannelTypeFeature {
val rfcName = "option_simple_taproot"
val mandatory = 80
}

case object PhoenixZeroReserve extends Feature with InitFeature with ChannelTypeFeature with PermanentChannelFeature {
val rfcName = "phoenix_zero_reserve"
val mandatory = 128
Expand Down Expand Up @@ -351,11 +356,6 @@ object Features {
val mandatory = 564
}

case object SimpleTaprootChannelsStaging extends Feature with InitFeature with NodeFeature with ChannelTypeFeature {
val rfcName = "option_simple_taproot_staging"
val mandatory = 180
}

/**
* Activate this feature to provide on-the-fly funding to remote nodes, as specified in bLIP 36: https://github.com/lightning/blips/blob/master/blip-0036.md.
* TODO: add NodeFeature once bLIP is merged.
Expand Down Expand Up @@ -399,8 +399,8 @@ object Features {
ZeroConf,
KeySend,
SimpleClose,
SimpleTaprootChannels,
SimpleTaprootChannelsPhoenix,
SimpleTaprootChannelsStaging,
WakeUpNotificationClient,
TrampolinePaymentPrototype,
AsyncPaymentPrototype,
Expand All @@ -421,6 +421,7 @@ object Features {
TrampolinePaymentPrototype -> (PaymentSecret :: Nil),
KeySend -> (VariableLengthOnion :: Nil),
SimpleClose -> (ShutdownAnySegwit :: Nil),
SimpleTaprootChannels -> (ChannelType :: SimpleClose :: Nil),
SimpleTaprootChannelsPhoenix -> (ChannelType :: SimpleClose :: Nil),
AsyncPaymentPrototype -> (TrampolinePaymentPrototype :: Nil),
OnTheFlyFunding -> (SplicePrototype :: Nil),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ case class NodeParams(nodeKeyManager: NodeKeyManager,
// We use the most likely commitment format, even though there is no guarantee that this is the one that will be used.
val commitmentFormat = if (Features.canUseFeature(localFeatures, remoteFeatures, Features.SimpleTaprootChannelsPhoenix)) {
PhoenixSimpleTaprootChannelCommitmentFormat
} else if (Features.canUseFeature(localFeatures, remoteFeatures, Features.SimpleTaprootChannelsStaging)) {
} else if (Features.canUseFeature(localFeatures, remoteFeatures, Features.SimpleTaprootChannels)) {
ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat
} else {
ZeroFeeHtlcTxAnchorOutputsCommitmentFormat
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,14 @@ object ChannelTypes {
override def commitmentFormat: CommitmentFormat = ZeroFeeHtlcTxAnchorOutputsCommitmentFormat
override def toString: String = s"anchor_outputs_zero_fee_htlc_tx${if (scidAlias) "+scid_alias" else ""}${if (zeroConf) "+zeroconf" else ""}"
}
case class SimpleTaprootChannelsStaging(scidAlias: Boolean = false, zeroConf: Boolean = false) extends SupportedChannelType {
case class SimpleTaprootChannel(scidAlias: Boolean = false, zeroConf: Boolean = false) extends SupportedChannelType {
override def features: Set[ChannelTypeFeature] = Set(
if (scidAlias) Some(Features.ScidAlias) else None,
if (zeroConf) Some(Features.ZeroConf) else None,
Some(Features.SimpleTaprootChannelsStaging),
Some(Features.SimpleTaprootChannels),
).flatten
override def commitmentFormat: CommitmentFormat = ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat
override def toString: String = s"simple_taproot_channel_staging${if (scidAlias) "+scid_alias" else ""}${if (zeroConf) "+zeroconf" else ""}"
override def toString: String = s"simple_taproot_channel${if (scidAlias) "+scid_alias" else ""}${if (zeroConf) "+zeroconf" else ""}"
}

case class UnsupportedChannelType(featureBits: Features[InitFeature]) extends ChannelType {
Expand All @@ -127,10 +127,10 @@ object ChannelTypes {
AnchorOutputsZeroFeeHtlcTx(zeroConf = true),
AnchorOutputsZeroFeeHtlcTx(scidAlias = true),
AnchorOutputsZeroFeeHtlcTx(scidAlias = true, zeroConf = true),
SimpleTaprootChannelsStaging(),
SimpleTaprootChannelsStaging(zeroConf = true),
SimpleTaprootChannelsStaging(scidAlias = true),
SimpleTaprootChannelsStaging(scidAlias = true, zeroConf = true),
SimpleTaprootChannel(),
SimpleTaprootChannel(zeroConf = true),
SimpleTaprootChannel(scidAlias = true),
SimpleTaprootChannel(scidAlias = true, zeroConf = true),
SimpleTaprootChannelsPhoenix,
).map {
channelType => Features(channelType.features.map(_ -> FeatureSupport.Mandatory).toMap) -> channelType
Expand All @@ -150,7 +150,9 @@ object ChannelTypes {

/** Returns our preferred channel type for public channels, if supported by our peer. */
def preferredForPublicChannels(localFeatures: Features[InitFeature], remoteFeatures: Features[InitFeature]): Option[SupportedChannelType] = {
if (Features.canUseFeature(localFeatures, remoteFeatures, Features.AnchorOutputsZeroFeeHtlcTx)) {
if (Features.canUseFeature(localFeatures, remoteFeatures, Features.SimpleTaprootChannels)) {
Some(SimpleTaprootChannel(scidAlias = Features.canUseFeature(localFeatures, remoteFeatures, Features.ScidAlias)))
} else if (Features.canUseFeature(localFeatures, remoteFeatures, Features.AnchorOutputsZeroFeeHtlcTx)) {
Some(AnchorOutputsZeroFeeHtlcTx(scidAlias = Features.canUseFeature(localFeatures, remoteFeatures, Features.ScidAlias)))
} else {
None
Expand Down
Loading
Loading