Monero / Wallets / Development
Monero Wallet Sync Fix Would Reject Invalid Daemon Heights
Monero PR 11720 adds a wallet sync check for invalid daemon start heights. What the code, regression test and current release establish.

A proposed Monero wallet fix would reject a daemon reply that places block hashes beyond the end of the wallet's stored chain. Developer kah-ja reports that the missing check can leave a wallet showing the wrong height and unable to complete later refreshes until it rescans the blockchain. PR #11720 adds the check to wallet2, the Monero wallet code.
At the 2026-11-10 23:58 UTC source check, the PR was open and unmerged. jpk68 and selsta had approved it. Its needs backport label identifies release-branch work to verify separately. The inspected patch is commit 0a424db.
Block hashes during wallet synchronization
A wallet needs blockchain information to find payments and keep track of its synchronization progress. The daemon supplies that information, while the wallet manages its keys. Our wallets and nodes introduction explains those roles.
Monero's fast_refresh path can fetch block hashes while advancing toward the height where fuller scanning should begin. A hash identifies a block. Downloading hashes for that earlier part of the chain avoids processing every block as a potential payment to the wallet. The calling code selects this path when a requested starting height, restore height or skip height is ahead of the wallet's current chain size.
The reply includes a starting height that tells the wallet where the returned sequence belongs. A list of hashes is not enough on its own. The wallet must also check whether that position makes sense for its existing chain.
The missing upper bound
Before this patch, fast_refresh checks whether the daemon's starting height falls below the stored hash chain's offset. That offset matters because the wallet can trim older entries. The proposal adds the opposite check: the reply must not start beyond the chain's current size. Patch and surrounding code.
Consider a wallet with only its genesis entry. Its chain size is one. A reply claims to start at height 11 and supplies 20 hashes. The old loop appends hashes at the current container end even though the reply claims a later starting position. It does not fill the missing positions through height 10 first. The stored positions and the reply's claimed heights no longer agree.
Those numbers come from the proposed regression test, not a report of an affected user's wallet. They show why checking the returned hashes' position matters. The PR author reports the resulting wrong height and later refresh failures. We inspected the code and test but did not independently reproduce that complete failure and recovery sequence.

The new condition is blocks_start_height > m_blockchain.size(). Equality remains allowed, so a reply can begin exactly where the next entry belongs. On an excessive starting height, the function logs the problem and returns before processing that batch. The caller can then continue through regular block refresh, unless the application stops refresh. This check validates remote data used by the wallet. The patch leaves Monero's consensus rules unchanged.
Regression test and its limits
The added unit test uses a mocked HTTP client. Its hash response specifies start height 11, current height 50 and 20 random hash values. The callback stops refresh so the test can examine the wallet's chain after this response. The assertion expects its size to remain one.
The author reports that this test fails without the patch and passes with it. GitHub's checks for the inspected commit reported 18 successful check runs, including an Ubuntu 24.04 tests job. We did not run the C++ test locally or inspect a separate per-test execution log. The assertion covers preservation of the chain size. It does not exercise later refreshes or recovery.
Release status and exposure
The latest stable release returned by the upstream release API was Monero v0.18.5.4. Its wallet source contains the lower-bound check and append loop but lacks this new upper bound. That establishes the missing check in this release. We have not established a complete historical affected-version range or which third-party wallet builds include the same code.
A malicious daemon would need to supply the inconsistent reply while the wallet is using this fast-refresh path. A broken daemon could also return bad data. A daemon can construct this reply without knowing wallet keys. The patch and test provide no evidence that this bug permits seed theft, transaction forgery or loss of funds. The reviewed PR, comments and test contain no report of exploitation against users.
This is separate from the legacy transaction-proof verification issues. Those concern evidence used to check a claimed payment or spend. PR #11720 concerns the wallet's synchronization bookkeeping.
What wallet users should do
Use a maintained wallet and check its release notes for the fix when an update becomes available. Check a release's actual contents before assuming an installed binary includes the fix.
If a wallet reports inconsistent heights or repeatedly fails to refresh, check its daemon connection and the wallet's documented recovery options. The author names rescan_blockchain as recovery for the reported state. That is not a universal diagnosis for synchronization failures. Preserve your recovery information before attempting recovery, and never provide a seed or private key to a remote-node operator.
The next verifiable milestones are a merge, any release-branch backport and a release containing the correction.