From dd578cb290d89a810b95098cec113dee7345737a Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Thu, 24 Mar 2022 17:02:43 -0600 Subject: [PATCH] Restore legacy default Sapling addresses to the keystore. Prior to zcash/zcash@90e59c3be0d15152b3d0da5bb069930846c2877b Sapling default payment addresses were added to the in-memory keystore whenever a full viewing key was added, or loaded from disk. After that change, the Sapling address was no longer being restored to the in-memory keystore on wallet load; instead, z_getnewaddress and z_getnewaddressforaccount both persist the address to the keystore directly. This commit adds handling to `LoadCaches` to correctly persist the default address to the wallet database, and add it to the in-memory keystore, when this condition is detected. --- src/wallet/wallet.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 4697a90d6..197e50d9b 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1136,6 +1136,32 @@ bool CWallet::LoadCaches() } } + // Sapling legacy addresses were not directly added to the keystore; instead, + // 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; + } + } + } + } + } + } + // Restore decrypted Orchard notes. for (const auto& [_, walletTx] : mapWallet) { if (!walletTx.orchardTxMeta.empty()) {