Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement option_simple_close #597

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
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
13 changes: 11 additions & 2 deletions modules/core/src/commonMain/kotlin/fr/acinq/lightning/Features.kt
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,6 @@ sealed class Feature {
override val scopes: Set<FeatureScope> get() = setOf(FeatureScope.Invoice)
}

// The following features have not been standardised, hence the high feature bits to avoid conflicts.

// We historically used the following feature bit in our invoices.
// However, the spec assigned the same feature bit to `option_scid_alias` (https://github.com/lightning/bolts/pull/910).
// We're moving this feature bit to 148, but we have to keep supporting it until enough wallet users have migrated, then we can remove it.
Expand All @@ -160,6 +158,15 @@ sealed class Feature {
override val scopes: Set<FeatureScope> get() = setOf(FeatureScope.Init, FeatureScope.Node, FeatureScope.Invoice)
}

@Serializable
object SimpleClose : Feature() {
override val rfcName get() = "option_simple_close"
override val mandatory get() = 60
override val scopes: Set<FeatureScope> get() = setOf(FeatureScope.Init, FeatureScope.Node)
}

// The following features have not been standardised, hence the high feature bits to avoid conflicts.

/** This feature bit should be activated when a node accepts having their channel reserve set to 0. */
@Serializable
object ZeroReserveChannels : Feature() {
Expand Down Expand Up @@ -340,6 +347,7 @@ data class Features(val activated: Map<Feature, FeatureSupport>, val unknown: Se
Feature.ChannelType,
Feature.PaymentMetadata,
Feature.TrampolinePayment,
Feature.SimpleClose,
Feature.ExperimentalTrampolinePayment,
Feature.ZeroReserveChannels,
Feature.ZeroConfChannels,
Expand Down Expand Up @@ -384,6 +392,7 @@ data class Features(val activated: Map<Feature, FeatureSupport>, val unknown: Se
Feature.PaymentSecret to listOf(Feature.VariableLengthOnion),
Feature.BasicMultiPartPayment to listOf(Feature.PaymentSecret),
Feature.AnchorOutputs to listOf(Feature.StaticRemoteKey),
Feature.SimpleClose to listOf(Feature.ShutdownAnySegwit),
Feature.TrampolinePayment to listOf(Feature.PaymentSecret),
Feature.ExperimentalTrampolinePayment to listOf(Feature.PaymentSecret),
Feature.OnTheFlyFunding to listOf(Feature.ExperimentalSplice),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ data class NodeParams(
require(features.hasFeature(Feature.ChannelType, FeatureSupport.Mandatory)) { "${Feature.ChannelType.rfcName} should be mandatory" }
require(features.hasFeature(Feature.DualFunding, FeatureSupport.Mandatory)) { "${Feature.DualFunding.rfcName} should be mandatory" }
require(features.hasFeature(Feature.RouteBlinding)) { "${Feature.RouteBlinding.rfcName} should be supported" }
require(features.hasFeature(Feature.ShutdownAnySegwit, FeatureSupport.Mandatory)) { "${Feature.ShutdownAnySegwit.rfcName} should be mandatory" }
require(features.hasFeature(Feature.SimpleClose, FeatureSupport.Mandatory)) { "${Feature.SimpleClose.rfcName} should be mandatory" }
require(!features.hasFeature(Feature.ZeroConfChannels)) { "${Feature.ZeroConfChannels.rfcName} has been deprecated: use the zeroConfPeers whitelist instead" }
require(!features.hasFeature(Feature.TrustedSwapInClient)) { "${Feature.TrustedSwapInClient.rfcName} has been deprecated" }
require(!features.hasFeature(Feature.TrustedSwapInProvider)) { "${Feature.TrustedSwapInProvider.rfcName} has been deprecated" }
Expand Down Expand Up @@ -204,6 +206,7 @@ data class NodeParams(
Feature.Quiescence to FeatureSupport.Mandatory,
Feature.ChannelType to FeatureSupport.Mandatory,
Feature.PaymentMetadata to FeatureSupport.Optional,
Feature.SimpleClose to FeatureSupport.Mandatory,
Feature.ExperimentalTrampolinePayment to FeatureSupport.Optional,
Feature.ZeroReserveChannels to FeatureSupport.Optional,
Feature.WakeUpNotificationClient to FeatureSupport.Optional,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import fr.acinq.lightning.MilliSatoshi
import fr.acinq.lightning.blockchain.WatchEvent
import fr.acinq.lightning.blockchain.electrum.WalletState
import fr.acinq.lightning.blockchain.fee.FeeratePerKw
import fr.acinq.lightning.channel.states.ClosingFeerates
import fr.acinq.lightning.channel.states.PersistedChannelState
import fr.acinq.lightning.crypto.KeyManager
import fr.acinq.lightning.utils.UUID
Expand Down Expand Up @@ -105,7 +104,7 @@ sealed class ChannelCommand {
}

sealed class Close : ChannelCommand() {
data class MutualClose(val scriptPubKey: ByteVector?, val feerates: ClosingFeerates?) : Close(), ForbiddenDuringSplice, ForbiddenDuringQuiescence
data class MutualClose(val scriptPubKey: ByteVector?, val feerate: FeeratePerKw) : Close(), ForbiddenDuringSplice, ForbiddenDuringQuiescence
data object ForceClose : Close()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import fr.acinq.lightning.logging.LoggingContext
import fr.acinq.lightning.transactions.Scripts
import fr.acinq.lightning.transactions.Transactions.TransactionWithInputInfo.*
import fr.acinq.lightning.utils.toMilliSatoshi
import fr.acinq.lightning.wire.ClosingSigned

/**
* Details about a force-close where we published our commitment.
Expand Down Expand Up @@ -370,10 +369,6 @@ data class LocalParams(
features = nodeParams.features.initFeatures()
)

// The node responsible for the commit tx fees is also the node paying the mutual close fees.
// The other node's balance may be empty, which wouldn't allow them to pay the closing fees.
val paysClosingFees: Boolean = paysCommitTxFees

fun channelKeys(keyManager: KeyManager) = keyManager.channelKeys(fundingKeyPath)
}

Expand All @@ -397,8 +392,6 @@ data class RemoteParams(
*/
data class ChannelFlags(val announceChannel: Boolean, val nonInitiatorPaysCommitFees: Boolean)

data class ClosingTxProposed(val unsignedTx: ClosingTx, val localClosingSigned: ClosingSigned)

/**
* @param miningFee fee paid to miners for the underlying on-chain transaction.
* @param serviceFee fee paid to our peer for any service provided with the on-chain transaction.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package fr.acinq.lightning.channel

import fr.acinq.bitcoin.BlockHash
import fr.acinq.bitcoin.ByteVector32
import fr.acinq.bitcoin.Satoshi
import fr.acinq.bitcoin.TxId
import fr.acinq.bitcoin.*
import fr.acinq.lightning.CltvExpiry
import fr.acinq.lightning.CltvExpiryDelta
import fr.acinq.lightning.MilliSatoshi
Expand Down Expand Up @@ -62,8 +59,10 @@ data class FeerateTooSmall (override val channelId: Byte
data class FeerateTooDifferent (override val channelId: ByteVector32, val localFeeratePerKw: FeeratePerKw, val remoteFeeratePerKw: FeeratePerKw) : ChannelException(channelId, "local/remote feerates are too different: remoteFeeratePerKw=${remoteFeeratePerKw.toLong()} localFeeratePerKw=${localFeeratePerKw.toLong()}")
data class InvalidCommitmentSignature (override val channelId: ByteVector32, val txId: TxId) : ChannelException(channelId, "invalid commitment signature: txId=$txId")
data class InvalidHtlcSignature (override val channelId: ByteVector32, val txId: TxId) : ChannelException(channelId, "invalid htlc signature: txId=$txId")
data class CannotGenerateClosingTx (override val channelId: ByteVector32) : ChannelException(channelId, "failed to generate closing transaction: all outputs are trimmed")
data class MissingCloseSignature (override val channelId: ByteVector32) : ChannelException(channelId, "closing_complete is missing a signature for a closing transaction including our output")
data class InvalidCloseSignature (override val channelId: ByteVector32, val txId: TxId) : ChannelException(channelId, "invalid close signature: txId=$txId")
data class InvalidCloseAmountBelowDust (override val channelId: ByteVector32, val txId: TxId) : ChannelException(channelId, "invalid closing tx: some outputs are below dust: txId=$txId")
data class InvalidCloseeScript (override val channelId: ByteVector32, val received: ByteVector, val expected: ByteVector) : ChannelException(channelId, "invalid closee script used in closing_complete: our latest script is $expected, you're using $received")
data class CommitSigCountMismatch (override val channelId: ByteVector32, val expected: Int, val actual: Int) : ChannelException(channelId, "commit sig count mismatch: expected=$expected actual=$actual")
data class HtlcSigCountMismatch (override val channelId: ByteVector32, val expected: Int, val actual: Int) : ChannelException(channelId, "htlc sig count mismatch: expected=$expected actual: $actual")
data class ForcedLocalCommit (override val channelId: ByteVector32) : ChannelException(channelId, "forced local commit")
Expand Down
Loading
Loading