aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
authorSuhas Daftuar <sdaftuar@gmail.com>2015-11-19 11:18:28 -0500
committerWladimir J. van der Laan <laanwj@gmail.com>2015-12-21 17:19:53 +0100
commit12c469b236aa9b31b3744e5c529b9236dda27b27 (patch)
tree77569facae72f92502391b0cafc89c3f50f4c470 /src/main.cpp
parenteccd67106d7ebfcb1d0913c2036848f57ba344fb (diff)
downloadbitcoin-12c469b236aa9b31b3744e5c529b9236dda27b27.tar.xz
[Mempool] Fix mempool limiting and replace-by-fee for PrioritiseTransaction
1) Fix mempool limiting for PrioritiseTransaction Redo the feerate index to be based on mining score, rather than fee. Update mempool_packages.py to test prioritisetransaction's effect on package scores. 2) Update replace-by-fee logic to use fee deltas 3) Use fee deltas for determining mempool acceptance 4) Remove GetMinRelayFee One test in AcceptToMemoryPool was to compare a transaction's fee agains the value returned by GetMinRelayFee. This value was zero for all small transactions. For larger transactions (between DEFAULT_BLOCK_PRIORITY_SIZE and MAX_STANDARD_TX_SIZE), this function was preventing low fee transactions from ever being accepted. With this function removed, we will now allow transactions in that range with fees (including modifications via PrioritiseTransaction) below the minRelayTxFee, provided that they have sufficient priority. Github-Pull: #7062 Rebased-From: eb306664e786ae43d539fde66f0fbe2a3e89d910 9ef2a25603c9ec4e44c4f45c6a5d4e4386ec86d3 27fae3484cdb21b0d24face833b966fce5926be5 901b01d674031f9aca717deeb372bafa160a24af
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp57
1 files changed, 15 insertions, 42 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 9e29fad978..7bc025308b 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -800,32 +800,6 @@ void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age) {
pcoinsTip->Uncache(removed);
}
-CAmount GetMinRelayFee(const CTransaction& tx, const CTxMemPool& pool, unsigned int nBytes, bool fAllowFree)
-{
- uint256 hash = tx.GetHash();
- double dPriorityDelta = 0;
- CAmount nFeeDelta = 0;
- pool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
- if (dPriorityDelta > 0 || nFeeDelta > 0)
- return 0;
-
- CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes);
-
- if (fAllowFree)
- {
- // There is a free transaction area in blocks created by most miners,
- // * If we are relaying we allow transactions up to DEFAULT_BLOCK_PRIORITY_SIZE - 1000
- // to be considered to fall into this category. We don't want to encourage sending
- // multiple transactions instead of one big transaction to avoid fees.
- if (nBytes < (DEFAULT_BLOCK_PRIORITY_SIZE - 1000))
- nMinFee = 0;
- }
-
- if (!MoneyRange(nMinFee))
- nMinFee = MAX_MONEY;
- return nMinFee;
-}
-
/** Convert CValidationState to a human-readable message for logging */
std::string FormatStateMessage(const CValidationState &state)
{
@@ -968,6 +942,11 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
CAmount nValueOut = tx.GetValueOut();
CAmount nFees = nValueIn-nValueOut;
+ // nModifiedFees includes any fee deltas from PrioritiseTransaction
+ CAmount nModifiedFees = nFees;
+ double nPriorityDummy = 0;
+ pool.ApplyDeltas(hash, nPriorityDummy, nModifiedFees);
+
CAmount inChainInputValue;
double dPriority = view.GetPriority(tx, chainActive.Height(), inChainInputValue);
@@ -985,16 +964,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx), inChainInputValue, fSpendsCoinbase, nSigOps);
unsigned int nSize = entry.GetTxSize();
- // Don't accept it if it can't get into a block
- CAmount txMinFee = GetMinRelayFee(tx, pool, nSize, true);
- if (fLimitFree && nFees < txMinFee)
- return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient fee", false,
- strprintf("%d < %d", nFees, txMinFee));
-
CAmount mempoolRejectFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nSize);
- if (mempoolRejectFee > 0 && nFees < mempoolRejectFee) {
+ if (mempoolRejectFee > 0 && nModifiedFees < mempoolRejectFee) {
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool min fee not met", false, strprintf("%d < %d", nFees, mempoolRejectFee));
- } else if (GetBoolArg("-relaypriority", DEFAULT_RELAYPRIORITY) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(entry.GetPriority(chainActive.Height() + 1))) {
+ } else if (GetBoolArg("-relaypriority", DEFAULT_RELAYPRIORITY) && nModifiedFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(entry.GetPriority(chainActive.Height() + 1))) {
// Require that free transactions have sufficient priority to be mined in the next block.
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
}
@@ -1002,7 +975,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
// Continuously rate-limit free (really, very-low-fee) transactions
// This mitigates 'penny-flooding' -- sending thousands of free transactions just to
// be annoying or make others' transactions take longer to confirm.
- if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize))
+ if (fLimitFree && nModifiedFees < ::minRelayTxFee.GetFee(nSize))
{
static CCriticalSection csFreeLimiter;
static double dFreeCount;
@@ -1067,7 +1040,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
LOCK(pool.cs);
if (setConflicts.size())
{
- CFeeRate newFeeRate(nFees, nSize);
+ CFeeRate newFeeRate(nModifiedFees, nSize);
set<uint256> setConflictsParents;
const int maxDescendantsToVisit = 100;
CTxMemPool::setEntries setIterConflicting;
@@ -1110,7 +1083,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
// ignored when deciding whether or not to replace, we do
// require the replacement to pay more overall fees too,
// mitigating most cases.
- CFeeRate oldFeeRate(mi->GetFee(), mi->GetTxSize());
+ CFeeRate oldFeeRate(mi->GetModifiedFee(), mi->GetTxSize());
if (newFeeRate <= oldFeeRate)
{
return state.DoS(0,
@@ -1138,7 +1111,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
pool.CalculateDescendants(it, allConflicting);
}
BOOST_FOREACH(CTxMemPool::txiter it, allConflicting) {
- nConflictingFees += it->GetFee();
+ nConflictingFees += it->GetModifiedFee();
nConflictingSize += it->GetTxSize();
}
} else {
@@ -1171,16 +1144,16 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
// The replacement must pay greater fees than the transactions it
// replaces - if we did the bandwidth used by those conflicting
// transactions would not be paid for.
- if (nFees < nConflictingFees)
+ if (nModifiedFees < nConflictingFees)
{
return state.DoS(0, error("AcceptToMemoryPool: rejecting replacement %s, less fees than conflicting txs; %s < %s",
- hash.ToString(), FormatMoney(nFees), FormatMoney(nConflictingFees)),
+ hash.ToString(), FormatMoney(nModifiedFees), FormatMoney(nConflictingFees)),
REJECT_INSUFFICIENTFEE, "insufficient fee");
}
// Finally in addition to paying more fees than the conflicts the
// new transaction must pay for its own bandwidth.
- CAmount nDeltaFees = nFees - nConflictingFees;
+ CAmount nDeltaFees = nModifiedFees - nConflictingFees;
if (nDeltaFees < ::minRelayTxFee.GetFee(nSize))
{
return state.DoS(0,
@@ -1218,7 +1191,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
LogPrint("mempool", "replacing tx %s with %s for %s BTC additional fees, %d delta bytes\n",
it->GetTx().GetHash().ToString(),
hash.ToString(),
- FormatMoney(nFees - nConflictingFees),
+ FormatMoney(nModifiedFees - nConflictingFees),
(int)nSize - (int)nConflictingSize);
}
pool.RemoveStaged(allConflicting);