merge bitcoin#13204: Faster sigcache nonce

This commit is contained in:
Kittywhiskers Van Gogh 2022-02-26 10:47:54 +05:30
parent 01dc196162
commit 0b4eddc359
4 changed files with 71 additions and 12 deletions

View File

@ -32,6 +32,7 @@ bench_bench_dash_SOURCES = \
bench/crypto_hash.cpp \
bench/ccoins_caching.cpp \
bench/gcs_filter.cpp \
bench/hashpadding.cpp \
bench/merkle_root.cpp \
bench/mempool_eviction.cpp \
bench/mempool_stress.cpp \

47
src/bench/hashpadding.cpp Normal file
View File

@ -0,0 +1,47 @@
// Copyright (c) 2015-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <bench/bench.h>
#include <hash.h>
#include <random.h>
#include <uint256.h>
static void PrePadded(benchmark::Bench& bench)
{
CSHA256 hasher;
// Setup the salted hasher
uint256 nonce = GetRandHash();
hasher.Write(nonce.begin(), 32);
hasher.Write(nonce.begin(), 32);
uint256 data = GetRandHash();
bench.run([&] {
unsigned char out[32];
CSHA256 h = hasher;
h.Write(data.begin(), 32);
h.Finalize(out);
});
}
BENCHMARK(PrePadded);
static void RegularPadded(benchmark::Bench& bench)
{
CSHA256 hasher;
// Setup the salted hasher
uint256 nonce = GetRandHash();
uint256 data = GetRandHash();
bench.run([&] {
unsigned char out[32];
CSHA256 h = hasher;
h.Write(nonce.begin(), 32);
h.Write(data.begin(), 32);
h.Finalize(out);
});
}
BENCHMARK(RegularPadded);

View File

@ -26,7 +26,7 @@ class CSignatureCache
{
private:
//! Entries are SHA256(nonce || signature hash || public key || signature):
uint256 nonce;
CSHA256 m_salted_hasher;
typedef CuckooCache::cache<uint256, SignatureCacheHasher> map_type;
map_type setValid;
std::shared_mutex cs_sigcache;
@ -34,13 +34,19 @@ private:
public:
CSignatureCache()
{
GetRandBytes(nonce.begin(), 32);
uint256 nonce = GetRandHash();
// We want the nonce to be 64 bytes long to force the hasher to process
// this chunk, which makes later hash computations more efficient. We
// just write our 32-byte entropy twice to fill the 64 bytes.
m_salted_hasher.Write(nonce.begin(), 32);
m_salted_hasher.Write(nonce.begin(), 32);
}
void
ComputeEntry(uint256& entry, const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubkey)
{
CSHA256().Write(nonce.begin(), 32).Write(hash.begin(), 32).Write(&pubkey[0], pubkey.size()).Write(&vchSig[0], vchSig.size()).Finalize(entry.begin());
CSHA256 hasher = m_salted_hasher;
hasher.Write(hash.begin(), 32).Write(&pubkey[0], pubkey.size()).Write(&vchSig[0], vchSig.size()).Finalize(entry.begin());
}
bool

View File

@ -1388,14 +1388,21 @@ int GetSpendHeight(const CCoinsViewCache& inputs)
}
static CuckooCache::cache<uint256, SignatureCacheHasher> scriptExecutionCache;
static uint256 scriptExecutionCacheNonce(GetRandHash());
static CuckooCache::cache<uint256, SignatureCacheHasher> g_scriptExecutionCache;
static CSHA256 g_scriptExecutionCacheHasher;
void InitScriptExecutionCache() {
// Setup the salted hasher
uint256 nonce = GetRandHash();
// We want the nonce to be 64 bytes long to force the hasher to process
// this chunk, which makes later hash computations more efficient. We
// just write our 32-byte entropy twice to fill the 64 bytes.
g_scriptExecutionCacheHasher.Write(nonce.begin(), 32);
g_scriptExecutionCacheHasher.Write(nonce.begin(), 32);
// nMaxCacheSize is unsigned. If -maxsigcachesize is set to zero,
// setup_bytes creates the minimum possible cache (2 elements).
size_t nMaxCacheSize = std::min(std::max((int64_t)0, gArgs.GetArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE) / 2), MAX_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20);
size_t nElems = scriptExecutionCache.setup_bytes(nMaxCacheSize);
size_t nElems = g_scriptExecutionCache.setup_bytes(nMaxCacheSize);
LogPrintf("Using %zu MiB out of %zu/2 requested for script execution cache, able to store %zu elements\n",
(nElems*sizeof(uint256)) >>20, (nMaxCacheSize*2)>>20, nElems);
}
@ -1438,12 +1445,10 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
// properly commits to the scriptPubKey in the inputs view of that
// transaction).
uint256 hashCacheEntry;
// We only use the first 19 bytes of nonce to avoid a second SHA
// round - giving us 19 + 32 + 4 = 55 bytes (+ 8 + 1 = 64)
static_assert(55 - sizeof(flags) - 32 >= 128/8, "Want at least 128 bits of nonce for script execution cache");
CSHA256().Write(scriptExecutionCacheNonce.begin(), 55 - sizeof(flags) - 32).Write(tx.GetHash().begin(), 32).Write((unsigned char*)&flags, sizeof(flags)).Finalize(hashCacheEntry.begin());
CSHA256 hasher = g_scriptExecutionCacheHasher;
hasher.Write(tx.GetHash().begin(), 32).Write((unsigned char*)&flags, sizeof(flags)).Finalize(hashCacheEntry.begin());
AssertLockHeld(cs_main); //TODO: Remove this requirement by making CuckooCache not require external locks
if (scriptExecutionCache.contains(hashCacheEntry, !cacheFullScriptStore)) {
if (g_scriptExecutionCache.contains(hashCacheEntry, !cacheFullScriptStore)) {
return true;
}
@ -1493,7 +1498,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
if (cacheFullScriptStore && !pvChecks) {
// We executed all of the provided scripts, and were told to
// cache the result. Do so now.
scriptExecutionCache.insert(hashCacheEntry);
g_scriptExecutionCache.insert(hashCacheEntry);
}
}
}