1
0

lnrouter: change edge cost estimate (distance metric)

Old estimate was heavily biased towards simply minimising CLTV sum.
(fees had a too low weight; typically they were ~noise)
Now also take payment_amount into account.
This commit is contained in:
SomberNight
2020-03-03 02:12:42 +01:00
parent 367d30d6c0
commit cdb72509a7
2 changed files with 16 additions and 10 deletions

View File

@@ -131,7 +131,7 @@ class LNPathFinder(Logger):
def _edge_cost(self, short_channel_id: bytes, start_node: bytes, end_node: bytes,
payment_amt_msat: int, ignore_costs=False, is_mine=False, *,
my_channels: Dict[ShortChannelID, 'Channel'] = None) -> Tuple[float, int]:
"""Heuristic cost of going through a channel.
"""Heuristic cost (distance metric) of going through a channel.
Returns (heuristic_cost, fee_for_edge_msat).
"""
channel_info = self.channel_db.get_channel_info(short_channel_id, my_channels=my_channels)
@@ -157,12 +157,20 @@ class LNPathFinder(Logger):
return float('inf'), 0 # payment amount too large
if not route_edge.is_sane_to_use(payment_amt_msat):
return float('inf'), 0 # thanks but no thanks
fee_msat = route_edge.fee_for_edge(payment_amt_msat) if not ignore_costs else 0
# TODO revise
# paying 10 more satoshis ~ waiting one more block
fee_cost = fee_msat / 1000 / 10
cltv_cost = route_edge.cltv_expiry_delta if not ignore_costs else 0
return cltv_cost + fee_cost + 1, fee_msat
# Distance metric notes: # TODO constants are ad-hoc
# ( somewhat based on https://github.com/lightningnetwork/lnd/pull/1358 )
# - Edges have a base cost. (more edges -> less likely none will fail)
# - The larger the payment amount, and the longer the CLTV,
# the more irritating it is if the HTLC gets stuck.
# - Paying lower fees is better. :)
base_cost = 500 # one more edge ~ paying 500 msat more fees
if ignore_costs:
return base_cost, 0
fee_msat = route_edge.fee_for_edge(payment_amt_msat)
cltv_cost = route_edge.cltv_expiry_delta * payment_amt_msat * 15 / 1_000_000_000
overall_cost = base_cost + fee_msat + cltv_cost
return overall_cost, fee_msat
@profiler
def find_path_for_payment(self, nodeA: bytes, nodeB: bytes,