wallet, migration: Warn and skip unidentified transactions #35826

pull pablomartin4btc wants to merge 2 commits into bitcoin:master from pablomartin4btc:wallet/fix-migratewallet-unowned-txs changing 2 files +67 −2
  1. pablomartin4btc commented at 5:26 PM on July 27, 2026: member

    Fixes #35626.

    <details> <summary>Legacy wallets can contain transactions they don't own, due to BDB log file cross-contamination.</summary>

    This happened when users swapped wallet.dat files manually (stopping the node and renaming files) without first flushing the BDB log files. BDB writes data to log files before checkpointing them into wallet.dat; if only the .dat was swapped but the log files remained, a subsequent node start replayed those logs into the new wallet, writing in transactions from a completely different wallet. The affected wallet has no keys or scripts for those transactions — gettransaction shows an empty details array.

    </details>

    Before this fix, migratewallet aborted with a fatal error when it encountered such a transaction in mapWallet that belonged to no migrated wallet:

      Error: Transaction <txid> in wallet cannot be identified to belong to migrated wallets

    <details> <summary>This change downgrades the fatal error to a warning and removes the unidentified transaction from the migrated wallet instead of aborting (as <a href="https://github.com/bitcoin/bitcoin/issues/35626#issuecomment-4846118013">suggested</a> by achow101).</summary>

    The txid is logged so the user can inspect it. The existing txids_to_delete / RemoveTxs mechanism (already used for watchonly transactions) handles the removal.



    </details>

    This fix applies to both the migratewallet RPC and the equivalent GUI option, as both go through the same migration code path.

    <details> <summary>A test is added to <code>wallet_migration.py</code> that simulates the cross-contamination scenario...</summary>

    a watchonly address is imported so the wallet records a foreign transaction, then the watchonly script and address book BDB records are erased, leaving a transaction in mapWallet with no wallet claiming it.

    </details>

  2. test: add test for migratewallet with unidentified transactions
    Adds a test to wallet_migration.py that simulates BDB log file
    cross-contamination (issue #35626): a transaction is present in
    mapWallet but belongs to no migrated wallet.
    
    The test documents the current (broken) behaviour: migratewallet
    aborts with "cannot be identified to belong to migrated wallets".
    93a75b7895
  3. wallet: warn and skip unidentified transactions during migration
    When ApplyMigrationData encounters a transaction in mapWallet that
    belongs to no migrated wallet, warn and remove it instead of aborting
    the migration.
    
    This fixes a real-world failure (issue #35626) where legacy wallets
    contain transactions they don't own due to BDB log file
    cross-contamination: swapping wallet.dat files manually without
    flushing BDB log files causes a different wallet's transactions to be
    written into the swapped-in wallet. The wallet has no keys or scripts
    for those transactions, so migration previously failed fatally.
    
    The warning identifies the dropped txid in the debug log.
    5bdc9468f6
  4. DrahtBot commented at 5:26 PM on July 27, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--006a51241073e994b41acfe9ec718e94-->

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/35826.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline and AI policy for information on the review process. A summary of reviews will appear here.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #35716 (wallet: Replace mapWallet and wtxOrdered with a boost::multi_index by achow101)
    • #34909 (wallet, refactor: modularise wallet by extracting out legacy wallet migration by rkrux)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

    LLM Linter (✨ experimental)

    Possible places where named args for integral literals may be used (e.g. func(x, /*named_arg=*/0) in C++, and func(x, named_arg=0) in Python):

    • listtransactions("*", 100, 0, True) in test/functional/wallet_migration.py

    <sup>2026-07-27 17:26:49</sup>

  5. furszy commented at 6:50 PM on July 27, 2026: member

    The scenario where this can realistically occur is rare. And, on the other hand, silently dropping a tx because migration failed to handle a valid script would hide a real correctness bug.

    I wouldn't touch this, and would continue failing with a clear error that identifies the affected tx(s) so the user can act on them. I don't think dropping txs automatically and only logging the drop is the best approach, as the user may never read the log.


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-07-31 20:50 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me