diff options
author | Gregory Maxwell <greg@xiph.org> | 2017-07-15 01:00:30 +0000 |
---|---|---|
committer | Gregory Maxwell <greg@xiph.org> | 2017-07-17 13:46:07 +0000 |
commit | 30d8f3a18e7d927459e409a38ee1c0d1ddf054ad (patch) | |
tree | 82256aa871d5204c641b624703674bac6cda7a21 /src/wallet/wallet.cpp | |
parent | 3a53f19718a2207f0d74c32a611ae91703d9da8d (diff) | |
download | bitcoin-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.
Diffstat (limited to 'src/wallet/wallet.cpp')
-rw-r--r-- | src/wallet/wallet.cpp | 35 |
1 files changed, 28 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) { |