Do not block the native-module queue while a Zano wallet catches up - #17
Do not block the native-module queue while a Zano wallet catches up#17j0ntz wants to merge 3 commits into
Conversation
84e93c8 to
18302e1
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 18302e1. Configure here.
paullinator
left a comment
There was a problem hiding this comment.
Moving the generateSeedPhrase / postponed-run warning onto configurePostponedRun in startWallet (GitHub will not attach a comment to generateSeedPhrase itself because that method is unchanged in this diff).
Additional Findings
- warning
git:1: All four PR commits exceed the 50-character subject limit (worst is 61: “Open wallets with the refresh worker postponed in startWallet”). Subjects are otherwise imperative and capitalized.- Rewrite subjects to ≤50 characters, e.g. “Postpone refresh worker in startWallet”, “Add migration scheduling design doc”.
d5b4755 to
b9a68a2
Compare
Bugbot is paused — on-demand spend limit reachedBugbot uses usage-based billing for this team and has hit its on-demand spend limit. A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue. |
b9a68a2 to
f3d11d0
Compare
|
Commit subjects are now within 50 characters, and the branch is the two commits you asked for:
Also folded in from the earlier review, since they were still live in the code:
Not done here, with reasons: the |
f3d11d0 to
8a13dae
Compare
|
Correcting my previous reply: two of the three things I deferred there did not deserve deferring, and one misread what you asked. All three are handled now.
|
Bugbot is paused — on-demand spend limit reachedBugbot uses usage-based billing for this team and has hit its on-demand spend limit. A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue. |
|
Additional in-app evidence from today's run (iOS sim, edge-funds, two Zano wallets), which also shows the user-visible shape of the stall: Before (published react-native-zano 0.4.0 installed): the Send scene could not even accept a recipient address. After (this branch linked, plus edge-currency-accountbased#1090): the same drive resolved the address immediately, the wallet finished its catch-up scan (blocks 3,528,465 to 3,826,151), and a 0.063 ZANO send between the two wallets completed to the success scene. So the queue starvation this PR fixes was not only a slowdown, it made address entry and sending unusable while any Zano wallet was behind. |
The 0.4.0 re-key migration ran resetWalletPassword against a wallet whose refresh worker had already taken the per-wallet lock for its entire first catch-up scan, so the call blocked for the whole scan (minutes to hours) while sitting on React Native's shared native-module dispatch queue. On iOS every native-module call in the app queued behind it, which presented as a severe app-wide performance drop whenever a Zano wallet was behind on blocks. Configure the native library's postponed_run_wallet mode before the migration's opens, so no probe or migration open starts a refresh, and start the worker explicitly for the one wallet startWallet returns. Both methods already exist in the shipped native dispatch, so this is a JS-only change. Creating a wallet took the same shape: generateSeedPhrase opened its temporary wallet without postponing the worker, so the closeWallet that follows waited on the per-wallet lock. Configure postponed-run there too, and treat a non-OK close as a failure rather than deleting a file this process still holds open. Also fixes transfer sending an empty payment_id for an integrated address when the caller passed none, and bumps the package to 0.4.1.
Covers the investigation evidence, the postponed-run design across this repo and edge-currency-accountbased, and the post-implementation retrospective. Covers the phase history through the Android validation-build fix, the QA verification, and the create-wallet instance of the same stall.
c93048f to
3b67325
Compare



Technical Design Document
zano-migration-off-module-queue.md
Description
QA reported severe app-wide iOS slowdowns after edge-react-gui upgraded to react-native-zano 0.4.0 (task: https://app.asana.com/0/1215088146871429/1217559756673909).
Root cause, captured live with a thread sample on the sim:
startWallet's wallet-file re-key migration opens the wallet with the legacy password, and that open auto-starts the native refresh worker, which takes the per-wallet recursive mutex for the entire first catch-up scan. The migration's next step,resetWalletPassword, blocks on that mutex until the scan finishes (minutes for a wallet weeks behind, hours for a fresh rescan) while sitting on React Native's shared native-module dispatch queue. Every native-module call in the app queues behind it, which presents as a severe app-wide performance drop. The app usually dies before the migration completes, so the file is never re-keyed and every launch repeats the same blocked migration. 0.3.0 had no re-key step, which is why the regression tracks the 0.4.0 upgrade.The fix is scheduling only, and JS-only: configure the native library's
postponed_run_walletmode before the migration's opens, so no probe or migration open starts a refresh worker, and start the worker explicitly (run_wallet, idempotent) for the one walletstartWalletreturns. Both methods already exist in the shipped native dispatch. The migration's correctness rules (legacy password order, rebuild guards, passphrase handling) are untouched.Verified on the iOS sim against an account with three Zano wallets that were weeks behind:
resetWalletPasswordobserved blocked on the wallet mutex for 15+ minutes oncom.meta.react.turbomodulemanager.queue; a probe pollinggetOpenedWalletsstarved the whole time; wallet files never re-keyed across many launches.Testing
npm test(34 passing, including new coverage: the migration call sequence now postpones the worker and runs only the returned wallet; every terminal path leaves exactly the returned wallet running)npx tsc --noEmit,verify-repo.shcleanNote
Medium Risk
Touches wallet open/migration scheduling and process-wide postponed-run mode; behavior is well-tested but incorrect
run_wallettiming could leave wallets not syncing until callers adopt/run them.Overview
Fixes app-wide iOS slowdown after 0.4.0 by changing when the native refresh worker starts, not migration logic.
startWalletnow calls nativeconfigurewithpostponed_run_wallet: truebefore any open/restore, so probe and re-key opens do not auto-start a catch-up scan that holds the per-wallet lock. New helpersconfigurePostponedRunandrunWalletwrap those sync calls; every successful return path runsstarted(), which callsrun_walletonly for the wallet being returned.Migration rules (legacy passwords, rebuild, passphrase handling) are unchanged. Tests and the fake module track
runningWalletsto assertconfigurefirst,run_walletlast, and that only the returned wallet syncs. CHANGELOG and a design doc document the TurboModule queue / mutex interaction.Reviewed by Cursor Bugbot for commit 7e73277. Bugbot is set up for automated code reviews on this repo. Configure here.