forked from bitcoinafterlife/bal-electrum-plugin
fix(plugin): missed-update fixes, server re-check, and bold Building Will results (v0.3.2)
Revert the v0.3.1 double-invalidation change (it caused an inheritance-list regression: stale/invalidated wills lingered and heir/date updates became incoherent) and add several targeted missed-update fixes plus a UI refinement. Revert (v0.3.1 -> v0.3.2): - Remove Will.mark_invalidated_by_tx() and its call in loop_broadcast_invalidating. core/will.py and gui/qt/dialogs.py are restored to the working v0.3.0 behaviour. The postpone double-invalidation issue is intentionally left open, to be addressed without touching the shared broadcast path. FIX 1 - detect heir removal on Check / Electrum close: - core/will.py (check_willexecutors_and_heirs): the else-branch now raises HeirNotFoundException when a will still carries an heir that is no longer in the current heirs set (heir removed), mirroring the existing 'heir added' path. Rebuild therefore triggers on Check and on_close (same build_will_task path), as decided by the user (manual update only, no auto-rebuild). FIX 2 - Check queries servers for already-sent wills: - core/will.py: new Will.needs_server_check(w) returns True for any VALID will with a will-executor that is not yet CHECKED (no longer limited to PUSHED). - gui/qt/lists.py (PreviewList.check): use needs_server_check so wills stuck on 'New / Not sent' are re-checked instead of reporting 'nothing to do'. FIX 3 - Settings-dialog hide toggles refresh the list: - core/plugin_base.py: new sync_hide_filters() re-reads the cached _hide_invalidated / _hide_replaced flags from the persisted config. - gui/qt/window.py (update_all): call sync_hide_filters() before refreshing, so toggling 'Hide Invalidated' / 'Hide Replaced' in the Settings dialog (which writes the config directly) updates the transaction list immediately instead of requiring an Electrum restart. UI - bold results in the Building Will dialog: - gui/qt/dialogs.py (BalBuildWillDialog): render the right-side results in bold (Ok, Ko, Nothing to do, Skipped, Wait, Timeout, ...) keeping the left-side state labels in normal weight. Centralised in msg_ok/msg_error/msg_warning/ msg_set_status, plus the will-executor push/check rows now show Ok/Ko and True/False in bold + colour (green/red). Tests/tooling: - tests/test_core_will.py: add test_check_heirs_unchanged_is_coherent, test_check_heir_removed_triggers_rebuild, test_check_heir_added_triggers_rebuild, test_needs_server_check. - tests/sim_update_flows.py: real-world update-scenario simulation. - tests/preview_build_will_dialog.py, tests/preview_we_rows.py: GUI-only before/after previews of the bold formatting. - Bump version to 0.3.2 (VERSION, manifest.json, __init__.py, plugin_base.py). 186 tests pass; smoke test, external-zip test and update-flow simulation OK; ruff reports only pre-existing star-import false positives.
This commit is contained in:
committed by
steal
parent
e477c5aa5b
commit
365824767b
@@ -708,19 +708,6 @@ class BalBuildWillDialog(BalDialog):
|
||||
self.msg_set_invalidating(self.msg_ok())
|
||||
if not txid:
|
||||
_logger.debug(f"should not be none txid: {txid}")
|
||||
else:
|
||||
# The invalidation tx is now broadcast, so the old signed/sent
|
||||
# will transactions spending those same UTXOs can no longer be
|
||||
# mined. Mark them INVALIDATED (which clears their VALID flag)
|
||||
# so the postpone/expire check does NOT fire a second
|
||||
# invalidation when phase 1 is restarted to rebuild the new
|
||||
# (postponed) will.
|
||||
invalidated = Will.mark_invalidated_by_tx(
|
||||
self.bal_window.willitems, tx
|
||||
)
|
||||
if invalidated:
|
||||
_logger.debug(f"invalidated will items: {invalidated}")
|
||||
self.bal_window.save_willitems()
|
||||
|
||||
except TxBroadcastError as e:
|
||||
_logger.error(f"fail to broadcast transaction:{e}")
|
||||
@@ -784,7 +771,10 @@ class BalBuildWillDialog(BalDialog):
|
||||
self.bal_window.willitems[wid].set_status("PUSH_FAIL", True)
|
||||
retry_flag["value"] = True
|
||||
done["count"] += 1
|
||||
self.msg_edit_row("{} : {}".format(url, "Ok" if ok else "Ko"))
|
||||
# Show the per-server result (Ok/Ko) in bold + color so the
|
||||
# outcome stands out, keeping the server URL in normal weight.
|
||||
result = self.msg_ok("Ok") if ok else self.msg_error("Ko")
|
||||
self.msg_edit_row("{} : {}".format(url, result))
|
||||
self.msg_set_pushing(_status_line())
|
||||
|
||||
def on_timeout(url, willexecutor):
|
||||
@@ -836,7 +826,7 @@ class BalBuildWillDialog(BalDialog):
|
||||
if self._stopping:
|
||||
return
|
||||
row = self.msg_edit_row(
|
||||
"checking {} - {} : {}".format(
|
||||
"checking {} - {} : <b>{}</b>".format(
|
||||
self.bal_window.willitems[wid].we["url"], wid, "Waiting"
|
||||
)
|
||||
)
|
||||
@@ -844,11 +834,16 @@ class BalBuildWillDialog(BalDialog):
|
||||
w.set_check_willexecutor(
|
||||
Willexecutors.check_transaction(wid, w.we["url"])
|
||||
)
|
||||
# Show the CHECKED result in bold + color (green True /
|
||||
# red False) so the outcome stands out, keeping the server
|
||||
# URL and tx id in normal weight.
|
||||
checked = self.bal_window.willitems[wid].get_status("CHECKED")
|
||||
result = self.msg_ok(checked) if checked else self.msg_error(checked)
|
||||
row = self.msg_edit_row(
|
||||
"checked {} - {} : {}".format(
|
||||
self.bal_window.willitems[wid].we["url"],
|
||||
wid,
|
||||
self.bal_window.willitems[wid].get_status("CHECKED"),
|
||||
result,
|
||||
),
|
||||
row,
|
||||
)
|
||||
@@ -1034,20 +1029,31 @@ class BalBuildWillDialog(BalDialog):
|
||||
self.wait_row = self.msg_edit_row(f"Please wait {status}secs", self.wait_row)
|
||||
|
||||
def msg_error(self, e):
|
||||
return "<font color='{}'>{}</font>".format(self.COLOR_ERROR, e)
|
||||
# Results are shown in bold so the outcome stands out from the
|
||||
# left-side state label (which stays in normal weight).
|
||||
return "<font color='{}'><b>{}</b></font>".format(self.COLOR_ERROR, e)
|
||||
|
||||
def msg_ok(self, e="Ok"):
|
||||
return "<font color='{}'>{}</font>".format(self.COLOR_OK, e)
|
||||
# Results are shown in bold (see msg_error).
|
||||
return "<font color='{}'><b>{}</b></font>".format(self.COLOR_OK, e)
|
||||
|
||||
def msg_warning(self, e):
|
||||
return "<font color='{}'>{}</font".format(self.COLOR_WARNING, e)
|
||||
# Results are shown in bold (see msg_error).
|
||||
return "<font color='{}'><b>{}</b></font>".format(self.COLOR_WARNING, e)
|
||||
|
||||
def msg_set_status(self, msg, row=None, status=None, color=None):
|
||||
# The left "state" label keeps its normal weight; only the right-side
|
||||
# result (``status``) is rendered in bold so it is easy to read at a
|
||||
# glance. ``status`` may already contain rich-text emitted by
|
||||
# msg_ok/msg_error/msg_warning (which add their own <b>...</b>); wrapping
|
||||
# it again in <b> is harmless for those cases.
|
||||
status = "Wait" if status is None else status
|
||||
if color is None:
|
||||
line = f"{_(msg)}:\t{status}"
|
||||
line = "{}:\t<b>{}</b>".format(_(msg), status)
|
||||
else:
|
||||
line = "<font color={}>{}:\t{}</font>".format(color, _(msg), status)
|
||||
line = "{}:\t<font color={}><b>{}</b></font>".format(
|
||||
_(msg), color, status
|
||||
)
|
||||
return self.msg_edit_row(line, row)
|
||||
|
||||
def ask_password(self, msg=None):
|
||||
|
||||
Reference in New Issue
Block a user