@@ -232,7 +232,7 @@ class IncomingPaymentHandler(val nodeParams: NodeParams, val db: PaymentsDb) {
232232 nodeParams._nodeEvents .emit(LiquidityEvents .Rejected (payment.amountReceived, 0 .msat, LiquidityEvents .Source .OffChainPayment , LiquidityEvents .Rejected .Reason .TooManyParts (payment.parts.size)))
233233 rejectPayment(payment, incomingPayment, TemporaryNodeFailure )
234234 }
235- willAddHtlcParts.isNotEmpty() -> when (val result = validateOnTheFlyFundingRate(willAddHtlcParts.map { it.amount }.sum(), remoteFeatures, currentFeerate, remoteFundingRates)) {
235+ willAddHtlcParts.isNotEmpty() -> when (val result = validateOnTheFlyFundingRate(willAddHtlcParts.map { it.amount }.sum(), remoteFeatures, currentFeeCredit, currentFeerate, remoteFundingRates)) {
236236 is Either .Left -> {
237237 logger.warning { " rejecting on-the-fly funding: reason=${result.value.reason} " }
238238 nodeParams._nodeEvents .emit(result.value)
@@ -241,13 +241,17 @@ class IncomingPaymentHandler(val nodeParams: NodeParams, val db: PaymentsDb) {
241241 is Either .Right -> {
242242 val (requestedAmount, fundingRate) = result.value
243243 val addToFeeCredit = run {
244- val featureOk = nodeParams.features.hasFeature( Feature . FundingFeeCredit ) && remoteFeatures.hasFeature( Feature .FundingFeeCredit )
244+ val featureOk = Features .canUseFeature(nodeParams.features, remoteFeatures, Feature .FundingFeeCredit )
245245 // We may need to use a higher feerate than the current value depending on whether this is a new channel or not,
246- // and whether we have enough balance. We keep adding to our fee credit until we haven't reached the worst case
247- // scenario in terms of fees we need to pay, otherwise we may not have enough to actually pay the liquidity fees.
248- val feerateThreshold = currentFeerate * AddLiquidityForIncomingPayment .SpliceWithNoBalanceFeerateRatio
249- val feeCreditThreshold = fundingRate.fees(feerateThreshold, requestedAmount, requestedAmount, isChannelCreation = true ).total
250- val amountBelowThreshold = (payment.amountReceived + currentFeeCredit).truncateToSatoshi() < feeCreditThreshold
246+ // and whether we have enough balance. We keep adding to our fee credit until we reach the worst case scenario
247+ // in terms of fees we need to pay, otherwise we may not have enough to actually pay the liquidity fees.
248+ val maxFeerate = currentFeerate * AddLiquidityForIncomingPayment .SpliceWithNoBalanceFeerateRatio
249+ val maxLiquidityFees = fundingRate.fees(maxFeerate, requestedAmount, requestedAmount, isChannelCreation = true ).total.toMilliSatoshi()
250+ val feeCreditThreshold = when (val policy = nodeParams.liquidityPolicy.value) {
251+ LiquidityPolicy .Disable -> maxLiquidityFees
252+ is LiquidityPolicy .Auto -> maxLiquidityFees.min(policy.maxAllowedFeeCredit)
253+ }
254+ val amountBelowThreshold = (willAddHtlcParts.map { it.amount }.sum() + currentFeeCredit) <= feeCreditThreshold
251255 featureOk && amountBelowThreshold
252256 }
253257 when {
@@ -340,7 +344,13 @@ class IncomingPaymentHandler(val nodeParams: NodeParams, val db: PaymentsDb) {
340344 return ProcessAddResult .Rejected (actions, incomingPayment)
341345 }
342346
343- private fun validateOnTheFlyFundingRate (willAddHtlcAmount : MilliSatoshi , remoteFeatures : Features , currentFeerate : FeeratePerKw , remoteFundingRates : LiquidityAds .WillFundRates ? ): Either <LiquidityEvents .Rejected , Pair <Satoshi , LiquidityAds .FundingRate >> {
347+ private fun validateOnTheFlyFundingRate (
348+ willAddHtlcAmount : MilliSatoshi ,
349+ remoteFeatures : Features ,
350+ currentFeeCredit : MilliSatoshi ,
351+ currentFeerate : FeeratePerKw ,
352+ remoteFundingRates : LiquidityAds .WillFundRates ?
353+ ): Either <LiquidityEvents .Rejected , Pair <Satoshi , LiquidityAds .FundingRate >> {
344354 return when (val liquidityPolicy = nodeParams.liquidityPolicy.value) {
345355 is LiquidityPolicy .Disable -> Either .Left (LiquidityEvents .Rejected (willAddHtlcAmount, 0 .msat, LiquidityEvents .Source .OffChainPayment , LiquidityEvents .Rejected .Reason .PolicySetToDisabled ))
346356 is LiquidityPolicy .Auto -> {
@@ -355,17 +365,17 @@ class IncomingPaymentHandler(val nodeParams: NodeParams, val db: PaymentsDb) {
355365 // We don't know at that point if we'll need a channel or if we already have one.
356366 // We must use the worst case fees that applies to channel creation.
357367 val fees = fundingRate.fees(currentFeerate, requestedAmount, requestedAmount, isChannelCreation = true ).total
368+ val canAddToFeeCredit = Features .canUseFeature(nodeParams.features, remoteFeatures, Feature .FundingFeeCredit ) && (willAddHtlcAmount + currentFeeCredit) <= liquidityPolicy.maxAllowedFeeCredit
358369 val rejected = when {
359- // We never reject if we can use the fee credit feature.
360- // We instead add payments to our fee credit until making an on-chain operation becomes acceptable.
361- nodeParams.features.hasFeature(Feature .FundingFeeCredit ) && remoteFeatures.hasFeature(Feature .FundingFeeCredit ) -> null
370+ // We never reject if we can add payments to our fee credit until making an on-chain operation becomes acceptable.
371+ canAddToFeeCredit -> null
362372 // We only initiate on-the-fly funding if the missing amount is greater than the fees paid.
363373 // Otherwise our peer may not be able to claim the funding fees from the relayed HTLCs.
364- willAddHtlcAmount < fees * 2 -> LiquidityEvents .Rejected (
374+ ( willAddHtlcAmount + currentFeeCredit) < fees * 2 -> LiquidityEvents .Rejected (
365375 requestedAmount.toMilliSatoshi(),
366376 fees.toMilliSatoshi(),
367377 LiquidityEvents .Source .OffChainPayment ,
368- LiquidityEvents .Rejected .Reason .MissingOffChainAmountTooLow (willAddHtlcAmount)
378+ LiquidityEvents .Rejected .Reason .MissingOffChainAmountTooLow (willAddHtlcAmount, currentFeeCredit )
369379 )
370380 else -> liquidityPolicy.maybeReject(requestedAmount.toMilliSatoshi(), fees.toMilliSatoshi(), LiquidityEvents .Source .OffChainPayment , logger)
371381 }
0 commit comments