Bitcoin ABC 0.32.4
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 <crypto/sha256.h>
9#include <logging.h>
10#include <pubkey.h>
11#include <random.h>
12#include <script/interpreter.h>
13#include <span.h>
14#include <uint256.h>
15
16#include <mutex>
17#include <shared_mutex>
18#include <vector>
19
20SignatureCache::SignatureCache(const size_t max_size_bytes) {
21 uint256 nonce = GetRandHash();
22 // We want the nonce to be 64 bytes long to force the hasher to process
23 // this chunk, which makes later hash computations more efficient. We
24 // just write our 32-byte entropy twice to fill the 64 bytes.
25 m_salted_hasher.Write(nonce.begin(), 32);
26 m_salted_hasher.Write(nonce.begin(), 32);
27
28 const auto [num_elems, approx_size_bytes] =
29 setValid.setup_bytes(max_size_bytes);
30 LogPrintf("Using %zu MiB out of %zu MiB requested for signature cache, "
31 "able to store %zu elements\n",
32 approx_size_bytes >> 20, max_size_bytes >> 20, num_elems);
33}
34
36 const std::vector<uint8_t> &vchSig,
37 const CPubKey &pubkey) const {
38 CSHA256 hasher = m_salted_hasher;
39 hasher.Write(hash.begin(), 32)
40 .Write(pubkey.data(), pubkey.size())
41 .Write(vchSig.data(), vchSig.size())
42 .Finalize(entry.begin());
43}
44
45bool SignatureCache::Get(const uint256 &entry, const bool erase) {
46 std::shared_lock<std::shared_mutex> lock(cs_sigcache);
47 return setValid.contains(entry, erase);
48}
49
50void SignatureCache::Set(const uint256 &entry) {
51 std::unique_lock<std::shared_mutex> lock(cs_sigcache);
52 setValid.insert(entry);
53}
54
55template <typename F>
56bool RunMemoizedCheck(SignatureCache &signatureCache,
57 const std::vector<uint8_t> &vchSig, const CPubKey &pubkey,
58 const uint256 &sighash, bool storeOrErase, const F &fun) {
59 uint256 entry;
60 signatureCache.ComputeEntry(entry, sighash, vchSig, pubkey);
61 if (signatureCache.Get(entry, !storeOrErase)) {
62 return true;
63 }
64 if (!fun()) {
65 return false;
66 }
67 if (storeOrErase) {
68 signatureCache.Set(entry);
69 }
70 return true;
71}
72
74 const std::vector<uint8_t> &vchSig, const CPubKey &pubkey,
75 const uint256 &sighash) const {
76 return RunMemoizedCheck(m_signature_cache, vchSig, pubkey, sighash, true,
77 [] { return false; });
78}
79
81 const std::vector<uint8_t> &vchSig, const CPubKey &pubkey,
82 const uint256 &sighash) const {
83 return RunMemoizedCheck(
84 m_signature_cache, vchSig, pubkey, sighash, store, [&] {
86 sighash);
87 });
88}
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:80
bool IsCached(const std::vector< uint8_t > &vchSig, const CPubKey &vchPubKey, const uint256 &sighash) const
Definition: sigcache.cpp:73
SignatureCache & m_signature_cache
Definition: sigcache.h:61
std::pair< uint32_t, size_t > setup_bytes(size_t bytes)
setup_bytes is a convenience function which accounts for internal memory usage when deciding how many...
Definition: cuckoocache.h:386
bool contains(const Key &k, const bool erase) const
contains iterates through the hash locations for a given element and checks to see if it is present.
Definition: cuckoocache.h:507
void insert(Element e, bool replace=false)
insert loops at most depth_limit times trying to insert a hash at various locations in the table via ...
Definition: cuckoocache.h:421
Valid signature cache, to avoid doing expensive ECDSA signature checking twice for every transaction ...
Definition: sigcache.h:33
SignatureCache(size_t max_size_bytes)
Definition: sigcache.cpp:20
void ComputeEntry(uint256 &entry, const uint256 &hash, const std::vector< uint8_t > &vchSig, const CPubKey &pubkey) const
Definition: sigcache.cpp:35
map_type setValid
Definition: sigcache.h:40
CSHA256 m_salted_hasher
Entries are SHA256(nonce || signature hash || public key || signature):
Definition: sigcache.h:36
std::shared_mutex cs_sigcache
Definition: sigcache.h:41
bool Get(const uint256 &entry, const bool erase)
Definition: sigcache.cpp:45
void Set(const uint256 &entry)
Definition: sigcache.cpp:50
uint8_t * begin()
Definition: uint256.h:85
256-bit opaque blob.
Definition: uint256.h:129
#define LogPrintf(...)
Definition: logging.h:424
uint256 GetRandHash() noexcept
Definition: random.cpp:662
bool RunMemoizedCheck(SignatureCache &signatureCache, const std::vector< uint8_t > &vchSig, const CPubKey &pubkey, const uint256 &sighash, bool storeOrErase, const F &fun)
Definition: sigcache.cpp:56