1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
14 #include "cuckoocache.h"
15 #include <boost/thread.hpp>
20 * We're hashing a nonce into the entries themselves, so we don't need extra
21 * blinding in the set hash computation.
23 * This may exhibit platform endian dependent behavior but because these are
24 * nonced hashes (random) and this state is only ever used locally it is safe.
25 * All that matters is local consistency.
27 class SignatureCacheHasher
30 template <uint8_t hash_select
>
31 uint32_t operator()(const uint256
& key
) const
33 static_assert(hash_select
<8, "SignatureCacheHasher only has 8 hashes available.");
35 std::memcpy(&u
, key
.begin()+4*hash_select
, 4);
41 * Valid signature cache, to avoid doing expensive ECDSA signature checking
42 * twice for every transaction (once when accepted into memory pool, and
43 * again when accepted into the block chain)
48 //! Entries are SHA256(nonce || signature hash || public key || signature):
50 typedef CuckooCache::cache
<uint256
, SignatureCacheHasher
> map_type
;
52 boost::shared_mutex cs_sigcache
;
57 GetRandBytes(nonce
.begin(), 32);
61 ComputeEntry(uint256
& entry
, const uint256
&hash
, const std::vector
<unsigned char>& vchSig
, const CPubKey
& pubkey
)
63 CSHA256().Write(nonce
.begin(), 32).Write(hash
.begin(), 32).Write(&pubkey
[0], pubkey
.size()).Write(&vchSig
[0], vchSig
.size()).Finalize(entry
.begin());
67 Get(const uint256
& entry
, const bool erase
)
69 boost::shared_lock
<boost::shared_mutex
> lock(cs_sigcache
);
70 return setValid
.contains(entry
, erase
);
73 void Set(uint256
& entry
)
75 boost::unique_lock
<boost::shared_mutex
> lock(cs_sigcache
);
76 setValid
.insert(entry
);
78 uint32_t setup_bytes(size_t n
)
80 return setValid
.setup_bytes(n
);
84 /* In previous versions of this code, signatureCache was a local static variable
85 * in CachingTransactionSignatureChecker::VerifySignature. We initialize
86 * signatureCache outside of VerifySignature to avoid the atomic operation per
87 * call overhead associated with local static variables even though
88 * signatureCache could be made local to VerifySignature.
90 static CSignatureCache signatureCache
;
93 // To be called once in AppInitMain/BasicTestingSetup to initialize the
95 void InitSignatureCache()
97 // nMaxCacheSize is unsigned. If -maxsigcachesize is set to zero,
98 // setup_bytes creates the minimum possible cache (2 elements).
99 size_t nMaxCacheSize
= std::min(std::max((int64_t)0, GetArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE
)), MAX_MAX_SIG_CACHE_SIZE
) * ((size_t) 1 << 20);
100 size_t nElems
= signatureCache
.setup_bytes(nMaxCacheSize
);
101 LogPrintf("Using %zu MiB out of %zu requested for signature cache, able to store %zu elements\n",
102 (nElems
*sizeof(uint256
)) >>20, nMaxCacheSize
>>20, nElems
);
105 bool CachingTransactionSignatureChecker::VerifySignature(const std::vector
<unsigned char>& vchSig
, const CPubKey
& pubkey
, const uint256
& sighash
) const
108 signatureCache
.ComputeEntry(entry
, sighash
, vchSig
, pubkey
);
109 if (signatureCache
.Get(entry
, !store
))
111 if (!TransactionSignatureChecker::VerifySignature(vchSig
, pubkey
, sighash
))
114 signatureCache
.Set(entry
);