| 42 | } |
| 43 | |
| 44 | void Set(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey) |
| 45 | { |
| 46 | // DoS prevention: limit cache size to less than 10MB |
| 47 | // (~200 bytes per cache entry times 50,000 entries) |
| 48 | // Since there are a maximum of 20,000 signature operations per block |
| 49 | // 50,000 is a reasonable default. |
| 50 | int64_t nMaxCacheSize = GetArg("-maxsigcachesize", 50000); |
| 51 | if (nMaxCacheSize <= 0) return; |
| 52 | |
| 53 | boost::unique_lock<boost::shared_mutex> lock(cs_sigcache); |
| 54 | |
| 55 | while (static_cast<int64_t>(setValid.size()) > nMaxCacheSize) |
| 56 | { |
| 57 | // Evict a random entry. Random because that helps |
| 58 | // foil would-be DoS attackers who might try to pre-generate |
| 59 | // and re-use a set of valid signatures just-slightly-greater |
| 60 | // than our cache size. |
| 61 | uint256 randomHash = GetRandHash(); |
| 62 | std::vector<unsigned char> unused; |
| 63 | std::set<sigdata_type>::iterator it = |
| 64 | setValid.lower_bound(sigdata_type(randomHash, unused, unused)); |
| 65 | if (it == setValid.end()) |
| 66 | it = setValid.begin(); |
| 67 | setValid.erase(*it); |
| 68 | } |
| 69 | |
| 70 | sigdata_type k(hash, vchSig, pubKey); |
| 71 | setValid.insert(k); |
| 72 | } |
| 73 | }; |
| 74 | |
| 75 | } |