Inside Bitcoin
Opening the selected file…
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.
1// Copyright (c) 2022-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#ifndef BITCOIN_NODE_MINI_MINER_H6#define BITCOIN_NODE_MINI_MINER_H8#include <attributes.h>9#include <consensus/amount.h>10#include <primitives/transaction.h>12#include <cstdint>13#include <map>14#include <optional>15#include <set>16#include <vector>18class CFeeRate;19class CTxMemPool;21namespace node {23// Container for tracking updates to ancestor feerate as we include ancestors in the "block"24class MiniMinerMempoolEntry25{26const CTransactionRef tx;27const int64_t vsize_individual;28int64_t vsize_with_ancestors;29const CAmount fee_individual;30CAmount fee_with_ancestors;32// This class must be constructed while holding mempool.cs. After construction, the object's33// methods can be called without holding that lock.35public:36explicit MiniMinerMempoolEntry(const CTransactionRef& tx_in,37int64_t vsize_self,38int64_t vsize_ancestor,39CAmount fee_self,40CAmount fee_ancestor):41tx{tx_in},42vsize_individual{vsize_self},43vsize_with_ancestors{vsize_ancestor},44fee_individual{fee_self},45fee_with_ancestors{fee_ancestor}46{ }48CAmount GetModifiedFee() const { return fee_individual; }49CAmount GetModFeesWithAncestors() const { return fee_with_ancestors; }50int64_t GetTxSize() const { return vsize_individual; }51int64_t GetSizeWithAncestors() const { return vsize_with_ancestors; }52const CTransaction& GetTx() const LIFETIMEBOUND { return *tx; }53void UpdateAncestorState(int64_t vsize_change, CAmount fee_change) {54vsize_with_ancestors += vsize_change;55fee_with_ancestors += fee_change;56}57};59// Comparator needed for std::set<MockEntryMap::iterator>60struct IteratorComparator61{62template<typename I>63bool operator()(const I& a, const I& b) const64{65return a->first < b->first;66}67};69/** A minimal version of BlockAssembler, using the same ancestor set scoring algorithm. Allows us to70* run this algorithm on a limited set of transactions (e.g. subset of mempool or transactions that71* are not yet in mempool) instead of the entire mempool, ignoring consensus rules.72* Callers may use this to:73* - Calculate the "bump fee" needed to spend an unconfirmed UTXO at a given feerate74* - "Linearize" a list of transactions to see the order in which they would be selected for75* inclusion in a block76*/77class MiniMiner78{79// When true, a caller may use CalculateBumpFees(). Becomes false if we failed to retrieve80// mempool entries (i.e. cluster size too large) or bump fees have already been calculated.81bool m_ready_to_calculate{true};83// Set once per lifetime, fill in during initialization.84// txids of to-be-replaced transactions85std::set<Txid> m_to_be_replaced;87// If multiple argument outpoints correspond to the same transaction, cache them together in88// a single entry indexed by txid. Then we can just work with txids since all outpoints from89// the same tx will have the same bumpfee. Excludes non-mempool transactions.90std::map<Txid, std::vector<COutPoint>> m_requested_outpoints_by_txid;92// Txid to a number representing the order in which this transaction was included (smaller93// number = included earlier). Transactions included in an ancestor set together have the same94// sequence number.95std::map<Txid, uint32_t> m_inclusion_order;96// What we're trying to calculate. Outpoint to the fee needed to bring the transaction to the target feerate.97std::map<COutPoint, CAmount> m_bump_fees;99// The constructed block template100std::set<Txid> m_in_block;102// Information on the current status of the block103CAmount m_total_fees{0};104int32_t m_total_vsize{0};106/** Main data structure holding the entries, can be indexed by txid */107std::map<Txid, MiniMinerMempoolEntry> m_entries_by_txid;108using MockEntryMap = decltype(m_entries_by_txid);110/** Vector of entries, can be sorted by ancestor feerate. */111std::vector<MockEntryMap::iterator> m_entries;113/** Map of txid to its descendants. Should be inclusive. */114std::map<Txid, std::vector<MockEntryMap::iterator>> m_descendant_set_by_txid;116/** Consider this ancestor package "mined" so remove all these entries from our data structures. */117void DeleteAncestorPackage(const std::set<MockEntryMap::iterator, IteratorComparator>& ancestors);119/** Perform some checks. */120void SanityCheck() const;122public:123/** Returns true if CalculateBumpFees may be called, false if not. */124bool IsReadyToCalculate() const { return m_ready_to_calculate; }126/** Build a block template until the target feerate is hit. If target_feerate is not given,127* builds a block template until all transactions have been selected. */128void BuildMockTemplate(std::optional<CFeeRate> target_feerate);130/** Returns set of txids in the block template if one has been constructed. */131std::set<Txid> GetMockTemplateTxids() const { return m_in_block; }133/** Constructor that takes a list of outpoints that may or may not belong to transactions in the134* mempool. Copies out information about the relevant transactions in the mempool into135* MiniMinerMempoolEntrys.136*/137MiniMiner(const CTxMemPool& mempool, const std::vector<COutPoint>& outpoints);139/** Constructor in which the MiniMinerMempoolEntry entries have been constructed manually.140* It is assumed that all entries are unique and their values are correct, otherwise results141* computed by MiniMiner may be incorrect. Callers should check IsReadyToCalculate() after142* construction.143* @param[in] descendant_caches A map from each transaction to the set of txids of this144* transaction's descendant set, including itself. Each tx in145* manual_entries must have a corresponding entry in this map, and146* all of the txids in a descendant set must correspond to a tx in147* manual_entries.148*/149MiniMiner(const std::vector<MiniMinerMempoolEntry>& manual_entries,150const std::map<Txid, std::set<Txid>>& descendant_caches);152/** Construct a new block template and, for each outpoint corresponding to a transaction that153* did not make it into the block, calculate the cost of bumping those transactions (and their154* ancestors) to the minimum feerate. Returns a map from outpoint to bump fee, or an empty map155* if they cannot be calculated. */156std::map<COutPoint, CAmount> CalculateBumpFees(const CFeeRate& target_feerate);158/** Construct a new block template and, calculate the cost of bumping all transactions that did159* not make it into the block to the target feerate. Returns the total bump fee, or std::nullopt160* if it cannot be calculated. */161std::optional<CAmount> CalculateTotalBumpFees(const CFeeRate& target_feerate);163/** Construct a new block template with all of the transactions and calculate the order in which164* they are selected. Returns the sequence number (lower = selected earlier) with which each165* transaction was selected, indexed by txid, or an empty map if it cannot be calculated.166*/167std::map<Txid, uint32_t> Linearize();168};169} // namespace node171#endif // BITCOIN_NODE_MINI_MINER_H
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.