MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / ApplyMigrationData

Method ApplyMigrationData

src/wallet/wallet.cpp:3939–4149  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3937}
3938
3939util::Result<void> CWallet::ApplyMigrationData(WalletBatch& local_wallet_batch, MigrationData& data)
3940{
3941 AssertLockHeld(cs_wallet);
3942
3943 LegacyDataSPKM* legacy_spkm = GetLegacyDataSPKM();
3944 if (!Assume(legacy_spkm)) {
3945 // This shouldn't happen
3946 return util::Error{Untranslated(STR_INTERNAL_BUG("Error: Legacy wallet data missing"))};
3947 }
3948
3949 // Note: when the legacy wallet has no spendable scripts, it must be empty at the end of the process.
3950 bool has_spendable_material = !data.desc_spkms.empty() || data.master_key.key.IsValid();
3951
3952 // Get all invalid or non-watched scripts that will not be migrated
3953 std::set<CTxDestination> not_migrated_dests;
3954 for (const auto& script : legacy_spkm->GetNotMineScriptPubKeys()) {
3955 CTxDestination dest;
3956 if (ExtractDestination(script, dest)) not_migrated_dests.emplace(dest);
3957 }
3958
3959 // When the legacy wallet has no spendable scripts, the main wallet will be empty, leaving its script cache empty as well.
3960 // The watch-only and/or solvable wallet(s) will contain the scripts in their respective caches.
3961 if (!data.desc_spkms.empty()) Assume(!m_cached_spks.empty());
3962 if (!data.watch_descs.empty()) Assume(!data.watchonly_wallet->m_cached_spks.empty());
3963 if (!data.solvable_descs.empty()) Assume(!data.solvable_wallet->m_cached_spks.empty());
3964
3965 for (auto& desc_spkm : data.desc_spkms) {
3966 if (m_spk_managers.contains(desc_spkm->GetID())) {
3967 return util::Error{_("Error: Duplicate descriptors created during migration. Your wallet may be corrupted.")};
3968 }
3969 uint256 id = desc_spkm->GetID();
3970 AddScriptPubKeyMan(id, std::move(desc_spkm));
3971 }
3972
3973 // Remove the LegacyScriptPubKeyMan from disk
3974 if (!legacy_spkm->DeleteRecordsWithDB(local_wallet_batch)) {
3975 return util::Error{_("Error: cannot remove legacy wallet records")};
3976 }
3977
3978 // Remove the LegacyScriptPubKeyMan from memory
3979 m_spk_managers.erase(legacy_spkm->GetID());
3980 m_external_spk_managers.clear();
3981 m_internal_spk_managers.clear();
3982
3983 // Setup new descriptors (only if we are migrating any key material)
3984 SetWalletFlagWithDB(local_wallet_batch, WALLET_FLAG_DESCRIPTORS | WALLET_FLAG_LAST_HARDENED_XPUB_CACHED);
3985 if (has_spendable_material && !IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
3986 // Use the existing master key if we have it
3987 if (data.master_key.key.IsValid()) {
3988 SetupDescriptorScriptPubKeyMans(local_wallet_batch, data.master_key);
3989 } else {
3990 // Setup with a new seed if we don't.
3991 SetupOwnDescriptorScriptPubKeyMans(local_wallet_batch);
3992 }
3993 }
3994
3995 // Get best block locator so that we can copy it to the watchonly and solvables
3996 // Note: The best block locator was introduced in #152 so ancient wallets do not have it

Callers 1

wallet.cppFile · 0.80

Calls 15

UntranslatedFunction · 0.85
ExtractDestinationFunction · 0.85
_Function · 0.85
ErrorStringFunction · 0.85
EncodeDestinationFunction · 0.85
PurposeToStringFunction · 0.85
emplaceMethod · 0.80
DeleteRecordsWithDBMethod · 0.80
WriteOrderPosNextMethod · 0.80
IsFromMeMethod · 0.80
LoadToWalletMethod · 0.80

Tested by

no test coverage detected