Skip to content

Commit 66d74bf

Browse files
committed
Expose CSignatureCache class in header
This is done in preparation for the following commit. Also rename it to SignatureCache.
1 parent 021d388 commit 66d74bf

File tree

2 files changed

+81
-63
lines changed

2 files changed

+81
-63
lines changed

src/script/sigcache.cpp

Lines changed: 41 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -5,91 +5,69 @@
55

66
#include <script/sigcache.h>
77

8-
#include <common/system.h>
8+
#include <crypto/sha256.h>
99
#include <logging.h>
1010
#include <pubkey.h>
1111
#include <random.h>
12+
#include <script/interpreter.h>
13+
#include <span.h>
1214
#include <uint256.h>
1315

14-
#include <cuckoocache.h>
15-
16-
#include <algorithm>
1716
#include <mutex>
1817
#include <shared_mutex>
1918
#include <vector>
2019

21-
namespace {
22-
/**
23-
* Valid signature cache, to avoid doing expensive ECDSA signature checking
24-
* twice for every transaction (once when accepted into memory pool, and
25-
* again when accepted into the block chain)
26-
*/
27-
class CSignatureCache
20+
SignatureCache::SignatureCache()
2821
{
29-
private:
30-
//! Entries are SHA256(nonce || 'E' or 'S' || 31 zero bytes || signature hash || public key || signature):
31-
CSHA256 m_salted_hasher_ecdsa;
32-
CSHA256 m_salted_hasher_schnorr;
33-
typedef CuckooCache::cache<uint256, SignatureCacheHasher> map_type;
34-
map_type setValid;
35-
std::shared_mutex cs_sigcache;
22+
uint256 nonce = GetRandHash();
23+
// We want the nonce to be 64 bytes long to force the hasher to process
24+
// this chunk, which makes later hash computations more efficient. We
25+
// just write our 32-byte entropy, and then pad with 'E' for ECDSA and
26+
// 'S' for Schnorr (followed by 0 bytes).
27+
static constexpr unsigned char PADDING_ECDSA[32] = {'E'};
28+
static constexpr unsigned char PADDING_SCHNORR[32] = {'S'};
29+
m_salted_hasher_ecdsa.Write(nonce.begin(), 32);
30+
m_salted_hasher_ecdsa.Write(PADDING_ECDSA, 32);
31+
m_salted_hasher_schnorr.Write(nonce.begin(), 32);
32+
m_salted_hasher_schnorr.Write(PADDING_SCHNORR, 32);
33+
}
3634

37-
public:
38-
CSignatureCache()
39-
{
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, and then pad with 'E' for ECDSA and
44-
// 'S' for Schnorr (followed by 0 bytes).
45-
static constexpr unsigned char PADDING_ECDSA[32] = {'E'};
46-
static constexpr unsigned char PADDING_SCHNORR[32] = {'S'};
47-
m_salted_hasher_ecdsa.Write(nonce.begin(), 32);
48-
m_salted_hasher_ecdsa.Write(PADDING_ECDSA, 32);
49-
m_salted_hasher_schnorr.Write(nonce.begin(), 32);
50-
m_salted_hasher_schnorr.Write(PADDING_SCHNORR, 32);
51-
}
35+
void SignatureCache::ComputeEntryECDSA(uint256& entry, const uint256& hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubkey) const
36+
{
37+
CSHA256 hasher = m_salted_hasher_ecdsa;
38+
hasher.Write(hash.begin(), 32).Write(pubkey.data(), pubkey.size()).Write(vchSig.data(), vchSig.size()).Finalize(entry.begin());
39+
}
5240

53-
void
54-
ComputeEntryECDSA(uint256& entry, const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubkey) const
55-
{
56-
CSHA256 hasher = m_salted_hasher_ecdsa;
57-
hasher.Write(hash.begin(), 32).Write(pubkey.data(), pubkey.size()).Write(vchSig.data(), vchSig.size()).Finalize(entry.begin());
58-
}
41+
void SignatureCache::ComputeEntrySchnorr(uint256& entry, const uint256& hash, Span<const unsigned char> sig, const XOnlyPubKey& pubkey) const
42+
{
43+
CSHA256 hasher = m_salted_hasher_schnorr;
44+
hasher.Write(hash.begin(), 32).Write(pubkey.data(), pubkey.size()).Write(sig.data(), sig.size()).Finalize(entry.begin());
45+
}
5946

60-
void
61-
ComputeEntrySchnorr(uint256& entry, const uint256 &hash, Span<const unsigned char> sig, const XOnlyPubKey& pubkey) const
62-
{
63-
CSHA256 hasher = m_salted_hasher_schnorr;
64-
hasher.Write(hash.begin(), 32).Write(pubkey.data(), pubkey.size()).Write(sig.data(), sig.size()).Finalize(entry.begin());
65-
}
47+
bool SignatureCache::Get(const uint256& entry, const bool erase)
48+
{
49+
std::shared_lock<std::shared_mutex> lock(cs_sigcache);
50+
return setValid.contains(entry, erase);
51+
}
6652

67-
bool
68-
Get(const uint256& entry, const bool erase)
69-
{
70-
std::shared_lock<std::shared_mutex> lock(cs_sigcache);
71-
return setValid.contains(entry, erase);
72-
}
53+
void SignatureCache::Set(const uint256& entry)
54+
{
55+
std::unique_lock<std::shared_mutex> lock(cs_sigcache);
56+
setValid.insert(entry);
57+
}
7358

74-
void Set(const uint256& entry)
75-
{
76-
std::unique_lock<std::shared_mutex> lock(cs_sigcache);
77-
setValid.insert(entry);
78-
}
79-
std::pair<uint32_t, size_t> setup_bytes(size_t n)
80-
{
81-
return setValid.setup_bytes(n);
82-
}
83-
};
59+
std::pair<uint32_t, size_t> SignatureCache::setup_bytes(size_t n)
60+
{
61+
return setValid.setup_bytes(n);
62+
}
8463

8564
/* In previous versions of this code, signatureCache was a local static variable
8665
* in CachingTransactionSignatureChecker::VerifySignature. We initialize
8766
* signatureCache outside of VerifySignature to avoid the atomic operation per
8867
* call overhead associated with local static variables even though
8968
* signatureCache could be made local to VerifySignature.
9069
*/
91-
static CSignatureCache signatureCache;
92-
} // namespace
70+
static SignatureCache signatureCache;
9371

9472
// To be called once in AppInitMain/BasicTestingSetup to initialize the
9573
// signatureCache.

src/script/sigcache.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,23 @@
66
#ifndef BITCOIN_SCRIPT_SIGCACHE_H
77
#define BITCOIN_SCRIPT_SIGCACHE_H
88

9+
#include <consensus/amount.h>
10+
#include <crypto/sha256.h>
11+
#include <cuckoocache.h>
912
#include <script/interpreter.h>
1013
#include <span.h>
14+
#include <uint256.h>
1115
#include <util/hasher.h>
1216

17+
#include <cstddef>
18+
#include <cstdint>
19+
#include <shared_mutex>
20+
#include <utility>
1321
#include <vector>
1422

23+
class CTransaction;
24+
class XOnlyPubKey;
25+
1526
// DoS prevention: limit cache size to 32MiB (over 1000000 entries on 64-bit
1627
// systems). Due to how we count cache size, actual memory usage is slightly
1728
// more (~32.25 MiB)
@@ -20,6 +31,35 @@ static constexpr size_t DEFAULT_SCRIPT_EXECUTION_CACHE_BYTES{DEFAULT_MAX_SIG_CAC
2031

2132
class CPubKey;
2233

34+
/**
35+
* Valid signature cache, to avoid doing expensive ECDSA signature checking
36+
* twice for every transaction (once when accepted into memory pool, and
37+
* again when accepted into the block chain)
38+
*/
39+
class SignatureCache
40+
{
41+
private:
42+
//! Entries are SHA256(nonce || 'E' or 'S' || 31 zero bytes || signature hash || public key || signature):
43+
CSHA256 m_salted_hasher_ecdsa;
44+
CSHA256 m_salted_hasher_schnorr;
45+
typedef CuckooCache::cache<uint256, SignatureCacheHasher> map_type;
46+
map_type setValid;
47+
std::shared_mutex cs_sigcache;
48+
49+
public:
50+
SignatureCache();
51+
52+
void ComputeEntryECDSA(uint256& entry, const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubkey) const;
53+
54+
void ComputeEntrySchnorr(uint256& entry, const uint256 &hash, Span<const unsigned char> sig, const XOnlyPubKey& pubkey) const;
55+
56+
bool Get(const uint256& entry, const bool erase);
57+
58+
void Set(const uint256& entry);
59+
60+
std::pair<uint32_t, size_t> setup_bytes(size_t n);
61+
};
62+
2363
class CachingTransactionSignatureChecker : public TransactionSignatureChecker
2464
{
2565
private:

0 commit comments

Comments
 (0)