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.
This commit is contained in:
parent
ccb26cf347
commit
6154a09e01
3 changed files with 101 additions and 54 deletions
|
@ -1261,57 +1261,18 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
|
|||
|
||||
// All good, time to import
|
||||
pwallet->MarkDirty();
|
||||
WalletBatch batch(pwallet->GetDBHandle());
|
||||
for (const auto& entry : import_data.import_scripts) {
|
||||
if (!pwallet->HaveCScript(CScriptID(entry)) && !pwallet->AddCScriptWithDB(batch, entry)) {
|
||||
if (!pwallet->ImportScripts(import_data.import_scripts)) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding script to wallet");
|
||||
}
|
||||
}
|
||||
for (const auto& entry : privkey_map) {
|
||||
const CKey& key = entry.second;
|
||||
CPubKey pubkey = key.GetPubKey();
|
||||
const CKeyID& id = entry.first;
|
||||
assert(key.VerifyPubKey(pubkey));
|
||||
pwallet->mapKeyMetadata[id].nCreateTime = timestamp;
|
||||
// If the private key is not present in the wallet, insert it.
|
||||
if (!pwallet->HaveKey(id) && !pwallet->AddKeyPubKeyWithDB(batch, key, pubkey)) {
|
||||
if (!pwallet->ImportPrivKeys(privkey_map, timestamp)) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
|
||||
}
|
||||
pwallet->UpdateTimeFirstKey(timestamp);
|
||||
}
|
||||
for (const auto& entry : import_data.key_origins) {
|
||||
pwallet->AddKeyOriginWithDB(batch, entry.second.first, entry.second.second);
|
||||
}
|
||||
for (const CKeyID& id : ordered_pubkeys) {
|
||||
auto entry = pubkey_map.find(id);
|
||||
if (entry == pubkey_map.end()) {
|
||||
continue;
|
||||
}
|
||||
const CPubKey& pubkey = entry->second;
|
||||
CPubKey temp;
|
||||
if (!pwallet->GetPubKey(id, temp) && !pwallet->AddWatchOnlyWithDB(batch, GetScriptForRawPubKey(pubkey), timestamp)) {
|
||||
if (!pwallet->ImportPubKeys(ordered_pubkeys, pubkey_map, import_data.key_origins, add_keypool, internal, timestamp)) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
|
||||
}
|
||||
pwallet->mapKeyMetadata[id].nCreateTime = timestamp;
|
||||
|
||||
// Add to keypool only works with pubkeys
|
||||
if (add_keypool) {
|
||||
pwallet->AddKeypoolPubkeyWithDB(pubkey, internal, batch);
|
||||
}
|
||||
}
|
||||
|
||||
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 (!pwallet->AddWatchOnlyWithDB(batch, script, timestamp)) {
|
||||
if (!pwallet->ImportScriptPubKeys(label, script_pub_keys, have_solving_data, internal, timestamp)) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
|
||||
}
|
||||
}
|
||||
CTxDestination dest;
|
||||
ExtractDestination(script, dest);
|
||||
if (!internal && IsValidDestination(dest)) {
|
||||
pwallet->SetAddressBook(dest, label, "receive");
|
||||
}
|
||||
}
|
||||
|
||||
result.pushKV("success", UniValue(true));
|
||||
} catch (const UniValue& e) {
|
||||
|
|
|
@ -1625,6 +1625,80 @@ bool CWallet::DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut>
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CWallet::ImportScripts(const std::set<CScript> scripts)
|
||||
{
|
||||
WalletBatch batch(*database);
|
||||
for (const auto& entry : scripts) {
|
||||
if (!HaveCScript(CScriptID(entry)) && !AddCScriptWithDB(batch, entry)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CWallet::ImportPrivKeys(const std::map<CKeyID, CKey>& privkey_map, const int64_t timestamp)
|
||||
{
|
||||
WalletBatch batch(*database);
|
||||
for (const auto& entry : privkey_map) {
|
||||
const CKey& key = entry.second;
|
||||
CPubKey pubkey = key.GetPubKey();
|
||||
const CKeyID& id = entry.first;
|
||||
assert(key.VerifyPubKey(pubkey));
|
||||
mapKeyMetadata[id].nCreateTime = timestamp;
|
||||
// If the private key is not present in the wallet, insert it.
|
||||
if (!HaveKey(id) && !AddKeyPubKeyWithDB(batch, key, pubkey)) {
|
||||
return false;
|
||||
}
|
||||
UpdateTimeFirstKey(timestamp);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
WalletBatch batch(*database);
|
||||
for (const auto& entry : key_origins) {
|
||||
AddKeyOriginWithDB(batch, entry.second.first, entry.second.second);
|
||||
}
|
||||
for (const CKeyID& id : ordered_pubkeys) {
|
||||
auto entry = pubkey_map.find(id);
|
||||
if (entry == pubkey_map.end()) {
|
||||
continue;
|
||||
}
|
||||
const CPubKey& pubkey = entry->second;
|
||||
CPubKey temp;
|
||||
if (!GetPubKey(id, temp) && !AddWatchOnlyWithDB(batch, GetScriptForRawPubKey(pubkey), timestamp)) {
|
||||
return false;
|
||||
}
|
||||
mapKeyMetadata[id].nCreateTime = timestamp;
|
||||
|
||||
// Add to keypool only works with pubkeys
|
||||
if (add_keypool) {
|
||||
AddKeypoolPubkeyWithDB(pubkey, internal, batch);
|
||||
NotifyCanGetAddressesChanged();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
WalletBatch batch(*database);
|
||||
for (const CScript& script : script_pub_keys) {
|
||||
if (!have_solving_data || !::IsMine(*this, script)) { // Always call AddWatchOnly for non-solvable watch-only, so that watch timestamp gets updated
|
||||
if (!AddWatchOnlyWithDB(batch, script, timestamp)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
CTxDestination dest;
|
||||
ExtractDestination(script, dest);
|
||||
if (!internal && IsValidDestination(dest)) {
|
||||
SetAddressBook(dest, label, "receive");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, bool use_max_sig)
|
||||
{
|
||||
std::vector<CTxOut> txouts;
|
||||
|
|
|
@ -704,6 +704,20 @@ private:
|
|||
bool AddWatchOnly(const CScript& dest) override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
|
||||
/** Add a KeyOriginInfo to the wallet */
|
||||
bool AddKeyOriginWithDB(WalletBatch& batch, const CPubKey& pubkey, const KeyOriginInfo& info);
|
||||
|
||||
//! Adds a key to the store, and saves it to disk.
|
||||
bool AddKeyPubKeyWithDB(WalletBatch &batch,const CKey& key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
|
||||
//! Adds a watch-only address to the store, and saves it to disk.
|
||||
bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest, int64_t create_time) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
|
||||
void AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch);
|
||||
|
||||
//! Adds a script to the store and saves it to disk
|
||||
bool AddCScriptWithDB(WalletBatch& batch, const CScript& script);
|
||||
|
||||
/** Interface for accessing chain state. */
|
||||
interfaces::Chain* m_chain;
|
||||
|
||||
|
@ -854,7 +868,6 @@ public:
|
|||
CPubKey GenerateNewKey(WalletBatch& batch, bool internal = false) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
//! Adds a key to the store, and saves it to disk.
|
||||
bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey) override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
bool AddKeyPubKeyWithDB(WalletBatch &batch,const CKey& key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
//! Adds a key to the store, without saving it to disk (used by LoadWallet)
|
||||
bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); }
|
||||
//! Load metadata (used by LoadWallet)
|
||||
|
@ -871,7 +884,6 @@ public:
|
|||
//! Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
|
||||
bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
|
||||
bool AddCScript(const CScript& redeemScript) override;
|
||||
bool AddCScriptWithDB(WalletBatch& batch, const CScript& script);
|
||||
bool LoadCScript(const CScript& redeemScript);
|
||||
|
||||
//! Adds a destination data tuple to the store, and saves it to disk
|
||||
|
@ -887,7 +899,6 @@ public:
|
|||
|
||||
//! Adds a watch-only address to the store, and saves it to disk.
|
||||
bool AddWatchOnly(const CScript& dest, int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest, int64_t create_time) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
bool RemoveWatchOnly(const CScript &dest) override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
//! Adds a watch-only address to the store, without saving it to disk (used by LoadWallet)
|
||||
bool LoadWatchOnly(const CScript &dest);
|
||||
|
@ -975,6 +986,11 @@ public:
|
|||
bool DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut> &txouts, bool use_max_sig = false) const;
|
||||
bool DummySignInput(CTxIn &tx_in, const CTxOut &txout, bool use_max_sig = false) const;
|
||||
|
||||
bool ImportScripts(const std::set<CScript> scripts) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
bool ImportPrivKeys(const std::map<CKeyID, CKey>& privkey_map, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
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);
|
||||
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);
|
||||
|
||||
CFeeRate m_pay_tx_fee{DEFAULT_PAY_TX_FEE};
|
||||
unsigned int m_confirm_target{DEFAULT_TX_CONFIRM_TARGET};
|
||||
bool m_spend_zero_conf_change{DEFAULT_SPEND_ZEROCONF_CHANGE};
|
||||
|
@ -994,7 +1010,6 @@ public:
|
|||
bool NewKeyPool();
|
||||
size_t KeypoolCountExternalKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
bool TopUpKeyPool(unsigned int kpSize = 0);
|
||||
void AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch);
|
||||
|
||||
/**
|
||||
* Reserves a key from the keypool and sets nIndex to its index
|
||||
|
@ -1211,9 +1226,6 @@ public:
|
|||
|
||||
/** Implement lookup of key origin information through wallet key metadata. */
|
||||
bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override;
|
||||
|
||||
/** Add a KeyOriginInfo to the wallet */
|
||||
bool AddKeyOriginWithDB(WalletBatch& batch, const CPubKey& pubkey, const KeyOriginInfo& info);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue