Browse Source

Refactor find_route_for_payment

- remove duplicated code
 - rename variable names to be consistent with the
'path', 'route' terminology
 - compute private route before route
patch-4
ThomasV 4 years ago
parent
commit
391dba7117
  1. 93
      electrum/lnworker.py

93
electrum/lnworker.py

@ -1470,20 +1470,48 @@ class LNWallet(LNWorker):
if chan.short_channel_id is not None
}
blacklist = self.network.channel_blacklist.get_current_list()
for private_route in r_tags:
if len(private_route) == 0:
# first try with routing hints, then without
for private_path in r_tags + [[]]:
private_route = []
path = full_path
if len(private_path) > NUM_MAX_EDGES_IN_PAYMENT_PATH:
continue
if len(private_route) > NUM_MAX_EDGES_IN_PAYMENT_PATH:
continue
border_node_pubkey = private_route[0][0]
if full_path:
# user pre-selected path. check that end of given path coincides with private_route:
if [edge.short_channel_id for edge in full_path[-len(private_route):]] != [edge[1] for edge in private_route]:
continue
path = full_path[:-len(private_route)]
if len(private_path) == 0:
border_node_pubkey = invoice_pubkey
else:
# find path now on public graph, to border node
path = None
border_node_pubkey = private_path[0][0]
# we need to shift the node pubkey by one towards the destination:
private_path_nodes = [edge[0] for edge in private_path][1:] + [invoice_pubkey]
private_path_rest = [edge[1:] for edge in private_path]
prev_node_id = border_node_pubkey
for node_pubkey, edge_rest in zip(private_path_nodes, private_path_rest):
short_channel_id, fee_base_msat, fee_proportional_millionths, cltv_expiry_delta = edge_rest
short_channel_id = ShortChannelID(short_channel_id)
# if we have a routing policy for this edge in the db, that takes precedence,
# as it is likely from a previous failure
channel_policy = self.channel_db.get_policy_for_node(
short_channel_id=short_channel_id,
node_id=prev_node_id,
my_channels=scid_to_my_channels)
if channel_policy:
fee_base_msat = channel_policy.fee_base_msat
fee_proportional_millionths = channel_policy.fee_proportional_millionths
cltv_expiry_delta = channel_policy.cltv_expiry_delta
node_info = self.channel_db.get_node_info_for_node_id(node_id=node_pubkey)
private_route.append(
RouteEdge(
node_id=node_pubkey,
short_channel_id=short_channel_id,
fee_base_msat=fee_base_msat,
fee_proportional_millionths=fee_proportional_millionths,
cltv_expiry_delta=cltv_expiry_delta,
node_features=node_info.features if node_info else 0))
prev_node_id = node_pubkey
if full_path:
# user pre-selected path. check that end of given path coincides with private_route:
if [edge.short_channel_id for edge in full_path[-len(private_path):]] != [edge[1] for edge in private_path]:
continue
path = full_path[:-len(private_path)]
try:
route = self.network.path_finder.find_route(
self.node_keypair.pubkey, border_node_pubkey, amount_msat,
@ -1492,49 +1520,14 @@ class LNWallet(LNWorker):
continue
if not route:
continue
# we need to shift the node pubkey by one towards the destination:
private_route_nodes = [edge[0] for edge in private_route][1:] + [invoice_pubkey]
private_route_rest = [edge[1:] for edge in private_route]
prev_node_id = border_node_pubkey
for node_pubkey, edge_rest in zip(private_route_nodes, private_route_rest):
short_channel_id, fee_base_msat, fee_proportional_millionths, cltv_expiry_delta = edge_rest
short_channel_id = ShortChannelID(short_channel_id)
# if we have a routing policy for this edge in the db, that takes precedence,
# as it is likely from a previous failure
channel_policy = self.channel_db.get_policy_for_node(
short_channel_id=short_channel_id,
node_id=prev_node_id,
my_channels=scid_to_my_channels)
if channel_policy:
fee_base_msat = channel_policy.fee_base_msat
fee_proportional_millionths = channel_policy.fee_proportional_millionths
cltv_expiry_delta = channel_policy.cltv_expiry_delta
node_info = self.channel_db.get_node_info_for_node_id(node_id=node_pubkey)
route.append(
RouteEdge(
node_id=node_pubkey,
short_channel_id=short_channel_id,
fee_base_msat=fee_base_msat,
fee_proportional_millionths=fee_proportional_millionths,
cltv_expiry_delta=cltv_expiry_delta,
node_features=node_info.features if node_info else 0))
prev_node_id = node_pubkey
route = route + private_route
# test sanity
if not is_route_sane_to_use(route, amount_msat, min_cltv_expiry):
self.logger.info(f"rejecting insane route {route}")
route = None
continue
break
# if could not find route using any hint; try without hint now
if route is None:
route = self.network.path_finder.find_route(
self.node_keypair.pubkey, invoice_pubkey, amount_msat,
path=full_path, my_channels=scid_to_my_channels, blacklist=blacklist)
if not route:
raise NoPathFound()
if not is_route_sane_to_use(route, amount_msat, min_cltv_expiry):
self.logger.info(f"rejecting insane route {route}")
raise NoPathFound()
else:
raise NoPathFound()
assert len(route) > 0
if route[-1].node_id != invoice_pubkey:
raise LNPathInconsistent("last node_id != invoice pubkey")

Loading…
Cancel
Save