Commit Graph
3 Commits
Author SHA1 Message Date
such-gitea d04d1c789d fix(nip98): widen the clock window and say what actually failed
The register, login and link handlers rejected any proof signed more than 30
seconds from server time, measured against a clock the client owns and we do
not. Ordinary desktop drift exceeds that, so a user at a new location failed
every attempt with 'Invalid Nostr proof': a cryptographic-sounding message that
names nothing the user can act on.

The window is now 120 seconds and symmetric, so a fast clock is bounded like a
slow one, and the message points at the device clock. Erasure moves with it:
left at 30 it would have let a device register and log in while silently unable
to delete or export its own data, which is harder to diagnose than a uniform
failure.

120 seconds is a mitigation, not a cure. Nobody has measured the reported
machine's offset, and whole-hour errors from a wrong timezone or an RTC kept in
local time are common. The durable fix is to return the server's time with the
challenge so an honest client stamps from it; the client already accepts an
injected timestamp.
2026-09-09 11:00:31 -04:00
such-gitea d48936308e fix(lws): count unconfirmed change as pending instead of erasing it
sum_mempool_received computed received minus sent, which reads as a net figure
but double-counts the spend: every mempool row's spent_outputs already go to the
wallet, which subtracts them after verifying each key image.

On a send with change, sent exceeds received because the whole input is consumed
and part comes back, so the subtraction underflowed and saturated to zero. The
change output then appeared nowhere until it confirmed. Reported 2026-09-08:
sending 0.3 from a 7 XMR output left 6.7 XMR invisible for a block, which to the
person holding the wallet looks like money that has gone missing.

Pure receives were unaffected, their sent being zero, which is why the mempool
work looked complete when it was tested against incoming payments.

The existing test encoded the defect as intended behaviour, annotating a
change-shaped row as 'net 0 via saturating_sub'. Corrected, plus a regression
case for the reported amounts and a property test that a spend can never shrink
the pending total.
2026-09-08 09:55:49 -04:00
such-gitea afa3ec7679 fix(lws): treat an existing account as registered, not as a node outage
register_account called add_account unconditionally when provisioning was off,
which is production's default. monero-lws answers a duplicate with
account_exists as an HTTP 500, the backend maps that to a node error, and the
user is told NODE_UNAVAILABLE. A routine re-registration was therefore
indistinguishable from the node being down.

Reported 2026-09-08: a tip failed with an upstream error while both LWS
instances were active and had logged no warnings in 24 hours. Nothing was wrong
with the node or the account.

The provisioning path already checked existence first and documented why. That
check now guards both paths, so registration is idempotent and the two branches
cannot drift apart again.
2026-09-08 09:44:23 -04:00