Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2024-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or https://www.opensource.org/licenses/mit-license.php.5#include <addresstype.h>6#include <bench/bench.h>7#include <consensus/amount.h>8#include <interfaces/wallet.h>9#include <key.h>10#include <primitives/block.h>11#include <primitives/transaction.h>12#include <pubkey.h>13#include <script/script.h>14#include <sync.h>15#include <test/util/setup_common.h>16#include <tinyformat.h>17#include <uint256.h>18#include <util/check.h>19#include <util/result.h>20#include <wallet/db.h>21#include <wallet/scriptpubkeyman.h>22#include <wallet/test/util.h>23#include <wallet/transaction.h>24#include <wallet/wallet.h>25#include <wallet/walletdb.h>27#include <algorithm>28#include <cstdint>29#include <cstddef>30#include <memory>31#include <optional>32#include <string>33#include <utility>34#include <vector>36namespace wallet{38static void WalletMigration(benchmark::Bench& bench)39{40const auto test_setup{MakeNoLogFileContext<TestingSetup>()};41const auto loader{MakeWalletLoader(*test_setup->m_node.chain, test_setup->m_args)};43// Number of imported watch only addresses44int NUM_WATCH_ONLY_ADDR = 20;46// Add watch-only addresses47std::vector<std::pair<CScript, CTxDestination>> scripts_watch_only;48for (int w = 0; w < NUM_WATCH_ONLY_ADDR; ++w) {49CKey key = GenerateRandomKey();50const PKHash dest{key.GetPubKey()};51scripts_watch_only.emplace_back(GetScriptForDestination(dest), dest);52}54// Generate transactions and local addresses55std::vector<CKey> keys(500);56std::ranges::generate(keys, []{ return GenerateRandomKey(); });58std::unique_ptr<CWallet> wallet;59size_t i = 0;60bench.epochs(/*numEpochs=*/1) // run the migration exactly once61.setup([&] {62// Setup legacy wallet63wallet = std::make_unique<CWallet>(test_setup->m_node.chain.get(), std::string(i++, 'A'), CreateMockableWalletDatabase());64LegacyDataSPKM* legacy_spkm = wallet->GetOrCreateLegacyDataSPKM();65WalletBatch batch{wallet->GetDatabase()};67LOCK(wallet->cs_wallet);69// Write a best block record as migration expects one to exist70CBlockLocator loc;71batch.WriteBestBlock(loc);73// Add watch-only addresses74for (size_t w = 0; w < scripts_watch_only.size(); ++w) {75const auto& [script, dest] = scripts_watch_only.at(w);76assert(legacy_spkm->LoadWatchOnly(script));77assert(wallet->SetAddressBook(dest, strprintf("watch_%d", w), /*purpose=*/std::nullopt));78batch.WriteWatchOnly(script, CKeyMetadata());79}81// Generate transactions and local addresses82for (size_t j = 0; j < keys.size(); ++j) {83const CKey& key = keys.at(j);84// Load key, scripts and create address book record85CPubKey pubkey = key.GetPubKey();86Assert(legacy_spkm->LoadKey(key, pubkey));87CTxDestination dest{PKHash(pubkey)};88Assert(wallet->SetAddressBook(dest, strprintf("legacy_%d", j), /*purpose=*/std::nullopt));90CMutableTransaction mtx;91mtx.vout.emplace_back(COIN, GetScriptForDestination(dest));92mtx.vout.emplace_back(COIN, scripts_watch_only.at(j % NUM_WATCH_ONLY_ADDR).first);93// Use distinct dummy prevouts so all txs don't appear to spend the same null outpoint94mtx.vin.emplace_back(COutPoint(Txid::FromUint256(uint256{uint8_t(j + 1)}), 0));95mtx.vin.emplace_back(COutPoint(Txid::FromUint256(uint256{uint8_t(j + 1)}), 1));96wallet->AddToWallet(MakeTransactionRef(mtx), TxStateInactive{}, /*update_wtx=*/nullptr, /*rescanning_old_block=*/true);97batch.WriteKey(pubkey, key.GetPrivKey(), CKeyMetadata());98}99})100.run([&] {101auto res{MigrateLegacyToDescriptor(std::move(wallet), /*passphrase=*/"", *loader->context())};102assert(res);103assert(res->wallet);104assert(res->watchonly_wallet);105});106}108BENCHMARK(WalletMigration);110} // namespace wallet
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.