Bitcoin ABC 0.26.3
P2P Digital Currency
Loading...
Searching...
No Matches
scriptcache.cpp
Go to the documentation of this file.
1// Copyright (c) 2017-2020 The Bitcoin developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
6
7#include <common/system.h>
8#include <crypto/sha256.h>
9#include <cuckoocache.h>
11#include <random.h>
12#include <script/sigcache.h>
13#include <sync.h>
14#include <validation.h>
15
38
39static_assert(sizeof(ScriptCacheElement) == 32,
40 "ScriptCacheElement should be 32 bytes");
41
43public:
44 template <uint8_t hash_select>
46 static_assert(hash_select < 8, "only has 8 hashes available.");
47
48 const auto &d = k.data;
49
50 static_assert(sizeof(d) == 28,
51 "modify the following if key size changes");
52
53 uint32_t u;
54 static_assert(sizeof(u) == 4 && sizeof(d[0]) == 1, "basic assumptions");
55 if (hash_select < 7) {
56 std::memcpy(&u, d.data() + 4 * hash_select, 4);
57 } else {
58 // We are required to produce 8 subhashes, and all bytes have
59 // been used once. We re-use the bytes but mix together different
60 // entries (and flip the order) to get a new, distinct value.
61 uint8_t arr[4];
62 arr[0] = d[3] ^ d[7] ^ d[11] ^ d[15];
63 arr[1] = d[6] ^ d[10] ^ d[14] ^ d[18];
64 arr[2] = d[9] ^ d[13] ^ d[17] ^ d[21];
65 arr[3] = d[12] ^ d[16] ^ d[20] ^ d[24];
66 std::memcpy(&u, arr, 4);
67 }
68 return u;
69 }
70};
71
75
76bool InitScriptExecutionCache(size_t max_size_bytes) {
77 // Setup the salted hasher
78 uint256 nonce = GetRandHash();
79 // We want the nonce to be 64 bytes long to force the hasher to process
80 // this chunk, which makes later hash computations more efficient. We
81 // just write our 32-byte entropy twice to fill the 64 bytes.
84
85 auto setup_results = g_scriptExecutionCache.setup_bytes(max_size_bytes);
86 if (!setup_results) {
87 return false;
88 }
89
91 LogPrintf("Using %zu MiB out of %zu MiB requested for script execution "
92 "cache, able to store %zu elements\n",
93 approx_size_bytes >> 20, max_size_bytes >> 20, num_elems);
94 return true;
95}
96
98 std::array<uint8_t, 32> hash;
100 hasher.Write(tx.GetHash().begin(), 32)
101 .Write((uint8_t *)&flags, sizeof(flags))
102 .Finalize(hash.begin());
103
104 assert(data.size() < hash.size());
105 std::copy(hash.begin(), hash.begin() + data.size(), data.begin());
106}
107
109 // TODO: Remove this requirement by making CuckooCache not require external
110 // locks
112
113 ScriptCacheElement elem(key, 0);
114 bool ret = g_scriptExecutionCache.get(elem, erase);
115 nSigChecksOut = elem.nSigChecks;
116 return ret;
117}
118
120 // TODO: Remove this requirement by making CuckooCache not require external
121 // locks
123
126}
int flags
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
The basic transaction that is broadcasted on the network and contained in blocks.
const TxHash GetHash() const
cache implements a cache with properties similar to a cuckoo-set.
uint32_t operator()(const ScriptCacheKey &k) const
The script cache is a map using a key/value element, that caches the success of executing a specific ...
Definition scriptcache.h:25
std::array< uint8_t, 28 > data
Definition scriptcache.h:26
ScriptCacheKey()=default
uint8_t * begin()
Definition uint256.h:85
256-bit opaque blob.
Definition uint256.h:129
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition cs_main.cpp:7
#define LogPrintf(...)
Definition logging.h:207
unsigned int nSigChecks
uint256 GetRandHash() noexcept
Definition random.cpp:659
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
Definition random.h:85
static CSHA256 g_scriptExecutionCacheHasher
static CuckooCache::cache< ScriptCacheElement, ScriptCacheHasher > g_scriptExecutionCache
bool InitScriptExecutionCache(size_t max_size_bytes)
Initializes the script-execution cache.
void AddKeyInScriptCache(ScriptCacheKey key, int nSigChecks)
Add an entry in the cache.
bool IsKeyInScriptCache(ScriptCacheKey key, bool erase, int &nSigChecksOut)
Check if a given key is in the cache, and if so, return its values.
In future if many more values are added, it should be considered to expand the element size to 64 byt...
const KeyType & getKey() const
ScriptCacheElement(const KeyType &keyIn, int nSigChecksIn)
ScriptCacheElement()=default
#define AssertLockHeld(cs)
Definition sync.h:146
assert(!tx.IsCoinBase())