Browse Source

Pushdown walletdb though CWallet::AddKeyPubKey to avoid flushes.

This prevents the wallet from being flushed between each and
 every key during top-up.  This results in a >10x speed-up
 for the top-up.
0.15
Gregory Maxwell 7 years ago
parent
commit
30d8f3a18e
  1. 35
      src/wallet/wallet.cpp
  2. 1
      src/wallet/wallet.h

35
src/wallet/wallet.cpp

@ -106,8 +106,9 @@ CPubKey CWallet::GenerateNewKey(CWalletDB &walletdb, bool internal)
} }
// Compressed public keys were introduced in version 0.6.0 // Compressed public keys were introduced in version 0.6.0
if (fCompressed) if (fCompressed) {
SetMinVersion(FEATURE_COMPRPUBKEY); SetMinVersion(FEATURE_COMPRPUBKEY);
}
CPubKey pubkey = secret.GetPubKey(); CPubKey pubkey = secret.GetPubKey();
assert(secret.VerifyPubKey(pubkey)); assert(secret.VerifyPubKey(pubkey));
@ -115,8 +116,9 @@ CPubKey CWallet::GenerateNewKey(CWalletDB &walletdb, bool internal)
mapKeyMetadata[pubkey.GetID()] = metadata; mapKeyMetadata[pubkey.GetID()] = metadata;
UpdateTimeFirstKey(nCreationTime); UpdateTimeFirstKey(nCreationTime);
if (!AddKeyPubKey(secret, pubkey)) if (!AddKeyPubKeyWithDB(walletdb, secret, pubkey)) {
throw std::runtime_error(std::string(__func__) + ": AddKey failed"); throw std::runtime_error(std::string(__func__) + ": AddKey failed");
}
return pubkey; return pubkey;
} }
@ -166,29 +168,48 @@ void CWallet::DeriveNewChildKey(CWalletDB &walletdb, CKeyMetadata& metadata, CKe
throw std::runtime_error(std::string(__func__) + ": Writing HD chain model failed"); throw std::runtime_error(std::string(__func__) + ": Writing HD chain model failed");
} }
bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey) bool CWallet::AddKeyPubKeyWithDB(CWalletDB &walletdb, const CKey& secret, const CPubKey &pubkey)
{ {
AssertLockHeld(cs_wallet); // mapKeyMetadata AssertLockHeld(cs_wallet); // mapKeyMetadata
if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey))
// CCryptoKeyStore has no concept of wallet databases, but calls AddCryptedKey
// which is overridden below. To avoid flushes, the database handle is
// tunneled through to it.
bool needsDB = !pwalletdbEncryption;
if (needsDB) {
pwalletdbEncryption = &walletdb;
}
if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey)) {
if (needsDB) pwalletdbEncryption = NULL;
return false; return false;
}
if (needsDB) pwalletdbEncryption = NULL;
// check if we need to remove from watch-only // check if we need to remove from watch-only
CScript script; CScript script;
script = GetScriptForDestination(pubkey.GetID()); script = GetScriptForDestination(pubkey.GetID());
if (HaveWatchOnly(script)) if (HaveWatchOnly(script)) {
RemoveWatchOnly(script); RemoveWatchOnly(script);
}
script = GetScriptForRawPubKey(pubkey); script = GetScriptForRawPubKey(pubkey);
if (HaveWatchOnly(script)) if (HaveWatchOnly(script)) {
RemoveWatchOnly(script); RemoveWatchOnly(script);
}
if (!IsCrypted()) { if (!IsCrypted()) {
return CWalletDB(*dbw).WriteKey(pubkey, return walletdb.WriteKey(pubkey,
secret.GetPrivKey(), secret.GetPrivKey(),
mapKeyMetadata[pubkey.GetID()]); mapKeyMetadata[pubkey.GetID()]);
} }
return true; return true;
} }
bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
{
CWalletDB walletdb(*dbw);
return CWallet::AddKeyPubKeyWithDB(walletdb, secret, pubkey);
}
bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
const std::vector<unsigned char> &vchCryptedSecret) const std::vector<unsigned char> &vchCryptedSecret)
{ {

1
src/wallet/wallet.h

@ -869,6 +869,7 @@ public:
CPubKey GenerateNewKey(CWalletDB& walletdb, bool internal = false); CPubKey GenerateNewKey(CWalletDB& walletdb, bool internal = false);
//! Adds a key to the store, and saves it to disk. //! Adds a key to the store, and saves it to disk.
bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey) override; bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey) override;
bool AddKeyPubKeyWithDB(CWalletDB &walletdb,const CKey& key, const CPubKey &pubkey);
//! Adds a key to the store, without saving it to disk (used by LoadWallet) //! Adds a key to the store, without saving it to disk (used by LoadWallet)
bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); } bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); }
//! Load metadata (used by LoadWallet) //! Load metadata (used by LoadWallet)

Loading…
Cancel
Save