Add an onchain matcher

The onchain matcher offers the possibility to enforce policies
depending on the current onchain fees. The confirmation target
can be configured by the user (default: 6).
This commit is contained in:
feelancer21 2024-05-29 21:32:18 +02:00
parent 6ddcd1d80a
commit 401101f03b
No known key found for this signature in database
GPG key ID: 1F7071EE8449729C
4 changed files with 34 additions and 4 deletions

View file

@ -193,6 +193,12 @@ Currently available properties:
| **node.min_shared_ratio_active** | match on active channels ratio with us |0..1|
| **node.max_shared_ratio_inactive** | match on inactive channels ratio with us|0..1|
| **node.min_shared_ratio_inactive** | match on inactive channels ratio with us|0..1|
|||
|ONCHAIN||
| **onchain.conf_target** | defines the confirmation target that is used for the determination of the onchain fee rate (default: 6)|# blocks|
| **onchain.min_fee_rate** | match on the onchain fee rate|# sat per vbyte|
| **onchain.max_fee_rate** | match on the onchain fee rate|# sat per vbyte|
File references should contain 1 item per line
### Strategies

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
import sys
import re
from .strategy import StrategyDelegate
from .strategy import StrategyDelegate, DEFAULT_CONF_TARGET
from . import fmt
def debug(message):
@ -108,8 +108,9 @@ class Policies:
def eval_matchers(self, channel, policy, policy_conf):
map = {
'chan' : self.match_by_chan,
'node' : self.match_by_node
'chan' : self.match_by_chan,
'node' : self.match_by_node,
'onchain': self.match_by_onchain
}
namespaces = []
for key in policy_conf.keys():
@ -379,6 +380,23 @@ class Policies:
return False
return True
def match_by_onchain(self, channel, config):
accepted = ['min_fee_rate', 'max_fee_rate', 'conf_target']
for key in config.keys():
if key.split(".")[0] == 'onchain' and key.split(".")[1] not in accepted:
raise Exception("Unknown property '%s'" % key)
fee_rate = self.lnd.get_fee_estimate(config.getint('onchain.conf_target', DEFAULT_CONF_TARGET))
if 'onchain.max_fee_rate' in config and not config.getfloat('onchain.max_fee_rate') >= fee_rate:
return False
if 'onchain.min_fee_rate' in config and not config.getfloat('onchain.min_fee_rate') <= fee_rate:
return False
return True
# simple minutes/hours/days format, e.g. '5m', '3h'
def parse_activity_period(self, period):

View file

@ -13,6 +13,7 @@ def debug(message):
KEEP='keep'
DONTCARE='dontcare'
DEFAULT_CONF_TARGET=6
def is_defined(x):
return x not in [KEEP, DONTCARE] and x is not None
@ -206,7 +207,7 @@ def strategy_onchain_fee(channel, policy, **kwargs):
if policy.getint('min_fee_ppm_delta',-1) < 0:
policy.set('min_fee_ppm_delta', 10) # set delta to 10 if not defined
numblocks = policy.getint('onchain_fee_numblocks', 6)
numblocks = policy.getint('onchain_fee_numblocks', DEFAULT_CONF_TARGET)
sat_per_byte = lnd.get_fee_estimate(numblocks)
if sat_per_byte < 1:
return (None, None, None, None, None)

View file

@ -16,6 +16,11 @@ min_fee_ppm_delta = 5
chan.max_base_fee_msat = 0
base_fee_msat = 0
[onchain-congestion]
# if the onchain fee rate is high (>= 500 sat/vbyte) we increase the base fee to 5 sat
onchan.min_fee_rate = 500
base_fee_msat = 5_000
[ignored_channels]
# don't let charge-lnd set fees (strategy=ignore) for channels to/from the specified nodes
node.id = 02da8d5a759ee9e4438da617cfdb61c87f723fb76c4b6371b877d0347abe953a4f,