Skip to content

Commit 6154a09

Browse files
Empactachow101
authored andcommitted
Move some of ProcessImport into CWallet::Import*
This maintains encapsulation of CWallet::database in the face of batching, e.g. allows making the `WithDB` methods private.
1 parent ccb26cf commit 6154a09

File tree

3 files changed

+101
-54
lines changed

3 files changed

+101
-54
lines changed

src/wallet/rpcdump.cpp

Lines changed: 8 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,56 +1261,17 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
12611261

12621262
// All good, time to import
12631263
pwallet->MarkDirty();
1264-
WalletBatch batch(pwallet->GetDBHandle());
1265-
for (const auto& entry : import_data.import_scripts) {
1266-
if (!pwallet->HaveCScript(CScriptID(entry)) && !pwallet->AddCScriptWithDB(batch, entry)) {
1267-
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding script to wallet");
1268-
}
1269-
}
1270-
for (const auto& entry : privkey_map) {
1271-
const CKey& key = entry.second;
1272-
CPubKey pubkey = key.GetPubKey();
1273-
const CKeyID& id = entry.first;
1274-
assert(key.VerifyPubKey(pubkey));
1275-
pwallet->mapKeyMetadata[id].nCreateTime = timestamp;
1276-
// If the private key is not present in the wallet, insert it.
1277-
if (!pwallet->HaveKey(id) && !pwallet->AddKeyPubKeyWithDB(batch, key, pubkey)) {
1278-
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
1279-
}
1280-
pwallet->UpdateTimeFirstKey(timestamp);
1264+
if (!pwallet->ImportScripts(import_data.import_scripts)) {
1265+
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding script to wallet");
12811266
}
1282-
for (const auto& entry : import_data.key_origins) {
1283-
pwallet->AddKeyOriginWithDB(batch, entry.second.first, entry.second.second);
1267+
if (!pwallet->ImportPrivKeys(privkey_map, timestamp)) {
1268+
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
12841269
}
1285-
for (const CKeyID& id : ordered_pubkeys) {
1286-
auto entry = pubkey_map.find(id);
1287-
if (entry == pubkey_map.end()) {
1288-
continue;
1289-
}
1290-
const CPubKey& pubkey = entry->second;
1291-
CPubKey temp;
1292-
if (!pwallet->GetPubKey(id, temp) && !pwallet->AddWatchOnlyWithDB(batch, GetScriptForRawPubKey(pubkey), timestamp)) {
1293-
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
1294-
}
1295-
pwallet->mapKeyMetadata[id].nCreateTime = timestamp;
1296-
1297-
// Add to keypool only works with pubkeys
1298-
if (add_keypool) {
1299-
pwallet->AddKeypoolPubkeyWithDB(pubkey, internal, batch);
1300-
}
1270+
if (!pwallet->ImportPubKeys(ordered_pubkeys, pubkey_map, import_data.key_origins, add_keypool, internal, timestamp)) {
1271+
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
13011272
}
1302-
1303-
for (const CScript& script : script_pub_keys) {
1304-
if (!have_solving_data || !::IsMine(*pwallet, script)) { // Always call AddWatchOnly for non-solvable watch-only, so that watch timestamp gets updated
1305-
if (!pwallet->AddWatchOnlyWithDB(batch, script, timestamp)) {
1306-
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
1307-
}
1308-
}
1309-
CTxDestination dest;
1310-
ExtractDestination(script, dest);
1311-
if (!internal && IsValidDestination(dest)) {
1312-
pwallet->SetAddressBook(dest, label, "receive");
1313-
}
1273+
if (!pwallet->ImportScriptPubKeys(label, script_pub_keys, have_solving_data, internal, timestamp)) {
1274+
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
13141275
}
13151276

13161277
result.pushKV("success", UniValue(true));

src/wallet/wallet.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1625,6 +1625,80 @@ bool CWallet::DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut>
16251625
return true;
16261626
}
16271627

1628+
bool CWallet::ImportScripts(const std::set<CScript> scripts)
1629+
{
1630+
WalletBatch batch(*database);
1631+
for (const auto& entry : scripts) {
1632+
if (!HaveCScript(CScriptID(entry)) && !AddCScriptWithDB(batch, entry)) {
1633+
return false;
1634+
}
1635+
}
1636+
return true;
1637+
}
1638+
1639+
bool CWallet::ImportPrivKeys(const std::map<CKeyID, CKey>& privkey_map, const int64_t timestamp)
1640+
{
1641+
WalletBatch batch(*database);
1642+
for (const auto& entry : privkey_map) {
1643+
const CKey& key = entry.second;
1644+
CPubKey pubkey = key.GetPubKey();
1645+
const CKeyID& id = entry.first;
1646+
assert(key.VerifyPubKey(pubkey));
1647+
mapKeyMetadata[id].nCreateTime = timestamp;
1648+
// If the private key is not present in the wallet, insert it.
1649+
if (!HaveKey(id) && !AddKeyPubKeyWithDB(batch, key, pubkey)) {
1650+
return false;
1651+
}
1652+
UpdateTimeFirstKey(timestamp);
1653+
}
1654+
return true;
1655+
}
1656+
1657+
bool CWallet::ImportPubKeys(const std::vector<CKeyID>& ordered_pubkeys, const std::map<CKeyID, CPubKey>& pubkey_map, const std::map<CKeyID, std::pair<CPubKey, KeyOriginInfo>>& key_origins, const bool add_keypool, const bool internal, const int64_t timestamp)
1658+
{
1659+
WalletBatch batch(*database);
1660+
for (const auto& entry : key_origins) {
1661+
AddKeyOriginWithDB(batch, entry.second.first, entry.second.second);
1662+
}
1663+
for (const CKeyID& id : ordered_pubkeys) {
1664+
auto entry = pubkey_map.find(id);
1665+
if (entry == pubkey_map.end()) {
1666+
continue;
1667+
}
1668+
const CPubKey& pubkey = entry->second;
1669+
CPubKey temp;
1670+
if (!GetPubKey(id, temp) && !AddWatchOnlyWithDB(batch, GetScriptForRawPubKey(pubkey), timestamp)) {
1671+
return false;
1672+
}
1673+
mapKeyMetadata[id].nCreateTime = timestamp;
1674+
1675+
// Add to keypool only works with pubkeys
1676+
if (add_keypool) {
1677+
AddKeypoolPubkeyWithDB(pubkey, internal, batch);
1678+
NotifyCanGetAddressesChanged();
1679+
}
1680+
}
1681+
return true;
1682+
}
1683+
1684+
bool CWallet::ImportScriptPubKeys(const std::string& label, const std::set<CScript>& script_pub_keys, const bool have_solving_data, const bool internal, const int64_t timestamp)
1685+
{
1686+
WalletBatch batch(*database);
1687+
for (const CScript& script : script_pub_keys) {
1688+
if (!have_solving_data || !::IsMine(*this, script)) { // Always call AddWatchOnly for non-solvable watch-only, so that watch timestamp gets updated
1689+
if (!AddWatchOnlyWithDB(batch, script, timestamp)) {
1690+
return false;
1691+
}
1692+
}
1693+
CTxDestination dest;
1694+
ExtractDestination(script, dest);
1695+
if (!internal && IsValidDestination(dest)) {
1696+
SetAddressBook(dest, label, "receive");
1697+
}
1698+
}
1699+
return true;
1700+
}
1701+
16281702
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, bool use_max_sig)
16291703
{
16301704
std::vector<CTxOut> txouts;

src/wallet/wallet.h

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,20 @@ class CWallet final : public CCryptoKeyStore, private interfaces::Chain::Notific
704704
bool AddWatchOnly(const CScript& dest) override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
705705
bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
706706

707+
/** Add a KeyOriginInfo to the wallet */
708+
bool AddKeyOriginWithDB(WalletBatch& batch, const CPubKey& pubkey, const KeyOriginInfo& info);
709+
710+
//! Adds a key to the store, and saves it to disk.
711+
bool AddKeyPubKeyWithDB(WalletBatch &batch,const CKey& key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
712+
713+
//! Adds a watch-only address to the store, and saves it to disk.
714+
bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest, int64_t create_time) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
715+
716+
void AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch);
717+
718+
//! Adds a script to the store and saves it to disk
719+
bool AddCScriptWithDB(WalletBatch& batch, const CScript& script);
720+
707721
/** Interface for accessing chain state. */
708722
interfaces::Chain* m_chain;
709723

@@ -854,7 +868,6 @@ class CWallet final : public CCryptoKeyStore, private interfaces::Chain::Notific
854868
CPubKey GenerateNewKey(WalletBatch& batch, bool internal = false) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
855869
//! Adds a key to the store, and saves it to disk.
856870
bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey) override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
857-
bool AddKeyPubKeyWithDB(WalletBatch &batch,const CKey& key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
858871
//! Adds a key to the store, without saving it to disk (used by LoadWallet)
859872
bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); }
860873
//! Load metadata (used by LoadWallet)
@@ -871,7 +884,6 @@ class CWallet final : public CCryptoKeyStore, private interfaces::Chain::Notific
871884
//! Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
872885
bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
873886
bool AddCScript(const CScript& redeemScript) override;
874-
bool AddCScriptWithDB(WalletBatch& batch, const CScript& script);
875887
bool LoadCScript(const CScript& redeemScript);
876888

