What changed, and why it matters
This commit removes support for older Lightning channel types ('static_remotekey' and 'default' channels) from the Eclair node software. It is a deliberate feature-removal change announced in the previous release. The main risk is operational: node operators who still have legacy channels and upgrade to this version will find Eclair fails to start, potentially leaving them unable to manage funds until those channels are closed with an older version. The patch also simplifies fee-rate handling because anchor-style channels handle fees differently, and it removes wallet-public-key caching code that was only needed for the obsolete channel types.
Node operators should verify they have no remaining 'static_remotekey' or 'default' channels before deploying this version; if any exist, close them using a prior Eclair release first. Reviewers should confirm that the removed code paths are fully unreachable and that no test or integration path still assumes legacy formats. The change is intentional and announced, so no security patch is needed, but release notes should clearly warn about the hard startup failure.
Security signals we found
Removal of legacy commitment format support reduces attack surface for fee-manipulation and transaction-malleability issues present in pre-anchor channels.
Simplified fee tolerance removes the 'too low' feerate check, relying on anchor/taproot CPFP/RBF behavior.
Explicit channel_type requirement prevents silent downgrade to weaker channel types.
Operational risk: nodes with legacy channels fail to start after upgrade, which could cause availability/funds-access issues.
No new cryptographic or memory-safety bug is introduced in the diff.
Evidence from the diff
The commit deletes the Standard and StaticRemoteKey channel types, the DefaultCommitmentFormat code paths, and the walletStaticPaymentBasepoint field. Channel type negotiation now requires an explicit channel_type and rejects legacy types. Fee tolerance checks are simplified: only an upper-bound commit feerate check remains, because anchor/taproot formats use CPFP/RBF and do not need a lower-bound check. The on-chain address refresher is refactored from OnChainPubkeyCache to OnChainAddressCache, removing getP2wpkhPubkey and the RenewPubkey command. Startup compatibility checks now throw IncompatibleDBException with the underlying cause. The change is large (+1129/-3942) and touches channel opening, commitments, closing, revocation handling, and tests.
Changed components
Eclair channel type negotiation and validationCommitment transaction construction and key derivationOn-chain fee configuration and tolerance checksChannel opening (single-funded and dual-funded)Mutual and force-close transaction generationOn-chain wallet address/key caching (OnChainAddressRefresher)Database compatibility check (DBChecker)Configuration reference.confInspect captured patch +1129 / −3942
diff --git a/docs/release-notes/eclair-vnext.md b/docs/release-notes/eclair-vnext.md
index 3566257..9665470 100644
--- a/docs/release-notes/eclair-vnext.md
+++ b/docs/release-notes/eclair-vnext.md
@@ -4,7 +4,10 @@
## Major changes
-<insert changes>
+### Remove support for non-anchor channels
+
+We remove the code used to support legacy channels that don't use anchor outputs or taproot.
+If you still have such channels, eclair won't start: you will need to close those channels, and will only be able to update eclair once they have been successfully closed.
### Configuration changes
diff --git a/eclair-core/src/main/resources/reference.conf b/eclair-core/src/main/resources/reference.conf
index a6c7b83..a6b7125 100644
--- a/eclair-core/src/main/resources/reference.conf
+++ b/eclair-core/src/main/resources/reference.conf
@@ -39,7 +39,7 @@ eclair {
// - unlock: eclair will automatically unlock the corresponding utxos
// - ignore: eclair will leave these utxos locked and start
startup-locked-utxos-behavior = "stop"
- final-pubkey-refresh-delay = 3 seconds
+ final-address-refresh-delay = 3 seconds
// If true, eclair will poll bitcoind for 30 seconds at start-up before giving up.
wait-for-bitcoind-up = true
// The txid of a transaction that exists in your custom signet network or "" to skip this check.
@@ -87,7 +87,7 @@ eclair {
// node that you trust using override-init-features (see below).
option_zeroconf = disabled
keysend = disabled
- option_simple_close=optional
+ option_simple_close = optional
trampoline_payment_prototype = disabled
async_payment_prototype = disabled
on_the_fly_funding = disabled
@@ -177,8 +177,6 @@ eclair {
channel-opener-whitelist = [] // a list of public keys; we will ignore rate limits on pending channels from these peers
}
- accept-incoming-static-remote-key-channels = false // whether we accept new incoming static_remote_key channels (which are obsolete, nodes should use anchor_output now)
-
quiescence-timeout = 1 minutes // maximum time we will stay quiescent (or wait to reach quiescence) before disconnecting
channel-update {
@@ -292,8 +290,8 @@ eclair {
max-closing-feerate = 10
feerate-tolerance {
- ratio-low = 0.5 // will allow remote fee rates as low as half our local feerate (only enforced when not using anchor outputs)
- ratio-high = 10.0 // will allow remote fee rates as high as 10 times our local feerate (for all commitment formats)
+ ratio-low = 0.5 // will allow remote fee rates as low as half our local feerate for funding/splice transactions
+ ratio-high = 10.0 // will allow remote fee rates as high as 10 times our local feerate for commitment transactions and funding/splice transactions
// when using anchor outputs, we only need to use a commitment feerate that allows the tx to propagate: we will use CPFP to speed up confirmation if needed.
// the following value is the maximum feerate we'll use for our commit tx (in sat/byte)
anchor-output-max-commit-feerate = 10
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/DBChecker.scala b/eclair-core/src/main/scala/fr/acinq/eclair/DBChecker.scala
index b6a59cf..2a6c9b8 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/DBChecker.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/DBChecker.scala
@@ -40,7 +40,7 @@ object DBChecker extends Logging {
case _ => ()
}
channels
- case Failure(_) => throw IncompatibleDBException
+ case Failure(t) => throw IncompatibleDBException(t)
}
}
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala b/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala
index e824e68..2bee26c 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala
@@ -21,9 +21,9 @@ import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
import fr.acinq.bitcoin.scalacompat.{Block, BlockHash, Crypto, Satoshi, SatoshiLong}
import fr.acinq.eclair.Setup.Seeds
import fr.acinq.eclair.blockchain.fee._
+import fr.acinq.eclair.channel.ChannelFlags
import fr.acinq.eclair.channel.fsm.Channel
import fr.acinq.eclair.channel.fsm.Channel.{BalanceThreshold, ChannelConf, UnhandledExceptionStrategy}
-import fr.acinq.eclair.channel.{ChannelFlags, ChannelTypes}
import fr.acinq.eclair.crypto.Noise.KeyPair
import fr.acinq.eclair.crypto.keymanager.{ChannelKeyManager, NodeKeyManager, OnChainKeyManager}
import fr.acinq.eclair.db._
@@ -39,7 +39,7 @@ import fr.acinq.eclair.router.Graph.HeuristicsConstants
import fr.acinq.eclair.router.Router._
import fr.acinq.eclair.router.{Graph, PathFindingExperimentConf, Router}
import fr.acinq.eclair.tor.Socks5ProxyParams
-import fr.acinq.eclair.transactions.Transactions
+import fr.acinq.eclair.transactions.Transactions.{PhoenixSimpleTaprootChannelCommitmentFormat, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat, ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat}
import fr.acinq.eclair.wire.protocol._
import grizzled.slf4j.Logging
import scodec.bits.ByteVector
@@ -129,14 +129,17 @@ case class NodeParams(nodeKeyManager: NodeKeyManager,
max = (fundingFeerate * feerateTolerance.ratioHigh).max(minimumFeerate),
)
// We use the most likely commitment format, even though there is no guarantee that this is the one that will be used.
- val commitmentFormat = ChannelTypes.defaultFromFeatures(localFeatures, remoteFeatures, announceChannel = false).commitmentFormat
+ val commitmentFormat = if (Features.canUseFeature(localFeatures, remoteFeatures, Features.SimpleTaprootChannelsPhoenix)) {
+ PhoenixSimpleTaprootChannelCommitmentFormat
+ } else if (Features.canUseFeature(localFeatures, remoteFeatures, Features.SimpleTaprootChannelsStaging)) {
+ ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat
+ } else {
+ ZeroFeeHtlcTxAnchorOutputsCommitmentFormat
+ }
val commitmentFeerate = onChainFeeConf.getCommitmentFeerate(currentBitcoinCoreFeerates, remoteNodeId, commitmentFormat)
val commitmentRange = RecommendedFeeratesTlv.CommitmentFeerateRange(
- min = (commitmentFeerate * feerateTolerance.ratioLow).max(minimumFeerate),
- max = (commitmentFormat match {
- case Transactions.DefaultCommitmentFormat => commitmentFeerate * feerateTolerance.ratioHigh
- case _: Transactions.AnchorOutputsCommitmentFormat | _: Transactions.SimpleTaprootChannelCommitmentFormat => (commitmentFeerate * feerateTolerance.ratioHigh).max(feerateTolerance.anchorOutputMaxCommitFeerate)
- }).max(minimumFeerate),
+ min = Seq(commitmentFeerate * feerateTolerance.ratioLow, minimumFeerate).max,
+ max = Seq(commitmentFeerate * feerateTolerance.ratioHigh, feerateTolerance.anchorOutputMaxCommitFeerate, minimumFeerate).max,
)
RecommendedFeerates(chainHash, fundingFeerate, commitmentFeerate, TlvStream(fundingRange, commitmentRange))
}
@@ -599,7 +602,6 @@ object NodeParams extends Logging {
quiescenceTimeout = FiniteDuration(config.getDuration("channel.quiescence-timeout").getSeconds, TimeUnit.SECONDS),
balanceThresholds = config.getConfigList("channel.channel-update.balance-thresholds").asScala.map(conf => BalanceThreshold(Satoshi(conf.getLong("available-sat")), Satoshi(conf.getLong("max-htlc-sat")))).toSeq,
minTimeBetweenUpdates = FiniteDuration(config.getDuration("channel.channel-update.min-time-between-updates").getSeconds, TimeUnit.SECONDS),
- acceptIncomingStaticRemoteKeyChannels = config.getBoolean("channel.accept-incoming-static-remote-key-channels")
),
onChainFeeConf = OnChainFeeConf(
feeTargets = feeTargets,
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/Setup.scala b/eclair-core/src/main/scala/fr/acinq/eclair/Setup.scala
index 4dd9fc4..0038338 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/Setup.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/Setup.scala
@@ -268,9 +268,8 @@ class Setup(val datadir: File,
})
_ <- feeratesRetrieved.future
- finalPubkey = new AtomicReference[PublicKey](null)
finalPubkeyScript = new AtomicReference[Seq[ScriptElt]](null)
- pubkeyRefreshDelay = FiniteDuration(config.getDuration("bitcoind.final-pubkey-refresh-delay").getSeconds, TimeUnit.SECONDS)
+ finalAddressRefreshDelay = FiniteDuration(config.getDuration("bitcoind.final-address-refresh-delay").getSeconds, TimeUnit.SECONDS)
// there are 3 possibilities regarding onchain key management:
// 1) there is no `eclair-signer.conf` file in Eclair's data directory, Eclair will not manage Bitcoin core keys, and Eclair's API will not return bitcoin core descriptors. This is the default mode.
// 2) there is an `eclair-signer.conf` file in Eclair's data directory, but the name of the wallet set in `eclair-signer.conf` does not match the `eclair.bitcoind.wallet` setting in `eclair.conf`.
@@ -278,14 +277,8 @@ class Setup(val datadir: File,
// This is how you would create a new bitcoin wallet whose private keys are managed by Eclair.
// 3) there is an `eclair-signer.conf` file in Eclair's data directory, and the name of the wallet set in `eclair-signer.conf` matches the `eclair.bitcoind.wallet` setting in `eclair.conf`.
// Eclair will assume that this is a watch-only bitcoin wallet that has been created from descriptors generated by Eclair, and will manage its private keys, and here we pass the onchain key manager to our bitcoin client.
- bitcoinClient = new BitcoinCoreClient(bitcoin, nodeParams.liquidityAdsConfig.lockUtxos, if (bitcoin.wallet == onChainKeyManager_opt.map(_.walletName)) onChainKeyManager_opt else None) with OnChainPubkeyCache {
- val refresher: typed.ActorRef[OnChainAddressRefresher.Command] = system.spawn(Behaviors.supervise(OnChainAddressRefresher(this, finalPubkey, finalPubkeyScript, pubkeyRefreshDelay)).onFailure(typed.SupervisorStrategy.restart), name = "onchain-address-manager")
-
- override def getP2wpkhPubkey(renew: Boolean): PublicKey = {
- val key = finalPubkey.get()
- if (renew) refresher ! OnChainAddressRefresher.RenewPubkey
- key
- }
+ bitcoinClient = new BitcoinCoreClient(bitcoin, nodeParams.liquidityAdsConfig.lockUtxos, if (bitcoin.wallet == onChainKeyManager_opt.map(_.walletName)) onChainKeyManager_opt else None) with OnChainAddressCache {
+ val refresher: typed.ActorRef[OnChainAddressRefresher.Command] = system.spawn(Behaviors.supervise(OnChainAddressRefresher(this, finalPubkeyScript, finalAddressRefreshDelay)).onFailure(typed.SupervisorStrategy.restart), name = "on-chain-address-manager")
override def getReceivePublicKeyScript(renew: Boolean): Seq[ScriptElt] = {
val script = finalPubkeyScript.get()
@@ -294,8 +287,6 @@ class Setup(val datadir: File,
}
}
_ = if (bitcoinClient.useEclairSigner) logger.info("using eclair to sign bitcoin core transactions")
- initialPubkey <- bitcoinClient.getP2wpkhPubkey()
- _ = finalPubkey.set(initialPubkey)
// We use the default address type configured on the Bitcoin Core node.
initialPubkeyScript <- bitcoinClient.getReceivePublicKeyScript(addressType_opt = None)
_ = finalPubkeyScript.set(initialPubkeyScript)
@@ -494,7 +485,7 @@ case class Kit(nodeParams: NodeParams,
postman: typed.ActorRef[Postman.Command],
offerManager: typed.ActorRef[OfferManager.Command],
defaultOfferHandler: typed.ActorRef[OfferManager.HandlerCommand],
- wallet: OnChainWallet with OnChainPubkeyCache)
+ wallet: OnChainWallet with OnChainAddressCache)
object Kit {
@@ -518,7 +509,7 @@ case class BitcoinWalletNotLoadedException(wallet: String, loaded: List[String])
case object EmptyAPIPasswordException extends RuntimeException("must set a password for the json-rpc api")
-case object IncompatibleDBException extends RuntimeException("database is not compatible with this version of eclair")
+case class IncompatibleDBException(t: Throwable) extends RuntimeException(s"database is not compatible with this version of eclair: ${t.getMessage}")
case object IncompatibleNetworkDBException extends RuntimeException("network database is not compatible with this version of eclair")
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/OnChainWallet.scala b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/OnChainWallet.scala
index caefb87..0d2a217 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/OnChainWallet.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/OnChainWallet.scala
@@ -17,7 +17,6 @@
package fr.acinq.eclair.blockchain
import fr.acinq.bitcoin.psbt.Psbt
-import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
import fr.acinq.bitcoin.scalacompat.{OutPoint, Satoshi, ScriptElt, Transaction, TxId}
import fr.acinq.eclair.blockchain.bitcoind.rpc.BitcoinCoreClient.AddressType
import fr.acinq.eclair.blockchain.fee.FeeratePerKw
@@ -120,18 +119,10 @@ trait OnChainAddressGenerator {
/** Generate the public key script for a new wallet address. */
def getReceivePublicKeyScript(addressType_opt: Option[AddressType] = None)(implicit ec: ExecutionContext): Future[Seq[ScriptElt]]
- /** Generate a p2wpkh wallet address and return the corresponding public key. */
- def getP2wpkhPubkey()(implicit ec: ExecutionContext): Future[PublicKey]
-
}
/** A caching layer for [[OnChainAddressGenerator]] that provides synchronous access to wallet addresses and keys. */
-trait OnChainPubkeyCache {
-
- /**
- * @param renew applies after requesting the current pubkey, and is asynchronous.
- */
- def getP2wpkhPubkey(renew: Boolean): PublicKey
+trait OnChainAddressCache {
/**
* @param renew applies after requesting the current script, and is asynchronous.
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/OnChainAddressRefresher.scala b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/OnChainAddressRefresher.scala
index 885cfee..b880846 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/OnChainAddressRefresher.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/OnChainAddressRefresher.scala
@@ -3,7 +3,6 @@ package fr.acinq.eclair.blockchain.bitcoind
import akka.actor.typed.Behavior
import akka.actor.typed.scaladsl.{ActorContext, Behaviors, TimerScheduler}
-import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
import fr.acinq.bitcoin.scalacompat.{Script, ScriptElt}
import fr.acinq.eclair.blockchain.OnChainAddressGenerator
@@ -19,18 +18,16 @@ object OnChainAddressRefresher {
// @formatter:off
sealed trait Command
- case object RenewPubkey extends Command
case object RenewPubkeyScript extends Command
- private case class SetPubkey(pubkey: PublicKey) extends Command
private case class SetPubkeyScript(script: Seq[ScriptElt]) extends Command
private case class Error(reason: Throwable) extends Command
private case object Done extends Command
// @formatter:on
- def apply(generator: OnChainAddressGenerator, finalPubkey: AtomicReference[PublicKey], finalPubkeyScript: AtomicReference[Seq[ScriptElt]], delay: FiniteDuration): Behavior[Command] = {
+ def apply(generator: OnChainAddressGenerator, finalPubkeyScript: AtomicReference[Seq[ScriptElt]], delay: FiniteDuration): Behavior[Command] = {
Behaviors.setup { context =>
Behaviors.withTimers { timers =>
- val refresher = new OnChainAddressRefresher(generator, finalPubkey, finalPubkeyScript, context, timers, delay)
+ val refresher = new OnChainAddressRefresher(generator, finalPubkeyScript, context, timers, delay)
refresher.idle()
}
}
@@ -38,7 +35,6 @@ object OnChainAddressRefresher {
}
private class OnChainAddressRefresher(generator: OnChainAddressGenerator,
- finalPubkey: AtomicReference[PublicKey],
finalPubkeyScript: AtomicReference[Seq[ScriptElt]],
context: ActorContext[OnChainAddressRefresher.Command],
timers: TimerScheduler[OnChainAddressRefresher.Command], delay: FiniteDuration) {
@@ -47,13 +43,6 @@ private class OnChainAddressRefresher(generator: OnChainAddressGenerator,
/** In that state, we're ready to renew our on-chain address whenever requested. */
def idle(): Behavior[Command] = Behaviors.receiveMessage {
- case RenewPubkey =>
- context.log.debug("renewing pubkey (current={})", finalPubkey.get())
- context.pipeToSelf(generator.getP2wpkhPubkey()) {
- case Success(pubkey) => SetPubkey(pubkey)
- case Failure(reason) => Error(reason)
- }
- renewing()
case RenewPubkeyScript =>
context.log.debug("renewing script (current={})", Script.write(finalPubkeyScript.get()).toHex)
context.pipeToSelf(generator.getReceivePublicKeyScript()) {
@@ -68,14 +57,11 @@ private class OnChainAddressRefresher(generator: OnChainAddressGenerator,
/** We ignore concurrent requests while waiting for bitcoind to respond. */
private def renewing(): Behavior[Command] = Behaviors.receiveMessage {
- case SetPubkey(pubkey) =>
- timers.startSingleTimer(Done, delay)
- delaying(Some(pubkey), None)
case SetPubkeyScript(script) =>
timers.startSingleTimer(Done, delay)
- delaying(None, Some(script))
+ delaying(script)
case Error(reason) =>
- context.log.error("cannot renew public key or script", reason)
+ context.log.error("cannot renew script", reason)
idle()
case cmd =>
context.log.debug("ignoring command={} while waiting for bitcoin core's response", cmd)
@@ -83,29 +69,16 @@ private class OnChainAddressRefresher(generator: OnChainAddressGenerator,
}
/**
- * After receiving our new script or pubkey from bitcoind, we wait before updating our current values.
+ * After receiving our new address from bitcoind, we wait before updating our current value.
* While waiting, we ignore additional requests to renew.
*
* This ensures that a burst of requests during a mass force-close use the same final on-chain address instead of
* creating a lot of address churn on our bitcoin wallet.
- *
- * Note that while we're updating our final script, we will ignore requests to update our final public key (and the
- * other way around). This is fine, since the public key is only used:
- * - when opening static_remotekey channels, which is disabled by default
- * - when closing channels with peers that don't support shutdown_anysegwit (which should be widely supported)
- *
- * In practice, we most likely always use [[RenewPubkeyScript]].
*/
- private def delaying(nextPubkey_opt: Option[PublicKey], nextScript_opt: Option[Seq[ScriptElt]]): Behavior[Command] = Behaviors.receiveMessage {
+ private def delaying(nextScript: Seq[ScriptElt]): Behavior[Command] = Behaviors.receiveMessage {
case Done =>
- nextPubkey_opt.foreach { nextPubkey =>
- context.log.info("setting pubkey to {}", nextPubkey)
- finalPubkey.set(nextPubkey)
- }
- nextScript_opt.foreach { nextScript =>
- context.log.info("setting script to {}", Script.write(nextScript).toHex)
- finalPubkeyScript.set(nextScript)
- }
+ context.log.info("setting script to {}", Script.write(nextScript).toHex)
+ finalPubkeyScript.set(nextScript)
idle()
case cmd =>
context.log.debug("rate-limiting command={}", cmd)
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/fee/OnChainFeeConf.scala b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/fee/OnChainFeeConf.scala
index 30ea02c..7deea85 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/fee/OnChainFeeConf.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/fee/OnChainFeeConf.scala
@@ -65,29 +65,11 @@ case class DustTolerance(maxExposure: Satoshi, closeOnUpdateFeeOverflow: Boolean
case class FeerateTolerance(ratioLow: Double, ratioHigh: Double, anchorOutputMaxCommitFeerate: FeeratePerKw, dustTolerance: DustTolerance) {
/**
- * @param commitmentFormat commitment format (anchor outputs allows a much higher tolerance since fees can be adjusted after tx is published)
* @param networkFeerate reference fee rate (value we estimate from our view of the network)
* @param proposedFeerate fee rate proposed (new proposal through update_fee or previous proposal used in our current commit tx)
* @return true if the difference between proposed and reference fee rates is too high.
*/
- def isFeeDiffTooHigh(commitmentFormat: CommitmentFormat, networkFeerate: FeeratePerKw, proposedFeerate: FeeratePerKw): Boolean = {
- isProposedFeerateTooLow(commitmentFormat, networkFeerate, proposedFeerate) || isProposedFeerateTooHigh(commitmentFormat, networkFeerate, proposedFeerate)
- }
-
- def isProposedFeerateTooHigh(commitmentFormat: CommitmentFormat, networkFeerate: FeeratePerKw, proposedFeerate: FeeratePerKw): Boolean = {
- commitmentFormat match {
- case Transactions.DefaultCommitmentFormat => networkFeerate * ratioHigh < proposedFeerate
- case ZeroFeeHtlcTxAnchorOutputsCommitmentFormat | UnsafeLegacyAnchorOutputsCommitmentFormat | PhoenixSimpleTaprootChannelCommitmentFormat | ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat => networkFeerate * ratioHigh < proposedFeerate
- }
- }
-
- def isProposedFeerateTooLow(commitmentFormat: CommitmentFormat, networkFeerate: FeeratePerKw, proposedFeerate: FeeratePerKw): Boolean = {
- commitmentFormat match {
- case Transactions.DefaultCommitmentFormat => proposedFeerate < networkFeerate * ratioLow
- // When using anchor outputs, we allow low feerates: fees will be set with CPFP and RBF at broadcast time.
- case ZeroFeeHtlcTxAnchorOutputsCommitmentFormat | UnsafeLegacyAnchorOutputsCommitmentFormat | PhoenixSimpleTaprootChannelCommitmentFormat | ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat => false
- }
- }
+ def isProposedCommitFeerateTooHigh(networkFeerate: FeeratePerKw, proposedFeerate: FeeratePerKw): Boolean = networkFeerate * ratioHigh < proposedFeerate
}
case class OnChainFeeConf(feeTargets: FeeTargets,
@@ -120,7 +102,6 @@ case class OnChainFeeConf(feeTargets: FeeTargets,
val networkFeerate = feerates.fast
val networkMinFee = feerates.minimum
commitmentFormat match {
- case Transactions.DefaultCommitmentFormat => networkFeerate
case _: Transactions.AnchorOutputsCommitmentFormat | _: Transactions.SimpleTaprootChannelCommitmentFormat =>
val targetFeerate = networkFeerate.min(feerateToleranceFor(remoteNodeId).anchorOutputMaxCommitFeerate)
// We make sure the feerate is always greater than the propagation threshold.
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelData.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelData.scala
index 1b0b286..81772a8 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelData.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelData.scala
@@ -786,11 +786,11 @@ object DATA_CLOSED {
},
closingAmount = closingType match {
case Closing.MutualClose(closingTx) => closingTx.toLocalOutput_opt.map(_.amount).getOrElse(0 sat)
- case Closing.LocalClose(_, localCommitPublished) => Closing.closingBalance(d.channelParams, d.commitments.latest.commitmentFormat, d.finalScriptPubKey, localCommitPublished)
- case Closing.CurrentRemoteClose(_, remoteCommitPublished) => Closing.closingBalance(d.channelParams, d.commitments.latest.commitmentFormat, d.finalScriptPubKey, remoteCommitPublished)
- case Closing.NextRemoteClose(_, remoteCommitPublished) => Closing.closingBalance(d.channelParams, d.commitments.latest.commitmentFormat, d.finalScriptPubKey, remoteCommitPublished)
- case Closing.RecoveryClose(remoteCommitPublished) => Closing.closingBalance(d.channelParams, d.commitments.latest.commitmentFormat, d.finalScriptPubKey, remoteCommitPublished)
- case Closing.RevokedClose(revokedCommitPublished) => Closing.closingBalance(d.channelParams, d.commitments.latest.commitmentFormat, d.finalScriptPubKey, revokedCommitPublished)
+ case Closing.LocalClose(_, localCommitPublished) => Closing.closingBalance(d.finalScriptPubKey, localCommitPublished)
+ case Closing.CurrentRemoteClose(_, remoteCommitPublished) => Closing.closingBalance(d.finalScriptPubKey, remoteCommitPublished)
+ case Closing.NextRemoteClose(_, remoteCommitPublished) => Closing.closingBalance(d.finalScriptPubKey, remoteCommitPublished)
+ case Closing.RecoveryClose(remoteCommitPublished) => Closing.closingBalance(d.finalScriptPubKey, remoteCommitPublished)
+ case Closing.RevokedClose(revokedCommitPublished) => Closing.closingBalance(d.finalScriptPubKey, revokedCommitPublished)
}
)
}
@@ -805,7 +805,6 @@ case class LocalChannelParams(nodeId: PublicKey,
isChannelOpener: Boolean,
paysCommitTxFees: Boolean,
upfrontShutdownScript_opt: Option[ByteVector],
- walletStaticPaymentBasepoint: Option[PublicKey],
// Current connection features, or last features used if the channel is disconnected. Note that
// these features are updated at each reconnection and may be different from the channel permanent
// features (see [[ChannelFeatures]]).
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelExceptions.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelExceptions.scala
index ed61f8f..884ed42 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelExceptions.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelExceptions.scala
@@ -44,7 +44,7 @@ case class FundingAmountTooHigh (override val channelId: Byte
case class InvalidFundingBalances (override val channelId: ByteVector32, fundingAmount: Satoshi, localBalance: MilliSatoshi, remoteBalance: MilliSatoshi) extends ChannelException(channelId, s"invalid balances funding_amount=$fundingAmount local=$localBalance remote=$remoteBalance")
case class InvalidPushAmount (override val channelId: ByteVector32, pushAmount: MilliSatoshi, max: MilliSatoshi) extends ChannelException(channelId, s"invalid pushAmount=$pushAmount (max=$max)")
case class InvalidMaxAcceptedHtlcs (override val channelId: ByteVector32, maxAcceptedHtlcs: Int, max: Int) extends ChannelException(channelId, s"invalid max_accepted_htlcs=$maxAcceptedHtlcs (max=$max)")
-case class InvalidChannelType (override val channelId: ByteVector32, ourChannelType: ChannelType, theirChannelType: ChannelType) extends ChannelException(channelId, s"invalid channel_type=$theirChannelType, expected channel_type=$ourChannelType")
+case class InvalidChannelType (override val channelId: ByteVector32, remoteChannelType: ChannelType) extends ChannelException(channelId, s"invalid channel_type=$remoteChannelType")
case class MissingChannelType (override val channelId: ByteVector32) extends ChannelException(channelId, "option_channel_type was negotiated but channel_type is missing")
case class DustLimitTooSmall (override val channelId: ByteVector32, dustLimit: Satoshi, min: Satoshi) extends ChannelException(channelId, s"dustLimit=$dustLimit is too small (min=$min)")
case class DustLimitTooLarge (override val channelId: ByteVector32, dustLimit: Satoshi, max: Satoshi) extends ChannelException(channelId, s"dustLimit=$dustLimit is too large (max=$max)")
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelFeatures.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelFeatures.scala
index 7ca5b53..e557cee 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelFeatures.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelFeatures.scala
@@ -16,6 +16,7 @@
package fr.acinq.eclair.channel
+import fr.acinq.bitcoin.scalacompat.ByteVector32
import fr.acinq.eclair.transactions.Transactions._
import fr.acinq.eclair.{ChannelTypeFeature, FeatureSupport, Features, InitFeature, PermanentChannelFeature}
@@ -67,9 +68,6 @@ sealed trait SupportedChannelType extends ChannelType {
/** Known channel-type features */
override def features: Set[ChannelTypeFeature]
- /** True if our main output in the remote commitment is directly sent (without any delay) to one of our wallet addresses. */
- def paysDirectlyToWallet: Boolean
-
/** Format of the channel transactions. */
def commitmentFormat: CommitmentFormat
}
@@ -77,25 +75,6 @@ sealed trait SupportedChannelType extends ChannelType {
object ChannelTypes {
// @formatter:off
- case class Standard(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,
- ).flatten
- override def paysDirectlyToWallet: Boolean = false
- override def commitmentFormat: CommitmentFormat = DefaultCommitmentFormat
- override def toString: String = s"standard${if (scidAlias) "+scid_alias" else ""}${if (zeroConf) "+zeroconf" else ""}"
- }
- case class StaticRemoteKey(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.StaticRemoteKey)
- ).flatten
- override def paysDirectlyToWallet: Boolean = true
- override def commitmentFormat: CommitmentFormat = DefaultCommitmentFormat
- override def toString: String = s"static_remotekey${if (scidAlias) "+scid_alias" else ""}${if (zeroConf) "+zeroconf" else ""}"
- }
case class AnchorOutputs(scidAlias: Boolean = false, zeroConf: Boolean = false) extends SupportedChannelType {
override def features: Set[ChannelTypeFeature] = Set(
if (scidAlias) Some(Features.ScidAlias) else None,
@@ -103,7 +82,6 @@ object ChannelTypes {
Some(Features.StaticRemoteKey),
Some(Features.AnchorOutputs)
).flatten
- override def paysDirectlyToWallet: Boolean = false
override def commitmentFormat: CommitmentFormat = UnsafeLegacyAnchorOutputsCommitmentFormat
override def toString: String = s"anchor_outputs${if (scidAlias) "+scid_alias" else ""}${if (zeroConf) "+zeroconf" else ""}"
}
@@ -114,18 +92,15 @@ object ChannelTypes {
Some(Features.StaticRemoteKey),
Some(Features.AnchorOutputsZeroFeeHtlcTx)
).flatten
- override def paysDirectlyToWallet: Boolean = false
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 {
- /** Known channel-type features */
override def features: Set[ChannelTypeFeature] = Set(
if (scidAlias) Some(Features.ScidAlias) else None,
if (zeroConf) Some(Features.ZeroConf) else None,
Some(Features.SimpleTaprootChannelsStaging),
).flatten
- override def paysDirectlyToWallet: Boolean = false
override def commitmentFormat: CommitmentFormat = ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat
override def toString: String = s"simple_taproot_channel_staging${if (scidAlias) "+scid_alias" else ""}${if (zeroConf) "+zeroconf" else ""}"
}
@@ -137,9 +112,7 @@ object ChannelTypes {
// Phoenix uses custom channel types, that we may remove in the future.
case object SimpleTaprootChannelsPhoenix extends SupportedChannelType {
- /** Known channel-type features */
override def features: Set[ChannelTypeFeature] = Set(Features.PhoenixZeroReserve, Features.SimpleTaprootChannelsPhoenix)
- override def paysDirectlyToWallet: Boolean = false
override def commitmentFormat: CommitmentFormat = PhoenixSimpleTaprootChannelCommitmentFormat
override def toString: String = "phoenix_simple_taproot_channel"
}
@@ -147,14 +120,6 @@ object ChannelTypes {
// @formatter:on
private val features2ChannelType: Map[Features[_ <: InitFeature], SupportedChannelType] = Set(
- Standard(),
- Standard(zeroConf = true),
- Standard(scidAlias = true),
- Standard(scidAlias = true, zeroConf = true),
- StaticRemoteKey(),
- StaticRemoteKey(zeroConf = true),
- StaticRemoteKey(scidAlias = true),
- StaticRemoteKey(scidAlias = true, zeroConf = true),
AnchorOutputs(),
AnchorOutputs(zeroConf = true),
AnchorOutputs(scidAlias = true),
@@ -163,49 +128,25 @@ object ChannelTypes {
AnchorOutputsZeroFeeHtlcTx(zeroConf = true),
AnchorOutputsZeroFeeHtlcTx(scidAlias = true),
AnchorOutputsZeroFeeHtlcTx(scidAlias = true, zeroConf = true),
- SimpleTaprootChannelsPhoenix,
SimpleTaprootChannelsStaging(),
SimpleTaprootChannelsStaging(zeroConf = true),
SimpleTaprootChannelsStaging(scidAlias = true),
SimpleTaprootChannelsStaging(scidAlias = true, zeroConf = true),
- )
- .map(channelType => Features(channelType.features.map(_ -> FeatureSupport.Mandatory).toMap) -> channelType)
- .toMap
+ SimpleTaprootChannelsPhoenix,
+ ).map {
+ channelType => Features(channelType.features.map(_ -> FeatureSupport.Mandatory).toMap) -> channelType
+ }.toMap
// NB: Bolt 2: features must exactly match in order to identify a channel type.
def fromFeatures(features: Features[InitFeature]): ChannelType = features2ChannelType.getOrElse(features, UnsupportedChannelType(features))
- /** Pick the channel type based on local and remote feature bits, as defined by the spec. */
- def defaultFromFeatures(localFeatures: Features[InitFeature], remoteFeatures: Features[InitFeature], announceChannel: Boolean): SupportedChannelType = {
- def canUse(feature: InitFeature): Boolean = Features.canUseFeature(localFeatures, remoteFeatures, feature)
-
- val scidAlias = canUse(Features.ScidAlias) && !announceChannel // alias feature is incompatible with public channel
- val zeroConf = canUse(Features.ZeroConf)
- if (canUse(Features.SimpleTaprootChannelsStaging)) {
- SimpleTaprootChannelsStaging(scidAlias, zeroConf)
- } else if (canUse(Features.SimpleTaprootChannelsPhoenix)) {
- SimpleTaprootChannelsPhoenix
- } else if (canUse(Features.AnchorOutputsZeroFeeHtlcTx)) {
- AnchorOutputsZeroFeeHtlcTx(scidAlias, zeroConf)
- } else if (canUse(Features.AnchorOutputs)) {
- AnchorOutputs(scidAlias, zeroConf)
- } else if (canUse(Features.StaticRemoteKey)) {
- StaticRemoteKey(scidAlias, zeroConf)
- } else {
- Standard(scidAlias, zeroConf)
- }
- }
-
/** Check if a given channel type is compatible with our features. */
- def areCompatible(localFeatures: Features[InitFeature], remoteChannelType: ChannelType): Option[SupportedChannelType] = remoteChannelType match {
- case _: UnsupportedChannelType => None
+ def areCompatible(channelId: ByteVector32, localFeatures: Features[InitFeature], remoteChannelType_opt: Option[ChannelType]): Either[ChannelException, SupportedChannelType] = remoteChannelType_opt match {
+ case None => Left(MissingChannelType(channelId))
+ case Some(channelType: UnsupportedChannelType) => Left(InvalidChannelType(channelId, channelType))
// We ensure that we support the features necessary for this channel type.
- case proposedChannelType: SupportedChannelType =>
- if (proposedChannelType.features.forall(f => localFeatures.hasFeature(f))) {
- Some(proposedChannelType)
- } else {
- None
- }
+ case Some(proposedChannelType: SupportedChannelType) if proposedChannelType.features.forall(f => localFeatures.hasFeature(f)) => Right(proposedChannelType)
+ case Some(proposedChannelType: SupportedChannelType) => Left(InvalidChannelType(channelId, proposedChannelType))
}
}
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/Commitments.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/Commitments.scala
index 9e87a3a..d2b4065 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/Commitments.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/Commitments.scala
@@ -202,7 +202,7 @@ object LocalCommit {
case class RemoteCommit(index: Long, spec: CommitmentSpec, txId: TxId, remotePerCommitmentPoint: PublicKey) {
def sign(channelParams: ChannelParams, commitParams: CommitParams, channelKeys: ChannelKeys, fundingTxIndex: Long, remoteFundingPubKey: PublicKey, commitInput: InputInfo, commitmentFormat: CommitmentFormat, remoteNonce_opt: Option[IndividualNonce], batchSize: Int = 1): Either[ChannelException, CommitSig] = {
val fundingKey = channelKeys.fundingKey(fundingTxIndex)
- val commitKeys = RemoteCommitmentKeys(channelParams, channelKeys, remotePerCommitmentPoint, commitmentFormat)
+ val commitKeys = RemoteCommitmentKeys(channelParams, channelKeys, remotePerCommitmentPoint)
val (remoteCommitTx, htlcTxs) = Commitment.makeRemoteTxs(channelParams, commitParams, commitKeys, index, fundingKey, remoteFundingPubKey, commitInput, commitmentFormat, spec)
val sortedHtlcTxs = htlcTxs.sortBy(_.input.outPoint.index)
val htlcSigs = sortedHtlcTxs.map(_.localSig(commitKeys))
@@ -278,9 +278,9 @@ case class Commitment(fundingTxIndex: Long,
def commitInput(channelKeys: ChannelKeys): InputInfo = commitInput(localFundingKey(channelKeys))
- def localKeys(params: ChannelParams, channelKeys: ChannelKeys): LocalCommitmentKeys = LocalCommitmentKeys(params, channelKeys, localCommit.index, commitmentFormat)
+ def localKeys(params: ChannelParams, channelKeys: ChannelKeys): LocalCommitmentKeys = LocalCommitmentKeys(params, channelKeys, localCommit.index)
- def remoteKeys(params: ChannelParams, channelKeys: ChannelKeys, remotePerCommitmentPoint: PublicKey): RemoteCommitmentKeys = RemoteCommitmentKeys(params, channelKeys, remotePerCommitmentPoint, commitmentFormat)
+ def remoteKeys(params: ChannelParams, channelKeys: ChannelKeys, remotePerCommitmentPoint: PublicKey): RemoteCommitmentKeys = RemoteCommitmentKeys(params, channelKeys, remotePerCommitmentPoint)
/** Channel reserve that applies to our funds. */
def localChannelReserve(params: ChannelParams): Satoshi = if (params.channelFeatures.hasFeature(Features.DualFunding) || fundingTxIndex > 0) {
@@ -458,19 +458,7 @@ case class Commitment(fundingTxIndex: Long,
localCommit.spec.htlcs.collect(DirectedHtlc.incoming).filter(nearlyExpired)
}
- def canSendAdd(amount: MilliSatoshi, params: ChannelParams, changes: CommitmentChanges, feerates: FeeratesPerKw, feeConf: OnChainFeeConf, reputationScore: Reputation.Score): Either[ChannelException, Unit] = {
- // we allowed mismatches between our feerates and our remote's as long as commitments didn't contain any HTLC at risk
- // we need to verify that we're not disagreeing on feerates anymore before offering new HTLCs
- // NB: there may be a pending update_fee that hasn't been applied yet that needs to be taken into account
- val localFeerate = feeConf.getCommitmentFeerate(feerates, params.remoteNodeId, commitmentFormat)
- val remoteFeerate = localCommit.spec.commitTxFeerate +: changes.remoteChanges.all.collect { case f: UpdateFee => f.feeratePerKw }
- // What we want to avoid is having an HTLC in a commitment transaction that has a very low feerate, which we won't
- // be able to confirm in time to claim the HTLC, so we only need to check that the feerate isn't too low.
- remoteFeerate.find(feerate => feeConf.feerateToleranceFor(params.remoteNodeId).isProposedFeerateTooLow(commitmentFormat, localFeerate, feerate)) match {
- case Some(feerate) => return Left(FeerateTooDifferent(params.channelId, localFeeratePerKw = localFeerate, remoteFeeratePerKw = feerate))
- case None =>
- }
-
+ def canSendAdd(amount: MilliSatoshi, params: ChannelParams, changes: CommitmentChanges, feeConf: OnChainFeeConf, reputationScore: Reputation.Score): Either[ChannelException, Unit] = {
// let's compute the current commitments *as seen by them* with the additional htlc
// we need to base the next current commitment on the last sig we sent, even if we didn't yet receive their revocation
val remoteCommit1 = nextRemoteCommit_opt.getOrElse(remoteCommit)
@@ -538,17 +526,7 @@ case class Commitment(fundingTxIndex: Long,
reputationScore.checkOutgoingChannelOccupancy(params.channelId, this, outgoingHtlcs.toSeq)
}
- def canReceiveAdd(amount: MilliSatoshi, params: ChannelParams, changes: CommitmentChanges, feerates: FeeratesPerKw, feeConf: OnChainFeeConf): Either[ChannelException, Unit] = {
- // we allowed mismatches between our feerates and our remote's as long as commitments didn't contain any HTLC at risk
- // we need to verify that we're not disagreeing on feerates anymore before accepting new HTLCs
- // NB: there may be a pending update_fee that hasn't been applied yet that needs to be taken into account
- val localFeerate = feeConf.getCommitmentFeerate(feerates, params.remoteNodeId, commitmentFormat)
- val remoteFeerate = localCommit.spec.commitTxFeerate +: changes.remoteChanges.all.collect { case f: UpdateFee => f.feeratePerKw }
- remoteFeerate.find(feerate => feeConf.feerateToleranceFor(params.remoteNodeId).isProposedFeerateTooLow(commitmentFormat, localFeerate, feerate)) match {
- case Some(feerate) => return Left(FeerateTooDifferent(params.channelId, localFeeratePerKw = localFeerate, remoteFeeratePerKw = feerate))
- case None =>
- }
-
+ def canReceiveAdd(amount: MilliSatoshi, params: ChannelParams, changes: CommitmentChanges): Either[ChannelException, Unit] = {
// let's compute the current commitment *as seen by us* including this additional htlc
val reduced = CommitmentSpec.reduce(localCommit.spec, changes.localChanges.acked, changes.remoteChanges.proposed)
val incomingHtlcs = reduced.htlcs.collect(DirectedHtlc.incoming)
@@ -616,10 +594,7 @@ case class Commitment(fundingTxIndex: Long,
def canReceiveFee(targetFeerate: FeeratePerKw, params: ChannelParams, changes: CommitmentChanges, feerates: FeeratesPerKw, feeConf: OnChainFeeConf): Either[ChannelException, Unit] = {
val localFeerate = feeConf.getCommitmentFeerate(feerates, params.remoteNodeId, commitmentFormat)
- if (feeConf.feerateToleranceFor(params.remoteNodeId).isProposedFeerateTooHigh(commitmentFormat, localFeerate, targetFeerate)) {
- return Left(FeerateTooDifferent(params.channelId, localFeeratePerKw = localFeerate, remoteFeeratePerKw = targetFeerate))
- } else if (feeConf.feerateToleranceFor(params.remoteNodeId).isProposedFeerateTooLow(commitmentFormat, localFeerate, targetFeerate) && hasPendingOrProposedHtlcs(changes)) {
- // If the proposed feerate is too low, but we don't have any pending HTLC, we temporarily accept it.
+ if (feeConf.feerateToleranceFor(params.remoteNodeId).isProposedCommitFeerateTooHigh(localFeerate, targetFeerate)) {
return Left(FeerateTooDifferent(params.channelId, localFeeratePerKw = localFeerate, remoteFeeratePerKw = targetFeerate))
} else {
// let's compute the current commitment *as seen by us* including this change
@@ -903,7 +878,7 @@ case class Commitments(channelParams: ChannelParams,
* @param cmd add HTLC command
* @return either Left(failure, error message) where failure is a failure message (see BOLT #4 and the Failure Message class) or Right(new commitments, updateAddHtlc)
*/
- def sendAdd(cmd: CMD_ADD_HTLC, currentHeight: BlockHeight, channelConf: ChannelConf, feerates: FeeratesPerKw, feeConf: OnChainFeeConf)(implicit log: LoggingAdapter): Either[ChannelException, (Commitments, UpdateAddHtlc)] = {
+ def sendAdd(cmd: CMD_ADD_HTLC, currentHeight: BlockHeight, channelConf: ChannelConf, feeConf: OnChainFeeConf)(implicit log: LoggingAdapter): Either[ChannelException, (Commitments, UpdateAddHtlc)] = {
// we must ensure we're not relaying htlcs that are already expired, otherwise the downstream channel will instantly close
// NB: we add a 3 blocks safety to reduce the probability of running into this when our bitcoin node is slightly outdated
val minExpiry = CltvExpiry(currentHeight + 3)
@@ -927,9 +902,9 @@ case class Commitments(channelParams: ChannelParams,
val changes1 = changes.addLocalProposal(add).copy(localNextHtlcId = changes.localNextHtlcId + 1)
val originChannels1 = originChannels + (add.id -> cmd.origin)
// we verify that this htlc is allowed in every active commitment
- val failures =
- (active.map(_.canSendAdd(add.amountMsat, channelParams, changes1, feerates, feeConf, cmd.reputationScore))
- :+ cmd.reputationScore.checkIncomingChannelOccupancy(cmd.origin.upstream.incomingChannelOccupancy, channelId))
+ val failures = active.map(_.canSendAdd(add.amountMsat, channelParams, changes1, feeConf, cmd.reputationScore))
+ // and that we don't exceed the authorized channel occupancy (jamming)
+ .appended(cmd.reputationScore.checkIncomingChannelOccupancy(cmd.origin.upstream.incomingChannelOccupancy, channelId))
.collect { case Left(f) => f }
if (failures.isEmpty) {
Right(copy(changes = changes1, originChannels = originChannels1), add)
@@ -953,7 +928,7 @@ case class Commitments(channelParams: ChannelParams,
}
}
- def receiveAdd(add: UpdateAddHtlc, feerates: FeeratesPerKw, feeConf: OnChainFeeConf): Either[ChannelException, Commitments] = {
+ def receiveAdd(add: UpdateAddHtlc): Either[ChannelException, Commitments] = {
if (add.id != changes.remoteNextHtlcId) {
return Left(UnexpectedHtlcId(channelId, expected = changes.remoteNextHtlcId, actual = add.id))
}
@@ -966,7 +941,7 @@ case class Commitments(channelParams: ChannelParams,
val changes1 = changes.addRemoteProposal(add).copy(remoteNextHtlcId = changes.remoteNextHtlcId + 1)
// we verify that this htlc is allowed in every active commitment
- active.map(_.canReceiveAdd(add.amountMsat, channelParams, changes1, feerates, feeConf))
+ active.map(_.canReceiveAdd(add.amountMsat, channelParams, changes1))
.collectFirst { case Left(f) => Left(f) }
.getOrElse(Right(copy(changes = changes1)))
}
@@ -1087,8 +1062,8 @@ case class Commitments(channelParams: ChannelParams,
remoteNextCommitInfo match {
case Right(_) if !changes.localHasChanges => Left(CannotSignWithoutChanges(channelId))
case Right(remoteNextPerCommitmentPoint) =>
+ val commitKeys = RemoteCommitmentKeys(channelParams, channelKeys, remoteNextPerCommitmentPoint)
val (active1, sigs) = active.map(c => {
- val commitKeys = RemoteCommitmentKeys(channelParams, channelKeys, remoteNextPerCommitmentPoint, c.commitmentFormat)
c.sendCommit(channelParams, channelKeys, commitKeys, changes, remoteNextPerCommitmentPoint, active.size, nextRemoteCommitNonces.get(c.fundingTxId)) match {
case Left(e) => return Left(e)
case Right((c, cs)) => (c, cs)
@@ -1118,8 +1093,8 @@ case class Commitments(channelParams: ChannelParams,
case commitSig: CommitSig => Seq(commitSig)
}
// Signatures are sent in order (most recent first), calling `zip` will drop trailing sigs that are for deactivated/pruned commitments.
+ val commitKeys = LocalCommitmentKeys(channelParams, channelKeys, localCommitIndex + 1)
val active1 = active.zip(sigs).map { case (commitment, commit) =>
- val commitKeys = LocalCommitmentKeys(channelParams, channelKeys, localCommitIndex + 1, commitment.commitmentFormat)
commitment.receiveCommit(channelParams, channelKeys, commitKeys, changes, commit) match {
case Left(f) => return Left(f)
case Right(commitment1) => commitment1
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/Helpers.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/Helpers.scala
index 230b9be..bec02e0 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/Helpers.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/Helpers.scala
@@ -21,7 +21,7 @@ import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey, sha256}
import fr.acinq.bitcoin.scalacompat.Musig2.{IndividualNonce, LocalNonce}
import fr.acinq.bitcoin.scalacompat._
import fr.acinq.eclair._
-import fr.acinq.eclair.blockchain.OnChainPubkeyCache
+import fr.acinq.eclair.blockchain.OnChainAddressCache
import fr.acinq.eclair.blockchain.fee._
import fr.acinq.eclair.channel.ChannelSpendSignature.{IndividualSignature, PartialSignatureWithNonce}
import fr.acinq.eclair.channel.fsm.Channel
@@ -99,7 +99,7 @@ object Helpers {
}
/** Called by the fundee of a single-funded channel. */
- def validateParamsSingleFundedFundee(nodeParams: NodeParams, channelType: SupportedChannelType, localFeatures: Features[InitFeature], open: OpenChannel, remoteNodeId: PublicKey, remoteFeatures: Features[InitFeature]): Either[ChannelException, (ChannelFeatures, Option[ByteVector])] = {
+ def validateParamsSingleFundedFundee(nodeParams: NodeParams, localFeatures: Features[InitFeature], open: OpenChannel, remoteNodeId: PublicKey, remoteFeatures: Features[InitFeature]): Either[ChannelException, (ChannelFeatures, Option[ByteVector])] = {
// BOLT #2: if the chain_hash value, within the open_channel, message is set to a hash of a chain that is unknown to the receiver:
// MUST reject the channel.
if (nodeParams.chainHash != open.chainHash) return Left(InvalidChainHash(open.temporaryChannelId, local = nodeParams.chainHash, remote = open.chainHash))
@@ -133,15 +133,19 @@ object Helpers {
return Left(ChannelReserveNotMet(open.temporaryChannelId, toLocalMsat, toRemoteMsat, open.channelReserveSatoshis))
}
+ val channelType = ChannelTypes.areCompatible(open.temporaryChannelId, localFeatures, open.channelType_opt) match {
+ case Left(f) => return Left(f)
+ case Right(proposedChannelType) => proposedChannelType
+ }
val channelFeatures = ChannelFeatures(channelType, localFeatures, remoteFeatures, open.channelFlags.announceChannel)
channelType.commitmentFormat match {
case _: SimpleTaprootChannelCommitmentFormat => if (open.commitNonce_opt.isEmpty) return Left(MissingCommitNonce(open.temporaryChannelId, TxId(ByteVector32.Zeroes), commitmentNumber = 0))
- case _: AnchorOutputsCommitmentFormat | DefaultCommitmentFormat => ()
+ case _: AnchorOutputsCommitmentFormat => ()
}
// BOLT #2: The receiving node MUST fail the channel if: it considers feerate_per_kw too small for timely processing or unreasonably large.
val localFeeratePerKw = nodeParams.onChainFeeConf.getCommitmentFeerate(nodeParams.currentBitcoinCoreFeerates, remoteNodeId, channelType.commitmentFormat)
- if (nodeParams.onChainFeeConf.feerateToleranceFor(remoteNodeId).isFeeDiffTooHigh(channelType.commitmentFormat, localFeeratePerKw, open.feeratePerKw)) return Left(FeerateTooDifferent(open.temporaryChannelId, localFeeratePerKw, open.feeratePerKw))
+ if (nodeParams.onChainFeeConf.feerateToleranceFor(remoteNodeId).isProposedCommitFeerateTooHigh(localFeeratePerKw, open.feeratePerKw)) return Left(FeerateTooDifferent(open.temporaryChannelId, localFeeratePerKw, open.feeratePerKw))
// we don't check that the funder's amount for the initial commitment transaction is sufficient for full fee payment
// now, but it will be done later when we receive `funding_created`
@@ -154,7 +158,6 @@ object Helpers {
/** Called by the non-initiator of a dual-funded channel. */
def validateParamsDualFundedNonInitiator(nodeParams: NodeParams,
- channelType: SupportedChannelType,
open: OpenDualFundedChannel,
fundingScript: ByteVector,
remoteNodeId: PublicKey,
@@ -184,11 +187,15 @@ object Helpers {
if (open.dustLimit < Channel.MIN_DUST_LIMIT) return Left(DustLimitTooSmall(open.temporaryChannelId, open.dustLimit, Channel.MIN_DUST_LIMIT))
if (open.dustLimit > nodeParams.channelConf.maxRemoteDustLimit) return Left(DustLimitTooLarge(open.temporaryChannelId, open.dustLimit, nodeParams.channelConf.maxRemoteDustLimit))
+ val channelType = ChannelTypes.areCompatible(open.temporaryChannelId, localFeatures, open.channelType_opt) match {
+ case Left(f) => return Left(f)
+ case Right(proposedChannelType) => proposedChannelType
+ }
val channelFeatures = ChannelFeatures(channelType, localFeatures, remoteFeatures, open.channelFlags.announceChannel)
// BOLT #2: The receiving node MUST fail the channel if: it considers feerate_per_kw too small for timely processing or unreasonably large.
val localFeeratePerKw = nodeParams.onChainFeeConf.getCommitmentFeerate(nodeParams.currentBitcoinCoreFeerates, remoteNodeId, channelType.commitmentFormat)
- if (nodeParams.onChainFeeConf.feerateToleranceFor(remoteNodeId).isFeeDiffTooHigh(channelType.commitmentFormat, localFeeratePerKw, open.commitmentFeerate)) return Left(FeerateTooDifferent(open.temporaryChannelId, localFeeratePerKw, open.commitmentFeerate))
+ if (nodeParams.onChainFeeConf.feerateToleranceFor(remoteNodeId).isProposedCommitFeerateTooHigh(localFeeratePerKw, open.commitmentFeerate)) return Left(FeerateTooDifferent(open.temporaryChannelId, localFeeratePerKw, open.commitmentFeerate))
for {
script_opt <- extractShutdownScript(open.temporaryChannelId, localFeatures, remoteFeatures, open.upfrontShutdownScript_opt)
@@ -196,29 +203,19 @@ object Helpers {
} yield (channelFeatures, script_opt, willFund_opt)
}
- private def validateChannelType(channelId: ByteVector32, channelType: SupportedChannelType, channelFlags: ChannelFlags, openChannelType_opt: Option[ChannelType], acceptChannelType_opt: Option[ChannelType], localFeatures: Features[InitFeature], remoteFeatures: Features[InitFeature]): Option[ChannelException] = {
- acceptChannelType_opt match {
- case Some(theirChannelType) if acceptChannelType_opt != openChannelType_opt =>
- // if channel_type is set, and channel_type was set in open_channel, and they are not equal types: MUST reject the channel.
- Some(InvalidChannelType(channelId, channelType, theirChannelType))
- case None if Features.canUseFeature(localFeatures, remoteFeatures, Features.ChannelType) =>
- // Bolt 2: if `option_channel_type` is negotiated: MUST set `channel_type`
- Some(MissingChannelType(channelId))
- case None if channelType != ChannelTypes.defaultFromFeatures(localFeatures, remoteFeatures, channelFlags.announceChannel) =>
- // If we have overridden the default channel type, but they didn't support explicit channel type negotiation,
- // we need to abort because they expect a different channel type than what we offered.
- Some(InvalidChannelType(channelId, channelType, ChannelTypes.defaultFromFeatures(localFeatures, remoteFeatures, channelFlags.announceChannel)))
- case _ =>
- // we agree on channel type
- None
+ private def validateChannelTypeInitiator(channelId: ByteVector32, openChannelType_opt: Option[ChannelType], acceptChannelType_opt: Option[ChannelType]): Either[ChannelException, SupportedChannelType] = {
+ (openChannelType_opt, acceptChannelType_opt) match {
+ case (Some(proposed: SupportedChannelType), Some(received)) if proposed == received => Right(proposed)
+ case (Some(_), Some(received)) => Left(InvalidChannelType(channelId, received))
+ case _ => Left(MissingChannelType(channelId))
}
}
/** Called by the funder of a single-funded channel. */
- def validateParamsSingleFundedFunder(nodeParams: NodeParams, channelType: SupportedChannelType, localFeatures: Features[InitFeature], remoteFeatures: Features[InitFeature], open: OpenChannel, accept: AcceptChannel): Either[ChannelException, (ChannelFeatures, Option[ByteVector])] = {
- validateChannelType(open.temporaryChannelId, channelType, open.channelFlags, open.channelType_opt, accept.channelType_opt, localFeatures, remoteFeatures) match {
- case Some(t) => return Left(t)
- case None => // we agree on channel type
+ def validateParamsSingleFundedFunder(nodeParams: NodeParams, localFeatures: Features[InitFeature], remoteFeatures: Features[InitFeature], open: OpenChannel, accept: AcceptChannel): Either[ChannelException, (ChannelFeatures, Option[ByteVector])] = {
+ val channelType = validateChannelTypeInitiator(open.temporaryChannelId, open.channelType_opt, accept.channelType_opt) match {
+ case Left(t) => return Left(t)
+ case Right(channelType) => channelType
}
if (accept.maxAcceptedHtlcs > Channel.MAX_ACCEPTED_HTLCS) return Left(InvalidMaxAcceptedHtlcs(accept.temporaryChannelId, accept.maxAcceptedHtlcs, Channel.MAX_ACCEPTED_HTLCS))
@@ -247,7 +244,7 @@ object Helpers {
val channelFeatures = ChannelFeatures(channelType, localFeatures, remoteFeatures, open.channelFlags.announceChannel)
channelType.commitmentFormat match {
case _: SimpleTaprootChannelCommitmentFormat => if (accept.commitNonce_opt.isEmpty) return Left(MissingCommitNonce(open.temporaryChannelId, TxId(ByteVector32.Zeroes), commitmentNumber = 0))
- case _: AnchorOutputsCommitmentFormat | DefaultCommitmentFormat => ()
+ case _: AnchorOutputsCommitmentFormat => ()
}
extractShutdownScript(accept.temporaryChannelId, localFeatures, remoteFeatures, accept.upfrontShutdownScript_opt).map(script_opt => (channelFeatures, script_opt))
}
@@ -255,14 +252,13 @@ object Helpers {
/** Called by the initiator of a dual-funded channel. */
def validateParamsDualFundedInitiator(nodeParams: NodeParams,
remoteNodeId: PublicKey,
- channelType: SupportedChannelType,
localFeatures: Features[InitFeature],
remoteFeatures: Features[InitFeature],
open: OpenDualFundedChannel,
accept: AcceptDualFundedChannel): Either[ChannelException, (ChannelFeatures, Option[ByteVector], Option[LiquidityAds.Purchase])] = {
- validateChannelType(open.temporaryChannelId, channelType, open.channelFlags, open.channelType_opt, accept.channelType_opt, localFeatures, remoteFeatures) match {
- case Some(t) => return Left(t)
- case None => // we agree on channel type
+ val channelType = validateChannelTypeInitiator(open.temporaryChannelId, open.channelType_opt, accept.channelType_opt) match {
+ case Left(t) => return Left(t)
+ case Right(channelType) => channelType
}
// BOLT #2: Channel funding limits
@@ -687,14 +683,8 @@ object Helpers {
object MutualClose {
- def generateFinalScriptPubKey(wallet: OnChainPubkeyCache, allowAnySegwit: Boolean, renew: Boolean = true): ByteVector = {
- if (!allowAnySegwit) {
- // If our peer only supports segwit v0, we cannot let bitcoind choose the address type: we always use p2wpkh.
- val finalPubKey = wallet.getP2wpkhPubkey(renew)
- Script.write(Script.pay2wpkh(finalPubKey))
- } else {
- Script.write(wallet.getReceivePublicKeyScript(renew))
- }
+ def generateFinalScriptPubKey(wallet: OnChainAddressCache, renew: Boolean = true): ByteVector = {
+ Script.write(wallet.getReceivePublicKeyScript(renew))
}
def isValidFinalScriptPubkey(scriptPubKey: ByteVector, allowAnySegwit: Boolean, allowOpReturn: Boolean): Boolean = {
@@ -721,15 +711,9 @@ object Helpers {
def firstClosingFee(channelKeys: ChannelKeys, commitment: FullCommitment, localScriptPubkey: ByteVector, remoteScriptPubkey: ByteVector, feerates: FeeratesPerKw, onChainFeeConf: OnChainFeeConf)(implicit log: LoggingAdapter): ClosingFees = {
val requestedFeerate = onChainFeeConf.getClosingFeerate(feerates, maxClosingFeerateOverride_opt = None)
- val preferredFeerate = commitment.commitmentFormat match {
- case DefaultCommitmentFormat =>
- // we "MUST set fee_satoshis less than or equal to the base fee of the final commitment transaction"
- requestedFeerate.min(commitment.localCommit.spec.commitTxFeerate)
- case _: AnchorOutputsCommitmentFormat | _: SimpleTaprootChannelCommitmentFormat => requestedFeerate
- }
// NB: we choose a minimum fee that ensures the tx will easily propagate while allowing low fees since we can
// always use CPFP to speed up confirmation if necessary.
- val closingFeerates = ClosingFeerates(preferredFeerate, preferredFeerate.min(ConfirmationPriority.Slow.getFeerate(feerates)), preferredFeerate * 2)
+ val closingFeerates = ClosingFeerates(requestedFeerate, requestedFeerate.min(ConfirmationPriority.Slow.getFeerate(feerates)), requestedFeerate * 2)
firstClosingFee(channelKeys, commitment, localScriptPubkey, remoteScriptPubkey, closingFeerates)
}
@@ -778,7 +762,7 @@ object Helpers {
dummyClosingTxs.preferred_opt match {
case Some(dummyTx) =>
commitment.commitmentFormat match {
- case DefaultCommitmentFormat | _: AnchorOutputsCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
val dummyPubkey = commitment.remoteFundingPubKey
val dummySig = IndividualSignature(Transactions.PlaceHolderSig)
val dummySignedTx = dummyTx.aggregateSigs(dummyPubkey, dummyPubkey, dummySig, dummySig)
@@ -816,7 +800,7 @@ object Helpers {
closingTxs.remoteOnly_opt.flatMap(tx => localSig(tx, localNonces.remoteOnly)).map(ClosingCompleteTlv.CloseeOutputOnlyPartialSignature(_)),
).flatten[ClosingCompleteTlv])
}
- case _: AnchorOutputsCommitmentFormat | DefaultCommitmentFormat => TlvStream(Set(
+ case _: AnchorOutputsCommitmentFormat => TlvStream(Set(
closingTxs.localAndRemote_opt.map(tx => ClosingTlv.CloserAndCloseeOutputs(tx.sign(localFundingKey, commitment.remoteFundingPubKey).sig)),
closingTxs.localOnly_opt.map(tx => ClosingTlv.CloserOutputOnly(tx.sign(localFundingKey, commitment.remoteFundingPubKey).sig)),
closingTxs.remoteOnly_opt.map(tx => ClosingTlv.CloseeOutputOnly(tx.sign(localFundingKey, commitment.remoteFundingPubKey).sig)),
@@ -870,7 +854,7 @@ object Helpers {
case None => Left(MissingCloseSignature(commitment.channelId))
}
}
- case _: AnchorOutputsCommitmentFormat | DefaultCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
(closingTxs.localAndRemote_opt, closingTxs.localOnly_opt) match {
case (Some(_), Some(_)) if closingComplete.closerAndCloseeOutputsSig_opt.isEmpty && closingComplete.closeeOutputOnlySig_opt.isEmpty => return Left(MissingCloseSignature(commitment.channelId))
case (Some(_), None) if closingComplete.closerAndCloseeOutputsSig_opt.isEmpty => return Left(MissingCloseSignature(commitment.channelId))
@@ -1186,7 +1170,7 @@ object Helpers {
object RemoteClose {
/** Transactions spending outputs of a remote commitment transaction. */
- case class SecondStageTransactions(mainTx_opt: Option[ClaimRemoteCommitMainOutputTx], anchorTx_opt: Option[ClaimRemoteAnchorTx], htlcTxs: Seq[ClaimHtlcTx])
+ case class SecondStageTransactions(mainTx_opt: Option[ClaimRemoteDelayedOutputTx], anchorTx_opt: Option[ClaimRemoteAnchorTx], htlcTxs: Seq[ClaimHtlcTx])
/** Claim all the outputs that belong to us in the remote commitment transaction (which can be either their current or next commitment). */
def claimCommitTxOutputs(channelKeys: ChannelKeys, commitment: FullCommitment, remoteCommit: RemoteCommit, commitTx: Transaction, closingFeerate: FeeratePerKw, finalScriptPubKey: ByteVector, spendAnchorWithoutHtlcs: Boolean)(implicit log: LoggingAdapter): (RemoteCommitPublished, SecondStageTransactions) = {
@@ -1223,11 +1207,8 @@ object Helpers {
}
/** Claim our main output from the remote commitment transaction, if available. */
- def claimMainOutput(commitKeys: RemoteCommitmentKeys, commitTx: Transaction, dustLimit: Satoshi, commitmentFormat: CommitmentFormat, feerate: FeeratePerKw, finalScriptPubKey: ByteVector)(implicit log: LoggingAdapter): Option[ClaimRemoteCommitMainOutputTx] = {
+ def claimMainOutput(commitKeys: RemoteCommitmentKeys, commitTx: Transaction, dustLimit: Satoshi, commitmentFormat: CommitmentFormat, feerate: FeeratePerKw, finalScriptPubKey: ByteVector)(implicit log: LoggingAdapter): Option[ClaimRemoteDelayedOutputTx] = {
commitmentFormat match {
- case DefaultCommitmentFormat => withTxGenerationLog("remote-main") {
- ClaimP2WPKHOutputTx.createUnsignedTx(commitKeys, commitTx, dustLimit, finalScriptPubKey, feerate, commitmentFormat)
- }
case _: AnchorOutputsCommitmentFormat | _: SimpleTaprootChannelCommitmentFormat => withTxGenerationLog("remote-main-delayed") {
ClaimRemoteDelayedOutputTx.createUnsignedTx(commitKeys, commitTx, dustLimit, finalScriptPubKey, feerate, commitmentFormat)
}
@@ -1348,7 +1329,7 @@ object Helpers {
object RevokedClose {
/** Transactions spending outputs of a revoked remote commitment transactions. */
- case class SecondStageTransactions(mainTx_opt: Option[ClaimRemoteCommitMainOutputTx], mainPenaltyTx_opt: Option[MainPenaltyTx], htlcPenaltyTxs: Seq[HtlcPenaltyTx])
+ case class SecondStageTransactions(mainTx_opt: Option[ClaimRemoteDelayedOutputTx], mainPenaltyTx_opt: Option[MainPenaltyTx], htlcPenaltyTxs: Seq[HtlcPenaltyTx])
/** Transactions spending outputs of confirmed remote HTLC transactions. */
case class ThirdStageTransactions(htlcDelayedPenaltyTxs: Seq[ClaimHtlcDelayedOutputPenaltyTx])
@@ -1368,7 +1349,7 @@ object Helpers {
// a valid tx will always have at least one input, but this ensures we don't throw in tests
val sequence = commitTx.txIn.headOption.map(_.sequence).getOrElse(0L)
val obscuredTxNumber = Transactions.decodeTxNumber(sequence, commitTx.lockTime)
- val localPaymentPoint = params.localParams.walletStaticPaymentBasepoint.getOrElse(channelKeys.paymentBasePoint)
+ val localPaymentPoint = channelKeys.paymentBasePoint
// this tx has been published by remote, so we need to invert local/remote params
val txNumber = Transactions.obscuredCommitTxNumber(obscuredTxNumber, !params.localParams.isChannelOpener, params.remoteParams.paymentBasepoint, localPaymentPoint)
if (txNumber > 0xffffffffffffL) {
@@ -1387,7 +1368,7 @@ object Helpers {
def claimCommitTxOutputs(channelParams: ChannelParams, channelKeys: ChannelKeys, commitTx: Transaction, commitmentNumber: Long, remotePerCommitmentSecret: PrivateKey, toSelfDelay: CltvExpiryDelta, commitmentFormat: CommitmentFormat, db: ChannelsDb, dustLimit: Satoshi, feerates: FeeratesPerKw, onChainFeeConf: OnChainFeeConf, finalScriptPubKey: ByteVector)(implicit log: LoggingAdapter): (RevokedCommitPublished, SecondStageTransactions) = {
log.warning("a revoked commit has been published with commitmentNumber={}", commitmentNumber)
- val commitKeys = RemoteCommitmentKeys(channelParams, channelKeys, remotePerCommitmentSecret.publicKey, commitmentFormat)
+ val commitKeys = RemoteCommitmentKeys(channelParams, channelKeys, remotePerCommitmentSecret.publicKey)
val revocationKey = channelKeys.revocationKey(remotePerCommitmentSecret)
val feerateMain = onChainFeeConf.getClosingFeerate(feerates, maxClosingFeerateOverride_opt = None)
@@ -1396,9 +1377,6 @@ object Helpers {
// First we will claim our main output right away.
val mainTx_opt = commitmentFormat match {
- case DefaultCommitmentFormat => withTxGenerationLog("remote-main") {
- ClaimP2WPKHOutputTx.createUnsignedTx(commitKeys, commitTx, dustLimit, finalScriptPubKey, feerateMain, commitmentFormat)
- }
case _: AnchorOutputsCommitmentFormat | _: SimpleTaprootChannelCommitmentFormat => withTxGenerationLog("remote-main-delayed") {
ClaimRemoteDelayedOutputTx.createUnsignedTx(commitKeys, commitTx, dustLimit, finalScriptPubKey, feerateMain, commitmentFormat)
}
@@ -1450,7 +1428,7 @@ object Helpers {
if (spendsHtlcOutput) {
getRemotePerCommitmentSecret(channelParams, channelKeys, remotePerCommitmentSecrets, revokedCommitPublished.commitTx).map {
case (_, remotePerCommitmentSecret) =>
- val commitmentKeys = RemoteCommitmentKeys(channelParams, channelKeys, remotePerCommitmentSecret.publicKey, commitmentFormat)
+ val commitmentKeys = RemoteCommitmentKeys(channelParams, channelKeys, remotePerCommitmentSecret.publicKey)
val revocationKey = channelKeys.revocationKey(remotePerCommitmentSecret)
val penaltyTxs = claimHtlcTxOutputs(commitmentKeys, revocationKey, toSelfDelay, commitmentFormat, htlcTx, dustLimit, feerates, finalScriptPubKey)
val revokedCommitPublished1 = revokedCommitPublished.copy(htlcDelayedOutputs = revokedCommitPublished.htlcDelayedOutputs ++ penaltyTxs.map(_.input.outPoint))
@@ -1474,7 +1452,7 @@ object Helpers {
* Claim the outputs of all 2nd-stage HTLC transactions that have been confirmed.
*/
def claimHtlcTxsOutputs(channelParams: ChannelParams, channelKeys: ChannelKeys, remotePerCommitmentSecret: PrivateKey, toSelfDelay: CltvExpiryDelta, commitmentFormat: CommitmentFormat, revokedCommitPublished: RevokedCommitPublished, dustLimit: Satoshi, feerates: FeeratesPerKw, finalScriptPubKey: ByteVector)(implicit log: LoggingAdapter): ThirdStageTransactions = {
- val commitmentKeys = RemoteCommitmentKeys(channelParams, channelKeys, remotePerCommitmentSecret.publicKey, commitmentFormat)
+ val commitmentKeys = RemoteCommitmentKeys(channelParams, channelKeys, remotePerCommitmentSecret.publicKey)
val revocationKey = channelKeys.revocationKey(remotePerCommitmentSecret)
val confirmedHtlcTxs = revokedCommitPublished.htlcOutputs.flatMap(htlcOutput => revokedCommitPublished.irrevocablySpent.get(htlcOutput))
val penaltyTxs = confirmedHtlcTxs.flatMap(htlcTx => claimHtlcTxOutputs(commitmentKeys, revocationKey, toSelfDelay, commitmentFormat, htlcTx, dustLimit, feerates, finalScriptPubKey))
@@ -1702,20 +1680,11 @@ object Helpers {
}
/** Returns the amount we've successfully claimed from a force-closed channel. */
- def closingBalance(channelParams: ChannelParams, commitmentFormat: CommitmentFormat, closingScript: ByteVector, commit: CommitPublished): Satoshi = {
- val toLocal = commit.localOutput_opt match {
- case Some(o) if o.index < commit.commitTx.txOut.size => commit.commitTx.txOut(o.index.toInt).amount
- case _ => 0 sat
- }
- val toClosingScript = commit.irrevocablySpent.values.flatMap(_.txOut)
+ def closingBalance(closingScript: ByteVector, commit: CommitPublished): Satoshi = {
+ commit.irrevocablySpent.values.flatMap(_.txOut)
.filter(_.publicKeyScript == closingScript)
.map(_.amount)
.sum
- commitmentFormat match {
- case DefaultCommitmentFormat if channelParams.localParams.walletStaticPaymentBasepoint.nonEmpty => toLocal + toClosingScript
- case DefaultCommitmentFormat => toClosingScript
- case _: AnchorOutputsCommitmentFormat | _: SimpleTaprootChannelCommitmentFormat => toClosingScript
- }
}
}
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/Channel.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/Channel.scala
index bef8a0c..6d92187 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/Channel.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/Channel.scala
@@ -109,8 +109,7 @@ object Channel {
remoteRbfLimits: RemoteRbfLimits,
quiescenceTimeout: FiniteDuration,
balanceThresholds: Seq[BalanceThreshold],
- minTimeBetweenUpdates: FiniteDuration,
- acceptIncomingStaticRemoteKeyChannels: Boolean) {
+ minTimeBetweenUpdates: FiniteDuration) {
require(0 <= maxHtlcValueInFlightPercent && maxHtlcValueInFlightPercent <= 100, "max-htlc-value-in-flight-percent must be between 0 and 100")
require(balanceThresholds.sortBy(_.available) == balanceThresholds, "channel-update.balance-thresholds must be sorted by available-sat")
@@ -147,7 +146,7 @@ object Channel {
}
}
- def props(nodeParams: NodeParams, channelKeys: ChannelKeys, wallet: OnChainChannelFunder with OnChainPubkeyCache, remoteNodeId: PublicKey, blockchain: typed.ActorRef[ZmqWatcher.Command], relayer: ActorRef, txPublisherFactory: TxPublisherFactory): Props =
+ def props(nodeParams: NodeParams, channelKeys: ChannelKeys, wallet: OnChainChannelFunder with OnChainAddressCache, remoteNodeId: PublicKey, blockchain: typed.ActorRef[ZmqWatcher.Command], relayer: ActorRef, txPublisherFactory: TxPublisherFactory): Props =
Props(new Channel(nodeParams, channelKeys, wallet, remoteNodeId, blockchain, relayer, txPublisherFactory))
// https://github.com/lightningnetwork/lightning-rfc/blob/master/02-peer-protocol.md#requirements
@@ -212,7 +211,7 @@ object Channel {
}
-class Channel(val nodeParams: NodeParams, val channelKeys: ChannelKeys, val wallet: OnChainChannelFunder with OnChainPubkeyCache, val remoteNodeId: PublicKey, val blockchain: typed.ActorRef[ZmqWatcher.Command], val relayer: ActorRef, val txPublisherFactory: Channel.TxPublisherFactory)(implicit val ec: ExecutionContext = ExecutionContext.Implicits.global)
+class Channel(val nodeParams: NodeParams, val channelKeys: ChannelKeys, val wallet: OnChainChannelFunder with OnChainAddressCache, val remoteNodeId: PublicKey, val blockchain: typed.ActorRef[ZmqWatcher.Command], val relayer: ActorRef, val txPublisherFactory: Channel.TxPublisherFactory)(implicit val ec: ExecutionContext = ExecutionContext.Implicits.global)
extends FSM[ChannelState, ChannelData]
with FSMDiagnosticActorLogging[ChannelState, ChannelData]
with ChannelOpenSingleFunded
@@ -317,11 +316,6 @@ class Channel(val nodeParams: NodeParams, val channelKeys: ChannelKeys, val wall
case Event(INPUT_RESTORED(data), _) =>
log.debug("restoring channel")
- data match {
- case data: ChannelDataWithCommitments if data.commitments.active.exists(_.commitmentFormat == DefaultCommitmentFormat) =>
- log.warning("channel is not using anchor outputs: please close it and re-open an anchor output channel before updating to the next version of eclair")
- case _ => ()
- }
context.system.eventStream.publish(ChannelRestored(self, data.channelId, peer, remoteNodeId, data))
txPublisher ! SetChannelId(remoteNodeId, data.channelId)
// We watch all unconfirmed funding txs, whatever our state is.
@@ -536,7 +530,7 @@ class Channel(val nodeParams: NodeParams, val channelKeys: ChannelKeys, val wall
handleAddHtlcCommandError(c, error, Some(d.channelUpdate))
case Event(c: CMD_ADD_HTLC, d: DATA_NORMAL) =>
- d.commitments.sendAdd(c, nodeParams.currentBlockHeight, nodeParams.channelConf, nodeParams.currentBitcoinCoreFeerates, nodeParams.onChainFeeConf) match {
+ d.commitments.sendAdd(c, nodeParams.currentBlockHeight, nodeParams.channelConf, nodeParams.onChainFeeConf) match {
case Right((commitments1, add)) =>
if (c.commit) self ! CMD_SIGN()
context.system.eventStream.publish(AvailableBalanceChanged(self, d.channelId, d.aliases, commitments1, d.lastAnnouncement_opt))
@@ -548,7 +542,7 @@ class Channel(val nodeParams: NodeParams, val channelKeys: ChannelKeys, val wall
}
case Event(add: UpdateAddHtlc, d: DATA_NORMAL) =>
- d.commitments.receiveAdd(add, nodeParams.currentBitcoinCoreFeerates, nodeParams.onChainFeeConf) match {
+ d.commitments.receiveAdd(add) match {
case Right(commitments1) => stay() using d.copy(commitments = commitments1)
case Left(cause) => handleLocalError(cause, d, Some(add))
}
@@ -670,7 +664,7 @@ class Channel(val nodeParams: NodeParams, val channelKeys: ChannelKeys, val wall
case (s: SpliceStatus.SpliceInProgress, sig: CommitSig) =>
log.debug("received their commit_sig, deferring message")
stay() using d.copy(spliceStatus = s.copy(remoteCommitSig = Some(sig)))
- case (SpliceStatus.SpliceAborted, sig: CommitSig) =>
+ case (SpliceStatus.SpliceAborted, _: CommitSig) =>
log.warning("received commit_sig after sending tx_abort, they probably sent it before receiving our tx_abort, ignoring...")
stay()
case (SpliceStatus.SpliceWaitingForSigs(signingSession), sig: CommitSig) =>
@@ -866,7 +860,7 @@ class Channel(val nodeParams: NodeParams, val channelKeys: ChannelKeys, val wall
case Event(ProcessCurrentBlockHeight(c), d: DATA_NORMAL) => handleNewBlock(c, d)
- case Event(c: CurrentFeerates.BitcoinCore, d: DATA_NORMAL) => handleCurrentFeerate(c, d)
+ case Event(c: CurrentFeerates.BitcoinCore, d: DATA_NORMAL) => handleCurrentFeerate(d)
case Event(_: ChannelReady, d: DATA_NORMAL) =>
// After a reconnection, if the channel hasn't been used yet, our peer cannot be sure we received their channel_ready
@@ -1114,10 +1108,10 @@ class Channel(val nodeParams: NodeParams, val channelKeys: ChannelKeys, val wall
// commitment format and will simply apply the previous commitment format.
val nextCommitmentFormat = msg.channelType_opt match {
case Some(ChannelTypes.SimpleTaprootChannelsPhoenix) if parentCommitment.commitmentFormat == UnsafeLegacyAnchorOutputsCommitmentFormat =>
- log.info(s"accepting upgrade to SimpleTaprootChannelsPhoenix during splice from commitment format ${parentCommitment.commitmentFormat}")
+ log.info("accepting upgrade to {} during splice from commitment format {}", ChannelTypes.SimpleTaprootChannelsPhoenix, parentCommitment.commitmentFormat)
PhoenixSimpleTaprootChannelCommitmentFormat
case Some(channelType) =>
- log.info(s"rejecting upgrade to $channelType during splice from commitment format ${parentCommitment.commitmentFormat}")
+ log.info("rejecting upgrade to {} during splice from commitment format {}", channelType, parentCommitment.commitmentFormat)
parentCommitment.commitmentFormat
case _ =>
parentCommitment.commitmentFormat
@@ -1768,7 +1762,7 @@ class Channel(val nodeParams: NodeParams, val channelKeys: ChannelKeys, val wall
case Event(ProcessCurrentBlockHeight(c), d: DATA_SHUTDOWN) => handleNewBlock(c, d)
- case Event(c: CurrentFeerates.BitcoinCore, d: DATA_SHUTDOWN) => handleCurrentFeerate(c, d)
+ case Event(c: CurrentFeerates.BitcoinCore, d: DATA_SHUTDOWN) => handleCurrentFeerate(d)
case Event(c: CMD_CLOSE, d: DATA_SHUTDOWN) =>
val useSimpleClose = Features.canUseFeature(d.commitments.localChannelParams.initFeatures, d.commitments.remoteChannelParams.initFeatures, Features.SimpleClose)
@@ -1989,11 +1983,8 @@ class Channel(val nodeParams: NodeParams, val channelKeys: ChannelKeys, val wall
// We are already watching the corresponding outputs: no need to set additional watches.
d.localCommitPublished.foreach(lcp => {
val commitKeys = commitment.localKeys(channelKeys)
- Closing.LocalClose.claimHtlcsWithPreimage(channelKeys, commitKeys, commitment, c.r).foreach(htlcTx => commitment.commitmentFormat match {
- case Transactions.DefaultCommitmentFormat =>
- txPublisher ! TxPublisher.PublishFinalTx(htlcTx, Some(lcp.commitTx.txid))
- case _: Transactions.AnchorOutputsCommitmentFormat | _: Transactions.SimpleTaprootChannelCommitmentFormat =>
- txPublisher ! TxPublisher.PublishReplaceableTx(htlcTx, lcp.commitTx, commitment, Closing.confirmationTarget(htlcTx))
+ Closing.LocalClose.claimHtlcsWithPreimage(channelKeys, commitKeys, commitment, c.r).foreach(htlcTx => {
+ txPublisher ! TxPublisher.PublishReplaceableTx(htlcTx, lcp.commitTx, commitment, Closing.confirmationTarget(htlcTx))
})
})
d.remoteCommitPublished.foreach(rcp => {
@@ -2525,7 +2516,7 @@ class Channel(val nodeParams: NodeParams, val channelKeys: ChannelKeys, val wall
case Event(ProcessCurrentBlockHeight(c), d: ChannelDataWithCommitments) => handleNewBlock(c, d)
- case Event(c: CurrentFeerates.BitcoinCore, d: ChannelDataWithCommitments) => handleCurrentFeerateDisconnected(c, d)
+ case Event(c: CurrentFeerates.BitcoinCore, d: ChannelDataWithCommitments) => stay()
case Event(c: CMD_ADD_HTLC, d: DATA_NORMAL) => handleAddDisconnected(c, d)
@@ -2830,7 +2821,7 @@ class Channel(val nodeParams: NodeParams, val channelKeys: ChannelKeys, val wall
case Event(ProcessCurrentBlockHeight(c), d: ChannelDataWithCommitments) => handleNewBlock(c, d)
- case Event(c: CurrentFeerates.BitcoinCore, d: ChannelDataWithCommitments) => handleCurrentFeerateDisconnected(c, d)
+ case Event(c: CurrentFeerates.BitcoinCore, d: ChannelDataWithCommitments) => stay()
case Event(getTxResponse: GetTxWithMetaResponse, d: DATA_WAIT_FOR_FUNDING_CONFIRMED) if getTxResponse.txid == d.commitments.latest.fundingTxId => handleGetFundingTx(getTxResponse, d.waitingSince, d.fundingTx_opt)
@@ -3224,50 +3215,15 @@ class Channel(val nodeParams: NodeParams, val channelKeys: ChannelKeys, val wall
888 888 d88P 888 888 Y888 8888888P" 88888888 8888888888 888 T88b "Y8888P"
*/
- private def handleCurrentFeerate(c: CurrentFeerates, d: ChannelDataWithCommitments) = {
+ private def handleCurrentFeerate(d: ChannelDataWithCommitments) = {
val commitments = d.commitments.latest
val networkFeeratePerKw = nodeParams.onChainFeeConf.getCommitmentFeerate(nodeParams.currentBitcoinCoreFeerates, remoteNodeId, d.commitments.latest.commitmentFormat)
val currentFeeratePerKw = commitments.localCommit.spec.commitTxFeerate
val shouldUpdateFee = d.commitments.localChannelParams.paysCommitTxFees && nodeParams.onChainFeeConf.shouldUpdateFee(currentFeeratePerKw, networkFeeratePerKw)
- val shouldClose = !d.commitments.localChannelParams.paysCommitTxFees &&
- nodeParams.onChainFeeConf.feerateToleranceFor(d.commitments.remoteNodeId).isProposedFeerateTooLow(d.commitments.latest.commitmentFormat, networkFeeratePerKw, currentFeeratePerKw) &&
- d.commitments.hasPendingOrProposedHtlcs // we close only if we have HTLCs potentially at risk
if (shouldUpdateFee) {
self ! CMD_UPDATE_FEE(networkFeeratePerKw, commit = true)
- stay()
- } else if (shouldClose) {
- handleLocalError(FeerateTooDifferent(d.channelId, localFeeratePerKw = networkFeeratePerKw, remoteFeeratePerKw = commitments.localCommit.spec.commitTxFeerate), d, Some(c))
- } else {
- stay()
- }
- }
-
- /**
- * This is used to check for the commitment fees when the channel is not operational but we have something at stake
- *
- * @param c the new feerates
- * @param d the channel commtiments
- * @return
- */
- private def handleCurrentFeerateDisconnected(c: CurrentFeerates, d: ChannelDataWithCommitments) = {
- val commitments = d.commitments.latest
- val networkFeeratePerKw = nodeParams.onChainFeeConf.getCommitmentFeerate(nodeParams.currentBitcoinCoreFeerates, remoteNodeId, d.commitments.latest.commitmentFormat)
- val currentFeeratePerKw = commitments.localCommit.spec.commitTxFeerate
- // if the network fees are too high we risk to not be able to confirm our current commitment
- val shouldClose = networkFeeratePerKw > currentFeeratePerKw &&
- nodeParams.onChainFeeConf.feerateToleranceFor(d.commitments.remoteNodeId).isProposedFeerateTooLow(d.commitments.latest.commitmentFormat, networkFeeratePerKw, currentFeeratePerKw) &&
- d.commitments.hasPendingOrProposedHtlcs // we close only if we have HTLCs potentially at risk
- if (shouldClose) {
- if (nodeParams.onChainFeeConf.closeOnOfflineMismatch) {
- log.warning(s"closing OFFLINE channel due to fee mismatch: currentFeeratePerKw=$currentFeeratePerKw networkFeeratePerKw=$networkFeeratePerKw")
- handleLocalError(FeerateTooDifferent(d.channelId, localFeeratePerKw = currentFeeratePerKw, remoteFeeratePerKw = networkFeeratePerKw), d, Some(c))
- } else {
- log.warning(s"channel is OFFLINE but its fee mismatch is over the threshold: currentFeeratePerKw=$currentFeeratePerKw networkFeeratePerKw=$networkFeeratePerKw")
- stay()
- }
- } else {
- stay()
}
+ stay()
}
private def handleCommandSuccess(c: channel.Command, newData: ChannelData) = {
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/ChannelOpenDualFunded.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/ChannelOpenDualFunded.scala
index 783bc62..586b14a 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/ChannelOpenDualFunded.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/ChannelOpenDualFunded.scala
@@ -127,7 +127,7 @@ trait ChannelOpenDualFunded extends DualFundingHandlers with ErrorHandlers {
lockTime = nodeParams.currentBlockHeight.toLong,
fundingPubkey = fundingPubKey,
revocationBasepoint = channelKeys.revocationBasePoint,
- paymentBasepoint = input.localChannelParams.walletStaticPaymentBasepoint.getOrElse(channelKeys.paymentBasePoint),
+ paymentBasepoint = channelKeys.paymentBasePoint,
delayedPaymentBasepoint = channelKeys.delayedPaymentBasePoint,
htlcBasepoint = channelKeys.htlcBasePoint,
firstPerCommitmentPoint = channelKeys.commitmentPoint(0),
@@ -141,7 +141,7 @@ trait ChannelOpenDualFunded extends DualFundingHandlers with ErrorHandlers {
case Event(open: OpenDualFundedChannel, d: DATA_WAIT_FOR_OPEN_DUAL_FUNDED_CHANNEL) =>
val localFundingPubkey = channelKeys.fundingKey(fundingTxIndex = 0).publicKey
val fundingScript = Transactions.makeFundingScript(localFundingPubkey, open.fundingPubkey, d.init.channelType.commitmentFormat).pubkeyScript
- Helpers.validateParamsDualFundedNonInitiator(nodeParams, d.init.channelType, open, fundingScript, remoteNodeId, d.init.localChannelParams.initFeatures, d.init.remoteInit.features, d.init.fundingContribution_opt) match {
+ Helpers.validateParamsDualFundedNonInitiator(nodeParams, open, fundingScript, remoteNodeId, d.init.localChannelParams.initFeatures, d.init.remoteInit.features, d.init.fundingContribution_opt) match {
case Left(t) => handleLocalError(t, d, Some(open))
case Right((channelFeatures, remoteShutdownScript, willFund_opt)) =>
context.system.eventStream.publish(ChannelCreated(self, peer, remoteNodeId, isOpener = false, open.temporaryChannelId, open.commitmentFeerate, Some(open.fundingFeerate)))
@@ -179,7 +179,7 @@ trait ChannelOpenDualFunded extends DualFundingHandlers with ErrorHandlers {
maxAcceptedHtlcs = localCommitParams.maxAcceptedHtlcs,
fundingPubkey = localFundingPubkey,
revocationBasepoint = channelKeys.revocationBasePoint,
- paymentBasepoint = d.init.localChannelParams.walletStaticPaymentBasepoint.getOrElse(channelKeys.paymentBasePoint),
+ paymentBasepoint = channelKeys.paymentBasePoint,
delayedPaymentBasepoint = channelKeys.delayedPaymentBasePoint,
htlcBasepoint = channelKeys.htlcBasePoint,
firstPerCommitmentPoint = channelKeys.commitmentPoint(0),
@@ -224,7 +224,7 @@ trait ChannelOpenDualFunded extends DualFundingHandlers with ErrorHandlers {
when(WAIT_FOR_ACCEPT_DUAL_FUNDED_CHANNEL)(handleExceptions {
case Event(accept: AcceptDualFundedChannel, d: DATA_WAIT_FOR_ACCEPT_DUAL_FUNDED_CHANNEL) =>
- Helpers.validateParamsDualFundedInitiator(nodeParams, remoteNodeId, d.init.channelType, d.init.localChannelParams.initFeatures, d.init.remoteInit.features, d.lastSent, accept) match {
+ Helpers.validateParamsDualFundedInitiator(nodeParams, remoteNodeId, d.init.localChannelParams.initFeatures, d.init.remoteInit.features, d.lastSent, accept) match {
case Left(t) =>
d.init.replyTo ! OpenChannelResponse.Rejected(t.getMessage)
handleLocalError(t, d, Some(accept))
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/ChannelOpenSingleFunded.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/ChannelOpenSingleFunded.scala
index f0510ce..1f10caa 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/ChannelOpenSingleFunded.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/ChannelOpenSingleFunded.scala
@@ -32,7 +32,7 @@ import fr.acinq.eclair.crypto.keymanager.{LocalCommitmentKeys, RemoteCommitmentK
import fr.acinq.eclair.crypto.{NonceGenerator, ShaChain}
import fr.acinq.eclair.io.Peer.OpenChannelResponse
import fr.acinq.eclair.transactions.Transactions
-import fr.acinq.eclair.transactions.Transactions.{AnchorOutputsCommitmentFormat, DefaultCommitmentFormat, SimpleTaprootChannelCommitmentFormat}
+import fr.acinq.eclair.transactions.Transactions.{AnchorOutputsCommitmentFormat, SimpleTaprootChannelCommitmentFormat}
import fr.acinq.eclair.wire.protocol.{AcceptChannel, AcceptChannelTlv, AnnouncementSignatures, ChannelReady, ChannelTlv, Error, FundingCreated, FundingSigned, OpenChannel, OpenChannelTlv, TlvStream}
import fr.acinq.eclair.{MilliSatoshiLong, randomKey, toLongId}
import scodec.bits.ByteVector
@@ -79,7 +79,7 @@ trait ChannelOpenSingleFunded extends SingleFundingHandlers with ErrorHandlers {
val localShutdownScript = input.localChannelParams.upfrontShutdownScript_opt.getOrElse(ByteVector.empty)
val localNonce = input.channelType.commitmentFormat match {
case _: SimpleTaprootChannelCommitmentFormat => Some(NonceGenerator.verificationNonce(NonceGenerator.dummyFundingTxId, fundingKey, NonceGenerator.dummyRemoteFundingPubKey, 0).publicNonce)
- case _: AnchorOutputsCommitmentFormat | DefaultCommitmentFormat => None
+ case _: AnchorOutputsCommitmentFormat => None
}
val open = OpenChannel(
chainHash = nodeParams.chainHash,
@@ -95,7 +95,7 @@ trait ChannelOpenSingleFunded extends SingleFundingHandlers with ErrorHandlers {
maxAcceptedHtlcs = input.proposedCommitParams.localMaxAcceptedHtlcs,
fundingPubkey = fundingKey.publicKey,
revocationBasepoint = channelKeys.revocationBasePoint,
- paymentBasepoint = input.localChannelParams.walletStaticPaymentBasepoint.getOrElse(channelKeys.paymentBasePoint),
+ paymentBasepoint = channelKeys.paymentBasePoint,
delayedPaymentBasepoint = channelKeys.delayedPaymentBasePoint,
htlcBasepoint = channelKeys.htlcBasePoint,
firstPerCommitmentPoint = channelKeys.commitmentPoint(0),
@@ -112,7 +112,7 @@ trait ChannelOpenSingleFunded extends SingleFundingHandlers with ErrorHandlers {
when(WAIT_FOR_OPEN_CHANNEL)(handleExceptions {
case Event(open: OpenChannel, d: DATA_WAIT_FOR_OPEN_CHANNEL) =>
- Helpers.validateParamsSingleFundedFundee(nodeParams, d.initFundee.channelType, d.initFundee.localChannelParams.initFeatures, open, remoteNodeId, d.initFundee.remoteInit.features) match {
+ Helpers.validateParamsSingleFundedFundee(nodeParams, d.initFundee.localChannelParams.initFeatures, open, remoteNodeId, d.initFundee.remoteInit.features) match {
case Left(t) => handleLocalError(t, d, Some(open))
case Right((channelFeatures, remoteShutdownScript)) =>
context.system.eventStream.publish(ChannelCreated(self, peer, remoteNodeId, isOpener = false, open.temporaryChannelId, open.feeratePerKw, None))
@@ -134,7 +134,7 @@ trait ChannelOpenSingleFunded extends SingleFundingHandlers with ErrorHandlers {
val localShutdownScript = d.initFundee.localChannelParams.upfrontShutdownScript_opt.getOrElse(ByteVector.empty)
val localNonce = d.initFundee.channelType.commitmentFormat match {
case _: SimpleTaprootChannelCommitmentFormat => Some(NonceGenerator.verificationNonce(NonceGenerator.dummyFundingTxId, fundingKey, NonceGenerator.dummyRemoteFundingPubKey, 0).publicNonce)
- case _: AnchorOutputsCommitmentFormat | DefaultCommitmentFormat => None
+ case _: AnchorOutputsCommitmentFormat => None
}
val accept = AcceptChannel(temporaryChannelId = open.temporaryChannelId,
dustLimitSatoshis = localCommitParams.dustLimit,
@@ -146,7 +146,7 @@ trait ChannelOpenSingleFunded extends SingleFundingHandlers with ErrorHandlers {
maxAcceptedHtlcs = localCommitParams.maxAcceptedHtlcs,
fundingPubkey = fundingKey.publicKey,
revocationBasepoint = channelKeys.revocationBasePoint,
- paymentBasepoint = d.initFundee.localChannelParams.walletStaticPaymentBasepoint.getOrElse(channelKeys.paymentBasePoint),
+ paymentBasepoint = channelKeys.paymentBasePoint,
delayedPaymentBasepoint = channelKeys.delayedPaymentBasePoint,
htlcBasepoint = channelKeys.htlcBasePoint,
firstPerCommitmentPoint = channelKeys.commitmentPoint(0),
@@ -168,7 +168,7 @@ trait ChannelOpenSingleFunded extends SingleFundingHandlers with ErrorHandlers {
when(WAIT_FOR_ACCEPT_CHANNEL)(handleExceptions {
case Event(accept: AcceptChannel, d: DATA_WAIT_FOR_ACCEPT_CHANNEL) =>
- Helpers.validateParamsSingleFundedFunder(nodeParams, d.initFunder.channelType, d.initFunder.localChannelParams.initFeatures, d.initFunder.remoteInit.features, d.lastSent, accept) match {
+ Helpers.validateParamsSingleFundedFunder(nodeParams, d.initFunder.localChannelParams.initFeatures, d.initFunder.remoteInit.features, d.lastSent, accept) match {
case Left(t) =>
d.initFunder.replyTo ! OpenChannelResponse.Rejected(t.getMessage)
handleLocalError(t, d, Some(accept))
@@ -215,8 +215,8 @@ trait ChannelOpenSingleFunded extends SingleFundingHandlers with ErrorHandlers {
val temporaryChannelId = d.channelParams.channelId
// let's create the first commitment tx that spends the yet uncommitted funding tx
val fundingKey = channelKeys.fundingKey(fundingTxIndex = 0)
- val localCommitmentKeys = LocalCommitmentKeys(d.channelParams, channelKeys, localCommitIndex = 0, d.commitmentFormat)
- val remoteCommitmentKeys = RemoteCommitmentKeys(d.channelParams, channelKeys, d.remoteFirstPerCommitmentPoint, d.commitmentFormat)
+ val localCommitmentKeys = LocalCommitmentKeys(d.channelParams, channelKeys, localCommitIndex = 0)
+ val remoteCommitmentKeys = RemoteCommitmentKeys(d.channelParams, channelKeys, d.remoteFirstPerCommitmentPoint)
Funding.makeFirstCommitTxs(d.channelParams, d.localCommitParams, d.remoteCommitParams, localFundingAmount = d.fundingAmount, remoteFundingAmount = 0 sat, localPushAmount = d.pushAmount, remotePushAmount = 0 msat, d.commitTxFeerate, d.commitmentFormat, fundingTx.txid, fundingTxOutputIndex, fundingKey, d.remoteFundingPubKey, localCommitmentKeys, remoteCommitmentKeys) match {
case Left(ex) => handleLocalError(ex, d, None)
case Right((localSpec, localCommitTx, remoteSpec, remoteCommitTx)) =>
@@ -233,7 +233,7 @@ trait ChannelOpenSingleFunded extends SingleFundingHandlers with ErrorHandlers {
}
case None => Left(MissingCommitNonce(d.channelId, NonceGenerator.dummyFundingTxId, commitmentNumber = 0))
}
- case _: AnchorOutputsCommitmentFormat | DefaultCommitmentFormat => Right(remoteCommitTx.sign(fundingKey, d.remoteFundingPubKey))
+ case _: AnchorOutputsCommitmentFormat => Right(remoteCommitTx.sign(fundingKey, d.remoteFundingPubKey))
}
localSigOfRemoteTx match {
case Left(f) => handleLocalError(f, d, None)
@@ -275,8 +275,8 @@ trait ChannelOpenSingleFunded extends SingleFundingHandlers with ErrorHandlers {
case Event(fc@FundingCreated(_, fundingTxId, fundingTxOutputIndex, _, _), d: DATA_WAIT_FOR_FUNDING_CREATED) =>
val temporaryChannelId = d.channelParams.channelId
val fundingKey = channelKeys.fundingKey(fundingTxIndex = 0)
- val localCommitmentKeys = LocalCommitmentKeys(d.channelParams, channelKeys, localCommitIndex = 0, d.commitmentFormat)
- val remoteCommitmentKeys = RemoteCommitmentKeys(d.channelParams, channelKeys, d.remoteFirstPerCommitmentPoint, d.commitmentFormat)
+ val localCommitmentKeys = LocalCommitmentKeys(d.channelParams, channelKeys, localCommitIndex = 0)
+ val remoteCommitmentKeys = RemoteCommitmentKeys(d.channelParams, channelKeys, d.remoteFirstPerCommitmentPoint)
Funding.makeFirstCommitTxs(d.channelParams, d.localCommitParams, d.remoteCommitParams, localFundingAmount = 0 sat, remoteFundingAmount = d.fundingAmount, localPushAmount = 0 msat, remotePushAmount = d.pushAmount, d.commitTxFeerate, d.commitmentFormat, fundingTxId, fundingTxOutputIndex, fundingKey, d.remoteFundingPubKey, localCommitmentKeys, remoteCommitmentKeys) match {
case Left(ex) => handleLocalError(ex, d, Some(fc))
case Right((localSpec, localCommitTx, remoteSpec, remoteCommitTx)) =>
@@ -303,7 +303,7 @@ trait ChannelOpenSingleFunded extends SingleFundingHandlers with ErrorHandlers {
}
case None => Left(MissingCommitNonce(channelId, NonceGenerator.dummyFundingTxId, commitmentNumber = 0))
}
- case _: AnchorOutputsCommitmentFormat | DefaultCommitmentFormat => Right(remoteCommitTx.sign(fundingKey, d.remoteFundingPubKey))
+ case _: AnchorOutputsCommitmentFormat => Right(remoteCommitTx.sign(fundingKey, d.remoteFundingPubKey))
}
localSigOfRemoteTx match {
case Left(f) => handleLocalError(f, d, Some(fc))
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/CommonFundingHandlers.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/CommonFundingHandlers.scala
index 0cdfb2a..0ce656c 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/CommonFundingHandlers.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/CommonFundingHandlers.scala
@@ -26,7 +26,7 @@ import fr.acinq.eclair.channel._
import fr.acinq.eclair.channel.fsm.Channel.{BroadcastChannelUpdate, PeriodicRefresh, REFRESH_CHANNEL_UPDATE_INTERVAL}
import fr.acinq.eclair.crypto.NonceGenerator
import fr.acinq.eclair.db.RevokedHtlcInfoCleaner
-import fr.acinq.eclair.transactions.Transactions.{AnchorOutputsCommitmentFormat, DefaultCommitmentFormat, SimpleTaprootChannelCommitmentFormat}
+import fr.acinq.eclair.transactions.Transactions.{AnchorOutputsCommitmentFormat, SimpleTaprootChannelCommitmentFormat}
import fr.acinq.eclair.wire.protocol._
import fr.acinq.eclair.{RealShortChannelId, ShortChannelId}
@@ -132,7 +132,7 @@ trait CommonFundingHandlers extends CommonHandlers {
val localFundingKey = channelKeys.fundingKey(fundingTxIndex = 0)
val nextLocalNonce = NonceGenerator.verificationNonce(commitments.latest.fundingTxId, localFundingKey, commitments.latest.remoteFundingPubKey, 1)
ChannelReady(params.channelId, nextPerCommitmentPoint, aliases.localAlias, nextLocalNonce.publicNonce)
- case _: AnchorOutputsCommitmentFormat | DefaultCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
ChannelReady(params.channelId, nextPerCommitmentPoint, aliases.localAlias)
}
}
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/CommonHandlers.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/CommonHandlers.scala
index 56ff91a..451150d 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/CommonHandlers.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/CommonHandlers.scala
@@ -24,7 +24,7 @@ import fr.acinq.eclair.channel._
import fr.acinq.eclair.crypto.NonceGenerator
import fr.acinq.eclair.db.PendingCommandsDb
import fr.acinq.eclair.io.Peer
-import fr.acinq.eclair.transactions.Transactions.{AnchorOutputsCommitmentFormat, DefaultCommitmentFormat, SimpleTaprootChannelCommitmentFormat}
+import fr.acinq.eclair.transactions.Transactions.{AnchorOutputsCommitmentFormat, SimpleTaprootChannelCommitmentFormat}
import fr.acinq.eclair.wire.protocol.{ClosingComplete, HtlcSettlementMessage, LightningMessage, Shutdown, UpdateMessage}
import scodec.bits.ByteVector
@@ -142,7 +142,7 @@ trait CommonHandlers {
val localCloseeNonce = NonceGenerator.signingNonce(localFundingPubKey, commitments.latest.remoteFundingPubKey, commitments.latest.fundingTxId)
localCloseeNonce_opt = Some(localCloseeNonce)
Shutdown(commitments.channelId, finalScriptPubKey, localCloseeNonce.publicNonce)
- case _: AnchorOutputsCommitmentFormat | DefaultCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
Shutdown(commitments.channelId, finalScriptPubKey)
}
}
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/ErrorHandlers.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/ErrorHandlers.scala
index 7b0869e..6807f36 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/ErrorHandlers.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/ErrorHandlers.scala
@@ -240,10 +240,7 @@ trait ErrorHandlers extends CommonHandlers {
case _ => None
}
val publishMainDelayedTx_opt = txs.mainDelayedTx_opt.map(tx => PublishFinalTx(tx, None))
- val publishHtlcTxs = txs.htlcTxs.map(htlcTx => commitment.commitmentFormat match {
- case DefaultCommitmentFormat => PublishFinalTx(htlcTx, Some(lcp.commitTx.txid))
- case _: AnchorOutputsCommitmentFormat | _: SimpleTaprootChannelCommitmentFormat => PublishReplaceableTx(htlcTx, lcp.commitTx, commitment, Closing.confirmationTarget(htlcTx))
- })
+ val publishHtlcTxs = txs.htlcTxs.map(htlcTx => PublishReplaceableTx(htlcTx, lcp.commitTx, commitment, Closing.confirmationTarget(htlcTx)))
val publishQueue = Seq(publishCommitTx) ++ publishAnchorTx_opt ++ publishMainDelayedTx_opt ++ publishHtlcTxs
publishIfNeeded(publishQueue, lcp.irrevocablySpent)
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fund/InteractiveTxBuilder.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fund/InteractiveTxBuilder.scala
index 7b841b1..8eb18a7 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fund/InteractiveTxBuilder.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fund/InteractiveTxBuilder.scala
@@ -894,8 +894,8 @@ private class InteractiveTxBuilder(replyTo: ActorRef[InteractiveTxBuilder.Respon
val fundingTx = completeTx.buildUnsignedTx()
val fundingOutputIndex = fundingTx.txOut.indexWhere(_.publicKeyScript == fundingPubkeyScript)
val liquidityFee = fundingParams.liquidityFees(liquidityPurchase_opt)
- val localCommitmentKeys = LocalCommitmentKeys(channelParams, channelKeys, purpose.localCommitIndex, fundingParams.commitmentFormat)
- val remoteCommitmentKeys = RemoteCommitmentKeys(channelParams, channelKeys, purpose.remotePerCommitmentPoint, fundingParams.commitmentFormat)
+ val localCommitmentKeys = LocalCommitmentKeys(channelParams, channelKeys, purpose.localCommitIndex)
+ val remoteCommitmentKeys = RemoteCommitmentKeys(channelParams, channelKeys, purpose.remotePerCommitmentPoint)
Funding.makeCommitTxs(channelParams, localCommitParams, remoteCommitParams,
fundingAmount = fundingParams.fundingAmount,
toLocal = completeTx.sharedOutput.localAmount - localPushAmount + remotePushAmount - liquidityFee,
@@ -1218,7 +1218,7 @@ object InteractiveTxSigningSession {
localCommit match {
case Left(unsignedLocalCommit) =>
val fundingKey = localFundingKey(channelKeys)
- val commitKeys = LocalCommitmentKeys(channelParams, channelKeys, localCommitIndex, fundingParams.commitmentFormat)
+ val commitKeys = LocalCommitmentKeys(channelParams, channelKeys, localCommitIndex)
val fundingOutput = commitInput(fundingKey)
LocalCommit.fromCommitSig(channelParams, localCommitParams, commitKeys, fundingTx.txId, fundingKey, fundingParams.remoteFundingPubKey, fundingOutput, remoteCommitSig, localCommitIndex, unsignedLocalCommit.spec, fundingParams.commitmentFormat).map { signedLocalCommit =>
if (shouldSignFirst(fundingParams.isInitiator, channelParams, fundingTx.tx)) {
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/CommitmentKeys.scala b/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/CommitmentKeys.scala
index 540650c..dc07cfa 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/CommitmentKeys.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/CommitmentKeys.scala
@@ -17,9 +17,7 @@
package fr.acinq.eclair.crypto.keymanager
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
-import fr.acinq.eclair.Features
import fr.acinq.eclair.channel.ChannelParams
-import fr.acinq.eclair.transactions.Transactions.{AnchorOutputsCommitmentFormat, CommitmentFormat, DefaultCommitmentFormat, SimpleTaprootChannelCommitmentFormat}
/**
* Created by t-bast on 10/04/2025.
@@ -67,16 +65,12 @@ case class LocalCommitmentKeys(ourDelayedPaymentKey: PrivateKey,
}
object LocalCommitmentKeys {
- def apply(params: ChannelParams, channelKeys: ChannelKeys, localCommitIndex: Long, commitmentFormat: CommitmentFormat): LocalCommitmentKeys = {
+ def apply(params: ChannelParams, channelKeys: ChannelKeys, localCommitIndex: Long): LocalCommitmentKeys = {
val localPerCommitmentPoint = channelKeys.commitmentPoint(localCommitIndex)
LocalCommitmentKeys(
ourDelayedPaymentKey = channelKeys.delayedPaymentKey(localPerCommitmentPoint),
- theirPaymentPublicKey = commitmentFormat match {
- case DefaultCommitmentFormat if params.localParams.walletStaticPaymentBasepoint.nonEmpty => params.remoteParams.paymentBasepoint
- case DefaultCommitmentFormat => ChannelKeys.remotePerCommitmentPublicKey(params.remoteParams.paymentBasepoint, localPerCommitmentPoint)
- case _: AnchorOutputsCommitmentFormat | _: SimpleTaprootChannelCommitmentFormat => params.remoteParams.paymentBasepoint
- },
- ourPaymentBasePoint = params.localParams.walletStaticPaymentBasepoint.getOrElse(channelKeys.paymentBasePoint),
+ theirPaymentPublicKey = params.remoteParams.paymentBasepoint,
+ ourPaymentBasePoint = channelKeys.paymentBasePoint,
ourHtlcKey = channelKeys.htlcKey(localPerCommitmentPoint),
theirHtlcPublicKey = ChannelKeys.remotePerCommitmentPublicKey(params.remoteParams.htlcBasepoint, localPerCommitmentPoint),
revocationPublicKey = ChannelKeys.revocationPublicKey(params.remoteParams.revocationBasepoint, localPerCommitmentPoint)
@@ -92,23 +86,16 @@ object LocalCommitmentKeys {
* to a p2wpkh address created by our bitcoin node. We thus don't need the private key, as the output can immediately
* be spent by our bitcoin node (no need for 2nd-stage transactions to send it back to our wallet).
*/
-case class RemoteCommitmentKeys(ourPaymentKey: Either[PublicKey, PrivateKey],
+case class RemoteCommitmentKeys(ourPaymentKey: PrivateKey,
theirDelayedPaymentPublicKey: PublicKey,
ourPaymentBasePoint: PublicKey,
ourHtlcKey: PrivateKey,
theirHtlcPublicKey: PublicKey,
revocationPublicKey: PublicKey) {
- val ourPaymentPublicKey: PublicKey = ourPaymentKey match {
- case Left(publicKey) => publicKey
- case Right(privateKey) => privateKey.publicKey
- }
// Since this is the remote commitment, local is them and remote is us.
val publicKeys: CommitmentPublicKeys = CommitmentPublicKeys(
localDelayedPaymentPublicKey = theirDelayedPaymentPublicKey,
- remotePaymentPublicKey = ourPaymentKey match {
- case Left(publicKey) => publicKey
- case Right(privateKey) => privateKey.publicKey
- },
+ remotePaymentPublicKey = ourPaymentKey.publicKey,
localHtlcPublicKey = theirHtlcPublicKey,
remoteHtlcPublicKey = ourHtlcKey.publicKey,
revocationPublicKey = revocationPublicKey
@@ -116,18 +103,11 @@ case class RemoteCommitmentKeys(ourPaymentKey: Either[PublicKey, PrivateKey],
}
object RemoteCommitmentKeys {
- def apply(params: ChannelParams, channelKeys: ChannelKeys, remotePerCommitmentPoint: PublicKey, commitmentFormat: CommitmentFormat): RemoteCommitmentKeys = {
+ def apply(params: ChannelParams, channelKeys: ChannelKeys, remotePerCommitmentPoint: PublicKey): RemoteCommitmentKeys = {
RemoteCommitmentKeys(
- ourPaymentKey = params.localParams.walletStaticPaymentBasepoint match {
- case Some(walletPublicKey) => Left(walletPublicKey)
- case None => commitmentFormat match {
- // Note that if we're using option_static_remotekey, a walletStaticPaymentBasepoint will be provided.
- case DefaultCommitmentFormat => Right(channelKeys.paymentKey(remotePerCommitmentPoint))
- case _: AnchorOutputsCommitmentFormat | _: SimpleTaprootChannelCommitmentFormat => Right(channelKeys.paymentBaseSecret)
- }
- },
+ ourPaymentKey = channelKeys.paymentBaseSecret,
theirDelayedPaymentPublicKey = ChannelKeys.remotePerCommitmentPublicKey(params.remoteParams.delayedPaymentBasepoint, remotePerCommitmentPoint),
- ourPaymentBasePoint = params.localParams.walletStaticPaymentBasepoint.getOrElse(channelKeys.paymentBasePoint),
+ ourPaymentBasePoint = channelKeys.paymentBasePoint,
ourHtlcKey = channelKeys.htlcKey(remotePerCommitmentPoint),
theirHtlcPublicKey = ChannelKeys.remotePerCommitmentPublicKey(params.remoteParams.htlcBasepoint, remotePerCommitmentPoint),
revocationPublicKey = ChannelKeys.revocationPublicKey(channelKeys.revocationBasePoint, remotePerCommitmentPoint)
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/io/OpenChannelInterceptor.scala b/eclair-core/src/main/scala/fr/acinq/eclair/io/OpenChannelInterceptor.scala
index ba4d204..8c50e39 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/io/OpenChannelInterceptor.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/io/OpenChannelInterceptor.scala
@@ -24,7 +24,7 @@ import akka.actor.typed.{ActorRef, Behavior}
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
import fr.acinq.bitcoin.scalacompat.{ByteVector32, Satoshi, SatoshiLong, Script}
import fr.acinq.eclair.Features.Wumbo
-import fr.acinq.eclair.blockchain.OnChainPubkeyCache
+import fr.acinq.eclair.blockchain.OnChainAddressCache
import fr.acinq.eclair.channel._
import fr.acinq.eclair.channel.fsm.Channel
import fr.acinq.eclair.io.Peer.{OpenChannelResponse, SpawnChannelNonInitiator}
@@ -70,14 +70,14 @@ object OpenChannelInterceptor {
private case object PluginTimeout extends QueryPluginCommands
// @formatter:on
- def apply(peer: ActorRef[Any], nodeParams: NodeParams, remoteNodeId: PublicKey, wallet: OnChainPubkeyCache, pendingChannelsRateLimiter: ActorRef[PendingChannelsRateLimiter.Command], pluginTimeout: FiniteDuration = 1 minute): Behavior[Command] =
+ def apply(peer: ActorRef[Any], nodeParams: NodeParams, remoteNodeId: PublicKey, wallet: OnChainAddressCache, pendingChannelsRateLimiter: ActorRef[PendingChannelsRateLimiter.Command], pluginTimeout: FiniteDuration = 1 minute): Behavior[Command] =
Behaviors.setup { context =>
Behaviors.withMdc(Logs.mdc(remoteNodeId_opt = Some(remoteNodeId))) {
new OpenChannelInterceptor(peer, pendingChannelsRateLimiter, pluginTimeout, nodeParams, wallet, context).waitForRequest()
}
}
- def makeChannelParams(nodeParams: NodeParams, initFeatures: Features[InitFeature], upfrontShutdownScript_opt: Option[ByteVector], walletStaticPaymentBasepoint_opt: Option[PublicKey], isChannelOpener: Boolean, paysCommitTxFees: Boolean, dualFunded: Boolean, fundingAmount: Satoshi): LocalChannelParams = {
+ def makeChannelParams(nodeParams: NodeParams, initFeatures: Features[InitFeature], upfrontShutdownScript_opt: Option[ByteVector], isChannelOpener: Boolean, paysCommitTxFees: Boolean, dualFunded: Boolean, fundingAmount: Satoshi): LocalChannelParams = {
LocalChannelParams(
nodeParams.nodeId,
nodeParams.channelKeyManager.newFundingKeyPath(isChannelOpener),
@@ -85,7 +85,6 @@ object OpenChannelInterceptor {
isChannelOpener = isChannelOpener,
paysCommitTxFees = paysCommitTxFees,
upfrontShutdownScript_opt = upfrontShutdownScript_opt,
- walletStaticPaymentBasepoint = walletStaticPaymentBasepoint_opt,
initFeatures = initFeatures
)
}
@@ -96,7 +95,7 @@ private class OpenChannelInterceptor(peer: ActorRef[Any],
pendingChannelsRateLimiter: ActorRef[PendingChannelsRateLimiter.Command],
pluginTimeout: FiniteDuration,
nodeParams: NodeParams,
- wallet: OnChainPubkeyCache,
+ wallet: OnChainAddressCache,
context: ActorContext[OpenChannelInterceptor.Command]) {
import OpenChannelInterceptor._
@@ -115,30 +114,23 @@ private class OpenChannelInterceptor(peer: ActorRef[Any],
} else if (request.open.fundingAmount >= Channel.MAX_FUNDING_WITHOUT_WUMBO && !request.remoteFeatures.hasFeature(Wumbo)) {
request.replyTo ! OpenChannelResponse.Rejected(s"fundingAmount=${request.open.fundingAmount} is too big, the remote peer doesn't support wumbo")
waitForRequest()
+ } else if (request.open.channelType_opt.isEmpty) {
+ request.replyTo ! OpenChannelResponse.Rejected("channel_type must be provided")
+ waitForRequest()
} else {
- // If a channel type was provided, we directly use it instead of computing it based on local and remote features.
- val channelFlags = request.open.channelFlags_opt.getOrElse(nodeParams.channelConf.channelFlags)
- val channelType = request.open.channelType_opt.getOrElse(ChannelTypes.defaultFromFeatures(request.localFeatures, request.remoteFeatures, channelFlags.announceChannel))
+ val channelType = request.open.channelType_opt.get
val dualFunded = Features.canUseFeature(request.localFeatures, request.remoteFeatures, Features.DualFunding)
val upfrontShutdownScript = Features.canUseFeature(request.localFeatures, request.remoteFeatures, Features.UpfrontShutdownScript)
// If we're purchasing liquidity, we expect our peer to contribute at least the amount we're purchasing, otherwise we'll cancel the funding attempt.
val expectedFundingAmount = request.open.fundingAmount + request.open.requestFunding_opt.map(_.requestedAmount).getOrElse(0 sat)
- val localParams = createLocalParams(nodeParams, request.localFeatures, upfrontShutdownScript, channelType, isChannelOpener = true, paysCommitTxFees = true, dualFunded = dualFunded, expectedFundingAmount)
+ val localParams = createLocalParams(nodeParams, request.localFeatures, upfrontShutdownScript, isChannelOpener = true, paysCommitTxFees = true, dualFunded = dualFunded, expectedFundingAmount)
peer ! Peer.SpawnChannelInitiator(request.replyTo, request.open, ChannelConfig.standard, channelType, localParams)
waitForRequest()
}
}
private def sanityCheckNonInitiator(request: OpenChannelNonInitiator): Behavior[Command] = {
- validateRemoteChannelType(request.temporaryChannelId, request.channelFlags, request.channelType_opt, request.localFeatures, request.remoteFeatures) match {
- case Right(_: ChannelTypes.Standard) =>
- context.log.warn("rejecting incoming channel: anchor outputs must be used for new channels")
- sendFailure("rejecting incoming channel: anchor outputs must be used for new channels", request)
- waitForRequest()
- case Right(_: ChannelTypes.StaticRemoteKey) if !nodeParams.channelConf.acceptIncomingStaticRemoteKeyChannels =>
- context.log.warn("rejecting static_remote_key incoming static_remote_key channels")
- sendFailure("rejecting incoming static_remote_key channel: anchor outputs must be used for new channels", request)
- waitForRequest()
+ ChannelTypes.areCompatible(request.temporaryChannelId, request.localFeatures, request.channelType_opt) match {
case Right(channelType) =>
val dualFunded = Features.canUseFeature(request.localFeatures, request.remoteFeatures, Features.DualFunding)
val upfrontShutdownScript = Features.canUseFeature(request.localFeatures, request.remoteFeatures, Features.UpfrontShutdownScript)
@@ -152,7 +144,6 @@ private class OpenChannelInterceptor(peer: ActorRef[Any],
nodeParams,
request.localFeatures,
upfrontShutdownScript,
- channelType,
isChannelOpener = false,
paysCommitTxFees = nonInitiatorPaysCommitTxFees,
dualFunded = dualFunded,
@@ -280,29 +271,15 @@ private class OpenChannelInterceptor(peer: ActorRef[Any],
}
}
- private def validateRemoteChannelType(temporaryChannelId: ByteVector32, channelFlags: ChannelFlags, remoteChannelType_opt: Option[ChannelType], localFeatures: Features[InitFeature], remoteFeatures: Features[InitFeature]): Either[ChannelException, SupportedChannelType] = {
- remoteChannelType_opt match {
- // remote explicitly specifies a channel type: we check whether we want to allow it
- case Some(remoteChannelType) => ChannelTypes.areCompatible(localFeatures, remoteChannelType) match {
- case Some(acceptedChannelType) => Right(acceptedChannelType)
- case None => Left(InvalidChannelType(temporaryChannelId, ChannelTypes.defaultFromFeatures(localFeatures, remoteFeatures, channelFlags.announceChannel), remoteChannelType))
- }
- // Bolt 2: if `option_channel_type` is negotiated: MUST set `channel_type`
- case None if Features.canUseFeature(localFeatures, remoteFeatures, Features.ChannelType) => Left(MissingChannelType(temporaryChannelId))
- // remote doesn't specify a channel type: we use spec-defined defaults
- case None => Right(ChannelTypes.defaultFromFeatures(localFeatures, remoteFeatures, channelFlags.announceChannel))
- }
- }
-
- private def createLocalParams(nodeParams: NodeParams, initFeatures: Features[InitFeature], upfrontShutdownScript: Boolean, channelType: SupportedChannelType, isChannelOpener: Boolean, paysCommitTxFees: Boolean, dualFunded: Boolean, fundingAmount: Satoshi): LocalChannelParams = {
+ private def createLocalParams(nodeParams: NodeParams, initFeatures: Features[InitFeature], upfrontShutdownScript: Boolean, isChannelOpener: Boolean, paysCommitTxFees: Boolean, dualFunded: Boolean, fundingAmount: Satoshi): LocalChannelParams = {
makeChannelParams(
- nodeParams, initFeatures,
+ nodeParams,
+ initFeatures,
// Note that if our bitcoin node is configured to use taproot, this will generate a taproot script.
// If our peer doesn't support option_shutdown_anysegwit, the channel open will fail.
// This is fine: "serious" nodes should support option_shutdown_anysegwit, and if we want to use taproot, we
// most likely don't want to open channels with nodes that don't support it.
if (upfrontShutdownScript) Some(Script.write(wallet.getReceivePublicKeyScript(renew = true))) else None,
- if (channelType.paysDirectlyToWallet) Some(wallet.getP2wpkhPubkey(renew = true)) else None,
isChannelOpener = isChannelOpener,
paysCommitTxFees = paysCommitTxFees,
dualFunded = dualFunded,
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/io/Peer.scala b/eclair-core/src/main/scala/fr/acinq/eclair/io/Peer.scala
index bd9dd6c..555a053 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/io/Peer.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/io/Peer.scala
@@ -29,7 +29,7 @@ import fr.acinq.eclair.NotificationsLogger.NotifyNodeOperator
import fr.acinq.eclair._
import fr.acinq.eclair.blockchain.bitcoind.ZmqWatcher
import fr.acinq.eclair.blockchain.fee.FeeratePerKw
-import fr.acinq.eclair.blockchain.{CurrentBlockHeight, CurrentFeerates, OnChainChannelFunder, OnChainPubkeyCache}
+import fr.acinq.eclair.blockchain.{CurrentBlockHeight, CurrentFeerates, OnChainAddressCache, OnChainChannelFunder}
import fr.acinq.eclair.channel._
import fr.acinq.eclair.channel.fsm.Channel
import fr.acinq.eclair.crypto.Sphinx
@@ -61,7 +61,7 @@ import scodec.bits.ByteVector
*/
class Peer(val nodeParams: NodeParams,
remoteNodeId: PublicKey,
- wallet: OnChainPubkeyCache,
+ wallet: OnChainAddressCache,
channelFactory: Peer.ChannelFactory,
switchboard: ActorRef,
register: ActorRef,
@@ -1024,12 +1024,12 @@ object Peer {
def spawn(context: ActorContext, remoteNodeId: PublicKey, channelKeys: ChannelKeys): ActorRef
}
- case class SimpleChannelFactory(nodeParams: NodeParams, watcher: typed.ActorRef[ZmqWatcher.Command], relayer: ActorRef, wallet: OnChainChannelFunder with OnChainPubkeyCache, txPublisherFactory: Channel.TxPublisherFactory) extends ChannelFactory {
+ case class SimpleChannelFactory(nodeParams: NodeParams, watcher: typed.ActorRef[ZmqWatcher.Command], relayer: ActorRef, wallet: OnChainChannelFunder with OnChainAddressCache, txPublisherFactory: Channel.TxPublisherFactory) extends ChannelFactory {
override def spawn(context: ActorContext, remoteNodeId: PublicKey, channelKeys: ChannelKeys): ActorRef =
context.actorOf(Channel.props(nodeParams, channelKeys, wallet, remoteNodeId, watcher, relayer, txPublisherFactory))
}
- def props(nodeParams: NodeParams, remoteNodeId: PublicKey, wallet: OnChainPubkeyCache, channelFactory: ChannelFactory, switchboard: ActorRef, register: ActorRef, router: typed.ActorRef[Router.GetNodeId], pendingChannelsRateLimiter: typed.ActorRef[PendingChannelsRateLimiter.Command]): Props =
+ def props(nodeParams: NodeParams, remoteNodeId: PublicKey, wallet: OnChainAddressCache, channelFactory: ChannelFactory, switchboard: ActorRef, register: ActorRef, router: typed.ActorRef[Router.GetNodeId], pendingChannelsRateLimiter: typed.ActorRef[PendingChannelsRateLimiter.Command]): Props =
Props(new Peer(nodeParams, remoteNodeId, wallet, channelFactory, switchboard, register, router, pendingChannelsRateLimiter))
// @formatter:off
@@ -1051,7 +1051,7 @@ object Peer {
def peerStorage: PeerStorage
}
case object Nothing extends Data {
- override def channels = Map.empty
+ override def channels: Map[_ <: ChannelId, ActorRef] = Map.empty
override def activeChannels: Set[ByteVector32] = Set.empty
override def peerStorage: PeerStorage = PeerStorage(None, written = true)
}
@@ -1112,7 +1112,7 @@ object Peer {
* the channel has been opened.
*/
case class Created(channelId: ByteVector32, fundingTxId: TxId, fee: Satoshi) extends OpenChannelResponse { override def toString = s"created channel $channelId with fundingTxId=$fundingTxId and fees=$fee" }
- case class Rejected(reason: String) extends OpenChannelResponse { override def toString = reason }
+ case class Rejected(reason: String) extends OpenChannelResponse { override def toString: String = reason }
case object Cancelled extends OpenChannelResponse { override def toString = "channel creation cancelled" }
case object Disconnected extends OpenChannelResponse { override def toString = "disconnected" }
case object TimedOut extends OpenChannelResponse { override def toString = "open channel cancelled, took too long" }
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/io/Switchboard.scala b/eclair-core/src/main/scala/fr/acinq/eclair/io/Switchboard.scala
index 6b4adfc..c455056 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/io/Switchboard.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/io/Switchboard.scala
@@ -22,7 +22,7 @@ import akka.actor.typed.scaladsl.adapter.{ClassicActorContextOps, ClassicActorRe
import akka.actor.{Actor, ActorContext, ActorLogging, ActorRef, OneForOneStrategy, Props, Stash, Status, SupervisorStrategy, typed}
import fr.acinq.bitcoin.scalacompat.ByteVector32
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.eclair.blockchain.OnChainPubkeyCache
+import fr.acinq.eclair.blockchain.OnChainAddressCache
import fr.acinq.eclair.channel.Helpers.Closing
import fr.acinq.eclair.channel._
import fr.acinq.eclair.io.IncomingConnectionsTracker.TrackIncomingConnection
@@ -180,7 +180,7 @@ object Switchboard {
def spawn(context: ActorContext, remoteNodeId: PublicKey): ActorRef
}
- case class SimplePeerFactory(nodeParams: NodeParams, wallet: OnChainPubkeyCache, channelFactory: Peer.ChannelFactory, pendingChannelsRateLimiter: typed.ActorRef[PendingChannelsRateLimiter.Command], register: ActorRef, router: typed.ActorRef[Router.GetNodeId]) extends PeerFactory {
+ case class SimplePeerFactory(nodeParams: NodeParams, wallet: OnChainAddressCache, channelFactory: Peer.ChannelFactory, pendingChannelsRateLimiter: typed.ActorRef[PendingChannelsRateLimiter.Command], register: ActorRef, router: typed.ActorRef[Router.GetNodeId]) extends PeerFactory {
override def spawn(context: ActorContext, remoteNodeId: PublicKey): ActorRef =
context.actorOf(Peer.props(nodeParams, remoteNodeId, wallet, channelFactory, context.self, register, router, pendingChannelsRateLimiter), name = peerActorName(remoteNodeId))
}
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/transactions/CommitmentSpec.scala b/eclair-core/src/main/scala/fr/acinq/eclair/transactions/CommitmentSpec.scala
index eb51784..8793de7 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/transactions/CommitmentSpec.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/transactions/CommitmentSpec.scala
@@ -19,7 +19,7 @@ package fr.acinq.eclair.transactions
import fr.acinq.bitcoin.scalacompat.{LexicographicalOrdering, SatoshiLong, TxOut}
import fr.acinq.eclair.MilliSatoshi
import fr.acinq.eclair.blockchain.fee.FeeratePerKw
-import fr.acinq.eclair.transactions.Transactions.{CommitmentFormat, DefaultCommitmentFormat, PhoenixSimpleTaprootChannelCommitmentFormat, UnsafeLegacyAnchorOutputsCommitmentFormat, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat, ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat}
+import fr.acinq.eclair.transactions.Transactions._
import fr.acinq.eclair.wire.protocol._
/**
@@ -95,7 +95,6 @@ final case class CommitmentSpec(htlcs: Set[DirectedHtlc], commitTxFeerate: Feera
def htlcTxFeerate(commitmentFormat: CommitmentFormat): FeeratePerKw = commitmentFormat match {
case ZeroFeeHtlcTxAnchorOutputsCommitmentFormat | ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat => FeeratePerKw(0 sat)
case UnsafeLegacyAnchorOutputsCommitmentFormat | PhoenixSimpleTaprootChannelCommitmentFormat => commitTxFeerate
- case DefaultCommitmentFormat => commitTxFeerate
}
def findIncomingHtlcById(id: Long): Option[IncomingHtlc] = htlcs.collectFirst { case htlc: IncomingHtlc if htlc.add.id == id => htlc }
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/transactions/Scripts.scala b/eclair-core/src/main/scala/fr/acinq/eclair/transactions/Scripts.scala
index 874e2ba..b64c842 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/transactions/Scripts.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/transactions/Scripts.scala
@@ -43,7 +43,6 @@ object Scripts {
def der(sig: ByteVector64, sighashType: Int = SIGHASH_ALL): ByteVector = Crypto.compact2der(sig) :+ sighashType.toByte
private def htlcRemoteSighash(commitmentFormat: CommitmentFormat): Int = commitmentFormat match {
- case DefaultCommitmentFormat => SIGHASH_ALL
case _: AnchorOutputsCommitmentFormat | _: SimpleTaprootChannelCommitmentFormat => SIGHASH_SINGLE | SIGHASH_ANYONECANPAY
}
@@ -204,7 +203,6 @@ object Scripts {
def htlcOffered(keys: CommitmentPublicKeys, paymentHash: ByteVector32, commitmentFormat: CommitmentFormat): Seq[ScriptElt] = {
val addCsvDelay = commitmentFormat match {
- case DefaultCommitmentFormat => false
case _: AnchorOutputsCommitmentFormat | _: SimpleTaprootChannelCommitmentFormat => true
}
// @formatter:off
@@ -263,7 +261,6 @@ object Scripts {
def htlcReceived(keys: CommitmentPublicKeys, paymentHash: ByteVector32, lockTime: CltvExpiry, commitmentFormat: CommitmentFormat): Seq[ScriptElt] = {
val addCsvDelay = commitmentFormat match {
- case DefaultCommitmentFormat => false
case _: AnchorOutputsCommitmentFormat | _: SimpleTaprootChannelCommitmentFormat => true
}
// @formatter:off
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/transactions/Transactions.scala b/eclair-core/src/main/scala/fr/acinq/eclair/transactions/Transactions.scala
index 9608b64..2375315 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/transactions/Transactions.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/transactions/Transactions.scala
@@ -81,7 +81,7 @@ object Transactions {
def claimHtlcTimeoutWeight: Int
/** Weight of a fully signed [[ClaimLocalDelayedOutputTx]] transaction. */
def toLocalDelayedWeight: Int
- /** Weight of a fully signed [[ClaimRemoteCommitMainOutputTx]] transaction. */
+ /** Weight of a fully signed [[ClaimRemoteDelayedOutputTx]] transaction. */
def toRemoteWeight: Int
/** Weight of a fully signed [[HtlcDelayedTx]] 3rd-stage transaction (spending the output of an [[HtlcTx]]). */
def htlcDelayedWeight: Int
@@ -100,30 +100,6 @@ object Transactions {
override val fundingInputWeight = 384
}
- /**
- * Commitment format as defined in the v1.0 specification (https://github.com/lightningnetwork/lightning-rfc/tree/v1.0).
- */
- case object DefaultCommitmentFormat extends SegwitV0CommitmentFormat {
- override val commitWeight = 724
- override val anchorInputWeight = 0
- override val htlcOutputWeight = 172
- override val htlcTimeoutInputWeight = 449
- override val htlcTimeoutWeight = 663
- override val htlcSuccessInputWeight = 488
- override val htlcSuccessWeight = 703
- override val claimHtlcSuccessWeight = 571
- override val claimHtlcTimeoutWeight = 544
- override val toLocalDelayedWeight = 483
- override val toRemoteWeight = 438
- override val htlcDelayedWeight = 483
- override val mainPenaltyWeight = 484
- override val htlcOfferedPenaltyWeight = 572
- override val htlcReceivedPenaltyWeight = 577
- override val claimHtlcPenaltyWeight = 484
-
- override def toString: String = "legacy"
- }
-
/**
* Commitment format that adds anchor outputs to the commitment transaction and uses custom sighash flags for HTLC
* transactions to allow unilateral fee bumping (https://github.com/lightningnetwork/lightning-rfc/pull/688).
@@ -212,11 +188,6 @@ object Transactions {
}
object RedeemInfo {
sealed trait SegwitV0 extends RedeemInfo { def redeemScript: ByteVector }
- /** @param publicKey the public key for this p2wpkh input. */
- case class P2wpkh(publicKey: PublicKey) extends SegwitV0 {
- override val redeemScript: ByteVector = Script.write(Script.pay2pkh(publicKey))
- override val pubkeyScript: ByteVector = Script.write(Script.pay2wpkh(publicKey))
- }
/** @param redeemScript the actual script must be known to redeem pay2wsh inputs. */
case class P2wsh(redeemScript: ByteVector) extends SegwitV0 {
override val pubkeyScript: ByteVector = Script.write(Script.pay2wsh(redeemScript))
@@ -491,14 +462,12 @@ object Transactions {
* Transactions spending a remote [[CommitTx]] or one of its descendants.
*
* When a current remote [[CommitTx]] is published:
- * - When using the default commitment format, [[ClaimP2WPKHOutputTx]] spends the to-local output of [[CommitTx]]
* - When using anchor outputs, [[ClaimRemoteDelayedOutputTx]] spends the to-local output of [[CommitTx]]
* - When using anchor outputs, [[ClaimRemoteAnchorTx]] spends the to-local anchor of [[CommitTx]]
* - [[ClaimHtlcSuccessTx]] spends received htlc outputs of [[CommitTx]] for which we have the preimage
* - [[ClaimHtlcTimeoutTx]] spends sent htlc outputs of [[CommitTx]] after a timeout
*
* When a revoked remote [[CommitTx]] is published:
- * - When using the default commitment format, [[ClaimP2WPKHOutputTx]] spends the to-local output of [[CommitTx]]
* - When using anchor outputs, [[ClaimRemoteDelayedOutputTx]] spends the to-local output of [[CommitTx]]
* - [[MainPenaltyTx]] spends the remote main output using the revocation secret
* - [[HtlcPenaltyTx]] spends all htlc outputs using the revocation secret (and competes with [[HtlcSuccessTx]] and [[HtlcTimeoutTx]] published by the remote node)
@@ -538,7 +507,6 @@ object Transactions {
// @formatter:on
def sighash(txOwner: TxOwner): Int = commitmentFormat match {
- case DefaultCommitmentFormat => SIGHASH_ALL
case _: AnchorOutputsCommitmentFormat => txOwner match {
case TxOwner.Local => SIGHASH_ALL
case TxOwner.Remote => SIGHASH_SINGLE | SIGHASH_ANYONECANPAY
@@ -632,7 +600,7 @@ object Transactions {
}
def redeemInfo(commitKeys: CommitmentPublicKeys, paymentHash: ByteVector32, htlcExpiry: CltvExpiry, commitmentFormat: CommitmentFormat): RedeemInfo = commitmentFormat match {
- case DefaultCommitmentFormat | _: AnchorOutputsCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
val redeemScript = Script.write(htlcReceived(commitKeys, paymentHash, htlcExpiry, commitmentFormat))
RedeemInfo.P2wsh(redeemScript)
case _: SimpleTaprootChannelCommitmentFormat =>
@@ -686,7 +654,7 @@ object Transactions {
}
def redeemInfo(commitKeys: CommitmentPublicKeys, paymentHash: ByteVector32, commitmentFormat: CommitmentFormat): RedeemInfo = commitmentFormat match {
- case DefaultCommitmentFormat | _: AnchorOutputsCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
val redeemScript = Script.write(htlcOffered(commitKeys, paymentHash, commitmentFormat))
RedeemInfo.P2wsh(redeemScript)
case _: SimpleTaprootChannelCommitmentFormat =>
@@ -702,7 +670,7 @@ object Transactions {
override def sign(): Transaction = {
val witness = commitmentFormat match {
- case DefaultCommitmentFormat | _: AnchorOutputsCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
val redeemScript = Script.write(toLocalDelayed(commitKeys.publicKeys, toLocalDelay))
val sig = sign(commitKeys.ourDelayedPaymentKey, sighash, RedeemInfo.P2wsh(redeemScript), extraUtxos = Map.empty)
witnessToLocalDelayedAfterDelay(sig, redeemScript)
@@ -736,7 +704,7 @@ object Transactions {
}
def redeemInfo(commitKeys: CommitmentPublicKeys, toLocalDelay: CltvExpiryDelta, commitmentFormat: CommitmentFormat): RedeemInfo = commitmentFormat match {
- case DefaultCommitmentFormat | _: AnchorOutputsCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
val redeemScript = Script.write(toLocalDelayed(commitKeys, toLocalDelay))
RedeemInfo.P2wsh(redeemScript)
case _: SimpleTaprootChannelCommitmentFormat =>
@@ -762,7 +730,7 @@ object Transactions {
override def sign(): Transaction = {
// Note that in/out HTLCs are inverted in the remote commitment: from their point of view it's an offered (outgoing) HTLC.
val witness = commitmentFormat match {
- case DefaultCommitmentFormat | _: AnchorOutputsCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
val redeemScript = Script.write(htlcOffered(commitKeys.publicKeys, paymentHash, commitmentFormat))
val sig = sign(commitKeys.ourHtlcKey, sighash, RedeemInfo.P2wsh(redeemScript), extraUtxos = Map.empty)
witnessClaimHtlcSuccessFromCommitTx(sig, preimage, redeemScript)
@@ -822,7 +790,7 @@ object Transactions {
override def sign(): Transaction = {
// Note that in/out HTLCs are inverted in the remote commitment: from their point of view it's a received (incoming) HTLC.
val witness = commitmentFormat match {
- case DefaultCommitmentFormat | _: AnchorOutputsCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
val redeemScript = Script.write(htlcReceived(commitKeys.publicKeys, paymentHash, htlcExpiry, commitmentFormat))
val sig = sign(commitKeys.ourHtlcKey, sighash, RedeemInfo.P2wsh(redeemScript), extraUtxos = Map.empty)
witnessClaimHtlcTimeoutFromCommitTx(sig, redeemScript)
@@ -882,7 +850,7 @@ object Transactions {
object ClaimAnchorTx {
def redeemInfo(fundingKey: PublicKey, paymentKey: PublicKey, commitmentFormat: CommitmentFormat): RedeemInfo = {
commitmentFormat match {
- case DefaultCommitmentFormat | _: AnchorOutputsCommitmentFormat => RedeemInfo.P2wsh(anchor(fundingKey))
+ case _: AnchorOutputsCommitmentFormat => RedeemInfo.P2wsh(anchor(fundingKey))
case _: SimpleTaprootChannelCommitmentFormat => RedeemInfo.TaprootKeyPath(paymentKey.xOnly, Some(Taproot.anchorScriptTree))
}
}
@@ -905,7 +873,7 @@ object Transactions {
override def sign(walletInputs: WalletInputs): Transaction = {
val toSign = copy(tx = setWalletInputs(walletInputs))
val witness = commitmentFormat match {
- case DefaultCommitmentFormat | _: AnchorOutputsCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
val redeemScript = Script.write(anchor(fundingKey.publicKey))
val sig = toSign.sign(fundingKey, sighash, RedeemInfo.P2wsh(redeemScript), walletInputs.spentUtxos)
witnessAnchor(sig, redeemScript)
@@ -942,14 +910,13 @@ object Transactions {
override def sign(walletInputs: WalletInputs): Transaction = {
val toSign = copy(tx = setWalletInputs(walletInputs))
val witness = commitmentFormat match {
- case DefaultCommitmentFormat | _: AnchorOutputsCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
val redeemScript = Script.write(anchor(fundingKey.publicKey))
val sig = toSign.sign(fundingKey, sighash, RedeemInfo.P2wsh(redeemScript), walletInputs.spentUtxos)
witnessAnchor(sig, redeemScript)
case _: SimpleTaprootChannelCommitmentFormat =>
- val Right(anchorKey) = commitKeys.ourPaymentKey
- val redeemInfo = RedeemInfo.TaprootKeyPath(anchorKey.xOnlyPublicKey(), Some(Taproot.anchorScriptTree))
- val sig = toSign.sign(anchorKey, sighash, redeemInfo, walletInputs.spentUtxos)
+ val redeemInfo = RedeemInfo.TaprootKeyPath(commitKeys.ourPaymentKey.xOnlyPublicKey(), Some(Taproot.anchorScriptTree))
+ val sig = toSign.sign(commitKeys.ourPaymentKey, sighash, redeemInfo, walletInputs.spentUtxos)
Script.witnessKeyPathPay2tr(sig)
}
toSign.tx.updateWitness(toSign.inputIndex, witness)
@@ -971,62 +938,21 @@ object Transactions {
}
}
- sealed trait ClaimRemoteCommitMainOutputTx extends RemoteCommitForceCloseTransaction
-
- /** This transaction claims our main balance from the remote commitment without any delay, when using the [[DefaultCommitmentFormat]]. */
- case class ClaimP2WPKHOutputTx(commitKeys: RemoteCommitmentKeys, input: InputInfo, tx: Transaction, commitmentFormat: CommitmentFormat) extends ClaimRemoteCommitMainOutputTx {
- override val desc: String = "remote-main"
- override val expectedWeight: Int = commitmentFormat.toRemoteWeight
-
- override def sign(): Transaction = {
- val Right(paymentKey) = commitKeys.ourPaymentKey
- val redeemInfo = RedeemInfo.P2wpkh(paymentKey.publicKey)
- val sig = sign(paymentKey, sighash, redeemInfo, extraUtxos = Map.empty)
- val witness = Script.witnessPay2wpkh(paymentKey.publicKey, der(sig))
- tx.updateWitness(inputIndex, witness)
- }
- }
-
- object ClaimP2WPKHOutputTx {
- def createUnsignedTx(commitKeys: RemoteCommitmentKeys, commitTx: Transaction, localDustLimit: Satoshi, localFinalScriptPubKey: ByteVector, feerate: FeeratePerKw, commitmentFormat: CommitmentFormat): Either[TxGenerationSkipped, ClaimP2WPKHOutputTx] = {
- val redeemInfo = RedeemInfo.P2wpkh(commitKeys.ourPaymentPublicKey)
- findPubKeyScriptIndex(commitTx, redeemInfo.pubkeyScript) match {
- case Left(skip) => Left(skip)
- case Right(outputIndex) =>
- commitKeys.ourPaymentKey match {
- case Left(_) => Left(OutputAlreadyInWallet)
- case Right(_) =>
- val input = InputInfo(OutPoint(commitTx, outputIndex), commitTx.txOut(outputIndex))
- val amount = input.txOut.amount - weight2fee(feerate, commitmentFormat.toRemoteWeight)
- val tx = Transaction(
- version = 2,
- txIn = TxIn(input.outPoint, ByteVector.empty, 0) :: Nil,
- txOut = TxOut(amount, localFinalScriptPubKey) :: Nil,
- lockTime = 0
- )
- val unsignedTx = ClaimP2WPKHOutputTx(commitKeys, input, tx, commitmentFormat)
- skipTxIfBelowDust(unsignedTx, localDustLimit)
- }
- }
- }
- }
-
/** This transaction spends our main balance from the remote commitment with a 1-block relative delay. */
- case class ClaimRemoteDelayedOutputTx(commitKeys: RemoteCommitmentKeys, input: InputInfo, tx: Transaction, commitmentFormat: CommitmentFormat) extends ClaimRemoteCommitMainOutputTx {
+ case class ClaimRemoteDelayedOutputTx(commitKeys: RemoteCommitmentKeys, input: InputInfo, tx: Transaction, commitmentFormat: CommitmentFormat) extends RemoteCommitForceCloseTransaction {
override val desc: String = "remote-main-delayed"
override val expectedWeight: Int = commitmentFormat.toRemoteWeight
override def sign(): Transaction = {
- val Right(paymentKey) = commitKeys.ourPaymentKey
val witness = commitmentFormat match {
- case DefaultCommitmentFormat | _: AnchorOutputsCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
val redeemScript = Script.write(toRemoteDelayed(commitKeys.publicKeys))
- val sig = sign(paymentKey, sighash, RedeemInfo.P2wsh(redeemScript), extraUtxos = Map.empty)
+ val sig = sign(commitKeys.ourPaymentKey, sighash, RedeemInfo.P2wsh(redeemScript), extraUtxos = Map.empty)
witnessClaimToRemoteDelayedFromCommitTx(sig, redeemScript)
case _: SimpleTaprootChannelCommitmentFormat =>
val scriptTree: ScriptTree.Leaf = Taproot.toRemoteScriptTree(commitKeys.publicKeys)
val redeemInfo = RedeemInfo.TaprootScriptPath(NUMS_POINT.xOnly, scriptTree, scriptTree.hash())
- val sig = sign(paymentKey, sighash, redeemInfo, extraUtxos = Map.empty)
+ val sig = sign(commitKeys.ourPaymentKey, sighash, redeemInfo, extraUtxos = Map.empty)
Script.witnessScriptPathPay2tr(redeemInfo.internalKey, scriptTree, ScriptWitness(Seq(sig)), scriptTree)
}
tx.updateWitness(inputIndex, witness)
@@ -1036,7 +962,7 @@ object Transactions {
object ClaimRemoteDelayedOutputTx {
def createUnsignedTx(commitKeys: RemoteCommitmentKeys, commitTx: Transaction, localDustLimit: Satoshi, localFinalScriptPubKey: ByteVector, feerate: FeeratePerKw, commitmentFormat: CommitmentFormat): Either[TxGenerationSkipped, ClaimRemoteDelayedOutputTx] = {
val redeemInfo = commitmentFormat match {
- case DefaultCommitmentFormat | _: AnchorOutputsCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
val redeemScript = Script.write(toRemoteDelayed(commitKeys.publicKeys))
RedeemInfo.P2wsh(redeemScript)
case _: SimpleTaprootChannelCommitmentFormat =>
@@ -1046,20 +972,16 @@ object Transactions {
findPubKeyScriptIndex(commitTx, redeemInfo.pubkeyScript) match {
case Left(skip) => Left(skip)
case Right(outputIndex) =>
- commitKeys.ourPaymentKey match {
- case Left(_) => Left(OutputAlreadyInWallet)
- case Right(_) =>
- val input = InputInfo(OutPoint(commitTx, outputIndex), commitTx.txOut(outputIndex))
- val amount = input.txOut.amount - weight2fee(feerate, commitmentFormat.toRemoteWeight)
- val tx = Transaction(
- version = 2,
- txIn = TxIn(input.outPoint, ByteVector.empty, 1) :: Nil,
- txOut = TxOut(amount, localFinalScriptPubKey) :: Nil,
- lockTime = 0
- )
- val unsignedTx = ClaimRemoteDelayedOutputTx(commitKeys, input, tx, commitmentFormat)
- skipTxIfBelowDust(unsignedTx, localDustLimit)
- }
+ val input = InputInfo(OutPoint(commitTx, outputIndex), commitTx.txOut(outputIndex))
+ val amount = input.txOut.amount - weight2fee(feerate, commitmentFormat.toRemoteWeight)
+ val tx = Transaction(
+ version = 2,
+ txIn = TxIn(input.outPoint, ByteVector.empty, 1) :: Nil,
+ txOut = TxOut(amount, localFinalScriptPubKey) :: Nil,
+ lockTime = 0
+ )
+ val unsignedTx = ClaimRemoteDelayedOutputTx(commitKeys, input, tx, commitmentFormat)
+ skipTxIfBelowDust(unsignedTx, localDustLimit)
}
}
}
@@ -1071,7 +993,7 @@ object Transactions {
override def sign(): Transaction = {
val witness = commitmentFormat match {
- case DefaultCommitmentFormat | _: AnchorOutputsCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
val redeemScript = Script.write(toLocalDelayed(commitKeys.publicKeys, toLocalDelay))
val sig = sign(commitKeys.ourDelayedPaymentKey, sighash, RedeemInfo.P2wsh(redeemScript), extraUtxos = Map.empty)
witnessToLocalDelayedAfterDelay(sig, redeemScript)
@@ -1088,7 +1010,7 @@ object Transactions {
object ClaimLocalDelayedOutputTx {
def createUnsignedTx(commitKeys: LocalCommitmentKeys, commitTx: Transaction, localDustLimit: Satoshi, toLocalDelay: CltvExpiryDelta, localFinalScriptPubKey: ByteVector, feerate: FeeratePerKw, commitmentFormat: CommitmentFormat): Either[TxGenerationSkipped, ClaimLocalDelayedOutputTx] = {
val redeemInfo = commitmentFormat match {
- case DefaultCommitmentFormat | _: AnchorOutputsCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
val redeemScript = Script.write(toLocalDelayed(commitKeys.publicKeys, toLocalDelay))
RedeemInfo.P2wsh(redeemScript)
case _: SimpleTaprootChannelCommitmentFormat =>
@@ -1119,7 +1041,7 @@ object Transactions {
override def sign(): Transaction = {
val witness = commitmentFormat match {
- case DefaultCommitmentFormat | _: AnchorOutputsCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
val redeemScript = Script.write(toLocalDelayed(commitKeys.publicKeys, toRemoteDelay))
val sig = sign(revocationKey, sighash, RedeemInfo.P2wsh(redeemScript), extraUtxos = Map.empty)
Scripts.witnessToLocalDelayedWithRevocationSig(sig, redeemScript)
@@ -1136,7 +1058,7 @@ object Transactions {
object MainPenaltyTx {
def createUnsignedTx(commitKeys: RemoteCommitmentKeys, revocationKey: PrivateKey, commitTx: Transaction, localDustLimit: Satoshi, localFinalScriptPubKey: ByteVector, toRemoteDelay: CltvExpiryDelta, feerate: FeeratePerKw, commitmentFormat: CommitmentFormat): Either[TxGenerationSkipped, MainPenaltyTx] = {
val redeemInfo = commitmentFormat match {
- case DefaultCommitmentFormat | _: AnchorOutputsCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
val redeemScript = Script.write(toLocalDelayed(commitKeys.publicKeys, toRemoteDelay))
RedeemInfo.P2wsh(redeemScript)
case _: SimpleTaprootChannelCommitmentFormat =>
@@ -1171,7 +1093,6 @@ object Transactions {
override def sign(): Transaction = {
val sig = sign(revocationKey, sighash, redeemInfo, extraUtxos = Map.empty)
val witness = redeemInfo match {
- case RedeemInfo.P2wpkh(_) => Script.witnessPay2wpkh(revocationKey.publicKey, der(sig))
case RedeemInfo.P2wsh(redeemScript) => Scripts.witnessHtlcWithRevocationSig(commitKeys, sig, redeemScript)
case _: RedeemInfo.TaprootKeyPath => Script.witnessKeyPathPay2tr(sig, sighash)
case s: RedeemInfo.TaprootScriptPath => Script.witnessScriptPathPay2tr(s.internalKey, s.leaf, ScriptWitness(Seq(sig)), s.scriptTree)
@@ -1194,7 +1115,7 @@ object Transactions {
case (paymentHash, htlcExpiry) =>
// We don't know if this was an incoming or outgoing HTLC, so we try both cases.
val (offered, received) = commitmentFormat match {
- case DefaultCommitmentFormat | _: AnchorOutputsCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
(RedeemInfo.P2wsh(Script.write(htlcOffered(commitKeys.publicKeys, paymentHash, commitmentFormat))),
RedeemInfo.P2wsh(Script.write(htlcReceived(commitKeys.publicKeys, paymentHash, htlcExpiry, commitmentFormat))))
case _: SimpleTaprootChannelCommitmentFormat =>
@@ -1243,7 +1164,7 @@ object Transactions {
override def sign(): Transaction = {
val witness = commitmentFormat match {
- case DefaultCommitmentFormat | _: AnchorOutputsCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
val redeemScript = Script.write(toLocalDelayed(commitKeys.publicKeys, toRemoteDelay))
val sig = sign(revocationKey, sighash, RedeemInfo.P2wsh(redeemScript), extraUtxos = Map.empty)
Scripts.witnessToLocalDelayedWithRevocationSig(sig, redeemScript)
@@ -1266,7 +1187,7 @@ object Transactions {
feerate: FeeratePerKw,
commitmentFormat: CommitmentFormat): Seq[Either[TxGenerationSkipped, ClaimHtlcDelayedOutputPenaltyTx]] = {
val redeemInfo = commitmentFormat match {
- case DefaultCommitmentFormat | _: AnchorOutputsCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
val redeemScript = Script.write(toLocalDelayed(commitKeys.publicKeys, toRemoteDelay))
RedeemInfo.P2wsh(redeemScript)
case _: SimpleTaprootChannelCommitmentFormat =>
@@ -1367,7 +1288,6 @@ object Transactions {
// When using anchor outputs, the channel initiator pays for *both* anchors all the time, even if only one anchor is present.
// This is not technically a fee (it doesn't go to miners) but it also has to be deduced from the channel initiator's main output.
val anchorsCost = commitmentFormat match {
- case DefaultCommitmentFormat => Satoshi(0)
case _: AnchorOutputsCommitmentFormat | _: SimpleTaprootChannelCommitmentFormat => AnchorOutputsCommitmentFormat.anchorAmount * 2
}
txFee + anchorsCost
@@ -1421,7 +1341,6 @@ object Transactions {
def decodeTxNumber(sequence: Long, locktime: Long): Long = ((sequence & 0xffffffL) << 24) + (locktime & 0xffffffL)
private def getHtlcTxInputSequence(commitmentFormat: CommitmentFormat): Long = commitmentFormat match {
- case DefaultCommitmentFormat => 0 // htlc txs immediately spend the commit tx
case _: AnchorOutputsCommitmentFormat | _: SimpleTaprootChannelCommitmentFormat => 1 // htlc txs have a 1-block delay to allow CPFP carve-out on anchors
}
@@ -1461,7 +1380,7 @@ object Transactions {
if (toLocalAmount >= dustLimit) {
val redeemInfo = commitmentFormat match {
- case _: AnchorOutputsCommitmentFormat | DefaultCommitmentFormat =>
+ case _: AnchorOutputsCommitmentFormat =>
RedeemInfo.P2wsh(toLocalDelayed(commitmentKeys, toSelfDelay))
case _: SimpleTaprootChannelCommitmentFormat =>
val toLocalTree = Taproot.toLocalScriptTree(commitmentKeys, toSelfDelay)
@@ -1472,8 +1391,6 @@ object Transactions {
if (toRemoteAmount >= dustLimit) {
val redeemInfo = commitmentFormat match {
- case DefaultCommitmentFormat =>
- RedeemInfo.P2wpkh(commitmentKeys.remotePaymentPublicKey)
case _: AnchorOutputsCommitmentFormat =>
RedeemInfo.P2wsh(toRemoteDelayed(commitmentKeys))
case _: SimpleTaprootChannelCommitmentFormat =>
@@ -1484,7 +1401,6 @@ object Transactions {
}
commitmentFormat match {
- case DefaultCommitmentFormat => ()
case _: AnchorOutputsCommitmentFormat | _: SimpleTaprootChannelCommitmentFormat =>
if (toLocalAmount >= dustLimit || hasHtlcs) {
val redeemInfo = ClaimLocalAnchorTx.redeemInfo(localFundingPublicKey, commitmentKeys, commitmentFormat)
@@ -1649,7 +1565,6 @@ object Transactions {
txInfo match {
case txInfo: ClaimLocalDelayedOutputTx => Right(txInfo.copy(tx = updatedTx))
case txInfo: ClaimRemoteDelayedOutputTx => Right(txInfo.copy(tx = updatedTx))
- case txInfo: ClaimP2WPKHOutputTx => Right(txInfo.copy(tx = updatedTx))
// Anchor transaction don't have any output: wallet inputs must be used to pay fees.
case txInfo: ClaimAnchorTx => Left(CannotUpdateFee(txInfo))
// HTLC transactions are pre-signed, we can't update their fee by lowering the output amount.
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version5/ChannelCodecs5.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version5/ChannelCodecs5.scala
index 657e02d..82a9cd3 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version5/ChannelCodecs5.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version5/ChannelCodecs5.scala
@@ -29,7 +29,7 @@ import fr.acinq.eclair.wire.protocol.{LiquidityAds, UpdateAddHtlc, UpdateMessage
import fr.acinq.eclair.{FeatureSupport, Features, PermanentChannelFeature}
import scodec.bits.{BitVector, ByteVector}
import scodec.codecs._
-import scodec.{Attempt, Codec}
+import scodec.{Attempt, Codec, Err}
/**
* Created by t-bast on 18/06/2025.
@@ -78,11 +78,18 @@ private[channel] object ChannelCodecs5 {
)
private val commitmentFormatCodec: Codec[Transactions.CommitmentFormat] = discriminated[Transactions.CommitmentFormat].by(uint8)
- .typecase(0x00, provide(Transactions.DefaultCommitmentFormat))
.typecase(0x01, provide(Transactions.UnsafeLegacyAnchorOutputsCommitmentFormat))
.typecase(0x02, provide(Transactions.ZeroFeeHtlcTxAnchorOutputsCommitmentFormat))
.typecase(0x03, provide(Transactions.PhoenixSimpleTaprootChannelCommitmentFormat))
.typecase(0x04, provide(Transactions.ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat))
+ // 0x00 was used for pre-anchor channels, which have been deprecated after eclair v0.13.1.
+ .typecase(0x00, fail[Transactions.CommitmentFormat](Err("some of your channels are not using anchor outputs: you must restart with your previous eclair version and close those channels before updating to this version of eclair (see the release notes for more details)")))
+
+ // The walletStaticPaymentBasepoint field was used for static_remotekey channels, which have been deprecated: we can
+ // thus safely ignore that field, and encode as if it wasn't provided.
+ // By keeping this codec, we can potentially re-introduce that field in the future if necessary for future channel
+ // types, without breaking backwards-compatibility.
+ private val ignoreWalletStaticPaymentBasepoint: Codec[Unit] = optional(bool8, publicKey).xmap[Unit](_ => (), _ => None)
private val localChannelParamsCodec: Codec[LocalChannelParams] = (
("nodeId" | publicKey) ::
@@ -91,7 +98,7 @@ private[channel] object ChannelCodecs5 {
// We pad to keep codecs byte-aligned.
("isChannelOpener" | bool) :: ("paysCommitTxFees" | bool) :: ignore(6) ::
("upfrontShutdownScript_opt" | optional(bool8, lengthDelimited(bytes))) ::
- ("walletStaticPaymentBasepoint" | optional(bool8, publicKey)) ::
+ ("walletStaticPaymentBasepoint" | ignoreWalletStaticPaymentBasepoint) ::
("features" | combinedFeaturesCodec)).as[LocalChannelParams]
val remoteChannelParamsCodec: Codec[RemoteChannelParams] = (
diff --git a/eclair-core/src/test/resources/bolt3-tx-test-vectors-default-commitment-format.txt b/eclair-core/src/test/resources/bolt3-tx-test-vectors-default-commitment-format.txt
deleted file mode 100644
index e4c7148..0000000
--- a/eclair-core/src/test/resources/bolt3-tx-test-vectors-default-commitment-format.txt
+++ /dev/null
@@ -1,367 +0,0 @@
- name: simple commitment tx with no HTLCs
- to_local_msat: 7000000000
- to_remote_msat: 3000000000
- local_feerate_per_kw: 15000
- # base commitment transaction fee = 10860
- # actual commitment transaction fee = 10860
- # to_local amount 6989140 wscript 63210212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b1967029000b2752103fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c68ac
- # to_remote amount 3000000 P2WPKH(0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b)
- remote_signature = 3045022100f51d2e566a70ba740fc5d8c0f07b9b93d2ed741c3c0860c613173de7d39e7968022041376d520e9c0e1ad52248ddf4b22e12be8763007df977253ef45a4ca3bdb7c0
- # local_signature = 3044022051b75c73198c6deee1a875871c3961832909acd297c6b908d59e3319e5185a46022055c419379c5051a78d00dbbce11b5b664a0c22815fbcc6fcef6b1937c3836939
- output commit_tx: 02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8002c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de84311054a56a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0400473044022051b75c73198c6deee1a875871c3961832909acd297c6b908d59e3319e5185a46022055c419379c5051a78d00dbbce11b5b664a0c22815fbcc6fcef6b1937c383693901483045022100f51d2e566a70ba740fc5d8c0f07b9b93d2ed741c3c0860c613173de7d39e7968022041376d520e9c0e1ad52248ddf4b22e12be8763007df977253ef45a4ca3bdb7c001475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220
- num_htlcs: 0
-
- name: commitment tx with all five HTLCs untrimmed (minimum feerate)
- to_local_msat: 6988000000
- to_remote_msat: 3000000000
- local_feerate_per_kw: 0
- # base commitment transaction fee = 0
- # actual commitment transaction fee = 0
- # HTLC #2 offered amount 2000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868
- # HTLC #3 offered amount 3000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868
- # HTLC #0 received amount 1000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f401b175ac6868
- # HTLC #1 received amount 2000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac6868
- # HTLC #4 received amount 4000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac6868
- # to_local amount 6988000 wscript 63210212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b1967029000b2752103fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c68ac
- # to_remote amount 3000000 P2WPKH(0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b)
- remote_signature = 304402204fd4928835db1ccdfc40f5c78ce9bd65249b16348df81f0c44328dcdefc97d630220194d3869c38bc732dd87d13d2958015e2fc16829e74cd4377f84d215c0b70606
- # local_signature = 30440220275b0c325a5e9355650dc30c0eccfbc7efb23987c24b556b9dfdd40effca18d202206caceb2c067836c51f296740c7ae807ffcbfbf1dd3a0d56b6de9a5b247985f06
- output commit_tx: 02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8007e80300000000000022002052bfef0479d7b293c27e0f1eb294bea154c63a3294ef092c19af51409bce0e2ad007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5d007000000000000220020748eba944fedc8827f6b06bc44678f93c0f9e6078b35c6331ed31e75f8ce0c2db80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110e0a06a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e04004730440220275b0c325a5e9355650dc30c0eccfbc7efb23987c24b556b9dfdd40effca18d202206caceb2c067836c51f296740c7ae807ffcbfbf1dd3a0d56b6de9a5b247985f060147304402204fd4928835db1ccdfc40f5c78ce9bd65249b16348df81f0c44328dcdefc97d630220194d3869c38bc732dd87d13d2958015e2fc16829e74cd4377f84d215c0b7060601475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220
- num_htlcs: 5
- # signature for output #0 (htlc-success for htlc #0)
- remote_htlc_signature = 304402206a6e59f18764a5bf8d4fa45eebc591566689441229c918b480fb2af8cc6a4aeb02205248f273be447684b33e3c8d1d85a8e0ca9fa0bae9ae33f0527ada9c162919a6
- # local_htlc_signature = 304402207cb324fa0de88f452ffa9389678127ebcf4cabe1dd848b8e076c1a1962bf34720220116ed922b12311bd602d67e60d2529917f21c5b82f25ff6506c0f87886b4dfd5
- htlc_success_tx (htlc #0): 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219700000000000000000001e8030000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402206a6e59f18764a5bf8d4fa45eebc591566689441229c918b480fb2af8cc6a4aeb02205248f273be447684b33e3c8d1d85a8e0ca9fa0bae9ae33f0527ada9c162919a60147304402207cb324fa0de88f452ffa9389678127ebcf4cabe1dd848b8e076c1a1962bf34720220116ed922b12311bd602d67e60d2529917f21c5b82f25ff6506c0f87886b4dfd5012000000000000000000000000000000000000000000000000000000000000000008a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f401b175ac686800000000
- # signature for output #1 (htlc-timeout for htlc #2)
- remote_htlc_signature = 3045022100d5275b3619953cb0c3b5aa577f04bc512380e60fa551762ce3d7a1bb7401cff9022037237ab0dac3fe100cde094e82e2bed9ba0ed1bb40154b48e56aa70f259e608b
- # local_htlc_signature = 3045022100c89172099507ff50f4c925e6c5150e871fb6e83dd73ff9fbb72f6ce829a9633f02203a63821d9162e99f9be712a68f9e589483994feae2661e4546cd5b6cec007be5
- htlc_timeout_tx (htlc #2): 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219701000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d5275b3619953cb0c3b5aa577f04bc512380e60fa551762ce3d7a1bb7401cff9022037237ab0dac3fe100cde094e82e2bed9ba0ed1bb40154b48e56aa70f259e608b01483045022100c89172099507ff50f4c925e6c5150e871fb6e83dd73ff9fbb72f6ce829a9633f02203a63821d9162e99f9be712a68f9e589483994feae2661e4546cd5b6cec007be501008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000
- # signature for output #2 (htlc-success for htlc #1)
- remote_htlc_signature = 304402201b63ec807771baf4fdff523c644080de17f1da478989308ad13a58b51db91d360220568939d38c9ce295adba15665fa68f51d967e8ed14a007b751540a80b325f202
- # local_htlc_signature = 3045022100def389deab09cee69eaa1ec14d9428770e45bcbe9feb46468ecf481371165c2f022015d2e3c46600b2ebba8dcc899768874cc6851fd1ecb3fffd15db1cc3de7e10da
- htlc_success_tx (htlc #1): 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219702000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402201b63ec807771baf4fdff523c644080de17f1da478989308ad13a58b51db91d360220568939d38c9ce295adba15665fa68f51d967e8ed14a007b751540a80b325f20201483045022100def389deab09cee69eaa1ec14d9428770e45bcbe9feb46468ecf481371165c2f022015d2e3c46600b2ebba8dcc899768874cc6851fd1ecb3fffd15db1cc3de7e10da012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000
- # signature for output #3 (htlc-timeout for htlc #3)
- remote_htlc_signature = 3045022100daee1808f9861b6c3ecd14f7b707eca02dd6bdfc714ba2f33bc8cdba507bb182022026654bf8863af77d74f51f4e0b62d461a019561bb12acb120d3f7195d148a554
- # local_htlc_signature = 30440220643aacb19bbb72bd2b635bc3f7375481f5981bace78cdd8319b2988ffcc6704202203d27784ec8ad51ed3bd517a05525a5139bb0b755dd719e0054332d186ac08727
- htlc_timeout_tx (htlc #3): 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219703000000000000000001b80b0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100daee1808f9861b6c3ecd14f7b707eca02dd6bdfc714ba2f33bc8cdba507bb182022026654bf8863af77d74f51f4e0b62d461a019561bb12acb120d3f7195d148a554014730440220643aacb19bbb72bd2b635bc3f7375481f5981bace78cdd8319b2988ffcc6704202203d27784ec8ad51ed3bd517a05525a5139bb0b755dd719e0054332d186ac0872701008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000
- # signature for output #4 (htlc-success for htlc #4)
- remote_htlc_signature = 304402207e0410e45454b0978a623f36a10626ef17b27d9ad44e2760f98cfa3efb37924f0220220bd8acd43ecaa916a80bd4f919c495a2c58982ce7c8625153f8596692a801d
- # local_htlc_signature = 30440220549e80b4496803cbc4a1d09d46df50109f546d43fbbf86cd90b174b1484acd5402205f12a4f995cb9bded597eabfee195a285986aa6d93ae5bb72507ebc6a4e2349e
- htlc_success_tx (htlc #4): 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219704000000000000000001a00f0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402207e0410e45454b0978a623f36a10626ef17b27d9ad44e2760f98cfa3efb37924f0220220bd8acd43ecaa916a80bd4f919c495a2c58982ce7c8625153f8596692a801d014730440220549e80b4496803cbc4a1d09d46df50109f546d43fbbf86cd90b174b1484acd5402205f12a4f995cb9bded597eabfee195a285986aa6d93ae5bb72507ebc6a4e2349e012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000
-
- name: commitment tx with seven outputs untrimmed (maximum feerate)
- to_local_msat: 6988000000
- to_remote_msat: 3000000000
- local_feerate_per_kw: 647
- # base commitment transaction fee = 1024
- # actual commitment transaction fee = 1024
- # HTLC #2 offered amount 2000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868
- # HTLC #3 offered amount 3000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868
- # HTLC #0 received amount 1000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f401b175ac6868
- # HTLC #1 received amount 2000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac6868
- # HTLC #4 received amount 4000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac6868
- # to_local amount 6986976 wscript 63210212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b1967029000b2752103fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c68ac
- # to_remote amount 3000000 P2WPKH(0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b)
- remote_signature = 3045022100a5c01383d3ec646d97e40f44318d49def817fcd61a0ef18008a665b3e151785502203e648efddd5838981ef55ec954be69c4a652d021e6081a100d034de366815e9b
- # local_signature = 304502210094bfd8f5572ac0157ec76a9551b6c5216a4538c07cd13a51af4a54cb26fa14320220768efce8ce6f4a5efac875142ff19237c011343670adf9c7ac69704a120d1163
- output commit_tx: 02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8007e80300000000000022002052bfef0479d7b293c27e0f1eb294bea154c63a3294ef092c19af51409bce0e2ad007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5d007000000000000220020748eba944fedc8827f6b06bc44678f93c0f9e6078b35c6331ed31e75f8ce0c2db80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110e09c6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040048304502210094bfd8f5572ac0157ec76a9551b6c5216a4538c07cd13a51af4a54cb26fa14320220768efce8ce6f4a5efac875142ff19237c011343670adf9c7ac69704a120d116301483045022100a5c01383d3ec646d97e40f44318d49def817fcd61a0ef18008a665b3e151785502203e648efddd5838981ef55ec954be69c4a652d021e6081a100d034de366815e9b01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220
- num_htlcs: 5
- # signature for output #0 (htlc-success for htlc #0)
- remote_htlc_signature = 30440220385a5afe75632f50128cbb029ee95c80156b5b4744beddc729ad339c9ca432c802202ba5f48550cad3379ac75b9b4fedb86a35baa6947f16ba5037fb8b11ab343740
- # local_htlc_signature = 304402205999590b8a79fa346e003a68fd40366397119b2b0cdf37b149968d6bc6fbcc4702202b1e1fb5ab7864931caed4e732c359e0fe3d86a548b557be2246efb1708d579a
- htlc_success_tx (htlc #0): 020000000001018323148ce2419f21ca3d6780053747715832e18ac780931a514b187768882bb60000000000000000000122020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004730440220385a5afe75632f50128cbb029ee95c80156b5b4744beddc729ad339c9ca432c802202ba5f48550cad3379ac75b9b4fedb86a35baa6947f16ba5037fb8b11ab3437400147304402205999590b8a79fa346e003a68fd40366397119b2b0cdf37b149968d6bc6fbcc4702202b1e1fb5ab7864931caed4e732c359e0fe3d86a548b557be2246efb1708d579a012000000000000000000000000000000000000000000000000000000000000000008a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f401b175ac686800000000
- # signature for output #1 (htlc-timeout for htlc #2)
- remote_htlc_signature = 304402207ceb6678d4db33d2401fdc409959e57c16a6cb97a30261d9c61f29b8c58d34b90220084b4a17b4ca0e86f2d798b3698ca52de5621f2ce86f80bed79afa66874511b0
- # local_htlc_signature = 304402207ff03eb0127fc7c6cae49cc29e2a586b98d1e8969cf4a17dfa50b9c2647720b902205e2ecfda2252956c0ca32f175080e75e4e390e433feb1f8ce9f2ba55648a1dac
- htlc_timeout_tx (htlc #2): 020000000001018323148ce2419f21ca3d6780053747715832e18ac780931a514b187768882bb60100000000000000000124060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402207ceb6678d4db33d2401fdc409959e57c16a6cb97a30261d9c61f29b8c58d34b90220084b4a17b4ca0e86f2d798b3698ca52de5621f2ce86f80bed79afa66874511b00147304402207ff03eb0127fc7c6cae49cc29e2a586b98d1e8969cf4a17dfa50b9c2647720b902205e2ecfda2252956c0ca32f175080e75e4e390e433feb1f8ce9f2ba55648a1dac01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000
- # signature for output #2 (htlc-success for htlc #1)
- remote_htlc_signature = 304402206a401b29a0dff0d18ec903502c13d83e7ec019450113f4a7655a4ce40d1f65ba0220217723a084e727b6ca0cc8b6c69c014a7e4a01fcdcba3e3993f462a3c574d833
- # local_htlc_signature = 3045022100d50d067ca625d54e62df533a8f9291736678d0b86c28a61bb2a80cf42e702d6e02202373dde7e00218eacdafb9415fe0e1071beec1857d1af3c6a201a44cbc47c877
- htlc_success_tx (htlc #1): 020000000001018323148ce2419f21ca3d6780053747715832e18ac780931a514b187768882bb6020000000000000000010a060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402206a401b29a0dff0d18ec903502c13d83e7ec019450113f4a7655a4ce40d1f65ba0220217723a084e727b6ca0cc8b6c69c014a7e4a01fcdcba3e3993f462a3c574d83301483045022100d50d067ca625d54e62df533a8f9291736678d0b86c28a61bb2a80cf42e702d6e02202373dde7e00218eacdafb9415fe0e1071beec1857d1af3c6a201a44cbc47c877012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000
- # signature for output #3 (htlc-timeout for htlc #3)
- remote_htlc_signature = 30450221009b1c987ba599ee3bde1dbca776b85481d70a78b681a8d84206723e2795c7cac002207aac84ad910f8598c4d1c0ea2e3399cf6627a4e3e90131315bc9f038451ce39d
- # local_htlc_signature = 3045022100db9dc65291077a52728c622987e9895b7241d4394d6dcb916d7600a3e8728c22022036ee3ee717ba0bb5c45ee84bc7bbf85c0f90f26ae4e4a25a6b4241afa8a3f1cb
- htlc_timeout_tx (htlc #3): 020000000001018323148ce2419f21ca3d6780053747715832e18ac780931a514b187768882bb6030000000000000000010c0a0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004830450221009b1c987ba599ee3bde1dbca776b85481d70a78b681a8d84206723e2795c7cac002207aac84ad910f8598c4d1c0ea2e3399cf6627a4e3e90131315bc9f038451ce39d01483045022100db9dc65291077a52728c622987e9895b7241d4394d6dcb916d7600a3e8728c22022036ee3ee717ba0bb5c45ee84bc7bbf85c0f90f26ae4e4a25a6b4241afa8a3f1cb01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000
- # signature for output #4 (htlc-success for htlc #4)
- remote_htlc_signature = 3045022100cc28030b59f0914f45b84caa983b6f8effa900c952310708c2b5b00781117022022027ba2ccdf94d03c6d48b327f183f6e28c8a214d089b9227f94ac4f85315274f0
- # local_htlc_signature = 304402202d1a3c0d31200265d2a2def2753ead4959ae20b4083e19553acfffa5dfab60bf022020ede134149504e15b88ab261a066de49848411e15e70f9e6a5462aec2949f8f
- htlc_success_tx (htlc #4): 020000000001018323148ce2419f21ca3d6780053747715832e18ac780931a514b187768882bb604000000000000000001da0d0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100cc28030b59f0914f45b84caa983b6f8effa900c952310708c2b5b00781117022022027ba2ccdf94d03c6d48b327f183f6e28c8a214d089b9227f94ac4f85315274f00147304402202d1a3c0d31200265d2a2def2753ead4959ae20b4083e19553acfffa5dfab60bf022020ede134149504e15b88ab261a066de49848411e15e70f9e6a5462aec2949f8f012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000
-
- name: commitment tx with six outputs untrimmed (minimum feerate)
- to_local_msat: 6988000000
- to_remote_msat: 3000000000
- local_feerate_per_kw: 648
- # base commitment transaction fee = 914
- # actual commitment transaction fee = 1914
- # HTLC #2 offered amount 2000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868
- # HTLC #3 offered amount 3000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868
- # HTLC #1 received amount 2000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac6868
- # HTLC #4 received amount 4000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac6868
- # to_local amount 6987086 wscript 63210212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b1967029000b2752103fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c68ac
- # to_remote amount 3000000 P2WPKH(0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b)
- remote_signature = 3044022072714e2fbb93cdd1c42eb0828b4f2eff143f717d8f26e79d6ada4f0dcb681bbe02200911be4e5161dd6ebe59ff1c58e1997c4aea804f81db6b698821db6093d7b057
- # local_signature = 3045022100a2270d5950c89ae0841233f6efea9c951898b301b2e89e0adbd2c687b9f32efa02207943d90f95b9610458e7c65a576e149750ff3accaacad004cd85e70b235e27de
- output commit_tx: 02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8006d007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5d007000000000000220020748eba944fedc8827f6b06bc44678f93c0f9e6078b35c6331ed31e75f8ce0c2db80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de8431104e9d6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0400483045022100a2270d5950c89ae0841233f6efea9c951898b301b2e89e0adbd2c687b9f32efa02207943d90f95b9610458e7c65a576e149750ff3accaacad004cd85e70b235e27de01473044022072714e2fbb93cdd1c42eb0828b4f2eff143f717d8f26e79d6ada4f0dcb681bbe02200911be4e5161dd6ebe59ff1c58e1997c4aea804f81db6b698821db6093d7b05701475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220
- num_htlcs: 4
- # signature for output #0 (htlc-timeout for htlc #2)
- remote_htlc_signature = 3044022062ef2e77591409d60d7817d9bb1e71d3c4a2931d1a6c7c8307422c84f001a251022022dad9726b0ae3fe92bda745a06f2c00f92342a186d84518588cf65f4dfaada8
- # local_htlc_signature = 3045022100a4c574f00411dd2f978ca5cdc1b848c311cd7849c087ad2f21a5bce5e8cc5ae90220090ae39a9bce2fb8bc879d7e9f9022df249f41e25e51f1a9bf6447a9eeffc098
- htlc_timeout_tx (htlc #2): 02000000000101579c183eca9e8236a5d7f5dcd79cfec32c497fdc0ec61533cde99ecd436cadd10000000000000000000123060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500473044022062ef2e77591409d60d7817d9bb1e71d3c4a2931d1a6c7c8307422c84f001a251022022dad9726b0ae3fe92bda745a06f2c00f92342a186d84518588cf65f4dfaada801483045022100a4c574f00411dd2f978ca5cdc1b848c311cd7849c087ad2f21a5bce5e8cc5ae90220090ae39a9bce2fb8bc879d7e9f9022df249f41e25e51f1a9bf6447a9eeffc09801008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000
- # signature for output #1 (htlc-success for htlc #1)
- remote_htlc_signature = 3045022100e968cbbb5f402ed389fdc7f6cd2a80ed650bb42c79aeb2a5678444af94f6c78502204b47a1cb24ab5b0b6fe69fe9cfc7dba07b9dd0d8b95f372c1d9435146a88f8d4
- # local_htlc_signature = 304402207679cf19790bea76a733d2fa0672bd43ab455687a068f815a3d237581f57139a0220683a1a799e102071c206b207735ca80f627ab83d6616b4bcd017c5d79ef3e7d0
- htlc_success_tx (htlc #1): 02000000000101579c183eca9e8236a5d7f5dcd79cfec32c497fdc0ec61533cde99ecd436cadd10100000000000000000109060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100e968cbbb5f402ed389fdc7f6cd2a80ed650bb42c79aeb2a5678444af94f6c78502204b47a1cb24ab5b0b6fe69fe9cfc7dba07b9dd0d8b95f372c1d9435146a88f8d40147304402207679cf19790bea76a733d2fa0672bd43ab455687a068f815a3d237581f57139a0220683a1a799e102071c206b207735ca80f627ab83d6616b4bcd017c5d79ef3e7d0012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000
- # signature for output #2 (htlc-timeout for htlc #3)
- remote_htlc_signature = 3045022100aa91932e305292cf9969cc23502bbf6cef83a5df39c95ad04a707c4f4fed5c7702207099fc0f3a9bfe1e7683c0e9aa5e76c5432eb20693bf4cb182f04d383dc9c8c2
- # local_htlc_signature = 304402200df76fea718745f3c529bac7fd37923e7309ce38b25c0781e4cf514dd9ef8dc802204172295739dbae9fe0474dcee3608e3433b4b2af3a2e6787108b02f894dcdda3
- htlc_timeout_tx (htlc #3): 02000000000101579c183eca9e8236a5d7f5dcd79cfec32c497fdc0ec61533cde99ecd436cadd1020000000000000000010b0a0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100aa91932e305292cf9969cc23502bbf6cef83a5df39c95ad04a707c4f4fed5c7702207099fc0f3a9bfe1e7683c0e9aa5e76c5432eb20693bf4cb182f04d383dc9c8c20147304402200df76fea718745f3c529bac7fd37923e7309ce38b25c0781e4cf514dd9ef8dc802204172295739dbae9fe0474dcee3608e3433b4b2af3a2e6787108b02f894dcdda301008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000
- # signature for output #3 (htlc-success for htlc #4)
- remote_htlc_signature = 3044022035cac88040a5bba420b1c4257235d5015309113460bc33f2853cd81ca36e632402202fc94fd3e81e9d34a9d01782a0284f3044370d03d60f3fc041e2da088d2de58f
- # local_htlc_signature = 304402200daf2eb7afd355b4caf6fb08387b5f031940ea29d1a9f35071288a839c9039e4022067201b562456e7948616c13acb876b386b511599b58ac1d94d127f91c50463a6
- htlc_success_tx (htlc #4): 02000000000101579c183eca9e8236a5d7f5dcd79cfec32c497fdc0ec61533cde99ecd436cadd103000000000000000001d90d0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500473044022035cac88040a5bba420b1c4257235d5015309113460bc33f2853cd81ca36e632402202fc94fd3e81e9d34a9d01782a0284f3044370d03d60f3fc041e2da088d2de58f0147304402200daf2eb7afd355b4caf6fb08387b5f031940ea29d1a9f35071288a839c9039e4022067201b562456e7948616c13acb876b386b511599b58ac1d94d127f91c50463a6012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000
-
- name: commitment tx with six outputs untrimmed (maximum feerate)
- to_local_msat: 6988000000
- to_remote_msat: 3000000000
- local_feerate_per_kw: 2069
- # base commitment transaction fee = 2921
- # actual commitment transaction fee = 3921
- # HTLC #2 offered amount 2000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868
- # HTLC #3 offered amount 3000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868
- # HTLC #1 received amount 2000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac6868
- # HTLC #4 received amount 4000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac6868
- # to_local amount 6985079 wscript 63210212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b1967029000b2752103fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c68ac
- # to_remote amount 3000000 P2WPKH(0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b)
- remote_signature = 3044022001d55e488b8b035b2dd29d50b65b530923a416d47f377284145bc8767b1b6a75022019bb53ddfe1cefaf156f924777eaaf8fdca1810695a7d0a247ad2afba8232eb4
- # local_signature = 304402203ca8f31c6a47519f83255dc69f1894d9a6d7476a19f498d31eaf0cd3a85eeb63022026fd92dc752b33905c4c838c528b692a8ad4ced959990b5d5ee2ff940fa90eea
- output commit_tx: 02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8006d007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5d007000000000000220020748eba944fedc8827f6b06bc44678f93c0f9e6078b35c6331ed31e75f8ce0c2db80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de84311077956a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402203ca8f31c6a47519f83255dc69f1894d9a6d7476a19f498d31eaf0cd3a85eeb63022026fd92dc752b33905c4c838c528b692a8ad4ced959990b5d5ee2ff940fa90eea01473044022001d55e488b8b035b2dd29d50b65b530923a416d47f377284145bc8767b1b6a75022019bb53ddfe1cefaf156f924777eaaf8fdca1810695a7d0a247ad2afba8232eb401475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220
- num_htlcs: 4
- # signature for output #0 (htlc-timeout for htlc #2)
- remote_htlc_signature = 3045022100d1cf354de41c1369336cf85b225ed033f1f8982a01be503668df756a7e668b66022001254144fb4d0eecc61908fccc3388891ba17c5d7a1a8c62bdd307e5a513f992
- # local_htlc_signature = 3044022056eb1af429660e45a1b0b66568cb8c4a3aa7e4c9c292d5d6c47f86ebf2c8838f022065c3ac4ebe980ca7a41148569be4ad8751b0a724a41405697ec55035dae66402
- htlc_timeout_tx (htlc #2): 02000000000101ca94a9ad516ebc0c4bdd7b6254871babfa978d5accafb554214137d398bfcf6a0000000000000000000175020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d1cf354de41c1369336cf85b225ed033f1f8982a01be503668df756a7e668b66022001254144fb4d0eecc61908fccc3388891ba17c5d7a1a8c62bdd307e5a513f99201473044022056eb1af429660e45a1b0b66568cb8c4a3aa7e4c9c292d5d6c47f86ebf2c8838f022065c3ac4ebe980ca7a41148569be4ad8751b0a724a41405697ec55035dae6640201008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000
- # signature for output #1 (htlc-success for htlc #1)
- remote_htlc_signature = 3045022100d065569dcb94f090345402736385efeb8ea265131804beac06dd84d15dd2d6880220664feb0b4b2eb985fadb6ec7dc58c9334ea88ce599a9be760554a2d4b3b5d9f4
- # local_htlc_signature = 3045022100914bb232cd4b2690ee3d6cb8c3713c4ac9c4fb925323068d8b07f67c8541f8d9022057152f5f1615b793d2d45aac7518989ae4fe970f28b9b5c77504799d25433f7f
- htlc_success_tx (htlc #1): 02000000000101ca94a9ad516ebc0c4bdd7b6254871babfa978d5accafb554214137d398bfcf6a0100000000000000000122020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d065569dcb94f090345402736385efeb8ea265131804beac06dd84d15dd2d6880220664feb0b4b2eb985fadb6ec7dc58c9334ea88ce599a9be760554a2d4b3b5d9f401483045022100914bb232cd4b2690ee3d6cb8c3713c4ac9c4fb925323068d8b07f67c8541f8d9022057152f5f1615b793d2d45aac7518989ae4fe970f28b9b5c77504799d25433f7f012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000
- # signature for output #2 (htlc-timeout for htlc #3)
- remote_htlc_signature = 3045022100d4e69d363de993684eae7b37853c40722a4c1b4a7b588ad7b5d8a9b5006137a102207a069c628170ee34be5612747051bdcc087466dbaa68d5756ea81c10155aef18
- # local_htlc_signature = 304402200e362443f7af830b419771e8e1614fc391db3a4eb799989abfc5ab26d6fcd032022039ab0cad1c14dfbe9446bf847965e56fe016e0cbcf719fd18c1bfbf53ecbd9f9
- htlc_timeout_tx (htlc #3): 02000000000101ca94a9ad516ebc0c4bdd7b6254871babfa978d5accafb554214137d398bfcf6a020000000000000000015d060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d4e69d363de993684eae7b37853c40722a4c1b4a7b588ad7b5d8a9b5006137a102207a069c628170ee34be5612747051bdcc087466dbaa68d5756ea81c10155aef180147304402200e362443f7af830b419771e8e1614fc391db3a4eb799989abfc5ab26d6fcd032022039ab0cad1c14dfbe9446bf847965e56fe016e0cbcf719fd18c1bfbf53ecbd9f901008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000
- # signature for output #3 (htlc-success for htlc #4)
- remote_htlc_signature = 30450221008ec888e36e4a4b3dc2ed6b823319855b2ae03006ca6ae0d9aa7e24bfc1d6f07102203b0f78885472a67ff4fe5916c0bb669487d659527509516fc3a08e87a2cc0a7c
- # local_htlc_signature = 304402202c3e14282b84b02705dfd00a6da396c9fe8a8bcb1d3fdb4b20a4feba09440e8b02202b058b39aa9b0c865b22095edcd9ff1f71bbfe20aa4993755e54d042755ed0d5
- htlc_success_tx (htlc #4): 02000000000101ca94a9ad516ebc0c4bdd7b6254871babfa978d5accafb554214137d398bfcf6a03000000000000000001f2090000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004830450221008ec888e36e4a4b3dc2ed6b823319855b2ae03006ca6ae0d9aa7e24bfc1d6f07102203b0f78885472a67ff4fe5916c0bb669487d659527509516fc3a08e87a2cc0a7c0147304402202c3e14282b84b02705dfd00a6da396c9fe8a8bcb1d3fdb4b20a4feba09440e8b02202b058b39aa9b0c865b22095edcd9ff1f71bbfe20aa4993755e54d042755ed0d5012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000
-
- name: commitment tx with five outputs untrimmed (minimum feerate)
- to_local_msat: 6988000000
- to_remote_msat: 3000000000
- local_feerate_per_kw: 2070
- # base commitment transaction fee = 2566
- # actual commitment transaction fee = 5566
- # HTLC #2 offered amount 2000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868
- # HTLC #3 offered amount 3000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868
- # HTLC #4 received amount 4000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac6868
- # to_local amount 6985434 wscript 63210212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b1967029000b2752103fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c68ac
- # to_remote amount 3000000 P2WPKH(0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b)
- remote_signature = 3045022100f2377f7a67b7fc7f4e2c0c9e3a7de935c32417f5668eda31ea1db401b7dc53030220415fdbc8e91d0f735e70c21952342742e25249b0d062d43efbfc564499f37526
- # local_signature = 30440220443cb07f650aebbba14b8bc8d81e096712590f524c5991ac0ed3bbc8fd3bd0c7022028a635f548e3ca64b19b69b1ea00f05b22752f91daf0b6dab78e62ba52eb7fd0
- output commit_tx: 02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8005d007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5b80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110da966a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e04004730440220443cb07f650aebbba14b8bc8d81e096712590f524c5991ac0ed3bbc8fd3bd0c7022028a635f548e3ca64b19b69b1ea00f05b22752f91daf0b6dab78e62ba52eb7fd001483045022100f2377f7a67b7fc7f4e2c0c9e3a7de935c32417f5668eda31ea1db401b7dc53030220415fdbc8e91d0f735e70c21952342742e25249b0d062d43efbfc564499f3752601475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220
- num_htlcs: 3
- # signature for output #0 (htlc-timeout for htlc #2)
- remote_htlc_signature = 3045022100eed143b1ee4bed5dc3cde40afa5db3e7354cbf9c44054b5f713f729356f08cf7022077161d171c2bbd9badf3c9934de65a4918de03bbac1450f715275f75b103f891
- # local_htlc_signature = 3045022100a0d043ed533e7fb1911e0553d31a8e2f3e6de19dbc035257f29d747c5e02f1f5022030cd38d8e84282175d49c1ebe0470db3ebd59768cf40780a784e248a43904fb8
- htlc_timeout_tx (htlc #2): 0200000000010140a83ce364747ff277f4d7595d8d15f708418798922c40bc2b056aca5485a2180000000000000000000174020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100eed143b1ee4bed5dc3cde40afa5db3e7354cbf9c44054b5f713f729356f08cf7022077161d171c2bbd9badf3c9934de65a4918de03bbac1450f715275f75b103f89101483045022100a0d043ed533e7fb1911e0553d31a8e2f3e6de19dbc035257f29d747c5e02f1f5022030cd38d8e84282175d49c1ebe0470db3ebd59768cf40780a784e248a43904fb801008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000
- # signature for output #1 (htlc-timeout for htlc #3)
- remote_htlc_signature = 3044022071e9357619fd8d29a411dc053b326a5224c5d11268070e88ecb981b174747c7a02202b763ae29a9d0732fa8836dd8597439460b50472183f420021b768981b4f7cf6
- # local_htlc_signature = 3045022100adb1d679f65f96178b59f23ed37d3b70443118f345224a07ecb043eee2acc157022034d24524fe857144a3bcfff3065a9994d0a6ec5f11c681e49431d573e242612d
- htlc_timeout_tx (htlc #3): 0200000000010140a83ce364747ff277f4d7595d8d15f708418798922c40bc2b056aca5485a218010000000000000000015c060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500473044022071e9357619fd8d29a411dc053b326a5224c5d11268070e88ecb981b174747c7a02202b763ae29a9d0732fa8836dd8597439460b50472183f420021b768981b4f7cf601483045022100adb1d679f65f96178b59f23ed37d3b70443118f345224a07ecb043eee2acc157022034d24524fe857144a3bcfff3065a9994d0a6ec5f11c681e49431d573e242612d01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000
- # signature for output #2 (htlc-success for htlc #4)
- remote_htlc_signature = 3045022100c9458a4d2cbb741705577deb0a890e5cb90ee141be0400d3162e533727c9cb2102206edcf765c5dc5e5f9b976ea8149bf8607b5a0efb30691138e1231302b640d2a4
- # local_htlc_signature = 304402200831422aa4e1ee6d55e0b894201770a8f8817a189356f2d70be76633ffa6a6f602200dd1b84a4855dc6727dd46c98daae43dfc70889d1ba7ef0087529a57c06e5e04
- htlc_success_tx (htlc #4): 0200000000010140a83ce364747ff277f4d7595d8d15f708418798922c40bc2b056aca5485a21802000000000000000001f1090000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100c9458a4d2cbb741705577deb0a890e5cb90ee141be0400d3162e533727c9cb2102206edcf765c5dc5e5f9b976ea8149bf8607b5a0efb30691138e1231302b640d2a40147304402200831422aa4e1ee6d55e0b894201770a8f8817a189356f2d70be76633ffa6a6f602200dd1b84a4855dc6727dd46c98daae43dfc70889d1ba7ef0087529a57c06e5e04012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000
-
- name: commitment tx with five outputs untrimmed (maximum feerate)
- to_local_msat: 6988000000
- to_remote_msat: 3000000000
- local_feerate_per_kw: 2194
- # base commitment transaction fee = 2720
- # actual commitment transaction fee = 5720
- # HTLC #2 offered amount 2000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868
- # HTLC #3 offered amount 3000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868
- # HTLC #4 received amount 4000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac6868
- # to_local amount 6985280 wscript 63210212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b1967029000b2752103fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c68ac
- # to_remote amount 3000000 P2WPKH(0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b)
- remote_signature = 3045022100d33c4e541aa1d255d41ea9a3b443b3b822ad8f7f86862638aac1f69f8f760577022007e2a18e6931ce3d3a804b1c78eda1de17dbe1fb7a95488c9a4ec86203953348
- # local_signature = 304402203b1b010c109c2ecbe7feb2d259b9c4126bd5dc99ee693c422ec0a5781fe161ba0220571fe4e2c649dea9c7aaf7e49b382962f6a3494963c97d80fef9a430ca3f7061
- output commit_tx: 02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8005d007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5b80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de84311040966a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402203b1b010c109c2ecbe7feb2d259b9c4126bd5dc99ee693c422ec0a5781fe161ba0220571fe4e2c649dea9c7aaf7e49b382962f6a3494963c97d80fef9a430ca3f706101483045022100d33c4e541aa1d255d41ea9a3b443b3b822ad8f7f86862638aac1f69f8f760577022007e2a18e6931ce3d3a804b1c78eda1de17dbe1fb7a95488c9a4ec8620395334801475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220
- num_htlcs: 3
- # signature for output #0 (htlc-timeout for htlc #2)
- remote_htlc_signature = 30450221009ed2f0a67f99e29c3c8cf45c08207b765980697781bb727fe0b1416de0e7622902206052684229bc171419ed290f4b615c943f819c0262414e43c5b91dcf72ddcf44
- # local_htlc_signature = 3044022004ad5f04ae69c71b3b141d4db9d0d4c38d84009fb3cfeeae6efdad414487a9a0022042d3fe1388c1ff517d1da7fb4025663d372c14728ed52dc88608363450ff6a2f
- htlc_timeout_tx (htlc #2): 02000000000101fb824d4e4dafc0f567789dee3a6bce8d411fe80f5563d8cdfdcc7d7e4447d43a0000000000000000000122020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004830450221009ed2f0a67f99e29c3c8cf45c08207b765980697781bb727fe0b1416de0e7622902206052684229bc171419ed290f4b615c943f819c0262414e43c5b91dcf72ddcf4401473044022004ad5f04ae69c71b3b141d4db9d0d4c38d84009fb3cfeeae6efdad414487a9a0022042d3fe1388c1ff517d1da7fb4025663d372c14728ed52dc88608363450ff6a2f01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000
- # signature for output #1 (htlc-timeout for htlc #3)
- remote_htlc_signature = 30440220155d3b90c67c33a8321996a9be5b82431b0c126613be751d400669da9d5c696702204318448bcd48824439d2c6a70be6e5747446be47ff45977cf41672bdc9b6b12d
- # local_htlc_signature = 304402201707050c870c1f77cc3ed58d6d71bf281de239e9eabd8ef0955bad0d7fe38dcc02204d36d80d0019b3a71e646a08fa4a5607761d341ae8be371946ebe437c289c915
- htlc_timeout_tx (htlc #3): 02000000000101fb824d4e4dafc0f567789dee3a6bce8d411fe80f5563d8cdfdcc7d7e4447d43a010000000000000000010a060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004730440220155d3b90c67c33a8321996a9be5b82431b0c126613be751d400669da9d5c696702204318448bcd48824439d2c6a70be6e5747446be47ff45977cf41672bdc9b6b12d0147304402201707050c870c1f77cc3ed58d6d71bf281de239e9eabd8ef0955bad0d7fe38dcc02204d36d80d0019b3a71e646a08fa4a5607761d341ae8be371946ebe437c289c91501008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000
- # signature for output #2 (htlc-success for htlc #4)
- remote_htlc_signature = 3045022100a12a9a473ece548584aabdd051779025a5ed4077c4b7aa376ec7a0b1645e5a48022039490b333f53b5b3e2ddde1d809e492cba2b3e5fc3a436cd3ffb4cd3d500fa5a
- # local_htlc_signature = 3045022100ff200bc934ab26ce9a559e998ceb0aee53bc40368e114ab9d3054d9960546e2802202496856ca163ac12c143110b6b3ac9d598df7254f2e17b3b94c3ab5301f4c3b0
- htlc_success_tx (htlc #4): 02000000000101fb824d4e4dafc0f567789dee3a6bce8d411fe80f5563d8cdfdcc7d7e4447d43a020000000000000000019a090000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100a12a9a473ece548584aabdd051779025a5ed4077c4b7aa376ec7a0b1645e5a48022039490b333f53b5b3e2ddde1d809e492cba2b3e5fc3a436cd3ffb4cd3d500fa5a01483045022100ff200bc934ab26ce9a559e998ceb0aee53bc40368e114ab9d3054d9960546e2802202496856ca163ac12c143110b6b3ac9d598df7254f2e17b3b94c3ab5301f4c3b0012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000
-
- name: commitment tx with four outputs untrimmed (minimum feerate)
- to_local_msat: 6988000000
- to_remote_msat: 3000000000
- local_feerate_per_kw: 2195
- # base commitment transaction fee = 2344
- # actual commitment transaction fee = 7344
- # HTLC #3 offered amount 3000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868
- # HTLC #4 received amount 4000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac6868
- # to_local amount 6985656 wscript 63210212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b1967029000b2752103fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c68ac
- # to_remote amount 3000000 P2WPKH(0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b)
- remote_signature = 304402205e2f76d4657fb732c0dfc820a18a7301e368f5799e06b7828007633741bda6df0220458009ae59d0c6246065c419359e05eb2a4b4ef4a1b310cc912db44eb7924298
- # local_signature = 304402203b12d44254244b8ff3bb4129b0920fd45120ab42f553d9976394b099d500c99e02205e95bb7a3164852ef0c48f9e0eaf145218f8e2c41251b231f03cbdc4f29a5429
- output commit_tx: 02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8004b80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110b8976a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402203b12d44254244b8ff3bb4129b0920fd45120ab42f553d9976394b099d500c99e02205e95bb7a3164852ef0c48f9e0eaf145218f8e2c41251b231f03cbdc4f29a54290147304402205e2f76d4657fb732c0dfc820a18a7301e368f5799e06b7828007633741bda6df0220458009ae59d0c6246065c419359e05eb2a4b4ef4a1b310cc912db44eb792429801475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220
- num_htlcs: 2
- # signature for output #0 (htlc-timeout for htlc #3)
- remote_htlc_signature = 3045022100a8a78fa1016a5c5c3704f2e8908715a3cef66723fb95f3132ec4d2d05cd84fb4022025ac49287b0861ec21932405f5600cbce94313dbde0e6c5d5af1b3366d8afbfc
- # local_htlc_signature = 3045022100be6ae1977fd7b630a53623f3f25c542317ccfc2b971782802a4f1ef538eb22b402207edc4d0408f8f38fd3c7365d1cfc26511b7cd2d4fecd8b005fba3cd5bc704390
- htlc_timeout_tx (htlc #3): 020000000001014e16c488fa158431c1a82e8f661240ec0a71ba0ce92f2721a6538c510226ad5c0000000000000000000109060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100a8a78fa1016a5c5c3704f2e8908715a3cef66723fb95f3132ec4d2d05cd84fb4022025ac49287b0861ec21932405f5600cbce94313dbde0e6c5d5af1b3366d8afbfc01483045022100be6ae1977fd7b630a53623f3f25c542317ccfc2b971782802a4f1ef538eb22b402207edc4d0408f8f38fd3c7365d1cfc26511b7cd2d4fecd8b005fba3cd5bc70439001008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000
- # signature for output #1 (htlc-success for htlc #4)
- remote_htlc_signature = 3045022100e769cb156aa2f7515d126cef7a69968629620ce82afcaa9e210969de6850df4602200b16b3f3486a229a48aadde520dbee31ae340dbadaffae74fbb56681fef27b92
- # local_htlc_signature = 30440220665b9cb4a978c09d1ca8977a534999bc8a49da624d0c5439451dd69cde1a003d022070eae0620f01f3c1bd029cc1488da13fb40fdab76f396ccd335479a11c5276d8
- htlc_success_tx (htlc #4): 020000000001014e16c488fa158431c1a82e8f661240ec0a71ba0ce92f2721a6538c510226ad5c0100000000000000000199090000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100e769cb156aa2f7515d126cef7a69968629620ce82afcaa9e210969de6850df4602200b16b3f3486a229a48aadde520dbee31ae340dbadaffae74fbb56681fef27b92014730440220665b9cb4a978c09d1ca8977a534999bc8a49da624d0c5439451dd69cde1a003d022070eae0620f01f3c1bd029cc1488da13fb40fdab76f396ccd335479a11c5276d8012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000
-
- name: commitment tx with four outputs untrimmed (maximum feerate)
- to_local_msat: 6988000000
- to_remote_msat: 3000000000
- local_feerate_per_kw: 3702
- # base commitment transaction fee = 3953
- # actual commitment transaction fee = 8953
- # HTLC #3 offered amount 3000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868
- # HTLC #4 received amount 4000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac6868
- # to_local amount 6984047 wscript 63210212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b1967029000b2752103fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c68ac
- # to_remote amount 3000000 P2WPKH(0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b)
- remote_signature = 3045022100c1a3b0b60ca092ed5080121f26a74a20cec6bdee3f8e47bae973fcdceb3eda5502207d467a9873c939bf3aa758014ae67295fedbca52412633f7e5b2670fc7c381c1
- # local_signature = 304402200e930a43c7951162dc15a2b7344f48091c74c70f7024e7116e900d8bcfba861c022066fa6cbda3929e21daa2e7e16a4b948db7e8919ef978402360d1095ffdaff7b0
- output commit_tx: 02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8004b80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de8431106f916a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402200e930a43c7951162dc15a2b7344f48091c74c70f7024e7116e900d8bcfba861c022066fa6cbda3929e21daa2e7e16a4b948db7e8919ef978402360d1095ffdaff7b001483045022100c1a3b0b60ca092ed5080121f26a74a20cec6bdee3f8e47bae973fcdceb3eda5502207d467a9873c939bf3aa758014ae67295fedbca52412633f7e5b2670fc7c381c101475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220
- num_htlcs: 2
- # signature for output #0 (htlc-timeout for htlc #3)
- remote_htlc_signature = 3045022100dfb73b4fe961b31a859b2bb1f4f15cabab9265016dd0272323dc6a9e85885c54022059a7b87c02861ee70662907f25ce11597d7b68d3399443a831ae40e777b76bdb
- # local_htlc_signature = 304402202765b9c9ece4f127fa5407faf66da4c5ce2719cdbe47cd3175fc7d48b482e43d02205605125925e07bad1e41c618a4b434d72c88a164981c4b8af5eaf4ee9142ec3a
- htlc_timeout_tx (htlc #3): 02000000000101b8de11eb51c22498fe39722c7227b6e55ff1a94146cf638458cb9bc6a060d3a30000000000000000000122020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100dfb73b4fe961b31a859b2bb1f4f15cabab9265016dd0272323dc6a9e85885c54022059a7b87c02861ee70662907f25ce11597d7b68d3399443a831ae40e777b76bdb0147304402202765b9c9ece4f127fa5407faf66da4c5ce2719cdbe47cd3175fc7d48b482e43d02205605125925e07bad1e41c618a4b434d72c88a164981c4b8af5eaf4ee9142ec3a01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000
- # signature for output #1 (htlc-success for htlc #4)
- remote_htlc_signature = 3045022100ea9dc2a7c3c3640334dab733bb4e036e32a3106dc707b24227874fa4f7da746802204d672f7ac0fe765931a8df10b81e53a3242dd32bd9dc9331eb4a596da87954e9
- # local_htlc_signature = 30440220048a41c660c4841693de037d00a407810389f4574b3286afb7bc392a438fa3f802200401d71fa87c64fe621b49ac07e3bf85157ac680acb977124da28652cc7f1a5c
- htlc_success_tx (htlc #4): 02000000000101b8de11eb51c22498fe39722c7227b6e55ff1a94146cf638458cb9bc6a060d3a30100000000000000000176050000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100ea9dc2a7c3c3640334dab733bb4e036e32a3106dc707b24227874fa4f7da746802204d672f7ac0fe765931a8df10b81e53a3242dd32bd9dc9331eb4a596da87954e9014730440220048a41c660c4841693de037d00a407810389f4574b3286afb7bc392a438fa3f802200401d71fa87c64fe621b49ac07e3bf85157ac680acb977124da28652cc7f1a5c012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000
-
- name: commitment tx with three outputs untrimmed (minimum feerate)
- to_local_msat: 6988000000
- to_remote_msat: 3000000000
- local_feerate_per_kw: 3703
- # base commitment transaction fee = 3317
- # actual commitment transaction fee = 11317
- # HTLC #4 received amount 4000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac6868
- # to_local amount 6984683 wscript 63210212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b1967029000b2752103fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c68ac
- # to_remote amount 3000000 P2WPKH(0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b)
- remote_signature = 30450221008b7c191dd46893b67b628e618d2dc8e81169d38bade310181ab77d7c94c6675e02203b4dd131fd7c9deb299560983dcdc485545c98f989f7ae8180c28289f9e6bdb0
- # local_signature = 3044022047305531dd44391dce03ae20f8735005c615eb077a974edb0059ea1a311857d602202e0ed6972fbdd1e8cb542b06e0929bc41b2ddf236e04cb75edd56151f4197506
- output commit_tx: 02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8003a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110eb936a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0400473044022047305531dd44391dce03ae20f8735005c615eb077a974edb0059ea1a311857d602202e0ed6972fbdd1e8cb542b06e0929bc41b2ddf236e04cb75edd56151f4197506014830450221008b7c191dd46893b67b628e618d2dc8e81169d38bade310181ab77d7c94c6675e02203b4dd131fd7c9deb299560983dcdc485545c98f989f7ae8180c28289f9e6bdb001475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220
- num_htlcs: 1
- # signature for output #0 (htlc-success for htlc #4)
- remote_htlc_signature = 3044022044f65cf833afdcb9d18795ca93f7230005777662539815b8a601eeb3e57129a902206a4bf3e53392affbba52640627defa8dc8af61c958c9e827b2798ab45828abdd
- # local_htlc_signature = 3045022100b94d931a811b32eeb885c28ddcf999ae1981893b21dd1329929543fe87ce793002206370107fdd151c5f2384f9ceb71b3107c69c74c8ed5a28a94a4ab2d27d3b0724
- htlc_success_tx (htlc #4): 020000000001011c076aa7fb3d7460d10df69432c904227ea84bbf3134d4ceee5fb0f135ef206d0000000000000000000175050000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500473044022044f65cf833afdcb9d18795ca93f7230005777662539815b8a601eeb3e57129a902206a4bf3e53392affbba52640627defa8dc8af61c958c9e827b2798ab45828abdd01483045022100b94d931a811b32eeb885c28ddcf999ae1981893b21dd1329929543fe87ce793002206370107fdd151c5f2384f9ceb71b3107c69c74c8ed5a28a94a4ab2d27d3b0724012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000
-
- name: commitment tx with three outputs untrimmed (maximum feerate)
- to_local_msat: 6988000000
- to_remote_msat: 3000000000
- local_feerate_per_kw: 4914
- # base commitment transaction fee = 4402
- # actual commitment transaction fee = 12402
- # HTLC #4 received amount 4000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac6868
- # to_local amount 6983598 wscript 63210212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b1967029000b2752103fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c68ac
- # to_remote amount 3000000 P2WPKH(0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b)
- remote_signature = 304402206d6cb93969d39177a09d5d45b583f34966195b77c7e585cf47ac5cce0c90cefb022031d71ae4e33a4e80df7f981d696fbdee517337806a3c7138b7491e2cbb077a0e
- # local_signature = 304402206a2679efa3c7aaffd2a447fd0df7aba8792858b589750f6a1203f9259173198a022008d52a0e77a99ab533c36206cb15ad7aeb2aa72b93d4b571e728cb5ec2f6fe26
- output commit_tx: 02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8003a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110ae8f6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402206a2679efa3c7aaffd2a447fd0df7aba8792858b589750f6a1203f9259173198a022008d52a0e77a99ab533c36206cb15ad7aeb2aa72b93d4b571e728cb5ec2f6fe260147304402206d6cb93969d39177a09d5d45b583f34966195b77c7e585cf47ac5cce0c90cefb022031d71ae4e33a4e80df7f981d696fbdee517337806a3c7138b7491e2cbb077a0e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220
- num_htlcs: 1
- # signature for output #0 (htlc-success for htlc #4)
- remote_htlc_signature = 3045022100fcb38506bfa11c02874092a843d0cc0a8613c23b639832564a5f69020cb0f6ba02206508b9e91eaa001425c190c68ee5f887e1ad5b1b314002e74db9dbd9e42dbecf
- # local_htlc_signature = 304502210086e76b460ddd3cea10525fba298405d3fe11383e56966a5091811368362f689a02200f72ee75657915e0ede89c28709acd113ede9e1b7be520e3bc5cda425ecd6e68
- htlc_success_tx (htlc #4): 0200000000010110a3fdcbcd5db477cd3ad465e7f501ffa8c437e8301f00a6061138590add757f0000000000000000000122020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100fcb38506bfa11c02874092a843d0cc0a8613c23b639832564a5f69020cb0f6ba02206508b9e91eaa001425c190c68ee5f887e1ad5b1b314002e74db9dbd9e42dbecf0148304502210086e76b460ddd3cea10525fba298405d3fe11383e56966a5091811368362f689a02200f72ee75657915e0ede89c28709acd113ede9e1b7be520e3bc5cda425ecd6e68012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000
-
- name: commitment tx with two outputs untrimmed (minimum feerate)
- to_local_msat: 6988000000
- to_remote_msat: 3000000000
- local_feerate_per_kw: 4915
- # base commitment transaction fee = 3558
- # actual commitment transaction fee = 15558
- # to_local amount 6984442 wscript 63210212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b1967029000b2752103fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c68ac
- # to_remote amount 3000000 P2WPKH(0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b)
- remote_signature = 304402200769ba89c7330dfa4feba447b6e322305f12ac7dac70ec6ba997ed7c1b598d0802204fe8d337e7fee781f9b7b1a06e580b22f4f79d740059560191d7db53f8765552
- # local_signature = 3045022100a012691ba6cea2f73fa8bac37750477e66363c6d28813b0bb6da77c8eb3fb0270220365e99c51304b0b1a6ab9ea1c8500db186693e39ec1ad5743ee231b0138384b9
- output commit_tx: 02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8002c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110fa926a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0400483045022100a012691ba6cea2f73fa8bac37750477e66363c6d28813b0bb6da77c8eb3fb0270220365e99c51304b0b1a6ab9ea1c8500db186693e39ec1ad5743ee231b0138384b90147304402200769ba89c7330dfa4feba447b6e322305f12ac7dac70ec6ba997ed7c1b598d0802204fe8d337e7fee781f9b7b1a06e580b22f4f79d740059560191d7db53f876555201475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220
- num_htlcs: 0
-
- name: commitment tx with two outputs untrimmed (maximum feerate)
- to_local_msat: 6988000000
- to_remote_msat: 3000000000
- local_feerate_per_kw: 9651180
- # base commitment transaction fee = 6987454
- # actual commitment transaction fee = 6999454
- # to_local amount 546 wscript 63210212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b1967029000b2752103fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c68ac
- # to_remote amount 3000000 P2WPKH(0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b)
- remote_signature = 3044022037f83ff00c8e5fb18ae1f918ffc24e54581775a20ff1ae719297ef066c71caa9022039c529cccd89ff6c5ed1db799614533844bd6d101da503761c45c713996e3bbd
- # local_signature = 30440220514f977bf7edc442de8ce43ace9686e5ebdc0f893033f13e40fb46c8b8c6e1f90220188006227d175f5c35da0b092c57bea82537aed89f7778204dc5bacf4f29f2b9
- output commit_tx: 02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b800222020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80ec0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de84311004004730440220514f977bf7edc442de8ce43ace9686e5ebdc0f893033f13e40fb46c8b8c6e1f90220188006227d175f5c35da0b092c57bea82537aed89f7778204dc5bacf4f29f2b901473044022037f83ff00c8e5fb18ae1f918ffc24e54581775a20ff1ae719297ef066c71caa9022039c529cccd89ff6c5ed1db799614533844bd6d101da503761c45c713996e3bbd01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220
- num_htlcs: 0
-
- name: commitment tx with one output untrimmed (minimum feerate)
- to_local_msat: 6988000000
- to_remote_msat: 3000000000
- local_feerate_per_kw: 9651181
- # base commitment transaction fee = 6987455
- # actual commitment transaction fee = 7000000
- # to_remote amount 3000000 P2WPKH(0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b)
- remote_signature = 3044022064901950be922e62cbe3f2ab93de2b99f37cff9fc473e73e394b27f88ef0731d02206d1dfa227527b4df44a07599289e207d6fd9cca60c0365682dcd3deaf739567e
- # local_signature = 3044022031a82b51bd014915fe68928d1abf4b9885353fb896cac10c3fdd88d7f9c7f2e00220716bda819641d2c63e65d3549b6120112e1aeaf1742eed94a471488e79e206b1
- output commit_tx: 02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8001c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de8431100400473044022031a82b51bd014915fe68928d1abf4b9885353fb896cac10c3fdd88d7f9c7f2e00220716bda819641d2c63e65d3549b6120112e1aeaf1742eed94a471488e79e206b101473044022064901950be922e62cbe3f2ab93de2b99f37cff9fc473e73e394b27f88ef0731d02206d1dfa227527b4df44a07599289e207d6fd9cca60c0365682dcd3deaf739567e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220
- num_htlcs: 0
-
- name: commitment tx with fee greater than funder amount
- to_local_msat: 6988000000
- to_remote_msat: 3000000000
- local_feerate_per_kw: 9651936
- # base commitment transaction fee = 6988001
- # actual commitment transaction fee = 7000000
- # to_remote amount 3000000 P2WPKH(0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b)
- remote_signature = 3044022064901950be922e62cbe3f2ab93de2b99f37cff9fc473e73e394b27f88ef0731d02206d1dfa227527b4df44a07599289e207d6fd9cca60c0365682dcd3deaf739567e
- # local_signature = 3044022031a82b51bd014915fe68928d1abf4b9885353fb896cac10c3fdd88d7f9c7f2e00220716bda819641d2c63e65d3549b6120112e1aeaf1742eed94a471488e79e206b1
- output commit_tx: 02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8001c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de8431100400473044022031a82b51bd014915fe68928d1abf4b9885353fb896cac10c3fdd88d7f9c7f2e00220716bda819641d2c63e65d3549b6120112e1aeaf1742eed94a471488e79e206b101473044022064901950be922e62cbe3f2ab93de2b99f37cff9fc473e73e394b27f88ef0731d02206d1dfa227527b4df44a07599289e207d6fd9cca60c0365682dcd3deaf739567e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220
- num_htlcs: 0
-
- name: commitment tx with 3 htlc outputs, 2 offered having the same amount and preimage
- to_local_msat: 6987999999
- to_remote_msat: 3000000000
- local_feerate_per_kw: 253
- # HTLC #1 received amount 2000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac6868
- # HTLC #5 offered amount 5000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9142002cc93ebefbb1b73f0af055dcc27a0b504ad7688ac6868
- # HTLC #6 offered amount 5000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9142002cc93ebefbb1b73f0af055dcc27a0b504ad7688ac6868
- # HTLC #5 and 6 have CLTV 506 and 505, respectively, and preimage 0505050505050505050505050505050505050505050505050505050505050505
- remote_signature = 304402206cda85b2811a211aa70fb74abf23303d87c4355ccf2c2c7954d4137c4fb26a830220719402ab3fef1cbaf42ba42fe437e9bed1e45f84547d603bf7af3fb88f501933
- # local_signature = 3045022100d25455151be075bae8b3400d0825341a3c25a1a5258b84ad2546c09539a83bc602203c1a4ac19c3ac415af7f6a98348f8d7e94fc0ab82dbed54c3c40134f465d027f
- output commit_tx: 02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8005d007000000000000220020748eba944fedc8827f6b06bc44678f93c0f9e6078b35c6331ed31e75f8ce0c2d8813000000000000220020305c12e1a0bc21e283c131cea1c66d68857d28b7b2fce0a6fbc40c164852121b8813000000000000220020305c12e1a0bc21e283c131cea1c66d68857d28b7b2fce0a6fbc40c164852121bc0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110a69f6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0400483045022100d25455151be075bae8b3400d0825341a3c25a1a5258b84ad2546c09539a83bc602203c1a4ac19c3ac415af7f6a98348f8d7e94fc0ab82dbed54c3c40134f465d027f0147304402206cda85b2811a211aa70fb74abf23303d87c4355ccf2c2c7954d4137c4fb26a830220719402ab3fef1cbaf42ba42fe437e9bed1e45f84547d603bf7af3fb88f50193301475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220
- num_htlcs: 3
- # signature for output #0 (htlc-success for htlc #1)
- remote_htlc_signature = 30450221008117770f1d750a8af7a23f27c51a22f66386ea8f074115d0feeac7fe0f077f6102203d4d8dab53ef695b634786224ae5138c81d223b0493fd4637a448e31f734bb30
- # local_htlc_signature = 3045022100f2868e4380ac389960b96a8d01bd0d7ae845d24ad67993f1680e207864d5d3ae0220779ad0a943f73951d628a4f931c3044c51d393de1ab6f8283df41b68485f2b1b
- htlc_success_tx (htlc #1): 0200000000010129253160416b9b2a2ecc303421b7fd1dee52d2e0b08d1a697f3979608334dbb9000000000000000000011f070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004830450221008117770f1d750a8af7a23f27c51a22f66386ea8f074115d0feeac7fe0f077f6102203d4d8dab53ef695b634786224ae5138c81d223b0493fd4637a448e31f734bb3001483045022100f2868e4380ac389960b96a8d01bd0d7ae845d24ad67993f1680e207864d5d3ae0220779ad0a943f73951d628a4f931c3044c51d393de1ab6f8283df41b68485f2b1b012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000
- # signature for output #1 (htlc-timeout for htlc #6)
- remote_htlc_signature = 30440220620b37379e587447e7ee9c8eed9e71b2d2ec29cadc89a4b5411ee6f9b013ca1b02201aaf26d1a03d901425fc44562bff77d5645cb54498e4d9a56c39456825974a3d
- # local_htlc_signature = 304402204db4a1266aa8f0df66d35cd8b4269feef47f1cccebf7fdbb2b64cef35d72d79f022021b6d270a6d623cfec4cd0186096596d8deb17505d8c1c9785c719e0dbfa7e84
- htlc_timeout_tx (htlc #6): 0200000000010129253160416b9b2a2ecc303421b7fd1dee52d2e0b08d1a697f3979608334dbb901000000000000000001e1120000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004730440220620b37379e587447e7ee9c8eed9e71b2d2ec29cadc89a4b5411ee6f9b013ca1b02201aaf26d1a03d901425fc44562bff77d5645cb54498e4d9a56c39456825974a3d0147304402204db4a1266aa8f0df66d35cd8b4269feef47f1cccebf7fdbb2b64cef35d72d79f022021b6d270a6d623cfec4cd0186096596d8deb17505d8c1c9785c719e0dbfa7e8401008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9142002cc93ebefbb1b73f0af055dcc27a0b504ad7688ac6868f9010000
- # signature for output #2 (htlc-timeout for htlc #5)
- remote_htlc_signature = 30450221009353b1d7e6313dc57a3781671b7ed9dde668b30e6f438ff08b13580937264de202200654599d2b9839fe9c88553f7c164a517fc8f0892e942b615460325fee7e0747
- # local_htlc_signature = 3045022100c11a3f26356524b556bdfaeeae80f3cdef2cdb1c42c49047014a56af6916e2cb0220230d0667dc5b86015056a2ae5158ff29cbaf9cde419677e058d23c59a0a07d31
- htlc_timeout_tx (htlc #5): 0200000000010129253160416b9b2a2ecc303421b7fd1dee52d2e0b08d1a697f3979608334dbb902000000000000000001e1120000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004830450221009353b1d7e6313dc57a3781671b7ed9dde668b30e6f438ff08b13580937264de202200654599d2b9839fe9c88553f7c164a517fc8f0892e942b615460325fee7e074701483045022100c11a3f26356524b556bdfaeeae80f3cdef2cdb1c42c49047014a56af6916e2cb0220230d0667dc5b86015056a2ae5158ff29cbaf9cde419677e058d23c59a0a07d3101008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9142002cc93ebefbb1b73f0af055dcc27a0b504ad7688ac6868fa010000
diff --git a/eclair-core/src/test/resources/bolt3-tx-test-vectors-static-remotekey-format.txt b/eclair-core/src/test/resources/bolt3-tx-test-vectors-static-remotekey-format.txt
deleted file mode 100644
index 52a450b..0000000
--- a/eclair-core/src/test/resources/bolt3-tx-test-vectors-static-remotekey-format.txt
+++ /dev/null
@@ -1,367 +0,0 @@
- name: simple commitment tx with no HTLCs
- to_local_msat: 7000000000
- to_remote_msat: 3000000000
- local_feerate_per_kw: 15000
- # base commitment transaction fee = 10860
- # actual commitment transaction fee = 10860
- # to_local amount 6989140 wscript 63210212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b1967029000b2752103fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c68ac
- # to_remote amount 3000000 P2WPKH(032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991)
- remote_signature = 3045022100c3127b33dcc741dd6b05b1e63cbd1a9a7d816f37af9b6756fa2376b056f032370220408b96279808fe57eb7e463710804cdf4f108388bc5cf722d8c848d2c7f9f3b0
- # local_signature = 30440220616210b2cc4d3afb601013c373bbd8aac54febd9f15400379a8cb65ce7deca60022034236c010991beb7ff770510561ae8dc885b8d38d1947248c38f2ae055647142
- output commit_tx: 02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8002c0c62d0000000000160014cc1b07838e387deacd0e5232e1e8b49f4c29e48454a56a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e04004730440220616210b2cc4d3afb601013c373bbd8aac54febd9f15400379a8cb65ce7deca60022034236c010991beb7ff770510561ae8dc885b8d38d1947248c38f2ae05564714201483045022100c3127b33dcc741dd6b05b1e63cbd1a9a7d816f37af9b6756fa2376b056f032370220408b96279808fe57eb7e463710804cdf4f108388bc5cf722d8c848d2c7f9f3b001475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220
- num_htlcs: 0
-
- name: commitment tx with all five HTLCs untrimmed (minimum feerate)
- to_local_msat: 6988000000
- to_remote_msat: 3000000000
- local_feerate_per_kw: 0
- # base commitment transaction fee = 0
- # actual commitment transaction fee = 0
- # HTLC #2 offered amount 2000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868
- # HTLC #3 offered amount 3000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868
- # HTLC #0 received amount 1000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f401b175ac6868
- # HTLC #1 received amount 2000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac6868
- # HTLC #4 received amount 4000 wscript 76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac6868
- # to_local amount 6988000 wscript 63210212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b1967029000b2752103fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c68ac
- # to_remote amount 3000000 P2WPKH(032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991)
- remote_signature = 3044022009b048187705a8cbc9ad73adbe5af148c3d012e1f067961486c822c7af08158c022006d66f3704cfab3eb2dc49dae24e4aa22a6910fc9b424007583204e3621af2e5
- # local_signature = 304402206fc2d1f10ea59951eefac0b4b7c396a3c3d87b71ff0b019796ef4535beaf36f902201765b0181e514d04f4c8ad75659d7037be26cdb3f8bb6f78fe61decef484c3ea
- output commit_tx: 02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8007e80300000000000022002052bfef0479d7b293c27e0f1eb294bea154c63a3294ef092c19af51409bce0e2ad007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5d007000000000000220020748eba944fedc8827f6b06bc44678f93c0f9e6078b35c6331ed31e75f8ce0c2db80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014cc1b07838e387deacd0e5232e1e8b49f4c29e484e0a06a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402206fc2d1f10ea59951eefac0b4b7c396a3c3d87b71ff0b019796ef4535beaf36f902201765b0181e514d04f4c8ad75659d7037be26cdb3f8bb6f78fe61decef484c3ea01473044022009b048187705a8cbc9ad73adbe5af148c3d012e1f067961486c822c7af08158c022006d66f3704cfab3eb2dc49dae24e4aa22a6910fc9b424007583204e3621af2e501475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220
- num_htlcs: 5
- # signature for output #0 (htlc-success for htlc #0)
- remote_htlc_signature = 3045022100d9e29616b8f3959f1d3d7f7ce893ffedcdc407717d0de8e37d808c91d3a7c50d022078c3033f6d00095c8720a4bc943c1b45727818c082e4e3ddbc6d3116435b624b
- # local_htlc_signature = 30440220636de5682ef0c5b61f124ec74e8aa2461a69777521d6998295dcea36bc3338110220165285594b23c50b28b82df200234566628a27bcd17f7f14404bd865354eb3ce
- htlc_success_tx (htlc #0): 02000000000101ab84ff284f162cfbfef241f853b47d4368d171f9e2a1445160cd591c4c7d882b00000000000000000001e8030000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d9e29616b8f3959f1d3d7f7ce893ffedcdc407717d0de8e37d808c91d3a7c50d022078c3033f6d00095c8720a4bc943c1b45727818c082e4e3ddbc6d3116435b624b014730440220636de5682ef0c5b61f124ec74e8aa2461a69777521d6998295dcea36bc3338110220165285594b23c50b28b82df200234566628a27bcd17f7f14404bd865354eb3ce012000000000000000000000000000000000000000000000000000000000000000008a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f401b175ac686800000000
- # signature for output #1 (htlc-timeout for htlc #2)
- remote_htlc_signature = 30440220649fe8b20e67e46cbb0d09b4acea87dbec001b39b08dee7bdd0b1f03922a8640022037c462dff79df501cecfdb12ea7f4de91f99230bb544726f6e04527b1f896004
- # local_htlc_signature = 3045022100803159dee7935dba4a1d36a61055ce8fd62caa528573cc221ae288515405a252022029c59e7cffce374fe860100a4a63787e105c3cf5156d40b12dd53ff55ac8cf3f
- htlc_timeout_tx (htlc #2): 02000000000101ab84ff284f162cfbfef241f853b47d4368d171f9e2a1445160cd591c4c7d882b01000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004730440220649fe8b20e67e46cbb0d09b4acea87dbec001b39b08dee7bdd0b1f03922a8640022037c462dff79df501cecfdb12ea7f4de91f99230bb544726f6e04527b1f89600401483045022100803159dee7935dba4a1d36a61055ce8fd62caa528573cc221ae288515405a252022029c59e7cffce374fe860100a4a63787e105c3cf5156d40b12dd53ff55ac8cf3f01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000
- # signature for output #2 (htlc-success for htlc #1)
- remote_htlc_signature = 30440220770fc321e97a19f38985f2e7732dd9fe08d16a2efa4bcbc0429400a447faf49102204d40b417f3113e1b0944ae0986f517564ab4acd3d190503faf97a6e420d43352
- # local_htlc_signature = 3045022100a437cc2ce77400ecde441b3398fea3c3ad8bdad8132be818227fe3c5b8345989022069d45e7fa0ae551ec37240845e2c561ceb2567eacf3076a6a43a502d05865faa
- htlc_success_tx (htlc #1): 02000000000101ab84ff284f162cfbfef241f853b47d4368d171f9e2a1445160cd591c4c7d882b02000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004730440220770fc321e97a19f38985f2e7732dd9fe08d16a2efa4bcbc0429400a447faf49102204d40b417f3113e1b0944ae0986f517564ab4acd3d190503faf97a6e420d4335201483045022100a437cc2ce77400ecde441b3398fea3c3ad8bdad8132be818227fe3c5b8345989022069d45e7fa0ae551ec37240845e2c561ceb2567eacf3076a6a43a502d05865faa012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000
- # signature for output #3 (htlc-timeout for htlc #3)
- remote_htlc_signature = 304402207bcbf4f60a9829b05d2dbab84ed593e0291836be715dc7db6b72a64caf646af802201e489a5a84f7c5cc130398b841d138d031a5137ac8f4c49c770a4959dc3c1363
- # local_htlc_signature = 304402203121d9b9c055f354304b016a36662ee99e1110d9501cb271b087ddb6f382c2c80220549882f3f3b78d9c492de47543cb9a697cecc493174726146536c5954dac7487
- htlc_timeout_tx (htlc #3): 02000000000101ab84ff284f162cfbfef241f853b47d4368d171f9e2a1445160cd591c4c7d882b03000000000000000001b80b0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402207bcbf4f60a9829b05d2dbab84ed593e0291836be715dc7db6b72a64caf646af802201e489a5a84f7c5cc130398b841d138d031a5137ac8f4c49c770a4959dc3c13630147304402203121d9b9c055f354304b016a36662ee99e1110d9501cb271b087ddb6f382c2c80220549882f3f3b78d9c492de47543cb9a697cecc493174726146536c5954dac748701008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000
- # signature for output #4 (htlc-success for htlc #4)
- remote_htlc_signature = 3044022076dca5cb81ba7e466e349b7128cdba216d4d01659e29b96025b9524aaf0d1899022060de85697b88b21c749702b7d2cfa7dfeaa1f472c8f1d7d9c23f2bf968464b87
- # local_htlc_signature = 3045022100d9080f103cc92bac15ec42464a95f070c7fb6925014e673ee2ea1374d36a7f7502200c65294d22eb20d48564954d5afe04a385551919d8b2ddb4ae2459daaeee1d95
- htlc_success_tx (htlc #4): 02000000000101ab84ff284f162cfbfef241f853b47d4368d171f9e2a1445160cd591c4c7d882b04000000000000000001a00f0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500473044022076dca5cb81ba7e466e349b7128cdba216d4d01659e29b96025b9524aaf0d1899022060de85697b88b21c749702b7d2cfa7dfeaa1f472c8f1d7d9c23f2bf968464b8701483045022100d9080f103cc92bac15ec42464a95f070c7fb6925014e673ee2ea1374d36a7f7502200c65294d22eb20d48564954d5afe04a385551919d8b2ddb4ae2459daaeee1d95012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000
-
- name: commitment tx with seven outputs untrimmed (maximum feerate)
- to_local_msat: 6988000000
- to_remote_msat: 3000000000
- local_feerate_per_kw: 647
- # base commitment transaction fee = 1024
- # actual commitment transactionWhy this scored 34/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.