LCOV - code coverage report
Current view: top level - src/script - sigcache.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 39 39 100.0 %
Date: 2020-09-26 01:30:44 Functions: 11 11 100.0 %

          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 : }

Generated by: LCOV version 1.15