[v0.1.x-branch] Backport #1131: mobile: prevent wallet stalls on external I/O - #1202
Merged
Conversation
Mobile hosts cannot pass caller contexts through gomobile. They may retain stale transports across OS suspension. Bound repeatable reads and invoice creation without retrying an uncertain receive. Keep the local satoshi balance available when optional remote credit enrichment stalls. (cherry picked from commit b854311)
Mobile wallet recovery asks the chain backend to filter remote blocks. The v0.18.0 wallet holds its database writer while that backend call is in flight, which can stall unrelated wallet operations on a slow path. Update to the merged btcwallet recovery change. It builds requests under a short read transaction, performs filter I/O without an open transaction, and atomically persists each batch while serializing address derivation. This keeps recovery progress atomic without blocking unrelated database writers during remote filter calls. The iOS binding build and the full wallet-runtime unit suite pass against the new version. (cherry picked from commit a4575fe)
Apply the binding-owned read deadline to every repeatable mobile read. Return a stable uncertain-outcome prefix when Receive reaches its own deadline. Document that receive timeouts over five minutes are rejected. (cherry picked from commit 038df79)
Mark Receive cancellation by either its request deadline or wallet Stop with the same stable uncertain-outcome prefix. This tells mobile hosts to reconcile Activity before retrying after foreground timeouts and lifecycle cancellation. (cherry picked from commit a41cc55)
Log the error when optional credit enrichment is omitted from an otherwise valid local balance response. This lets operators distinguish a degraded remote read from a genuine zero-credit wallet without failing the local refresh. (cherry picked from commit 502fa87)
Release the Postgres fixture semaphore after Docker startup and store migrations finish instead of retaining it until test cleanup. This preserves bounded initialization while preventing parallel tests from exhausting every slot and blocking the remaining test barrier. (cherry picked from commit 7da20dd)
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.
Backport of #1131
The problem
Mobile hosts call the embedded Wavelength wallet through gomobile, which cannot carry a caller
context.Context. If iOS or Android suspends the process while an external connection is using an old network path, wallet reads and Lightning invoice creation can wait for the embedded daemon's full lifetime instead of returning control to the app.Wallet recovery can cause a second stall. btcwallet v0.18.0 keeps its database writer open while the chain backend filters recovery blocks. The lightweight backend may perform remote I/O during that call, so unrelated wallet operations can wait behind a slow recovery request.
Read calls are safe to repeat. Invoice creation is different: a deadline or lifecycle cancellation may race durable receive-session creation, so cancellation does not prove that no invoice exists.
The fix
GetInfo,Balance,List,ExitStatus,ExitSummary,GetExitPlan,Status, and the scalar convenience helpers.Receivean optionalTimeoutSecondsfield. Older hosts receive a 20-second default. Values above five minutes are rejected.Receiveas an uncertain outcome with a stable reconcile-before-retry error prefix.Safety rule
The host may retry timed-out reads. It must not blindly retry a canceled
Receive; it must first reconcile the authoritative Activity view and recover any matching invoice.Recovery keeps address-index operations serialized and commits each completed batch atomically, while unrelated database writers remain available during remote filter I/O.
What does not change
TimeoutSeconds.Tests
make lint-changed-localmake tidy-module-checkmake unit-swapruntimego test -tags='mobile wavewalletrpc swapruntime' ./sdk/wavewalletdk/mobilego test -tags='wavewalletrpc swapruntime' ./swapwallet -run '^TestServiceBalance' -count=1go test -tags=test_postgres ./waved -count=1 -timeout=30mgo test -tags=test_postgres ./db -count=1 -timeout=30mmake mobile-iosThe tests cover default and explicit mobile deadlines, invalid deadline values, repeatable read deadlines, uncertain
Receivecancellation, healthy credit enrichment, credit timeout fallback and logging, and the Postgres fixture-slot lifecycle. The full wallet-runtime suite and iOS xcframework build pass against the updated btcwallet dependency.Exact-head CI passes all 20 required checks, including Postgres unit and system tests, race tests, SQLite tests, lint, static checks, and every cross-build.
Compatibility and rollout
TimeoutSecondsis additive at the mobile JSON boundary. Older Wavelength bindings ignore the extra field. Updated bindings apply the bounded default even when an older host omits it.The btcwallet fix is pinned to
v0.18.1-0.20260826052527-33c252f3b4d6, the Go pseudo-version for merged commit33c252f3b4d6. No btcwallet v0.18.1 tag exists yet.After this PR merges, publish a Wavelength release containing both changes. wavelength-mobile#6 can then consume and validate the release xcframework.