sigcache.h raw

   1  // Copyright (c) 2009-2010 Satoshi Nakamoto
   2  // Copyright (c) 2009-2022 The Limenka 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  #ifndef LIMENKA_SCRIPT_SIGCACHE_H
   7  #define LIMENKA_SCRIPT_SIGCACHE_H
   8  
   9  #include <consensus/amount.h>
  10  #include <crypto/sha256.h>
  11  #include <cuckoocache.h>
  12  #include <script/interpreter.h>
  13  #include <span.h>
  14  #include <uint256.h>
  15  #include <util/hasher.h>
  16  
  17  #include <cstddef>
  18  #include <shared_mutex>
  19  #include <vector>
  20  
  21  class CPubKey;
  22  class CTransaction;
  23  class XOnlyPubKey;
  24  
  25  // DoS prevention: limit cache size to 32MiB (over 1000000 entries on 64-bit
  26  // systems). Due to how we count cache size, actual memory usage is slightly
  27  // more (~32.25 MiB)
  28  static constexpr size_t DEFAULT_VALIDATION_CACHE_BYTES{32 << 20};
  29  static constexpr size_t DEFAULT_SIGNATURE_CACHE_BYTES{DEFAULT_VALIDATION_CACHE_BYTES / 2};
  30  static constexpr size_t DEFAULT_SCRIPT_EXECUTION_CACHE_BYTES{DEFAULT_VALIDATION_CACHE_BYTES / 2};
  31  static_assert(DEFAULT_VALIDATION_CACHE_BYTES == DEFAULT_SIGNATURE_CACHE_BYTES + DEFAULT_SCRIPT_EXECUTION_CACHE_BYTES);
  32  
  33  /**
  34   * Valid signature cache, to avoid doing expensive ECDSA signature checking
  35   * twice for every transaction (once when accepted into memory pool, and
  36   * again when accepted into the block chain)
  37   */
  38  class SignatureCache
  39  {
  40  private:
  41      //! Entries are SHA256(nonce || 'E' or 'S' || 31 zero bytes || signature hash || public key || signature):
  42      CSHA256 m_salted_hasher_ecdsa;
  43      CSHA256 m_salted_hasher_schnorr;
  44      typedef CuckooCache::cache<uint256, SignatureCacheHasher> map_type;
  45      map_type setValid;
  46      std::shared_mutex cs_sigcache;
  47  
  48  public:
  49      SignatureCache(size_t max_size_bytes);
  50  
  51      SignatureCache(const SignatureCache&) = delete;
  52      SignatureCache& operator=(const SignatureCache&) = delete;
  53  
  54      void ComputeEntryECDSA(uint256& entry, const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubkey) const;
  55  
  56      void ComputeEntrySchnorr(uint256& entry, const uint256 &hash, Span<const unsigned char> sig, const XOnlyPubKey& pubkey) const;
  57  
  58      bool Get(const uint256& entry, const bool erase);
  59  
  60      void Set(const uint256& entry);
  61  };
  62  
  63  class CachingTransactionSignatureChecker : public TransactionSignatureChecker
  64  {
  65  private:
  66      bool store;
  67      SignatureCache& m_signature_cache;
  68  
  69  public:
  70      CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, bool storeIn, SignatureCache& signature_cache, PrecomputedTransactionData& txdataIn) : TransactionSignatureChecker(txToIn, nInIn, amountIn, txdataIn, MissingDataBehavior::ASSERT_FAIL), store(storeIn), m_signature_cache(signature_cache)  {}
  71  
  72      bool VerifyECDSASignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const override;
  73      bool VerifySchnorrSignature(Span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const override;
  74  };
  75  
  76  #endif // LIMENKA_SCRIPT_SIGCACHE_H
  77