877889
//! Adds a destination data tuple to the store, and saves it to disk
@@ -887,7 +899,6 @@ class CWallet final : public CCryptoKeyStore, private interfaces::Chain::Notific
887899

888900
//! Adds a watch-only address to the store, and saves it to disk.
889901
bool AddWatchOnly(const CScript& dest, int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
890-
bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest, int64_t create_time) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
891902
bool RemoveWatchOnly(const CScript &dest) override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
892903
//! Adds a watch-only address to the store, without saving it to disk (used by LoadWallet)
893904
bool LoadWatchOnly(const CScript &dest);
@@ -975,6 +986,11 @@ class CWallet final : public CCryptoKeyStore, private interfaces::Chain::Notific
975986
bool DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut> &txouts, bool use_max_sig = false) const;
976987
bool DummySignInput(CTxIn &tx_in, const CTxOut &txout, bool use_max_sig = false) const;
977988

989+
bool ImportScripts(const std::set<CScript> scripts) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
990+
bool ImportPrivKeys(const std::map<CKeyID, CKey>& privkey_map, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
991+
bool ImportPubKeys(const std::vector<CKeyID>& ordered_pubkeys, const std::map<CKeyID, CPubKey>& pubkey_map, const std::map<CKeyID, std::pair<CPubKey, KeyOriginInfo>>& key_origins, const bool add_keypool, const bool internal, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
992+
bool ImportScriptPubKeys(const std::string& label, const std::set<CScript>& script_pub_keys, const bool have_solving_data, const bool internal, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
993+
978994
CFeeRate m_pay_tx_fee{DEFAULT_PAY_TX_FEE};
979995
unsigned int m_confirm_target{DEFAULT_TX_CONFIRM_TARGET};
980996
bool m_spend_zero_conf_change{DEFAULT_SPEND_ZEROCONF_CHANGE};
@@ -994,7 +1010,6 @@ class CWallet final : public CCryptoKeyStore, private interfaces::Chain::Notific
9941010
bool NewKeyPool();
9951011
size_t KeypoolCountExternalKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
9961012
bool TopUpKeyPool(unsigned int kpSize = 0);
997-
void AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch);
9981013

9991014
/**
10001015
* Reserves a key from the keypool and sets nIndex to its index
@@ -1211,9 +1226,6 @@ class CWallet final : public CCryptoKeyStore, private interfaces::Chain::Notific
12111226

12121227
/** Implement lookup of key origin information through wallet key metadata. */
12131228
bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override;
1214-
1215-
/** Add a KeyOriginInfo to the wallet */
1216-
bool AddKeyOriginWithDB(WalletBatch& batch, const CPubKey& pubkey, const KeyOriginInfo& info);
12171229
};
12181230

12191231
/**

0 commit comments

Comments
 (0)