Skip to content

Commit 92e53dc

Browse files
authored
Configurable anchor output max commitment feerate (#1718)
It makes sense to allow node operators to configure the value they want to use as a maximum threshold for anchor outputs commitment tx feerate. This allows node operators to raise this value when mempools start getting full in anticipation of a potential rise of the min-relay-fee. This value can also be overridden for specific nodes.
1 parent c4c0248 commit 92e53dc

17 files changed

+107
-96
lines changed

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

+5-1
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,17 @@ eclair {
115115
feerate-tolerance {
116116
ratio-low = 0.5 // will allow remote fee rates as low as half our local feerate
117117
ratio-high = 10.0 // will allow remote fee rates as high as 10 times our local feerate
118+
// 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.
119+
// the following value is the maximum feerate we'll use for our commit tx (in sat/byte)
120+
anchor-output-max-commit-feerate = 10
118121
}
119122
override-feerate-tolerance = [ // optional per-node feerate tolerance
120123
# {
121-
# nodeid = "02aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
124+
# nodeid = "02aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
122125
# feerate-tolerance {
123126
# ratio-low = 0.1
124127
# ratio-high = 20.0
128+
# anchor-output-max-commit-feerate = 10
125129
# }
126130
# }
127131
]

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

+17-10
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,12 @@
1616

1717
package fr.acinq.eclair
1818

19-
import java.io.File
20-
import java.net.InetSocketAddress
21-
import java.nio.file.Files
22-
import java.util.UUID
23-
import java.util.concurrent.TimeUnit
24-
import java.util.concurrent.atomic.AtomicLong
25-
2619
import com.typesafe.config.{Config, ConfigFactory, ConfigValueType}
2720
import fr.acinq.bitcoin.Crypto.PublicKey
2821
import fr.acinq.bitcoin.{Block, ByteVector32, Crypto, Satoshi}
2922
import fr.acinq.eclair.NodeParams.WatcherType
3023
import fr.acinq.eclair.Setup.Seeds
31-
import fr.acinq.eclair.blockchain.fee.{FeeEstimator, FeeTargets, FeerateTolerance, OnChainFeeConf}
24+
import fr.acinq.eclair.blockchain.fee._
3225
import fr.acinq.eclair.channel.Channel
3326
import fr.acinq.eclair.crypto.Noise.KeyPair
3427
import fr.acinq.eclair.crypto.keymanager.{ChannelKeyManager, NodeKeyManager}
@@ -40,6 +33,12 @@ import fr.acinq.eclair.wire.{Color, EncodingType, NodeAddress}
4033
import grizzled.slf4j.Logging
4134
import scodec.bits.ByteVector
4235

36+
import java.io.File
37+
import java.net.InetSocketAddress
38+
import java.nio.file.Files
39+
import java.util.UUID
40+
import java.util.concurrent.TimeUnit
41+
import java.util.concurrent.atomic.AtomicLong
4342
import scala.concurrent.duration._
4443
import scala.jdk.CollectionConverters._
4544

@@ -330,10 +329,18 @@ object NodeParams extends Logging {
330329
feeEstimator = feeEstimator,
331330
closeOnOfflineMismatch = config.getBoolean("on-chain-fees.close-on-offline-feerate-mismatch"),
332331
updateFeeMinDiffRatio = config.getDouble("on-chain-fees.update-fee-min-diff-ratio"),
333-
defaultFeerateTolerance = FeerateTolerance(config.getDouble("on-chain-fees.feerate-tolerance.ratio-low"), config.getDouble("on-chain-fees.feerate-tolerance.ratio-high")),
332+
defaultFeerateTolerance = FeerateTolerance(
333+
config.getDouble("on-chain-fees.feerate-tolerance.ratio-low"),
334+
config.getDouble("on-chain-fees.feerate-tolerance.ratio-high"),
335+
FeeratePerKw(FeeratePerByte(Satoshi(config.getLong("on-chain-fees.feerate-tolerance.anchor-output-max-commit-feerate"))))
336+
),
334337
perNodeFeerateTolerance = config.getConfigList("on-chain-fees.override-feerate-tolerance").asScala.map { e =>
335338
val nodeId = PublicKey(ByteVector.fromValidHex(e.getString("nodeid")))
336-
val tolerance = FeerateTolerance(e.getDouble("feerate-tolerance.ratio-low"), e.getDouble("feerate-tolerance.ratio-high"))
339+
val tolerance = FeerateTolerance(
340+
e.getDouble("feerate-tolerance.ratio-low"),
341+
e.getDouble("feerate-tolerance.ratio-high"),
342+
FeeratePerKw(FeeratePerByte(Satoshi(e.getLong("feerate-tolerance.anchor-output-max-commit-feerate"))))
343+
)
337344
nodeId -> tolerance
338345
}.toMap
339346
),

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

+7-11
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
package fr.acinq.eclair.blockchain.fee
1818

1919
import fr.acinq.bitcoin.Crypto.PublicKey
20-
import fr.acinq.bitcoin.{Satoshi, SatoshiLong}
20+
import fr.acinq.bitcoin.Satoshi
2121
import fr.acinq.eclair.blockchain.CurrentFeerates
2222
import fr.acinq.eclair.channel.ChannelVersion
2323

@@ -28,14 +28,9 @@ trait FeeEstimator {
2828
// @formatter:on
2929
}
3030

31-
object FeeEstimator {
32-
/** When using anchor outputs, we only need to set a feerate that allows the tx to propagate: we will use CPFP to speed up confirmation if needed. */
33-
val AnchorOutputMaxCommitFeerate = FeeratePerKw(FeeratePerByte(10 sat))
34-
}
35-
3631
case class FeeTargets(fundingBlockTarget: Int, commitmentBlockTarget: Int, mutualCloseBlockTarget: Int, claimMainBlockTarget: Int)
3732

38-
case class FeerateTolerance(ratioLow: Double, ratioHigh: Double) {
33+
case class FeerateTolerance(ratioLow: Double, ratioHigh: Double, anchorOutputMaxCommitFeerate: FeeratePerKw) {
3934
/**
4035
* @param channelVersion channel version
4136
* @param networkFeerate reference fee rate (value we estimate from our view of the network)
@@ -44,7 +39,7 @@ case class FeerateTolerance(ratioLow: Double, ratioHigh: Double) {
4439
*/
4540
def isFeeDiffTooHigh(channelVersion: ChannelVersion, networkFeerate: FeeratePerKw, proposedFeerate: FeeratePerKw): Boolean = {
4641
if (channelVersion.hasAnchorOutputs) {
47-
proposedFeerate < networkFeerate * ratioLow || FeeEstimator.AnchorOutputMaxCommitFeerate * ratioHigh < proposedFeerate
42+
proposedFeerate < networkFeerate * ratioLow || anchorOutputMaxCommitFeerate * ratioHigh < proposedFeerate
4843
} else {
4944
proposedFeerate < networkFeerate * ratioLow || networkFeerate * ratioHigh < proposedFeerate
5045
}
@@ -53,7 +48,7 @@ case class FeerateTolerance(ratioLow: Double, ratioHigh: Double) {
5348

5449
case class OnChainFeeConf(feeTargets: FeeTargets, feeEstimator: FeeEstimator, closeOnOfflineMismatch: Boolean, updateFeeMinDiffRatio: Double, private val defaultFeerateTolerance: FeerateTolerance, private val perNodeFeerateTolerance: Map[PublicKey, FeerateTolerance]) {
5550

56-
def maxFeerateMismatchFor(nodeId: PublicKey): FeerateTolerance = perNodeFeerateTolerance.getOrElse(nodeId, defaultFeerateTolerance)
51+
def feerateToleranceFor(nodeId: PublicKey): FeerateTolerance = perNodeFeerateTolerance.getOrElse(nodeId, defaultFeerateTolerance)
5752

5853
/** 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. */
5954
def shouldUpdateFee(currentFeeratePerKw: FeeratePerKw, nextFeeratePerKw: FeeratePerKw): Boolean =
@@ -64,16 +59,17 @@ case class OnChainFeeConf(feeTargets: FeeTargets, feeEstimator: FeeEstimator, cl
6459
* - 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
6560
* - otherwise we use a feerate that should get the commit tx confirmed within the configured block target
6661
*
62+
* @param remoteNodeId nodeId of our channel peer
6763
* @param channelVersion channel version
6864
* @param currentFeerates_opt if provided, will be used to compute the most up-to-date network fee, otherwise we rely on the fee estimator
6965
*/
70-
def getCommitmentFeerate(channelVersion: ChannelVersion, channelCapacity: Satoshi, currentFeerates_opt: Option[CurrentFeerates]): FeeratePerKw = {
66+
def getCommitmentFeerate(remoteNodeId: PublicKey, channelVersion: ChannelVersion, channelCapacity: Satoshi, currentFeerates_opt: Option[CurrentFeerates]): FeeratePerKw = {
7167
val networkFeerate = currentFeerates_opt match {
7268
case Some(currentFeerates) => currentFeerates.feeratesPerKw.feePerBlock(feeTargets.commitmentBlockTarget)
7369
case None => feeEstimator.getFeeratePerKw(feeTargets.commitmentBlockTarget)
7470
}
7571
if (channelVersion.hasAnchorOutputs) {
76-
networkFeerate.min(FeeEstimator.AnchorOutputMaxCommitFeerate)
72+
networkFeerate.min(feerateToleranceFor(remoteNodeId).anchorOutputMaxCommitFeerate)
7773
} else {
7874
networkFeerate
7975
}

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

+5-5
Original file line numberDiff line numberDiff line change
@@ -1625,7 +1625,7 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId
16251625
val shutdownInProgress = d.localShutdown.nonEmpty || d.remoteShutdown.nonEmpty
16261626
if (d.commitments.localParams.isFunder && !shutdownInProgress) {
16271627
val currentFeeratePerKw = d.commitments.localCommit.spec.feeratePerKw
1628-
val networkFeeratePerKw = nodeParams.onChainFeeConf.getCommitmentFeerate(d.commitments.channelVersion, d.commitments.capacity, None)
1628+
val networkFeeratePerKw = nodeParams.onChainFeeConf.getCommitmentFeerate(remoteNodeId, d.commitments.channelVersion, d.commitments.capacity, None)
16291629
if (nodeParams.onChainFeeConf.shouldUpdateFee(currentFeeratePerKw, networkFeeratePerKw)) {
16301630
self ! CMD_UPDATE_FEE(networkFeeratePerKw, commit = true)
16311631
}
@@ -1880,11 +1880,11 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId
18801880
}
18811881

18821882
private def handleCurrentFeerate(c: CurrentFeerates, d: HasCommitments) = {
1883-
val networkFeeratePerKw = nodeParams.onChainFeeConf.getCommitmentFeerate(d.commitments.channelVersion, d.commitments.capacity, Some(c))
1883+
val networkFeeratePerKw = nodeParams.onChainFeeConf.getCommitmentFeerate(remoteNodeId, d.commitments.channelVersion, d.commitments.capacity, Some(c))
18841884
val currentFeeratePerKw = d.commitments.localCommit.spec.feeratePerKw
18851885
val shouldUpdateFee = d.commitments.localParams.isFunder && nodeParams.onChainFeeConf.shouldUpdateFee(currentFeeratePerKw, networkFeeratePerKw)
18861886
val shouldClose = !d.commitments.localParams.isFunder &&
1887-
nodeParams.onChainFeeConf.maxFeerateMismatchFor(d.commitments.remoteNodeId).isFeeDiffTooHigh(d.commitments.channelVersion, networkFeeratePerKw, currentFeeratePerKw) &&
1887+
nodeParams.onChainFeeConf.feerateToleranceFor(d.commitments.remoteNodeId).isFeeDiffTooHigh(d.commitments.channelVersion, networkFeeratePerKw, currentFeeratePerKw) &&
18881888
d.commitments.hasPendingOrProposedHtlcs // we close only if we have HTLCs potentially at risk
18891889
if (shouldUpdateFee) {
18901890
self ! CMD_UPDATE_FEE(networkFeeratePerKw, commit = true)
@@ -1904,11 +1904,11 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId
19041904
* @return
19051905
*/
19061906
private def handleOfflineFeerate(c: CurrentFeerates, d: HasCommitments) = {
1907-
val networkFeeratePerKw = nodeParams.onChainFeeConf.getCommitmentFeerate(d.commitments.channelVersion, d.commitments.capacity, Some(c))
1907+
val networkFeeratePerKw = nodeParams.onChainFeeConf.getCommitmentFeerate(remoteNodeId, d.commitments.channelVersion, d.commitments.capacity, Some(c))
19081908
val currentFeeratePerKw = d.commitments.localCommit.spec.feeratePerKw
19091909
// if the network fees are too high we risk to not be able to confirm our current commitment
19101910
val shouldClose = networkFeeratePerKw > currentFeeratePerKw &&
1911-
nodeParams.onChainFeeConf.maxFeerateMismatchFor(d.commitments.remoteNodeId).isFeeDiffTooHigh(d.commitments.channelVersion, networkFeeratePerKw, currentFeeratePerKw) &&
1911+
nodeParams.onChainFeeConf.feerateToleranceFor(d.commitments.remoteNodeId).isFeeDiffTooHigh(d.commitments.channelVersion, networkFeeratePerKw, currentFeeratePerKw) &&
19121912
d.commitments.hasPendingOrProposedHtlcs // we close only if we have HTLCs potentially at risk
19131913
if (shouldClose) {
19141914
if (nodeParams.onChainFeeConf.closeOnOfflineMismatch) {

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

+6-6
Original file line numberDiff line numberDiff line change
@@ -288,9 +288,9 @@ object Commitments {
288288
// we allowed mismatches between our feerates and our remote's as long as commitments didn't contain any HTLC at risk
289289
// we need to verify that we're not disagreeing on feerates anymore before offering new HTLCs
290290
// NB: there may be a pending update_fee that hasn't been applied yet that needs to be taken into account
291-
val localFeeratePerKw = feeConf.getCommitmentFeerate(commitments.channelVersion, commitments.capacity, None)
291+
val localFeeratePerKw = feeConf.getCommitmentFeerate(commitments.remoteNodeId, commitments.channelVersion, commitments.capacity, None)
292292
val remoteFeeratePerKw = commitments.localCommit.spec.feeratePerKw +: commitments.remoteChanges.all.collect { case f: UpdateFee => f.feeratePerKw }
293-
remoteFeeratePerKw.find(feerate => feeConf.maxFeerateMismatchFor(commitments.remoteNodeId).isFeeDiffTooHigh(commitments.channelVersion, localFeeratePerKw, feerate)) match {
293+
remoteFeeratePerKw.find(feerate => feeConf.feerateToleranceFor(commitments.remoteNodeId).isFeeDiffTooHigh(commitments.channelVersion, localFeeratePerKw, feerate)) match {
294294
case Some(feerate) => return Left(FeerateTooDifferent(commitments.channelId, localFeeratePerKw = localFeeratePerKw, remoteFeeratePerKw = feerate))
295295
case None =>
296296
}
@@ -352,9 +352,9 @@ object Commitments {
352352
// we allowed mismatches between our feerates and our remote's as long as commitments didn't contain any HTLC at risk
353353
// we need to verify that we're not disagreeing on feerates anymore before accepting new HTLCs
354354
// NB: there may be a pending update_fee that hasn't been applied yet that needs to be taken into account
355-
val localFeeratePerKw = feeConf.getCommitmentFeerate(commitments.channelVersion, commitments.capacity, None)
355+
val localFeeratePerKw = feeConf.getCommitmentFeerate(commitments.remoteNodeId, commitments.channelVersion, commitments.capacity, None)
356356
val remoteFeeratePerKw = commitments.localCommit.spec.feeratePerKw +: commitments.remoteChanges.all.collect { case f: UpdateFee => f.feeratePerKw }
357-
remoteFeeratePerKw.find(feerate => feeConf.maxFeerateMismatchFor(commitments.remoteNodeId).isFeeDiffTooHigh(commitments.channelVersion, localFeeratePerKw, feerate)) match {
357+
remoteFeeratePerKw.find(feerate => feeConf.feerateToleranceFor(commitments.remoteNodeId).isFeeDiffTooHigh(commitments.channelVersion, localFeeratePerKw, feerate)) match {
358358
case Some(feerate) => return Left(FeerateTooDifferent(commitments.channelId, localFeeratePerKw = localFeeratePerKw, remoteFeeratePerKw = feerate))
359359
case None =>
360360
}
@@ -501,9 +501,9 @@ object Commitments {
501501
Left(FeerateTooSmall(commitments.channelId, remoteFeeratePerKw = fee.feeratePerKw))
502502
} else {
503503
Metrics.RemoteFeeratePerKw.withoutTags().record(fee.feeratePerKw.toLong)
504-
val localFeeratePerKw = feeConf.getCommitmentFeerate(commitments.channelVersion, commitments.capacity, None)
504+
val localFeeratePerKw = feeConf.getCommitmentFeerate(commitments.remoteNodeId, commitments.channelVersion, commitments.capacity, None)
505505
log.info("remote feeratePerKw={}, local feeratePerKw={}, ratio={}", fee.feeratePerKw, localFeeratePerKw, fee.feeratePerKw.toLong.toDouble / localFeeratePerKw.toLong)
506-
if (feeConf.maxFeerateMismatchFor(commitments.remoteNodeId).isFeeDiffTooHigh(commitments.channelVersion, localFeeratePerKw, fee.feeratePerKw) && commitments.hasPendingOrProposedHtlcs) {
506+
if (feeConf.feerateToleranceFor(commitments.remoteNodeId).isFeeDiffTooHigh(commitments.channelVersion, localFeeratePerKw, fee.feeratePerKw) && commitments.hasPendingOrProposedHtlcs) {
507507
Left(FeerateTooDifferent(commitments.channelId, localFeeratePerKw = localFeeratePerKw, remoteFeeratePerKw = fee.feeratePerKw))
508508
} else {
509509
// NB: we check that the funder can afford this new fee even if spec allows to do it at next signature

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@ object Helpers {
116116
}
117117

118118
// BOLT #2: The receiving node MUST fail the channel if: it considers feerate_per_kw too small for timely processing or unreasonably large.
119-
val localFeeratePerKw = nodeParams.onChainFeeConf.getCommitmentFeerate(channelVersion, open.fundingSatoshis, None)
120-
if (nodeParams.onChainFeeConf.maxFeerateMismatchFor(remoteNodeId).isFeeDiffTooHigh(channelVersion, localFeeratePerKw, open.feeratePerKw)) return Left(FeerateTooDifferent(open.temporaryChannelId, localFeeratePerKw, open.feeratePerKw))
119+
val localFeeratePerKw = nodeParams.onChainFeeConf.getCommitmentFeerate(remoteNodeId, channelVersion, open.fundingSatoshis, None)
120+
if (nodeParams.onChainFeeConf.feerateToleranceFor(remoteNodeId).isFeeDiffTooHigh(channelVersion, localFeeratePerKw, open.feeratePerKw)) return Left(FeerateTooDifferent(open.temporaryChannelId, localFeeratePerKw, open.feeratePerKw))
121121
// only enforce dust limit check on mainnet
122122
if (nodeParams.chainHash == Block.LivenetGenesisBlock.hash) {
123123
if (open.dustLimitSatoshis < Channel.MIN_DUSTLIMIT) return Left(DustLimitTooSmall(open.temporaryChannelId, open.dustLimitSatoshis, Channel.MIN_DUSTLIMIT))

eclair-core/src/main/scala/fr/acinq/eclair/io/Peer.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ class Peer(val nodeParams: NodeParams, remoteNodeId: PublicKey, watcher: ActorRe
126126
val (channel, localParams) = createNewChannel(nodeParams, d.localFeatures, funder = true, c.fundingSatoshis, origin_opt = Some(sender), channelVersion)
127127
c.timeout_opt.map(openTimeout => context.system.scheduler.scheduleOnce(openTimeout.duration, channel, Channel.TickChannelOpenTimeout)(context.dispatcher))
128128
val temporaryChannelId = randomBytes32
129-
val channelFeeratePerKw = nodeParams.onChainFeeConf.getCommitmentFeerate(channelVersion, c.fundingSatoshis, None)
129+
val channelFeeratePerKw = nodeParams.onChainFeeConf.getCommitmentFeerate(remoteNodeId, channelVersion, c.fundingSatoshis, None)
130130
val fundingTxFeeratePerKw = c.fundingTxFeeratePerKw_opt.getOrElse(nodeParams.onChainFeeConf.feeEstimator.getFeeratePerKw(target = nodeParams.onChainFeeConf.feeTargets.fundingBlockTarget))
131131
log.info(s"requesting a new channel with fundingSatoshis=${c.fundingSatoshis}, pushMsat=${c.pushMsat} and fundingFeeratePerByte=${c.fundingTxFeeratePerKw_opt} temporaryChannelId=$temporaryChannelId localParams=$localParams")
132132
channel ! INPUT_INIT_FUNDER(temporaryChannelId, c.fundingSatoshis, c.pushMsat, channelFeeratePerKw, fundingTxFeeratePerKw, c.initialRelayFees_opt, localParams, d.peerConnection, d.remoteInit, c.channelFlags.getOrElse(nodeParams.channelFlags), channelVersion)

eclair-core/src/test/scala/fr/acinq/eclair/StartupSpec.scala

+7-5
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717
package fr.acinq.eclair
1818

1919
import com.typesafe.config.{Config, ConfigFactory}
20-
import fr.acinq.bitcoin.Block
2120
import fr.acinq.bitcoin.Crypto.PublicKey
21+
import fr.acinq.bitcoin.{Block, SatoshiLong}
2222
import fr.acinq.eclair.FeatureSupport.{Mandatory, Optional}
2323
import fr.acinq.eclair.Features._
24-
import fr.acinq.eclair.blockchain.fee.FeerateTolerance
24+
import fr.acinq.eclair.blockchain.fee.{FeeratePerByte, FeeratePerKw, FeerateTolerance}
2525
import fr.acinq.eclair.crypto.keymanager.{LocalChannelKeyManager, LocalNodeKeyManager}
2626
import org.scalatest.funsuite.AnyFunSuite
2727
import scodec.bits.{ByteVector, HexStringSyntax}
@@ -156,23 +156,25 @@ class StartupSpec extends AnyFunSuite {
156156
| feerate-tolerance {
157157
| ratio-low = 0.1
158158
| ratio-high = 15.0
159+
| anchor-output-max-commit-feerate = 15
159160
| }
160161
| },
161162
| {
162163
| nodeid = "02bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
163164
| feerate-tolerance {
164165
| ratio-low = 0.75
165166
| ratio-high = 5.0
167+
| anchor-output-max-commit-feerate = 5
166168
| }
167169
| },
168170
| ]
169171
""".stripMargin
170172
)
171173

172174
val nodeParams = makeNodeParamsWithDefaults(perNodeConf.withFallback(defaultConf))
173-
assert(nodeParams.onChainFeeConf.maxFeerateMismatchFor(PublicKey(hex"02aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")) === FeerateTolerance(0.1, 15.0))
174-
assert(nodeParams.onChainFeeConf.maxFeerateMismatchFor(PublicKey(hex"02bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")) === FeerateTolerance(0.75, 5.0))
175-
assert(nodeParams.onChainFeeConf.maxFeerateMismatchFor(PublicKey(hex"02cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc")) === FeerateTolerance(0.5, 10.0))
175+
assert(nodeParams.onChainFeeConf.feerateToleranceFor(PublicKey(hex"02aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")) === FeerateTolerance(0.1, 15.0, FeeratePerKw(FeeratePerByte(15 sat))))
176+
assert(nodeParams.onChainFeeConf.feerateToleranceFor(PublicKey(hex"02bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")) === FeerateTolerance(0.75, 5.0, FeeratePerKw(FeeratePerByte(5 sat))))
177+
assert(nodeParams.onChainFeeConf.feerateToleranceFor(PublicKey(hex"02cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc")) === FeerateTolerance(0.5, 10.0, FeeratePerKw(FeeratePerByte(10 sat))))
176178
}
177179

178180
test("NodeParams should fail if htlc-minimum-msat is set to 0") {

0 commit comments

Comments
 (0)