Batch writes for importmulti

When writing all of the imported data to the wallet, use a common
WalletBatch object so that batch writes are done and the writes
finish more quickly.

AddKeypoolPubkey is no longer needed so it is also removed
This commit is contained in:
Andrew Chow 2019-04-03 18:57:33 -04:00
parent d6576e349e
commit ccb26cf347
3 changed files with 7 additions and 14 deletions

View file

@ -1261,8 +1261,9 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
// All good, time to import // All good, time to import
pwallet->MarkDirty(); pwallet->MarkDirty();
WalletBatch batch(pwallet->GetDBHandle());
for (const auto& entry : import_data.import_scripts) { for (const auto& entry : import_data.import_scripts) {
if (!pwallet->HaveCScript(CScriptID(entry)) && !pwallet->AddCScript(entry)) { if (!pwallet->HaveCScript(CScriptID(entry)) && !pwallet->AddCScriptWithDB(batch, entry)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding script to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding script to wallet");
} }
} }
@ -1273,13 +1274,13 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
assert(key.VerifyPubKey(pubkey)); assert(key.VerifyPubKey(pubkey));
pwallet->mapKeyMetadata[id].nCreateTime = timestamp; pwallet->mapKeyMetadata[id].nCreateTime = timestamp;
// If the private key is not present in the wallet, insert it. // If the private key is not present in the wallet, insert it.
if (!pwallet->HaveKey(id) && !pwallet->AddKeyPubKey(key, pubkey)) { if (!pwallet->HaveKey(id) && !pwallet->AddKeyPubKeyWithDB(batch, key, pubkey)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
} }
pwallet->UpdateTimeFirstKey(timestamp); pwallet->UpdateTimeFirstKey(timestamp);
} }
for (const auto& entry : import_data.key_origins) { for (const auto& entry : import_data.key_origins) {
pwallet->AddKeyOrigin(entry.second.first, entry.second.second); pwallet->AddKeyOriginWithDB(batch, entry.second.first, entry.second.second);
} }
for (const CKeyID& id : ordered_pubkeys) { for (const CKeyID& id : ordered_pubkeys) {
auto entry = pubkey_map.find(id); auto entry = pubkey_map.find(id);
@ -1288,20 +1289,20 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
} }
const CPubKey& pubkey = entry->second; const CPubKey& pubkey = entry->second;
CPubKey temp; CPubKey temp;
if (!pwallet->GetPubKey(id, temp) && !pwallet->AddWatchOnly(GetScriptForRawPubKey(pubkey), timestamp)) { if (!pwallet->GetPubKey(id, temp) && !pwallet->AddWatchOnlyWithDB(batch, GetScriptForRawPubKey(pubkey), timestamp)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
} }
pwallet->mapKeyMetadata[id].nCreateTime = timestamp; pwallet->mapKeyMetadata[id].nCreateTime = timestamp;
// Add to keypool only works with pubkeys // Add to keypool only works with pubkeys
if (add_keypool) { if (add_keypool) {
pwallet->AddKeypoolPubkey(pubkey, internal); pwallet->AddKeypoolPubkeyWithDB(pubkey, internal, batch);
} }
} }
for (const CScript& script : script_pub_keys) { for (const CScript& script : script_pub_keys) {
if (!have_solving_data || !::IsMine(*pwallet, script)) { // Always call AddWatchOnly for non-solvable watch-only, so that watch timestamp gets updated if (!have_solving_data || !::IsMine(*pwallet, script)) { // Always call AddWatchOnly for non-solvable watch-only, so that watch timestamp gets updated
if (!pwallet->AddWatchOnly(script, timestamp)) { if (!pwallet->AddWatchOnlyWithDB(batch, script, timestamp)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
} }
} }

View file

@ -3372,13 +3372,6 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize)
return true; return true;
} }
void CWallet::AddKeypoolPubkey(const CPubKey& pubkey, const bool internal)
{
WalletBatch batch(*database);
AddKeypoolPubkeyWithDB(pubkey, internal, batch);
NotifyCanGetAddressesChanged();
}
void CWallet::AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch) void CWallet::AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch)
{ {
LOCK(cs_wallet); LOCK(cs_wallet);

View file

@ -994,7 +994,6 @@ public:
bool NewKeyPool(); bool NewKeyPool();
size_t KeypoolCountExternalKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); size_t KeypoolCountExternalKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
bool TopUpKeyPool(unsigned int kpSize = 0); bool TopUpKeyPool(unsigned int kpSize = 0);
void AddKeypoolPubkey(const CPubKey& pubkey, const bool internal);
void AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch); void AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch);
/** /**