Browse Source

Deduplicate SignatureCacheHasher

This moves the SignatureCacheHasher to the sigcache header, out of the anonymous
namespace, so that the tests can import it.
0.15
Jeremy Rubin 8 years ago
parent
commit
f9c88079df
  1. 22
      src/script/sigcache.cpp
  2. 21
      src/script/sigcache.h
  3. 25
      src/test/cuckoocache_tests.cpp

22
src/script/sigcache.cpp

@ -15,28 +15,6 @@
#include <boost/thread.hpp> #include <boost/thread.hpp>
namespace { namespace {
/**
* We're hashing a nonce into the entries themselves, so we don't need extra
* blinding in the set hash computation.
*
* This may exhibit platform endian dependent behavior but because these are
* nonced hashes (random) and this state is only ever used locally it is safe.
* All that matters is local consistency.
*/
class SignatureCacheHasher
{
public:
template <uint8_t hash_select>
uint32_t operator()(const uint256& key) const
{
static_assert(hash_select <8, "SignatureCacheHasher only has 8 hashes available.");
uint32_t u;
std::memcpy(&u, key.begin()+4*hash_select, 4);
return u;
}
};
/** /**
* Valid signature cache, to avoid doing expensive ECDSA signature checking * Valid signature cache, to avoid doing expensive ECDSA signature checking
* twice for every transaction (once when accepted into memory pool, and * twice for every transaction (once when accepted into memory pool, and

21
src/script/sigcache.h

@ -19,6 +19,27 @@ static const int64_t MAX_MAX_SIG_CACHE_SIZE = 16384;
class CPubKey; class CPubKey;
/**
* We're hashing a nonce into the entries themselves, so we don't need extra
* blinding in the set hash computation.
*
* This may exhibit platform endian dependent behavior but because these are
* nonced hashes (random) and this state is only ever used locally it is safe.
* All that matters is local consistency.
*/
class SignatureCacheHasher
{
public:
template <uint8_t hash_select>
uint32_t operator()(const uint256& key) const
{
static_assert(hash_select <8, "SignatureCacheHasher only has 8 hashes available.");
uint32_t u;
std::memcpy(&u, key.begin()+4*hash_select, 4);
return u;
}
};
class CachingTransactionSignatureChecker : public TransactionSignatureChecker class CachingTransactionSignatureChecker : public TransactionSignatureChecker
{ {
private: private:

25
src/test/cuckoocache_tests.cpp

@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include "cuckoocache.h" #include "cuckoocache.h"
#include "script/sigcache.h"
#include "test/test_bitcoin.h" #include "test/test_bitcoin.h"
#include "random.h" #include "random.h"
#include <thread> #include <thread>
@ -36,20 +37,6 @@ void insecure_GetRandHash(uint256& t)
*(ptr++) = insecure_rand.rand32(); *(ptr++) = insecure_rand.rand32();
} }
/** Definition copied from /src/script/sigcache.cpp
*/
class uint256Hasher
{
public:
template <uint8_t hash_select>
uint32_t operator()(const uint256& key) const
{
static_assert(hash_select <8, "SignatureCacheHasher only has 8 hashes available.");
uint32_t u;
std::memcpy(&u, key.begin() + 4 * hash_select, 4);
return u;
}
};
/* Test that no values not inserted into the cache are read out of it. /* Test that no values not inserted into the cache are read out of it.
@ -59,7 +46,7 @@ public:
BOOST_AUTO_TEST_CASE(test_cuckoocache_no_fakes) BOOST_AUTO_TEST_CASE(test_cuckoocache_no_fakes)
{ {
insecure_rand = FastRandomContext(true); insecure_rand = FastRandomContext(true);
CuckooCache::cache<uint256, uint256Hasher> cc{}; CuckooCache::cache<uint256, SignatureCacheHasher> cc{};
size_t megabytes = 4; size_t megabytes = 4;
cc.setup_bytes(megabytes << 20); cc.setup_bytes(megabytes << 20);
uint256 v; uint256 v;
@ -138,7 +125,7 @@ BOOST_AUTO_TEST_CASE(cuckoocache_hit_rate_ok)
double HitRateThresh = 0.98; double HitRateThresh = 0.98;
size_t megabytes = 4; size_t megabytes = 4;
for (double load = 0.1; load < 2; load *= 2) { for (double load = 0.1; load < 2; load *= 2) {
double hits = test_cache<CuckooCache::cache<uint256, uint256Hasher>>(megabytes, load); double hits = test_cache<CuckooCache::cache<uint256, SignatureCacheHasher>>(megabytes, load);
BOOST_CHECK(normalize_hit_rate(hits, load) > HitRateThresh); BOOST_CHECK(normalize_hit_rate(hits, load) > HitRateThresh);
} }
} }
@ -206,7 +193,7 @@ void test_cache_erase(size_t megabytes)
BOOST_AUTO_TEST_CASE(cuckoocache_erase_ok) BOOST_AUTO_TEST_CASE(cuckoocache_erase_ok)
{ {
size_t megabytes = 4; size_t megabytes = 4;
test_cache_erase<CuckooCache::cache<uint256, uint256Hasher>>(megabytes); test_cache_erase<CuckooCache::cache<uint256, SignatureCacheHasher>>(megabytes);
} }
template <typename Cache> template <typename Cache>
@ -293,7 +280,7 @@ void test_cache_erase_parallel(size_t megabytes)
BOOST_AUTO_TEST_CASE(cuckoocache_erase_parallel_ok) BOOST_AUTO_TEST_CASE(cuckoocache_erase_parallel_ok)
{ {
size_t megabytes = 4; size_t megabytes = 4;
test_cache_erase_parallel<CuckooCache::cache<uint256, uint256Hasher>>(megabytes); test_cache_erase_parallel<CuckooCache::cache<uint256, SignatureCacheHasher>>(megabytes);
} }
@ -389,7 +376,7 @@ void test_cache_generations()
} }
BOOST_AUTO_TEST_CASE(cuckoocache_generations) BOOST_AUTO_TEST_CASE(cuckoocache_generations)
{ {
test_cache_generations<CuckooCache::cache<uint256, uint256Hasher>>(); test_cache_generations<CuckooCache::cache<uint256, SignatureCacheHasher>>();
} }
BOOST_AUTO_TEST_SUITE_END(); BOOST_AUTO_TEST_SUITE_END();

Loading…
Cancel
Save