Testing with a wallet with a ~1000 unpaid/expired payment requests,
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.
This commit is contained in:
@@ -813,6 +813,8 @@ class MyTreeView(QTreeView):
|
||||
return row
|
||||
|
||||
def refresh_all(self):
|
||||
if self.maybe_defer_update():
|
||||
return
|
||||
for row in range(0, self.std_model.rowCount()):
|
||||
item = self.std_model.item(row, 0)
|
||||
key = item.data(self.key_role)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import time
|
||||
from typing import TYPE_CHECKING, List, Optional, Union, Dict, Any
|
||||
from typing import TYPE_CHECKING, List, Optional, Union, Dict, Any, Sequence
|
||||
from decimal import Decimal
|
||||
|
||||
import attr
|
||||
@@ -126,16 +126,13 @@ class Invoice(StoredObject):
|
||||
address = self._lnaddr.get_fallback_address() or None
|
||||
return address
|
||||
|
||||
def get_outputs(self):
|
||||
if self.is_lightning():
|
||||
def get_outputs(self) -> Sequence[PartialTxOutput]:
|
||||
outputs = self.outputs or []
|
||||
if not outputs:
|
||||
address = self.get_address()
|
||||
amount = self.get_amount_sat()
|
||||
if address and amount is not None:
|
||||
outputs = [PartialTxOutput.from_address_and_value(address, int(amount))]
|
||||
else:
|
||||
outputs = []
|
||||
else:
|
||||
outputs = self.outputs
|
||||
return outputs
|
||||
|
||||
def can_be_paid_onchain(self) -> bool:
|
||||
|
||||
@@ -148,9 +148,18 @@ class TxOutput:
|
||||
return cls(scriptpubkey=bfh(addr), value=val)
|
||||
raise Exception(f"unexpected legacy address type: {_type}")
|
||||
|
||||
@property
|
||||
def scriptpubkey(self) -> bytes:
|
||||
return self._scriptpubkey
|
||||
|
||||
@scriptpubkey.setter
|
||||
def scriptpubkey(self, scriptpubkey: bytes):
|
||||
self._scriptpubkey = scriptpubkey
|
||||
self._address = get_address_from_output_script(scriptpubkey)
|
||||
|
||||
@property
|
||||
def address(self) -> Optional[str]:
|
||||
return get_address_from_output_script(self.scriptpubkey) # TODO cache this?
|
||||
return self._address
|
||||
|
||||
def get_ui_address_str(self) -> str:
|
||||
addr = self.address
|
||||
|
||||
Reference in New Issue
Block a user