Changeset View
Changeset View
Standalone View
Standalone View
src/txmempool.h
Show First 20 Lines • Show All 464 Lines • ▼ Show 20 Lines | |||||
* properly update the descendant information for a tx being added from a | * properly update the descendant information for a tx being added from a | ||||
* disconnected block. If we would exceed the limit, then we instead mark the | * disconnected block. If we would exceed the limit, then we instead mark the | ||||
* entry as "dirty", and set the feerate for sorting purposes to be equal the | * entry as "dirty", and set the feerate for sorting purposes to be equal the | ||||
* feerate of the transaction without any descendants. | * feerate of the transaction without any descendants. | ||||
*/ | */ | ||||
class CTxMemPool { | class CTxMemPool { | ||||
private: | private: | ||||
//!< Value n means that n times in 2^32 we check. | //!< Value n means that n times in 2^32 we check. | ||||
uint32_t nCheckFrequency; | uint32_t nCheckFrequency GUARDED_BY(cs); | ||||
unsigned int nTransactionsUpdated; | unsigned int nTransactionsUpdated; | ||||
//!< sum of all mempool tx's virtual sizes. | //!< sum of all mempool tx's virtual sizes. | ||||
uint64_t totalTxSize; | uint64_t totalTxSize; | ||||
//!< sum of dynamic memory usage of all the map elements (NOT the maps | //!< sum of dynamic memory usage of all the map elements (NOT the maps | ||||
//! themselves) | //! themselves) | ||||
uint64_t cachedInnerUsage; | uint64_t cachedInnerUsage; | ||||
Show All 31 Lines | typedef boost::multi_index_container< | ||||
// sorted by fee rate with ancestors | // sorted by fee rate with ancestors | ||||
boost::multi_index::ordered_non_unique< | boost::multi_index::ordered_non_unique< | ||||
boost::multi_index::tag<ancestor_score>, | boost::multi_index::tag<ancestor_score>, | ||||
boost::multi_index::identity<CTxMemPoolEntry>, | boost::multi_index::identity<CTxMemPoolEntry>, | ||||
CompareTxMemPoolEntryByAncestorFee>>> | CompareTxMemPoolEntryByAncestorFee>>> | ||||
indexed_transaction_set; | indexed_transaction_set; | ||||
mutable CCriticalSection cs; | mutable CCriticalSection cs; | ||||
indexed_transaction_set mapTx; | indexed_transaction_set mapTx GUARDED_BY(cs); | ||||
typedef indexed_transaction_set::nth_index<0>::type::iterator txiter; | typedef indexed_transaction_set::nth_index<0>::type::iterator txiter; | ||||
//!< All tx hashes/entries in mapTx, in random order | //!< All tx hashes/entries in mapTx, in random order | ||||
std::vector<std::pair<uint256, txiter>> vTxHashes; | std::vector<std::pair<uint256, txiter>> vTxHashes; | ||||
struct CompareIteratorByHash { | struct CompareIteratorByHash { | ||||
bool operator()(const txiter &a, const txiter &b) const { | bool operator()(const txiter &a, const txiter &b) const { | ||||
return a->GetTx().GetId() < b->GetTx().GetId(); | return a->GetTx().GetId() < b->GetTx().GetId(); | ||||
} | } | ||||
}; | }; | ||||
typedef std::set<txiter, CompareIteratorByHash> setEntries; | typedef std::set<txiter, CompareIteratorByHash> setEntries; | ||||
const setEntries &GetMemPoolParents(txiter entry) const; | const setEntries &GetMemPoolParents(txiter entry) const | ||||
const setEntries &GetMemPoolChildren(txiter entry) const; | EXCLUSIVE_LOCKS_REQUIRED(cs); | ||||
const setEntries &GetMemPoolChildren(txiter entry) const | |||||
EXCLUSIVE_LOCKS_REQUIRED(cs); | |||||
private: | private: | ||||
typedef std::map<txiter, setEntries, CompareIteratorByHash> cacheMap; | typedef std::map<txiter, setEntries, CompareIteratorByHash> cacheMap; | ||||
struct TxLinks { | struct TxLinks { | ||||
setEntries parents; | setEntries parents; | ||||
setEntries children; | setEntries children; | ||||
}; | }; | ||||
typedef std::map<txiter, TxLinks, CompareIteratorByHash> txlinksMap; | typedef std::map<txiter, TxLinks, CompareIteratorByHash> txlinksMap; | ||||
txlinksMap mapLinks; | txlinksMap mapLinks; | ||||
void UpdateParent(txiter entry, txiter parent, bool add); | void UpdateParent(txiter entry, txiter parent, bool add); | ||||
void UpdateChild(txiter entry, txiter child, bool add); | void UpdateChild(txiter entry, txiter child, bool add); | ||||
std::vector<indexed_transaction_set::const_iterator> | std::vector<indexed_transaction_set::const_iterator> | ||||
GetSortedDepthAndScore() const EXCLUSIVE_LOCKS_REQUIRED(cs); | GetSortedDepthAndScore() const EXCLUSIVE_LOCKS_REQUIRED(cs); | ||||
public: | public: | ||||
indirectmap<COutPoint, const CTransaction *> mapNextTx; | indirectmap<COutPoint, const CTransaction *> mapNextTx GUARDED_BY(cs); | ||||
std::map<uint256, TXModifier> mapDeltas; | std::map<uint256, TXModifier> mapDeltas; | ||||
/** Create a new CTxMemPool. | /** | ||||
* Create a new CTxMemPool. | |||||
*/ | */ | ||||
CTxMemPool(); | CTxMemPool(); | ||||
~CTxMemPool(); | ~CTxMemPool(); | ||||
/** | /** | ||||
* If sanity-checking is turned on, check makes sure the pool is consistent | * If sanity-checking is turned on, check makes sure the pool is consistent | ||||
* (does not contain two transactions that spend the same inputs, all inputs | * (does not contain two transactions that spend the same inputs, all inputs | ||||
* are in the mapNextTx array). If sanity-checking is turned off, check does | * are in the mapNextTx array). If sanity-checking is turned off, check does | ||||
* nothing. | * nothing. | ||||
*/ | */ | ||||
void check(const CCoinsViewCache *pcoins) const; | void check(const CCoinsViewCache *pcoins) const; | ||||
void setSanityCheck(double dFrequency = 1.0) { | void setSanityCheck(double dFrequency = 1.0) { | ||||
LOCK(cs); | |||||
nCheckFrequency = static_cast<uint32_t>(dFrequency * 4294967295.0); | nCheckFrequency = static_cast<uint32_t>(dFrequency * 4294967295.0); | ||||
} | } | ||||
// addUnchecked must updated state for all ancestors of a given transaction, | // addUnchecked must updated state for all ancestors of a given transaction, | ||||
// to track size/count of descendant transactions. First version of | // to track size/count of descendant transactions. First version of | ||||
// addUnchecked can be used to have it call CalculateMemPoolAncestors(), and | // addUnchecked can be used to have it call CalculateMemPoolAncestors(), and | ||||
// then invoke the second version. | // then invoke the second version. | ||||
// Note that addUnchecked is ONLY called from ATMP outside of tests | // Note that addUnchecked is ONLY called from ATMP outside of tests | ||||
Show All 9 Lines | public: | ||||
void removeForReorg(const Config &config, const CCoinsViewCache *pcoins, | void removeForReorg(const Config &config, const CCoinsViewCache *pcoins, | ||||
unsigned int nMemPoolHeight, int flags); | unsigned int nMemPoolHeight, int flags); | ||||
void removeConflicts(const CTransaction &tx); | void removeConflicts(const CTransaction &tx); | ||||
void removeForBlock(const std::vector<CTransactionRef> &vtx, | void removeForBlock(const std::vector<CTransactionRef> &vtx, | ||||
unsigned int nBlockHeight); | unsigned int nBlockHeight); | ||||
void clear(); | void clear(); | ||||
// lock free | // lock free | ||||
void _clear(); | void _clear() EXCLUSIVE_LOCKS_REQUIRED(cs); | ||||
bool CompareDepthAndScore(const uint256 &hasha, const uint256 &hashb); | bool CompareDepthAndScore(const uint256 &hasha, const uint256 &hashb); | ||||
void queryHashes(std::vector<uint256> &vtxid); | void queryHashes(std::vector<uint256> &vtxid); | ||||
bool isSpent(const COutPoint &outpoint); | bool isSpent(const COutPoint &outpoint); | ||||
unsigned int GetTransactionsUpdated() const; | unsigned int GetTransactionsUpdated() const; | ||||
void AddTransactionsUpdated(unsigned int n); | void AddTransactionsUpdated(unsigned int n); | ||||
/** | /** | ||||
* Check that none of this transactions inputs are in the mempool, and thus | * Check that none of this transactions inputs are in the mempool, and thus | ||||
* the tx is not dependent on other mempool transactions to be included in a | * the tx is not dependent on other mempool transactions to be included in a | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | bool CalculateMemPoolAncestors( | ||||
uint64_t limitDescendantCount, uint64_t limitDescendantSize, | uint64_t limitDescendantCount, uint64_t limitDescendantSize, | ||||
std::string &errString, bool fSearchForParents = true) const; | std::string &errString, bool fSearchForParents = true) const; | ||||
/** | /** | ||||
* Populate setDescendants with all in-mempool descendants of hash. | * Populate setDescendants with all in-mempool descendants of hash. | ||||
* Assumes that setDescendants includes all in-mempool descendants of | * Assumes that setDescendants includes all in-mempool descendants of | ||||
* anything already in it. | * anything already in it. | ||||
*/ | */ | ||||
void CalculateDescendants(txiter it, setEntries &setDescendants) const; | void CalculateDescendants(txiter it, setEntries &setDescendants) const | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs); | |||||
/** | /** | ||||
* The minimum fee to get into the mempool, which may itself not be enough | * The minimum fee to get into the mempool, which may itself not be enough | ||||
* for larger-sized transactions. The incrementalRelayFee policy variable is | * for larger-sized transactions. The incrementalRelayFee policy variable is | ||||
* used to bound the time it takes the fee rate to go back down all the way | * used to bound the time it takes the fee rate to go back down all the way | ||||
* to 0. When the feerate would otherwise be half of this, it is set to 0 | * to 0. When the feerate would otherwise be half of this, it is set to 0 | ||||
* instead. | * instead. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | private: | ||||
* the mempool after the transaction being updated and hence their state is | * the mempool after the transaction being updated and hence their state is | ||||
* already reflected in the parent state). | * already reflected in the parent state). | ||||
* | * | ||||
* cachedDescendants will be updated with the descendants of the transaction | * cachedDescendants will be updated with the descendants of the transaction | ||||
* being updated, so that future invocations don't need to walk the same | * being updated, so that future invocations don't need to walk the same | ||||
* transaction again, if encountered in another transaction chain. | * transaction again, if encountered in another transaction chain. | ||||
*/ | */ | ||||
void UpdateForDescendants(txiter updateIt, cacheMap &cachedDescendants, | void UpdateForDescendants(txiter updateIt, cacheMap &cachedDescendants, | ||||
const std::set<TxId> &setExclude); | const std::set<TxId> &setExclude) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs); | |||||
/** | /** | ||||
* Update ancestors of hash to add/remove it as a descendant transaction. | * Update ancestors of hash to add/remove it as a descendant transaction. | ||||
*/ | */ | ||||
void UpdateAncestorsOf(bool add, txiter hash, setEntries &setAncestors); | void UpdateAncestorsOf(bool add, txiter hash, setEntries &setAncestors) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs); | |||||
/** Set ancestor state for an entry */ | /** Set ancestor state for an entry */ | ||||
void UpdateEntryForAncestors(txiter it, const setEntries &setAncestors); | void UpdateEntryForAncestors(txiter it, const setEntries &setAncestors) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs); | |||||
/** | /** | ||||
* For each transaction being removed, update ancestors and any direct | * For each transaction being removed, update ancestors and any direct | ||||
* children. If updateDescendants is true, then also update in-mempool | * children. If updateDescendants is true, then also update in-mempool | ||||
* descendants' ancestor state. | * descendants' ancestor state. | ||||
*/ | */ | ||||
void UpdateForRemoveFromMempool(const setEntries &entriesToRemove, | void UpdateForRemoveFromMempool(const setEntries &entriesToRemove, | ||||
bool updateDescendants); | bool updateDescendants) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs); | |||||
/** Sever link between specified transaction and direct children. */ | /** Sever link between specified transaction and direct children. */ | ||||
void UpdateChildrenForRemoval(txiter entry); | void UpdateChildrenForRemoval(txiter entry) EXCLUSIVE_LOCKS_REQUIRED(cs); | ||||
/** | /** | ||||
* Before calling removeUnchecked for a given transaction, | * Before calling removeUnchecked for a given transaction, | ||||
* UpdateForRemoveFromMempool must be called on the entire (dependent) set | * UpdateForRemoveFromMempool must be called on the entire (dependent) set | ||||
* of transactions being removed at the same time. We use each | * of transactions being removed at the same time. We use each | ||||
* CTxMemPoolEntry's setMemPoolParents in order to walk ancestors of a given | * CTxMemPoolEntry's setMemPoolParents in order to walk ancestors of a given | ||||
* transaction that is removed, so we can't remove intermediate transactions | * transaction that is removed, so we can't remove intermediate transactions | ||||
* in a chain before we've updated all the state for the removal. | * in a chain before we've updated all the state for the removal. | ||||
*/ | */ | ||||
void removeUnchecked(txiter entry, MemPoolRemovalReason reason = | void | ||||
MemPoolRemovalReason::UNKNOWN); | removeUnchecked(txiter entry, | ||||
MemPoolRemovalReason reason = MemPoolRemovalReason::UNKNOWN) | |||||
EXCLUSIVE_LOCKS_REQUIRED(cs); | |||||
}; | }; | ||||
/** | /** | ||||
* CCoinsView that brings transactions from a memorypool into view. | * CCoinsView that brings transactions from a memorypool into view. | ||||
* It does not check for spendings by memory pool transactions. | * It does not check for spendings by memory pool transactions. | ||||
*/ | */ | ||||
class CCoinsViewMemPool : public CCoinsViewBacked { | class CCoinsViewMemPool : public CCoinsViewBacked { | ||||
protected: | protected: | ||||
▲ Show 20 Lines • Show All 143 Lines • Show Last 20 Lines |