Changeset View
Changeset View
Standalone View
Standalone View
src/txmempool.h
Show First 20 Lines • Show All 227 Lines • ▼ Show 20 Lines | struct update_lock_points { | ||||
void operator()(CTxMemPoolEntry &e) { e.UpdateLockPoints(lp); } | void operator()(CTxMemPoolEntry &e) { e.UpdateLockPoints(lp); } | ||||
private: | private: | ||||
const LockPoints &lp; | const LockPoints &lp; | ||||
}; | }; | ||||
// extracts a TxMemPoolEntry's transaction hash | // extracts a TxMemPoolEntry's transaction hash | ||||
struct mempoolentry_txid { | struct mempoolentry_txid { | ||||
typedef uint256 result_type; | typedef TxHash result_type; | ||||
result_type operator()(const CTxMemPoolEntry &entry) const { | result_type operator()(const CTxMemPoolEntry &entry) const { | ||||
return entry.GetTx().GetHash(); | return entry.GetTx().GetHash(); | ||||
} | } | ||||
}; | }; | ||||
/** \class CompareTxMemPoolEntryByDescendantScore | /** \class CompareTxMemPoolEntryByDescendantScore | ||||
* | * | ||||
* Sort an entry by max(score/size of entry's tx, score/size with all | * Sort an entry by max(score/size of entry's tx, score/size with all | ||||
▲ Show 20 Lines • Show All 271 Lines • ▼ Show 20 Lines | typedef boost::multi_index_container< | ||||
CompareTxMemPoolEntryByAncestorFee>>> | CompareTxMemPoolEntryByAncestorFee>>> | ||||
indexed_transaction_set; | indexed_transaction_set; | ||||
mutable CCriticalSection cs; | mutable CCriticalSection cs; | ||||
indexed_transaction_set mapTx; | indexed_transaction_set mapTx; | ||||
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<TxHash, 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().GetHash() < b->GetTx().GetHash(); | return a->GetTx().GetHash() < b->GetTx().GetHash(); | ||||
} | } | ||||
}; | }; | ||||
typedef std::set<txiter, CompareIteratorByHash> setEntries; | typedef std::set<txiter, CompareIteratorByHash> setEntries; | ||||
Show All 14 Lines | private: | ||||
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; | GetSortedDepthAndScore() const; | ||||
public: | public: | ||||
indirectmap<COutPoint, const CTransaction *> mapNextTx; | indirectmap<COutPoint, const CTransaction *> mapNextTx; | ||||
std::map<uint256, std::pair<double, Amount>> mapDeltas; | std::map<TxHash, std::pair<double, Amount>> mapDeltas; | ||||
/** Create a new CTxMemPool. | /** Create a new CTxMemPool. | ||||
*/ | */ | ||||
CTxMemPool(const CFeeRate &_minReasonableRelayFee); | CTxMemPool(const CFeeRate &_minReasonableRelayFee); | ||||
~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) { | ||||
nCheckFrequency = dFrequency * 4294967295.0; | nCheckFrequency = 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. | ||||
bool addUnchecked(const uint256 &hash, const CTxMemPoolEntry &entry, | bool addUnchecked(const TxHash &hash, const CTxMemPoolEntry &entry, | ||||
bool validFeeEstimate = true); | bool validFeeEstimate = true); | ||||
bool addUnchecked(const uint256 &hash, const CTxMemPoolEntry &entry, | bool addUnchecked(const TxHash &hash, const CTxMemPoolEntry &entry, | ||||
setEntries &setAncestors, bool validFeeEstimate = true); | setEntries &setAncestors, bool validFeeEstimate = true); | ||||
void removeRecursive( | void removeRecursive( | ||||
const CTransaction &tx, | const CTransaction &tx, | ||||
MemPoolRemovalReason reason = MemPoolRemovalReason::UNKNOWN); | MemPoolRemovalReason reason = MemPoolRemovalReason::UNKNOWN); | ||||
void removeForReorg(const CCoinsViewCache *pcoins, | void removeForReorg(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(); | ||||
bool CompareDepthAndScore(const uint256 &hasha, const uint256 &hashb); | bool CompareDepthAndScore(const TxHash &hasha, const TxHash &hashb); | ||||
void queryHashes(std::vector<uint256> &vtxid); | void queryHashes(std::vector<TxHash> &vtxhash); | ||||
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 | ||||
* block. | * block. | ||||
*/ | */ | ||||
bool HasNoInputsOf(const CTransaction &tx) const; | bool HasNoInputsOf(const CTransaction &tx) const; | ||||
/** Affect CreateNewBlock prioritisation of transactions */ | /** Affect CreateNewBlock prioritisation of transactions */ | ||||
void PrioritiseTransaction(const uint256 hash, const std::string strHash, | void PrioritiseTransaction(const TxHash hash, const std::string strHash, | ||||
double dPriorityDelta, const Amount nFeeDelta); | double dPriorityDelta, const Amount nFeeDelta); | ||||
void ApplyDeltas(const uint256 hash, double &dPriorityDelta, | void ApplyDeltas(const TxHash hash, double &dPriorityDelta, | ||||
Amount &nFeeDelta) const; | Amount &nFeeDelta) const; | ||||
void ClearPrioritisation(const uint256 hash); | void ClearPrioritisation(const TxHash hash); | ||||
public: | public: | ||||
/** | /** | ||||
* Remove a set of transactions from the mempool. If a transaction is in | * Remove a set of transactions from the mempool. If a transaction is in | ||||
* this set, then all in-mempool descendants must also be in the set, unless | * this set, then all in-mempool descendants must also be in the set, unless | ||||
* this transaction is being removed for being in a block. Set | * this transaction is being removed for being in a block. Set | ||||
* updateDescendants to true when removing a tx that was in a block, so that | * updateDescendants to true when removing a tx that was in a block, so that | ||||
* any in-mempool descendants have their ancestor state updated. | * any in-mempool descendants have their ancestor state updated. | ||||
*/ | */ | ||||
void | void | ||||
RemoveStaged(setEntries &stage, bool updateDescendants, | RemoveStaged(setEntries &stage, bool updateDescendants, | ||||
MemPoolRemovalReason reason = MemPoolRemovalReason::UNKNOWN); | MemPoolRemovalReason reason = MemPoolRemovalReason::UNKNOWN); | ||||
/** | /** | ||||
* When adding transactions from a disconnected block back to the mempool, | * When adding transactions from a disconnected block back to the mempool, | ||||
* new mempool entries may have children in the mempool (which is generally | * new mempool entries may have children in the mempool (which is generally | ||||
* not the case when otherwise adding transactions). | * not the case when otherwise adding transactions). | ||||
* UpdateTransactionsFromBlock() will find child transactions and update the | * UpdateTransactionsFromBlock() will find child transactions and update the | ||||
* descendant state for each transaction in hashesToUpdate (excluding any | * descendant state for each transaction in hashesToUpdate (excluding any | ||||
* child transactions present in hashesToUpdate, which are already accounted | * child transactions present in hashesToUpdate, which are already accounted | ||||
* for). Note: hashesToUpdate should be the set of transactions from the | * for). Note: hashesToUpdate should be the set of transactions from the | ||||
* disconnected block that have been accepted back into the mempool. | * disconnected block that have been accepted back into the mempool. | ||||
*/ | */ | ||||
void | void UpdateTransactionsFromBlock(const std::vector<TxHash> &hashesToUpdate); | ||||
UpdateTransactionsFromBlock(const std::vector<uint256> &hashesToUpdate); | |||||
/** | /** | ||||
* Try to calculate all in-mempool ancestors of entry. | * Try to calculate all in-mempool ancestors of entry. | ||||
* (these are all calculated including the tx itself) | * (these are all calculated including the tx itself) | ||||
* limitAncestorCount = max number of ancestors | * limitAncestorCount = max number of ancestors | ||||
* limitAncestorSize = max size of ancestors | * limitAncestorSize = max size of ancestors | ||||
* limitDescendantCount = max number of descendants any ancestor can have | * limitDescendantCount = max number of descendants any ancestor can have | ||||
* limitDescendantSize = max size of descendants any ancestor can have | * limitDescendantSize = max size of descendants any ancestor can have | ||||
Show All 33 Lines | void TrimToSize(size_t sizelimit, | ||||
std::vector<COutPoint> *pvNoSpendsRemaining = nullptr); | std::vector<COutPoint> *pvNoSpendsRemaining = nullptr); | ||||
/** Expire all transaction (and their dependencies) in the mempool older | /** Expire all transaction (and their dependencies) in the mempool older | ||||
* than time. Return the number of removed transactions. */ | * than time. Return the number of removed transactions. */ | ||||
int Expire(int64_t time); | int Expire(int64_t time); | ||||
/** Returns false if the transaction is in the mempool and not within the | /** Returns false if the transaction is in the mempool and not within the | ||||
* chain limit specified. */ | * chain limit specified. */ | ||||
bool TransactionWithinChainLimit(const uint256 &txid, | bool TransactionWithinChainLimit(const TxHash &txhash, | ||||
size_t chainLimit) const; | size_t chainLimit) const; | ||||
unsigned long size() { | unsigned long size() { | ||||
LOCK(cs); | LOCK(cs); | ||||
return mapTx.size(); | return mapTx.size(); | ||||
} | } | ||||
uint64_t GetTotalTxSize() { | uint64_t GetTotalTxSize() { | ||||
LOCK(cs); | LOCK(cs); | ||||
return totalTxSize; | return totalTxSize; | ||||
} | } | ||||
bool exists(uint256 hash) const { | bool exists(TxHash hash) const { | ||||
LOCK(cs); | LOCK(cs); | ||||
return mapTx.count(hash) != 0; | return mapTx.count(hash) != 0; | ||||
} | } | ||||
bool exists(const COutPoint &outpoint) const { | bool exists(const COutPoint &outpoint) const { | ||||
LOCK(cs); | LOCK(cs); | ||||
auto it = mapTx.find(outpoint.hash); | auto it = mapTx.find(outpoint.hash); | ||||
return it != mapTx.end() && outpoint.n < it->GetTx().vout.size(); | return it != mapTx.end() && outpoint.n < it->GetTx().vout.size(); | ||||
} | } | ||||
CTransactionRef get(const uint256 &hash) const; | CTransactionRef get(const TxHash &hash) const; | ||||
TxMempoolInfo info(const uint256 &hash) const; | TxMempoolInfo info(const TxHash &hash) const; | ||||
std::vector<TxMempoolInfo> infoAll() const; | std::vector<TxMempoolInfo> infoAll() const; | ||||
/** | /** | ||||
* Estimate fee rate needed to get into the next nBlocks. If no answer can | * Estimate fee rate needed to get into the next nBlocks. If no answer can | ||||
* be given at nBlocks, return an estimate at the lowest number of blocks | * be given at nBlocks, return an estimate at the lowest number of blocks | ||||
* where one can be given. | * where one can be given. | ||||
*/ | */ | ||||
CFeeRate estimateSmartFee(int nBlocks, | CFeeRate estimateSmartFee(int nBlocks, | ||||
Show All 33 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<uint256> &setExclude); | const std::set<TxHash> &setExclude); | ||||
/** 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); | ||||
/** 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); | ||||
/** | /** | ||||
* 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 | ||||
▲ Show 20 Lines • Show All 47 Lines • Show Last 20 Lines |