diff options
author | Andrew Chow <achow101-github@achow101.com> | 2022-04-13 14:42:00 -0400 |
---|---|---|
committer | Andrew Chow <github@achow101.com> | 2023-06-19 11:29:14 -0400 |
commit | 7be10adff36c0dc49ae56ac571bb033cba7a565b (patch) | |
tree | e1248315b34ed19039026215f6620a92faa103aa /src/wallet/walletdb.cpp | |
parent | 52932c5adb29bb9ec5f0bcde9a31b74113a20651 (diff) | |
download | bitcoin-7be10adff36c0dc49ae56ac571bb033cba7a565b.tar.xz |
walletdb: Refactor key reading and loading to its own function
Diffstat (limited to 'src/wallet/walletdb.cpp')
-rw-r--r-- | src/wallet/walletdb.cpp | 120 |
1 files changed, 67 insertions, 53 deletions
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 05de63fd3e..3958211da8 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -320,6 +320,72 @@ public: CWalletScanState() = default; }; +bool LoadKey(CWallet* pwallet, DataStream& ssKey, DataStream& ssValue, std::string& strErr) +{ + LOCK(pwallet->cs_wallet); + try { + CPubKey vchPubKey; + ssKey >> vchPubKey; + if (!vchPubKey.IsValid()) + { + strErr = "Error reading wallet database: CPubKey corrupt"; + return false; + } + CKey key; + CPrivKey pkey; + uint256 hash; + + ssValue >> pkey; + + // Old wallets store keys as DBKeys::KEY [pubkey] => [privkey] + // ... which was slow for wallets with lots of keys, because the public key is re-derived from the private key + // using EC operations as a checksum. + // Newer wallets store keys as DBKeys::KEY [pubkey] => [privkey][hash(pubkey,privkey)], which is much faster while + // remaining backwards-compatible. + try + { + ssValue >> hash; + } + catch (const std::ios_base::failure&) {} + + bool fSkipCheck = false; + + if (!hash.IsNull()) + { + // hash pubkey/privkey to accelerate wallet load + std::vector<unsigned char> vchKey; + vchKey.reserve(vchPubKey.size() + pkey.size()); + vchKey.insert(vchKey.end(), vchPubKey.begin(), vchPubKey.end()); + vchKey.insert(vchKey.end(), pkey.begin(), pkey.end()); + + if (Hash(vchKey) != hash) + { + strErr = "Error reading wallet database: CPubKey/CPrivKey corrupt"; + return false; + } + + fSkipCheck = true; + } + + if (!key.Load(pkey, vchPubKey, fSkipCheck)) + { + strErr = "Error reading wallet database: CPrivKey corrupt"; + return false; + } + if (!pwallet->GetOrCreateLegacyScriptPubKeyMan()->LoadKey(key, vchPubKey)) + { + strErr = "Error reading wallet database: LegacyScriptPubKeyMan::LoadKey failed"; + return false; + } + } catch (const std::exception& e) { + if (strErr.empty()) { + strErr = e.what(); + } + return false; + } + return true; +} + static bool ReadKeyValue(CWallet* pwallet, DataStream& ssKey, CDataStream& ssValue, CWalletScanState &wss, std::string& strType, std::string& strErr, const KeyFilterFn& filter_fn = nullptr) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) @@ -410,60 +476,8 @@ ReadKeyValue(CWallet* pwallet, DataStream& ssKey, CDataStream& ssValue, pwallet->GetOrCreateLegacyScriptPubKeyMan()->LoadWatchOnly(script); } } else if (strType == DBKeys::KEY) { - CPubKey vchPubKey; - ssKey >> vchPubKey; - if (!vchPubKey.IsValid()) - { - strErr = "Error reading wallet database: CPubKey corrupt"; - return false; - } - CKey key; - CPrivKey pkey; - uint256 hash; - wss.nKeys++; - ssValue >> pkey; - - // Old wallets store keys as DBKeys::KEY [pubkey] => [privkey] - // ... which was slow for wallets with lots of keys, because the public key is re-derived from the private key - // using EC operations as a checksum. - // Newer wallets store keys as DBKeys::KEY [pubkey] => [privkey][hash(pubkey,privkey)], which is much faster while - // remaining backwards-compatible. - try - { - ssValue >> hash; - } - catch (const std::ios_base::failure&) {} - - bool fSkipCheck = false; - - if (!hash.IsNull()) - { - // hash pubkey/privkey to accelerate wallet load - std::vector<unsigned char> vchKey; - vchKey.reserve(vchPubKey.size() + pkey.size()); - vchKey.insert(vchKey.end(), vchPubKey.begin(), vchPubKey.end()); - vchKey.insert(vchKey.end(), pkey.begin(), pkey.end()); - - if (Hash(vchKey) != hash) - { - strErr = "Error reading wallet database: CPubKey/CPrivKey corrupt"; - return false; - } - - fSkipCheck = true; - } - - if (!key.Load(pkey, vchPubKey, fSkipCheck)) - { - strErr = "Error reading wallet database: CPrivKey corrupt"; - return false; - } - if (!pwallet->GetOrCreateLegacyScriptPubKeyMan()->LoadKey(key, vchPubKey)) - { - strErr = "Error reading wallet database: LegacyScriptPubKeyMan::LoadKey failed"; - return false; - } + if (!LoadKey(pwallet, ssKey, ssValue, strErr)) return false; } else if (strType == DBKeys::MASTER_KEY) { // Master encryption key is loaded into only the wallet and not any of the ScriptPubKeyMans. unsigned int nID; |