Skip to content

test: add native USDT recovery fault fixture - #180

Open
ben-kaufman wants to merge 3 commits into
masterfrom
test/native-usdt-recovery-fixture
Open

ben-kaufman wants to merge 3 commits into
masterfrom
test/native-usdt-recovery-fixture

Conversation

@ben-kaufman

@ben-kaufman ben-kaufman commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator

Companion: synonymdev/bitkit-ios#1118
Companion: synonymdev/bitkit-android#1681

Description

Add a loopback RPC/VSS fixture so both apps can exercise actual native signing, encrypted recovery uploads and restart/restore without funds. It injects rejected writes or committed writes with lost acknowledgements, records every submission attempt before validation, and preserves an independent original-operation oracle. Native tests must acknowledge their own recovery record before submitting the same signed operation.

Preview

N/A — test infrastructure, no UI changes.

QA Notes

Setup

Follow the pinned recipe. Use Node 22+, locked dependencies, a dedicated simulator/emulator with no application wallet, and the companion app branches. The recipe starts a loopback-only server and runs prepare, resume and restore in separate native test processes. Never fund the public fixture mnemonic or reset an existing wallet.

Verified

  • 1. npm run check and npm test passed. The black-box guard test proves rejected invalid submissions are counted, the original oracle cannot be replaced, and evidence/token survive server restart.
  • 2. Both native platforms passed rejected backup and lost-acknowledgement cases, retries, separate-process restart and fresh-database restore. Each phase requires its own injected fault, acknowledgement and identical signed payload. iOS test tree is committed as 9a763eb4; Android as 2d8f87470.
  • 3. iOS-to-Android and Android-to-iOS encrypted snapshot restore passed with the same signed operation.
  • 4. cargo fmt --check, CI-scope Clippy and git diff --check passed. All 94 Clippy warning blocks match unchanged Core production; this PR changes no Rust code. Final companion gates passed 2,889 iOS unit tests and 4,602 Android unit tests with clean native format/lint reports.

Native evidence used Core c393f8e0, Paykit e79b7bbb and Pubky 65a331e0 built locally; it is not proof of released dependency adoption. The initial native protocol evidence used fixture 3c6cbca9. Review repair 16e67c7d now validates and persists the entire control update before changing live state; mixed-field rejection and disk-write failure tests fail before the repair and pass after it. Independent re-review found no remaining actionable issue. Commit 96420950 runs the fixture syntax and regression tests in hosted CI.

Limits

This fixture does not execute deployed contracts, validate LNURL signatures or test the complete UI/Paykit journey. Android exercises the recovery store directly; iOS exercises the BackupService handler. The complete-wallet assertion preserves sentinel bytes, not a full-wallet migration. The unused Pubky 503 endpoint is not outage-integration evidence. Existing component tests cover migration/concurrent state changes separately. One iOS test launch was rejected by Simulator before execution and a later restore was interrupted by the chat shutdown; the final fresh rejected-backup sequence passed all phases.

Models used

  • Planning/scoping: gpt-6-astra (reasoning: xhigh)
  • Implementation: gpt-6-astra (reasoning: xhigh)
  • Review: gpt-6-astra (reasoning: xhigh)

@talosmachina talosmachina left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 finding (1 P2). Adds a loopback RPC/VSS fixture with fault injection and an append-only event ledger for the native USDT recovery tests; no Rust changes. Reviewed 3c6cbca, full tier.

What I checked, and 4 candidates I ruled out

Read in full: provider.mjs, control.mjs, provider.test.mjs, README.md, package.json, package-lock.json, .gitignore
Ran: npm ci --ignore-scripts, npm run check, npm test on Node 24: 1/1 pass. Reproduced the finding against a live fixture on a scratch port.
Cross-checked: how the bitkit-android#1681 test drives /control (mode with advance, faultMode read back).
CI: green (usdt-tests, SwiftPM manifest, Scripts/Cargo/Android manifests). CI does not run the fixture's npm test.

Ruled out

  • Lockfile pulls from an unexpected source: all 9 packages resolve from registry.npmjs.org with integrity hashes; ethers 6.17.0 pinned exactly.
  • Server reachable off-box: binds 127.0.0.1 only.
  • Path traversal through the case id: load() requires ^[a-z0-9-]{1,64}$ before touching the filesystem.
  • Second, different operation accepted on resubmission: a resubmitted hash must deep-equal the stored payload, and the companion test asserts exactly one operation.

Merge confidence: 4/5, one P2 in the fault-injection control path; the rest is covered by the fixture's own test and the companion runs.

Comment thread tests/native-recovery/provider.mjs Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants