diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2016-06-08 14:01:05 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2016-06-08 14:01:18 +0200 |
commit | a7c41f2de03c315394c0560f369544e24a3e5586 (patch) | |
tree | 919733dfaa3aaaadbf9f944a72c57557f3268275 /src/txmempool.cpp | |
parent | 761cddb69029cbef1fc62267aeb2e4c17c6ed34d (diff) | |
parent | 288d85ddf2e0a0c9d25a23db56052883170466d0 (diff) |
Merge #8126: std::shared_ptr based CTransaction storage in mempool
288d85d Get rid of CTxMempool::lookup() entirely (Pieter Wuille)
c2a4724 Optimization: use usec in expiration and reuse nNow (Pieter Wuille)
e9b4780 Optimization: don't check the mempool at all if no mempool req ever (Pieter Wuille)
dbfb426 Optimize the relay map to use shared_ptr's (Pieter Wuille)
8d39d7a Switch CTransaction storage in mempool to std::shared_ptr (Pieter Wuille)
1b9e6d3 Add support for unique_ptr and shared_ptr to memusage (Pieter Wuille)
Diffstat (limited to 'src/txmempool.cpp')
-rw-r--r-- | src/txmempool.cpp | 86 |
1 files changed, 56 insertions, 30 deletions
diff --git a/src/txmempool.cpp b/src/txmempool.cpp index f44e450363..205ffd6379 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -23,18 +23,18 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, int64_t _nTime, double _entryPriority, unsigned int _entryHeight, bool poolHasNoInputsOf, CAmount _inChainInputValue, bool _spendsCoinbase, unsigned int _sigOps, LockPoints lp): - tx(_tx), nFee(_nFee), nTime(_nTime), entryPriority(_entryPriority), entryHeight(_entryHeight), + tx(std::make_shared<CTransaction>(_tx)), nFee(_nFee), nTime(_nTime), entryPriority(_entryPriority), entryHeight(_entryHeight), hadNoDependencies(poolHasNoInputsOf), inChainInputValue(_inChainInputValue), spendsCoinbase(_spendsCoinbase), sigOpCount(_sigOps), lockPoints(lp) { - nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); - nModSize = tx.CalculateModifiedSize(nTxSize); - nUsageSize = RecursiveDynamicUsage(tx); + nTxSize = ::GetSerializeSize(_tx, SER_NETWORK, PROTOCOL_VERSION); + nModSize = _tx.CalculateModifiedSize(nTxSize); + nUsageSize = RecursiveDynamicUsage(*tx) + memusage::DynamicUsage(tx); nCountWithDescendants = 1; nSizeWithDescendants = nTxSize; nModFeesWithDescendants = nFee; - CAmount nValueIn = tx.GetValueOut()+nFee; + CAmount nValueIn = _tx.GetValueOut()+nFee; assert(inChainInputValue <= nValueIn); feeDelta = 0; @@ -768,50 +768,76 @@ bool CTxMemPool::CompareDepthAndScore(const uint256& hasha, const uint256& hashb namespace { class DepthAndScoreComparator { - CTxMemPool *mp; public: - DepthAndScoreComparator(CTxMemPool *mempool) : mp(mempool) {} - bool operator()(const uint256& a, const uint256& b) { return mp->CompareDepthAndScore(a, b); } + bool operator()(const CTxMemPool::indexed_transaction_set::const_iterator& a, const CTxMemPool::indexed_transaction_set::const_iterator& b) + { + uint64_t counta = a->GetCountWithAncestors(); + uint64_t countb = b->GetCountWithAncestors(); + if (counta == countb) { + return CompareTxMemPoolEntryByScore()(*a, *b); + } + return counta < countb; + } }; } -void CTxMemPool::queryHashes(vector<uint256>& vtxid) +std::vector<CTxMemPool::indexed_transaction_set::const_iterator> CTxMemPool::GetSortedDepthAndScore() const { - vtxid.clear(); + std::vector<indexed_transaction_set::const_iterator> iters; + AssertLockHeld(cs); + + iters.reserve(mapTx.size()); + for (indexed_transaction_set::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) { + iters.push_back(mi); + } + std::sort(iters.begin(), iters.end(), DepthAndScoreComparator()); + return iters; +} + +void CTxMemPool::queryHashes(vector<uint256>& vtxid) +{ LOCK(cs); + auto iters = GetSortedDepthAndScore(); + + vtxid.clear(); vtxid.reserve(mapTx.size()); - for (indexed_transaction_set::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) - vtxid.push_back(mi->GetTx().GetHash()); - std::sort(vtxid.begin(), vtxid.end(), DepthAndScoreComparator(this)); + for (auto it : iters) { + vtxid.push_back(it->GetTx().GetHash()); + } } - -bool CTxMemPool::lookup(uint256 hash, CTransaction& result, int64_t& time) const +std::vector<TxMempoolInfo> CTxMemPool::infoAll() const { LOCK(cs); - indexed_transaction_set::const_iterator i = mapTx.find(hash); - if (i == mapTx.end()) return false; - result = i->GetTx(); - time = i->GetTime(); - return true; + auto iters = GetSortedDepthAndScore(); + + std::vector<TxMempoolInfo> ret; + ret.reserve(mapTx.size()); + for (auto it : iters) { + ret.push_back(TxMempoolInfo{it->GetSharedTx(), it->GetTime(), CFeeRate(it->GetFee(), it->GetTxSize())}); + } + + return ret; } -bool CTxMemPool::lookup(uint256 hash, CTransaction& result) const +std::shared_ptr<const CTransaction> CTxMemPool::get(const uint256& hash) const { - int64_t time; - return CTxMemPool::lookup(hash, result, time); + LOCK(cs); + indexed_transaction_set::const_iterator i = mapTx.find(hash); + if (i == mapTx.end()) + return nullptr; + return i->GetSharedTx(); } -bool CTxMemPool::lookupFeeRate(const uint256& hash, CFeeRate& feeRate) const +TxMempoolInfo CTxMemPool::info(const uint256& hash) const { LOCK(cs); indexed_transaction_set::const_iterator i = mapTx.find(hash); if (i == mapTx.end()) - return false; - feeRate = CFeeRate(i->GetFee(), i->GetTxSize()); - return true; + return TxMempoolInfo(); + return TxMempoolInfo{i->GetSharedTx(), i->GetTime(), CFeeRate(i->GetFee(), i->GetTxSize())}; } CFeeRate CTxMemPool::estimateFee(int nBlocks) const @@ -924,9 +950,9 @@ bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) const { // If an entry in the mempool exists, always return that one, as it's guaranteed to never // conflict with the underlying cache, and it cannot have pruned entries (as it contains full) // transactions. First checking the underlying cache risks returning a pruned entry instead. - CTransaction tx; - if (mempool.lookup(txid, tx)) { - coins = CCoins(tx, MEMPOOL_HEIGHT); + shared_ptr<const CTransaction> ptx = mempool.get(txid); + if (ptx) { + coins = CCoins(*ptx, MEMPOOL_HEIGHT); return true; } return (base->GetCoins(txid, coins) && !coins.IsPruned()); |