perf(spv): persist checkpoint-anchoring state across sync sessions
_anchoredUpTo tracked which heights were already proven to hash-chain back to a checkpoint, but only in memory: every app restart re-walked and re-verified the whole header chain from the checkpoint even when the header bytes themselves were already cached on disk, dominating reconnect time on large wallets. Round-trip it through SyncCache like the other sync caches (RawTxHex/VerifiedAt/BlockHeaders).
This commit is contained in:
1 parent
b6440484c1
commit
d9dd05aa52
5 files changed
+94
-15
No files matched your search
@@ -271,7 +271,8 @@ public partial class MainWindowViewModel
|
||||
_doc.Cache?.BlockHeaders,
|
||||
_doc.Cache?.NextReceiveIndex ?? 0,
|
||||
_doc.Cache?.NextChangeIndex ?? 0,
|
||||
net);
|
||||
net,
|
||||
_doc.Cache?.AnchoredUpTo);
|
||||
_synchronizer.Progress += msg => Dispatcher.UIThread.Post(() => StatusMessage = msg);
|
||||
// Progressive verification (§7.4): the wallet becomes usable as soon as
|
||||
// transaction downloads finish, without waiting for every historical Merkle
|
||||
@@ -289,15 +290,19 @@ public partial class MainWindowViewModel
|
||||
// Off the UI thread: sync does heavy CPU work (LINQ over thousands of
|
||||
// cached txs/UTXOs) and blocking JSON/disk I/O between awaits, negligible
|
||||
// on desktop but enough to freeze the UI (ANR) on slower mobile hardware.
|
||||
var (result, rawHex, verifiedAt, blockHeaders) = await Task.Run(async () =>
|
||||
var (result, rawHex, verifiedAt, blockHeaders, anchoredUpTo) = await Task.Run(async () =>
|
||||
{
|
||||
var r = await _synchronizer.SyncOnceAsync(ct);
|
||||
var caches = _synchronizer.ExportCaches(PalladiumNetworks.For(_account.Profile.Kind));
|
||||
return (r, caches.RawTxHex, caches.VerifiedAt, caches.BlockHeaders);
|
||||
return (r, caches.RawTxHex, caches.VerifiedAt, caches.BlockHeaders, caches.AnchoredUpTo);
|
||||
}, ct);
|
||||
_lastTransactions = result.Transactions;
|
||||
|
||||
var cache = new SyncCache { RawTxHex = rawHex, VerifiedAt = verifiedAt, BlockHeaders = blockHeaders };
|
||||
var cache = new SyncCache
|
||||
{
|
||||
RawTxHex = rawHex, VerifiedAt = verifiedAt, BlockHeaders = blockHeaders,
|
||||
AnchoredUpTo = anchoredUpTo,
|
||||
};
|
||||
FillDisplayFields(cache, result);
|
||||
_doc.Cache = cache;
|
||||
await WalletStore.SaveAsync(_doc, _walletPath!, _password);
|
||||
@@ -493,12 +498,13 @@ public partial class MainWindowViewModel
|
||||
try
|
||||
{
|
||||
var net = PalladiumNetworks.For(_account.Profile.Kind);
|
||||
var (rawHex, verifiedAt, blockHeaders) = _synchronizer.ExportCaches(net);
|
||||
var (rawHex, verifiedAt, blockHeaders, anchoredUpTo) = _synchronizer.ExportCaches(net);
|
||||
if (rawHex.Count == 0 && verifiedAt.Count == 0)
|
||||
return;
|
||||
(_doc.Cache ??= new SyncCache()).RawTxHex = rawHex;
|
||||
_doc.Cache.VerifiedAt = verifiedAt;
|
||||
_doc.Cache.BlockHeaders = blockHeaders;
|
||||
_doc.Cache.AnchoredUpTo = anchoredUpTo;
|
||||
WalletStore.Save(_doc, _walletPath, _password);
|
||||
}
|
||||
catch { /* non-fatal: the next full save will recover */ }
|
||||
|
||||
Reference in new issue
Block a user