Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/wallet.h
Show All 13 Lines | |||||
#include <primitives/blockhash.h> | #include <primitives/blockhash.h> | ||||
#include <tinyformat.h> | #include <tinyformat.h> | ||||
#include <ui_interface.h> | #include <ui_interface.h> | ||||
#include <util/strencodings.h> | #include <util/strencodings.h> | ||||
#include <util/system.h> | #include <util/system.h> | ||||
#include <validationinterface.h> | #include <validationinterface.h> | ||||
#include <wallet/coinselection.h> | #include <wallet/coinselection.h> | ||||
#include <wallet/crypter.h> | #include <wallet/crypter.h> | ||||
#include <wallet/ismine.h> | |||||
#include <wallet/rpcwallet.h> | #include <wallet/rpcwallet.h> | ||||
#include <wallet/scriptpubkeyman.h> | |||||
#include <wallet/walletdb.h> | #include <wallet/walletdb.h> | ||||
#include <wallet/walletutil.h> | #include <wallet/walletutil.h> | ||||
#include <algorithm> | #include <algorithm> | ||||
#include <atomic> | #include <atomic> | ||||
#include <cstdint> | #include <cstdint> | ||||
#include <map> | #include <map> | ||||
#include <memory> | #include <memory> | ||||
▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | |||||
* | * | ||||
* If an address is reserved and KeepDestination() is not called, then the | * If an address is reserved and KeepDestination() is not called, then the | ||||
* address will be returned when the ReserveDestination goes out of scope. | * address will be returned when the ReserveDestination goes out of scope. | ||||
*/ | */ | ||||
class ReserveDestination { | class ReserveDestination { | ||||
protected: | protected: | ||||
//! The wallet to reserve from | //! The wallet to reserve from | ||||
CWallet *pwallet; | CWallet *pwallet; | ||||
LegacyScriptPubKeyMan *m_spk_man{nullptr}; | |||||
//! The index of the address's key in the keypool | //! The index of the address's key in the keypool | ||||
int64_t nIndex{-1}; | int64_t nIndex{-1}; | ||||
//! The public key for the address | //! The public key for the address | ||||
CPubKey vchPubKey; | CPubKey vchPubKey; | ||||
//! The destination | //! The destination | ||||
CTxDestination address; | CTxDestination address; | ||||
//! Whether this is from the internal (change output) keypool | //! Whether this is from the internal (change output) keypool | ||||
bool fInternal{false}; | bool fInternal{false}; | ||||
▲ Show 20 Lines • Show All 468 Lines • ▼ Show 20 Lines | CoinSelectionParams(bool use_bnb_, size_t change_output_size_, | ||||
tx_noinputs_size(tx_noinputs_size_) {} | tx_noinputs_size(tx_noinputs_size_) {} | ||||
CoinSelectionParams() {} | CoinSelectionParams() {} | ||||
}; | }; | ||||
// forward declarations for ScanForWalletTransactions/RescanFromTime | // forward declarations for ScanForWalletTransactions/RescanFromTime | ||||
class WalletRescanReserver; | class WalletRescanReserver; | ||||
/** | /** | ||||
* A CWallet is an extension of a keystore, which also maintains a set of | * A CWallet maintains a set of transactions and balances, and provides the | ||||
* transactions and balances, and provides the ability to create new | * ability to create new transactions. | ||||
* transactions. | |||||
*/ | */ | ||||
class CWallet final : public FillableSigningProvider, | class CWallet final : public WalletStorage, | ||||
public interfaces::Chain::Notifications { | public interfaces::Chain::Notifications { | ||||
private: | private: | ||||
CKeyingMaterial vMasterKey GUARDED_BY(cs_KeyStore); | CKeyingMaterial vMasterKey GUARDED_BY(cs_KeyStore); | ||||
//! if fUseCrypto is true, mapKeys must be empty | //! if fUseCrypto is true, mapKeys must be empty | ||||
//! if fUseCrypto is false, vMasterKey must be empty | //! if fUseCrypto is false, vMasterKey must be empty | ||||
std::atomic<bool> fUseCrypto; | std::atomic<bool> fUseCrypto; | ||||
//! keeps track of whether Unlock has run a thorough check before | //! keeps track of whether Unlock has run a thorough check before | ||||
bool fDecryptionThoroughlyChecked; | bool fDecryptionThoroughlyChecked; | ||||
using CryptedKeyMap = | |||||
std::map<CKeyID, std::pair<CPubKey, std::vector<uint8_t>>>; | |||||
using WatchOnlySet = std::set<CScript>; | |||||
using WatchKeyMap = std::map<CKeyID, CPubKey>; | |||||
bool SetCrypted(); | bool SetCrypted(); | ||||
//! will encrypt previously unencrypted keys | |||||
bool EncryptKeys(CKeyingMaterial &vMasterKeyIn); | |||||
bool Unlock(const CKeyingMaterial &vMasterKeyIn, | bool Unlock(const CKeyingMaterial &vMasterKeyIn, | ||||
bool accept_no_keys = false); | bool accept_no_keys = false); | ||||
CryptedKeyMap mapCryptedKeys GUARDED_BY(cs_KeyStore); | |||||
WatchOnlySet setWatchOnly GUARDED_BY(cs_KeyStore); | |||||
WatchKeyMap mapWatchKeys GUARDED_BY(cs_KeyStore); | |||||
bool AddCryptedKeyInner(const CPubKey &vchPubKey, | |||||
const std::vector<uint8_t> &vchCryptedSecret); | |||||
bool AddKeyPubKeyInner(const CKey &key, const CPubKey &pubkey); | |||||
std::atomic<bool> fAbortRescan{false}; | std::atomic<bool> fAbortRescan{false}; | ||||
// controlled by WalletRescanReserver | // controlled by WalletRescanReserver | ||||
std::atomic<bool> fScanningWallet{false}; | std::atomic<bool> fScanningWallet{false}; | ||||
std::atomic<int64_t> m_scanning_start{0}; | std::atomic<int64_t> m_scanning_start{0}; | ||||
std::atomic<double> m_scanning_progress{0}; | std::atomic<double> m_scanning_progress{0}; | ||||
std::mutex mutexScanning; | std::mutex mutexScanning; | ||||
friend class WalletRescanReserver; | friend class WalletRescanReserver; | ||||
WalletBatch *encrypted_batch GUARDED_BY(cs_wallet) = nullptr; | |||||
//! the current wallet version: clients below this version are not able to | //! the current wallet version: clients below this version are not able to | ||||
//! load the wallet | //! load the wallet | ||||
int nWalletVersion GUARDED_BY(cs_wallet) = FEATURE_BASE; | int nWalletVersion GUARDED_BY(cs_wallet) = FEATURE_BASE; | ||||
//! the maximum wallet format version: memory-only variable that specifies | //! the maximum wallet format version: memory-only variable that specifies | ||||
//! to what version this wallet may be upgraded | //! to what version this wallet may be upgraded | ||||
int nWalletMaxVersion GUARDED_BY(cs_wallet) = FEATURE_BASE; | int nWalletMaxVersion GUARDED_BY(cs_wallet) = FEATURE_BASE; | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | private: | ||||
* Should be called with non-zero block_hash and posInBlock if this is for a | * Should be called with non-zero block_hash and posInBlock if this is for a | ||||
* transaction that is included in a block. | * transaction that is included in a block. | ||||
*/ | */ | ||||
void SyncTransaction(const CTransactionRef &tx, CWalletTx::Status status, | void SyncTransaction(const CTransactionRef &tx, CWalletTx::Status status, | ||||
const BlockHash &block_hash, int posInBlock = 0, | const BlockHash &block_hash, int posInBlock = 0, | ||||
bool update_tx = true) | bool update_tx = true) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | ||||
/* the HD chain data model (external chain counters) */ | |||||
CHDChain hdChain; | |||||
/* HD derive new child key (on internal or external chain) */ | |||||
void DeriveNewChildKey(WalletBatch &batch, CKeyMetadata &metadata, | |||||
CKey &secret, bool internal = false) | |||||
EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | |||||
std::set<int64_t> setInternalKeyPool GUARDED_BY(cs_wallet); | |||||
std::set<int64_t> setExternalKeyPool GUARDED_BY(cs_wallet); | |||||
std::set<int64_t> set_pre_split_keypool GUARDED_BY(cs_wallet); | |||||
int64_t m_max_keypool_index GUARDED_BY(cs_wallet) = 0; | |||||
std::map<CKeyID, int64_t> m_pool_key_to_index; | |||||
std::atomic<uint64_t> m_wallet_flags{0}; | std::atomic<uint64_t> m_wallet_flags{0}; | ||||
int64_t nTimeFirstKey GUARDED_BY(cs_wallet) = 0; | |||||
/** | |||||
* Private version of AddWatchOnly method which does not accept a timestamp, | |||||
* and which will reset the wallet's nTimeFirstKey value to 1 if the watch | |||||
* key did not previously have a timestamp associated with it. Because this | |||||
* is an inherited virtual method, it is accessible despite being marked | |||||
* private, but it is marked private anyway to encourage use of the other | |||||
* AddWatchOnly which accepts a timestamp and sets nTimeFirstKey more | |||||
* intelligently for more efficient rescans. | |||||
*/ | |||||
bool AddWatchOnly(const CScript &dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | |||||
bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript &dest) | |||||
EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | |||||
bool AddWatchOnlyInMem(const CScript &dest); | |||||
/** 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); | |||||
bool SetAddressBookWithDB(WalletBatch &batch, const CTxDestination &address, | bool SetAddressBookWithDB(WalletBatch &batch, const CTxDestination &address, | ||||
const std::string &strName, | const std::string &strName, | ||||
const std::string &strPurpose); | const std::string &strPurpose); | ||||
//! Adds a script to the store and saves it to disk | |||||
bool AddCScriptWithDB(WalletBatch &batch, const CScript &script); | |||||
//! Unsets a wallet flag and saves it to disk | //! Unsets a wallet flag and saves it to disk | ||||
void UnsetWalletFlagWithDB(WalletBatch &batch, uint64_t flag); | void UnsetWalletFlagWithDB(WalletBatch &batch, uint64_t flag) override; | ||||
/** Interface for accessing chain state. */ | /** Interface for accessing chain state. */ | ||||
interfaces::Chain *m_chain; | interfaces::Chain *m_chain; | ||||
/** | /** | ||||
* Wallet location which includes wallet name (see WalletLocation). | * Wallet location which includes wallet name (see WalletLocation). | ||||
*/ | */ | ||||
WalletLocation m_location; | WalletLocation m_location; | ||||
/** Internal database handle. */ | /** Internal database handle. */ | ||||
std::unique_ptr<WalletDatabase> database; | std::unique_ptr<WalletDatabase> database; | ||||
/** | /** | ||||
* The following is used to keep track of how far behind the wallet is | * The following is used to keep track of how far behind the wallet is | ||||
* from the chain sync, and to allow clients to block on us being caught up. | * from the chain sync, and to allow clients to block on us being caught up. | ||||
* | * | ||||
* Note that this is *not* how far we've processed, we may need some rescan | * Note that this is *not* how far we've processed, we may need some rescan | ||||
* to have seen all transactions in the chain, but is only used to track | * to have seen all transactions in the chain, but is only used to track | ||||
* live BlockConnected callbacks. | * live BlockConnected callbacks. | ||||
*/ | */ | ||||
BlockHash m_last_block_processed GUARDED_BY(cs_wallet); | BlockHash m_last_block_processed GUARDED_BY(cs_wallet); | ||||
//! Fetches a key from the keypool | |||||
bool GetKeyFromPool(CPubKey &key, bool internal = false); | |||||
public: | public: | ||||
const CChainParams &chainParams; | const CChainParams &chainParams; | ||||
/* | /* | ||||
* Main wallet lock. | * Main wallet lock. | ||||
* This lock protects all the fields added by CWallet. | * This lock protects all the fields added by CWallet. | ||||
*/ | */ | ||||
mutable RecursiveMutex cs_wallet; | mutable RecursiveMutex cs_wallet; | ||||
/** | /** | ||||
* Get database handle used by this wallet. Ideally this function would not | * Get database handle used by this wallet. Ideally this function would not | ||||
* be necessary. | * be necessary. | ||||
*/ | */ | ||||
WalletDatabase &GetDBHandle() { return *database; } | WalletDatabase &GetDBHandle() { return *database; } | ||||
WalletDatabase &GetDatabase() override { return *database; } | |||||
/** | /** | ||||
* Select a set of coins such that nValueRet >= nTargetValue and at least | * Select a set of coins such that nValueRet >= nTargetValue and at least | ||||
* all coins from coinControl are selected; Never select unconfirmed coins | * all coins from coinControl are selected; Never select unconfirmed coins | ||||
* if they are not ours. | * if they are not ours. | ||||
*/ | */ | ||||
bool SelectCoins(const std::vector<COutput> &vAvailableCoins, | bool SelectCoins(const std::vector<COutput> &vAvailableCoins, | ||||
const Amount nTargetValue, | const Amount nTargetValue, | ||||
std::set<CInputCoin> &setCoinsRet, Amount &nValueRet, | std::set<CInputCoin> &setCoinsRet, Amount &nValueRet, | ||||
const CCoinControl &coin_control, | const CCoinControl &coin_control, | ||||
CoinSelectionParams &coin_selection_params, | CoinSelectionParams &coin_selection_params, | ||||
bool &bnb_used) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | bool &bnb_used) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | ||||
const WalletLocation &GetLocation() const { return m_location; } | const WalletLocation &GetLocation() const { return m_location; } | ||||
/** | /** | ||||
* Get a name for this wallet for logging/debugging purposes. | * Get a name for this wallet for logging/debugging purposes. | ||||
*/ | */ | ||||
const std::string &GetName() const { return m_location.GetName(); } | const std::string &GetName() const { return m_location.GetName(); } | ||||
void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool) | |||||
EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | |||||
void MarkPreSplitKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | |||||
// Map from Key ID to key metadata. | |||||
std::map<CKeyID, CKeyMetadata> mapKeyMetadata GUARDED_BY(cs_wallet); | |||||
// Map from Script ID to key metadata (for watch-only keys). | |||||
std::map<CScriptID, CKeyMetadata> m_script_metadata GUARDED_BY(cs_wallet); | |||||
typedef std::map<unsigned int, CMasterKey> MasterKeyMap; | typedef std::map<unsigned int, CMasterKey> MasterKeyMap; | ||||
MasterKeyMap mapMasterKeys; | MasterKeyMap mapMasterKeys; | ||||
unsigned int nMasterKeyMaxID = 0; | unsigned int nMasterKeyMaxID = 0; | ||||
/** Construct wallet with specified name and database implementation. */ | /** Construct wallet with specified name and database implementation. */ | ||||
CWallet(const CChainParams &chainParamsIn, interfaces::Chain *chain, | CWallet(const CChainParams &chainParamsIn, interfaces::Chain *chain, | ||||
const WalletLocation &location, | const WalletLocation &location, | ||||
std::unique_ptr<WalletDatabase> databaseIn) | std::unique_ptr<WalletDatabase> databaseIn) | ||||
: fUseCrypto(false), fDecryptionThoroughlyChecked(false), | : fUseCrypto(false), fDecryptionThoroughlyChecked(false), | ||||
m_chain(chain), m_location(location), database(std::move(databaseIn)), | m_chain(chain), m_location(location), database(std::move(databaseIn)), | ||||
chainParams(chainParamsIn) {} | chainParams(chainParamsIn) {} | ||||
~CWallet() { | ~CWallet() { | ||||
// Should not have slots connected at this point. | // Should not have slots connected at this point. | ||||
assert(NotifyUnload.empty()); | assert(NotifyUnload.empty()); | ||||
delete encrypted_batch; | delete encrypted_batch; | ||||
encrypted_batch = nullptr; | encrypted_batch = nullptr; | ||||
} | } | ||||
bool IsCrypted() const { return fUseCrypto; } | bool IsCrypted() const { return fUseCrypto; } | ||||
bool IsLocked() const; | bool IsLocked() const override; | ||||
bool Lock(); | bool Lock(); | ||||
/** Interface to assert chain access and if successful lock it */ | /** Interface to assert chain access and if successful lock it */ | ||||
std::unique_ptr<interfaces::Chain::Lock> LockChain() { | std::unique_ptr<interfaces::Chain::Lock> LockChain() { | ||||
return m_chain ? m_chain->lock() : nullptr; | return m_chain ? m_chain->lock() : nullptr; | ||||
} | } | ||||
std::map<TxId, CWalletTx> mapWallet GUARDED_BY(cs_wallet); | std::map<TxId, CWalletTx> mapWallet GUARDED_BY(cs_wallet); | ||||
Show All 17 Lines | interfaces::Chain &chain() const { | ||||
assert(m_chain); | assert(m_chain); | ||||
return *m_chain; | return *m_chain; | ||||
} | } | ||||
const CWalletTx *GetWalletTx(const TxId &txid) const; | const CWalletTx *GetWalletTx(const TxId &txid) const; | ||||
//! check whether we are allowed to upgrade (or already support) to the | //! check whether we are allowed to upgrade (or already support) to the | ||||
//! named feature | //! named feature | ||||
bool CanSupportFeature(enum WalletFeature wf) const | bool CanSupportFeature(enum WalletFeature wf) const override | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { | EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { | ||||
AssertLockHeld(cs_wallet); | AssertLockHeld(cs_wallet); | ||||
return nWalletMaxVersion >= wf; | return nWalletMaxVersion >= wf; | ||||
} | } | ||||
/** | /** | ||||
* populate vCoins with vector of available COutputs. | * populate vCoins with vector of available COutputs. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | public: | ||||
bool IsScanning() { return fScanningWallet; } | bool IsScanning() { return fScanningWallet; } | ||||
int64_t ScanningDuration() const { | int64_t ScanningDuration() const { | ||||
return fScanningWallet ? GetTimeMillis() - m_scanning_start : 0; | return fScanningWallet ? GetTimeMillis() - m_scanning_start : 0; | ||||
} | } | ||||
double ScanningProgress() const { | double ScanningProgress() const { | ||||
return fScanningWallet ? double(m_scanning_progress) : 0; | return fScanningWallet ? double(m_scanning_progress) : 0; | ||||
} | } | ||||
/** | |||||
* keystore implementation | |||||
* Generate a new key | |||||
*/ | |||||
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); | |||||
//! Adds a key to the store, without saving it to disk (used by LoadWallet) | |||||
bool LoadKey(const CKey &key, const CPubKey &pubkey) { | |||||
return AddKeyPubKeyInner(key, pubkey); | |||||
} | |||||
//! Load metadata (used by LoadWallet) | |||||
void LoadKeyMetadata(const CKeyID &keyID, const CKeyMetadata &metadata) | |||||
EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | |||||
void LoadScriptMetadata(const CScriptID &script_id, | |||||
const CKeyMetadata &metadata) | |||||
EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | |||||
//! Upgrade stored CKeyMetadata objects to store key origin info as | //! Upgrade stored CKeyMetadata objects to store key origin info as | ||||
//! KeyOriginInfo | //! KeyOriginInfo | ||||
void UpgradeKeyMetadata() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | void UpgradeKeyMetadata() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | ||||
bool LoadMinVersion(int nVersion) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { | bool LoadMinVersion(int nVersion) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { | ||||
AssertLockHeld(cs_wallet); | AssertLockHeld(cs_wallet); | ||||
nWalletVersion = nVersion; | nWalletVersion = nVersion; | ||||
nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); | nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); | ||||
return true; | return true; | ||||
} | } | ||||
void UpdateTimeFirstKey(int64_t nCreateTime) | |||||
EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | |||||
//! Adds an encrypted key to the store, and saves it to disk. | |||||
bool AddCryptedKey(const CPubKey &vchPubKey, | |||||
const std::vector<uint8_t> &vchCryptedSecret); | |||||
//! Adds an encrypted key to the store, without saving it to disk (used by | |||||
//! LoadWallet) | |||||
bool LoadCryptedKey(const CPubKey &vchPubKey, | |||||
const std::vector<uint8_t> &vchCryptedSecret); | |||||
bool GetKey(const CKeyID &address, CKey &keyOut) const override; | |||||
bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override; | |||||
bool HaveKey(const CKeyID &address) const override; | |||||
std::set<CKeyID> GetKeys() const override; | |||||
bool AddCScript(const CScript &redeemScript) override; | |||||
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 | ||||
bool AddDestData(const CTxDestination &dest, const std::string &key, | bool AddDestData(const CTxDestination &dest, const std::string &key, | ||||
const std::string &value) | const std::string &value) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | ||||
//! Erases a destination data tuple in the store and on disk | //! Erases a destination data tuple in the store and on disk | ||||
bool EraseDestData(const CTxDestination &dest, const std::string &key) | bool EraseDestData(const CTxDestination &dest, const std::string &key) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | ||||
//! Adds a destination data tuple to the store, without saving it to disk | //! Adds a destination data tuple to the store, without saving it to disk | ||||
void LoadDestData(const CTxDestination &dest, const std::string &key, | void LoadDestData(const CTxDestination &dest, const std::string &key, | ||||
const std::string &value) | const std::string &value) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | ||||
//! Look up a destination data tuple in the store, return true if found | //! Look up a destination data tuple in the store, return true if found | ||||
//! false otherwise | //! false otherwise | ||||
bool GetDestData(const CTxDestination &dest, const std::string &key, | bool GetDestData(const CTxDestination &dest, const std::string &key, | ||||
std::string *value) const | std::string *value) const | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | ||||
//! Get all destination values matching a prefix. | //! Get all destination values matching a prefix. | ||||
std::vector<std::string> GetDestValues(const std::string &prefix) const | std::vector<std::string> GetDestValues(const std::string &prefix) const | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | ||||
//! 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 RemoveWatchOnly(const CScript &dest) | |||||
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); | |||||
//! Returns whether the watch-only script is in the wallet | |||||
bool HaveWatchOnly(const CScript &dest) const; | |||||
//! Returns whether there are any watch-only things in the wallet | |||||
bool HaveWatchOnly() const; | |||||
//! Fetches a pubkey from mapWatchKeys if it exists there | |||||
bool GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const; | |||||
//! Holds a timestamp at which point the wallet is scheduled (externally) to | //! Holds a timestamp at which point the wallet is scheduled (externally) to | ||||
//! be relocked. Caller must arrange for actual relocking to occur via | //! be relocked. Caller must arrange for actual relocking to occur via | ||||
//! Lock(). | //! Lock(). | ||||
int64_t nRelockTime = 0; | int64_t nRelockTime = 0; | ||||
bool Unlock(const SecureString &strWalletPassphrase, | bool Unlock(const SecureString &strWalletPassphrase, | ||||
bool accept_no_keys = false); | bool accept_no_keys = false); | ||||
bool ChangeWalletPassphrase(const SecureString &strOldWalletPassphrase, | bool ChangeWalletPassphrase(const SecureString &strOldWalletPassphrase, | ||||
▲ Show 20 Lines • Show All 146 Lines • ▼ Show 20 Lines | public: | ||||
OutputType m_default_address_type{DEFAULT_ADDRESS_TYPE}; | OutputType m_default_address_type{DEFAULT_ADDRESS_TYPE}; | ||||
OutputType m_default_change_type{DEFAULT_CHANGE_TYPE}; | OutputType m_default_change_type{DEFAULT_CHANGE_TYPE}; | ||||
/** | /** | ||||
* Absolute maximum transaction fee (in satoshis) used by default for the | * Absolute maximum transaction fee (in satoshis) used by default for the | ||||
* wallet. | * wallet. | ||||
*/ | */ | ||||
Amount m_default_max_tx_fee{DEFAULT_TRANSACTION_MAXFEE}; | Amount m_default_max_tx_fee{DEFAULT_TRANSACTION_MAXFEE}; | ||||
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); | ||||
/** | |||||
* Reserves a key from the keypool and sets nIndex to its index | |||||
* | |||||
* @param[out] nIndex the index of the key in keypool | |||||
* @param[out] keypool the keypool the key was drawn from, which could be | |||||
* the the pre-split pool if present, or the internal or external pool | |||||
* @param fRequestedInternal true if the caller would like the key drawn | |||||
* from the internal keypool, false if external is preferred | |||||
* | |||||
* @return true if succeeded, false if failed due to empty keypool | |||||
* @throws std::runtime_error if keypool read failed, key was invalid, | |||||
* was not found in the wallet, or was misclassified in the internal | |||||
* or external keypool | |||||
*/ | |||||
bool ReserveKeyFromKeyPool(int64_t &nIndex, CKeyPool &keypool, | |||||
bool fRequestedInternal); | |||||
void KeepKey(int64_t nIndex); | |||||
void ReturnKey(int64_t nIndex, bool fInternal, const CPubKey &pubkey); | |||||
int64_t GetOldestKeyPoolTime(); | int64_t GetOldestKeyPoolTime(); | ||||
/** | |||||
* Marks all keys in the keypool up to and including reserve_key as used. | |||||
*/ | |||||
void MarkReserveKeysAsUsed(int64_t keypool_id) | |||||
EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | |||||
const std::map<CKeyID, int64_t> &GetAllReserveKeys() const { | |||||
return m_pool_key_to_index; | |||||
} | |||||
std::set<std::set<CTxDestination>> GetAddressGroupings() | std::set<std::set<CTxDestination>> GetAddressGroupings() | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); | ||||
std::map<CTxDestination, Amount> | std::map<CTxDestination, Amount> | ||||
GetAddressBalances(interfaces::Chain::Lock &locked_chain); | GetAddressBalances(interfaces::Chain::Lock &locked_chain); | ||||
std::set<CTxDestination> GetLabelAddresses(const std::string &label) const; | std::set<CTxDestination> GetLabelAddresses(const std::string &label) const; | ||||
bool GetNewDestination(const OutputType type, const std::string label, | bool GetNewDestination(const OutputType type, const std::string label, | ||||
CTxDestination &dest, std::string &error); | CTxDestination &dest, std::string &error); | ||||
bool GetNewChangeDestination(const OutputType type, CTxDestination &dest, | bool GetNewChangeDestination(const OutputType type, CTxDestination &dest, | ||||
std::string &error); | std::string &error); | ||||
isminetype IsMine(const CTxDestination &dest) const; | |||||
isminetype IsMine(const CScript &script) const; | |||||
isminetype IsMine(const CTxIn &txin) const; | isminetype IsMine(const CTxIn &txin) const; | ||||
/** | /** | ||||
* Returns amount of debit if the input matches the filter, otherwise | * Returns amount of debit if the input matches the filter, otherwise | ||||
* returns 0 | * returns 0 | ||||
*/ | */ | ||||
Amount GetDebit(const CTxIn &txin, const isminefilter &filter) const; | Amount GetDebit(const CTxIn &txin, const isminefilter &filter) const; | ||||
isminetype IsMine(const CTxOut &txout) const; | isminetype IsMine(const CTxOut &txout) const; | ||||
Amount GetCredit(const CTxOut &txout, const isminefilter &filter) const; | Amount GetCredit(const CTxOut &txout, const isminefilter &filter) const; | ||||
Show All 24 Lines | public: | ||||
unsigned int GetKeyPoolSize() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { | unsigned int GetKeyPoolSize() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { | ||||
AssertLockHeld(cs_wallet); | AssertLockHeld(cs_wallet); | ||||
return setInternalKeyPool.size() + setExternalKeyPool.size(); | return setInternalKeyPool.size() + setExternalKeyPool.size(); | ||||
} | } | ||||
//! signify that a particular wallet feature is now used. this may change | //! signify that a particular wallet feature is now used. this may change | ||||
//! nWalletVersion and nWalletMaxVersion if those are lower | //! nWalletVersion and nWalletMaxVersion if those are lower | ||||
void SetMinVersion(enum WalletFeature, WalletBatch *batch_in = nullptr, | void SetMinVersion(enum WalletFeature, WalletBatch *batch_in = nullptr, | ||||
bool fExplicit = false); | bool fExplicit = false) override; | ||||
//! change which version we're allowed to upgrade to (note that this does | //! change which version we're allowed to upgrade to (note that this does | ||||
//! not immediately imply upgrading to that format) | //! not immediately imply upgrading to that format) | ||||
bool SetMaxVersion(int nVersion); | bool SetMaxVersion(int nVersion); | ||||
//! get the current wallet format (the oldest client version guaranteed to | //! get the current wallet format (the oldest client version guaranteed to | ||||
//! understand this wallet) | //! understand this wallet) | ||||
int GetVersion() { | int GetVersion() { | ||||
▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | public: | ||||
* Wallet post-init setup | * Wallet post-init setup | ||||
* Gives the wallet a chance to register repetitive tasks and complete | * Gives the wallet a chance to register repetitive tasks and complete | ||||
* post-init tasks | * post-init tasks | ||||
*/ | */ | ||||
void postInitProcess(); | void postInitProcess(); | ||||
bool BackupWallet(const std::string &strDest); | bool BackupWallet(const std::string &strDest); | ||||
/* Set the HD chain model (chain child index counters) */ | |||||
void SetHDChain(const CHDChain &chain, bool memonly); | |||||
const CHDChain &GetHDChain() const { return hdChain; } | |||||
/* Returns true if HD is enabled */ | /* Returns true if HD is enabled */ | ||||
bool IsHDEnabled() const; | bool IsHDEnabled() const; | ||||
/* Returns true if the wallet can generate new keys */ | |||||
bool CanGenerateKeys(); | |||||
/** | /** | ||||
* Returns true if the wallet can give out new addresses. This means it has | * Returns true if the wallet can give out new addresses. This means it has | ||||
* keys in the keypool or can generate new keys. | * keys in the keypool or can generate new keys. | ||||
*/ | */ | ||||
bool CanGetAddresses(bool internal = false); | bool CanGetAddresses(bool internal = false); | ||||
/* Generates a new HD seed (will not be activated) */ | |||||
CPubKey GenerateNewSeed(); | |||||
/** | |||||
* Derives a new HD seed (will not be activated) | |||||
*/ | |||||
CPubKey DeriveNewSeed(const CKey &key); | |||||
/** | |||||
* Set the current HD seed (will reset the chain child index counters) | |||||
* Sets the seed's version based on the current wallet version (so the | |||||
* caller must ensure the current wallet version is correct before calling | |||||
* this function). | |||||
*/ | |||||
void SetHDSeed(const CPubKey &key); | |||||
/** | /** | ||||
* Blocks until the wallet state is up-to-date to /at least/ the current | * Blocks until the wallet state is up-to-date to /at least/ the current | ||||
* chain at the time this function is entered. | * chain at the time this function is entered. | ||||
* Obviously holding cs_main/cs_wallet when going into this call may cause | * Obviously holding cs_main/cs_wallet when going into this call may cause | ||||
* deadlock | * deadlock | ||||
*/ | */ | ||||
void BlockUntilSyncedToCurrentChain() LOCKS_EXCLUDED(cs_main, cs_wallet); | void BlockUntilSyncedToCurrentChain() LOCKS_EXCLUDED(cs_main, cs_wallet); | ||||
/** | /** | ||||
* Explicitly make the wallet learn the related scripts for outputs to the | |||||
* given key. This is purely to make the wallet file compatible with older | |||||
* software, as FillableSigningProvider automatically does this implicitly | |||||
* for all keys now. | |||||
*/ | |||||
void LearnRelatedScripts(const CPubKey &key, OutputType); | |||||
/** | |||||
* Same as LearnRelatedScripts, but when the OutputType is not known (and | |||||
* could be anything). | |||||
*/ | |||||
void LearnAllRelatedScripts(const CPubKey &key); | |||||
/** | |||||
* Set a single wallet flag. | * Set a single wallet flag. | ||||
*/ | */ | ||||
void SetWalletFlag(uint64_t flags); | void SetWalletFlag(uint64_t flags) override; | ||||
/** | /** | ||||
* Unsets a single wallet flag. | * Unsets a single wallet flag. | ||||
*/ | */ | ||||
void UnsetWalletFlag(uint64_t flag); | void UnsetWalletFlag(uint64_t flag); | ||||
/** | /** | ||||
* Check if a certain wallet flag is set. | * Check if a certain wallet flag is set. | ||||
*/ | */ | ||||
bool IsWalletFlagSet(uint64_t flag) const; | bool IsWalletFlagSet(uint64_t flag) const override; | ||||
/** | /** | ||||
* Overwrite all flags by the given uint64_t. | * Overwrite all flags by the given uint64_t. | ||||
* Returns false if unknown, non-tolerable flags are present. | * Returns false if unknown, non-tolerable flags are present. | ||||
*/ | */ | ||||
bool SetWalletFlags(uint64_t overwriteFlags, bool memOnly); | bool SetWalletFlags(uint64_t overwriteFlags, bool memOnly); | ||||
/** | /** | ||||
* Returns a bracketed wallet name for displaying in logs, will return | * Returns a bracketed wallet name for displaying in logs, will return | ||||
* [default wallet] if the wallet has no name. | * [default wallet] if the wallet has no name. | ||||
*/ | */ | ||||
const std::string GetDisplayName() const { | const std::string GetDisplayName() const override { | ||||
std::string wallet_name = | std::string wallet_name = | ||||
GetName().length() == 0 ? "default wallet" : GetName(); | GetName().length() == 0 ? "default wallet" : GetName(); | ||||
return strprintf("[%s]", wallet_name); | return strprintf("[%s]", wallet_name); | ||||
}; | }; | ||||
/** | /** | ||||
* Prepends the wallet name in logging output to ease debugging in | * Prepends the wallet name in logging output to ease debugging in | ||||
* multi-wallet use cases. | * multi-wallet use cases. | ||||
*/ | */ | ||||
template <typename... Params> | template <typename... Params> | ||||
void WalletLogPrintf(std::string fmt, Params... parameters) const { | void WalletLogPrintf(std::string fmt, Params... parameters) const { | ||||
LogPrintf(("%s " + fmt).c_str(), GetDisplayName(), parameters...); | LogPrintf(("%s " + fmt).c_str(), GetDisplayName(), parameters...); | ||||
}; | }; | ||||
template <typename... Params> | template <typename... Params> | ||||
void WalletLogPrintfToBeContinued(std::string fmt, | void WalletLogPrintfToBeContinued(std::string fmt, | ||||
Params... parameters) const { | Params... parameters) const { | ||||
LogPrintfToBeContinued(("%s " + fmt).c_str(), GetDisplayName(), | LogPrintfToBeContinued(("%s " + fmt).c_str(), GetDisplayName(), | ||||
parameters...); | parameters...); | ||||
}; | }; | ||||
/** | ScriptPubKeyMan *GetScriptPubKeyMan() const; | ||||
* Implement lookup of key origin information through wallet key metadata. | const SigningProvider *GetSigningProvider() const; | ||||
*/ | LegacyScriptPubKeyMan *GetLegacyScriptPubKeyMan() const; | ||||
bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const override; | |||||
// Temporary LegacyScriptPubKeyMan accessors and aliases. | |||||
friend class LegacyScriptPubKeyMan; | |||||
std::unique_ptr<LegacyScriptPubKeyMan> m_spk_man = | |||||
std::make_unique<LegacyScriptPubKeyMan>(*this); | |||||
RecursiveMutex &cs_KeyStore = m_spk_man->cs_KeyStore; | |||||
LegacyScriptPubKeyMan::KeyMap & | |||||
mapKeys GUARDED_BY(cs_KeyStore) = m_spk_man->mapKeys; | |||||
LegacyScriptPubKeyMan::ScriptMap & | |||||
mapScripts GUARDED_BY(cs_KeyStore) = m_spk_man->mapScripts; | |||||
LegacyScriptPubKeyMan::CryptedKeyMap & | |||||
mapCryptedKeys GUARDED_BY(cs_KeyStore) = m_spk_man->mapCryptedKeys; | |||||
LegacyScriptPubKeyMan::WatchOnlySet & | |||||
setWatchOnly GUARDED_BY(cs_KeyStore) = m_spk_man->setWatchOnly; | |||||
LegacyScriptPubKeyMan::WatchKeyMap & | |||||
mapWatchKeys GUARDED_BY(cs_KeyStore) = m_spk_man->mapWatchKeys; | |||||
WalletBatch *& | |||||
encrypted_batch GUARDED_BY(cs_wallet) = m_spk_man->encrypted_batch; | |||||
std::set<int64_t> &setInternalKeyPool GUARDED_BY(cs_wallet) = | |||||
m_spk_man->setInternalKeyPool; | |||||
std::set<int64_t> &setExternalKeyPool GUARDED_BY(cs_wallet) = | |||||
m_spk_man->setExternalKeyPool; | |||||
int64_t &nTimeFirstKey GUARDED_BY(cs_wallet) = m_spk_man->nTimeFirstKey; | |||||
std::map<CKeyID, CKeyMetadata> & | |||||
mapKeyMetadata GUARDED_BY(cs_wallet) = m_spk_man->mapKeyMetadata; | |||||
std::map<CScriptID, CKeyMetadata> & | |||||
m_script_metadata GUARDED_BY(cs_wallet) = m_spk_man->m_script_metadata; | |||||
void MarkPreSplitKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { | |||||
AssertLockHeld(m_spk_man->cs_wallet); | |||||
m_spk_man->MarkPreSplitKeys(); | |||||
} | |||||
void MarkReserveKeysAsUsed(int64_t keypool_id) | |||||
EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { | |||||
AssertLockHeld(m_spk_man->cs_wallet); | |||||
m_spk_man->MarkReserveKeysAsUsed(keypool_id); | |||||
} | |||||
using CryptedKeyMap = LegacyScriptPubKeyMan::CryptedKeyMap; | |||||
}; | }; | ||||
/** | /** | ||||
* Called periodically by the schedule thread. Prompts individual wallets to | * Called periodically by the schedule thread. Prompts individual wallets to | ||||
* resend their transactions. Actual rebroadcast schedule is managed by the | * resend their transactions. Actual rebroadcast schedule is managed by the | ||||
* wallets themselves. | * wallets themselves. | ||||
*/ | */ | ||||
void MaybeResendWalletTxs(); | void MaybeResendWalletTxs(); | ||||
▲ Show 20 Lines • Show All 50 Lines • Show Last 20 Lines |