diff options
-rw-r--r-- | src/wallet/wallet.cpp | 75 |
1 files changed, 32 insertions, 43 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index e392f7f8aa..cebb7b3912 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4009,52 +4009,41 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error) // Check the address book data in the same way we did for transactions std::vector<CTxDestination> dests_to_delete; - for (const auto& addr_pair : m_address_book) { - // Labels applied to receiving addresses should go based on IsMine - if (addr_pair.second.purpose == AddressPurpose::RECEIVE) { - if (!IsMine(addr_pair.first)) { - // Check the address book data is the watchonly wallet's - if (data.watchonly_wallet) { - LOCK(data.watchonly_wallet->cs_wallet); - if (data.watchonly_wallet->IsMine(addr_pair.first)) { - // Add to the watchonly. Copy the entire address book entry - data.watchonly_wallet->m_address_book[addr_pair.first] = addr_pair.second; - dests_to_delete.push_back(addr_pair.first); - continue; - } - } - if (data.solvable_wallet) { - LOCK(data.solvable_wallet->cs_wallet); - if (data.solvable_wallet->IsMine(addr_pair.first)) { - // Add to the solvable. Copy the entire address book entry - data.solvable_wallet->m_address_book[addr_pair.first] = addr_pair.second; - dests_to_delete.push_back(addr_pair.first); - continue; - } - } + for (const auto& [dest, record] : m_address_book) { + // Ensure "receive" entries that are no longer part of the original wallet are transferred to another wallet + // Entries for everything else ("send") will be cloned to all wallets. + bool require_transfer = record.purpose == AddressPurpose::RECEIVE && !IsMine(dest); + bool copied = false; + for (auto& wallet : {data.watchonly_wallet, data.solvable_wallet}) { + if (!wallet) continue; + + LOCK(wallet->cs_wallet); + if (require_transfer && !wallet->IsMine(dest)) continue; + + // Copy the entire address book entry + wallet->m_address_book[dest] = record; + + copied = true; + // Only delete 'receive' records that are no longer part of the original wallet + if (require_transfer) { + dests_to_delete.push_back(dest); + break; + } + } - // Skip invalid/non-watched scripts that will not be migrated - if (not_migrated_dests.count(addr_pair.first) > 0) { - dests_to_delete.push_back(addr_pair.first); - continue; - } + // Fail immediately if we ever found an entry that was ours and cannot be transferred + // to any of the created wallets (watch-only, solvable). + // Means that no inferred descriptor maps to the stored entry. Which mustn't happen. + if (require_transfer && !copied) { - // Not ours, not in watchonly wallet, and not in solvable - error = _("Error: Address book data in wallet cannot be identified to belong to migrated wallets"); - return false; - } - } else { - // Labels for everything else ("send") should be cloned to all - if (data.watchonly_wallet) { - LOCK(data.watchonly_wallet->cs_wallet); - // Add to the watchonly. Copy the entire address book entry - data.watchonly_wallet->m_address_book[addr_pair.first] = addr_pair.second; - } - if (data.solvable_wallet) { - LOCK(data.solvable_wallet->cs_wallet); - // Add to the solvable. Copy the entire address book entry - data.solvable_wallet->m_address_book[addr_pair.first] = addr_pair.second; + // Skip invalid/non-watched scripts that will not be migrated + if (not_migrated_dests.count(dest) > 0) { + dests_to_delete.push_back(dest); + continue; } + + error = _("Error: Address book data in wallet cannot be identified to belong to migrated wallets"); + return false; } } |