Skip to content

Potential crash (assert) rescanning wallet #31474

Closed
@psgreco

Description

@psgreco

Is there an existing issue for this?

  • I have searched the existing issues

Current behaviour

Preface: This whole analysis was made using Elements Core, not Bitcoin Core, but the code and the conditions should line up in a way that makes this likely in Bitcoin too.

There's an assert crash in assert(chain_depth >= 0); // coinbase tx should not be conflicted calling CWallet::GetTxBlocksToMaturity because CWallet::GetTxDepthInMainChain returns a negative value for TxStateConfirmed txs. The reason for this is that m_last_block_processed is set at the beginning of AttachChain, but the rescan loop keeps going beyond that point, so when GetTxDepthInMainChain is called right after the scan is done, m_last_block_processed is lower than the actual block in the latest txs, hence returning a negative value and crashing.

In discussions with @achow101 , it's possible that #30221 fixes this issue by calling SetBestBlock after the rescan is done. Another approach could be to stop the scan when m_last_block_processed is reached with something like this

@@ -1689,6 +1693,11 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
         if (max_height && block_height >= *max_height) {
             break;
         }
+        if (block_height >= GetLastBlockHeight()) {
+            WalletLogPrintf("Stopping scan. At block %d. Progress=%f\n", block_height, progress_current);
+            break;
+        }
+
         {
             if (!next_block) {
                 // break successfully when rescan has reached the tip, or

Expected behaviour

The wallet data should be consistent to avoid the crash

Steps to reproduce

This is reproduced using QT

  1. Create a chain with many coinbase txs.
  2. Attach a wallet (could be read only) with the address of the coinbase txs
  3. While the wallet is still being loaded, create many more blocks with coinbase txs to that address
  4. Assert happens when the wallet is done loading

Relevant log output

No response

How did you obtain Bitcoin Core

Compiled from source

What version of Bitcoin Core are you using?

master@62bd61de110b057cbfd6e31e4d0b727d93119c72

Operating system and version

Fedora 41

Machine specifications

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions