Skip to content

Commit 30d8f3a

Browse files
committed
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.
1 parent 3a53f19 commit 30d8f3a

File tree

2 files changed

+29
-7
lines changed

2 files changed

+29
-7
lines changed

src/wallet/wallet.cpp

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,17 +106,19 @@ CPubKey CWallet::GenerateNewKey(CWalletDB &walletdb, bool internal)
106106
}
107107

108108
// Compressed public keys were introduced in version 0.6.0
109-
if (fCompressed)
109+
if (fCompressed) {
110110
SetMinVersion(FEATURE_COMPRPUBKEY);
111+
}
111112

112113
CPubKey pubkey = secret.GetPubKey();
113114
assert(secret.VerifyPubKey(pubkey));
114115

115116
mapKeyMetadata[pubkey.GetID()] = metadata;
116117
UpdateTimeFirstKey(nCreationTime);
117118

118-
if (!AddKeyPubKey(secret, pubkey))
119+
if (!AddKeyPubKeyWithDB(walletdb, secret, pubkey)) {
119120
throw std::runtime_error(std::string(__func__) + ": AddKey failed");
121+
}
120122
return pubkey;
121123
}
122124

@@ -166,29 +168,48 @@ void CWallet::DeriveNewChildKey(CWalletDB &walletdb, CKeyMetadata& metadata, CKe
166168
throw std::runtime_error(std::string(__func__) + ": Writing HD chain model failed");
167169
}
168170

169-
bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
171+
bool CWallet::AddKeyPubKeyWithDB(CWalletDB &walletdb, const CKey& secret, const CPubKey &pubkey)
170172
{
171173
AssertLockHeld(cs_wallet); // mapKeyMetadata
172-
if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey))
174+
175+
// CCryptoKeyStore has no concept of wallet databases, but calls AddCryptedKey
176+
// which is overridden below. To avoid flushes, the database handle is
177+
// tunneled through to it.
178+
bool needsDB = !pwalletdbEncryption;
179+
if (needsDB) {
180+
pwalletdbEncryption = &walletdb;
181+
}
182+
if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey)) {
183+
if (needsDB) pwalletdbEncryption = NULL;
173184
return false;
185+
}
186+
if (needsDB) pwalletdbEncryption = NULL;
174187

175188
// check if we need to remove from watch-only
176189
CScript script;
177190
script = GetScriptForDestination(pubkey.GetID());
178-
if (HaveWatchOnly(script))
191+
if (HaveWatchOnly(script)) {
179192
RemoveWatchOnly(script);
193+
}
180194
script = GetScriptForRawPubKey(pubkey);
181-
if (HaveWatchOnly(script))
195+
if (HaveWatchOnly(script)) {
182196
RemoveWatchOnly(script);
197+
}
183198

184199
if (!IsCrypted()) {
185-
return CWalletDB(*dbw).WriteKey(pubkey,
200+
return walletdb.WriteKey(pubkey,
186201
secret.GetPrivKey(),
187202
mapKeyMetadata[pubkey.GetID()]);
188203
}
189204
return true;
190205
}
191206

207+
bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
208+
{
209+
CWalletDB walletdb(*dbw);
210+
return CWallet::AddKeyPubKeyWithDB(walletdb, secret, pubkey);
211+
}
212+
192213
bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
193214
const std::vector<unsigned char> &vchCryptedSecret)
194215
{

src/wallet/wallet.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
869869
CPubKey GenerateNewKey(CWalletDB& walletdb, bool internal = false);
870870
//! Adds a key to the store, and saves it to disk.
871871
bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey) override;
872+
bool AddKeyPubKeyWithDB(CWalletDB &walletdb,const CKey& key, const CPubKey &pubkey);
872873
//! Adds a key to the store, without saving it to disk (used by LoadWallet)
873874
bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); }
874875
//! Load metadata (used by LoadWallet)

0 commit comments

Comments
 (0)