From 5de8b54c5138e47b6df40d31f282fb45243b29bf Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Fri, 11 Mar 2011 11:50:16 -0500 Subject: [PATCH] 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. --- main.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/main.cpp b/main.cpp index c65cd72de..5cb1342b9 100644 --- a/main.cpp +++ b/main.cpp @@ -738,19 +738,22 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi if (nFees < GetMinFee(1000)) return error("AcceptToMemoryPool() : not enough fees"); - // Limit free transactions per 10 minutes - if (nFees < CENT && GetBoolArg("-limitfreerelay")) - { - static int64 nNextReset; - static int64 nFreeCount; - if (GetTime() > nNextReset) - { - nNextReset = GetTime() + 10 * 60; - nFreeCount = 0; - } - if (nFreeCount > 150000 && !IsFromMe()) + // Continuously rate-limit free transactions + if (nFees < CENT) + { + static double dFreeCount; + static int64 nLastTime; + int64 nNow = GetTime(); + // Use an exponentially decaying ~10-minute window: + dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime)); + nLastTime = nNow; + // -limitfreerelay unit is thousand-bytes-per-minute + // 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"); - nFreeCount += nSize; + if (fDebug) + printf("Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize); + dFreeCount += nSize; } }