72 lines
2.5 KiB
Python
72 lines
2.5 KiB
Python
"""
|
|
bal.core.checkalive
|
|
===================
|
|
|
|
The "Check Alive" policy: the single reference timestamp (``date_to_check``)
|
|
against which every will-validity check is evaluated, and the BASIC/ADVANCED
|
|
mode rules that decide it.
|
|
|
|
Pure, GUI-free. The GUI raises :class:`CheckAliveError` to trigger the
|
|
postpone/invalidate flow; the decision that it *should* be raised lives here.
|
|
"""
|
|
|
|
from datetime import datetime
|
|
from typing import Any
|
|
|
|
from .plugin_base import BalTimestamp
|
|
|
|
|
|
class CheckAliveError(Exception):
|
|
"""Raised when the "check alive" date is in the past."""
|
|
|
|
def __init__(self, timestamp_to_check):
|
|
self.timestamp_to_check = timestamp_to_check
|
|
|
|
def __str__(self):
|
|
return "Check alive expired please update it: {}".format(
|
|
datetime.fromtimestamp(self.timestamp_to_check).isoformat()
|
|
)
|
|
|
|
|
|
def resolve_date_to_check(
|
|
is_basic_mode: bool, will_settings: Any, now: float | None = None
|
|
) -> float:
|
|
"""Return the reference timestamp for every will-validity check.
|
|
|
|
``date_to_check`` is the single reference timestamp that EVERY downstream
|
|
check reads: the build filter, the heir count, ``check_will_expired``,
|
|
``check_amounts`` and the locktime-vs-threshold guard.
|
|
|
|
* BASIC mode: the Check Alive is hidden and NOT editable, so it must never
|
|
govern those checks. ``date_to_check`` is set to *now*: every check is
|
|
evaluated against the current moment (the Check Alive effectively does not
|
|
exist) while the delivery locktime is still fully enforced.
|
|
* ADVANCED mode: the user-controlled stored threshold is used as-is.
|
|
|
|
Args:
|
|
is_basic_mode: ``True`` for the SIMPLE / BASIC user type.
|
|
will_settings: the per-wallet settings dict (``"threshold"`` key).
|
|
now: overridable clock for tests; defaults to ``datetime.now()``.
|
|
|
|
Returns:
|
|
The reference timestamp (float, UNIX seconds).
|
|
"""
|
|
if is_basic_mode:
|
|
return (now if now is not None else datetime.now().timestamp())
|
|
return BalTimestamp(will_settings["threshold"]).to_timestamp()
|
|
|
|
|
|
def check_alive_expired(
|
|
is_basic_mode: bool, date_to_check: float, now: float | None = None
|
|
) -> bool:
|
|
"""True when the Check Alive guard should fire (``CheckAliveError``).
|
|
|
|
Only ADVANCED mode can be "expired": in BASIC mode the Check Alive is inert
|
|
by construction, so a passed check-alive date must never force a postpone or
|
|
rewrite of the will.
|
|
"""
|
|
if is_basic_mode:
|
|
return False
|
|
current = now if now is not None else datetime.now().timestamp()
|
|
return date_to_check < current
|