core+gui+cli: anticipation/rebuild dates, preserve relative settings
Fixes around the delivery/build/check date handling (karen7 regtest):
- build_will (GUI + CLI) re-anchors date_to_check to the CURRENT heirs'
earliest future delivery before building, so an anticipated rebuild is no
longer blocked by the stale old-will anchor (NO_FUTURE_DATE). The checks of
the existing will keep their anchored date_to_check.
- _sync_locktime_to_built_txs now PRESERVES RELATIVE locktime/threshold
recipes ("2y"/"150d") in WILL_SETTINGS instead of freezing them to absolute
timestamps: the anchored comparisons (resolve_locktime_against_tx and
resolve_date_to_check with built_locktime) already prevent the daily
invalidate prompt. Absolute values still sync on a genuine automatic
anticipation.
- Will.remove_stale_wallet_history drops stale wallet-LOCAL will placeholders
before every (re)build in GUI and CLI so their coins are available again.
- check_willexecutors_and_heirs raises HeirNotFoundException outside the
count_heirs gate: a shortened relative recipe on a signed will now triggers
a plain rebuild ("no heirs" only when there really are none).
- is_locktime_below_threshold compares the settings on one reference frame
(resolve_guard_threshold), no longer against the built-will anchor.
Tests: purge unit + call-site, no-heirs, guard, anticipated-rebuild
end-to-end (GUI) + CLI mirror + fixed_percent_lists_amount unit,
relative-preserve sync; conftest restores electrum.constants.net after each
test (cross-file pollution guard).
This commit is contained in:
@@ -13,8 +13,14 @@ import sys
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir))
|
||||
|
||||
from bal.core.checkalive import resolve_date_to_check
|
||||
from bal.core.util import copy_structure
|
||||
from bal.core.will import Will, WillItem
|
||||
from bal.core.will import (
|
||||
HeirNotFoundException,
|
||||
NoHeirsException,
|
||||
Will,
|
||||
WillItem,
|
||||
)
|
||||
|
||||
# A valid serialized Bitcoin transaction hex (1 input + 1 P2PKH output, version 2)
|
||||
_VALID_TX_HEX = (
|
||||
@@ -210,6 +216,59 @@ def test_check_heir_added_triggers_rebuild():
|
||||
assert raised, "adding an heir must raise HeirNotFoundException"
|
||||
|
||||
|
||||
def test_shortened_relative_recipe_on_signed_rebuilds_not_noheirs():
|
||||
"""Regression (karen7): heirs shortened "2y"->"1y" on a signed will whose
|
||||
ADVANCED check window is anchored to the frozen built delivery must trigger
|
||||
a plain rebuild (HeirNotFoundException), NOT "No Heirs".
|
||||
|
||||
Earlier the count gate resolved each current relative recipe from *now*
|
||||
while ``check_date`` was anchored to the (longer) frozen built locktime, so
|
||||
every heir fell below the window and was silently excluded -> NoHeirs even
|
||||
though the will simply needs rebuilding on the new, shorter schedule."""
|
||||
lt = 2_100_000_000 # a far-future frozen delivery (a "2y" build)
|
||||
will_heirs = {"alice": ["addr_alice", 5000, "2y"]}
|
||||
current_heirs = {"alice": ["addr_alice", 5000, "1y"]}
|
||||
will = _make_will_with_heirs(will_heirs, lt)
|
||||
will["willid_1"].set_status("COMPLETE", True)
|
||||
check_date = resolve_date_to_check(
|
||||
False, {"locktime": "2y", "threshold": "150d"}, built_locktime=lt
|
||||
)
|
||||
assert check_date < lt # the anchored window really precedes the delivery
|
||||
raised = None
|
||||
try:
|
||||
Will.check_willexecutors_and_heirs(
|
||||
will, copy_structure(current_heirs), {}, False, check_date, 100
|
||||
)
|
||||
except HeirNotFoundException:
|
||||
raised = "rebuild"
|
||||
except NoHeirsException:
|
||||
raised = "noheirs"
|
||||
assert raised == "rebuild", (
|
||||
f"shortened recipe on a signed will must rebuild, got {raised!r}"
|
||||
)
|
||||
|
||||
|
||||
def test_all_heirs_past_check_date_still_noheirs():
|
||||
"""The "no valid heirs" gate is preserved: when every heir is coherent with
|
||||
the built will but its delivery lies before ``check_date``, the check still
|
||||
reports NoHeirsException (there is literally nothing future to inherit)."""
|
||||
lt = 1_900_000_000
|
||||
will_heirs = {"alice": ["addr_alice", 5000, str(lt)]}
|
||||
will = _make_will_with_heirs(will_heirs, lt)
|
||||
raised = None
|
||||
try:
|
||||
Will.check_willexecutors_and_heirs(
|
||||
will, copy_structure(will_heirs), {}, False, lt + 86400, 100
|
||||
)
|
||||
except HeirNotFoundException:
|
||||
raised = "rebuild"
|
||||
except NoHeirsException:
|
||||
raised = "noheirs"
|
||||
assert raised == "noheirs", (
|
||||
f"a fully delivered will must report NoHeirs, got {raised!r}"
|
||||
)
|
||||
|
||||
|
||||
def test_needs_server_check():
|
||||
"""Check button selection logic: only a VALID, PUSHED will with a
|
||||
will-executor that is not yet CHECKED must be queried on the server.
|
||||
|
||||
Reference in New Issue
Block a user