Commit Graph

6 Commits

Author SHA1 Message Date
davide 3d5a226a5a docs: translate all code comments to English (language policy)
Translate every Italian /// XML doc comment, <!-- --> XAML comment, and
// inline comment to English across all source files (Core, App, tests).
Add the language policy to CLAUDE.md (conversation Italian; all code
and docs English). Update one test assertion that checked an Italian
exception message that was also translated.
2026-06-16 14:40:11 +02:00
davide 5ff2075a45 perf(spv): incremental discovery, parallel chains, persistent header cache
Speed up wallet synchronization, especially re-syncs of large wallets:

- Incremental address discovery: known indices from the previous sync
  (NextReceiveIndex/NextChangeIndex) are fetched in a single parallel
  burst instead of sequential gap-limit rounds, cutting round-trips from
  O(used/gapLimit) to ~O(1). Receive and change chains scan in parallel.
- Merge tx download and Merkle verification into one parallel phase
  (no barrier between them); the per-call semaphore is dropped in favor
  of the transport-level in-flight gate.
- Persist verified block headers (SyncCache.BlockHeaders, height -> hex):
  immutable once stored, so blockchain.block.header round-trips for
  already-verified proofs are eliminated on later syncs.
- RetryOnBusyAsync with exponential backoff around server calls, treating
  -101/-102 and "server busy"/"excessive resource usage" as transient.

Wire the new PreloadCaches/ExportCaches signatures through the desktop
view model and the CLI sync command.
2026-06-16 09:27:48 +02:00
davide 3054a9baaa fix(spv): resilient sync — GetHistory discovery, tx cache, auto-connect fallback
Three interrelated fixes for sync reliability on large wallets:

1. Prevent -101 "excessive resource usage":
   ScanChainAsync uses GetHistoryAsync for discovery instead of
   SubscribeScripthashAsync. Subscriptions are limited to the gap window
   only (≤ 2×gapLimit addresses), so the session subscription count stays
   constant regardless of wallet history size — eliminating -101 on
   wallets with 1000+ historical addresses.

2. Persist and resume tx cache across sessions and disconnects:
   WalletSynchronizer gains ExportCaches() and PreloadCaches(). On every
   successful sync (and on partial failure) the downloaded raw tx hex and
   verified Merkle heights are written to SyncCache.RawTxHex/VerifiedAt
   in the wallet file. On reconnect or app restart the new synchronizer
   is pre-populated from disk so only new transactions are downloaded.
   _synchronizer is always nulled on reconnect (new client = new instance)
   while caches survive via the wallet file.

3. Auto-connect with multi-server fallback and retry:
   ConnectAndSync iterates BuildServerCandidates() (current server first,
   then all KnownServers in order) and stops at the first that responds.
   _autoReconnect and _syncFailed are set in OpenLoaded() so the keepalive
   timer (20 s) retries automatically on any failure — connection error,
   -101 mid-download, or timeout. PersistPartialTxCache() saves whatever
   was downloaded so each retry resumes from its checkpoint.
2026-06-15 14:23:31 +02:00
davide 73a2d5356d feat(spv): Electrum-style continuous updates with incremental parallel sync
WalletSynchronizer now pipelines JSON-RPC requests (address subscribes,
histories, tx downloads and Merkle proofs run in parallel batches) and
keeps per-connection caches of downloaded transactions and verified
proofs, so notification-triggered resyncs only cost the delta.

The app connects automatically when a wallet opens, keeps one
synchronizer per connection, and queues notifications that arrive
during a sync instead of dropping them: incoming transactions now show
up within seconds.
2026-06-11 13:37:34 +02:00
davide 08217e5306 feat(spv): per-address balance and tx count in sync result 2026-06-11 11:27:31 +02:00
davide bd5e740599 feat(spv): header sync, Merkle proofs, scripthash 2026-06-11 10:47:16 +02:00