qt: main_window: use TaskThread for each of sign/verify/encrypt/decrypt
What changed, and why it matters
This commit moves four message-crypto operations (sign, verify, encrypt, decrypt) in Electrum's Qt wallet window onto a background worker thread so they all behave the same way. It also lets the background thread surface user-facing errors through the existing error handler. The change is a UI refactor, not a fix for a known exploit, but it removes a direct synchronous call that previously swallowed exceptions and could briefly freeze the GUI.
Treat as a routine refactor with minor hardening. No urgent action required. If auditing, confirm that window.on_error correctly handles UserFacingException from these tasks and that the sign/decrypt paths already behave equivalently. Consider whether the removed local warning for encrypt errors changes user-visible behavior.
Security signals we found
Moved blocking wallet crypto calls off the GUI thread, reducing UI freeze / DoS surface
Removed local exception swallowing for encrypt_message; errors now propagate through the window's on_error handler
Added defensive RuntimeError guard for deleted Qt widget in async callback
No input validation, crypto algorithm, or privilege changes visible in the diff
Evidence from the diff
The patch refactors do_verify_message() and do_encrypt_message() in electrum/gui/qt/main_window.py to run self.wallet.verify_message() and self.wallet.encrypt_message() via self.thread.add() (TaskThread) with on_success callbacks. It removes an inline try/except around encrypt_message() and instead relies on window.on_error to handle UserFacingException raised by wallet methods. A RuntimeError guard is added in the encrypt callback in case the QTextEdit has been destroyed before the thread finishes. The sign/decrypt paths were already using TaskThread; this makes all four operations homogeneous.
Changed components
electrum/gui/qt/main_window.pySign/verify message dialogEncrypt/decrypt message dialogTaskThread / background worker integrationInspect captured patch +28 / −15
diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py
index c8c8ed9..20244bb 100644
--- a/electrum/gui/qt/main_window.py
+++ b/electrum/gui/qt/main_window.py
@@ -2159,12 +2159,20 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener):
) -> None:
address = address_e.text().strip()
message = message_e.toPlainText().strip()
- verified = self.wallet.verify_message(
- address=address, signature=str(signature_e.toPlainText()), message=message)
- if verified:
- self.show_message(_("Signature verified"))
- else:
- self.show_error(_("Wrong signature"))
+ task = partial(
+ self.wallet.verify_message,
+ address=address,
+ signature=str(signature_e.toPlainText()),
+ message=message,
+ )
+
+ def on_result(verified):
+ if verified:
+ self.show_message(_("Signature verified"))
+ else:
+ self.show_error(_("Wrong signature"))
+
+ self.thread.add(task, on_success=on_result)
def sign_verify_message(self, address: str = "") -> None:
d = WindowModalDialog(self, _('Sign/verify Message'))
@@ -2238,15 +2246,20 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener):
encrypted_e: QTextEdit,
) -> None:
message = message_e.toPlainText()
- try:
- encrypted = self.wallet.encrypt_message(
- pubkey=pubkey_e.text(),
- message=message,
- )
- except UserFacingException as e:
- self.show_warning(str(e))
- return
- encrypted_e.setText(encrypted)
+ task = partial(
+ self.wallet.encrypt_message,
+ pubkey=pubkey_e.text(),
+ message=message,
+ )
+
+ def setText(text):
+ try:
+ encrypted_e.setText(text)
+ except RuntimeError:
+ # (encrypted_e) wrapped C/C++ object has been deleted
+ pass
+
+ self.thread.add(task, on_success=setText)
def encrypt_message(self, address: str = "") -> None:
d = WindowModalDialog(self, _('Encrypt/decrypt Message'))
Why this scored 16/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.