mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-21 15:50:07 +01:00
Implement on-the-fly mempool size limitation.
After each transaction which is added to mempool, we first call Expire() to remove old transactions, then throwing away the lowest-feerate transactions. After throwing away transactions by feerate, we set the minimum relay fee to the maximum fee transaction-and-dependant-set we removed, plus the default minimum relay fee. After the next block is received, the minimum relay fee is allowed to decrease exponentially. Its halflife defaults to 12 hours, but is decreased to 6 hours if the mempool is smaller than half its maximum size, and 3 hours if the mempool is smaller than a quarter its maximum size. The minimum -maxmempool size is 40*-limitdescendantsize, as it is easy for an attacker to play games with the cheapest -limitdescendantsize transactions. -maxmempool defaults to 300MB. This disables high-priority transaction relay when the min relay fee adjustment is >0 (ie when the mempool is full). When the relay fee adjustment drops below the default minimum relay fee / 2 it is set to 0 (re-enabling priority-based free relay).
This commit is contained in:
16
src/main.cpp
16
src/main.cpp
@@ -885,8 +885,11 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
||||
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient fee", false,
|
||||
strprintf("%d < %d", nFees, txMinFee));
|
||||
|
||||
// Require that free transactions have sufficient priority to be mined in the next block.
|
||||
if (GetBoolArg("-relaypriority", true) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) {
|
||||
CAmount mempoolRejectFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nSize);
|
||||
if (mempoolRejectFee > 0 && nFees < mempoolRejectFee) {
|
||||
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool min fee not met", false, strprintf("%d < %d", nFees, mempoolRejectFee));
|
||||
} else if (GetBoolArg("-relaypriority", true) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, 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");
|
||||
}
|
||||
|
||||
@@ -951,6 +954,15 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
||||
|
||||
// Store transaction in memory
|
||||
pool.addUnchecked(hash, entry, setAncestors, !IsInitialBlockDownload());
|
||||
|
||||
// trim mempool and check if tx was trimmed
|
||||
int expired = pool.Expire(GetTime() - GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
|
||||
if (expired != 0)
|
||||
LogPrint("mempool", "Expired %i transactions from the memory pool\n", expired);
|
||||
|
||||
pool.TrimToSize(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
|
||||
if (!pool.exists(tx.GetHash()))
|
||||
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool full");
|
||||
}
|
||||
|
||||
SyncWithWallets(tx, NULL);
|
||||
|
||||
Reference in New Issue
Block a user