@@ -4009,52 +4009,41 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
4009
4009
4010
4010
// Check the address book data in the same way we did for transactions
4011
4011
std::vector<CTxDestination> dests_to_delete;
4012
- for (const auto & addr_pair : m_address_book) {
4013
- // Labels applied to receiving addresses should go based on IsMine
4014
- if (addr_pair.second .purpose == AddressPurpose::RECEIVE) {
4015
- if (!IsMine (addr_pair.first )) {
4016
- // Check the address book data is the watchonly wallet's
4017
- if (data.watchonly_wallet ) {
4018
- LOCK (data.watchonly_wallet ->cs_wallet );
4019
- if (data.watchonly_wallet ->IsMine (addr_pair.first )) {
4020
- // Add to the watchonly. Copy the entire address book entry
4021
- data.watchonly_wallet ->m_address_book [addr_pair.first ] = addr_pair.second ;
4022
- dests_to_delete.push_back (addr_pair.first );
4023
- continue ;
4024
- }
4025
- }
4026
- if (data.solvable_wallet ) {
4027
- LOCK (data.solvable_wallet ->cs_wallet );
4028
- if (data.solvable_wallet ->IsMine (addr_pair.first )) {
4029
- // Add to the solvable. Copy the entire address book entry
4030
- data.solvable_wallet ->m_address_book [addr_pair.first ] = addr_pair.second ;
4031
- dests_to_delete.push_back (addr_pair.first );
4032
- continue ;
4033
- }
4034
- }
4012
+ for (const auto & [dest, record] : m_address_book) {
4013
+ // Ensure "receive" entries that are no longer part of the original wallet are transferred to another wallet
4014
+ // Entries for everything else ("send") will be cloned to all wallets.
4015
+ bool require_transfer = record.purpose == AddressPurpose::RECEIVE && !IsMine (dest);
4016
+ bool copied = false ;
4017
+ for (auto & wallet : {data.watchonly_wallet , data.solvable_wallet }) {
4018
+ if (!wallet) continue ;
4019
+
4020
+ LOCK (wallet->cs_wallet );
4021
+ if (require_transfer && !wallet->IsMine (dest)) continue ;
4022
+
4023
+ // Copy the entire address book entry
4024
+ wallet->m_address_book [dest] = record;
4025
+
4026
+ copied = true ;
4027
+ // Only delete 'receive' records that are no longer part of the original wallet
4028
+ if (require_transfer) {
4029
+ dests_to_delete.push_back (dest);
4030
+ break ;
4031
+ }
4032
+ }
4035
4033
4036
- // Skip invalid/non-watched scripts that will not be migrated
4037
- if (not_migrated_dests.count (addr_pair.first ) > 0 ) {
4038
- dests_to_delete.push_back (addr_pair.first );
4039
- continue ;
4040
- }
4034
+ // Fail immediately if we ever found an entry that was ours and cannot be transferred
4035
+ // to any of the created wallets (watch-only, solvable).
4036
+ // Means that no inferred descriptor maps to the stored entry. Which mustn't happen.
4037
+ if (require_transfer && !copied) {
4041
4038
4042
- // Not ours, not in watchonly wallet, and not in solvable
4043
- error = _ (" Error: Address book data in wallet cannot be identified to belong to migrated wallets" );
4044
- return false ;
4045
- }
4046
- } else {
4047
- // Labels for everything else ("send") should be cloned to all
4048
- if (data.watchonly_wallet ) {
4049
- LOCK (data.watchonly_wallet ->cs_wallet );
4050
- // Add to the watchonly. Copy the entire address book entry
4051
- data.watchonly_wallet ->m_address_book [addr_pair.first ] = addr_pair.second ;
4052
- }
4053
- if (data.solvable_wallet ) {
4054
- LOCK (data.solvable_wallet ->cs_wallet );
4055
- // Add to the solvable. Copy the entire address book entry
4056
- data.solvable_wallet ->m_address_book [addr_pair.first ] = addr_pair.second ;
4039
+ // Skip invalid/non-watched scripts that will not be migrated
4040
+ if (not_migrated_dests.count (dest) > 0 ) {
4041
+ dests_to_delete.push_back (dest);
4042
+ continue ;
4057
4043
}
4044
+
4045
+ error = _ (" Error: Address book data in wallet cannot be identified to belong to migrated wallets" );
4046
+ return false ;
4058
4047
}
4059
4048
}
4060
4049
0 commit comments