fix(crowdnode): single history scan per restore pass instead of two - #973
Merged
Conversation
restoreState() ran the identical full post-2022 history fetch twice back-to-back on wallets with no CrowdNode account: once in tryRestoreSignUp(), then again in getApiAddressConfirmationTx() via getOnlineAccountAddress(). On a 7k-tx wallet each fetch materializes ~5,900 SwiftData rows (~6.5s, observed up to 38s under sync load), so the restore paid that cost twice at every launch sync-done. Hoist one shared snapshot into restoreState() and pass it to both consumers. Every path now performs exactly one scan (previously one or two); no consumer sees fewer rows than before. No fetchLimit on purpose: the fetch is newest-first, so a cap would silently drop old signup transactions and fail to restore real accounts. Verified on the QA-iPhone16 simulator against a synthetic 7,007-tx mainnet store: "restoring CrowdNode state" is now followed by exactly one "CrowdNode scan" line (fetch 5944 rows) and the account-not-found memo still suppresses repeat scans in-session. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthrough
ChangesCrowdNode restoration
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested reviewers: ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
This was referenced Aug 10, 2026
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.
Issue being fixed or feature implemented
App startup on a large wallet logged "restoring CrowdNode state" followed by two identical full-history scans (
CrowdNode scan: fetch 5940 rows in 6496ms/6474mson a 7k-tx mainnet wallet — up to 38s per scan under concurrent sync load). OnerestoreState()pass ran the same SwiftData fetch twice: once intryRestoreSignUp(), and — when no signup was found, i.e. on every wallet that never used CrowdNode — again ingetApiAddressConfirmationTx()viagetOnlineAccountAddress(). Each fetch materializes every post-2022 row (~1.1ms/row), so the common case paid the multi-second cost twice at every launch sync-done.What was done?
restoreState()now fetches one shared snapshot (fetchObserved(firstSeenAtOrAfter: januaryFirst2022Epoch)) and passes it to both consumers:tryRestoreSignUp(_:)andgetOnlineAccountAddress(state:observed:)→getApiAddressConfirmationTx(in:).fetchLimit: the fetch is newest-first, so a cap would silently drop old signup transactions and fail to restore real accounts — now documented at the fetch site.FullCrowdNodeSignUpTxSet(the floor constant is applied byrestoreState, nottryRestoreSignUp).Reviewer note: skipping the restore scan outright under the CrowdNode-suspension release posture was considered and rejected for now — the suspension is not implemented on this branch (Explore menu, shortcuts, balance reminder, and interrupted-signup resume all still consume restored CrowdNode state). If/when the hide lands, gating
checkCrowdNodeState()behind the same flag can zero this cost entirely.How Has This Been Tested?
dashpayscheme build (arm64 simulator).restoring CrowdNode statefollowed by twoCrowdNode scanlines (12,005ms + 38,585ms in the worst observed launch); with this fix the same launch logs exactly one scan (fetch 5944 rows in 11035ms) followed byCrowdNode: account not found, and the in-session memo still prevents any further scans.Breaking Changes
None.
Checklist:
For repository code-owners and collaborators only
🤖 Generated with Claude Code
Summary by CodeRabbit