```
6.15 | E | gui.qt.exception_window.Exception_Hook | exception caught by crash reporter
Traceback (most recent call last):
File "/home/user/wspace/electrum/electrum/gui/qt/history_list.py", line 637, in plot_history_dialog
plt = plot_history(list(self.hm.transactions.values()))
File "/home/user/wspace/electrum/electrum/plot.py", line 24, in plot_history
if not item['confirmations']:
KeyError: 'confirmations'
```
During wallet-open, we load all invoices/payreqs. This involved decoding the lnaddrs twice.
Now we only decode once.
For a wallet with ~1000 payreqs, this noticeably sped up wallet-open:
(before:)
8.83 | D | util.profiler | Daemon._load_wallet 6.4317 sec
(after:)
5.69 | D | util.profiler | Daemon._load_wallet 3.4450 sec
It is very expensive to parse all the lnaddrs...
related https://github.com/spesmilo/electrum/issues/8202
For a HD wallet, instead of checking the first 10 addrs + 10 additional random ones,
we now check the first 10 addrs + 10 random used addrs + 10 random unused addrs.
Checking unused addresses is useful to prevent getting money sent there,
and checking used addresses is useful to inform people of already lost money.
with the Qt gui, the python process saturates one of my CPU cores to 100%.
This is because main_window.timer_actions() calls request_list.refresh_all()
every 0.5 seconds, which iterates over all unpaid payreqs, and does a
scriptpubkey->address->scriptpubkey conversion.
Trace of the hot path:
```
File "/home/user/wspace/electrum/./run_electrum", line 510, in <module>
main()
File "/home/user/wspace/electrum/./run_electrum", line 421, in main
handle_cmd(
File "/home/user/wspace/electrum/./run_electrum", line 439, in handle_cmd
d.run_gui(config, plugins)
File "/home/user/wspace/electrum/electrum/daemon.py", line 581, in run_gui
self.gui_object.main()
File "/home/user/wspace/electrum/electrum/gui/qt/__init__.py", line 469, in main
self.app.exec_()
File "/home/user/wspace/electrum/electrum/gui/qt/main_window.py", line 861, in timer_actions
self.receive_tab.request_list.refresh_all()
File "/home/user/wspace/electrum/electrum/gui/qt/util.py", line 821, in refresh_all
self.refresh_row(key, row)
File "/home/user/wspace/electrum/electrum/gui/qt/request_list.py", line 126, in refresh_row
status = self.wallet.get_invoice_status(request)
File "/home/user/wspace/electrum/electrum/wallet.py", line 2330, in get_invoice_status
paid, conf = self.is_onchain_invoice_paid(invoice)
File "/home/user/wspace/electrum/electrum/wallet.py", line 1118, in is_onchain_invoice_paid
is_paid, conf_needed, relevant_txs = self._is_onchain_invoice_paid(invoice)
File "/home/user/wspace/electrum/electrum/wallet.py", line 1085, in _is_onchain_invoice_paid
outputs = invoice.get_outputs()
File "/home/user/wspace/electrum/electrum/invoices.py", line 130, in get_outputs
traceback.print_stack()
```
These commits drastically reduce the CPU utilisation.
In particular, window.timer_actions() calls
request_list.refresh_all() and invoice_list.refresh_all(),
every 0.5 seconds.
We avoid doing this at least when those lists are not visible anyway.
In order to avoid repeatedly calling get_addr_from_output_script() on
every read of the "TxOutput.address" property, determine and cache it
only whenever the output script is created/changed.