From d67055e00dd90f504384e5c3f229fc95306d5aac Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Tue, 3 Dec 2019 19:06:15 -0500 Subject: [PATCH] Upgrade or rewrite encrypted key checksums If fDecryptionThoroughlyChecked is false, after a key has been checked, write (or rewrite) its checksum. This serves to upgrade wallets and correct those which have the checksum corrupted but not the key. --- src/wallet/scriptpubkeyman.cpp | 5 +++++ src/wallet/walletdb.cpp | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp index 6d65d6f69..fba2bf731 100644 --- a/src/wallet/scriptpubkeyman.cpp +++ b/src/wallet/scriptpubkeyman.cpp @@ -210,6 +210,7 @@ bool LegacyScriptPubKeyMan::CheckDecryptionKey(const CKeyingMaterial& master_key bool keyPass = mapCryptedKeys.empty(); // Always pass when there are no encrypted keys bool keyFail = false; CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin(); + WalletBatch batch(m_storage.GetDatabase()); for (; mi != mapCryptedKeys.end(); ++mi) { const CPubKey &vchPubKey = (*mi).second.first; @@ -223,6 +224,10 @@ bool LegacyScriptPubKeyMan::CheckDecryptionKey(const CKeyingMaterial& master_key keyPass = true; if (fDecryptionThoroughlyChecked) break; + else { + // Rewrite these encrypted keys with checksums + batch.WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]); + } } if (keyPass && keyFail) { diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index ab1ad1a64..6cb8c720f 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -114,7 +114,14 @@ bool WalletBatch::WriteCryptedKey(const CPubKey& vchPubKey, const auto key = std::make_pair(DBKeys::CRYPTED_KEY, vchPubKey); if (!WriteIC(key, std::make_pair(vchCryptedSecret, checksum), false)) { - return false; + // It may already exist, so try writing just the checksum + std::vector val; + if (!m_batch.Read(key, val)) { + return false; + } + if (!WriteIC(key, std::make_pair(val, checksum), true)) { + return false; + } } EraseIC(std::make_pair(DBKeys::KEY, vchPubKey)); return true;