Bitcoin ABC  0.26.3
P2P Digital Currency
sigcache.cpp
Go to the documentation of this file.
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.
5 
6 #include <script/sigcache.h>
7 
8 #include <cuckoocache.h>
9 #include <pubkey.h>
10 #include <random.h>
11 #include <uint256.h>
12 #include <util/system.h>
13 
14 #include <algorithm>
15 #include <mutex>
16 #include <shared_mutex>
17 #include <vector>
18 
19 namespace {
20 
26 class CSignatureCache {
27 private:
29  CSHA256 m_salted_hasher;
32  map_type;
33  map_type setValid;
34  std::shared_mutex cs_sigcache;
35 
36 public:
37  CSignatureCache() {
38  uint256 nonce = GetRandHash();
39  // We want the nonce to be 64 bytes long to force the hasher to process
40  // this chunk, which makes later hash computations more efficient. We
41  // just write our 32-byte entropy twice to fill the 64 bytes.
42  m_salted_hasher.Write(nonce.begin(), 32);
43  m_salted_hasher.Write(nonce.begin(), 32);
44  }
45 
46  void ComputeEntry(uint256 &entry, const uint256 &hash,
47  const std::vector<uint8_t> &vchSig,
48  const CPubKey &pubkey) {
49  CSHA256 hasher = m_salted_hasher;
50  hasher.Write(hash.begin(), 32)
51  .Write(pubkey.data(), pubkey.size())
52  .Write(vchSig.data(), vchSig.size())
53  .Finalize(entry.begin());
54  }
55 
56  bool Get(const uint256 &entry, const bool erase) {
57  std::shared_lock<std::shared_mutex> lock(cs_sigcache);
58  return setValid.contains(entry, erase);
59  }
60 
61  void Set(const uint256 &entry) {
62  std::unique_lock<std::shared_mutex> lock(cs_sigcache);
63  setValid.insert(entry);
64  }
65  uint32_t setup_bytes(size_t n) { return setValid.setup_bytes(n); }
66 };
67 
75 static CSignatureCache signatureCache;
76 } // namespace
77 
78 // To be called once in AppInitMain/BasicTestingSetup to initialize the
79 // signatureCache.
81  // nMaxCacheSize is unsigned. If -maxsigcachesize is set to zero,
82  // setup_bytes creates the minimum possible cache (2 elements).
83  size_t nMaxCacheSize =
84  std::min(
85  std::max(int64_t(0), gArgs.GetIntArg("-maxsigcachesize",
88  (size_t(1) << 20);
89  size_t nElems = signatureCache.setup_bytes(nMaxCacheSize);
90  LogPrintf("Using %zu MiB out of %zu requested for signature cache, able to "
91  "store %zu elements\n",
92  (nElems * sizeof(uint256)) >> 20, nMaxCacheSize >> 20, nElems);
93 }
94 
95 template <typename F>
96 bool RunMemoizedCheck(const std::vector<uint8_t> &vchSig, const CPubKey &pubkey,
97  const uint256 &sighash, bool storeOrErase, const F &fun) {
98  uint256 entry;
99  signatureCache.ComputeEntry(entry, sighash, vchSig, pubkey);
100  if (signatureCache.Get(entry, !storeOrErase)) {
101  return true;
102  }
103  if (!fun()) {
104  return false;
105  }
106  if (storeOrErase) {
107  signatureCache.Set(entry);
108  }
109  return true;
110 }
111 
113  const std::vector<uint8_t> &vchSig, const CPubKey &pubkey,
114  const uint256 &sighash) const {
115  return RunMemoizedCheck(vchSig, pubkey, sighash, true,
116  [] { return false; });
117 }
118 
120  const std::vector<uint8_t> &vchSig, const CPubKey &pubkey,
121  const uint256 &sighash) const {
122  return RunMemoizedCheck(vchSig, pubkey, sighash, store, [&] {
123  return TransactionSignatureChecker::VerifySignature(vchSig, pubkey,
124  sighash);
125  });
126 }
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
Definition: system.cpp:634
virtual bool VerifySignature(const std::vector< uint8_t > &vchSig, const CPubKey &vchPubKey, const uint256 &sighash) const
An encapsulated public key.
Definition: pubkey.h:31
const uint8_t * data() const
Definition: pubkey.h:99
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
Definition: pubkey.h:98
A hasher class for SHA-256.
Definition: sha256.h:13
CSHA256 & Write(const uint8_t *data, size_t len)
Definition: sha256.cpp:819
void Finalize(uint8_t hash[OUTPUT_SIZE])
Definition: sha256.cpp:844
bool VerifySignature(const std::vector< uint8_t > &vchSig, const CPubKey &vchPubKey, const uint256 &sighash) const override
Definition: sigcache.cpp:119
bool IsCached(const std::vector< uint8_t > &vchSig, const CPubKey &vchPubKey, const uint256 &sighash) const
Definition: sigcache.cpp:112
cache implements a cache with properties similar to a cuckoo-set.
Definition: cuckoocache.h:165
We're hashing a nonce into the entries themselves, so we don't need extra blinding in the set hash co...
Definition: hasher.h:80
uint8_t * begin()
Definition: uint256.h:83
256-bit opaque blob.
Definition: uint256.h:127
#define LogPrintf(...)
Definition: logging.h:206
uint256 GetRandHash() noexcept
Definition: random.cpp:659
bool RunMemoizedCheck(const std::vector< uint8_t > &vchSig, const CPubKey &pubkey, const uint256 &sighash, bool storeOrErase, const F &fun)
Definition: sigcache.cpp:96
void InitSignatureCache()
Definition: sigcache.cpp:80
static const unsigned int DEFAULT_MAX_SIG_CACHE_SIZE
Definition: sigcache.h:17
static const int64_t MAX_MAX_SIG_CACHE_SIZE
Definition: sigcache.h:19
ArgsManager gArgs
Definition: system.cpp:79