Repository: spesmilo/electrum
Issue: AttributeError("'Network' object has no attribute 'path_finder'")

Hello! I'm playing with testnet lightning payments and have some troubles. When I pay invoice, I've got an error AttributeError("'Network' object has no attribute 'path_finder'"). On remote node invoice is settled, but in electrum its stuck on Status "In progress"

What I do:
1. Open channel with trampoline "endurance" 
2. Receive some LN payments 
3. Make LN payment 

[electrum_log_20210424T163303Z_197398.log](https://github.com/spesmilo/electrum/files/6370306/electrum_log_20210424T163303Z_197398.log)


Changed files:
electrum/lnworker.py, electrum/network.py, electrum/commands.py

diff --git a/electrum/commands.py b/electrum/commands.py
index 7c5c5ec33..3159f4ed5 100644
--- a/electrum/commands.py
+++ b/electrum/commands.py
@@ -1092,11 +1092,13 @@ class Commands:
 
     @command('n')
     async def clear_ln_blacklist(self):
-        self.network.path_finder.liquidity_hints.clear_blacklist()
+        if self.network.path_finder:
+            self.network.path_finder.liquidity_hints.clear_blacklist()
 
     @command('n')
     async def reset_liquidity_hints(self):
-        self.network.path_finder.liquidity_hints.reset_liquidity_hints()
+        if self.network.path_finder:
+            self.network.path_finder.liquidity_hints.reset_liquidity_hints()
 
     @command('w')
     async def list_invoices(self, wallet: Abstract_Wallet = None):
diff --git a/electrum/lnworker.py b/electrum/lnworker.py
index 7e59d8d70..e96bb5da1 100644
--- a/electrum/lnworker.py
+++ b/electrum/lnworker.py
@@ -1214,7 +1214,8 @@ class LNWallet(LNWorker):
                 # even in the case of success, we report channels of the
                 # route as being able to send the same amount in the future,
                 # as we assume to not know the capacity
-                self.network.path_finder.update_liquidity_hints(htlc_log.route, htlc_log.amount_msat)
+                if self.network.path_finder:
+                    self.network.path_finder.update_liquidity_hints(htlc_log.route, htlc_log.amount_msat)
                 return
             # htlc failed
             if len(log) >= attempts:
@@ -1309,8 +1310,6 @@ class LNWallet(LNWorker):
             raise PaymentFailure(failure_msg.code_name())
         try:
             fallback_channel = route[sender_idx + 1].short_channel_id
-            node_from = route[sender_idx].start_node
-            node_to = route[sender_idx].end_node
         except IndexError:
             raise PaymentFailure(f'payment destination reported error: {failure_msg.code_name()}') from None
 
@@ -1325,7 +1324,7 @@ class LNWallet(LNWorker):
             if payload is None:
                 self.logger.info(f'could not decode channel_update for failed htlc: '
                                  f'{channel_update_as_received.hex()}')
-                self.network.path_finder.channel_blacklist.add(fallback_channel)
+                self.network.path_finder.liquidity_hints.add_to_blacklist(fallback_channel)
             else:
                 # apply the channel update or get blacklisted
                 blacklist, update = self._handle_chanupd_from_failed_htlc(
@@ -1345,7 +1344,6 @@ class LNWallet(LNWorker):
                 # if we can't decide on some action, we are stuck
                 if not (blacklist or update):
                     raise PaymentFailure(failure_msg.code_name())
-
         # for errors that do not include a channel update
         else:
             self.network.path_finder.liquidity_hints.add_to_blacklist(fallback_channel)
diff --git a/electrum/network.py b/electrum/network.py
index 9203a3991..37ae015d6 100644
--- a/electrum/network.py
+++ b/electrum/network.py
@@ -65,6 +65,7 @@ from .logging import get_logger, Logger
 
 if TYPE_CHECKING:
     from .channel_db import ChannelDB
+    from .lnrouter import LNPathFinder
     from .lnworker import LNGossip
     from .lnwatcher import WatchTower
     from .daemon import Daemon
@@ -256,6 +257,7 @@ class Network(Logger, NetworkRetryManager[ServerAddr]):
     channel_db: Optional['ChannelDB'] = None
     lngossip: Optional['LNGossip'] = None
     local_watchtower: Optional['WatchTower'] = None
+    path_finder: Optional['LNPathFinder'] = None
 
     def __init__(self, config: SimpleConfig, *, daemon: 'Daemon' = None):
         global _INSTANCE