mirror of
https://github.com/aljazceru/plugins.git
synced 2025-12-24 08:34:18 +01:00
feeadjuster: set base fee for median strategy
This commit is contained in:
@@ -120,8 +120,11 @@ def get_fees_median(plugin: Plugin, scid: str):
|
||||
and ch['source'] != plugin.our_node_id]
|
||||
if len(channels_to_peer) == 0:
|
||||
return None
|
||||
fees_ppm = [ch['fee_per_millionth'] for ch in channels_to_peer]
|
||||
return {"base": plugin.adj_basefee, "ppm": statistics.median(fees_ppm) * plugin.median_multiplier}
|
||||
# fees > ~5000 (base and ppm) are currently about top 2% of network fee extremists
|
||||
fees_ppm = [ch['fee_per_millionth'] for ch in channels_to_peer if 0 < ch['fee_per_millionth'] < 5000]
|
||||
fees_base = [ch['base_fee_millisatoshi'] for ch in channels_to_peer if 0 < ch['base_fee_millisatoshi'] < 5000]
|
||||
return {"base": statistics.median(fees_base) * plugin.median_multiplier,
|
||||
"ppm": statistics.median(fees_ppm) * plugin.median_multiplier}
|
||||
|
||||
|
||||
def setchannelfee(plugin: Plugin, scid: str, base: int, ppm: int, min_htlc: int = None, max_htlc: int = None):
|
||||
@@ -162,19 +165,19 @@ def maybe_adjust_fees(plugin: Plugin, scids: list):
|
||||
our = plugin.adj_balances[scid]["our"]
|
||||
total = plugin.adj_balances[scid]["total"]
|
||||
percentage = our / total
|
||||
base = plugin.adj_basefee
|
||||
ppm = plugin.adj_ppmfee
|
||||
base = int(plugin.adj_basefee)
|
||||
ppm = int(plugin.adj_ppmfee)
|
||||
|
||||
# select ideal values per channel
|
||||
fees = plugin.fee_strategy(plugin, scid)
|
||||
if fees is not None:
|
||||
base = fees['base']
|
||||
ppm = fees['ppm']
|
||||
base = int(fees['base'])
|
||||
ppm = int(fees['ppm'])
|
||||
|
||||
# reset to normal fees if imbalance is not high enough
|
||||
if (percentage > plugin.imbalance and percentage < 1 - plugin.imbalance):
|
||||
if setchannelfee(plugin, scid, base, ppm):
|
||||
plugin.log(f"Set default fees as imbalance is too low: {scid}")
|
||||
plugin.log(f"Set default fees as imbalance is too low for {scid}: ppm {ppm} base {base}msat")
|
||||
plugin.adj_balances[scid]["last_liquidity"] = our
|
||||
channels_adjusted += 1
|
||||
continue
|
||||
@@ -189,8 +192,8 @@ def maybe_adjust_fees(plugin: Plugin, scids: list):
|
||||
max_htlc = int(total * math.ceil(plugin.max_htlc_steps * percentage) / plugin.max_htlc_steps)
|
||||
else:
|
||||
max_htlc = None
|
||||
if setchannelfee(plugin, scid, int(base), int(ppm * ratio), None, max_htlc):
|
||||
plugin.log(f"Adjusted fees of {scid} with a ratio of {ratio}, set max_htlc to {max_htlc}")
|
||||
if setchannelfee(plugin, scid, base, int(ppm * ratio), None, max_htlc):
|
||||
plugin.log(f"Adjusted fees of {scid} with a ratio of {ratio}: ppm {int(ppm * ratio)} base {base}msat max_htlc {max_htlc}")
|
||||
plugin.adj_balances[scid]["last_liquidity"] = our
|
||||
channels_adjusted += 1
|
||||
return channels_adjusted
|
||||
|
||||
@@ -189,8 +189,8 @@ def test_feeadjuster_imbalance(node_factory):
|
||||
amount = int(chan_total * 0.5)
|
||||
pay(l1, l3, amount)
|
||||
l2.daemon.wait_for_logs([
|
||||
f'Set default fees as imbalance is too low: {scid_A}',
|
||||
f'Set default fees as imbalance is too low: {scid_B}'
|
||||
f'Set default fees as imbalance is too low for {scid_A}',
|
||||
f'Set default fees as imbalance is too low for {scid_B}'
|
||||
])
|
||||
wait_for_fees(l2, scids, default_fees[0])
|
||||
|
||||
@@ -211,8 +211,8 @@ def test_feeadjuster_imbalance(node_factory):
|
||||
# Bringing it back must cause default fees
|
||||
pay(l3, l1, amount)
|
||||
l2.daemon.wait_for_logs([
|
||||
f'Set default fees as imbalance is too low: {scid_A}',
|
||||
f'Set default fees as imbalance is too low: {scid_B}'
|
||||
f'Set default fees as imbalance is too low for {scid_A}',
|
||||
f'Set default fees as imbalance is too low for {scid_B}'
|
||||
])
|
||||
wait_for_fees(l2, scids, default_fees[0])
|
||||
|
||||
@@ -290,3 +290,46 @@ def test_feeadjuster_big_enough_liquidity(node_factory):
|
||||
f"Adjusted fees.*{scid_B}"
|
||||
])
|
||||
wait_for_not_fees(l2, scids, default_fees[0])
|
||||
|
||||
|
||||
@unittest.skipIf(not DEVELOPER, "Too slow without fast gossip")
|
||||
def test_feeadjuster_median(node_factory):
|
||||
"""
|
||||
A rather simple network:
|
||||
|
||||
a b c
|
||||
l1 <=======> l2 <=======> l3 <=======> l4
|
||||
|
||||
l2 will adjust its configuration-set base and proportional fees for
|
||||
channels A and B as l1 and l3 exchange payments.
|
||||
l4 is needed so l2 can make a median peers-of-peer calculation on l3.
|
||||
"""
|
||||
opts = {
|
||||
"fee-base": 1337,
|
||||
"fee-per-satoshi": 42,
|
||||
}
|
||||
l2_opts = {
|
||||
"fee-base": 1000,
|
||||
"fee-per-satoshi": 100,
|
||||
"plugin": plugin_path,
|
||||
"feeadjuster-deactivate-fuzz": None,
|
||||
"feeadjuster-imbalance": 0.5,
|
||||
"feeadjuster-feestrategy": "median"
|
||||
}
|
||||
l1, l2, l3, _ = node_factory.line_graph(4, opts=[opts, l2_opts, opts, opts],
|
||||
wait_for_announce=True)
|
||||
|
||||
scid_a = l2.rpc.listpeerchannels(l1.info["id"])["channels"][0]["short_channel_id"]
|
||||
scid_b = l2.rpc.listpeerchannels(l3.info["id"])["channels"][0]["short_channel_id"]
|
||||
|
||||
# we do a manual feeadjust
|
||||
l2.rpc.feeadjust()
|
||||
l2.daemon.wait_for_logs([
|
||||
f"Adjusted fees.*{scid_a}",
|
||||
f"Adjusted fees.*{scid_b}"
|
||||
])
|
||||
|
||||
# since there is only l4 with channel c towards l3, l2 should take that value
|
||||
chan_b = l2.rpc.listpeerchannels(l3.info['id'])['channels'][0]
|
||||
assert chan_b['fee_base_msat'] == 1337
|
||||
assert chan_b['fee_proportional_millionths'] < 42 # we could do the actual ratio math, but meh
|
||||
|
||||
Reference in New Issue
Block a user