6 #ifndef BITCOIN_WALLET_WALLET_H 7 #define BITCOIN_WALLET_WALLET_H 48 #include <unordered_map> 52 #include <boost/signals2/signal.hpp> 77 using
LoadWalletFn = std::function<void(std::unique_ptr<interfaces::Wallet> wallet)>;
92 bool RemoveWallet(WalletContext&
context,
const std::shared_ptr<CWallet>&
wallet, std::optional<bool> load_on_start, std::vector<bilingual_str>& warnings);
201 bool fInternal{
false};
221 void ReturnDestination();
223 void KeepDestination();
254 bool previously_spent{
false};
263 std::map<std::string, std::string> receive_requests{};
266 bool IsChange()
const {
return !label.has_value(); }
267 std::string
GetLabel()
const {
return label ? *label : std::string{}; }
305 bool Unlock(
const CKeyingMaterial& vMasterKeyIn,
bool accept_no_keys =
false);
307 std::atomic<bool> fAbortRescan{
false};
308 std::atomic<bool> fScanningWallet{
false};
309 std::atomic<bool> m_attaching_chain{
false};
310 std::atomic<bool> m_scanning_with_passphrase{
false};
311 std::atomic<SteadyClock::time_point> m_scanning_start{SteadyClock::time_point{}};
312 std::atomic<double> m_scanning_progress{0};
322 bool fBroadcastTransactions =
false;
324 std::atomic<int64_t> m_best_block_time {0};
328 std::atomic<int64_t> m_birth_time{std::numeric_limits<int64_t>::max()};
335 typedef std::unordered_multimap<COutPoint, uint256, SaltedOutpointHasher>
TxSpends;
359 void MarkConflicted(const
uint256& hashBlock,
int conflicting_height, const
uint256& hashTx);
361 enum class
TxUpdate { UNCHANGED, CHANGED, NOTIFY_CHANGED };
376 std::atomic<uint64_t> m_wallet_flags{0};
378 bool SetAddressBookWithDB(
WalletBatch& batch,
const CTxDestination& address,
const std::string& strName,
const std::optional<AddressPurpose>& strPurpose);
381 void UnsetWalletFlagWithDB(
WalletBatch& batch, uint64_t flag);
384 void UnsetBlankWalletFlag(
WalletBatch& batch)
override;
409 int m_last_block_processed_height
GUARDED_BY(cs_wallet) = -1;
420 void AddScriptPubKeyMan(
const uint256&
id, std::unique_ptr<ScriptPubKeyMan> spkm_man);
440 assert(static_cast<bool>(m_database));
446 const std::string&
GetName()
const {
return m_name; }
450 unsigned int nMasterKeyMaxID = 0;
456 m_database(
std::move(database))
466 bool IsCrypted()
const;
467 bool IsLocked()
const override;
471 bool HaveChain()
const {
return m_chain ? true :
false; }
475 std::unordered_map<uint256, CWalletTx, SaltedTxidHasher> mapWallet
GUARDED_BY(cs_wallet);
477 typedef std::multimap<int64_t, CWalletTx*>
TxItems;
480 int64_t nOrderPosNext
GUARDED_BY(cs_wallet) = 0;
482 std::map<CTxDestination, CAddressBookData> m_address_book
GUARDED_BY(cs_wallet);
511 return GetTxDepthInMainChain(wtx) > 0;
543 void AbortRescan() { fAbortRescan =
true; }
547 SteadyClock::duration
ScanningDuration()
const {
return fScanningWallet ? SteadyClock::now() - m_scanning_start.load() : SteadyClock::duration{}; }
548 double ScanningProgress()
const {
return fScanningWallet ? (double) m_scanning_progress : 0; }
567 Mutex m_unlock_mutex;
571 bool Unlock(
const SecureString& strWalletPassphrase,
bool accept_no_keys =
false);
572 bool ChangeWalletPassphrase(
const SecureString& strOldWalletPassphrase,
const SecureString& strNewWalletPassphrase);
573 bool EncryptWallet(
const SecureString& strWalletPassphrase);
576 unsigned int ComputeTimeSmart(
const CWalletTx& wtx,
bool rescanning_old_block)
const;
603 void blockDisconnected(const
interfaces::BlockInfo& block) override;
604 void updatedBlockTip() override;
622 ScanResult ScanForWalletTransactions(
const uint256& start_block,
int start_height, std::optional<int> max_height,
const WalletRescanReserver& reserver,
bool fUpdate,
const bool save_progress);
627 bool ShouldResend()
const;
628 void ResubmitWalletTransactions(
bool relay,
bool force);
630 OutputType TransactionChangeType(
const std::optional<OutputType>& change_type,
const std::vector<CRecipient>& vecSend)
const;
636 SigningResult SignMessage(
const std::string& message,
const PKHash& pkhash, std::string& str_sig)
const;
657 bool bip32derivs =
true,
658 size_t* n_signed =
nullptr,
659 bool finalize =
true)
const;
673 bool SubmitTxMemoryPoolAndRelay(
CWalletTx& wtx, std::string& err_string,
bool relay)
const 677 bool ImportPrivKeys(
const std::map<CKeyID, CKey>& privkey_map,
const int64_t timestamp)
EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
678 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);
679 bool ImportScriptPubKeys(
const std::string& label,
const std::set<CScript>& script_pub_keys,
const bool have_solving_data,
const bool apply_label,
const int64_t timestamp)
EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
682 void MaybeUpdateBirthTime(int64_t time);
690 bool m_allow_fallback_fee{
true};
718 std::optional<OutputType> m_default_change_type{};
729 bool TopUpKeyPool(
unsigned int kpSize = 0);
731 std::optional<int64_t> GetOldestKeyPoolTime() const;
736 std::optional<std::string> m_op_label{std::nullopt};
738 bool ignore_change{
true};
744 std::vector<CTxDestination> ListAddrBookAddresses(
const std::optional<AddrBookFilter>& filter)
const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
749 std::set<std::string> ListAddrBookLabels(
const std::optional<AddressPurpose> purpose)
const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
755 using ListAddrBookFunc = std::function<void(const CTxDestination& dest, const std::string& label, bool is_change, const std::optional<AddressPurpose> purpose)>;
785 bool SetAddressBook(
const CTxDestination& address,
const std::string& strName,
const std::optional<AddressPurpose>& purpose);
802 int GetVersion()
const {
LOCK(cs_wallet);
return nWalletVersion; }
824 const std::string& label,
bool isMine,
835 boost::signals2::signal<void (const std::string &title, int nProgress)>
ShowProgress;
855 bool TransactionCanBeAbandoned(
const uint256& hashTx)
const;
858 bool AbandonTransaction(
const uint256& hashTx);
861 bool MarkReplaced(
const uint256& originalHash,
const uint256& newHash);
864 static std::shared_ptr<CWallet> Create(
WalletContext&
context,
const std::string&
name, std::unique_ptr<WalletDatabase> database, uint64_t wallet_creation_flags,
bilingual_str&
error, std::vector<bilingual_str>& warnings);
870 void postInitProcess();
872 bool BackupWallet(
const std::string& strDest)
const;
875 bool IsHDEnabled()
const;
878 bool CanGetAddresses(
bool internal =
false)
const;
892 void SetWalletFlag(uint64_t
flags);
895 void UnsetWalletFlag(uint64_t flag);
898 bool IsWalletFlagSet(uint64_t flag) const override;
903 void InitWalletFlags(uint64_t
flags);
908 bool IsLegacy() const;
911 std::
string GetDisplayName()
const override 913 std::string wallet_name = GetName().length() == 0 ?
"default wallet" : GetName();
918 template <
typename...
Params>
921 LogPrintf((
"%s " + std::string{fmt}).c_str(), GetDisplayName(), parameters...);
928 std::set<ScriptPubKeyMan*> GetActiveScriptPubKeyMans()
const;
931 std::set<ScriptPubKeyMan*> GetAllScriptPubKeyMans()
const;
937 std::set<ScriptPubKeyMan*> GetScriptPubKeyMans(
const CScript& script)
const;
942 std::unique_ptr<SigningProvider> GetSolvingProvider(
const CScript& script)
const;
943 std::unique_ptr<SigningProvider> GetSolvingProvider(
const CScript& script,
SignatureData& sigdata)
const;
946 std::vector<WalletDescriptor> GetWalletDescriptors(
const CScript& script)
const;
953 void SetupLegacyScriptPubKeyMan();
956 bool HasEncryptionKeys()
const override;
962 assert(m_last_block_processed_height >= 0);
963 return m_last_block_processed_height;
968 assert(m_last_block_processed_height >= 0);
969 return m_last_block_processed;
975 m_last_block_processed_height = block_height;
976 m_last_block_processed = block_hash;
980 void ConnectScriptPubKeyManNotifiers();
1033 bool CanGrindR() const;
1046 using Clock = std::chrono::steady_clock;
1047 using NowFn = std::function<Clock::time_point()>;
1049 bool m_could_reserve{
false};
1056 assert(!m_could_reserve);
1057 if (
m_wallet.fScanningWallet.exchange(
true)) {
1060 m_wallet.m_scanning_with_passphrase.exchange(with_passphrase);
1061 m_wallet.m_scanning_start = SteadyClock::now();
1063 m_could_reserve =
true;
1069 return (m_could_reserve &&
m_wallet.fScanningWallet);
1072 Clock::time_point
now()
const {
return m_now ? m_now() : Clock::now(); };
1078 if (m_could_reserve) {
1080 m_wallet.m_scanning_with_passphrase =
false;
1103 #endif // BITCOIN_WALLET_WALLET_H std::shared_ptr< const CTransaction > CTransactionRef
uint256 last_failed_block
Height of the most recent block that could not be scanned due to read errors or pruning.
static const std::string sighash
constexpr OutputType DEFAULT_ADDRESS_TYPE
Default for -addresstype.
bool CanSupportFeature(enum WalletFeature wf) const override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
check whether we support the named feature
void SignTransaction(CMutableTransaction &mtx, const SigningProvider *keystore, const std::map< COutPoint, Coin > &coins, const UniValue &hashType, UniValue &result)
Sign a transaction with the given keystore and previous transactions.
std::chrono::time_point< NodeClock > time_point
static const CAmount DEFAULT_TRANSACTION_MINFEE
-mintxfee default
std::map< OutputType, ScriptPubKeyMan * > m_external_spk_managers
constexpr CAmount HIGH_TX_FEE_PER_KB
Discourage users to set fees higher than this amount (in satoshis) per kB.
static constexpr size_t DUMMY_NESTED_P2WPKH_INPUT_SIZE
Pre-calculated constants for input size estimation in virtual size
std::function< void(std::unique_ptr< interfaces::Wallet > wallet)> LoadWalletFn
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
Never set in current code may be present in older wallet databases.
std::optional< int > last_scanned_height
std::optional< AddressPurpose > purpose
Address purpose which was originally recorded for payment protocol support but now serves as a cached...
~ReserveDestination()
Destructor. If a key has been reserved and not KeepKey'ed, it will be returned to the keypool...
DBErrors
Error statuses for the wallet database.
uint256 last_scanned_block
Hash and height of most recent block that was successfully scanned.
std::map< std::string, std::string > mapValue_t
std::string GetLabel() const
std::string m_notify_tx_changed_script
Notify external script when a wallet transaction comes in or is updated (handled by -walletnotify) ...
std::optional< AddressPurpose > PurposeFromString(std::string_view s)
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal...
const std::string & GetName() const
Get a name for this wallet for logging/debugging purposes.
std::shared_ptr< CWallet > LoadWallet(WalletContext &context, const std::string &name, std::optional< bool > load_on_start, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
void SetBroadcastTransactions(bool broadcast)
Set whether this wallet broadcasts transactions.
struct containing information needed for migrating legacy wallets to descriptor wallets ...
std::shared_ptr< CWallet > m_wallet
WalletRescanReserver(CWallet &w)
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
MasterKeyMap mapMasterKeys
WalletDatabase & GetDatabase() const override
static const unsigned int DEFAULT_KEYPOOL_SIZE
Default for -keypool.
std::string PurposeToString(AddressPurpose p)
const CWallet *const pwallet
The wallet to reserve from.
CTxDestination address
The destination.
RecursiveMutex cs_wallet
Main wallet lock.
bool RemoveWalletSetting(interfaces::Chain &chain, const std::string &wallet_name)
Remove wallet name from persistent configuration so it will not be loaded on startup.
std::variant< TxStateConfirmed, TxStateInMempool, TxStateInactive > SyncTxState
Subset of states transaction sync logic is implemented to handle.
static const bool DEFAULT_DISABLE_WALLET
RAII object to check and reserve a wallet rescan.
std::multimap< int64_t, CWalletTx * > TxItems
A version of CTransaction with the PSBT format.
bool reserve(bool with_passphrase=false)
Access to the wallet database.
RecursiveMutex m_relock_mutex
boost::signals2::signal< void()> NotifyUnload
Wallet is about to be unloaded.
boost::signals2::signal< void(const uint256 &hashTx, ChangeType status)> NotifyTransactionChanged
Wallet transaction added, removed or updated.
double ScanningProgress() const
std::function< void(const CTxDestination &dest, const std::string &label, bool is_change, const std::optional< AddressPurpose > purpose)> ListAddrBookFunc
Walk-through the address book entries.
Taproot only; implied when sighash byte is missing, and equivalent to SIGHASH_ALL.
std::function< Clock::time_point()> NowFn
Flag set when a wallet contains no HD seed and no private keys, scripts, addresses, and other watch only things, and is therefore "blank.".
constexpr CAmount HIGH_MAX_TX_FEE
-maxtxfee will warn if called with a higher fee than this amount (in satoshis)
static constexpr uint64_t MUTABLE_WALLET_FLAGS
Result CommitTransaction(CWallet &wallet, const uint256 &txid, CMutableTransaction &&mtx, std::vector< bilingual_str > &errors, uint256 &bumped_txid)
Commit the bumpfee transaction.
static const bool DEFAULT_WALLET_RBF
-walletrbf default
void MaybeResendWalletTxs(WalletContext &context)
Called periodically by the schedule thread.
static const CAmount DEFAULT_MAX_AVOIDPARTIALSPEND_FEE
maximum fee increase allowed to do partial spend avoidance, even for nodes with this feature disabled...
static const bool DEFAULT_SPEND_ZEROCONF_CHANGE
Default for -spendzeroconfchange.
std::map< uint256, std::unique_ptr< ScriptPubKeyMan > > m_spk_managers
boost::signals2::signal< void(bool fHaveWatchOnly)> NotifyWatchonlyChanged
Watch-only address added.
int64_t CAmount
Amount in satoshis (Can be negative)
static DBErrors LoadWalletFlags(CWallet *pwallet, DatabaseBatch &batch) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
constexpr CAmount DEFAULT_PAY_TX_FEE
-paytxfee default
A transaction with a bunch of additional info that only the owner cares about.
interfaces::Chain * m_chain
Interface for accessing chain state.
std::function< TxUpdate(CWalletTx &wtx)> TryUpdatingStateFn
CWallet(interfaces::Chain *chain, const std::string &name, std::unique_ptr< WalletDatabase > database)
Construct wallet with specified name and database implementation.
AddressPurpose
Address purpose field that has been been stored with wallet sending and receiving addresses since BIP...
Indicates that the wallet needs an external signer.
bool fSubtractFeeFromAmount
std::underlying_type< isminetype >::type isminefilter
used for bitflags of isminetype
std::shared_ptr< CWallet > wallet
static const CAmount WALLET_INCREMENTAL_RELAY_FEE
minimum recommended increment for replacement txs
std::chrono::steady_clock Clock
ChainstateRole
This enum describes the various roles a specific Chainstate instance can take.
bool GetBroadcastTransactions() const
Inquire whether this wallet broadcasts transactions.
An input of a transaction.
static constexpr uint64_t KNOWN_WALLET_FLAGS
int GetLastBlockHeight() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Get last block processed height.
static const unsigned int DEFAULT_TX_CONFIRM_TARGET
-txconfirmtarget default
std::map< OutputType, ScriptPubKeyMan * > m_internal_spk_managers
std::optional< std::string > label
Address label which is always nullopt for change addresses.
void SetLastBlockProcessed(int block_height, uint256 block_hash) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Set last block processed height, currently only use in unit test.
int nWalletVersion GUARDED_BY(cs_wallet)
the current wallet version: clients below this version are not able to load the wallet ...
An encapsulated public key.
isminetype
IsMine() return codes, which depend on ScriptPubKeyMan implementation.
static const CAmount DEFAULT_DISCARD_FEE
-discardfee default
void NotifyWalletLoaded(WalletContext &context, const std::shared_ptr< CWallet > &wallet)
bool IsFeatureSupported(int wallet_version, int feature_version)
WalletFeature
(client) version numbers for particular wallet features
Indicate that this wallet supports DescriptorScriptPubKeyMan.
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
An output of a transaction.
std::map< unsigned int, CMasterKey > MasterKeyMap
std::string m_name
Wallet name: relative directory name or "" for default wallet.
An outpoint - a combination of a transaction hash and an index n into its vout.
static DBErrors LoadMinVersion(CWallet *pwallet, DatabaseBatch &batch) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
static const std::map< std::string, WalletFlags > WALLET_FLAG_MAP
void UnloadWallet(std::shared_ptr< CWallet > &&wallet)
Explicitly unload and delete the wallet.
static const CAmount DEFAULT_FALLBACK_FEE
-fallbackfee default
util::Result< MigrationResult > MigrateLegacyToDescriptor(const std::string &wallet_name, const SecureString &passphrase, WalletContext &context)
Do all steps to migrate a legacy wallet to a descriptor wallet.
boost::signals2::signal< void(const std::string &title, int nProgress)> ShowProgress
Show progress e.g.
bool AddWalletSetting(interfaces::Chain &chain, const std::string &wallet_name)
Add wallet name to persistent configuration so it will be loaded on startup.
std::shared_ptr< CWallet > solvables_wallet
bool IsTxInMainChain(const CWalletTx &wtx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Descriptor with some wallet metadata.
static const bool DEFAULT_WALLETBROADCAST
bool RemoveWallet(WalletContext &context, const std::shared_ptr< CWallet > &wallet, std::optional< bool > load_on_start, std::vector< bilingual_str > &warnings)
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
std::shared_ptr< CWallet > GetWallet(WalletContext &context, const std::string &name)
static void NotifyUnload(WalletModel *walletModel)
bool IsChange() const
Accessor methods.
void WalletLogPrintf(const char *fmt, Params... parameters) const
Prepends the wallet name in logging output to ease debugging in multi-wallet use cases.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
std::vector< std::shared_ptr< CWallet > > GetWallets(WalletContext &context)
An interface to be implemented by keystores that support signing.
#define LOCKS_EXCLUDED(...)
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
bool error(const char *fmt, const Args &... args)
const CChainParams & Params()
Return the currently selected parameters.
std::function< bool(CWalletTx &wtx, bool new_tx)> UpdateWalletTxFn
Callback for updating transaction metadata in mapWallet.
Serialized script, used inside transaction inputs and outputs.
std::shared_ptr< CWallet > watchonly_wallet
int64_t GetBirthTime() const
bool IsAbortingRescan() const
boost::signals2::signal< void(CWallet *wallet)> NotifyStatusChanged
Wallet status (encrypted, locked) changed.
A reference to a CKey: the Hash160 of its serialized public key.
std::unique_ptr< interfaces::Handler > HandleLoadWallet(WalletContext &context, LoadWalletFn load_wallet)
constexpr CAmount DEFAULT_TRANSACTION_MAXFEE
-maxtxfee default
WalletContext struct containing references to state shared between CWallet instances, like the reference to the chain interface, and the list of opened wallets.
A wrapper to reserve an address from a wallet.
bool HaveChain() const
Interface to assert chain access.
Fee rate in satoshis per kilovirtualbyte: CAmount / kvB.
void SetLabel(std::string name)
bool IsScanningWithPassphrase() const
SteadyClock::duration ScanningDuration() const
std::unordered_multimap< COutPoint, uint256, SaltedOutpointHasher > TxSpends
Used to keep track of spent outpoints, and detect and report conflicts (double-spends or mutated tran...
A mutable version of CTransaction.
uint256 GetLastBlockHash() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
void SetNextResend()
Set the next time this wallet should resend transactions to 12-36 hours from now, ~1 day on average...
std::unique_ptr< WalletDatabase > m_database
Internal database handle.
An encapsulated private key.
The basic transaction that is broadcasted on the network and contained in blocks. ...
static const bool DEFAULT_WALLETCROSSCHAIN
constexpr CAmount HIGH_APS_FEE
discourage APS fee higher than this amount
static const CAmount DEFAULT_CONSOLIDATE_FEERATE
-consolidatefeerate default
std::shared_ptr< CWallet > CreateWallet(WalletContext &context, const std::string &name, std::optional< bool > load_on_start, DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
ReserveDestination(CWallet *pwallet, OutputType type)
Construct a ReserveDestination object. This does NOT reserve an address yet.
ChangeType
General change type (added, updated, removed).
boost::signals2::signal< void(const CTxDestination &address, const std::string &label, bool isMine, AddressPurpose purpose, ChangeType status)> NotifyAddressBookChanged
Address book entry changed.
std::shared_ptr< CWallet > RestoreWallet(WalletContext &context, const fs::path &backup_file, const std::string &wallet_name, std::optional< bool > load_on_start, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
std::shared_ptr< CWallet > GetDefaultWallet(WalletContext &context, size_t &count)
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
bool AddWallet(WalletContext &context, const std::shared_ptr< CWallet > &wallet)
static std::set< std::string > g_loading_wallet_set GUARDED_BY(g_loading_wallet_mutex)
std::variant< TxStateConfirmed, TxStateInMempool, TxStateConflicted, TxStateInactive, TxStateUnrecognized > TxState
All possible CWalletTx states.
An instance of this class represents one database.
boost::signals2::signal< void()> NotifyCanGetAddressesChanged
Keypool has new keys.
std::vector< unsigned char, secure_allocator< unsigned char > > CKeyingMaterial
Clock::time_point now() const
std::unique_ptr< WalletDatabase > MakeWalletDatabase(const std::string &name, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error_string)
static const bool DEFAULT_WALLET_REJECT_LONG_CHAINS
Default for -walletrejectlongchains.
static constexpr CAmount COIN
The amount of satoshis in one BTC.