Continuously rate-limit free transactions.

Changed algorithm to use continuous exponential function instead of discrete 10-minute window.
Changed -limitfreerelay to be kilobytes-per-minute instead of boolean.
This commit is contained in:
Gavin Andresen 2011-03-11 11:50:16 -05:00
parent 8f58d0dbc8
commit 5de8b54c51
1 changed files with 14 additions and 11 deletions

View File

@ -738,19 +738,22 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
if (nFees < GetMinFee(1000)) if (nFees < GetMinFee(1000))
return error("AcceptToMemoryPool() : not enough fees"); return error("AcceptToMemoryPool() : not enough fees");
// Limit free transactions per 10 minutes // Continuously rate-limit free transactions
if (nFees < CENT && GetBoolArg("-limitfreerelay")) if (nFees < CENT)
{ {
static int64 nNextReset; static double dFreeCount;
static int64 nFreeCount; static int64 nLastTime;
if (GetTime() > nNextReset) int64 nNow = GetTime();
{ // Use an exponentially decaying ~10-minute window:
nNextReset = GetTime() + 10 * 60; dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime));
nFreeCount = 0; nLastTime = nNow;
} // -limitfreerelay unit is thousand-bytes-per-minute
if (nFreeCount > 150000 && !IsFromMe()) // At default rate it would take over a month to fill 1GB
if (dFreeCount > GetArg("-limitfreerelay", 15)*10*1000 && !IsFromMe())
return error("AcceptToMemoryPool() : free transaction rejected by rate limiter"); return error("AcceptToMemoryPool() : free transaction rejected by rate limiter");
nFreeCount += nSize; if (fDebug)
printf("Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
dFreeCount += nSize;
} }
} }