Browse Source

MPP: refactor code

master
ThomasV 5 years ago
parent
commit
64c9ddb88d
  1. 87
      electrum/lnworker.py

87
electrum/lnworker.py

@ -1378,16 +1378,6 @@ class LNWallet(LNWorker):
node_features=trampoline_features)) node_features=trampoline_features))
return route return route
def channels_with_funds(self) -> Dict[bytes, int]:
"""Determines a dict of channels (keyed by channel id in bytes) that
maps to their spendable amounts."""
with self.lock:
channels = {}
for cid, chan in self._channels.items():
spend_amount = int(chan.available_to_spend(HTLCOwner.LOCAL))
channels[cid] = spend_amount
return channels
@profiler @profiler
def create_routes_for_payment( def create_routes_for_payment(
self, self,
@ -1402,8 +1392,8 @@ class LNWallet(LNWorker):
We first try to conduct the payment over a single channel. If that fails We first try to conduct the payment over a single channel. If that fails
and mpp is supported by the receiver, we will split the payment.""" and mpp is supported by the receiver, we will split the payment."""
# try to send over a single channel
try: # to send over a single channel try:
routes = [self.create_route_for_payment( routes = [self.create_route_for_payment(
amount_msat, amount_msat,
invoice_pubkey, invoice_pubkey,
@ -1414,49 +1404,40 @@ class LNWallet(LNWorker):
full_path=full_path full_path=full_path
)] )]
except NoPathFound: except NoPathFound:
if invoice_features & LnFeatures.BASIC_MPP_OPT: if not invoice_features & LnFeatures.BASIC_MPP_OPT:
# Create split configurations that are rated according to our raise
# preference (low rating=high preference). channels_with_funds = dict([
split_configurations = suggest_splits( (cid, int(chan.available_to_spend(HTLCOwner.LOCAL)))
amount_msat, for cid, chan in self._channels.items()])
self.channels_with_funds() # Create split configurations that are rated according to our
) # preference -funds = (low rating=high preference).
split_configurations = suggest_splits(amount_msat, channels_with_funds)
self.logger.info("Created the following splitting configurations.") for s in split_configurations:
for s in split_configurations: self.logger.info(f"trying split configuration: {s[0]} rating: {s[1]}")
self.logger.info(f"{s[0]} rating: {s[1]}")
routes = [] routes = []
for s in split_configurations: try:
try: for chanid, part_amount_msat in s[0].items():
for chanid, part_amount_msat in s[0].items(): if part_amount_msat:
if part_amount_msat: channel = self.channels[chanid]
channel = self.channels[chanid] # It could happen that the pathfinding uses a channel
# It could happen that the pathfinding uses a channel # in the graph multiple times, meaning we could exhaust
# in the graph multiple times, meaning we could exhaust # its capacity. This could be dealt with by temporarily
# its capacity. This could be dealt with by temporarily # iteratively blacklisting channels for this mpp attempt.
# iteratively blacklisting channels for this mpp attempt. route, amt = self.create_route_for_payment(
route, amt = self.create_route_for_payment( part_amount_msat,
part_amount_msat, invoice_pubkey,
invoice_pubkey, min_cltv_expiry,
min_cltv_expiry, r_tags,
r_tags, invoice_features,
invoice_features, channel,
channel, full_path=None)
full_path=None routes.append((route, amt))
) break
routes.append((route, amt)) except NoPathFound:
break continue
except NoPathFound:
routes = []
continue
else: else:
raise raise NoPathFound
return routes
if not routes:
raise NoPathFound
else:
return routes
def create_route_for_payment( def create_route_for_payment(
self, self,

Loading…
Cancel
Save