Merge pull request #5759 from nuttycom/fix/restore_imported_addrs

Ensure that legacy imported addresses are properly restored to the wallet.
This commit is contained in:
Kris Nuttycombe 2022-03-29 07:33:36 -06:00 committed by GitHub
commit a574f6042b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 18 deletions

View File

@ -4,7 +4,14 @@
# file COPYING or https://www.opensource.org/licenses/mit-license.php .
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, start_nodes, connect_nodes_bi, NU5_BRANCH_ID
from test_framework.util import (
assert_equal,
connect_nodes_bi,
start_nodes,
stop_nodes,
wait_bitcoinds,
NU5_BRANCH_ID,
)
from test_framework.mininode import nuparams
# Test wallet address behaviour across network upgrades
@ -105,6 +112,25 @@ class WalletAddressesTest(BitcoinTestFramework):
assert 'diversifier_index' in unified_obj[0]['addresses'][0]
assert_equal(unified_obj[0]['addresses'][0]['receiver_types'], ['p2pkh', 'sapling', 'orchard'])
# import the key for sapling_1 into node 1
sapling_1_key = self.nodes[0].z_exportkey(sapling_1)
self.nodes[1].z_importkey(sapling_1_key)
# verify that we see the imported source
listed_addresses = self.list_addresses(1, ['imported', 'mnemonic_seed'])
imported_src = get_source(listed_addresses, 'imported')
assert_equal(imported_src['sapling'][0]['addresses'], [sapling_1])
# stop the nodes & restart to ensure that the imported address
# still shows up in listaddresses output
stop_nodes(self.nodes)
wait_bitcoinds()
self.setup_network()
listed_addresses = self.list_addresses(1, ['imported', 'mnemonic_seed'])
imported_src = get_source(listed_addresses, 'imported')
assert_equal(imported_src['sapling'][0]['addresses'], [sapling_1])
print("Testing height 2 (NU5)")
self.nodes[0].generate(1)
self.sync_all()

View File

@ -1134,22 +1134,23 @@ bool CWallet::LoadCaches()
// the default address for each key was automatically added to the in-memory
// keystore, but not persisted. Following the addition of unified addresses,
// all addresses must be written to the wallet database explicitly.
auto legacySeed = GetLegacyHDSeed();
if (legacySeed.has_value()) {
for (const auto& [saplingIvk, keyMeta] : mapSaplingZKeyMetadata) {
// This condition only applies for keys derived from the legacy seed
if (keyMeta.seedFp == legacySeed.value().Fingerprint()) {
SaplingExtendedFullViewingKey extfvk;
if (GetSaplingFullViewingKey(saplingIvk, extfvk)) {
auto defaultAddress = extfvk.DefaultAddress();
if (!HaveSaplingIncomingViewingKey(defaultAddress)) {
// restore the address to the keystore and persist it so that
// the database state is consistent.
if (!AddSaplingPaymentAddress(saplingIvk, defaultAddress)) {
LogPrintf("%s: Error: Failed to write legacy Sapling payment address to the wallet database.\n",
__func__);
return false;
}
auto mnemonicSeed = GetMnemonicSeed();
for (const auto& [saplingIvk, keyMeta] : mapSaplingZKeyMetadata) {
// This condition only applies for keys derived from the legacy seed
// or from imported keys.
if (!mnemonicSeed.has_value() || keyMeta.seedFp != mnemonicSeed.value().Fingerprint()) {
SaplingExtendedFullViewingKey extfvk;
if (GetSaplingFullViewingKey(saplingIvk, extfvk)) {
// only add the association with the default address if it
// does not already exist
auto defaultAddress = extfvk.DefaultAddress();
if (!HaveSaplingIncomingViewingKey(defaultAddress)) {
// restore the address to the keystore and persist it so that
// the database state is consistent.
if (!AddSaplingPaymentAddress(saplingIvk, defaultAddress)) {
LogPrintf("%s: Error: Failed to write legacy Sapling payment address to the wallet database.\n",
__func__);
return false;
}
}
}
@ -2493,7 +2494,7 @@ void CWallet::AddToSpends(const uint256& wtxid)
}
// for Orchard, the effects of this operation are performed by
// AddNotesIfInvolvingMe and LoadUnifiedCaches
// AddNotesIfInvolvingMe and LoadCaches
}
void CWallet::ClearNoteWitnessCache()