mirror of
https://github.com/aljazceru/plugins.git
synced 2025-12-23 16:14:20 +01:00
automatic rebalance: review fixes part 2
This commit is contained in:
committed by
Michael Schmoock
parent
06d771539d
commit
e2ed65e187
@@ -5,10 +5,11 @@ import time
|
||||
import uuid
|
||||
|
||||
plugin = Plugin()
|
||||
plugin.rebalance_stop = False
|
||||
|
||||
|
||||
def setup_routing_fees(plugin, route, msatoshi):
|
||||
delay = int(plugin.get_option('cltv-final'))
|
||||
delay = plugin.cltv_final
|
||||
for r in reversed(route):
|
||||
r['msatoshi'] = msatoshi.millisatoshis
|
||||
r['amount_msat'] = msatoshi
|
||||
@@ -174,7 +175,7 @@ def rebalance(plugin, outgoing_scid, incoming_scid, msatoshi: Millisatoshi=None,
|
||||
for channel in mychannels:
|
||||
excludes += [channel['short_channel_id'] + '/0', channel['short_channel_id'] + '/1']
|
||||
|
||||
while int(time.time()) - start_ts < retry_for and not plugin.get_option("rebalance-stop"):
|
||||
while int(time.time()) - start_ts < retry_for and not plugin.rebalance_stop:
|
||||
r = plugin.rpc.getroute(incoming_node_id, msatoshi, riskfactor=1, cltv=9, fromid=outgoing_node_id, exclude=excludes)
|
||||
route_mid = r['route']
|
||||
route = [route_out] + route_mid + [route_in]
|
||||
@@ -336,10 +337,7 @@ def get_max_amount(i: int, min_amount: int, enough_liquidity: int):
|
||||
|
||||
def get_max_fee(plugin: Plugin, msat: int):
|
||||
# TODO: sanity check
|
||||
base = int(plugin.get_option("fee-base"))
|
||||
ppm = int(plugin.get_option("fee-per-satoshi"))
|
||||
feeratio = float(plugin.get_option("feeratio"))
|
||||
return int((base + ppm * msat / 1000000) * feeratio)
|
||||
return int((plugin.basefee + plugin.ppmfee * msat / 1000000) * plugin.feeratio)
|
||||
|
||||
|
||||
def get_chan(plugin: Plugin, scid: str):
|
||||
@@ -361,18 +359,19 @@ def maybe_rebalance_pairs(plugin: Plugin, ch1, ch2, failed_pairs: list):
|
||||
result = {"success": False, "fee_spent": 0}
|
||||
if scid1 + ":" + scid2 in failed_pairs:
|
||||
return result
|
||||
enough_liquidity = int(plugin.get_option("enough-liquidity"))
|
||||
ideal_ratio = float(plugin.get_option("ideal-ratio"))
|
||||
min_amount = int(Millisatoshi(plugin.get_option("min-amount")))
|
||||
min_amount = int(plugin.min_amount)
|
||||
i = 0
|
||||
while not plugin.get_option("rebalance-stop"):
|
||||
amount1 = min(must_send(ch1, enough_liquidity), could_receive(ch2, enough_liquidity))
|
||||
amount2 = min(should_send(ch1, enough_liquidity, ideal_ratio), should_receive(ch2, enough_liquidity, ideal_ratio))
|
||||
amount3 = min(could_send(ch1, enough_liquidity), must_receive(ch2, enough_liquidity))
|
||||
while not plugin.rebalance_stop:
|
||||
amount1 = min(must_send(ch1, plugin.enough_liquidity),
|
||||
could_receive(ch2, plugin.enough_liquidity))
|
||||
amount2 = min(should_send(ch1, plugin.enough_liquidity, plugin.ideal_ratio),
|
||||
should_receive(ch2, plugin.enough_liquidity, plugin.ideal_ratio))
|
||||
amount3 = min(could_send(ch1, plugin.enough_liquidity),
|
||||
must_receive(ch2, plugin.enough_liquidity))
|
||||
amount = max(amount1, amount2, amount3)
|
||||
if amount < min_amount:
|
||||
return result
|
||||
amount = int(min(amount, get_max_amount(i, min_amount, enough_liquidity)))
|
||||
amount = int(min(amount, get_max_amount(i, min_amount, plugin.enough_liquidity)))
|
||||
maxfee = get_max_fee(plugin, amount)
|
||||
plugin.log(f"Try to rebalance: {scid1} -> {scid2}; amount={amount:,} msat; maxfee={maxfee:,} msat")
|
||||
try:
|
||||
@@ -380,10 +379,10 @@ def maybe_rebalance_pairs(plugin: Plugin, ch1, ch2, failed_pairs: list):
|
||||
except Exception:
|
||||
failed_pairs.append(scid1 + ":" + scid2)
|
||||
# rebalance failed, let's try with a smaller amount
|
||||
while (get_max_amount(i, min_amount, enough_liquidity) >= amount and
|
||||
get_max_amount(i, min_amount, enough_liquidity) != get_max_amount(i + i, min_amount, enough_liquidity)):
|
||||
while (get_max_amount(i, min_amount, plugin.enough_liquidity) >= amount and
|
||||
get_max_amount(i, min_amount, plugin.enough_liquidity) != get_max_amount(i + i, min_amount, plugin.enough_liquidity)):
|
||||
i += 1
|
||||
if amount > get_max_amount(i, min_amount, enough_liquidity):
|
||||
if amount > get_max_amount(i, min_amount, plugin.enough_liquidity):
|
||||
continue
|
||||
return result
|
||||
plugin.log(f"Rebalance succeeded: {res}")
|
||||
@@ -402,7 +401,7 @@ def maybe_rebalance_once(plugin: Plugin, failed_pairs: list):
|
||||
for ch1 in channels:
|
||||
for ch2 in channels:
|
||||
result = maybe_rebalance_pairs(plugin, ch1, ch2, failed_pairs)
|
||||
if result["success"] or plugin.get_option("rebalance-stop"):
|
||||
if result["success"] or plugin.rebalance_stop:
|
||||
return result
|
||||
return {"success": False, "fee_spent": 0}
|
||||
|
||||
@@ -410,18 +409,16 @@ def maybe_rebalance_once(plugin: Plugin, failed_pairs: list):
|
||||
def rebalanceall_thread(plugin: Plugin):
|
||||
try:
|
||||
channels = get_our_channels(plugin)
|
||||
enough_liquidity = get_enough_liquidity_threshold(channels)
|
||||
ideal_ratio = get_ideal_ratio(channels, enough_liquidity)
|
||||
plugin.log(f"Automatic rebalance is running with enough liquidity threshold: {enough_liquidity:,} msat, "
|
||||
f"ideal liquidity ratio: {ideal_ratio * 100:.2f}%, "
|
||||
f"min rebalancable amount: {int(Millisatoshi(plugin.get_option('min-amount'))):,} msat, "
|
||||
f"feeratio: {plugin.get_option('feeratio')}")
|
||||
plugin.options["enough-liquidity"]["value"] = enough_liquidity
|
||||
plugin.options["ideal-ratio"]["value"] = ideal_ratio
|
||||
plugin.enough_liquidity = get_enough_liquidity_threshold(channels)
|
||||
plugin.ideal_ratio = get_ideal_ratio(channels, plugin.enough_liquidity)
|
||||
plugin.log(f"Automatic rebalance is running with enough liquidity threshold: {plugin.enough_liquidity:,} msat, "
|
||||
f"ideal liquidity ratio: {plugin.ideal_ratio * 100:.2f}%, "
|
||||
f"min rebalancable amount: {int(plugin.min_amount):,} msat, "
|
||||
f"feeratio: {plugin.feeratio}")
|
||||
failed_pairs = []
|
||||
success = 0
|
||||
fee_spent = 0
|
||||
while not plugin.get_option("rebalance-stop"):
|
||||
while not plugin.rebalance_stop:
|
||||
result = maybe_rebalance_once(plugin, failed_pairs)
|
||||
if not result["success"]:
|
||||
break
|
||||
@@ -441,11 +438,10 @@ def rebalanceall(plugin: Plugin, min_amount: Millisatoshi = Millisatoshi("50000s
|
||||
It may run for a long time (hours) in the background, but can be stopped with the rebalancestop method.
|
||||
"""
|
||||
if not plugin.mutex.acquire(blocking=False):
|
||||
return {"message": "Rebalance is already running, this may take a while"}
|
||||
return {"message": "Rebalance is already running, this may take a while. To stop it use the cli method 'rebalancestop'."}
|
||||
try:
|
||||
plugin.options["feeratio"]["value"] = float(feeratio)
|
||||
plugin.options["min-amount"]["value"] = Millisatoshi(min_amount)
|
||||
plugin.options["rebalance-stop"]["value"] = False
|
||||
plugin.feeratio = float(feeratio)
|
||||
plugin.min_amount = Millisatoshi(min_amount)
|
||||
t = Thread(target=rebalanceall_thread, args=(plugin, ))
|
||||
t.start()
|
||||
except Exception as e:
|
||||
@@ -458,9 +454,9 @@ def rebalanceall(plugin: Plugin, min_amount: Millisatoshi = Millisatoshi("50000s
|
||||
def rebalancestop(plugin: Plugin):
|
||||
"""It stops the ongoing rebalanceall.
|
||||
"""
|
||||
plugin.options["rebalance-stop"]["value"] = True
|
||||
plugin.rebalance_stop = True
|
||||
plugin.mutex.acquire(blocking=True)
|
||||
plugin.options["rebalance-stop"]["value"] = False
|
||||
plugin.rebalance_stop = False
|
||||
plugin.mutex.release()
|
||||
return {"message": "Rebalance stopped"}
|
||||
|
||||
@@ -468,20 +464,11 @@ def rebalancestop(plugin: Plugin):
|
||||
@plugin.init()
|
||||
def init(options, configuration, plugin):
|
||||
config = plugin.rpc.listconfigs()
|
||||
plugin.options["cltv-final"]["value"] = config.get("cltv-final")
|
||||
plugin.options["fee-base"]["value"] = config.get("fee-base")
|
||||
plugin.options["fee-per-satoshi"]["value"] = config.get("fee-per-satoshi")
|
||||
plugin.options["rebalance-stop"]["value"] = False
|
||||
plugin.cltv_final = config.get("cltv-final")
|
||||
plugin.basefee = config.get("fee-base")
|
||||
plugin.ppmfee = config.get("fee-per-satoshi")
|
||||
plugin.mutex = Lock()
|
||||
plugin.log("Plugin rebalance.py initialized")
|
||||
|
||||
|
||||
plugin.add_option("cltv-final", 10, "Number of blocks for final CheckLockTimeVerify expiry", "int")
|
||||
plugin.add_option("fee-base", 0, "The routing base fee in msat. Will be derived automatically via rpc.listconfigs()", "int")
|
||||
plugin.add_option("fee-per-satoshi", 0, "The routing fee ppm. Will be derived automatically via rpc.listconfigs()", "int")
|
||||
plugin.add_option("feeratio", "0.5", "Rebalance fee in the ratio of our node's default fee. Default 0.5 means it will use max half of our fee.", "string")
|
||||
plugin.add_option("enough-liquidity", 0, "Above this threshold (in msat), a channel's liquidity is big enough. Will be calculated.", "int")
|
||||
plugin.add_option("ideal-ratio", "0.5", "Ideal liquidity ratio for big channels. Will be calculated.", "string")
|
||||
plugin.add_option("min-amount", "50000sat", "The minimum rebalancable amount.", "string")
|
||||
plugin.add_option("rebalance-stop", False, "It stops the ongoing rebalanceall, set by rebalancestop", "flag")
|
||||
plugin.run()
|
||||
|
||||
Reference in New Issue
Block a user