diff options
author | Gregory Maxwell <greg@xiph.org> | 2013-08-18 20:21:06 -0700 |
---|---|---|
committer | Gregory Maxwell <greg@xiph.org> | 2013-08-20 02:27:26 -0700 |
commit | 37c6389c5a0ca63ae3573440ecdfe95d28ad8f07 (patch) | |
tree | 51ef4367b16dc75bd60d4de0da261b65cebf4f2d /src/bloom.cpp | |
parent | 4bc9a192696273c88966c39debf8d17f16ebe471 (diff) |
Performance optimization for bloom filters.
This reduces a peer's ability to attack network resources by
using a full bloom filter, but without reducing the usability
of bloom filters. It sets a default match everything filter
for peers and it generalizes a prior optimization to
cover more cases.
Diffstat (limited to 'src/bloom.cpp')
-rw-r--r-- | src/bloom.cpp | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/src/bloom.cpp b/src/bloom.cpp index b6799e143d..8e8d8fa06b 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -23,6 +23,8 @@ vData(min((unsigned int)(-1 / LN2SQUARED * nElements * log(nFPRate)), MAX_BLOOM // The ideal number of hash functions is filter size * ln(2) / number of elements // Again, we ignore filter parameters which will create a bloom filter with more hash functions than the protocol limits // See http://en.wikipedia.org/wiki/Bloom_filter for an explanation of these formulas +isFull(false), +isEmpty(false), nHashFuncs(min((unsigned int)(vData.size() * 8 / nElements * LN2), MAX_HASH_FUNCS)), nTweak(nTweakIn), nFlags(nFlagsIn) @@ -37,7 +39,7 @@ inline unsigned int CBloomFilter::Hash(unsigned int nHashNum, const std::vector< void CBloomFilter::insert(const vector<unsigned char>& vKey) { - if (vData.size() == 1 && vData[0] == 0xff) + if (isFull) return; for (unsigned int i = 0; i < nHashFuncs; i++) { @@ -45,6 +47,7 @@ void CBloomFilter::insert(const vector<unsigned char>& vKey) // Sets bit nIndex of vData vData[nIndex >> 3] |= bit_mask[7 & nIndex]; } + isEmpty = false; } void CBloomFilter::insert(const COutPoint& outpoint) @@ -63,8 +66,10 @@ void CBloomFilter::insert(const uint256& hash) bool CBloomFilter::contains(const vector<unsigned char>& vKey) const { - if (vData.size() == 1 && vData[0] == 0xff) + if (isFull) return true; + if (isEmpty) + return false; for (unsigned int i = 0; i < nHashFuncs; i++) { unsigned int nIndex = Hash(i, vKey); @@ -99,6 +104,10 @@ bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx, const uint256& ha bool fFound = false; // Match if the filter contains the hash of tx // for finding tx when they appear in a block + if (isFull) + return true; + if (isEmpty) + return false; if (contains(hash)) fFound = true; @@ -158,3 +167,16 @@ bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx, const uint256& ha return false; } + +void CBloomFilter::UpdateEmptyFull() +{ + bool full = true; + bool empty = true; + for (unsigned int i = 0; i < vData.size(); i++) + { + full &= vData[i] == 0xff; + empty &= vData[i] == 0; + } + isFull = full; + isEmpty = empty; +} |