Bitcoin ABC 0.30.5
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 <common/system.h>
9#include <cuckoocache.h>
10#include <logging.h>
11#include <pubkey.h>
12#include <random.h>
13#include <uint256.h>
14
15#include <algorithm>
16#include <mutex>
17#include <optional>
18#include <shared_mutex>
19#include <vector>
20
21namespace {
22
28class CSignatureCache {
29private:
31 CSHA256 m_salted_hasher;
34 map_type;
35 map_type setValid;
36 std::shared_mutex cs_sigcache;
37
38public:
39 CSignatureCache() {
40 uint256 nonce = GetRandHash();
41 // We want the nonce to be 64 bytes long to force the hasher to process
42 // this chunk, which makes later hash computations more efficient. We
43 // just write our 32-byte entropy twice to fill the 64 bytes.
44 m_salted_hasher.Write(nonce.begin(), 32);
45 m_salted_hasher.Write(nonce.begin(), 32);
46 }
47
48 void ComputeEntry(uint256 &entry, const uint256 &hash,
49 const std::vector<uint8_t> &vchSig,
50 const CPubKey &pubkey) {
51 CSHA256 hasher = m_salted_hasher;
52 hasher.Write(hash.begin(), 32)
53 .Write(pubkey.data(), pubkey.size())
54 .Write(vchSig.data(), vchSig.size())
55 .Finalize(entry.begin());
56 }
57
58 bool Get(const uint256 &entry, const bool erase) {
59 std::shared_lock<std::shared_mutex> lock(cs_sigcache);
60 return setValid.contains(entry, erase);
61 }
62
63 void Set(const uint256 &entry) {
64 std::unique_lock<std::shared_mutex> lock(cs_sigcache);
65 setValid.insert(entry);
66 }
67 std::optional<std::pair<uint32_t, size_t>> setup_bytes(size_t n) {
68 return setValid.setup_bytes(n);
69 }
70};
71
79static CSignatureCache signatureCache;
80} // namespace
81
82// To be called once in AppInitMain/BasicTestingSetup to initialize the
83// signatureCache.
84
85bool InitSignatureCache(size_t max_size_bytes) {
86 auto setup_results = signatureCache.setup_bytes(max_size_bytes);
87 if (!setup_results) {
88 return false;
89 }
90
91 const auto [num_elems, approx_size_bytes] = *setup_results;
92 LogPrintf("Using %zu MiB out of %zu MiB requested for signature cache, "
93 "able to store %zu elements\n",
94 approx_size_bytes >> 20, max_size_bytes >> 20, num_elems);
95 return true;
96}
97
98template <typename F>
99bool RunMemoizedCheck(const std::vector<uint8_t> &vchSig, const CPubKey &pubkey,
100 const uint256 &sighash, bool storeOrErase, const F &fun) {
101 uint256 entry;
102 signatureCache.ComputeEntry(entry, sighash, vchSig, pubkey);
103 if (signatureCache.Get(entry, !storeOrErase)) {
104 return true;
105 }
106 if (!fun()) {
107 return false;
108 }
109 if (storeOrErase) {
110 signatureCache.Set(entry);
111 }
112 return true;
113}
114
116 const std::vector<uint8_t> &vchSig, const CPubKey &pubkey,
117 const uint256 &sighash) const {
118 return RunMemoizedCheck(vchSig, pubkey, sighash, true,
119 [] { return false; });
120}
121
123 const std::vector<uint8_t> &vchSig, const CPubKey &pubkey,
124 const uint256 &sighash) const {
125 return RunMemoizedCheck(vchSig, pubkey, sighash, store, [&] {
127 sighash);
128 });
129}
virtual bool VerifySignature(const std::vector< uint8_t > &vchSig, const CPubKey &vchPubKey, const uint256 &sighash) const
An encapsulated public key.
Definition: pubkey.h:31
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
Definition: pubkey.h:98
const uint8_t * data() const
Definition: pubkey.h:99
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:122
bool IsCached(const std::vector< uint8_t > &vchSig, const CPubKey &vchPubKey, const uint256 &sighash) const
Definition: sigcache.cpp:115
cache implements a cache with properties similar to a cuckoo-set.
Definition: cuckoocache.h:167
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:85
256-bit opaque blob.
Definition: uint256.h:129
#define LogPrintf(...)
Definition: logging.h:207
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:99
bool InitSignatureCache(size_t max_size_bytes)
Definition: sigcache.cpp:85