mirror of
https://github.com/aljazceru/plugins.git
synced 2025-12-19 22:24:19 +01:00
feat: calculate optional amount
This commit is contained in:
committed by
Christian Decker
parent
ee9eaa9e31
commit
5efb86da46
@@ -20,6 +20,13 @@ def setup_routing_fees(plugin, route, msatoshi):
|
||||
delay += ch['delay']
|
||||
|
||||
|
||||
def amounts_from_scid(plugin, scid):
|
||||
channels = plugin.rpc.listfunds().get('channels')
|
||||
channel = next(c for c in channels if c['short_channel_id'] == scid)
|
||||
our_msat = Millisatoshi(channel['our_amount_msat'])
|
||||
total_msat = Millisatoshi(channel['amount_msat'])
|
||||
return our_msat, total_msat
|
||||
|
||||
def peer_from_scid(plugin, short_channel_id, my_node_id, payload):
|
||||
channels = plugin.rpc.listchannels(short_channel_id).get('channels')
|
||||
for ch in channels:
|
||||
@@ -54,8 +61,54 @@ def rebalance_fail(plugin, label, payload, success_msg, error=None):
|
||||
raise error
|
||||
|
||||
|
||||
# This function calculates the optimal rebalance amount
|
||||
# based on the selected channels capacity and state.
|
||||
# It will return a value that brings at least one of the channels to balance.
|
||||
# It will raise an error, when this isnt possible.
|
||||
#
|
||||
# EXAMPLE
|
||||
# |------------------- out_total -------------|
|
||||
# OUT -v => |-------- out_ours -------||-- out_theirs --| => +v
|
||||
#
|
||||
# IN +v <= |-- in_ours --||---------- in_theirs ---------| <= -v
|
||||
# |--------- in_total --------------------------|
|
||||
#
|
||||
# CHEAP SOLUTION: take v_min from 50/50 values
|
||||
# O* vo = out_ours - (out_total/2)
|
||||
# I* vi = (in_total/2) - in_ours
|
||||
# return min(vo, vi)
|
||||
#
|
||||
# ... and cover edge cases with exceeding in/out capacity or negative values.
|
||||
# TODO: their_reserve_msat our_reserve_msat spendable_msat
|
||||
def calc_optimal_amount(out_ours, out_total, in_ours, in_total, payload):
|
||||
out_ours, out_total = int(out_ours), int(out_total)
|
||||
in_ours, in_total = int(in_ours), int(in_total)
|
||||
|
||||
in_theirs = in_total - in_ours
|
||||
vo = out_ours - (out_total/2)
|
||||
vi = (in_total/2) - in_ours
|
||||
|
||||
# cases where one option can be eliminated because it exceeds other capacity
|
||||
if vo > in_theirs and vi > 0 and vi < out_ours:
|
||||
return Millisatoshi(vi)
|
||||
if vi > out_ours and vo > 0 and vo < in_theirs:
|
||||
return Millisatoshi(vo)
|
||||
|
||||
# cases where one channel is still capable to bring other to balance
|
||||
if vo < 0 and vi > 0 and vi < out_ours:
|
||||
return Millisatoshi(vi)
|
||||
if vi < 0 and vo > 0 and vo < in_theirs:
|
||||
return Millisatoshi(vo)
|
||||
|
||||
# when both options are possible take the one with least effort
|
||||
if vo > 0 and vo < in_theirs and vi > 0 and vi < out_ours:
|
||||
return Millisatoshi(min(vi, vo))
|
||||
|
||||
raise RpcError("rebalance", payload, {'message': 'rebalancing these channels will make things worse'})
|
||||
|
||||
|
||||
@plugin.method("rebalance")
|
||||
def rebalance(plugin, outgoing_scid, incoming_scid, msatoshi: Millisatoshi,
|
||||
def rebalance(plugin, outgoing_scid, incoming_scid, msatoshi: Millisatoshi=None,
|
||||
maxfeepercent="0.5", retry_for="60", exemptfee: Millisatoshi=Millisatoshi(5000)):
|
||||
"""Rebalancing channel liquidity with circular payments.
|
||||
|
||||
@@ -76,6 +129,13 @@ def rebalance(plugin, outgoing_scid, incoming_scid, msatoshi: Millisatoshi,
|
||||
plugin.log("Outgoing node: %s, channel: %s" % (outgoing_node_id, outgoing_scid))
|
||||
plugin.log("Incoming node: %s, channel: %s" % (incoming_node_id, incoming_scid))
|
||||
|
||||
# If amount was not given, calculate a suitable 50/50 rebalance amount
|
||||
if msatoshi is None:
|
||||
out_ours, out_total = amounts_from_scid(plugin, outgoing_scid)
|
||||
in_ours, in_total = amounts_from_scid(plugin, incoming_scid)
|
||||
msatoshi = calc_optimal_amount(out_ours, out_total, in_ours, in_total, payload)
|
||||
plugin.log("Estimating optimal amount %s" % msatoshi)
|
||||
|
||||
route_out = {'id': outgoing_node_id, 'channel': outgoing_scid}
|
||||
route_in = {'id': my_node_id, 'channel': incoming_scid}
|
||||
start_ts = int(time.time())
|
||||
|
||||
Reference in New Issue
Block a user