Commit Graph
10 Commits
Author SHA1 Message Date
davide 4e3d93e167 fix(spv): anchor headers up to a checkpoint above them
With proof of work skipped, chaining headers from a checkpoint up to a
transaction's block proves nothing: a server can fabricate a header and
fake headers after a real checkpoint. The header must now hash-chain up to
the nearest checkpoint at or above its height, whose hash is hardcoded.
This also anchors heights below the first checkpoint. The cached anchor
state is renamed AnchoredDownTo and caches without it are re-verified
once. Blocks above the newest checkpoint remain a documented limit.
See ADR 0040.
2026-11-03 14:52:29 +01:00
davide c8ba2294f2 feat(app): suggest fee rates from the server and enforce the relay fee
After connecting, the Send tab offers Fast/Normal/Economy rates from the
server's fee estimates (never below the relay fee, implausible values
ignored). A manual rate below the relay fee is refused before building and
a fee above 1% of the amount is flagged in the preview. See ADR 0039.
2026-11-03 14:33:32 +01:00
davide 92fd783658 feat(cli): read the wallet password from env, stdin or a prompt
The password no longer has to be a command-line argument: it can come from
--password-env, --password-stdin or a no-echo prompt (--password still works
but warns). Plaintext storage is now an explicit opt-in (--no-encryption)
instead of the result of a forgotten flag. See ADR 0038.
2026-11-03 14:21:58 +01:00
davide 06d1f59c2b fix(app): derive an address private key only when revealed
Address rows and the address detail sheet no longer carry the WIF of
every listed address for the whole session. The key is derived after the
password gate and dropped when hidden, when the sheet closes or when the
wallet closes. See ADR 0037.
2026-11-03 14:10:58 +01:00
davide 8bcee27c23 feat(spv): verify the chain identity of a server on connect
After the handshake the wallet checks server.features genesis_hash and,
when the profile has checkpoints, the header at the highest checkpoint
not above the server's tip (mainnet shares Bitcoin's genesis, so the
checkpoint is what tells the chains apart). A server on another chain is
refused with WrongChainException and the next candidate is tried. Used by
the GUI, peer discovery, the CLI and the server probe. See ADR 0036.
2026-11-03 14:01:34 +01:00
davide 65c515bf7a fix(net): cap the length of a server line
A hostile server could stream an endless line with no newline and exhaust
the client's memory. A single reply is now capped at 16 MiB (configurable
via maxLineBytes in ConnectAsync); on excess the connection fails with
InvalidDataException. See ADR 0035.
2026-11-03 13:52:49 +01:00
davide 3be761d97e fix(net): bound every request with a timeout
A server that stops answering without closing the socket left a running
sync waiting forever. Requests now fail with TimeoutException after 30 s
(10 s for the handshake, both configurable in ConnectAsync) and the
connection is marked dead so the app reconnects. See ADR 0034.
2026-11-03 12:18:39 +01:00
davide d431996ddc docs: describe the extended test strategy
ADR 0033, ADR 0032 update, README test section, agent rules and
changelog entry.
2026-11-03 11:45:43 +01:00
davide 9c0a408c49 docs: record CI in ADR 0032 and mention it in README and agent rules
Also update docs-as-code to reflect that the docs check now runs in CI.
2026-11-03 09:49:51 +01:00
davide b292590cdc docs: add docs-as-code process and one ADR per feature
docs/docs-as-code.md defines the workflow; docs/adr holds 31 ADRs
(retroactive, reconstructed from code and changelog) with a template and
index. docs/check-docs.sh validates ADR structure, index, cited code
paths, relative links and CLAUDE.md/AGENTS.md sync.
2026-11-03 09:45:51 +01:00