mirror of
https://github.com/bitromortac/lndmanage.git
synced 2026-08-13 12:33:37 +02:00
liqudityhints: extend with mission control data
This commit is contained in:
parent
9eb115de5b
commit
9d758fc05e
5 changed files with 123 additions and 8 deletions
|
|
@ -146,15 +146,19 @@ class LiquidityHint:
|
|||
else:
|
||||
return self.cannot_send_backward
|
||||
|
||||
def update_can_send(self, is_forward_direction: bool, amount: int):
|
||||
timestamp = int(time.time())
|
||||
def update_can_send(self, is_forward_direction: bool, amount: int,
|
||||
timestamp: int = None):
|
||||
if not timestamp:
|
||||
timestamp = int(time.time())
|
||||
if is_forward_direction:
|
||||
self.can_send_forward = AmountHistory(amount, timestamp)
|
||||
else:
|
||||
self.can_send_backward = AmountHistory(amount, timestamp)
|
||||
|
||||
def update_cannot_send(self, is_forward_direction: bool, amount: int):
|
||||
timestamp = int(time.time())
|
||||
def update_cannot_send(self, is_forward_direction: bool, amount: int,
|
||||
timestamp: int = None):
|
||||
if not timestamp:
|
||||
timestamp = int(time.time())
|
||||
if is_forward_direction:
|
||||
self.cannot_send_forward = AmountHistory(amount, timestamp)
|
||||
else:
|
||||
|
|
@ -224,18 +228,20 @@ class LiquidityHintMgr:
|
|||
self._liquidity_hints[node_pair] = hint
|
||||
return hint
|
||||
|
||||
def update_can_send(self, node_from: NodeID, node_to: NodeID, amount_msat: int):
|
||||
def update_can_send(self, node_from: NodeID, node_to: NodeID, amount_msat: int,
|
||||
timestamp: int = None):
|
||||
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)
|
||||
hint.update_can_send(node_from > node_to, amount_msat, timestamp)
|
||||
self._could_route[node_from] += 1
|
||||
|
||||
def update_cannot_send(self, node_from: NodeID, node_to: NodeID, amount: int):
|
||||
def update_cannot_send(self, node_from: NodeID, node_to: NodeID, amount: int,
|
||||
timestamp: int = None):
|
||||
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)
|
||||
hint.update_cannot_send(node_from > node_to, amount, timestamp)
|
||||
self._could_not_route[node_from] += 1
|
||||
|
||||
def update_badness_hint(self, node: NodeID, badness: float):
|
||||
|
|
@ -374,3 +380,20 @@ class LiquidityHintMgr:
|
|||
for k, v in self._liquidity_hints.items():
|
||||
string += f"{k}: {v}\n"
|
||||
return string
|
||||
|
||||
def extend_with_mission_control(self, mc_pairs):
|
||||
for pair in mc_pairs:
|
||||
node_from = pair.node_from.hex()
|
||||
node_to = pair.node_to.hex()
|
||||
|
||||
if pair.history.success_time:
|
||||
self.update_can_send(
|
||||
node_from, node_to, pair.history.success_amt_msat,
|
||||
pair.history.success_time,
|
||||
)
|
||||
|
||||
if pair.history.fail_time:
|
||||
self.update_cannot_send(
|
||||
node_from, node_to, pair.history.fail_amt_msat,
|
||||
pair.history.fail_time,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -90,6 +90,12 @@ class Network:
|
|||
except Exception as e:
|
||||
logger.exception(e)
|
||||
|
||||
# TODO: don't load if we loaded some time ago
|
||||
# we extend our information with data from mission control
|
||||
mc_pairs = self.node.query_mc()
|
||||
self.liquidity_hints.extend_with_mission_control(mc_pairs)
|
||||
self.save_liquidty_hints()
|
||||
|
||||
@profiled
|
||||
def save_liquidty_hints(self):
|
||||
cache_hints_filename = make_cache_filename('liquidity_hints.gpickle')
|
||||
|
|
|
|||
|
|
@ -1039,3 +1039,9 @@ class LndNode:
|
|||
node_to_channel_map[cv['remote_pubkey']].append(c)
|
||||
|
||||
return node_to_channel_map
|
||||
|
||||
def query_mc(self):
|
||||
resp = self._routerrpc.QueryMissionControl(
|
||||
lndrouter.QueryMissionControlRequest()
|
||||
)
|
||||
return resp.pairs
|
||||
|
|
|
|||
79
test/test_liquidityhints.py
Normal file
79
test/test_liquidityhints.py
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
from dataclasses import dataclass
|
||||
from unittest import TestCase, mock
|
||||
|
||||
from lndmanage.lib.data_types import NodePair
|
||||
from lndmanage.lib.liquidityhints import LiquidityHintMgr, AmountHistory
|
||||
|
||||
|
||||
@dataclass
|
||||
class MCPairHistory:
|
||||
fail_amt_msat: int
|
||||
success_amt_msat: int
|
||||
fail_time: int = 0
|
||||
success_time: int = 0
|
||||
|
||||
|
||||
@dataclass
|
||||
class MCPair:
|
||||
node_from: bytes
|
||||
node_to: bytes
|
||||
history: MCPairHistory
|
||||
|
||||
|
||||
class LiquidityTest(TestCase):
|
||||
|
||||
@mock.patch('time.time', mock.MagicMock(return_value=100))
|
||||
def test_load_mission_control(self):
|
||||
mgr = LiquidityHintMgr("pubkey")
|
||||
|
||||
pairs = [
|
||||
# valid pair
|
||||
MCPair(
|
||||
node_from=bytes.fromhex("aa"),
|
||||
node_to=bytes.fromhex("bb"),
|
||||
history=MCPairHistory(
|
||||
success_amt_msat=10000,
|
||||
success_time=1, # to be considered a valid hint
|
||||
fail_amt_msat=30000,
|
||||
fail_time=1, # to be considered a valid hint
|
||||
)
|
||||
),
|
||||
# invalid pair (no timestamps)
|
||||
MCPair(
|
||||
node_from=bytes.fromhex("bb"),
|
||||
node_to=bytes.fromhex("cc"),
|
||||
history=MCPairHistory(
|
||||
fail_amt_msat=30000,
|
||||
success_amt_msat=10000,
|
||||
)
|
||||
)
|
||||
]
|
||||
mgr.extend_with_mission_control(pairs)
|
||||
|
||||
node_pair = NodePair(("aa", "bb"))
|
||||
hint = mgr._liquidity_hints.get(node_pair)
|
||||
# hint from mc:
|
||||
self.assertEqual(
|
||||
AmountHistory(amount=10000, timestamp=1),
|
||||
hint.can_send("aa" > "bb"),
|
||||
)
|
||||
# hint from mc:
|
||||
self.assertEqual(
|
||||
AmountHistory(amount=30000, timestamp=1),
|
||||
hint.cannot_send("aa" > "bb"),
|
||||
)
|
||||
# we conclude for the backward direction from the failure:
|
||||
self.assertEqual(
|
||||
AmountHistory(amount=30000, timestamp=1),
|
||||
hint.can_send("bb" > "aa"),
|
||||
)
|
||||
# we can't say anything about the amount that cannot be sent in the backward
|
||||
# direction
|
||||
self.assertEqual(
|
||||
AmountHistory(),
|
||||
hint.cannot_send("bb" > "aa"),
|
||||
)
|
||||
|
||||
node_pair = NodePair(("bb", "cc"))
|
||||
hint = mgr._liquidity_hints.get(node_pair)
|
||||
self.assertIsNone(hint)
|
||||
|
|
@ -19,6 +19,7 @@ def new_test_graph(graph: Dict):
|
|||
# we need to init the node interface with a public key
|
||||
class MockNode:
|
||||
pub_key = 'A'
|
||||
query_mc = lambda x: {}
|
||||
|
||||
# we disable cached graph reading
|
||||
with mock.patch.object(Network, 'load_graph', return_value=None):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue