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
|
// All good, time to import
|
||||||
pwallet->MarkDirty();
|
pwallet->MarkDirty();
|
||||||
WalletBatch batch(pwallet->GetDBHandle());
|
if (!pwallet->ImportScripts(import_data.import_scripts)) {
|
||||||
for (const auto& entry : import_data.import_scripts) {
|
|
||||||
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");
|
||||||
}
|
}
|
||||||
}
|
if (!pwallet->ImportPrivKeys(privkey_map, timestamp)) {
|
||||||
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)) {
|
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
|
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
|
||||||
}
|
}
|
||||||
pwallet->UpdateTimeFirstKey(timestamp);
|
if (!pwallet->ImportPubKeys(ordered_pubkeys, pubkey_map, import_data.key_origins, add_keypool, internal, 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)) {
|
|
||||||
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;
|
if (!pwallet->ImportScriptPubKeys(label, script_pub_keys, have_solving_data, internal, 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)) {
|
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
|
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));
|
result.pushKV("success", UniValue(true));
|
||||||
} catch (const UniValue& e) {
|
} catch (const UniValue& e) {
|
||||||
|
|
|
@ -1625,6 +1625,80 @@ bool CWallet::DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut>
|
||||||
return true;
|
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)
|
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, bool use_max_sig)
|
||||||
{
|
{
|
||||||
std::vector<CTxOut> txouts;
|
std::vector<CTxOut> txouts;
|
||||||
|
|
|
@ -704,6 +704,20 @@ private:
|
||||||
bool AddWatchOnly(const CScript& dest) override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
bool AddWatchOnly(const CScript& dest) override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||||
bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest) 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. */
|
/** Interface for accessing chain state. */
|
||||||
interfaces::Chain* m_chain;
|
interfaces::Chain* m_chain;
|
||||||
|
|
||||||
|
@ -854,7 +868,6 @@ public:
|
||||||
CPubKey GenerateNewKey(WalletBatch& batch, bool internal = false) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
CPubKey GenerateNewKey(WalletBatch& batch, bool internal = false) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||||
//! Adds a key to the store, and saves it to disk.
|
//! 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 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)
|
//! 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); }
|
bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); }
|
||||||
//! Load metadata (used by LoadWallet)
|
//! 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)
|
//! 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 LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
|
||||||
bool AddCScript(const CScript& redeemScript) override;
|
bool AddCScript(const CScript& redeemScript) override;
|
||||||
bool AddCScriptWithDB(WalletBatch& batch, const CScript& script);
|
|
||||||
bool LoadCScript(const CScript& redeemScript);
|
bool LoadCScript(const CScript& redeemScript);
|
||||||
|
|
||||||
//! Adds a destination data tuple to the store, and saves it to disk
|
//! 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.
|
//! 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 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);
|
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)
|
//! Adds a watch-only address to the store, without saving it to disk (used by LoadWallet)
|
||||||
bool LoadWatchOnly(const CScript &dest);
|
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 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 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};
|
CFeeRate m_pay_tx_fee{DEFAULT_PAY_TX_FEE};
|
||||||
unsigned int m_confirm_target{DEFAULT_TX_CONFIRM_TARGET};
|
unsigned int m_confirm_target{DEFAULT_TX_CONFIRM_TARGET};
|
||||||
bool m_spend_zero_conf_change{DEFAULT_SPEND_ZEROCONF_CHANGE};
|
bool m_spend_zero_conf_change{DEFAULT_SPEND_ZEROCONF_CHANGE};
|
||||||
|
@ -994,7 +1010,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 AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reserves a key from the keypool and sets nIndex to its index
|
* 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. */
|
/** Implement lookup of key origin information through wallet key metadata. */
|
||||||
bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override;
|
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