Improve wallet sync throughput, binary transport, and checkpoint recovery - #486
Open
BraydenLangley wants to merge 24 commits into
Open
Improve wallet sync throughput, binary transport, and checkpoint recovery#486BraydenLangley wants to merge 24 commits into
BraydenLangley wants to merge 24 commits into
Conversation
BraydenLangley
force-pushed
the
agent/wallet-sync-throughput
branch
6 times, most recently
from
August 17, 2026 21:57
568e029 to
3d420ab
Compare
BraydenLangley
force-pushed
the
agent/wallet-sync-throughput
branch
from
September 1, 2026 00:51
74ee852 to
3443b28
Compare
BraydenLangley
force-pushed
the
agent/wallet-sync-throughput
branch
from
September 8, 2026 21:39
a4c615b to
0367743
Compare
BraydenLangley
marked this pull request as ready for review
September 9, 2026 00:45
BraydenLangley
requested review from
tonesnotes and
ty-everett
as code owners
September 9, 2026 00:45
BraydenLangley
marked this pull request as draft
September 9, 2026 18:56
BraydenLangley
marked this pull request as ready for review
September 9, 2026 20:21
BraydenLangley
marked this pull request as draft
September 9, 2026 20:22
|
BraydenLangley
marked this pull request as ready for review
September 9, 2026 20:41
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Results at a glance
Backups now transfer oversized records in authenticated pieces, verify integrity before import, and resume interrupted uploads.
Live E2E testing used a large wallet in the native desktop client, covering
complete local copies, restart recovery, and repeat sync. Transfer size was
measured separately with a synthetic fixture.
Timing compares successive candidates, not a controlled comparison against upstream
main. Byte verification was sampled, not database-wide. Seetest methods and limits for details.
Implementation, detailed test evidence, and release notes
Program and scope
Tracker: Improve wallet sync throughput, binary transport, and checkpoint recovery #486, wallet storage replication throughput and recovery.
Problem: large syncs spend time in small source queries, repeated transactions, oversized checkpoint downloads, and decimal JSON byte payloads.
Implementation: adaptive bounded source reads and proof indexes; atomic page/checkpoint commits; IndexedDB identity and relation lookups that avoid wallet-wide scans; optional totals; writer-scoped checkpoint selection; negotiated compact checkpoints reused after each committed page; compact binary sync bytes in both directions; bounded retries for oversized read responses; no late authentication dispatch or session recovery after the caller's deadline.
Compatibility: legacy peers retain full checkpoints and array payloads. Binary uploads remain opt-in and negotiated. Gateway failures do not cause write replay. Complete ID mappings remain durable on the writer.
Out of scope: merging this PR, publishing npm packages, changing wallet ownership or primary-provider policy.
Rebased onto upstream
mainatc42233af7cfd143b74154c89df65a7ea60384477(this repository has no upstreammaster).Earlier throughput revision:
7c39d891dfbe654ff1ebc7f79d6cb4d7ca0d2a20; health, authenticated identity/capability, configuration preservation, and artifact verification passed. That deployed revision passed the complete merge gate (CI run 34292518689), CodeQL (34292518596), and conformance workflow (34292518668).Deployed production implementation:
1901c63108ec136ddce901eca6293f3bc08b0613. Adds negotiated bounded record transfers: raw binary framing, authenticated pieces, durable staged uploads, integrity verification and a matching-checkpoint commit guard. Existing ordinary-page and BRC-38/39 file formats are retained. This exact revision is deployed and has passed public/local health, authenticated storage-identity and transfer-capability checks, artifact verification, and configuration preservation. An offline migration/rollback rehearsal preserved all 23 existing application tables; a fresh off-host database snapshot was verified before cutover. Earlier timing results below describe preceding revisions.Review follow-up:
afe5a64287d97f57345e20785ff77cd4729f0126changes only tests; all 1,180 packed runtime files match the deployment. Thirteen focused cases passed, including explicit staged-read fallback, malformed acknowledgements, upload cleanup, and rejection of identity changes despite a valid frame hash. All 38 applicable follow-up checks passed, including the external Codecov patch check at 92.82% against the unchanged 90% target (repository CI run 34401057984); four scope-based skips were accepted by the merge gate.Current local evidence: 230-suite Toolbox regression passed; focused final transfer, migration/replay and authenticated user-isolation checks passed. Desktop: 208 tests, TypeScript, and production builds passed with both linked candidates and an isolated published-dependency fixture; lint and security checks passed. Real-browser synthetic HTTP/IndexedDB transfer, interruption, corruption rejection and unchanged resync passed in 10.4 seconds on the final runtime. Four fixed portable framing vectors passed; conformance now has 6,483 passing and 211 existing skipped cases.
Health, lint, formatting, typecheck, packed Node consumers and Vite/esbuild/Metro/Hermes checks passed locally. The deployed runtime revision passed all 37 repository hosted checks, including the merge gate, combined coverage, mutation, conformance, CodeQL, zero-new-Sonar, and browser/mobile gates (CI run 34398746700). Four scope-based skips were accepted by the merge gate. No new open code-scanning alerts or unresolved review threads remain. Linux and macOS artifact measurements are documented for review. Proposed narrow bundle-budget increases require explicit review; measured composition and cost are documented in the transfer guide.
Fresh large-wallet validation: a default-provider-to-device copy completed 134,240 records / 817 pages with successful temporary cleanup and both configured backups preserved. All six existing profiles were exercised with saved local copies. The full copy took 45m 29s, including 43m 25s remote reads; this validates completion, not a speedup against the separately optimized provider.
Post-deployment native sample: 20 pages / 4,770 records copied from the deployed revision into temporary IndexedDB in 16.4s; cleanup passed. Foreground timer-delay p95 22 ms, maximum 44 ms across 115 samples. This bounded sample is not a full-wallet benchmark or a controlled speed comparison.
Impact
Release candidates:
@bsv/sdk2.5.0 (upstream's existing unreleased minor candidate, with this PR's compatible timeout and large-payload hashing fixes); toolbox/server, client, and mobile 2.11.0. Publication remains a separate release workflow.Verification
Earlier throughput-candidate results (current transfer validation is summarized above):
pnpm health:check,pnpm lint,pnpm format:check,pnpm typecheck: passed.pnpm --filter @bsv/sdk test: 158 suites, 5,950 tests passed.pnpm --filter @bsv/wallet-toolbox test: 228 suites, 2,202 tests passed; one existing skip.pnpm conformance: all 6,690 vectors in 76 files parsed/validated structurally; this command is not a claim that every external implementation executed them.pnpm test:mutation --target sdk-auth-http: 85.47%; 72 killed, 28 timed out, 17 survived. No mutation threshold or exclusion was changed.pnpm audit:security: passed the existing governed audit policy; existing advisory dispositions remain. No new override or suppression.Measured improvements on synthetic fixtures:
Live native integration results:
A client-only sample against the older server did not improve overall throughput. After binary-capable server deployment, a comparable partial sample took 28.9 seconds versus 34.6 seconds initially. These are observational samples, not a full-wallet comparison against upstream main.
The first completed disposable full restore took 990.3 seconds. Its proof-batch preflight scans and large synchronous signature-payload hashing motivated the indexed lookup and asynchronous hashing fixes in this PR.
The second complete restore took 769.5 seconds versus 990.3 seconds (22.3% less elapsed time), with identical entity counts and successful temporary database cleanup. Reads took 619.2 seconds, writes 146.0 seconds, and measurement 4.1 seconds. Proof-page writes fell from 75.7 to 9.8 seconds. This sequential comparison between candidates does not isolate each optimization or prove a full-wallet speedup against upstream main.
The second full restore's all-state timer-delay p95 was 908 ms. Focus was not recorded, so that metric cannot establish foreground latency. Four subsequent 90-second foreground probes across transactions, outputs, heavier outputs, and proof requests measured p95 delays of 5, 8, 10, and 5 ms; the largest sampled foreground delay was 298 ms. These selected-phase samples do not guarantee latency throughout a full restore.
A retained local backup completed after safe cancellation, a connectivity pause, and checkpoint recovery. A subsequent full native app restart preserved all twelve entity-store counts exactly. Local transaction/output reads passed, a sampled transaction-byte SHA-256 matched its pre-pause fingerprint, and an explicit resync reported zero inserts and zero updates. The original remote primary remained selected. This is not independent byte-for-byte verification of the whole database, nor an offline spending test. This retained restore used the older primary provider, so its duration is not an optimized-server benchmark.
A final 20-page diagnostic against deployed head
7c39d891dfbe654ff1ebc7f79d6cb4d7ca0d2a20completed in 17.7 seconds. All 166 timer samples were visible/focused: p95 delay 24 ms, maximum 48 ms. Temporary database cleanup succeeded. This deliberately bounded sample is not a full restore; network conditions had changed, so it is not a controlled speed comparison.Native development testing exposed a linked-dependency browser-cache issue: rebuilding a candidate could retain an immutable Vite URL and load an older IndexedDB schema. The companion desktop PR fingerprints linked package JavaScript in Vite's optimizer cache identity; reopening the retained backup subsequently passed twice without clearing wallet data. Regression tests cover unchanged package versions and lockfiles. This fix is in metanet-client-desktop#42.
The final deployed revision passed artifact verification, local/public health, authenticated storage identity/capability, and configuration-preservation checks. Health remained successful after the final sample. Private operational evidence stays outside application repositories and PR discussion.
Self-reviewed correctness, security, compatibility, API, artifacts, dependencies, documentation, and operational impact.
All applicable final-head checks reached terminal success, including the separately reported Codecov patch check; no unresolved review/security findings remain.
Security and dependencies
js-yaml3.x resolution from 3.15.1 to 3.15.2 after the audit gate began reporting GHSA-2883-xcg3-v3hh. Reviewed the upstream patch: it charges empty merge sources and rejects abnormally long merge sequences. Only Jest coverage configuration and documentation frontmatter consume this workspace dependency; their tests and the complete docs build passed. Dependency ranges, peer graph, wallet runtime dependencies, and audit policy are unchanged. No new override, release-age exception, or advisory dismissal.Release and operations
Completion evidence and release recommendation
Ready for maintainer review: exact-head repository and external coverage gates, migration/rollback rehearsal, deployment, fresh native large-wallet completion, and final normal backup sync passed. The follow-up changes only tests; its 1,180 packed runtime files are identical to the deployed implementation. The proposed artifact-budget increases require explicit review; transport remains bounded to 64 MiB frames. The earlier whole-wallet throughput results remain valid for that dataset; they did not prove oversized-record support. The new bounded transfer specifically addresses that missing protocol path. No merge or npm publication has been performed.
The desktop application still declares published SDK 2.4.1 / toolbox-client 2.10.2; these integration tests used the linked SDK 2.5.0 / toolbox 2.11.0 candidates. Coordinate publication and reviewed desktop dependency updates before shipping the combined behavior. A candidate-upgraded IndexedDB database requires a schema-compatible client; reverting to the older published client is not a compatible database downgrade.
The measurements support the improvements described above, not a universal throughput or latency guarantee. Public fixtures are synthetic; personal infrastructure, identities, credentials, wallet contents, and raw operational output are excluded.
Record-size boundary and standards
Upgraded peers negotiate version 1 transfers with frames up to 64 MiB and pieces no larger than 256 KiB. Complete frames are still materialized in memory. Uploads resume durable pieces after restart; interrupted downloads resume at the last committed record and may re-download an incomplete record. Larger records fail explicitly and are never skipped. Legacy providers require an upgrade when a single record exceeds their HTTP limits.
BRC-40 is transport-agnostic; reassembled records keep its ordering, watermark, ID maps and commit semantics. BRC-38/39 export/encryption formats are unchanged and their existing regression tests pass. A live IndexedDB copy is not a portable export file. A pre-existing legacy BRC-38 restore migration changes a default-basket liquidity value, so these results are not a blanket claim of exact preservation of every exported value. No spec revision is proposed.