6 #ifndef BITCOIN_TXMEMPOOL_H 7 #define BITCOIN_TXMEMPOOL_H 27 #include <boost/multi_index/hashed_index.hpp> 28 #include <boost/multi_index/identity.hpp> 29 #include <boost/multi_index/indexed_by.hpp> 30 #include <boost/multi_index/ordered_index.hpp> 31 #include <boost/multi_index/sequenced_index.hpp> 32 #include <boost/multi_index/tag.hpp> 33 #include <boost/multi_index_container.hpp> 40 #include <string_view> 58 static constexpr uint64_t POST_CHANGE_COST = 5 * ACCEPTABLE_COST; 63 bool TestLockPointValidity(CChain& active_chain, const LockPoints& lp) EXCLUSIVE_LOCKS_REQUIRED(cs_main); 65 // extracts a transaction hash from CTxMemPoolEntry or CTransactionRef 66 struct mempoolentry_txid 68 typedef Txid result_type; 69 result_type operator() (const CTxMemPoolEntry &entry) const 71 return entry.GetTx().GetHash(); 74 result_type operator() (const CTransactionRef& tx) const 80 // extracts a transaction witness-hash from CTxMemPoolEntry or CTransactionRef 81 struct mempoolentry_wtxid 83 typedef Wtxid result_type; 84 result_type operator() (const CTxMemPoolEntry &entry) const 86 return entry.GetTx().GetWitnessHash(); 89 result_type operator() (const CTransactionRef& tx) const 91 return tx->GetWitnessHash(); 95 class CompareTxMemPoolEntryByEntryTime 98 bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const 100 return a.GetTime() < b.GetTime(); 104 // Multi_index tag names 105 struct entry_time {}; 106 struct index_by_wtxid {}; 117 std::chrono::seconds m_time; 189 std::atomic<unsigned int> nTransactionsUpdated{0}; //!< Used by getblocktemplate to trigger CreateNewBlock() invocation 191 uint64_t totalTxSize GUARDED_BY(cs){0}; //!< sum of all mempool tx's virtual sizes. Differs from serialized tx size since witness
data is discounted. Defined in BIP 141.
208 CFeeRate GetMinFee(
size_t sizelimit)
const;
212 static const int ROLLING_FEE_HALFLIFE = 60 * 60 * 12;
216 boost::multi_index::hashed_unique<mempoolentry_txid, SaltedTxidHasher>,
218 boost::multi_index::hashed_unique<
219 boost::multi_index::tag<index_by_wtxid>,
224 boost::multi_index::ordered_non_unique<
225 boost::multi_index::tag<entry_time>,
226 boost::multi_index::identity<CTxMemPoolEntry>,
227 CompareTxMemPoolEntryByEntryTime
231 typedef boost::multi_index_container<
262 mutable std::unique_ptr<TxGraph::BlockBuilder> m_builder
GUARDED_BY(
cs);
265 using txiter = indexed_transaction_set::nth_index<0>::type::const_iterator;
266 std::vector<std::pair<Wtxid, txiter>> txns_randomized
GUARDED_BY(
cs);
277 std::vector<CTxMemPoolEntry::CTxMemPoolEntryRef> GetChildren(
const CTxMemPoolEntry &entry)
const;
278 std::vector<CTxMemPoolEntry::CTxMemPoolEntryRef> GetParents(
const CTxMemPoolEntry &entry)
const;
290 return TxMempoolInfo{it->GetSharedTx(), it->GetTime(), it->GetFee(), it->GetTxSize(), it->GetModifiedFee() - it->GetFee()};
336 bool CompareMiningScoreWithTopology(
const Wtxid& hasha,
const Wtxid& hashb)
const;
337 bool isSpent(
const COutPoint& outpoint)
const;
338 unsigned int GetTransactionsUpdated()
const;
339 void AddTransactionsUpdated(
unsigned int n);
347 void PrioritiseTransaction(
const Txid& hash,
const CAmount& nFeeDelta);
398 return m_txgraph->GetMainChunkFeerate(tx);
401 auto tx = GetIter(txid);
404 std::vector<const CTxMemPoolEntry*>
ret;
405 ret.reserve(cluster.size());
406 for (
const auto& tx : cluster) {
407 ret.emplace_back(static_cast<const CTxMemPoolEntry*>(tx));
414 std::vector<const TxGraph::Ref *> entries;
415 entries.reserve(iters_conflicting.size());
416 for (
auto it : iters_conflicting) {
417 entries.emplace_back(&*it);
432 bool HasDescendants(
const Txid& txid)
const;
471 void GetTransactionAncestry(const
Txid& txid,
size_t& ancestors,
size_t& cluster_count,
size_t* ancestorsize =
nullptr,
CAmount* ancestorfees =
nullptr) const;
477 bool GetLoadTried() const;
483 void SetLoadTried(
bool load_tried);
485 unsigned long size()
const 506 return (mapTx.count(txid) != 0);
519 template <Tx
idOrWtx
id T>
528 template <Tx
idOrWtx
id T>
533 return (i.has_value() && i.value()->GetSequence() < last_sequence) ? GetInfo(*i) :
TxMempoolInfo{};
539 size_t DynamicMemoryUsage() const;
542 void AddUnbroadcastTx(const
Txid& txid)
547 if (exists(txid)) m_unbroadcast_txids.insert(txid);
553 void RemoveUnbroadcastTx(
const Txid& txid,
bool unchecked =
false);
559 return m_unbroadcast_txids;
566 return m_unbroadcast_txids.contains(txid);
571 return m_sequence_number++;
575 return m_sequence_number;
625 if (m_pool->m_txgraph->HaveStaging()) {
626 m_pool->m_txgraph->AbortStaging();
628 m_pool->m_have_changeset =
false;
643 bool CheckMemPoolPolicyLimits();
648 auto it = m_ancestors.find(tx);
649 if (it != m_ancestors.end())
return it->second;
654 auto ret = m_pool->CalculateMemPoolAncestors(*tx);
655 m_ancestors.try_emplace(tx,
ret);
660 std::vector<CTransactionRef>
ret;
661 ret.reserve(m_entry_vec.size());
662 for (
const auto& entry : m_entry_vec) {
663 ret.emplace_back(entry->GetSharedTx());
682 void ProcessDependencies();
690 bool m_dependencies_processed{
false};
696 Assume(!m_have_changeset);
697 m_have_changeset =
true;
698 return std::make_unique<ChangeSet>(
this);
723 if (!m_builder) {
return {}; }
725 auto res = m_builder->GetCurrentChunk();
726 if (!res) {
return {}; }
728 auto [chunk_entries, chunk_feerate] = *res;
730 entries.emplace_back(static_cast<const CTxMemPoolEntry&>(*ref));
732 return chunk_feerate;
758 std::unordered_map<COutPoint, Coin, SaltedOutpointHasher>
m_temp_added;
781 #endif // BITCOIN_TXMEMPOOL_H std::shared_ptr< const CTransaction > CTransactionRef
int64_t lastRollingFeeUpdate GUARDED_BY(cs)
sum of dynamic memory usage of all the map elements (NOT the maps themselves)
const bool in_mempool
Whether this transaction is in the mempool.
CTxMemPool::setEntries CalculateMemPoolAncestors(TxHandle tx)
void IncludeBuilderChunk() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Information about a mempool transaction.
std::unordered_set< COutPoint, SaltedOutpointHasher > m_non_base_coins
Set of all coins that have been fetched from mempool or created using PackageAddTransaction (not base...
Always refers to the main graph, whether staging is present or not.
bool m_have_changeset GUARDED_BY(cs)
indexed_transaction_set::nth_index< 0 >::type::const_iterator txiter
const CTransaction & GetAddedTxn(size_t index) const
std::vector< const CTxMemPoolEntry * > GetCluster(Txid txid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
~ChangeSet() EXCLUSIVE_LOCKS_REQUIRED(m_pool -> cs)
Options struct containing limit options for a CTxMemPool.
An in-memory indexed chain of blocks.
int64_t GetAncestorCount(const CTxMemPoolEntry &e) const
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal...
int64_t GetTime()
DEPRECATED, see GetTime.
TxMempoolInfo info(const T &id) const
size_t GetTxCount() const
ChangeSet(CTxMemPool *pool)
uint64_t GetSequence() const EXCLUSIVE_LOCKS_REQUIRED(cs)
void StartBlockBuilding() const EXCLUSIVE_LOCKS_REQUIRED(cs)
std::unique_ptr< ChangeSet > GetChangeSet() EXCLUSIVE_LOCKS_REQUIRED(cs)
std::set< txiter, CompareIteratorByHash > setEntries
void check(const CCoinsViewCache &active_coins_tip, int64_t spendheight) const EXCLUSIVE_LOCKS_REQUIRED(void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
If sanity-checking is turned on, check makes sure the pool is consistent (does not contain two transa...
CFeeRate GetMinFee() const
The minimum fee to get into the mempool, which may itself not be enough for larger-sized transactions...
Tagged wrapper around FeeFrac to avoid unit confusion.
std::optional< Coin > GetCoin(const COutPoint &outpoint) const override
GetCoin, returning whether it exists and is not spent.
int64_t GetDescendantCount(txiter it) const
void StopBlockBuilding() const EXCLUSIVE_LOCKS_REQUIRED(cs)
std::set< Txid > GetUnbroadcastTxs() const
Returns transactions in unbroadcast set.
const CTxMemPool::setEntries & GetRemovals() const
const CAmount delta
The fee delta added using PrioritiseTransaction().
size_t GetUniqueClusterCount(const setEntries &iters_conflicting) const EXCLUSIVE_LOCKS_REQUIRED(cs)
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
int64_t CAmount
Amount in satoshis (Can be negative)
static const uint32_t MEMPOOL_HEIGHT
Fake height value used in Coin to signify they are only in the memory pool (since 0...
bool blockSinceLastRollingFeeBump GUARDED_BY(cs)
TxMempoolInfo info_for_relay(const T &id, uint64_t last_sequence) const
Returns info for a transaction if its entry_sequence < last_sequence.
static constexpr uint64_t ACCEPTABLE_COST
How much linearization cost required for TxGraph clusters to have "acceptable" quality, if they cannot be optimally linearized with less cost.
Abstract view on the open txout dataset.
bool IsUnbroadcastTx(const Txid &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Returns whether a txid is in the unbroadcast set.
bool m_load_tried GUARDED_BY(cs)
double rollingMinimumFeeRate GUARDED_BY(cs)
uint64_t cachedInnerUsage GUARDED_BY(cs)
sum of all mempool tx's fees (NOT modified fee)
CTxMemPool::txiter TxHandle
uint64_t GetTotalTxSize() const EXCLUSIVE_LOCKS_REQUIRED(cs)
uint64_t m_sequence_number GUARDED_BY(cs)
minimum fee to get into the pool, decreases exponentially
boost::multi_index_container< CTxMemPoolEntry, CTxMemPoolEntry_Indices > indexed_transaction_set
An outpoint - a combination of a transaction hash and an index n into its vout.
const Txid txid
The prioritised transaction's txid.
#define Assume(val)
Assume is the identity function.
bool exists(const Txid &txid) const
std::vector< CTransactionRef > GetAddedTxns() const
std::optional< CAmount > modified_fee
The modified fee (base fee + delta) of this entry.
void Apply() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
uint64_t GetAndIncrementSequence() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Guards this internal counter for external reporting.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
void SkipBuilderChunk() const EXCLUSIVE_LOCKS_REQUIRED(cs)
FeePerWeight GetBlockBuilderChunk(std::vector< CTxMemPoolEntry::CTxMemPoolEntryRef > &entries) const EXCLUSIVE_LOCKS_REQUIRED(cs)
void Reset()
Clear m_temp_added and m_non_base_coins.
const std::unordered_set< COutPoint, SaltedOutpointHasher > & GetNonBaseCoins() const
Get all coins in m_non_base_coins.
CAmount GetTotalFee() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Fee rate in satoshis per virtualbyte: CAmount / vB the feerate is represented internally as FeeFrac...
bool exists(const Wtxid &wtxid) const
void PackageAddTransaction(const CTransactionRef &tx)
Add the coins created by this transaction.
CCoinsViewMemPool(CCoinsView *baseIn, const CTxMemPool &mempoolIn)
Options struct containing options for constructing a CTxMemPool.
CAmount m_total_fee GUARDED_BY(cs)
sum of all mempool tx's virtual sizes. Differs from serialized tx size since witness data is discount...
The basic transaction that is broadcasted on the network and contained in blocks. ...
CCoinsView backed by another CCoinsView.
CCoinsView that adds a memory cache for transactions to another CCoinsView.
const CTxMemPool & mempool
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
void addNewTransaction(CTxMemPool::txiter it) EXCLUSIVE_LOCKS_REQUIRED(cs)
CCoinsView that brings transactions from a mempool into view.
int64_t GetDescendantCount(const CTxMemPoolEntry &e) const
std::unordered_map< COutPoint, Coin, SaltedOutpointHasher > m_temp_added
Coins made available by transactions being validated.
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it...