mirror of
https://github.com/bitromortac/lndmanage.git
synced 2026-08-13 12:33:37 +02:00
liquidityhints: switch to pair based keying
This commit is contained in:
parent
660419b00c
commit
ef31e8948c
3 changed files with 34 additions and 24 deletions
|
|
@ -6,7 +6,7 @@ from math import inf, log
|
|||
|
||||
import logging
|
||||
|
||||
from lib.data_types import NodeID, ShortChannelID
|
||||
from lib.data_types import NodeID, NodePair
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.addHandler(logging.NullHandler())
|
||||
|
|
@ -163,7 +163,7 @@ class LiquidityHintMgr:
|
|||
# TODO: hints based on node pairs only (shadow channels, non-strict forwarding)?
|
||||
def __init__(self, source_node: str):
|
||||
self.source_node = source_node
|
||||
self._liquidity_hints: Dict[ShortChannelID, LiquidityHint] = {}
|
||||
self._liquidity_hints: Dict[NodePair, LiquidityHint] = {}
|
||||
# could_not_route tracks node's failures to route
|
||||
self._could_not_route: Dict[NodeID, int] = defaultdict(int)
|
||||
# could_route tracks node's successes to route
|
||||
|
|
@ -184,22 +184,24 @@ class LiquidityHintMgr:
|
|||
def now(self):
|
||||
return time.time()
|
||||
|
||||
def get_hint(self, channel_id: ShortChannelID) -> LiquidityHint:
|
||||
hint = self._liquidity_hints.get(channel_id)
|
||||
def _get_hint(self, node_pair: NodePair) -> LiquidityHint:
|
||||
hint = self._liquidity_hints.get(node_pair)
|
||||
if not hint:
|
||||
hint = LiquidityHint()
|
||||
self._liquidity_hints[channel_id] = hint
|
||||
self._liquidity_hints[node_pair] = hint
|
||||
return hint
|
||||
|
||||
def update_can_send(self, node_from: NodeID, node_to: NodeID, channel_id: ShortChannelID, amount_msat: int):
|
||||
logger.debug(f" report: can send {amount_msat // 1000} sat over channel {channel_id}")
|
||||
hint = self.get_hint(channel_id)
|
||||
def update_can_send(self, node_from: NodeID, node_to: NodeID, amount_msat: int):
|
||||
node_pair = NodePair((node_from, node_to))
|
||||
logger.debug(f" report: can send {amount_msat // 1000} sat over channel {node_pair}")
|
||||
hint = self._get_hint(node_pair)
|
||||
hint.update_can_send(node_from < node_to, amount_msat)
|
||||
self._could_route[node_from] += 1
|
||||
|
||||
def update_cannot_send(self, node_from: NodeID, node_to: NodeID, channel_id: ShortChannelID, amount: int):
|
||||
logger.debug(f" report: cannot send {amount // 1000} sat over channel {channel_id}")
|
||||
hint = self.get_hint(channel_id)
|
||||
def update_cannot_send(self, node_from: NodeID, node_to: NodeID, amount: int):
|
||||
node_pair = NodePair((node_from, node_to))
|
||||
logger.debug(f" report: cannot send {amount // 1000} sat over channel {node_pair}")
|
||||
hint = self._get_hint(node_pair)
|
||||
hint.update_cannot_send(node_from < node_to, amount)
|
||||
self._could_not_route[node_from] += 1
|
||||
|
||||
|
|
@ -222,12 +224,14 @@ class LiquidityHintMgr:
|
|||
avg_time = self._elapsed_time[node] / nfwd if nfwd else 0
|
||||
logger.debug(f" report: update elapsed time {elapsed_time} +=> {self._elapsed_time[node]} (avg: {avg_time}) (node: {node})")
|
||||
|
||||
def add_htlc(self, node_from: NodeID, node_to: NodeID, channel_id: ShortChannelID):
|
||||
hint = self.get_hint(channel_id)
|
||||
def add_htlc(self, node_from: NodeID, node_to: NodeID):
|
||||
node_pair = NodePair((node_from, node_to))
|
||||
hint = self._get_hint(node_pair)
|
||||
hint.add_htlc(node_from < node_to)
|
||||
|
||||
def remove_htlc(self, node_from: NodeID, node_to: NodeID, channel_id: ShortChannelID):
|
||||
hint = self.get_hint(channel_id)
|
||||
def remove_htlc(self, node_from: NodeID, node_to: NodeID):
|
||||
node_pair = NodePair((node_from, node_to))
|
||||
hint = self._get_hint(node_pair)
|
||||
hint.remove_htlc(node_from < node_to)
|
||||
|
||||
def penalty(self, node_from: NodeID, node_to: NodeID, edge: Dict, amount_msat: int, fee_rate_milli_msat: int) -> float:
|
||||
|
|
@ -255,7 +259,7 @@ class LiquidityHintMgr:
|
|||
if self.source_node in [node_from, ]:
|
||||
return 0
|
||||
# we only evaluate hints here, so use dict get (to not create many hints with self.get_hint)
|
||||
hint = self._liquidity_hints.get(edge['channel_id'])
|
||||
hint = self._liquidity_hints.get(edge['node_pair'])
|
||||
if not hint:
|
||||
can_send, cannot_send, num_inflight_htlcs = None, None, 0
|
||||
else:
|
||||
|
|
@ -305,12 +309,12 @@ class LiquidityHintMgr:
|
|||
self._badness_hints[node_from] *= math.exp(-time_delta / BADNESS_DECAY_SEC)
|
||||
return amount * self._badness_hints[node_from]
|
||||
|
||||
def add_to_blacklist(self, channel_id: ShortChannelID):
|
||||
hint = self.get_hint(channel_id)
|
||||
def add_to_blacklist(self, node_pair: NodePair):
|
||||
hint = self._get_hint(node_pair)
|
||||
now = int(time.time())
|
||||
hint.blacklist_timestamp = now
|
||||
|
||||
def get_blacklist(self) -> Set[ShortChannelID]:
|
||||
def get_blacklist(self) -> Set[NodePair]:
|
||||
now = int(time.time())
|
||||
return set(k for k, v in self._liquidity_hints.items() if now - v.blacklist_timestamp < BLACKLIST_DURATION)
|
||||
|
||||
|
|
|
|||
|
|
@ -151,7 +151,9 @@ class Rebalancer(object):
|
|||
self.node.network.liquidity_hints.update_elapsed_time(source_node, elapsed_time / success_path_length)
|
||||
if failed_hop_index and hop == failed_hop_index:
|
||||
break
|
||||
self.node.network.liquidity_hints.update_can_send(source_node, target_node, channel['chan_id'], amt_msat)
|
||||
self.node.network.liquidity_hints.update_can_send(
|
||||
source_node, target_node, amt_msat,
|
||||
)
|
||||
|
||||
# symmetrically penalize a route about the error source if it failed
|
||||
if failed_hop_index:
|
||||
|
|
@ -206,7 +208,8 @@ class Rebalancer(object):
|
|||
|
||||
# report that channel could not route the amount to liquidity hints
|
||||
self.node.network.liquidity_hints.update_cannot_send(
|
||||
failed_source, failed_target, failed_channel_id, amt_msat)
|
||||
failed_source, failed_target, amt_msat,
|
||||
)
|
||||
|
||||
# report all the previous hops that they could route the amount
|
||||
report_success_up_to_failed_hop(failed_hop)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import networkx as nx
|
|||
|
||||
from test import testing_common
|
||||
|
||||
from lndmanage.lib.data_types import NodePair
|
||||
from lndmanage.lib.network import Network
|
||||
from lndmanage.lib.rating import ChannelRater
|
||||
from lndmanage.lib.pathfinding import dijkstra
|
||||
|
|
@ -44,6 +45,7 @@ def new_test_graph(graph: Dict):
|
|||
network.edges[channel] = {
|
||||
'node1_pub': node,
|
||||
'node2_pub': to_node,
|
||||
'node_pair': NodePair((node, to_node)),
|
||||
'capacity': channel_definition['capacity'],
|
||||
'last_update': None,
|
||||
'channel_id': channel,
|
||||
|
|
@ -61,6 +63,7 @@ def new_test_graph(graph: Dict):
|
|||
channel_id=channel,
|
||||
last_update=None,
|
||||
capacity=channel_definition['capacity'],
|
||||
node_pair=NodePair((node, to_node)),
|
||||
fees={
|
||||
node > to_node: channel_definition['policies'][node > to_node],
|
||||
to_node > node: channel_definition['policies'][to_node > node],
|
||||
|
|
@ -103,16 +106,16 @@ class TestGraph(TestCase):
|
|||
self.assertEqual(['A', 'B', 'E'], path)
|
||||
|
||||
# We report that B cannot send to E
|
||||
network.liquidity_hints.update_cannot_send('B', 'E', 2, 1_000)
|
||||
network.liquidity_hints.update_cannot_send('B', 'E', 1_000)
|
||||
path = dijkstra(network.graph, 'A', 'E', weight=weight_function)
|
||||
self.assertEqual(['A', 'D', 'E'], path)
|
||||
|
||||
# We report that D cannot send to E
|
||||
network.liquidity_hints.update_cannot_send('D', 'E', 5, 1_000)
|
||||
network.liquidity_hints.update_cannot_send('D', 'E', 1_000)
|
||||
path = dijkstra(network.graph, 'A', 'E', weight=weight_function)
|
||||
self.assertEqual(['A', 'B', 'C', 'E'], path)
|
||||
|
||||
# We report that D can send to C
|
||||
network.liquidity_hints.update_can_send('D', 'C', 4, amt_msat + 1000)
|
||||
network.liquidity_hints.update_can_send('D', 'C', amt_msat + 1000)
|
||||
path = dijkstra(network.graph, 'A', 'E', weight=weight_function)
|
||||
self.assertEqual(['A', 'D', 'C', 'E'], path)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue