Skip to content

Commit c5d9eec

Browse files
committed
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 dd5b0aa commit c5d9eec

File tree

3 files changed

+104
-69
lines changed

3 files changed

+104
-69
lines changed

src/wallet/rpcdump.cpp

Lines changed: 8 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,72 +1261,17 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
12611261
for (const auto& entry : import_data.import_scripts) {
12621262
if (!pwallet->HaveCScript(CScriptID(entry)) && !pwallet->AddCScript(entry)) {
12631263
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding script to wallet");
1264-
}
1265-
}
1266-
std::unique_ptr<WalletBatch> batch = MakeUnique<WalletBatch>(pwallet->GetDBHandle());
1267-
size_t cnt = 0;
1268-
for (const auto& entry : privkey_map) {
1269-
const CKey& key = entry.second;
1270-
CPubKey pubkey = key.GetPubKey();
1271-
const CKeyID& id = entry.first;
1272-
assert(key.VerifyPubKey(pubkey));
1273-
pwallet->mapKeyMetadata[id].nCreateTime = timestamp;
1274-
// If the private key is not present in the wallet, insert it.
1275-
if (!pwallet->HaveKey(id) && !pwallet->AddKeyPubKeyWithDB(*batch, key, pubkey)) {
1276-
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
1277-
}
1278-
pwallet->UpdateTimeFirstKey(timestamp);
1279-
if (++cnt % 1000 == 0) {
1280-
batch.reset(new WalletBatch(pwallet->GetDBHandle()));
1281-
}
1282-
}
1283-
for (const CKeyID& id : ordered_pubkeys) {
1284-
auto entry = pubkey_map.find(id);
1285-
if (entry == pubkey_map.end()) {
1286-
continue;
1287-
}
1288-
const CPubKey& pubkey = entry->second;
1289-
CPubKey temp;
1290-
if (!pwallet->GetPubKey(id, temp) && !pwallet->AddWatchOnlyWithDB(*batch, GetScriptForRawPubKey(pubkey), timestamp)) {
1291-
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
1292-
}
1293-
if (++cnt % 1000 == 0) {
1294-
batch.reset(new WalletBatch(pwallet->GetDBHandle()));
1295-
}
1296-
const auto& key_orig_it = import_data.key_origins.find(id);
1297-
if (key_orig_it != import_data.key_origins.end()) {
1298-
pwallet->AddKeyOriginWithDB(*batch, pubkey, key_orig_it->second);
1299-
if (++cnt % 1000 == 0) {
1300-
batch.reset(new WalletBatch(pwallet->GetDBHandle()));
1301-
}
1302-
}
1303-
pwallet->mapKeyMetadata[id].nCreateTime = timestamp;
1304-
1305-
// Add to keypool only works with pubkeys
1306-
if (add_keypool) {
1307-
pwallet->AddKeypoolPubkeyWithDB(pubkey, internal, *batch);
1308-
if (++cnt % 1000 == 0) {
1309-
batch.reset(new WalletBatch(pwallet->GetDBHandle()));
1310-
}
13111264
}
13121265
}
1313-
1314-
for (const CScript& script : script_pub_keys) {
1315-
if (!have_solving_data || !::IsMine(*pwallet, script)) { // Always call AddWatchOnly for non-solvable watch-only, so that watch timestamp gets updated
1316-
if (!pwallet->AddWatchOnlyWithDB(*batch, script, timestamp)) {
1317-
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
1318-
}
1319-
if (++cnt % 1000 == 0) {
1320-
batch.reset(new WalletBatch(pwallet->GetDBHandle()));
1321-
}
1322-
}
1323-
CTxDestination dest;
1324-
ExtractDestination(script, dest);
1325-
if (!internal && IsValidDestination(dest)) {
1326-
pwallet->SetAddressBook(dest, label, "receive");
1327-
}
1266+
if (!pwallet->ImportPrivKeys(privkey_map, timestamp)) {
1267+
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
1268+
}
1269+
if (!pwallet->ImportPubKeys(ordered_pubkeys, pubkey_map, import_data.key_origins, add_keypool, internal, timestamp)) {
1270+
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
1271+
}
1272+
if (!pwallet->ImportScriptPubKeys(label, script_pub_keys, have_solving_data, internal, timestamp)) {
1273+
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
13281274
}
1329-
batch.reset();
13301275

13311276
result.pushKV("success", UniValue(true));
13321277
} catch (const UniValue& e) {

src/wallet/wallet.cpp

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,6 +1618,87 @@ bool CWallet::DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut>
16181618
return true;
16191619
}
16201620

1621+
bool CWallet::ImportPrivKeys(const std::map<CKeyID, CKey>& privkey_map, const int64_t timestamp)
1622+
{
1623+
std::unique_ptr<WalletBatch> batch = MakeUnique<WalletBatch>(*database);
1624+
size_t cnt = 0;
1625+
for (const auto& entry : privkey_map) {
1626+
const CKey& key = entry.second;
1627+
CPubKey pubkey = key.GetPubKey();
1628+
const CKeyID& id = entry.first;
1629+
assert(key.VerifyPubKey(pubkey));
1630+
mapKeyMetadata[id].nCreateTime = timestamp;
1631+
// If the private key is not present in the wallet, insert it.
1632+
if (!HaveKey(id) && !AddKeyPubKeyWithDB(*batch, key, pubkey)) {
1633+
return false;
1634+
}
1635+
UpdateTimeFirstKey(timestamp);
1636+
if (++cnt % 1000 == 0) {
1637+
batch.reset(new WalletBatch(*database));
1638+
}
1639+
}
1640+
return true;
1641+
}
1642+
1643+
bool CWallet::ImportPubKeys(const std::vector<CKeyID>& ordered_pubkeys, const std::map<CKeyID, CPubKey>& pubkey_map, const std::map<CKeyID, KeyOriginInfo>& key_origins, const bool add_keypool, const bool internal, const int64_t timestamp)
1644+
{
1645+
std::unique_ptr<WalletBatch> batch = MakeUnique<WalletBatch>(*database);
1646+
size_t cnt = 0;
1647+
for (const CKeyID& id : ordered_pubkeys) {
1648+
auto entry = pubkey_map.find(id);
1649+
if (entry == pubkey_map.end()) {
1650+
continue;
1651+
}
1652+
const CPubKey& pubkey = entry->second;
1653+
CPubKey temp;
1654+
if (!GetPubKey(id, temp) && !AddWatchOnlyWithDB(*batch, GetScriptForRawPubKey(pubkey), timestamp)) {
1655+
return false;
1656+
}
1657+
if (++cnt % 1000 == 0) {
1658+
batch.reset(new WalletBatch(*database));
1659+
}
1660+
const auto& key_orig_it = key_origins.find(id);
1661+
if (key_orig_it != key_origins.end()) {
1662+
AddKeyOriginWithDB(*batch, pubkey, key_orig_it->second);
1663+
if (++cnt % 1000 == 0) {
1664+
batch.reset(new WalletBatch(*database));
1665+
}
1666+
}
1667+
mapKeyMetadata[id].nCreateTime = timestamp;
1668+
1669+
// Add to keypool only works with pubkeys
1670+
if (add_keypool) {
1671+
AddKeypoolPubkeyWithDB(pubkey, internal, *batch);
1672+
if (++cnt % 1000 == 0) {
1673+
batch.reset(new WalletBatch(*database));
1674+
}
1675+
}
1676+
}
1677+
return true;
1678+
}
1679+
1680+
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)
1681+
{
1682+
std::unique_ptr<WalletBatch> batch = MakeUnique<WalletBatch>(*database);
1683+
size_t cnt = 0;
1684+
for (const CScript& script : script_pub_keys) {
1685+
if (!have_solving_data || !::IsMine(*this, script)) { // Always call AddWatchOnly for non-solvable watch-only, so that watch timestamp gets updated
1686+
if (!AddWatchOnlyWithDB(*batch, script, timestamp)) {
1687+
return false;
1688+
}
1689+
if (++cnt % 1000 == 0) {
1690+
batch.reset(new WalletBatch(*database));
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+
16211702
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, bool use_max_sig)
16221703
{
16231704
std::vector<CTxOut> txouts;

src/wallet/wallet.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,17 @@ class CWallet final : public CCryptoKeyStore, private interfaces::Chain::Notific
722722
bool AddWatchOnly(const CScript& dest) override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
723723
bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
724724

725+
/** Add a KeyOriginInfo to the wallet */
726+
bool AddKeyOriginWithDB(WalletBatch& batch, const CPubKey& pubkey, const KeyOriginInfo& info);
727+
728+
//! Adds a key to the store, and saves it to disk.
729+
bool AddKeyPubKeyWithDB(WalletBatch &batch,const CKey& key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
730+
731+
//! Adds a watch-only address to the store, and saves it to disk.
732+
bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest, int64_t create_time) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
733+
734+
void AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch);
735+
725736
/** Interface for accessing chain state. */
726737
interfaces::Chain& m_chain;
727738

@@ -866,7 +877,6 @@ class CWallet final : public CCryptoKeyStore, private interfaces::Chain::Notific
866877
CPubKey GenerateNewKey(WalletBatch& batch, bool internal = false) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
867878
//! Adds a key to the store, and saves it to disk.
868879
bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey) override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
869-
bool AddKeyPubKeyWithDB(WalletBatch &batch,const CKey& key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
870880
//! Adds a key to the store, without saving it to disk (used by LoadWallet)
871881
bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); }
872882
//! Load metadata (used by LoadWallet)
@@ -898,7 +908,6 @@ class CWallet final : public CCryptoKeyStore, private interfaces::Chain::Notific
898908

899909
//! Adds a watch-only address to the store, and saves it to disk.
900910
bool AddWatchOnly(const CScript& dest, int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
901-
bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest, int64_t create_time) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
902911
bool RemoveWatchOnly(const CScript &dest) override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
903912
//! Adds a watch-only address to the store, without saving it to disk (used by LoadWallet)
904913
bool LoadWatchOnly(const CScript &dest);
@@ -982,6 +991,10 @@ class CWallet final : public CCryptoKeyStore, private interfaces::Chain::Notific
982991
bool DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut> &txouts, bool use_max_sig = false) const;
983992
bool DummySignInput(CTxIn &tx_in, const CTxOut &txout, bool use_max_sig = false) const;
984993

994+
bool ImportPrivKeys(const std::map<CKeyID, CKey>& privkey_map, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
995+
bool ImportPubKeys(const std::vector<CKeyID>& ordered_pubkeys, const std::map<CKeyID, CPubKey>& pubkey_map, const std::map<CKeyID, KeyOriginInfo>& key_origins, const bool add_keypool, const bool internal, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
996+
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);
997+
985998
CFeeRate m_pay_tx_fee{DEFAULT_PAY_TX_FEE};
986999
unsigned int m_confirm_target{DEFAULT_TX_CONFIRM_TARGET};
9871000
bool m_spend_zero_conf_change{DEFAULT_SPEND_ZEROCONF_CHANGE};
@@ -1002,7 +1015,6 @@ class CWallet final : public CCryptoKeyStore, private interfaces::Chain::Notific
10021015
size_t KeypoolCountExternalKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
10031016
bool TopUpKeyPool(unsigned int kpSize = 0);
10041017
void AddKeypoolPubkey(const CPubKey& pubkey, const bool internal);
1005-
void AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch);
10061018

10071019
/**
10081020
* Reserves a key from the keypool and sets nIndex to its index
@@ -1220,9 +1232,6 @@ class CWallet final : public CCryptoKeyStore, private interfaces::Chain::Notific
12201232
/** Implement lookup of key origin information through wallet key metadata. */
12211233
bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override;
12221234

1223-
/** Add a KeyOriginInfo to the wallet */
1224-
bool AddKeyOriginWithDB(WalletBatch& batch, const CPubKey& pubkey, const KeyOriginInfo& info);
1225-
12261235
friend struct WalletTestingSetup;
12271236
};
12281237

0 commit comments

Comments
 (0)