Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
501std::unordered_map<Txid, CWalletTx, SaltedTxidHasher> mapWallet GUARDED_BY(cs_wallet);503typedef std::multimap<int64_t, CWalletTx*> TxItems;504TxItems wtxOrdered;506int64_t nOrderPosNext GUARDED_BY(cs_wallet) = 0;508std::map<CTxDestination, CAddressBookData> m_address_book GUARDED_BY(cs_wallet);509const CAddressBookData* FindAddressBookEntry(const CTxDestination&, bool allow_change = false) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);511/** Set of Coins owned by this wallet that we won't try to spend from. A512* Coin may be locked if it has already been used to fund a transaction513* that hasn't confirmed yet. We wouldn't consider the Coin spent already,514* but also shouldn't try to use it again.515* bool to track whether this locked coin is persisted to disk.516*/517std::map<COutPoint, bool> m_locked_coins GUARDED_BY(cs_wallet);519/** Registered interfaces::Chain::Notifications handler. */520std::unique_ptr<interfaces::Handler> m_chain_notifications_handler;522/** Interface for accessing chain state. */523interfaces::Chain& chain() const { assert(m_chain); return *m_chain; }525const CWalletTx* GetWalletTx(const Txid& hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);527std::set<Txid> GetTxConflicts(const CWalletTx& wtx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);529const std::unordered_map<COutPoint, WalletTXO, SaltedOutpointHasher>& GetTXOs() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { AssertLockHeld(cs_wallet); return m_txos; };530std::optional<WalletTXO> GetTXO(const COutPoint& outpoint) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);532/** Cache outputs that belong to the wallet from a single transaction */533void RefreshTXOsFromTx(const CWalletTx& wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);534/** Cache outputs that belong to the wallet for all transactions in the wallet */535void RefreshAllTXOs() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);537/**538* Return depth of transaction in blockchain:539* <0 : conflicts with a transaction this deep in the blockchain540* 0 : in memory pool, waiting to be included in a block541* >=1 : this many blocks deep in the main chain542*543* Preconditions: it is only valid to call this function when the wallet is544* online and the block index is loaded. So this cannot be called by545* bitcoin-wallet tool code or by wallet migration code. If this is called546* without the wallet being online, it won't be able able to determine the547* the height of the last block processed, or the heights of blocks548* referenced in transaction, and might cause assert failures.549*/550int GetTxDepthInMainChain(const CWalletTx& wtx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);552/**553* @return number of blocks to maturity for this transaction:554* 0 : is not a coinbase transaction, or is a mature coinbase transaction555* >0 : is a coinbase transaction which matures in this many blocks556*/557int GetTxBlocksToMaturity(const CWalletTx& wtx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);558bool IsTxImmatureCoinBase(const CWalletTx& wtx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);560enum class SpendType {561UNSPENT,562CONFIRMED,563MEMPOOL,564NONMEMPOOL,565};566SpendType HowSpent(const COutPoint& outpoint) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);567bool IsSpent(const COutPoint& outpoint) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);569// Whether this or any known scriptPubKey with the same single key has been spent.570bool IsSpentKey(const CScript& scriptPubKey) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);571void SetSpentKeyState(WalletBatch& batch, const Txid& hash, unsigned int n, bool used, std::set<CTxDestination>& tx_destinations) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);573/** Display address on an external signer. */574util::Result<void> DisplayAddress(const CTxDestination& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);576bool IsLockedCoin(const COutPoint& output) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);577void LoadLockedCoin(const COutPoint& coin, bool persistent) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);578bool LockCoin(const COutPoint& output, bool persist) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);579bool UnlockCoin(const COutPoint& output) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);580bool UnlockAllCoins() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);581void ListLockedCoins(std::vector<COutPoint>& vOutpts) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);583/*584* Rescan abort properties585*/586void AbortRescan() { fAbortRescan = true; }587bool IsAbortingRescan() const { return fAbortRescan; }588bool IsScanning() const { return fScanningWallet; }589bool IsScanningWithPassphrase() const { return m_scanning_with_passphrase; }590SteadyClock::duration ScanningDuration() const { return fScanningWallet ? SteadyClock::now() - m_scanning_start.load() : SteadyClock::duration{}; }591double ScanningProgress() const { return fScanningWallet ? (double) m_scanning_progress : 0; }593//! Upgrade DescriptorCaches594void UpgradeDescriptorCache() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);596//! Marks destination as previously spent.597void LoadAddressPreviouslySpent(const CTxDestination& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);598//! Appends payment request to destination.599void LoadAddressReceiveRequest(const CTxDestination& dest, const std::string& id, const std::string& request) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);601//! Holds a timestamp at which point the wallet is scheduled (externally) to be relocked. Caller must arrange for actual relocking to occur via Lock().602int64_t nRelockTime GUARDED_BY(cs_wallet){0};604// Used to prevent concurrent calls to walletpassphrase RPC.605Mutex m_unlock_mutex;606// Used to prevent deleting the passphrase from memory when it is still in use.607RecursiveMutex m_relock_mutex;609bool Unlock(const SecureString& strWalletPassphrase);610bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase);611bool EncryptWallet(const SecureString& strWalletPassphrase);613unsigned int ComputeTimeSmart(const CWalletTx& wtx, bool rescanning_old_block) const;615/**616* Increment the next transaction order id617* @return next transaction order id618*/619int64_t IncOrderPosNext(WalletBatch *batch = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);620DBErrors ReorderTransactions();622void MarkDirty();624//! Callback for updating transaction metadata in mapWallet.625//!626//! @param wtx - reference to mapWallet transaction to update627//! @param new_tx - true if wtx is newly inserted, false if it previously existed628//!629//! @return true if wtx is changed and needs to be saved to disk, otherwise false630using UpdateWalletTxFn = std::function<bool(CWalletTx& wtx, bool new_tx)>;632/**633* Add the transaction to the wallet, wrapping it up inside a CWalletTx634* @return the recently added wtx pointer or nullptr if there was a db write error.635*/636CWalletTx* AddToWallet(CTransactionRef tx, const TxState& state, const UpdateWalletTxFn& update_wtx=nullptr, bool rescanning_old_block = false);637bool LoadToWallet(CWalletTx&& wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);638void transactionAddedToMempool(const CTransactionRef& tx) override;639void blockConnected(const kernel::ChainstateRole& role, const interfaces::BlockInfo& block) override;640void blockDisconnected(const interfaces::BlockInfo& block) override;641void updatedBlockTip() override;642int64_t RescanFromTime(int64_t startTime, const WalletRescanReserver& reserver);644struct ScanResult {645enum { SUCCESS, FAILURE, USER_ABORT } status = SUCCESS;647//! Hash and height of most recent block that was successfully scanned.648//! Unset if no blocks were scanned due to read errors or the chain649//! being empty.650uint256 last_scanned_block;651std::optional<int> last_scanned_height;653//! Height of the most recent block that could not be scanned due to654//! read errors or pruning. Will be set if status is FAILURE, unset if655//! status is SUCCESS, and may or may not be set if status is656//! USER_ABORT.657uint256 last_failed_block;658};659ScanResult ScanForWalletTransactions(const uint256& start_block, int start_height, std::optional<int> max_height, const WalletRescanReserver& reserver, bool save_progress);660void transactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason) override;661/** Set the next time this wallet should resend transactions to 12-36 hours from now, ~1 day on average. */662void SetNextResend() { m_next_resend = GetDefaultNextResend(); }663/** Return true if all conditions for periodically resending transactions are met. */664bool ShouldResend() const;665void ResubmitWalletTransactions(node::TxBroadcast broadcast_method, bool force);667OutputType TransactionChangeType(const std::optional<OutputType>& change_type, const std::vector<CRecipient>& vecSend) const;669/** Fetch the inputs and sign with SIGHASH_ALL. */670bool SignTransaction(CMutableTransaction& tx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);671/** Sign the tx given the input coins and sighash. */672bool SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, bilingual_str>& input_errors) const;673SigningResult SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const;675/**676* Fills out a PSBT with information from the wallet. Fills in UTXOs if we have677* them. Tries to sign if options.sign=true.678* Sets `complete` if the PSBT is now complete (i.e. has all required679* signatures or signature-parts, and is ready to finalize.)680*681* @param[in] psbtx PartiallySignedTransaction to fill in682* @param[in] options options for filling or signing683* @param[out] complete indicates whether the PSBT is now complete684* @param[out] n_signed the number of inputs signed by this wallet685* @returns an error if something goes wrong686*/687std::optional<common::PSBTError> FillPSBT(PartiallySignedTransaction& psbtx,688const common::PSBTFillOptions& options,689bool& complete,690size_t* n_signed = nullptr) const;692/**693* Submit the transaction to the node's mempool and then relay to peers.694* Should be called after CreateTransaction unless you want to abort695* broadcasting the transaction.696*697* @param[in] tx The transaction to be broadcast.698* @param[in] replaces_txid The txid of the transaction that this transaction replaces699* @param[in] comment The user's comment for this transaction700* @param[in] comment_to The comment for this transaction indicating where coins are sent to701* @param[in] messages The BIP 21 URI messages to attach to this transaction702*/703void CommitTransaction(704CTransactionRef tx,705std::optional<Txid> replaces_txid = std::nullopt,706std::optional<std::string> comment = std::nullopt,707std::optional<std::string> comment_to = std::nullopt,708const std::vector<std::string>& messages = {},709const std::vector<std::string>& payment_requests = {}710);712/** Pass this transaction to node for optional mempool insertion and relay to peers. */713bool SubmitTxMemoryPoolAndRelay(CWalletTx& wtx, std::string& err_string, node::TxBroadcast broadcast_method) const714EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);716/** Updates wallet birth time if 'time' is below it */717void MaybeUpdateBirthTime(int64_t time);719unsigned int m_confirm_target{DEFAULT_TX_CONFIRM_TARGET};720/** Allow Coin Selection to pick unconfirmed UTXOs that were sent from our own wallet if it721* cannot fund the transaction otherwise. */722bool m_spend_zero_conf_change{DEFAULT_SPEND_ZEROCONF_CHANGE};723bool m_signal_rbf{DEFAULT_WALLET_RBF};724bool m_allow_fallback_fee{true}; //!< will be false if -fallbackfee=0725CFeeRate m_min_fee{DEFAULT_TRANSACTION_MINFEE};726/**727* If fee estimation does not have enough data to provide estimates, use this fee instead.728* Has no effect if not using fee estimation729* Override with -fallbackfee730*/731CFeeRate m_fallback_fee{DEFAULT_FALLBACK_FEE};733/** If the cost to spend a change output at this feerate is greater than the value of the734* output itself, just drop it to fees. */735CFeeRate m_discard_rate{DEFAULT_DISCARD_FEE};737/** When the actual feerate is less than the consolidate feerate, we will tend to make transactions which738* consolidate inputs. When the actual feerate is greater than the consolidate feerate, we will tend to make739* transactions which have the lowest fees.740*/741CFeeRate m_consolidate_feerate{DEFAULT_CONSOLIDATE_FEERATE};743/** The maximum fee amount we're willing to pay to prioritize partial spend avoidance. */744CAmount m_max_aps_fee{DEFAULT_MAX_AVOIDPARTIALSPEND_FEE}; //!< note: this is absolute fee, not fee rate745OutputType m_default_address_type{DEFAULT_ADDRESS_TYPE};746/**747* Default output type for change outputs. When unset, automatically choose type748* based on address type setting and the types other of non-change outputs749* (see -changetype option documentation and implementation in750* CWallet::TransactionChangeType for details).
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.