aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.bench.include1
-rw-r--r--src/bench/hashpadding.cpp47
-rw-r--r--src/script/sigcache.cpp12
-rw-r--r--src/validation.cpp23
4 files changed, 71 insertions, 12 deletions
diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include
index 766c0fca54..93b5156af3 100644
--- a/src/Makefile.bench.include
+++ b/src/Makefile.bench.include
@@ -29,6 +29,7 @@ bench_bench_bitcoin_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 \
diff --git a/src/bench/hashpadding.cpp b/src/bench/hashpadding.cpp
new file mode 100644
index 0000000000..985be8bdba
--- /dev/null
+++ b/src/bench/hashpadding.cpp
@@ -0,0 +1,47 @@
+// Copyright (c) 2015-2018 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::State& state)
+{
+
+ CSHA256 hasher;
+
+ // Setup the salted hasher
+ uint256 nonce = GetRandHash();
+ hasher.Write(nonce.begin(), 32);
+ hasher.Write(nonce.begin(), 32);
+ uint256 data = GetRandHash();
+ while (state.KeepRunning()) {
+ unsigned char out[32];
+ CSHA256 h = hasher;
+ h.Write(data.begin(), 32);
+ h.Finalize(out);
+ }
+}
+
+BENCHMARK(PrePadded, 10000);
+
+static void RegularPadded(benchmark::State& state)
+{
+ CSHA256 hasher;
+
+ // Setup the salted hasher
+ uint256 nonce = GetRandHash();
+ uint256 data = GetRandHash();
+ while (state.KeepRunning()) {
+ unsigned char out[32];
+ CSHA256 h = hasher;
+ h.Write(nonce.begin(), 32);
+ h.Write(data.begin(), 32);
+ h.Finalize(out);
+ }
+}
+
+BENCHMARK(RegularPadded, 10000);
diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp
index e7b6df3ce8..3c54d5bee4 100644
--- a/src/script/sigcache.cpp
+++ b/src/script/sigcache.cpp
@@ -23,7 +23,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;
boost::shared_mutex cs_sigcache;
@@ -31,13 +31,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
diff --git a/src/validation.cpp b/src/validation.cpp
index 396fc0a1b5..0d57900670 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -1481,14 +1481,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);
}
@@ -1526,12 +1533,10 @@ bool CheckInputScripts(const CTransaction& tx, TxValidationState &state, const C
// 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.GetWitnessHash().begin(), 32).Write((unsigned char*)&flags, sizeof(flags)).Finalize(hashCacheEntry.begin());
+ CSHA256 hasher = g_scriptExecutionCacheHasher;
+ hasher.Write(tx.GetWitnessHash().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;
}
@@ -1586,7 +1591,7 @@ bool CheckInputScripts(const CTransaction& tx, TxValidationState &state, const C
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);
}
return true;