Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto 2 : // Copyright (c) 2009-2019 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. 5 : 6 : #include <script/sigcache.h> 7 : 8 : #include <pubkey.h> 9 : #include <random.h> 10 : #include <uint256.h> 11 : #include <util/system.h> 12 : 13 : #include <cuckoocache.h> 14 : #include <boost/thread/shared_mutex.hpp> 15 : 16 : namespace { 17 : /** 18 : * Valid signature cache, to avoid doing expensive ECDSA signature checking 19 : * twice for every transaction (once when accepted into memory pool, and 20 : * again when accepted into the block chain) 21 : */ 22 1280 : class CSignatureCache 23 : { 24 : private: 25 : //! Entries are SHA256(nonce || signature hash || public key || signature): 26 : CSHA256 m_salted_hasher; 27 : typedef CuckooCache::cache<uint256, SignatureCacheHasher> map_type; 28 : map_type setValid; 29 : boost::shared_mutex cs_sigcache; 30 : 31 : public: 32 1280 : CSignatureCache() 33 640 : { 34 640 : uint256 nonce = GetRandHash(); 35 : // We want the nonce to be 64 bytes long to force the hasher to process 36 : // this chunk, which makes later hash computations more efficient. We 37 : // just write our 32-byte entropy twice to fill the 64 bytes. 38 640 : m_salted_hasher.Write(nonce.begin(), 32); 39 640 : m_salted_hasher.Write(nonce.begin(), 32); 40 1280 : } 41 : 42 : void 43 190555 : ComputeEntry(uint256& entry, const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubkey) 44 : { 45 190555 : CSHA256 hasher = m_salted_hasher; 46 190555 : hasher.Write(hash.begin(), 32).Write(&pubkey[0], pubkey.size()).Write(&vchSig[0], vchSig.size()).Finalize(entry.begin()); 47 190555 : } 48 : 49 : bool 50 191036 : Get(const uint256& entry, const bool erase) 51 : { 52 191036 : boost::shared_lock<boost::shared_mutex> lock(cs_sigcache); 53 191036 : return setValid.contains(entry, erase); 54 191125 : } 55 : 56 12368 : void Set(uint256& entry) 57 : { 58 12368 : boost::unique_lock<boost::shared_mutex> lock(cs_sigcache); 59 12368 : setValid.insert(entry); 60 12368 : } 61 988 : uint32_t setup_bytes(size_t n) 62 : { 63 988 : return setValid.setup_bytes(n); 64 : } 65 : }; 66 : 67 : /* In previous versions of this code, signatureCache was a local static variable 68 : * in CachingTransactionSignatureChecker::VerifySignature. We initialize 69 : * signatureCache outside of VerifySignature to avoid the atomic operation per 70 : * call overhead associated with local static variables even though 71 : * signatureCache could be made local to VerifySignature. 72 : */ 73 640 : static CSignatureCache signatureCache; 74 : } // namespace 75 : 76 : // To be called once in AppInitMain/BasicTestingSetup to initialize the 77 : // signatureCache. 78 988 : void InitSignatureCache() 79 : { 80 : // nMaxCacheSize is unsigned. If -maxsigcachesize is set to zero, 81 : // setup_bytes creates the minimum possible cache (2 elements). 82 988 : 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); 83 988 : size_t nElems = signatureCache.setup_bytes(nMaxCacheSize); 84 988 : LogPrintf("Using %zu MiB out of %zu/2 requested for signature cache, able to store %zu elements\n", 85 988 : (nElems*sizeof(uint256)) >>20, (nMaxCacheSize*2)>>20, nElems); 86 988 : } 87 : 88 190526 : bool CachingTransactionSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const 89 : { 90 190526 : uint256 entry; 91 190526 : signatureCache.ComputeEntry(entry, sighash, vchSig, pubkey); 92 190526 : if (signatureCache.Get(entry, !store)) 93 115787 : return true; 94 75345 : if (!TransactionSignatureChecker::VerifySignature(vchSig, pubkey, sighash)) 95 175 : return false; 96 75143 : if (store) 97 12368 : signatureCache.Set(entry); 98 75146 : return true; 99 191108 : }