diff options
author | Gavin Andresen <gavinandresen@gmail.com> | 2011-03-13 17:15:44 -0400 |
---|---|---|
committer | Gavin Andresen <gavinandresen@gmail.com> | 2011-03-13 17:15:44 -0400 |
commit | 2abd56f4280cf19e76b1eab3544f75954a0c267f (patch) | |
tree | 118d350180b7e3e3969a2bd61133b2f430f5e278 | |
parent | 1bf9b3b06f483d908bb70ba3736ec347b72d90c8 (diff) | |
parent | 88abf70386f18020bb624bca4a4cb7900ce47d0c (diff) |
Merge branch 'limitfree' of /Users/gavin/src/integration_btc
-rw-r--r-- | main.cpp | 34 |
1 files changed, 22 insertions, 12 deletions
@@ -742,19 +742,29 @@ 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; + // Continuously rate-limit free transactions + // This mitigates 'penny-flooding' -- sending thousands of free transactions just to + // be annoying or make other's transactions take longer to confirm. + if (nFees < CENT) + { + static CCriticalSection cs; + static double dFreeCount; + static int64 nLastTime; + int64 nNow = GetTime(); + + CRITICAL_BLOCK(cs) + { + // 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"); + if (fDebug) + printf("Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize); + dFreeCount += nSize; } - if (nFreeCount > 150000 && !IsFromMe()) - return error("AcceptToMemoryPool() : free transaction rejected by rate limiter"); - nFreeCount += nSize; } } |