Add a wtxid-index to the mempool

This commit is contained in:
Suhas Daftuar 2020-01-29 10:36:23 -05:00
parent 090d877160
commit 2b4b90aa8f
2 changed files with 44 additions and 12 deletions

View File

@ -726,12 +726,12 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
assert(innerUsage == cachedInnerUsage); assert(innerUsage == cachedInnerUsage);
} }
bool CTxMemPool::CompareDepthAndScore(const uint256& hasha, const uint256& hashb) bool CTxMemPool::CompareDepthAndScore(const uint256& hasha, const uint256& hashb, bool wtxid)
{ {
LOCK(cs); LOCK(cs);
indexed_transaction_set::const_iterator i = mapTx.find(hasha); indexed_transaction_set::const_iterator i = wtxid ? get_iter_from_wtxid(hasha) : mapTx.find(hasha);
if (i == mapTx.end()) return false; if (i == mapTx.end()) return false;
indexed_transaction_set::const_iterator j = mapTx.find(hashb); indexed_transaction_set::const_iterator j = wtxid ? get_iter_from_wtxid(hashb) : mapTx.find(hashb);
if (j == mapTx.end()) return true; if (j == mapTx.end()) return true;
uint64_t counta = i->GetCountWithAncestors(); uint64_t counta = i->GetCountWithAncestors();
uint64_t countb = j->GetCountWithAncestors(); uint64_t countb = j->GetCountWithAncestors();
@ -811,10 +811,10 @@ CTransactionRef CTxMemPool::get(const uint256& hash) const
return i->GetSharedTx(); return i->GetSharedTx();
} }
TxMempoolInfo CTxMemPool::info(const uint256& hash) const TxMempoolInfo CTxMemPool::info(const uint256& hash, bool wtxid) const
{ {
LOCK(cs); LOCK(cs);
indexed_transaction_set::const_iterator i = mapTx.find(hash); indexed_transaction_set::const_iterator i = (wtxid ? get_iter_from_wtxid(hash) : mapTx.find(hash));
if (i == mapTx.end()) if (i == mapTx.end())
return TxMempoolInfo(); return TxMempoolInfo();
return GetInfo(i); return GetInfo(i);
@ -917,8 +917,8 @@ bool CCoinsViewMemPool::GetCoin(const COutPoint &outpoint, Coin &coin) const {
size_t CTxMemPool::DynamicMemoryUsage() const { size_t CTxMemPool::DynamicMemoryUsage() const {
LOCK(cs); LOCK(cs);
// Estimate the overhead of mapTx to be 12 pointers + an allocation, as no exact formula for boost::multi_index_contained is implemented. // Estimate the overhead of mapTx to be 15 pointers + an allocation, as no exact formula for boost::multi_index_contained is implemented.
return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 12 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(mapLinks) + memusage::DynamicUsage(vTxHashes) + cachedInnerUsage; return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 15 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(mapLinks) + memusage::DynamicUsage(vTxHashes) + cachedInnerUsage;
} }
void CTxMemPool::RemoveUnbroadcastTx(const uint256& txid, const bool unchecked) { void CTxMemPool::RemoveUnbroadcastTx(const uint256& txid, const bool unchecked) {

View File

@ -198,6 +198,22 @@ struct mempoolentry_txid
} }
}; };
// extracts a transaction witness-hash from CTxMemPoolEntry or CTransactionRef
struct mempoolentry_wtxid
{
typedef uint256 result_type;
result_type operator() (const CTxMemPoolEntry &entry) const
{
return entry.GetTx().GetWitnessHash();
}
result_type operator() (const CTransactionRef& tx) const
{
return tx->GetWitnessHash();
}
};
/** \class CompareTxMemPoolEntryByDescendantScore /** \class CompareTxMemPoolEntryByDescendantScore
* *
* Sort an entry by max(score/size of entry's tx, score/size with all descendants). * Sort an entry by max(score/size of entry's tx, score/size with all descendants).
@ -318,6 +334,7 @@ public:
struct descendant_score {}; struct descendant_score {};
struct entry_time {}; struct entry_time {};
struct ancestor_score {}; struct ancestor_score {};
struct index_by_wtxid {};
class CBlockPolicyEstimator; class CBlockPolicyEstimator;
@ -383,8 +400,9 @@ public:
* *
* CTxMemPool::mapTx, and CTxMemPoolEntry bookkeeping: * CTxMemPool::mapTx, and CTxMemPoolEntry bookkeeping:
* *
* mapTx is a boost::multi_index that sorts the mempool on 4 criteria: * mapTx is a boost::multi_index that sorts the mempool on 5 criteria:
* - transaction hash * - transaction hash (txid)
* - witness-transaction hash (wtxid)
* - descendant feerate [we use max(feerate of tx, feerate of tx with all descendants)] * - descendant feerate [we use max(feerate of tx, feerate of tx with all descendants)]
* - time in mempool * - time in mempool
* - ancestor feerate [we use min(feerate of tx, feerate of tx with all unconfirmed ancestors)] * - ancestor feerate [we use min(feerate of tx, feerate of tx with all unconfirmed ancestors)]
@ -469,6 +487,12 @@ public:
boost::multi_index::indexed_by< boost::multi_index::indexed_by<
// sorted by txid // sorted by txid
boost::multi_index::hashed_unique<mempoolentry_txid, SaltedTxidHasher>, boost::multi_index::hashed_unique<mempoolentry_txid, SaltedTxidHasher>,
// sorted by wtxid
boost::multi_index::hashed_unique<
boost::multi_index::tag<index_by_wtxid>,
mempoolentry_wtxid,
SaltedTxidHasher
>,
// sorted by fee rate // sorted by fee rate
boost::multi_index::ordered_non_unique< boost::multi_index::ordered_non_unique<
boost::multi_index::tag<descendant_score>, boost::multi_index::tag<descendant_score>,
@ -586,7 +610,7 @@ public:
void clear(); void clear();
void _clear() EXCLUSIVE_LOCKS_REQUIRED(cs); //lock free void _clear() EXCLUSIVE_LOCKS_REQUIRED(cs); //lock free
bool CompareDepthAndScore(const uint256& hasha, const uint256& hashb); bool CompareDepthAndScore(const uint256& hasha, const uint256& hashb, bool wtxid=false);
void queryHashes(std::vector<uint256>& vtxid) const; void queryHashes(std::vector<uint256>& vtxid) const;
bool isSpent(const COutPoint& outpoint) const; bool isSpent(const COutPoint& outpoint) const;
unsigned int GetTransactionsUpdated() const; unsigned int GetTransactionsUpdated() const;
@ -689,14 +713,22 @@ public:
return totalTxSize; return totalTxSize;
} }
bool exists(const uint256& hash) const bool exists(const uint256& hash, bool wtxid=false) const
{ {
LOCK(cs); LOCK(cs);
if (wtxid) {
return (mapTx.get<index_by_wtxid>().count(hash) != 0);
}
return (mapTx.count(hash) != 0); return (mapTx.count(hash) != 0);
} }
CTransactionRef get(const uint256& hash) const; CTransactionRef get(const uint256& hash) const;
TxMempoolInfo info(const uint256& hash) const; txiter get_iter_from_wtxid(const uint256& wtxid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
{
AssertLockHeld(cs);
return mapTx.project<0>(mapTx.get<index_by_wtxid>().find(wtxid));
}
TxMempoolInfo info(const uint256& hash, bool wtxid=false) const;
std::vector<TxMempoolInfo> infoAll() const; std::vector<TxMempoolInfo> infoAll() const;
size_t DynamicMemoryUsage() const; size_t DynamicMemoryUsage() const;