diff --git a/src/commonMain/kotlin/fr/acinq/lightning/NodeParams.kt b/src/commonMain/kotlin/fr/acinq/lightning/NodeParams.kt index 9f3e26823..da7e7fd6f 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/NodeParams.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/NodeParams.kt @@ -218,7 +218,7 @@ data class NodeParams( enableTrampolinePayment = true, zeroConfPeers = emptySet(), paymentRecipientExpiryParams = RecipientCltvExpiryParams(CltvExpiryDelta(75), CltvExpiryDelta(200)), - liquidityPolicy = MutableStateFlow(LiquidityPolicy.Auto(maxAbsoluteFee = 2_000.sat, maxRelativeFeeBasisPoints = 3_000 /* 3000 = 30 % */)) + liquidityPolicy = MutableStateFlow(LiquidityPolicy.Auto(maxAbsoluteFee = 2_000.sat, maxRelativeFeeBasisPoints = 3_000 /* 3000 = 30 % */, alwaysAllowPayToOpen = false)) ) sealed class Chain(val name: String, private val genesis: Block) { diff --git a/src/commonMain/kotlin/fr/acinq/lightning/payment/LiquidityPolicy.kt b/src/commonMain/kotlin/fr/acinq/lightning/payment/LiquidityPolicy.kt index 4df7c91ee..10cd58ceb 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/payment/LiquidityPolicy.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/payment/LiquidityPolicy.kt @@ -3,7 +3,6 @@ package fr.acinq.lightning.payment import fr.acinq.bitcoin.Satoshi import fr.acinq.lightning.LiquidityEvents import fr.acinq.lightning.MilliSatoshi -import fr.acinq.lightning.utils.LoggingContext import fr.acinq.lightning.utils.MDCLogger import fr.acinq.lightning.utils.toMilliSatoshi @@ -16,8 +15,9 @@ sealed class LiquidityPolicy { * Allow automated liquidity managements, within relative and absolute fee limits. Both conditions must be met. * @param maxAbsoluteFee max absolute fee * @param maxRelativeFeeBasisPoints max relative fee (all included: service fee and mining fee) (1_000 bips = 10 %) + * @param alwaysAllowPayToOpen always accept pay-to-open */ - data class Auto(val maxAbsoluteFee: Satoshi, val maxRelativeFeeBasisPoints: Int) : LiquidityPolicy() { + data class Auto(val maxAbsoluteFee: Satoshi, val maxRelativeFeeBasisPoints: Int, val alwaysAllowPayToOpen: Boolean) : LiquidityPolicy() { /** Maximum fee that we are willing to pay for a particular amount */ fun maxFee(amount: MilliSatoshi) = maxAbsoluteFee.toMilliSatoshi().min(amount * maxRelativeFeeBasisPoints / 10_000) } @@ -26,13 +26,17 @@ sealed class LiquidityPolicy { fun maybeReject(amount: MilliSatoshi, fee: MilliSatoshi, source: LiquidityEvents.Source, logger: MDCLogger): LiquidityEvents.Rejected? { return when (this) { is Disable -> LiquidityEvents.Rejected.Reason.PolicySetToDisabled - is Auto -> { - val maxAllowedFee = maxFee(amount) - logger.info { "liquidity policy check: fee=$fee maxAllowedFee=$maxAllowedFee policy=$this" } - if (fee > maxAllowedFee) { - LiquidityEvents.Rejected.Reason.TooExpensive(maxAllowed = maxAllowedFee, actual = fee) - } else null - } + is Auto -> + if (source == LiquidityEvents.Source.OffChainPayment && alwaysAllowPayToOpen) { + logger.info { "liquidity policy check: fee=$fee maxAllowedFee=bypassed policy=$this" } + null + } else { + val maxAllowedFee = maxFee(amount) + logger.info { "liquidity policy check: fee=$fee maxAllowedFee=$maxAllowedFee policy=$this" } + if (fee > maxAllowedFee) { + LiquidityEvents.Rejected.Reason.TooExpensive(maxAllowed = maxAllowedFee, actual = fee) + } else null + } }?.let { reason -> LiquidityEvents.Rejected(amount, fee, source, reason) } }