LCOV - code coverage report
Current view: top level - src/script - sigcache.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 29 29 100.0 %
Date: 2025-02-23 09:33:43 Functions: 6 6 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2014 The Bitcoin developers
       3             : // Copyright (c) 2018-2021 The PIVX Core developers
       4             : // Distributed under the MIT software license, see the accompanying
       5             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       6             : 
       7             : #include "sigcache.h"
       8             : 
       9             : #include "cuckoocache.h"
      10             : #include "memusage.h"
      11             : #include "pubkey.h"
      12             : #include "random.h"
      13             : #include "uint256.h"
      14             : #include "util/system.h"
      15             : 
      16             : #include <boost/thread/thread.hpp>
      17             : 
      18             : namespace {
      19             : /**
      20             :  * Valid signature cache, to avoid doing expensive ECDSA signature checking
      21             :  * twice for every transaction (once when accepted into memory pool, and
      22             :  * again when accepted into the block chain)
      23             :  */
      24             : class CSignatureCache
      25             : {
      26             : private:
      27             :      //! Entries are SHA256(nonce || signature hash || public key || signature):
      28             :     uint256 nonce;
      29             :     typedef CuckooCache::cache<uint256, SignatureCacheHasher> map_type;
      30             :     map_type setValid;
      31             :     boost::shared_mutex cs_sigcache;
      32             : 
      33             : public:
      34         479 :     CSignatureCache()
      35         958 :     {
      36         479 :         GetRandBytes(nonce.begin(), 32);
      37         479 :     }
      38             : 
      39             :     void
      40     1419348 :     ComputeEntry(uint256& entry, const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubkey)
      41             :     {
      42     1423848 :         CSHA256().Write(nonce.begin(), 32).Write(hash.begin(), 32).Write(pubkey.data(), pubkey.size()).Write(vchSig.data(), vchSig.size()).Finalize(entry.begin());
      43     1419348 :     }
      44             : 
      45             :     bool
      46     1419348 :     Get(const uint256& entry, const bool erase)
      47             :     {
      48     1419348 :         boost::shared_lock<boost::shared_mutex> lock(cs_sigcache);
      49     1419348 :         return setValid.contains(entry, erase);
      50             :     }
      51             : 
      52      211326 :     void Set(uint256& entry)
      53             :     {
      54      211326 :         boost::unique_lock<boost::shared_mutex> lock(cs_sigcache);
      55      211326 :         setValid.insert(entry);
      56      211326 :     }
      57         791 :     uint32_t setup_bytes(size_t n)
      58             :     {
      59        1582 :         return setValid.setup_bytes(n);
      60             :     }
      61             : };
      62             : 
      63             : /* In previous versions of this code, signatureCache was a local static variable
      64             :  * in CachingTransactionSignatureChecker::VerifySignature.  We initialize
      65             :  * signatureCache outside of VerifySignature to avoid the atomic operation per
      66             :  * call overhead associated with local static variables even though
      67             :  * signatureCache could be made local to VerifySignature.
      68             : */
      69             : static CSignatureCache signatureCache;
      70             : }
      71             : 
      72             : // To be called once in AppInitMain/BasicTestingSetup to initialize the
      73             : // signatureCache.
      74         791 : void InitSignatureCache()
      75             : {
      76             :     // nMaxCacheSize is unsigned. If -maxsigcachesize is set to zero,
      77             :     // setup_bytes creates the minimum possible cache (2 elements).
      78        1582 :     size_t nMaxCacheSize = std::min(std::max((int64_t)0, gArgs.GetArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE)), MAX_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20);
      79         791 :     size_t nElems = signatureCache.setup_bytes(nMaxCacheSize);
      80         791 :     LogPrintf("Using %zu MiB out of %zu requested for signature cache, able to store %zu elements\n",
      81         791 :             (nElems*sizeof(uint256)) >>20, nMaxCacheSize>>20, nElems);
      82         791 : }
      83             : 
      84     1419348 : bool CachingTransactionSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
      85             : {
      86     1419348 :     uint256 entry;
      87     1419348 :     signatureCache.ComputeEntry(entry, sighash, vchSig, pubkey);
      88     1419348 :     if (signatureCache.Get(entry, !store))
      89             :         return true;
      90      397519 :     if (!TransactionSignatureChecker::VerifySignature(vchSig, pubkey, sighash))
      91             :         return false;
      92      397508 :     if (store)
      93      211326 :         signatureCache.Set(entry);
      94             :     return true;
      95             : }

Generated by: LCOV version 1.14