Stop sending `update_fee` for mobile wallets (#3186)
What changed, and why it matters
This change adjusts how Eclair sets on-chain fees for channels with mobile wallets (specifically Phoenix). Instead of repeatedly sending fee-update messages and using higher feerates, it now pins the commitment transaction feerate to 1 satoshi per byte and stops sending update_fee for those channels. The goal is to simplify fee handling during complex operations like splicing and shutdown, relying on Bitcoin's package relay to still allow force-closes to propagate. The commit notes a trade-off: mobile wallets without their own on-chain funds may struggle to confirm force-close transactions via CPFP, but that was already the case because the LSP (the node running Eclair) controlled the feerate anyway.
Review whether the 1 sat/byte floor is safe under all network conditions and mempool congestion scenarios, and confirm that package relay assumptions hold for the deployment's Bitcoin Core version and peer topology. Monitor for any edge cases during splicing, shutdown, or fee disagreements that the change is intended to avoid.
Security signals we found
Change in fee policy for mobile wallet channels
Pins commitment feerate to 1 sat/byte for specific commitment formats
Stops sending update_fee for mobile wallet channels
Relies on Bitcoin Core v28 1-parent-1-child package relay for commit tx propagation
Acknowledged residual risk: mobile wallets without on-chain funds cannot CPFP the commit tx
References future v3 transaction and zero-fee commitment improvements
Evidence from the diff
The patch modifies OnChainFeeConf to treat UnsafeLegacyAnchorOutputsCommitmentFormat and PhoenixSimpleTaprootChannelCommitmentFormat as mobile-wallet formats. For these, getCommitmentFeerate now returns 1 sat/byte regardless of network feerates, and shouldUpdateFee returns true only when the current feerate is above 1 sat/byte (to drive it down). For ZeroFeeHtlcTx anchor formats, the existing ratio-based update logic and network-feerate-aware commitment feerate remain. Channel.scala passes the commitment format into shouldUpdateFee. Tests are updated to expect 1 sat/byte for Phoenix/legacy-anchor formats and to use the new constant phoenixCommitFeeratePerKw.
Changed components
eclair-core/src/main/scala/fr/acinq/eclair/blockchain/fee/OnChainFeeConf.scalaeclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/Channel.scalaMobile wallet channels using UnsafeLegacyAnchorOutputsCommitmentFormatMobile wallet channels using PhoenixSimpleTaprootChannelCommitmentFormatInspect captured patch +53 / −33
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 7deea85..2a009c4 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
@@ -17,7 +17,7 @@
package fr.acinq.eclair.blockchain.fee
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
-import fr.acinq.bitcoin.scalacompat.Satoshi
+import fr.acinq.bitcoin.scalacompat.{Satoshi, SatoshiLong}
import fr.acinq.eclair.BlockHeight
import fr.acinq.eclair.transactions.Transactions
import fr.acinq.eclair.transactions.Transactions._
@@ -65,8 +65,8 @@ case class DustTolerance(maxExposure: Satoshi, closeOnUpdateFeeOverflow: Boolean
case class FeerateTolerance(ratioLow: Double, ratioHigh: Double, anchorOutputMaxCommitFeerate: FeeratePerKw, dustTolerance: DustTolerance) {
/**
- * @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)
+ * @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 isProposedCommitFeerateTooHigh(networkFeerate: FeeratePerKw, proposedFeerate: FeeratePerKw): Boolean = networkFeerate * ratioHigh < proposedFeerate
@@ -85,15 +85,24 @@ case class OnChainFeeConf(feeTargets: FeeTargets,
def feerateToleranceFor(nodeId: PublicKey): FeerateTolerance = perNodeFeerateTolerance.getOrElse(nodeId, defaultFeerateTolerance)
/** To avoid spamming our peers with fee updates every time there's a small variation, we only update the fee when the difference exceeds a given ratio. */
- def shouldUpdateFee(currentFeeratePerKw: FeeratePerKw, nextFeeratePerKw: FeeratePerKw): Boolean =
- currentFeeratePerKw.toLong == 0 || Math.abs((currentFeeratePerKw.toLong - nextFeeratePerKw.toLong).toDouble / currentFeeratePerKw.toLong) > updateFeeMinDiffRatio
+ def shouldUpdateFee(currentFeeratePerKw: FeeratePerKw, nextFeeratePerKw: FeeratePerKw, commitmentFormat: CommitmentFormat): Boolean = {
+ commitmentFormat match {
+ case Transactions.UnsafeLegacyAnchorOutputsCommitmentFormat | Transactions.PhoenixSimpleTaprootChannelCommitmentFormat =>
+ // If we're not already using 1 sat/byte, we update the fee.
+ FeeratePerKw(FeeratePerByte(1 sat)) < currentFeeratePerKw
+ case Transactions.ZeroFeeHtlcTxAnchorOutputsCommitmentFormat | Transactions.ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat =>
+ // If the fee has a large enough change, we update the fee.
+ currentFeeratePerKw.toLong == 0 || Math.abs((currentFeeratePerKw.toLong - nextFeeratePerKw.toLong).toDouble / currentFeeratePerKw.toLong) > updateFeeMinDiffRatio
+ }
+ }
def getFundingFeerate(feerates: FeeratesPerKw): FeeratePerKw = feeTargets.funding.getFeerate(feerates)
/**
* Get the feerate that should apply to a channel commitment transaction:
- * - if we're using anchor outputs, we use a feerate that allows network propagation of the commit tx: we will use CPFP to speed up confirmation if needed
- * - otherwise we use a feerate that should get the commit tx confirmed within the configured block target
+ * - if the remote peer is a mobile wallet that supports anchor outputs, we use 1 sat/byte
+ * - otherwise, we use a feerate that should allow network propagation of the commit tx on its own: we will use CPFP
+ * on the anchor output to speed up confirmation if needed or to help propagation
*
* @param remoteNodeId nodeId of our channel peer
* @param commitmentFormat commitment format
@@ -102,7 +111,11 @@ case class OnChainFeeConf(feeTargets: FeeTargets,
val networkFeerate = feerates.fast
val networkMinFee = feerates.minimum
commitmentFormat match {
- case _: Transactions.AnchorOutputsCommitmentFormat | _: Transactions.SimpleTaprootChannelCommitmentFormat =>
+ case Transactions.UnsafeLegacyAnchorOutputsCommitmentFormat | Transactions.PhoenixSimpleTaprootChannelCommitmentFormat =>
+ // Since Bitcoin Core v28, 1-parent-1-child package relay has been deployed: it should be ok if the commit tx
+ // doesn't propagate on its own.
+ FeeratePerKw(FeeratePerByte(1 sat))
+ case Transactions.ZeroFeeHtlcTxAnchorOutputsCommitmentFormat | Transactions.ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat =>
val targetFeerate = networkFeerate.min(feerateToleranceFor(remoteNodeId).anchorOutputMaxCommitFeerate)
// We make sure the feerate is always greater than the propagation threshold.
targetFeerate.max(networkMinFee * 1.25)
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 6d92187..84ac61d 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
@@ -2736,7 +2736,7 @@ class Channel(val nodeParams: NodeParams, val channelKeys: ChannelKeys, val wall
if (d.commitments.localChannelParams.paysCommitTxFees && !shutdownInProgress) {
val currentFeeratePerKw = d.commitments.latest.localCommit.spec.commitTxFeerate
val networkFeeratePerKw = nodeParams.onChainFeeConf.getCommitmentFeerate(nodeParams.currentBitcoinCoreFeerates, remoteNodeId, d.commitments.latest.commitmentFormat)
- if (nodeParams.onChainFeeConf.shouldUpdateFee(currentFeeratePerKw, networkFeeratePerKw)) {
+ if (nodeParams.onChainFeeConf.shouldUpdateFee(currentFeeratePerKw, networkFeeratePerKw, d.commitments.latest.commitmentFormat)) {
self ! CMD_UPDATE_FEE(networkFeeratePerKw, commit = true)
}
}
@@ -3219,7 +3219,7 @@ class Channel(val nodeParams: NodeParams, val channelKeys: ChannelKeys, val wall
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 shouldUpdateFee = d.commitments.localChannelParams.paysCommitTxFees && nodeParams.onChainFeeConf.shouldUpdateFee(currentFeeratePerKw, networkFeeratePerKw, d.commitments.latest.commitmentFormat)
if (shouldUpdateFee) {
self ! CMD_UPDATE_FEE(networkFeeratePerKw, commit = true)
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/TestConstants.scala b/eclair-core/src/test/scala/fr/acinq/eclair/TestConstants.scala
index b939873..97b8a51 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/TestConstants.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/TestConstants.scala
@@ -53,6 +53,7 @@ object TestConstants {
val nonInitiatorPushAmount: MilliSatoshi = 100_000_000L msat
val feeratePerKw: FeeratePerKw = FeeratePerKw(10_000 sat)
val anchorOutputsFeeratePerKw: FeeratePerKw = FeeratePerKw(2_500 sat)
+ val phoenixCommitFeeratePerKw: FeeratePerKw = FeeratePerByte(1 sat).perKw
val defaultLiquidityRates: LiquidityAds.WillFundRates = LiquidityAds.WillFundRates(
fundingRates = LiquidityAds.FundingRate(100_000 sat, 10_000_000 sat, 500, 100, 100 sat, 1000 sat) :: Nil,
paymentTypes = Set(LiquidityAds.PaymentType.FromChannelBalance)
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/fee/OnChainFeeConfSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/fee/OnChainFeeConfSpec.scala
index 67b3c43..446ae06 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/fee/OnChainFeeConfSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/fee/OnChainFeeConfSpec.scala
@@ -18,7 +18,7 @@ package fr.acinq.eclair.blockchain.fee
import fr.acinq.bitcoin.scalacompat.SatoshiLong
import fr.acinq.eclair.randomKey
-import fr.acinq.eclair.transactions.Transactions.{UnsafeLegacyAnchorOutputsCommitmentFormat, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat}
+import fr.acinq.eclair.transactions.Transactions.{PhoenixSimpleTaprootChannelCommitmentFormat, UnsafeLegacyAnchorOutputsCommitmentFormat, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat, ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat}
import org.scalatest.funsuite.AnyFunSuite
class OnChainFeeConfSpec extends AnyFunSuite {
@@ -29,22 +29,25 @@ class OnChainFeeConfSpec extends AnyFunSuite {
test("should update fee when diff ratio exceeded") {
val feeConf = OnChainFeeConf(defaultFeeTargets, defaultMaxClosingFeerate, safeUtxosThreshold = 0, spendAnchorWithoutHtlcs = true, anchorWithoutHtlcsMaxFee = 10_000.sat, closeOnOfflineMismatch = true, updateFeeMinDiffRatio = 0.1, defaultFeerateTolerance, Map.empty)
- assert(!feeConf.shouldUpdateFee(FeeratePerKw(1000 sat), FeeratePerKw(1000 sat)))
- assert(!feeConf.shouldUpdateFee(FeeratePerKw(1000 sat), FeeratePerKw(900 sat)))
- assert(!feeConf.shouldUpdateFee(FeeratePerKw(1000 sat), FeeratePerKw(1100 sat)))
- assert(feeConf.shouldUpdateFee(FeeratePerKw(1000 sat), FeeratePerKw(899 sat)))
- assert(feeConf.shouldUpdateFee(FeeratePerKw(1000 sat), FeeratePerKw(1101 sat)))
+ assert(!feeConf.shouldUpdateFee(FeeratePerKw(1000 sat), FeeratePerKw(1000 sat), ZeroFeeHtlcTxAnchorOutputsCommitmentFormat))
+ assert(!feeConf.shouldUpdateFee(FeeratePerKw(1000 sat), FeeratePerKw(900 sat), ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat))
+ assert(!feeConf.shouldUpdateFee(FeeratePerKw(1000 sat), FeeratePerKw(1100 sat), ZeroFeeHtlcTxAnchorOutputsCommitmentFormat))
+ assert(feeConf.shouldUpdateFee(FeeratePerKw(1000 sat), FeeratePerKw(899 sat), ZeroFeeHtlcTxAnchorOutputsCommitmentFormat))
+ assert(feeConf.shouldUpdateFee(FeeratePerKw(1000 sat), FeeratePerKw(1101 sat), ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat))
}
- test("get commitment feerate") {
+ test("should update fee to set to 1 sat/byte") {
val feeConf = OnChainFeeConf(defaultFeeTargets, defaultMaxClosingFeerate, safeUtxosThreshold = 0, spendAnchorWithoutHtlcs = true, anchorWithoutHtlcsMaxFee = 10_000.sat, closeOnOfflineMismatch = true, updateFeeMinDiffRatio = 0.1, defaultFeerateTolerance, Map.empty)
- val feerates1 = FeeratesPerKw.single(FeeratePerKw(10000 sat)).copy(fast = FeeratePerKw(5000 sat))
- assert(feeConf.getCommitmentFeerate(feerates1, randomKey().publicKey, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat) == FeeratePerKw(2500 sat))
- val feerates2 = FeeratesPerKw.single(FeeratePerKw(10000 sat)).copy(fast = FeeratePerKw(2000 sat))
- assert(feeConf.getCommitmentFeerate(feerates2, randomKey().publicKey, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat) == FeeratePerKw(2000 sat))
+ // We always use 1 sat/byte for mobile wallet commitment formats, regardless of the current feerate.
+ val feerates = FeeratesPerKw.single(FeeratePerKw(FeeratePerByte(20 sat)))
+ assert(feeConf.getCommitmentFeerate(feerates, randomKey().publicKey, UnsafeLegacyAnchorOutputsCommitmentFormat) == FeeratePerKw(FeeratePerByte(1 sat)))
+ assert(feeConf.getCommitmentFeerate(feerates, randomKey().publicKey, PhoenixSimpleTaprootChannelCommitmentFormat) == FeeratePerKw(FeeratePerByte(1 sat)))
+ // If we're not already using 1 sat/byte, we update the feerate.
+ assert(feeConf.shouldUpdateFee(FeeratePerKw(300 sat), FeeratePerKw(FeeratePerByte(1 sat)), UnsafeLegacyAnchorOutputsCommitmentFormat))
+ assert(feeConf.shouldUpdateFee(FeeratePerKw(300 sat), FeeratePerKw(FeeratePerByte(1 sat)), PhoenixSimpleTaprootChannelCommitmentFormat))
}
- test("get commitment feerate (anchor outputs)") {
+ test("get commitment feerate") {
val defaultNodeId = randomKey().publicKey
val defaultMaxCommitFeerate = defaultFeerateTolerance.anchorOutputMaxCommitFeerate
val overrideNodeId = randomKey().publicKey
@@ -52,33 +55,33 @@ class OnChainFeeConfSpec extends AnyFunSuite {
val feeConf = OnChainFeeConf(defaultFeeTargets, defaultMaxClosingFeerate, safeUtxosThreshold = 0, spendAnchorWithoutHtlcs = true, anchorWithoutHtlcsMaxFee = 10_000.sat, closeOnOfflineMismatch = true, updateFeeMinDiffRatio = 0.1, defaultFeerateTolerance, Map(overrideNodeId -> defaultFeerateTolerance.copy(anchorOutputMaxCommitFeerate = overrideMaxCommitFeerate)))
val feerates1 = FeeratesPerKw.single(FeeratePerKw(10000 sat)).copy(fast = defaultMaxCommitFeerate / 2, minimum = FeeratePerKw(250 sat))
- assert(feeConf.getCommitmentFeerate(feerates1, defaultNodeId, UnsafeLegacyAnchorOutputsCommitmentFormat) == defaultMaxCommitFeerate / 2)
+ assert(feeConf.getCommitmentFeerate(feerates1, defaultNodeId, ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat) == defaultMaxCommitFeerate / 2)
assert(feeConf.getCommitmentFeerate(feerates1, defaultNodeId, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat) == defaultMaxCommitFeerate / 2)
val feerates2 = FeeratesPerKw.single(FeeratePerKw(10000 sat)).copy(fast = defaultMaxCommitFeerate * 2, minimum = FeeratePerKw(250 sat))
- assert(feeConf.getCommitmentFeerate(feerates2, defaultNodeId, UnsafeLegacyAnchorOutputsCommitmentFormat) == defaultMaxCommitFeerate)
+ assert(feeConf.getCommitmentFeerate(feerates2, defaultNodeId, ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat) == defaultMaxCommitFeerate)
assert(feeConf.getCommitmentFeerate(feerates2, defaultNodeId, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat) == defaultMaxCommitFeerate)
- assert(feeConf.getCommitmentFeerate(feerates2, overrideNodeId, UnsafeLegacyAnchorOutputsCommitmentFormat) == overrideMaxCommitFeerate)
+ assert(feeConf.getCommitmentFeerate(feerates2, overrideNodeId, ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat) == overrideMaxCommitFeerate)
assert(feeConf.getCommitmentFeerate(feerates2, overrideNodeId, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat) == overrideMaxCommitFeerate)
val feerates3 = FeeratesPerKw.single(FeeratePerKw(10000 sat)).copy(fast = defaultMaxCommitFeerate / 2, minimum = FeeratePerKw(250 sat))
- assert(feeConf.getCommitmentFeerate(feerates3, defaultNodeId, UnsafeLegacyAnchorOutputsCommitmentFormat) == defaultMaxCommitFeerate / 2)
+ assert(feeConf.getCommitmentFeerate(feerates3, defaultNodeId, ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat) == defaultMaxCommitFeerate / 2)
assert(feeConf.getCommitmentFeerate(feerates3, defaultNodeId, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat) == defaultMaxCommitFeerate / 2)
val feerates4 = FeeratesPerKw.single(FeeratePerKw(10000 sat)).copy(fast = defaultMaxCommitFeerate * 1.5, minimum = FeeratePerKw(250 sat))
- assert(feeConf.getCommitmentFeerate(feerates4, defaultNodeId, UnsafeLegacyAnchorOutputsCommitmentFormat) == defaultMaxCommitFeerate)
+ assert(feeConf.getCommitmentFeerate(feerates4, defaultNodeId, ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat) == defaultMaxCommitFeerate)
assert(feeConf.getCommitmentFeerate(feerates4, defaultNodeId, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat) == defaultMaxCommitFeerate)
val feerates5 = FeeratesPerKw.single(FeeratePerKw(25000 sat)).copy(minimum = FeeratePerKw(10000 sat))
- assert(feeConf.getCommitmentFeerate(feerates5, defaultNodeId, UnsafeLegacyAnchorOutputsCommitmentFormat) == FeeratePerKw(10000 sat) * 1.25)
+ assert(feeConf.getCommitmentFeerate(feerates5, defaultNodeId, ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat) == FeeratePerKw(10000 sat) * 1.25)
assert(feeConf.getCommitmentFeerate(feerates5, defaultNodeId, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat) == FeeratePerKw(10000 sat) * 1.25)
- assert(feeConf.getCommitmentFeerate(feerates5, overrideNodeId, UnsafeLegacyAnchorOutputsCommitmentFormat) == FeeratePerKw(10000 sat) * 1.25)
+ assert(feeConf.getCommitmentFeerate(feerates5, overrideNodeId, ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat) == FeeratePerKw(10000 sat) * 1.25)
assert(feeConf.getCommitmentFeerate(feerates5, overrideNodeId, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat) == FeeratePerKw(10000 sat) * 1.25)
val feerates6 = FeeratesPerKw.single(FeeratePerKw(25000 sat)).copy(minimum = FeeratePerKw(10000 sat))
- assert(feeConf.getCommitmentFeerate(feerates6, defaultNodeId, UnsafeLegacyAnchorOutputsCommitmentFormat) == FeeratePerKw(10000 sat) * 1.25)
+ assert(feeConf.getCommitmentFeerate(feerates6, defaultNodeId, ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat) == FeeratePerKw(10000 sat) * 1.25)
assert(feeConf.getCommitmentFeerate(feerates6, defaultNodeId, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat) == FeeratePerKw(10000 sat) * 1.25)
- assert(feeConf.getCommitmentFeerate(feerates6, overrideNodeId, UnsafeLegacyAnchorOutputsCommitmentFormat) == FeeratePerKw(10000 sat) * 1.25)
+ assert(feeConf.getCommitmentFeerate(feerates6, overrideNodeId, ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat) == FeeratePerKw(10000 sat) * 1.25)
assert(feeConf.getCommitmentFeerate(feerates6, overrideNodeId, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat) == FeeratePerKw(10000 sat) * 1.25)
}
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/ChannelStateTestsHelperMethods.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/ChannelStateTestsHelperMethods.scala
index acf6b99..a2aa6ae 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/ChannelStateTestsHelperMethods.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/ChannelStateTestsHelperMethods.scala
@@ -140,7 +140,10 @@ trait ChannelStateTestsBase extends Assertions with Eventually {
temporaryChannelId = ByteVector32.Zeroes,
fundingAmount = fundingAmount,
dualFunded = dualFunded,
- commitTxFeerate = TestConstants.anchorOutputsFeeratePerKw,
+ commitTxFeerate = channelType match {
+ case _: ChannelTypes.AnchorOutputs | ChannelTypes.SimpleTaprootChannelsPhoenix => TestConstants.phoenixCommitFeeratePerKw
+ case _ => TestConstants.anchorOutputsFeeratePerKw
+ },
fundingTxFeerate = TestConstants.feeratePerKw,
fundingTxFeeBudget_opt = None,
pushAmount_opt = pushAmount_opt,
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala
index af697c8..b1b794b 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala
@@ -547,7 +547,7 @@ class PeerSpec extends FixtureSpec {
assert(init.channelType == ChannelTypes.AnchorOutputs())
assert(!init.dualFunded)
assert(init.fundingAmount == 15000.sat)
- assert(init.commitTxFeerate == TestConstants.anchorOutputsFeeratePerKw)
+ assert(init.commitTxFeerate == TestConstants.phoenixCommitFeeratePerKw)
assert(init.fundingTxFeerate == nodeParams.onChainFeeConf.getFundingFeerate(nodeParams.currentFeeratesForFundingClosing))
}
Why this scored 36/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.