6 #ifndef BITCOIN_TXMEMPOOL_H 7 #define BITCOIN_TXMEMPOOL_H 26 #include <boost/multi_index_container.hpp> 27 #include <boost/multi_index/hashed_index.hpp> 28 #include <boost/multi_index/ordered_index.hpp> 29 #include <boost/multi_index/sequenced_index.hpp> 49 LockPoints() : height(0), time(0), maxInputBlock(nullptr) { }
56 bool operator()(
const std::reference_wrapper<T>& a,
const std::reference_wrapper<T>& b)
const 58 return a.get().GetTx().GetHash() < b.get().GetTx().GetHash();
63 return a->GetTx().GetHash() < b->GetTx().GetHash();
83 typedef std::set<CTxMemPoolEntryRef, CompareIteratorByHash>
Parents;
84 typedef std::set<CTxMemPoolEntryRef, CompareIteratorByHash>
Children;
115 int64_t _nTime,
unsigned int _entryHeight,
122 size_t GetTxSize()
const;
124 std::chrono::seconds
GetTime()
const {
return std::chrono::seconds{nTime}; }
132 void UpdateDescendantState(int64_t modifySize,
CAmount modifyFee, int64_t modifyCount);
134 void UpdateAncestorState(int64_t modifySize,
CAmount modifyFee, int64_t modifyCount, int64_t modifySigOps);
137 void UpdateFeeDelta(int64_t feeDelta);
165 modifySize(_modifySize), modifyFee(_modifyFee), modifyCount(_modifyCount)
180 modifySize(_modifySize), modifyFee(_modifyFee), modifyCount(_modifyCount), modifySigOpsCost(_modifySigOpsCost)
224 return tx->GetHash();
239 return tx->GetWitnessHash();
253 double a_mod_fee, a_size, b_mod_fee, b_size;
255 GetModFeeAndSize(a, a_mod_fee, a_size);
256 GetModFeeAndSize(b, b_mod_fee, b_size);
259 double f1 = a_mod_fee * b_size;
260 double f2 = a_size * b_mod_fee;
326 double a_mod_fee, a_size, b_mod_fee, b_size;
328 GetModFeeAndSize(a, a_mod_fee, a_size);
329 GetModFeeAndSize(b, b_mod_fee, b_size);
332 double f1 = a_mod_fee * b_size;
333 double f2 = a_size * b_mod_fee;
336 return a.GetTx().GetHash() < b.GetTx().GetHash();
342 template <
typename T>
347 double f1 = (double)a.GetModifiedFee() * a.GetSizeWithAncestors();
348 double f2 = (double)a.GetModFeesWithAncestors() * a.GetTxSize();
351 mod_fee = a.GetModFeesWithAncestors();
352 size = a.GetSizeWithAncestors();
354 mod_fee = a.GetModifiedFee();
355 size = a.GetTxSize();
405 const uint64_t k0,
k1;
507 mutable uint64_t m_sequence_number{1};
515 static const int ROLLING_FEE_HALFLIFE = 60 * 60 * 12;
517 typedef boost::multi_index_container<
519 boost::multi_index::indexed_by<
521 boost::multi_index::hashed_unique<mempoolentry_txid, SaltedTxidHasher>,
523 boost::multi_index::hashed_unique<
524 boost::multi_index::tag<index_by_wtxid>,
529 boost::multi_index::ordered_non_unique<
530 boost::multi_index::tag<descendant_score>,
531 boost::multi_index::identity<CTxMemPoolEntry>,
535 boost::multi_index::ordered_non_unique<
536 boost::multi_index::tag<entry_time>,
537 boost::multi_index::identity<CTxMemPoolEntry>,
541 boost::multi_index::ordered_non_unique<
542 boost::multi_index::tag<ancestor_score>,
543 boost::multi_index::identity<CTxMemPoolEntry>,
579 using txiter = indexed_transaction_set::nth_index<0>::type::const_iterator;
580 std::vector<std::pair<uint256, txiter>> vTxHashes
GUARDED_BY(cs);
586 typedef std::map<txiter, setEntries, CompareIteratorByHash>
cacheMap;
592 std::vector<indexed_transaction_set::const_iterator> GetSortedDepthAndScore() const EXCLUSIVE_LOCKS_REQUIRED(cs);
597 std::set<
uint256> m_unbroadcast_txids GUARDED_BY(cs);
614 void setSanityCheck(
double dFrequency = 1.0) {
LOCK(cs); nCheckFrequency =
static_cast<uint32_t
>(dFrequency * 4294967295.0); }
623 void addUnchecked(
const CTxMemPoolEntry& entry,
bool validFeeEstimate =
true) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main);
624 void addUnchecked(const CTxMemPoolEntry& entry, setEntries& setAncestors,
bool validFeeEstimate = true) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main);
627 void removeForReorg(const
CCoinsViewCache* pcoins,
unsigned int nMemPoolHeight,
int flags) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main);
628 void removeConflicts(const
CTransaction& tx) EXCLUSIVE_LOCKS_REQUIRED(cs);
629 void removeForBlock(const
std::vector<
CTransactionRef>& vtx,
unsigned int nBlockHeight) EXCLUSIVE_LOCKS_REQUIRED(cs);
632 void _clear() EXCLUSIVE_LOCKS_REQUIRED(cs);
633 bool CompareDepthAndScore(const
uint256& hasha, const
uint256& hashb,
bool wtxid=false);
634 void queryHashes(
std::vector<
uint256>& vtxid) const;
635 bool isSpent(const
COutPoint& outpoint) const;
636 unsigned int GetTransactionsUpdated() const;
637 void AddTransactionsUpdated(
unsigned int n);
642 bool HasNoInputsOf(const
CTransaction& tx) const EXCLUSIVE_LOCKS_REQUIRED(cs);
645 void PrioritiseTransaction(const
uint256& hash, const
CAmount& nFeeDelta);
646 void ApplyDelta(const
uint256& hash,
CAmount &nFeeDelta) const EXCLUSIVE_LOCKS_REQUIRED(cs);
647 void ClearPrioritisation(const
uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs);
656 setEntries GetIterSet(const
std::set<
uint256>& hashes) const EXCLUSIVE_LOCKS_REQUIRED(cs);
665 void RemoveStaged(setEntries& stage,
bool updateDescendants,
MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs);
688 bool CalculateMemPoolAncestors(const CTxMemPoolEntry& entry, setEntries& setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize,
std::
string& errString,
bool fSearchForParents = true) const EXCLUSIVE_LOCKS_REQUIRED(cs);
693 void CalculateDescendants(
txiter it, setEntries& setDescendants) const EXCLUSIVE_LOCKS_REQUIRED(cs);
701 CFeeRate GetMinFee(
size_t sizelimit) const;
707 void TrimToSize(
size_t sizelimit,
std::vector<
COutPoint>* pvNoSpendsRemaining =
nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs);
710 int Expire(
std::chrono::seconds
time) EXCLUSIVE_LOCKS_REQUIRED(cs);
716 void GetTransactionAncestry(const
uint256& txid,
size_t& ancestors,
size_t& descendants) const;
719 bool IsLoaded() const;
722 void SetIsLoaded(
bool loaded);
724 unsigned long size()
const 742 return (mapTx.count(gtxid.
GetHash()) != 0);
754 std::vector<TxMempoolInfo> infoAll()
const;
756 size_t DynamicMemoryUsage()
const;
764 if (exists(txid)) m_unbroadcast_txids.insert(txid);
768 void RemoveUnbroadcastTx(
const uint256& txid,
const bool unchecked =
false);
774 return m_unbroadcast_txids;
781 return m_unbroadcast_txids.count(txid) != 0;
786 return m_sequence_number++;
790 return m_sequence_number;
807 void UpdateForDescendants(
txiter updateIt,
808 cacheMap &cachedDescendants,
817 void UpdateForRemoveFromMempool(
const setEntries &entriesToRemove,
bool updateDescendants)
EXCLUSIVE_LOCKS_REQUIRED(cs);
858 EpochGuard GetFreshEpoch() const EXCLUSIVE_LOCKS_REQUIRED(cs);
868 bool visited(
txiter it) const EXCLUSIVE_LOCKS_REQUIRED(cs) {
869 assert(m_has_epoch_guard);
870 bool ret = it->m_epoch >= m_epoch;
871 it->m_epoch = std::max(it->m_epoch, m_epoch);
876 assert(m_has_epoch_guard);
877 return !it || visited(*it);
900 bool GetCoin(
const COutPoint &outpoint,
Coin &coin)
const override;
923 typedef boost::multi_index_container<
925 boost::multi_index::indexed_by<
927 boost::multi_index::hashed_unique<
928 boost::multi_index::tag<txid_index>,
933 boost::multi_index::sequenced<
934 boost::multi_index::tag<insertion_order>
950 uint64_t cachedInnerUsage = 0;
955 return memusage::MallocUsage(
sizeof(CTransactionRef) + 6 *
sizeof(
void*)) * queuedTx.size() + cachedInnerUsage;
968 if (queuedTx.empty()) {
971 for (
auto const &tx : vtx) {
972 auto it = queuedTx.find(tx->GetHash());
973 if (
it != queuedTx.end()) {
981 void removeEntry(indexed_disconnected_transactions::index<insertion_order>::type::iterator entry)
989 cachedInnerUsage = 0;
994 #endif // BITCOIN_TXMEMPOOL_H
std::shared_ptr< const CTransaction > CTransactionRef
peer m_getdata_requests erase(peer.m_getdata_requests.begin(), it)
size_t vTxHashesIdx
Index in mempool's vTxHashes.
const bool spendsCoinbase
keep track of transactions that spend a coinbase
uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256 &val)
Optimized SipHash-2-4 implementation for uint256.
Information about a mempool transaction.
CAmount GetModFeesWithAncestors() const
update_fee_delta(int64_t _feeDelta)
CAmount nModFeesWithDescendants
... and total fees (all including us)
void UpdateLockPoints(const LockPoints &lp)
std::deque< CInv >::iterator it
unsigned int GetHeight() const
indexed_transaction_set::nth_index< 0 >::type::const_iterator txiter
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
uint64_t GetCountWithAncestors() const
uint64_t GetCountWithDescendants() const
~DisconnectedBlockTransactions()
size_t GetTxWeight() const
Removed in size limiting.
bool exists(const GenTxid >xid) const
const unsigned int entryHeight
Chain height when entering the mempool.
bool operator()(const CTxMemPoolEntry &a, const CTxMemPoolEntry &b) const
std::chrono::seconds GetTime() const
uint64_t GetSequence() const EXCLUSIVE_LOCKS_REQUIRED(cs)
uint64_t m_epoch
epoch when last touched, useful for graph algorithms
size_t DynamicMemoryUsage() const
std::set< txiter, CompareIteratorByHash > setEntries
void addTransaction(const CTransactionRef &tx)
size_t vsize
Virtual size of the transaction.
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal...
std::atomic< unsigned int > nTransactionsUpdated
Used by getblocktemplate to trigger CreateNewBlock() invocation.
const int64_t nTime
Local time when entering the mempool.
void UpdateAncestorState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount, int64_t modifySigOps)
uint64_t nCountWithDescendants
number of descendant transactions
int64_t lastRollingFeeUpdate
const LockPoints & GetLockPoints() const
const Children & GetMemPoolChildrenConst() const
bool operator()(const CTxMemPoolEntry &a, const CTxMemPoolEntry &b) const
int64_t nFeeDelta
The fee delta.
update_descendant_state(int64_t _modifySize, CAmount _modifyFee, int64_t _modifyCount)
CTransactionRef tx
The transaction itself.
disconnectpool queuedTx clear()
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
boost::multi_index_container< CTransactionRef, boost::multi_index::indexed_by< boost::multi_index::hashed_unique< boost::multi_index::tag< txid_index >, mempoolentry_txid, SaltedTxidHasher >, boost::multi_index::sequenced< boost::multi_index::tag< insertion_order > > > > indexed_disconnected_transactions
int64_t CAmount
Amount in satoshis (Can be negative)
uint64_t GetSizeWithDescendants() const
pool TrimToSize(limit,&vNoSpendsRemaining)
bool blockSinceLastRollingFeeBump
Removed for reorganization.
indexed_disconnected_transactions queuedTx
static const uint32_t MEMPOOL_HEIGHT
Fake height value used in Coin to signify they are only in the memory pool (since 0...
const CAmount & GetFee() const
int64_t nSigOpCostWithAncestors
const size_t nTxWeight
... and avoid recomputing tx weight (also used for GetTxSize())
bool exists(const uint256 &txid) const
std::set< CTxMemPoolEntryRef, CompareIteratorByHash > Parents
void AddUnbroadcastTx(const uint256 &txid)
Adds a transaction to the unbroadcast set.
void UpdateFeeDelta(int64_t feeDelta)
bool operator()(const std::reference_wrapper< T > &a, const std::reference_wrapper< T > &b) const
CTransactionRef GetSharedTx() const
uint64_t nSizeWithAncestors
int64_t feeDelta
Used for determining the priority of the transaction for mining in a block.
Abstract view on the open txout dataset.
void removeForBlock(const std::vector< CTransactionRef > &vtx)
The BlockPolicyEstimator is used for estimating the feerate needed for a transaction to be included i...
Removed for conflict with in-block transaction.
DisconnectedBlockTransactions.
void GetModFeeAndSize(const CTxMemPoolEntry &a, double &mod_fee, double &size) const
size_t DynamicMemoryUsage() const
CAmount GetModFeesWithDescendants() const
AssertLockHeld(mempool.cs)
void GetModFeeAndSize(const T &a, double &mod_fee, double &size) const
Parents & GetMemPoolParents() const
mempool UpdateTransactionsFromBlock(vHashUpdate)
Children & GetMemPoolChildren() const
int64_t GetSigOpCost() const
bool GetSpendsCoinbase() const
bool operator()(const T &a, const T &b) const
uint64_t cachedInnerUsage
sum of dynamic memory usage of all the map elements (NOT the maps themselves)
Sort an entry by max(score/size of entry's tx, score/size with all descendants).
uint64_t GetTotalTxSize() const EXCLUSIVE_LOCKS_REQUIRED(cs)
CAmount nModFeesWithAncestors
An outpoint - a combination of a transaction hash and an index n into its vout.
uint64_t nSizeWithDescendants
... and size
const uint256 & GetWitnessHash() const
uint64_t GetSizeWithAncestors() const
const size_t nUsageSize
... and total memory usage
uint64_t totalTxSize
sum of all mempool tx's virtual sizes. Differs from serialized tx size since witness data is discount...
bool operator()(const CTxMemPoolEntry &a, const CTxMemPoolEntry &b) const
static size_t MallocUsage(size_t alloc)
Compute the total memory used by allocating alloc bytes.
const uint256 & GetHash() const
const int64_t sigOpCost
Total sigop cost.
bool visited(Optional< txiter > it) const EXCLUSIVE_LOCKS_REQUIRED(cs)
const CTransaction & GetTx() const
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 ...
int64_t GetModifiedFee() const
boost::multi_index_container< CTxMemPoolEntry, boost::multi_index::indexed_by< boost::multi_index::hashed_unique< mempoolentry_txid, SaltedTxidHasher >, boost::multi_index::hashed_unique< boost::multi_index::tag< index_by_wtxid >, mempoolentry_wtxid, SaltedTxidHasher >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< descendant_score >, boost::multi_index::identity< CTxMemPoolEntry >, CompareTxMemPoolEntryByDescendantScore >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< entry_time >, boost::multi_index::identity< CTxMemPoolEntry >, CompareTxMemPoolEntryByEntryTime >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< ancestor_score >, boost::multi_index::identity< CTxMemPoolEntry >, CompareTxMemPoolEntryByAncestorFee > > > indexed_transaction_set
std::map< txiter, setEntries, CompareIteratorByHash > cacheMap
The block chain is a tree shaped structure starting with the genesis block at the root...
LockPoints lockPoints
Track the height and time at which tx was final.
void UpdateDescendantState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount)
update_ancestor_state(int64_t _modifySize, CAmount _modifyFee, int64_t _modifyCount, int64_t _modifySigOpsCost)
std::reference_wrapper< const CTxMemPoolEntry > CTxMemPoolEntryRef
std::set< uint256 > GetUnbroadcastTxs() const
Returns transactions in unbroadcast set.
txiter get_iter_from_wtxid(const uint256 &wtxid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
std::set< CTxMemPoolEntryRef, CompareIteratorByHash > Children
uint64_t nCountWithAncestors
Fee rate in satoshis per kilobyte: CAmount / kB.
const CAmount nFee
Cached to avoid expensive parent-transaction lookups.
CAmount fee
Fee of the transaction.
static size_t RecursiveDynamicUsage(const CScript &script)
update_lock_points(const LockPoints &_lp)
const uint256 & GetHash() const
int64_t GetSigOpCostWithAncestors() const
pool addUnchecked(CTxMemPoolEntry( tx, nFee, nTime, nHeight, spendsCoinbase, sigOpCost, lp))
bool operator()(const T &a, const T &b) const
The basic transaction that is broadcasted on the network and contained in blocks. ...
CCoinsView backed by another CCoinsView.
boost::optional< T > Optional
Substitute for C++17 std::optional.
bool IsUnbroadcastTx(const uint256 &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Returns whether a txid is in the unbroadcast set.
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Sort by feerate of entry (fee/size) in descending order This is only used for transaction relay...
size_t operator()(const uint256 &txid) const
const CTxMemPool & mempool
CBlockPolicyEstimator * minerPolicyEstimator
std::chrono::seconds m_time
Time the transaction entered the mempool.
CBlockIndex * maxInputBlock
double rollingMinimumFeeRate
minimum fee to get into the pool, decreases exponentially
CCoinsView that brings transactions from a mempool into view.
A generic txid reference (txid or wtxid).
EpochGuard: RAII-style guard for using epoch-based graph traversal algorithms.
void removeEntry(indexed_disconnected_transactions::index< insertion_order >::type::iterator entry)
const Parents & GetMemPoolParentsConst() const
bool m_is_loaded GUARDED_BY(cs)
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it...