aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSuhas Daftuar <sdaftuar@gmail.com>2020-01-29 10:36:23 -0500
committerJohn Newbery <john@johnnewbery.com>2020-09-24 13:24:10 +0100
commit4df3d139b7261de33c070691f76a535b8b17433a (patch)
tree5f69c9ef206c659012770ffb0758d3b63d041b03
parent80aa83aa406447d9b0932301b37966a30d0e1b6e (diff)
downloadbitcoin-4df3d139b7261de33c070691f76a535b8b17433a.tar.xz
Add a wtxid-index to the mempool
-rw-r--r--src/txmempool.cpp14
-rw-r--r--src/txmempool.h42
2 files changed, 44 insertions, 12 deletions
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index c14417a847..8de225ba19 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -724,12 +724,12 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
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);
- 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;
- 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;
uint64_t counta = i->GetCountWithAncestors();
uint64_t countb = j->GetCountWithAncestors();
@@ -809,10 +809,10 @@ CTransactionRef CTxMemPool::get(const uint256& hash) const
return i->GetSharedTx();
}
-TxMempoolInfo CTxMemPool::info(const uint256& hash) const
+TxMempoolInfo CTxMemPool::info(const uint256& hash, bool wtxid) const
{
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())
return TxMempoolInfo();
return GetInfo(i);
@@ -915,8 +915,8 @@ bool CCoinsViewMemPool::GetCoin(const COutPoint &outpoint, Coin &coin) const {
size_t CTxMemPool::DynamicMemoryUsage() const {
LOCK(cs);
- // Estimate the overhead of mapTx to be 12 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;
+ // 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) + 15 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(mapLinks) + memusage::DynamicUsage(vTxHashes) + cachedInnerUsage;
}
void CTxMemPool::RemoveStaged(setEntries &stage, bool updateDescendants, MemPoolRemovalReason reason) {
diff --git a/src/txmempool.h b/src/txmempool.h
index 3dae0a04c7..40986f13a3 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -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
*
* 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 entry_time {};
struct ancestor_score {};
+struct index_by_wtxid {};
class CBlockPolicyEstimator;
@@ -383,8 +400,9 @@ public:
*
* CTxMemPool::mapTx, and CTxMemPoolEntry bookkeeping:
*
- * mapTx is a boost::multi_index that sorts the mempool on 4 criteria:
- * - transaction hash
+ * mapTx is a boost::multi_index that sorts the mempool on 5 criteria:
+ * - transaction hash (txid)
+ * - witness-transaction hash (wtxid)
* - descendant feerate [we use max(feerate of tx, feerate of tx with all descendants)]
* - time in mempool
* - 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<
// sorted by txid
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
boost::multi_index::ordered_non_unique<
boost::multi_index::tag<descendant_score>,
@@ -583,7 +607,7 @@ public:
void clear();
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;
bool isSpent(const COutPoint& outpoint) const;
unsigned int GetTransactionsUpdated() const;
@@ -686,14 +710,22 @@ public:
return totalTxSize;
}
- bool exists(const uint256& hash) const
+ bool exists(const uint256& hash, bool wtxid=false) const
{
LOCK(cs);
+ if (wtxid) {
+ return (mapTx.get<index_by_wtxid>().count(hash) != 0);
+ }
return (mapTx.count(hash) != 0);
}
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;
size_t DynamicMemoryUsage() const;