|
|
|
@ -306,6 +306,8 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
@@ -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,
@@ -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)) |
|
|
|
|