aboutsummaryrefslogtreecommitdiff
path: root/src/txmempool.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/txmempool.cpp')
-rw-r--r--src/txmempool.cpp83
1 files changed, 41 insertions, 42 deletions
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 313d33507f..5b085f492d 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2015 The Bitcoin Core developers
+// Copyright (c) 2009-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -8,7 +8,7 @@
#include "clientversion.h"
#include "consensus/consensus.h"
#include "consensus/validation.h"
-#include "main.h"
+#include "validation.h"
#include "policy/policy.h"
#include "policy/fees.h"
#include "streams.h"
@@ -20,22 +20,22 @@
using namespace std;
-CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
+CTxMemPoolEntry::CTxMemPoolEntry(const CTransactionRef& _tx, const CAmount& _nFee,
int64_t _nTime, double _entryPriority, unsigned int _entryHeight,
- bool poolHasNoInputsOf, CAmount _inChainInputValue,
+ CAmount _inChainInputValue,
bool _spendsCoinbase, int64_t _sigOpsCost, LockPoints lp):
- tx(std::make_shared<CTransaction>(_tx)), nFee(_nFee), nTime(_nTime), entryPriority(_entryPriority), entryHeight(_entryHeight),
- hadNoDependencies(poolHasNoInputsOf), inChainInputValue(_inChainInputValue),
+ tx(_tx), nFee(_nFee), nTime(_nTime), entryPriority(_entryPriority), entryHeight(_entryHeight),
+ inChainInputValue(_inChainInputValue),
spendsCoinbase(_spendsCoinbase), sigOpCost(_sigOpsCost), lockPoints(lp)
{
- nTxWeight = GetTransactionWeight(_tx);
- nModSize = _tx.CalculateModifiedSize(GetTxSize());
+ nTxWeight = GetTransactionWeight(*tx);
+ nModSize = tx->CalculateModifiedSize(GetTxSize());
nUsageSize = RecursiveDynamicUsage(*tx) + memusage::DynamicUsage(tx);
nCountWithDescendants = 1;
nSizeWithDescendants = GetTxSize();
nModFeesWithDescendants = nFee;
- CAmount nValueIn = _tx.GetValueOut()+nFee;
+ CAmount nValueIn = tx->GetValueOut()+nFee;
assert(inChainInputValue <= nValueIn);
feeDelta = 0;
@@ -359,7 +359,6 @@ CTxMemPool::CTxMemPool(const CFeeRate& _minReasonableRelayFee) :
nCheckFrequency = 0;
minerPolicyEstimator = new CBlockPolicyEstimator(_minReasonableRelayFee);
- minReasonableRelayFee = _minReasonableRelayFee;
}
CTxMemPool::~CTxMemPool()
@@ -392,7 +391,7 @@ void CTxMemPool::AddTransactionsUpdated(unsigned int n)
nTransactionsUpdated += n;
}
-bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool fCurrentEstimate)
+bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool validFeeEstimate)
{
// Add to memory pool without checking anything.
// Used by main.cpp AcceptToMemoryPool(), which DOES do
@@ -442,7 +441,7 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry,
nTransactionsUpdated++;
totalTxSize += entry.GetTxSize();
- minerPolicyEstimator->processTransaction(entry, fCurrentEstimate);
+ minerPolicyEstimator->processTransaction(entry, validFeeEstimate);
vTxHashes.emplace_back(tx.GetWitnessHash(), newit);
newit->vTxHashesIdx = vTxHashes.size() - 1;
@@ -503,7 +502,7 @@ void CTxMemPool::CalculateDescendants(txiter entryit, setEntries &setDescendants
}
}
-void CTxMemPool::removeRecursive(const CTransaction &origTx, std::vector<std::shared_ptr<const CTransaction>>* removed)
+void CTxMemPool::removeRecursive(const CTransaction &origTx)
{
// Remove transaction from memory pool
{
@@ -530,11 +529,6 @@ void CTxMemPool::removeRecursive(const CTransaction &origTx, std::vector<std::sh
BOOST_FOREACH(txiter it, txToRemove) {
CalculateDescendants(it, setAllRemoves);
}
- if (removed) {
- BOOST_FOREACH(txiter it, setAllRemoves) {
- removed->emplace_back(it->GetSharedTx());
- }
- }
RemoveStaged(setAllRemoves, false);
}
}
@@ -576,7 +570,7 @@ void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMem
RemoveStaged(setAllRemoves, false);
}
-void CTxMemPool::removeConflicts(const CTransaction &tx, std::vector<std::shared_ptr<const CTransaction>>* removed)
+void CTxMemPool::removeConflicts(const CTransaction &tx)
{
// Remove transactions which depend on inputs of tx, recursively
LOCK(cs);
@@ -586,8 +580,8 @@ void CTxMemPool::removeConflicts(const CTransaction &tx, std::vector<std::shared
const CTransaction &txConflict = *it->second;
if (txConflict != tx)
{
- removeRecursive(txConflict, removed);
ClearPrioritisation(txConflict.GetHash());
+ removeRecursive(txConflict);
}
}
}
@@ -596,32 +590,31 @@ void CTxMemPool::removeConflicts(const CTransaction &tx, std::vector<std::shared
/**
* Called when a block is connected. Removes from mempool and updates the miner fee estimator.
*/
-void CTxMemPool::removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight,
- std::vector<std::shared_ptr<const CTransaction>>* conflicts, bool fCurrentEstimate)
+void CTxMemPool::removeForBlock(const std::vector<CTransactionRef>& vtx, unsigned int nBlockHeight)
{
LOCK(cs);
- std::vector<CTxMemPoolEntry> entries;
- BOOST_FOREACH(const CTransaction& tx, vtx)
+ std::vector<const CTxMemPoolEntry*> entries;
+ for (const auto& tx : vtx)
{
- uint256 hash = tx.GetHash();
+ uint256 hash = tx->GetHash();
indexed_transaction_set::iterator i = mapTx.find(hash);
if (i != mapTx.end())
- entries.push_back(*i);
+ entries.push_back(&*i);
}
- BOOST_FOREACH(const CTransaction& tx, vtx)
+ // Before the txs in the new block have been removed from the mempool, update policy estimates
+ minerPolicyEstimator->processBlock(nBlockHeight, entries);
+ for (const auto& tx : vtx)
{
- txiter it = mapTx.find(tx.GetHash());
+ txiter it = mapTx.find(tx->GetHash());
if (it != mapTx.end()) {
setEntries stage;
stage.insert(it);
RemoveStaged(stage, true);
}
- removeConflicts(tx, conflicts);
- ClearPrioritisation(tx.GetHash());
+ removeConflicts(*tx);
+ ClearPrioritisation(tx->GetHash());
}
- // After the txs in the new block have been removed from the mempool, update policy estimates
- minerPolicyEstimator->processBlock(nBlockHeight, entries, fCurrentEstimate);
lastRollingFeeUpdate = GetTime();
blockSinceLastRollingFeeBump = true;
}
@@ -851,7 +844,7 @@ std::vector<TxMempoolInfo> CTxMemPool::infoAll() const
return ret;
}
-std::shared_ptr<const CTransaction> CTxMemPool::get(const uint256& hash) const
+CTransactionRef CTxMemPool::get(const uint256& hash) const
{
LOCK(cs);
indexed_transaction_set::const_iterator i = mapTx.find(hash);
@@ -895,7 +888,7 @@ CTxMemPool::WriteFeeEstimates(CAutoFile& fileout) const
{
try {
LOCK(cs);
- fileout << 109900; // version required to read: 0.10.99 or later
+ fileout << 139900; // version required to read: 0.13.99 or later
fileout << CLIENT_VERSION; // version that wrote the file
minerPolicyEstimator->Write(fileout);
}
@@ -914,9 +907,8 @@ CTxMemPool::ReadFeeEstimates(CAutoFile& filein)
filein >> nVersionRequired >> nVersionThatWrote;
if (nVersionRequired > CLIENT_VERSION)
return error("CTxMemPool::ReadFeeEstimates(): up-version (%d) fee estimate file", nVersionRequired);
-
LOCK(cs);
- minerPolicyEstimator->Read(filein);
+ minerPolicyEstimator->Read(filein, nVersionThatWrote);
}
catch (const std::exception&) {
LogPrintf("CTxMemPool::ReadFeeEstimates(): unable to read policy estimator data (non-fatal)\n");
@@ -979,7 +971,7 @@ 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.
- shared_ptr<const CTransaction> ptx = mempool.get(txid);
+ CTransactionRef ptx = mempool.get(txid);
if (ptx) {
coins = CCoins(*ptx, MEMPOOL_HEIGHT);
return true;
@@ -1021,14 +1013,14 @@ int CTxMemPool::Expire(int64_t time) {
return stage.size();
}
-bool CTxMemPool::addUnchecked(const uint256&hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate)
+bool CTxMemPool::addUnchecked(const uint256&hash, 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, fCurrentEstimate);
+ return addUnchecked(hash, entry, setAncestors, validFeeEstimate);
}
void CTxMemPool::UpdateChild(txiter entry, txiter child, bool add)
@@ -1083,12 +1075,12 @@ CFeeRate CTxMemPool::GetMinFee(size_t sizelimit) const {
rollingMinimumFeeRate = rollingMinimumFeeRate / pow(2.0, (time - lastRollingFeeUpdate) / halflife);
lastRollingFeeUpdate = time;
- if (rollingMinimumFeeRate < minReasonableRelayFee.GetFeePerK() / 2) {
+ if (rollingMinimumFeeRate < (double)incrementalRelayFee.GetFeePerK() / 2) {
rollingMinimumFeeRate = 0;
return CFeeRate(0);
}
}
- return std::max(CFeeRate(rollingMinimumFeeRate), minReasonableRelayFee);
+ return std::max(CFeeRate(rollingMinimumFeeRate), incrementalRelayFee);
}
void CTxMemPool::trackPackageRemoved(const CFeeRate& rate) {
@@ -1112,7 +1104,7 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<uint256>* pvNoSpendsRe
// to have 0 fee). This way, we don't allow txn to enter mempool with feerate
// equal to txn which were removed with no block in between.
CFeeRate removed(it->GetModFeesWithDescendants(), it->GetSizeWithDescendants());
- removed += minReasonableRelayFee;
+ removed += incrementalRelayFee;
trackPackageRemoved(removed);
maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed);
@@ -1143,3 +1135,10 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<uint256>* pvNoSpendsRe
if (maxFeeRateRemoved > CFeeRate(0))
LogPrint("mempool", "Removed %u txn, rolling minimum fee bumped to %s\n", nTxnRemoved, maxFeeRateRemoved.ToString());
}
+
+bool CTxMemPool::TransactionWithinChainLimit(const uint256& txid, size_t chainLimit) const {
+ LOCK(cs);
+ auto it = mapTx.find(txid);
+ return it == mapTx.end() || (it->GetCountWithAncestors() < chainLimit &&
+ it->GetCountWithDescendants() < chainLimit);
+}