Repository navigation
Repair missing UTXO address rows on startup - #464
Merged
Merged
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
j0ntz
force-pushed
the
jon/ltc-missing-data-layer-address
branch
from
October 8, 2026 17:59
70f5d4d to
4670089
Compare
peachbits
approved these changes
Oct 8, 2026
The Blockbook spec connects to a live Edge server. When that server is slow, the suite fails for every branch. The live block now runs only with LIVE_NETWORK_TESTS=1.
The address tables can report an address count while the rows behind it are unreadable. Android writes a file by truncating it and then writing the new contents, so a process that dies in between leaves an empty bucket file, and the storage layer reads an unparseable bucket as a missing row. Every address of one script type shares a bucket, so one cut-short write loses all of them and the engine failed with "Missing data-layer address" on every later launch. Each row derives from the wallet keys and its path, so rebuild the missing row during initialization and let the address sync again.
A failed initialization left the processor marked as running, so the next start skipped it and connected to servers with no addresses to subscribe to. Clear the flag when initialization throws so the next call runs it again.
j0ntz
force-pushed
the
jon/ltc-missing-data-layer-address
branch
from
October 9, 2026 19:32
4670089 to
b9f1431
Compare
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.
CHANGELOG
Does this branch warrant an entry to the CHANGELOG?
Dependencies
none
Description
A Litecoin wallet on Android (4.52.0 staging) showed
Engine Failed: Missing data-layer address with 'bip49/0/0' path during initializationon every login. The device log has the same failure in four consecutive logins. Each login builds a new engine, which puts the bad state on disk.Cause. The wallet's path index still counts its addresses, but the row for an address cannot be read. Either bucket file can produce this:
tables/addressByScriptPubkey/a914.json(every bip49 address of the wallet shares it) ortables/scriptPubkeyByPath/bip49_0/0.json. The storage layer treats an empty or unparseable bucket as "row not found", andinitializeAddressSubscriptionsthrew on the first missing row. The log does not prove what emptied the file on the reporter's device. The leading candidate is a write cut short by a process kill: Android's disklet write truncates the file before writing it.Fix.
initializeAddressSubscriptionsre-derives a missing row from the wallet keys and its path, saves it, and continues. It still throws if the row cannot be read back after the save.run()clears itsrunningflag when initialization throws. A later call then retries instead of skipping initialization.A repaired row starts with default metadata (unused, never queried). The engine queries it again. Balances are keyed by script, which keeps a repaired address from being counted twice.
Testing.
AddressRepair.spec.tsruns a real Litecoin engine over a memory disklet. It empties each bucket file, restarts the engine, and expects the file content back. A third test covers the retry. All three fail onmasterwith the production error and stack.a914.jsonin the app container. The published 3.15.0 bundle shows theEngine Failedrow from the report. With this branch's bundle the wallet loads and Receive shows its address. The file has the same sha1 as the backup afterward. Emptying the path bucket heals the same way.Blockbooktests opt-in:LIVE_NETWORK_TESTS=1 npm testruns them. They connect tobtc-wusa1.edge.app, and on 2026-10-08 two of them (fetchAddress,fetchAddressUtxos) timed out on this branch and onmaster, which failsnpm run verifyfor any PR. The commit touches only that spec file and can be dropped on its own.Test evidence
4670089Retry UTXO engine init after a failure
2026-10-08
1. before engine failed
2. after wallet loads
3. after receive
Note
Medium Risk
Touches UTXO engine startup and on-disk address recovery; incorrect repair could affect sync state, though repaired rows re-sync and balances stay keyed by scriptPubkey.
Overview
Fixes UTXO wallets that could not load with "Missing data-layer address" when on-disk address buckets were empty or corrupt (e.g. after a truncated write) while path counts still expected those rows.
During
initializeAddressSubscriptions, a missing row is now re-derived from wallet keys and the derivation path, saved via the data layer, and used to continue startup; it still fails if the row cannot be read back after save.run()clears itsrunningguard when initialization throws so a lateraddGapLimitAddresses/ start can retry instead of being skipped permanently.Adds
AddressRepair.spec.ts(Litecoin engine, corrupted bucket files, init retry). LiveBlockbookintegration tests are opt-in viaLIVE_NETWORK_TESTS=1so default CI does not hit external servers.Reviewed by Cursor Bugbot for commit b9f1431. Bugbot is set up for automated code reviews on this repo. Configure here.