Summary
A wallet restored with a Wallet Creation Date set only scans the chain from that date
forward. Settings → Rescan blockchain with the date cleared is the way to widen it back out.
It does not work: the app arms the rewind, the SDK reports no error, but the scan never replays
the earlier range. The wallet keeps its partial balance and truncated history indefinitely.
There is currently no in-app recovery from a wrong creation date. The only remedy found is to
restore the wallet again from the recovery phrase with the date left unset.
Found while testing a separate UI fix; reproduced on two builds, neither of which touches the
rescan path.
Environment
- Android 16 (API 36) emulator,
_testNet3 release, versionCode 12000014 (12.0.0-upgrade)
- Reproduced on
fix/upgrade-memory-and-sync @ 70569d6 and on a branch off it @ 3f4c603a5
- Testnet, large shared QA wallet (~108 tDASH, history back to 2020)
Steps to reproduce
- Fresh install.
- Restore a wallet with plenty of old history, and on the restore screen set Wallet Creation
Date to today.
- Wait for
L1Shadow phase=SYNCED 100.0%. Note the partial balance, and that
BirthHeightResolver mapped the date to birth height 1,401,408 of a 1,558,713 tip.
- Settings → Rescan blockchain. Tap the X beside the pre-filled date so the field reads
"Select" (no date). Tap Rescan.
- Watch
/data/data/<pkg>/files/log/wallet.log.
Observed
The arm looks correct:
BirthHeightResolver - resolved birth time 1427610960 to SDK birth height 0 (checkpoint height 1728, margin 4032 blocks)
DashSdkServiceImpl - armSpvRescan: filter watermark rewind to 0 armed on b7118ed5…
SdkWalletBinder - blockchain-reset rescan arm on b7118ed5…: armed=true
The scan does not follow it. Over 40 minutes the filter cursor oscillated in a ~15k-block
window sitting at the dated bind's own birth height, never descending:
10:25:47 phase=FILTERS 97.0% headers 1558715/1558715 filters 1416407/1558715 wallet 1558715
10:31:17 phase=FILTERS 96.6% headers 1558717/1558717 filters 1401407/1558717 wallet 1558715
...
11:04:29 phase=FILTERS 96.6% headers 1558733/1558733 filters 1401407/1558733 wallet 1558715
The committed wallet cursor stayed at tip throughout and memory was flat (~340 MB PSS) — so
nothing is being replayed; this is not a slow replay or a leak. Network Monitor read
"Scanning block filters 94%, Block filters 1,401,407 / 1,558,733". Balance unchanged.
Second trial, arming the rescan and then closing from recents and relaunching (in case the
rewind applies at engine start): the engine settled straight back to
phase=SYNCED 100.0% filters 1558738/1558738 within a minute. Balance unchanged, oldest history
row unchanged.
Expected
After a rescan with no date, the scan restarts from the earliest HD seed height and the wallet
ends up with the same balance and history as a dateless restore of the same seed.
Control — the engine can do the full scan
The same wallet, restored fresh with the date left unset, scans from genesis and finishes in
6 minutes 24 seconds:
11:06:35 restore complete (birth height 0)
11:08:10 phase=HEADERS 39.0% headers 1214000/1558734 filters 90999/1558734 wallet 90999
11:12:59 phase=SYNCED 100.0% headers 1558736/1558736 filters 1558736/1558736 wallet 1558736
|
dated restore |
+ dateless rescan |
dateless restore |
| balance |
22.704714 tDASH |
22.704714 tDASH |
108.051627 tDASH |
| oldest history row |
20 Sep 2026 |
20 Sep 2026 |
Feb 2020 |
| scan floor |
height 1,401,408 |
armed 0, unchanged |
height 0 |
So it is specifically the rewind of an already-bound wallet that does not take.
Where to look
The app side appears to do the right thing. SdkWalletBinder.armSpvRescanForBlockchainReset() →
DashSdkServiceImpl.armSpvRescan() (DashSdkServiceImpl.kt:867) resolves the birth height
through the same checkpoint mapping the bind used, then calls:
manager.rescanSpvFilters(walletId, birthHeight.toInt()) // birthHeight = 0 here
That call returns without throwing — the success log line is emitted — so the defect is at or
below rescanSpvFilters. The suspect is the SDK wallet's own stored birthHeight, fixed at
1,401,408 when the wallet was created during the dated restore and never lowered: if the rewind
target is clamped to it, that would explain the cursor sitting exactly there.
Worth confirming whether rescanSpvFilters is expected to lower a wallet's birth height at all,
or whether the app has to re-create/re-bind the wallet to widen the scan.
Related
A wallet in this state also reported a bare "Synced" with no indication that most of the chain
was never scanned. That reporting half is being fixed separately. That fix derives its warning
from the stored creation-date preference, because the scan floor the engine actually used is
not exposed to the app — so a dateless rescan clears the preference and retires the warning
while leaving the wallet just as partial.
Exposing the bound wallet's real birthHeight (or the height its filter scan actually started
from) would fix both this issue and that gap.
Summary
A wallet restored with a Wallet Creation Date set only scans the chain from that date
forward. Settings → Rescan blockchain with the date cleared is the way to widen it back out.
It does not work: the app arms the rewind, the SDK reports no error, but the scan never replays
the earlier range. The wallet keeps its partial balance and truncated history indefinitely.
There is currently no in-app recovery from a wrong creation date. The only remedy found is to
restore the wallet again from the recovery phrase with the date left unset.
Found while testing a separate UI fix; reproduced on two builds, neither of which touches the
rescan path.
Environment
_testNet3release, versionCode 12000014 (12.0.0-upgrade)fix/upgrade-memory-and-sync@ 70569d6 and on a branch off it @ 3f4c603a5Steps to reproduce
Date to today.
L1Shadow phase=SYNCED 100.0%. Note the partial balance, and thatBirthHeightResolvermapped the date to birth height 1,401,408 of a 1,558,713 tip."Select" (no date). Tap Rescan.
/data/data/<pkg>/files/log/wallet.log.Observed
The arm looks correct:
The scan does not follow it. Over 40 minutes the filter cursor oscillated in a ~15k-block
window sitting at the dated bind's own birth height, never descending:
The committed
walletcursor stayed at tip throughout and memory was flat (~340 MB PSS) — sonothing is being replayed; this is not a slow replay or a leak. Network Monitor read
"Scanning block filters 94%, Block filters 1,401,407 / 1,558,733". Balance unchanged.
Second trial, arming the rescan and then closing from recents and relaunching (in case the
rewind applies at engine start): the engine settled straight back to
phase=SYNCED 100.0% filters 1558738/1558738within a minute. Balance unchanged, oldest historyrow unchanged.
Expected
After a rescan with no date, the scan restarts from the earliest HD seed height and the wallet
ends up with the same balance and history as a dateless restore of the same seed.
Control — the engine can do the full scan
The same wallet, restored fresh with the date left unset, scans from genesis and finishes in
6 minutes 24 seconds:
So it is specifically the rewind of an already-bound wallet that does not take.
Where to look
The app side appears to do the right thing.
SdkWalletBinder.armSpvRescanForBlockchainReset()→DashSdkServiceImpl.armSpvRescan()(DashSdkServiceImpl.kt:867) resolves the birth heightthrough the same checkpoint mapping the bind used, then calls:
manager.rescanSpvFilters(walletId, birthHeight.toInt()) // birthHeight = 0 hereThat call returns without throwing — the success log line is emitted — so the defect is at or
below
rescanSpvFilters. The suspect is the SDK wallet's own storedbirthHeight, fixed at1,401,408 when the wallet was created during the dated restore and never lowered: if the rewind
target is clamped to it, that would explain the cursor sitting exactly there.
Worth confirming whether
rescanSpvFiltersis expected to lower a wallet's birth height at all,or whether the app has to re-create/re-bind the wallet to widen the scan.
Related
A wallet in this state also reported a bare "Synced" with no indication that most of the chain
was never scanned. That reporting half is being fixed separately. That fix derives its warning
from the stored creation-date preference, because the scan floor the engine actually used is
not exposed to the app — so a dateless rescan clears the preference and retires the warning
while leaving the wallet just as partial.
Exposing the bound wallet's real
birthHeight(or the height its filter scan actually startedfrom) would fix both this issue and that gap.