aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/wallet.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet/wallet.h')
-rw-r--r--src/wallet/wallet.h156
1 files changed, 93 insertions, 63 deletions
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index b85f374a06..1e23b44eae 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -32,25 +32,19 @@
#include <utility>
#include <vector>
-typedef CWallet* CWalletRef;
-extern std::vector<CWalletRef> vpwallets;
-
-/**
- * Settings
- */
-extern CFeeRate payTxFee;
-extern unsigned int nTxConfirmTarget;
-extern bool bSpendZeroConfChange;
-extern bool fWalletRbf;
-extern bool g_wallet_allow_fallback_fee;
+bool AddWallet(CWallet* wallet);
+bool RemoveWallet(CWallet* wallet);
+bool HasWallets();
+std::vector<CWallet*> GetWallets();
+CWallet* GetWallet(const std::string& name);
//! Default for -keypool
static const unsigned int DEFAULT_KEYPOOL_SIZE = 1000;
//! -paytxfee default
-static const CAmount DEFAULT_TRANSACTION_FEE = 0;
+constexpr CAmount DEFAULT_PAY_TX_FEE = 0;
//! -fallbackfee default
static const CAmount DEFAULT_FALLBACK_FEE = 20000;
-//! -m_discard_rate default
+//! -discardfee default
static const CAmount DEFAULT_DISCARD_FEE = 10000;
//! -mintxfee default
static const CAmount DEFAULT_TRANSACTION_MINFEE = 1000;
@@ -95,19 +89,30 @@ enum WalletFeature
FEATURE_NO_DEFAULT_KEY = 159900, // Wallet without a default key written
- FEATURE_LATEST = FEATURE_COMPRPUBKEY // HD is optional, use FEATURE_COMPRPUBKEY as latest version
+ FEATURE_PRE_SPLIT_KEYPOOL = 169900, // Upgraded to HD SPLIT and can have a pre-split keypool
+
+ FEATURE_LATEST = FEATURE_PRE_SPLIT_KEYPOOL
};
enum class OutputType {
- NONE,
LEGACY,
P2SH_SEGWIT,
BECH32,
+
+ /**
+ * Special output type for change outputs only. Automatically choose type
+ * based on address type setting and the types other of non-change outputs
+ * (see -changetype option documentation and implementation in
+ * CWallet::TransactionChangeType for details).
+ */
+ CHANGE_AUTO,
};
//! Default for -addresstype
constexpr OutputType DEFAULT_ADDRESS_TYPE{OutputType::P2SH_SEGWIT};
+//! Default for -changetype
+constexpr OutputType DEFAULT_CHANGE_TYPE{OutputType::CHANGE_AUTO};
/** A key pool entry */
class CKeyPool
@@ -116,6 +121,7 @@ public:
int64_t nTime;
CPubKey vchPubKey;
bool fInternal; // for change outputs
+ bool m_pre_split; // For keys generated before keypool split upgrade
CKeyPool();
CKeyPool(const CPubKey& vchPubKeyIn, bool internalIn);
@@ -138,9 +144,18 @@ public:
(this will be the case for any wallet before the HD chain split version) */
fInternal = false;
}
+ try {
+ READWRITE(m_pre_split);
+ }
+ catch (std::ios_base::failure&) {
+ /* flag as postsplit address if we can't read the m_pre_split boolean
+ (this will be the case for any wallet that upgrades to HD chain split)*/
+ m_pre_split = false;
+ }
}
else {
READWRITE(fInternal);
+ READWRITE(m_pre_split);
}
}
};
@@ -268,7 +283,7 @@ public:
//Get the marginal bytes of spending the specified output
int CalculateMaximumSignedInputSize(const CTxOut& txout, const CWallet* pwallet);
-/**
+/**
* A transaction with a bunch of additional info that only the owner cares about.
* It includes any unrecorded transactions needed to link it back to the block chain.
*/
@@ -653,7 +668,7 @@ struct CoinEligibilityFilter
};
class WalletRescanReserver; //forward declarations for ScanForWalletTransactions/RescanFromTime
-/**
+/**
* A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,
* and provides the ability to create new transactions.
*/
@@ -695,16 +710,17 @@ private:
/* Used by TransactionAddedToMemorypool/BlockConnected/Disconnected.
* Should be called with pindexBlock and posInBlock if this is for a transaction that is included in a block. */
- void SyncTransaction(const CTransactionRef& tx, const CBlockIndex *pindex = nullptr, int posInBlock = 0);
+ void SyncTransaction(const CTransactionRef& tx, const CBlockIndex *pindex = nullptr, int posInBlock = 0) 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);
+ void DeriveNewChildKey(WalletBatch &batch, CKeyMetadata& metadata, CKey& secret, bool internal = false) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
std::set<int64_t> setInternalKeyPool;
std::set<int64_t> setExternalKeyPool;
+ std::set<int64_t> set_pre_split_keypool;
int64_t m_max_keypool_index = 0;
std::map<CKeyID, int64_t> m_pool_key_to_index;
@@ -719,7 +735,7 @@ private:
* of the other AddWatchOnly which accepts a timestamp and sets
* nTimeFirstKey more intelligently for more efficient rescans.
*/
- bool AddWatchOnly(const CScript& dest) override;
+ bool AddWatchOnly(const CScript& dest) override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
/**
* Wallet filename from wallet=<path> command line or config option.
@@ -770,7 +786,8 @@ public:
*/
const std::string& GetName() const { return m_name; }
- void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool);
+ void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ void MarkPreSplitKeys();
// Map from Key ID to key metadata.
std::map<CKeyID, CKeyMetadata> mapKeyMetadata;
@@ -811,12 +828,12 @@ public:
const CWalletTx* GetWalletTx(const uint256& hash) const;
//! check whether we are allowed to upgrade (or already support) to the named feature
- bool CanSupportFeature(enum WalletFeature wf) const { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; }
+ bool CanSupportFeature(enum WalletFeature wf) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; }
/**
* populate vCoins with vector of available COutputs.
*/
- void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlySafe=true, const CCoinControl *coinControl = nullptr, const CAmount& nMinimumAmount = 1, const CAmount& nMaximumAmount = MAX_MONEY, const CAmount& nMinimumSumAmount = MAX_MONEY, const uint64_t nMaximumCount = 0, const int nMinDepth = 0, const int nMaxDepth = 9999999) const;
+ void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlySafe=true, const CCoinControl *coinControl = nullptr, const CAmount& nMinimumAmount = 1, const CAmount& nMaximumAmount = MAX_MONEY, const CAmount& nMinimumSumAmount = MAX_MONEY, const uint64_t nMaximumCount = 0, const int nMinDepth = 0, const int nMaxDepth = 9999999) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
/**
* Return list of available coins and locked coins grouped by non-change output address.
@@ -839,11 +856,11 @@ public:
bool IsSpent(const uint256& hash, unsigned int n) const;
- bool IsLockedCoin(uint256 hash, unsigned int n) const;
- void LockCoin(const COutPoint& output);
- void UnlockCoin(const COutPoint& output);
- void UnlockAllCoins();
- void ListLockedCoins(std::vector<COutPoint>& vOutpts) const;
+ bool IsLockedCoin(uint256 hash, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ void LockCoin(const COutPoint& output) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ void UnlockCoin(const COutPoint& output) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ void UnlockAllCoins() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ void ListLockedCoins(std::vector<COutPoint>& vOutpts) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
/*
* Rescan abort properties
@@ -856,18 +873,18 @@ public:
* keystore implementation
* Generate a new key
*/
- CPubKey GenerateNewKey(WalletBatch& batch, bool internal = false);
+ 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;
- bool AddKeyPubKeyWithDB(WalletBatch &batch,const CKey& key, const CPubKey &pubkey);
+ 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)
- bool LoadKeyMetadata(const CKeyID& keyID, const CKeyMetadata &metadata);
- bool LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata &metadata);
+ bool LoadKeyMetadata(const CKeyID& keyID, const CKeyMetadata &metadata) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ bool LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata &metadata) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
- bool LoadMinVersion(int nVersion) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; }
- void UpdateTimeFirstKey(int64_t nCreateTime);
+ bool LoadMinVersion(int nVersion) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); 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<unsigned char> &vchCryptedSecret) override;
@@ -888,8 +905,8 @@ public:
std::vector<std::string> GetDestValues(const std::string& prefix) const;
//! Adds a watch-only address to the store, and saves it to disk.
- bool AddWatchOnly(const CScript& dest, int64_t nCreateTime);
- bool RemoveWatchOnly(const CScript &dest) override;
+ bool AddWatchOnly(const CScript& dest, int64_t nCreateTime) 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);
@@ -900,16 +917,16 @@ public:
bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase);
bool EncryptWallet(const SecureString& strWalletPassphrase);
- void GetKeyBirthTimes(std::map<CTxDestination, int64_t> &mapKeyBirth) const;
+ void GetKeyBirthTimes(std::map<CTxDestination, int64_t> &mapKeyBirth) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
unsigned int ComputeTimeSmart(const CWalletTx& wtx) const;
- /**
+ /**
* Increment the next transaction order id
* @return next transaction order id
*/
- int64_t IncOrderPosNext(WalletBatch *batch = nullptr);
+ int64_t IncOrderPosNext(WalletBatch *batch = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
DBErrors ReorderTransactions();
- bool AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment = "");
+ bool AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment = "") EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
bool GetLabelDestination(CTxDestination &dest, const std::string& label, bool bForceNew = false);
void MarkDirty();
@@ -918,7 +935,7 @@ public:
void TransactionAddedToMempool(const CTransactionRef& tx) override;
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex *pindex, const std::vector<CTransactionRef>& vtxConflicted) override;
void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock) override;
- bool AddToWalletIfInvolvingMe(const CTransactionRef& tx, const CBlockIndex* pIndex, int posInBlock, bool fUpdate);
+ bool AddToWalletIfInvolvingMe(const CTransactionRef& tx, const CBlockIndex* pIndex, int posInBlock, bool fUpdate) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
int64_t RescanFromTime(int64_t startTime, const WalletRescanReserver& reserver, bool update);
CBlockIndex* ScanForWalletTransactions(CBlockIndex* pindexStart, CBlockIndex* pindexStop, const WalletRescanReserver& reserver, bool fUpdate = false);
void TransactionRemovedFromMempool(const CTransactionRef &ptx) override;
@@ -942,7 +959,7 @@ public:
* calling CreateTransaction();
*/
bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool lockUnspents, const std::set<int>& setSubtractFeeFromOutputs, CCoinControl);
- bool SignTransaction(CMutableTransaction& tx);
+ bool SignTransaction(CMutableTransaction& tx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
/**
* Create a new transaction paying the recipients with a set of coins
@@ -965,14 +982,24 @@ public:
bool DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut> &txouts) const;
bool DummySignInput(CTxIn &tx_in, const CTxOut &txout) const;
- static CFeeRate minTxFee;
- static CFeeRate fallbackFee;
- static CFeeRate m_discard_rate;
+ 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};
+ bool m_signal_rbf{DEFAULT_WALLET_RBF};
+ bool m_allow_fallback_fee{true}; //<! will be defined via chainparams
+ CFeeRate m_min_fee{DEFAULT_TRANSACTION_MINFEE}; //!< Override with -mintxfee
+ /**
+ * If fee estimation does not have enough data to provide estimates, use this fee instead.
+ * Has no effect if not using fee estimation
+ * Override with -fallbackfee
+ */
+ CFeeRate m_fallback_fee{DEFAULT_FALLBACK_FEE};
+ CFeeRate m_discard_rate{DEFAULT_DISCARD_FEE};
OutputType m_default_address_type{DEFAULT_ADDRESS_TYPE};
- OutputType m_default_change_type{OutputType::NONE}; // Default to OutputType::NONE if not set by -changetype
+ OutputType m_default_change_type{DEFAULT_CHANGE_TYPE};
bool NewKeyPool();
- size_t KeypoolCountExternalKeys();
+ size_t KeypoolCountExternalKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
bool TopUpKeyPool(unsigned int kpSize = 0);
void ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRequestedInternal);
void KeepKey(int64_t nIndex);
@@ -982,10 +1009,10 @@ public:
/**
* Marks all keys in the keypool up to and including reserve_key as used.
*/
- void MarkReserveKeysAsUsed(int64_t keypool_id);
+ 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);
std::map<CTxDestination, CAmount> GetAddressBalances();
std::set<CTxDestination> GetLabelAddresses(const std::string& label) const;
@@ -1009,11 +1036,11 @@ public:
bool IsAllFromMe(const CTransaction& tx, const isminefilter& filter) const;
CAmount GetCredit(const CTransaction& tx, const isminefilter& filter) const;
CAmount GetChange(const CTransaction& tx) const;
- void SetBestChain(const CBlockLocator& loc) override;
+ void ChainStateFlushed(const CBlockLocator& loc) override;
DBErrors LoadWallet(bool& fFirstRunRet);
DBErrors ZapWalletTx(std::vector<CWalletTx>& vWtx);
- DBErrors ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut);
+ DBErrors ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
bool SetAddressBook(const CTxDestination& address, const std::string& strName, const std::string& purpose);
@@ -1032,8 +1059,8 @@ public:
}
void GetScriptForMining(std::shared_ptr<CReserveScript> &script);
-
- unsigned int GetKeyPoolSize()
+
+ unsigned int GetKeyPoolSize() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
{
AssertLockHeld(cs_wallet); // set{Ex,In}ternalKeyPool
return setInternalKeyPool.size() + setExternalKeyPool.size();
@@ -1052,12 +1079,12 @@ public:
std::set<uint256> GetConflicts(const uint256& txid) const;
//! Check if a given transaction has any of its outputs spent by another transaction in the wallet
- bool HasWalletSpend(const uint256& txid) const;
+ bool HasWalletSpend(const uint256& txid) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
//! Flush wallet (bitdb flush)
void Flush(bool shutdown=false);
- /**
+ /**
* Address book entry changed.
* @note called with lock cs_wallet held.
*/
@@ -1066,7 +1093,7 @@ public:
const std::string &purpose,
ChangeType status)> NotifyAddressBookChanged;
- /**
+ /**
* Wallet transaction added, removed or updated.
* @note called with lock cs_wallet held.
*/
@@ -1113,7 +1140,10 @@ public:
/* Generates a new HD master key (will not be activated) */
CPubKey GenerateNewHDMasterKey();
-
+
+ /* Derives a new HD master key (will not be activated) */
+ CPubKey DeriveNewMasterHDKey(const CKey& key);
+
/* Set the current HD master key (will reset the chain child index counters)
Sets the master key's version based on the current wallet version (so the
caller must ensure the current wallet version is correct before calling
@@ -1126,7 +1156,7 @@ public:
* Obviously holding cs_main/cs_wallet when going into this call may cause
* deadlock
*/
- void BlockUntilSyncedToCurrentChain();
+ void BlockUntilSyncedToCurrentChain() LOCKS_EXCLUDED(cs_wallet);
/**
* Explicitly make the wallet learn the related scripts for outputs to the
@@ -1184,7 +1214,7 @@ public:
};
-/**
+/**
* DEPRECATED Account information.
* Stored in wallet with key "acc"+string account name.
*/
@@ -1214,7 +1244,7 @@ public:
}
};
-OutputType ParseOutputType(const std::string& str, OutputType default_type);
+bool ParseOutputType(const std::string& str, OutputType& output_type);
const std::string& FormatOutputType(OutputType type);
/**
@@ -1230,10 +1260,10 @@ std::vector<CTxDestination> GetAllDestinationsForKey(const CPubKey& key);
class WalletRescanReserver
{
private:
- CWalletRef m_wallet;
+ CWallet* m_wallet;
bool m_could_reserve;
public:
- explicit WalletRescanReserver(CWalletRef w) : m_wallet(w), m_could_reserve(false) {}
+ explicit WalletRescanReserver(CWallet* w) : m_wallet(w), m_could_reserve(false) {}
bool reserve()
{