Skip to content

Commit b4fb0a3

Browse files
committed
Merge bitcoin/bitcoin#26761: wallet: fully migrate address book entries for watchonly/solvable wallets
730e14a test: wallet: check that labels are migrated to watchonly wallet (Sebastian Falbesoner) d5f4ae7 wallet: fully migrate address book entries for watchonly/solvable wallets (Sebastian Falbesoner) Pull request description: Currently `migratewallet` migrates the address book (i.e. labels and purposes) for watchonly and solvable wallets only in RAM, but doesn't persist them on disk. Fix this by adding another loop for both of the special wallet types after which writes the corresponding NAME and PURPOSE entries to the database in a single batch. Also adds a corresponding test that checks if labels were migrated correctly for a watchonly wallet. ACKs for top commit: achow101: ACK 730e14a furszy: code ACK 730e14a, left a non-blocking nit. aureleoules: ACK 730e14a Tree-SHA512: 159487e11e858924ef762e0190ccaea185bdff239e3d2280c8d63c4ac2649ec71714dc4d53dec644f03488f91c3b4bbbbf3434dad23bc0fcecb6657f353ea766
2 parents 3212d10 + 730e14a commit b4fb0a3

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

src/wallet/wallet.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4001,6 +4001,23 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
40014001
}
40024002
}
40034003
}
4004+
4005+
// Persist added address book entries (labels, purpose) for watchonly and solvable wallets
4006+
auto persist_address_book = [](const CWallet& wallet) {
4007+
LOCK(wallet.cs_wallet);
4008+
WalletBatch batch{wallet.GetDatabase()};
4009+
for (const auto& [destination, addr_book_data] : wallet.m_address_book) {
4010+
auto address{EncodeDestination(destination)};
4011+
auto purpose{addr_book_data.purpose};
4012+
auto label{addr_book_data.GetLabel()};
4013+
// don't bother writing default values (unknown purpose, empty label)
4014+
if (purpose != "unknown") batch.WritePurpose(address, purpose);
4015+
if (!label.empty()) batch.WriteName(address, label);
4016+
}
4017+
};
4018+
if (data.watchonly_wallet) persist_address_book(*data.watchonly_wallet);
4019+
if (data.solvable_wallet) persist_address_book(*data.solvable_wallet);
4020+
40044021
// Remove the things to delete
40054022
if (dests_to_delete.size() > 0) {
40064023
for (const auto& dest : dests_to_delete) {

test/functional/wallet_migration.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ def test_other_watchonly(self):
258258
self.log.info("Test migration of a wallet with watchonly imports")
259259
imports0 = self.create_legacy_wallet("imports0")
260260

261-
# Exteranl address label
261+
# External address label
262262
imports0.setlabel(default.getnewaddress(), "external")
263263

264264
# Normal non-watchonly tx
@@ -311,6 +311,13 @@ def test_other_watchonly(self):
311311
assert_raises_rpc_error(-5, "Invalid or non-wallet transaction id", watchonly.gettransaction, received_txid)
312312
assert_equal(len(watchonly.listtransactions(include_watchonly=True)), 3)
313313

314+
# Check that labels were migrated and persisted to watchonly wallet
315+
self.nodes[0].unloadwallet("imports0_watchonly")
316+
self.nodes[0].loadwallet("imports0_watchonly")
317+
labels = watchonly.listlabels()
318+
assert "external" in labels
319+
assert "imported" in labels
320+
314321
def test_no_privkeys(self):
315322
default = self.nodes[0].get_wallet_rpc(self.default_wallet_name)
316323

0 commit comments

Comments
 (0)