aboutsummaryrefslogtreecommitdiff
path: root/src/walletdb.cpp
diff options
context:
space:
mode:
authorGavin Andresen <gavinandresen@gmail.com>2013-10-16 20:12:38 -0700
committerGavin Andresen <gavinandresen@gmail.com>2013-10-16 20:12:38 -0700
commit796e7b7aecd84a5c0cd7098c2f770ef8fba732e3 (patch)
tree1abfc8aaa832090071cf96ea611685d7af86a64f /src/walletdb.cpp
parent5a8a4be28949fd0531ae5ea8e21c713373e22c01 (diff)
parentbc68788317a4ece16f0cfb0cb7eb1e0e220cbc6f (diff)
Merge pull request #2950 from pstratem/walletload
Walletload
Diffstat (limited to 'src/walletdb.cpp')
-rw-r--r--src/walletdb.cpp38
1 files changed, 33 insertions, 5 deletions
diff --git a/src/walletdb.cpp b/src/walletdb.cpp
index 635fda1b42..efcd59d5f1 100644
--- a/src/walletdb.cpp
+++ b/src/walletdb.cpp
@@ -306,6 +306,8 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
}
CKey key;
CPrivKey pkey;
+ uint256 hash = 0;
+
if (strType == "key")
{
wss.nKeys++;
@@ -315,14 +317,40 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
ssValue >> wkey;
pkey = wkey.vchPrivKey;
}
- if (!key.SetPrivKey(pkey, vchPubKey.IsCompressed()))
+
+ // Old wallets store keys as "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 "key"[pubkey] => [privkey][hash(pubkey,privkey)], which is much faster while
+ // remaining backwards-compatible.
+ try
{
- strErr = "Error reading wallet database: CPrivKey corrupt";
- return false;
+ ssValue >> hash;
+ }
+ catch(...){}
+
+ bool fSkipCheck = false;
+
+ if (hash != 0)
+ {
+ // 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.begin(), vchKey.end()) != hash)
+ {
+ strErr = "Error reading wallet database: CPubKey/CPrivKey corrupt";
+ return false;
+ }
+
+ fSkipCheck = true;
}
- if (key.GetPubKey() != vchPubKey)
+
+ if (!key.Load(pkey, vchPubKey, fSkipCheck))
{
- strErr = "Error reading wallet database: CPrivKey pubkey inconsistency";
+ strErr = "Error reading wallet database: CPrivKey corrupt";
return false;
}
if (!pwallet->LoadKey(key, vchPubKey))