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>
19 * Valid signature cache, to avoid doing expensive ECDSA signature checking
20 * twice for every transaction (once when accepted into memory pool, and
21 * again when accepted into the block chain)
26 //! Entries are SHA256(nonce || signature hash || public key || signature):
28 typedef CuckooCache::cache
<uint256
, SignatureCacheHasher
> map_type
;
30 boost::shared_mutex cs_sigcache
;
35 GetRandBytes(nonce
.begin(), 32);
39 ComputeEntry(uint256
& entry
, const uint256
&hash
, const std::vector
<unsigned char>& vchSig
, const CPubKey
& pubkey
)
41 CSHA256().Write(nonce
.begin(), 32).Write(hash
.begin(), 32).Write(&pubkey
[0], pubkey
.size()).Write(&vchSig
[0], vchSig
.size()).Finalize(entry
.begin());
45 Get(const uint256
& entry
, const bool erase
)
47 boost::shared_lock
<boost::shared_mutex
> lock(cs_sigcache
);
48 return setValid
.contains(entry
, erase
);
51 void Set(uint256
& entry
)
53 boost::unique_lock
<boost::shared_mutex
> lock(cs_sigcache
);
54 setValid
.insert(entry
);
56 uint32_t setup_bytes(size_t n
)
58 return setValid
.setup_bytes(n
);
62 /* In previous versions of this code, signatureCache was a local static variable
63 * in CachingTransactionSignatureChecker::VerifySignature. We initialize
64 * signatureCache outside of VerifySignature to avoid the atomic operation per
65 * call overhead associated with local static variables even though
66 * signatureCache could be made local to VerifySignature.
68 static CSignatureCache signatureCache
;
71 // To be called once in AppInitMain/BasicTestingSetup to initialize the
73 void InitSignatureCache()
75 // nMaxCacheSize is unsigned. If -maxsigcachesize is set to zero,
76 // setup_bytes creates the minimum possible cache (2 elements).
77 size_t nMaxCacheSize
= std::min(std::max((int64_t)0, gArgs
.GetArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE
) / 2), MAX_MAX_SIG_CACHE_SIZE
) * ((size_t) 1 << 20);
78 size_t nElems
= signatureCache
.setup_bytes(nMaxCacheSize
);
79 LogPrintf("Using %zu MiB out of %zu/2 requested for signature cache, able to store %zu elements\n",
80 (nElems
*sizeof(uint256
)) >>20, (nMaxCacheSize
*2)>>20, nElems
);
83 bool CachingTransactionSignatureChecker::VerifySignature(const std::vector
<unsigned char>& vchSig
, const CPubKey
& pubkey
, const uint256
& sighash
) const
86 signatureCache
.ComputeEntry(entry
, sighash
, vchSig
, pubkey
);
87 if (signatureCache
.Get(entry
, !store
))
89 if (!TransactionSignatureChecker::VerifySignature(vchSig
, pubkey
, sighash
))
92 signatureCache
.Set(entry
);