aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Maxwell <greg@xiph.org>2017-07-15 01:00:30 +0000
committerGregory Maxwell <greg@xiph.org>2017-07-17 13:46:07 +0000
commit30d8f3a18e7d927459e409a38ee1c0d1ddf054ad (patch)
tree82256aa871d5204c641b624703674bac6cda7a21
parent3a53f19718a2207f0d74c32a611ae91703d9da8d (diff)
downloadbitcoin-30d8f3a18e7d927459e409a38ee1c0d1ddf054ad.tar.xz
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.
-rw-r--r--src/wallet/wallet.cpp35
-rw-r--r--src/wallet/wallet.h1
2 files changed, 29 insertions, 7 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index b3b3c1c10a..d8c1dd94fc 100644
--- a/src/wallet/wallet.cpp
+++ b/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
- if (fCompressed)
+ if (fCompressed) {
SetMinVersion(FEATURE_COMPRPUBKEY);
+ }
CPubKey pubkey = secret.GetPubKey();
assert(secret.VerifyPubKey(pubkey));
@@ -115,8 +116,9 @@ CPubKey CWallet::GenerateNewKey(CWalletDB &walletdb, bool internal)
mapKeyMetadata[pubkey.GetID()] = metadata;
UpdateTimeFirstKey(nCreationTime);
- if (!AddKeyPubKey(secret, pubkey))
+ if (!AddKeyPubKeyWithDB(walletdb, secret, pubkey)) {
throw std::runtime_error(std::string(__func__) + ": AddKey failed");
+ }
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");
}
-bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
+bool CWallet::AddKeyPubKeyWithDB(CWalletDB &walletdb, const CKey& secret, const CPubKey &pubkey)
{
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;
+ }
+ if (needsDB) pwalletdbEncryption = NULL;
// check if we need to remove from watch-only
CScript script;
script = GetScriptForDestination(pubkey.GetID());
- if (HaveWatchOnly(script))
+ if (HaveWatchOnly(script)) {
RemoveWatchOnly(script);
+ }
script = GetScriptForRawPubKey(pubkey);
- if (HaveWatchOnly(script))
+ if (HaveWatchOnly(script)) {
RemoveWatchOnly(script);
+ }
if (!IsCrypted()) {
- return CWalletDB(*dbw).WriteKey(pubkey,
+ return walletdb.WriteKey(pubkey,
secret.GetPrivKey(),
mapKeyMetadata[pubkey.GetID()]);
}
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,
const std::vector<unsigned char> &vchCryptedSecret)
{
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index e91a6effd3..0bf6ccf722 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -869,6 +869,7 @@ public:
CPubKey GenerateNewKey(CWalletDB& walletdb, bool internal = false);
//! Adds a key to the store, and saves it to disk.
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)
bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); }
//! Load metadata (used by LoadWallet)