@@ -4007,21 +4007,44 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
4007
4007
}
4008
4008
}
4009
4009
4010
+ // Pair external wallets with their corresponding db handler
4011
+ std::vector<std::pair<std::shared_ptr<CWallet>, std::unique_ptr<WalletBatch>>> wallets_vec;
4012
+ for (const auto & ext_wallet : {data.watchonly_wallet , data.solvable_wallet }) {
4013
+ if (!ext_wallet) continue ;
4014
+
4015
+ std::unique_ptr<WalletBatch> batch = std::make_unique<WalletBatch>(ext_wallet->GetDatabase ());
4016
+ if (!batch->TxnBegin ()) {
4017
+ error = strprintf (_ (" Error: database transaction cannot be executed for wallet %s" ), ext_wallet->GetName ());
4018
+ return false ;
4019
+ }
4020
+ wallets_vec.emplace_back (ext_wallet, std::move (batch));
4021
+ }
4022
+
4023
+ // Write address book entry to disk
4024
+ auto func_store_addr = [](WalletBatch& batch, const CTxDestination& dest, const CAddressBookData& entry) {
4025
+ auto address{EncodeDestination (dest)};
4026
+ if (entry.purpose ) batch.WritePurpose (address, PurposeToString (*entry.purpose ));
4027
+ if (entry.label ) batch.WriteName (address, *entry.label );
4028
+ for (const auto & [id, request] : entry.receive_requests ) {
4029
+ batch.WriteAddressReceiveRequest (dest, id, request);
4030
+ }
4031
+ if (entry.previously_spent ) batch.WriteAddressPreviouslySpent (dest, true );
4032
+ };
4033
+
4010
4034
// Check the address book data in the same way we did for transactions
4011
4035
std::vector<CTxDestination> dests_to_delete;
4012
4036
for (const auto & [dest, record] : m_address_book) {
4013
4037
// Ensure "receive" entries that are no longer part of the original wallet are transferred to another wallet
4014
4038
// Entries for everything else ("send") will be cloned to all wallets.
4015
4039
bool require_transfer = record.purpose == AddressPurpose::RECEIVE && !IsMine (dest);
4016
4040
bool copied = false ;
4017
- for (auto & wallet : {data.watchonly_wallet , data.solvable_wallet }) {
4018
- if (!wallet) continue ;
4019
-
4041
+ for (auto & [wallet, batch] : wallets_vec) {
4020
4042
LOCK (wallet->cs_wallet );
4021
4043
if (require_transfer && !wallet->IsMine (dest)) continue ;
4022
4044
4023
4045
// Copy the entire address book entry
4024
4046
wallet->m_address_book [dest] = record;
4047
+ func_store_addr (*batch, dest, record);
4025
4048
4026
4049
copied = true ;
4027
4050
// Only delete 'receive' records that are no longer part of the original wallet
@@ -4047,24 +4070,15 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
4047
4070
}
4048
4071
}
4049
4072
4050
- // Persist added address book entries (labels, purpose) for watchonly and solvable wallets
4051
- auto persist_address_book = [](const CWallet& wallet) {
4052
- LOCK (wallet.cs_wallet );
4053
- WalletBatch batch{wallet.GetDatabase ()};
4054
- for (const auto & [destination, addr_book_data] : wallet.m_address_book ) {
4055
- auto address{EncodeDestination (destination)};
4056
- if (addr_book_data.purpose ) batch.WritePurpose (address, PurposeToString (*addr_book_data.purpose ));
4057
- if (addr_book_data.label ) batch.WriteName (address, *addr_book_data.label );
4058
- for (const auto & [id, request] : addr_book_data.receive_requests ) {
4059
- batch.WriteAddressReceiveRequest (destination, id, request);
4060
- }
4061
- if (addr_book_data.previously_spent ) batch.WriteAddressPreviouslySpent (destination, true );
4073
+ // Persist external wallets address book entries
4074
+ for (auto & [wallet, batch] : wallets_vec) {
4075
+ if (!batch->TxnCommit ()) {
4076
+ error = strprintf (_ (" Error: address book copy failed for wallet %s" ), wallet->GetName ());
4077
+ return false ;
4062
4078
}
4063
- };
4064
- if (data.watchonly_wallet ) persist_address_book (*data.watchonly_wallet );
4065
- if (data.solvable_wallet ) persist_address_book (*data.solvable_wallet );
4079
+ }
4066
4080
4067
- // Remove the things to delete
4081
+ // Remove the things to delete in this wallet
4068
4082
if (dests_to_delete.size () > 0 ) {
4069
4083
for (const auto & dest : dests_to_delete) {
4070
4084
if (!DelAddressBook (dest)) {
0 commit comments