aboutsummaryrefslogtreecommitdiff
path: root/src/txmempool.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/txmempool.cpp')
-rw-r--r--src/txmempool.cpp76
1 files changed, 40 insertions, 36 deletions
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 2108e6ba2d..3ad93342c4 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2017 The Bitcoin Core developers
+// Copyright (c) 2009-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -20,13 +20,10 @@
CTxMemPoolEntry::CTxMemPoolEntry(const CTransactionRef& _tx, const CAmount& _nFee,
int64_t _nTime, unsigned int _entryHeight,
- bool _spendsCoinbase, int64_t _sigOpsCost, LockPoints lp):
- tx(_tx), nFee(_nFee), nTime(_nTime), entryHeight(_entryHeight),
+ bool _spendsCoinbase, int64_t _sigOpsCost, LockPoints lp)
+ : tx(_tx), nFee(_nFee), nTxWeight(GetTransactionWeight(*tx)), nUsageSize(RecursiveDynamicUsage(tx)), nTime(_nTime), entryHeight(_entryHeight),
spendsCoinbase(_spendsCoinbase), sigOpCost(_sigOpsCost), lockPoints(lp)
{
- nTxWeight = GetTransactionWeight(*tx);
- nUsageSize = RecursiveDynamicUsage(tx);
-
nCountWithDescendants = 1;
nSizeWithDescendants = GetTxSize();
nModFeesWithDescendants = nFee;
@@ -151,8 +148,6 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<uint256> &vHashes
bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents /* = true */) const
{
- LOCK(cs);
-
setEntries parentHashes;
const CTransaction &tx = entry.GetTx();
@@ -161,9 +156,9 @@ bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntr
// GetMemPoolParents() is only valid for entries in the mempool, so we
// iterate mapTx to find parents.
for (unsigned int i = 0; i < tx.vin.size(); i++) {
- txiter piter = mapTx.find(tx.vin[i].prevout.hash);
- if (piter != mapTx.end()) {
- parentHashes.insert(piter);
+ boost::optional<txiter> piter = GetIter(tx.vin[i].prevout.hash);
+ if (piter) {
+ parentHashes.insert(*piter);
if (parentHashes.size() + 1 > limitAncestorCount) {
errString = strprintf("too many unconfirmed parents [limit: %u]", limitAncestorCount);
return false;
@@ -198,7 +193,7 @@ bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntr
}
const setEntries & setMemPoolParents = GetMemPoolParents(stageit);
- for (const txiter &phash : setMemPoolParents) {
+ for (txiter phash : setMemPoolParents) {
// If this is a new ancestor, add it.
if (setAncestors.count(phash) == 0) {
parentHashes.insert(phash);
@@ -357,25 +352,22 @@ void CTxMemPool::AddTransactionsUpdated(unsigned int n)
nTransactionsUpdated += n;
}
-bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool validFeeEstimate)
+void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, setEntries &setAncestors, bool validFeeEstimate)
{
NotifyEntryAdded(entry.GetSharedTx());
// Add to memory pool without checking anything.
// Used by AcceptToMemoryPool(), which DOES do
// all the appropriate checks.
- LOCK(cs);
indexed_transaction_set::iterator newit = mapTx.insert(entry).first;
mapLinks.insert(make_pair(newit, TxLinks()));
// Update transaction for any feeDelta created by PrioritiseTransaction
// TODO: refactor so that the fee delta is calculated before inserting
// into mapTx.
- std::map<uint256, CAmount>::const_iterator pos = mapDeltas.find(hash);
- if (pos != mapDeltas.end()) {
- const CAmount &delta = pos->second;
- if (delta) {
+ CAmount delta{0};
+ ApplyDelta(entry.GetTx().GetHash(), delta);
+ if (delta) {
mapTx.modify(newit, update_fee_delta(delta));
- }
}
// Update cachedInnerUsage to include contained transaction's usage.
@@ -397,11 +389,8 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry,
// to clean up the mess we're leaving here.
// Update ancestors with information about this tx
- for (const uint256 &phash : setParentTransactions) {
- txiter pit = mapTx.find(phash);
- if (pit != mapTx.end()) {
+ for (const auto& pit : GetIterSet(setParentTransactions)) {
UpdateParent(newit, pit, true);
- }
}
UpdateAncestorsOf(true, newit, setAncestors);
UpdateEntryForAncestors(newit, setAncestors);
@@ -412,8 +401,6 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry,
vTxHashes.emplace_back(tx.GetWitnessHash(), newit);
newit->vTxHashesIdx = vTxHashes.size() - 1;
-
- return true;
}
void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason)
@@ -462,7 +449,7 @@ void CTxMemPool::CalculateDescendants(txiter entryit, setEntries& setDescendants
stage.erase(it);
const setEntries &setChildren = GetMemPoolChildren(it);
- for (const txiter &childiter : setChildren) {
+ for (txiter childiter : setChildren) {
if (!setDescendants.count(childiter)) {
stage.insert(childiter);
}
@@ -645,8 +632,6 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
innerUsage += memusage::DynamicUsage(links.parents) + memusage::DynamicUsage(links.children);
bool fDependsWait = false;
setEntries setParentCheck;
- int64_t parentSizes = 0;
- int64_t parentSigOpCost = 0;
for (const CTxIn &txin : tx.vin) {
// Check that every mempool transaction's inputs refer to available coins, or other mempool tx's.
indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash);
@@ -654,10 +639,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
const CTransaction& tx2 = it2->GetTx();
assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull());
fDependsWait = true;
- if (setParentCheck.insert(it2).second) {
- parentSizes += it2->GetTxSize();
- parentSigOpCost += it2->GetSigOpCost();
- }
+ setParentCheck.insert(it2);
} else {
assert(pcoins->HaveCoin(txin.prevout));
}
@@ -877,6 +859,29 @@ void CTxMemPool::ClearPrioritisation(const uint256 hash)
mapDeltas.erase(hash);
}
+const CTransaction* CTxMemPool::GetConflictTx(const COutPoint& prevout) const
+{
+ const auto it = mapNextTx.find(prevout);
+ return it == mapNextTx.end() ? nullptr : it->second;
+}
+
+boost::optional<CTxMemPool::txiter> CTxMemPool::GetIter(const uint256& txid) const
+{
+ auto it = mapTx.find(txid);
+ if (it != mapTx.end()) return it;
+ return boost::optional<txiter>{};
+}
+
+CTxMemPool::setEntries CTxMemPool::GetIterSet(const std::set<uint256>& hashes) const
+{
+ CTxMemPool::setEntries ret;
+ for (const auto& h : hashes) {
+ const auto mi = GetIter(h);
+ if (mi) ret.insert(*mi);
+ }
+ return ret;
+}
+
bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const
{
for (unsigned int i = 0; i < tx.vin.size(); i++)
@@ -912,7 +917,7 @@ size_t CTxMemPool::DynamicMemoryUsage() const {
void CTxMemPool::RemoveStaged(setEntries &stage, bool updateDescendants, MemPoolRemovalReason reason) {
AssertLockHeld(cs);
UpdateForRemoveFromMempool(stage, updateDescendants);
- for (const txiter& it : stage) {
+ for (txiter it : stage) {
removeUnchecked(it, reason);
}
}
@@ -933,14 +938,13 @@ int CTxMemPool::Expire(int64_t time) {
return stage.size();
}
-bool CTxMemPool::addUnchecked(const uint256&hash, const CTxMemPoolEntry &entry, bool validFeeEstimate)
+void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, bool validFeeEstimate)
{
- LOCK(cs);
setEntries setAncestors;
uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
std::string dummy;
CalculateMemPoolAncestors(entry, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy);
- return addUnchecked(hash, entry, setAncestors, validFeeEstimate);
+ return addUnchecked(entry, setAncestors, validFeeEstimate);
}
void CTxMemPool::UpdateChild(txiter entry, txiter child, bool add)