Bitcoin ABC  0.24.7
P2P Digital Currency
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 
5 #include <script/scriptcache.h>
6 
7 #include <crypto/sha256.h>
8 #include <cuckoocache.h>
10 #include <random.h>
11 #include <script/sigcache.h>
12 #include <sync.h>
13 #include <util/system.h>
14 #include <validation.h>
15 
27 
30 
31  ScriptCacheElement() = default;
32 
33  ScriptCacheElement(const KeyType &keyIn, int nSigChecksIn)
34  : key(keyIn), nSigChecks(nSigChecksIn) {}
35 
36  const KeyType &getKey() const { return key; }
37 };
38 
39 static_assert(sizeof(ScriptCacheElement) == 32,
40  "ScriptCacheElement should be 32 bytes");
41 
43 public:
44  template <uint8_t hash_select>
45  uint32_t operator()(const ScriptCacheKey &k) const {
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 
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  // nMaxCacheSize is unsigned. If -maxscriptcachesize is set to zero,
85  // setup_bytes creates the minimum possible cache (2 elements).
86  size_t nMaxCacheSize =
87  std::min(
88  std::max(int64_t(0), gArgs.GetArg("-maxscriptcachesize",
91  (size_t(1) << 20);
92  size_t nElems = g_scriptExecutionCache.setup_bytes(nMaxCacheSize);
93  LogPrintf("Using %zu MiB out of %zu requested for script execution cache, "
94  "able to store %zu elements\n",
95  (nElems * sizeof(uint256)) >> 20, nMaxCacheSize >> 20, nElems);
96 }
97 
99  std::array<uint8_t, 32> hash;
101  hasher.Write(tx.GetHash().begin(), 32)
102  .Write((uint8_t *)&flags, sizeof(flags))
103  .Finalize(hash.begin());
104 
105  assert(data.size() < hash.size());
106  std::copy(hash.begin(), hash.begin() + data.size(), data.begin());
107 }
108 
109 bool IsKeyInScriptCache(ScriptCacheKey key, bool erase, int &nSigChecksOut) {
110  // TODO: Remove this requirement by making CuckooCache not require external
111  // locks
113 
114  ScriptCacheElement elem(key, 0);
115  bool ret = g_scriptExecutionCache.get(elem, erase);
116  nSigChecksOut = elem.nSigChecks;
117  return ret;
118 }
119 
120 void AddKeyInScriptCache(ScriptCacheKey key, int nSigChecks) {
121  // TODO: Remove this requirement by making CuckooCache not require external
122  // locks
124 
125  ScriptCacheElement elem(key, nSigChecks);
126  g_scriptExecutionCache.insert(elem);
127 }
MAX_MAX_SCRIPT_CACHE_SIZE
static const int64_t MAX_MAX_SCRIPT_CACHE_SIZE
Definition: scriptcache.h:50
CuckooCache::cache
cache implements a cache with properties similar to a cuckoo-set.
Definition: cuckoocache.h:162
flags
int flags
Definition: bitcoin-tx.cpp:532
sync.h
transaction.h
InitScriptExecutionCache
void InitScriptExecutionCache()
Initializes the script-execution cache.
Definition: scriptcache.cpp:76
ScriptCacheElement::key
KeyType key
Definition: scriptcache.cpp:28
ScriptCacheKey::data
std::array< uint8_t, 28 > data
Definition: scriptcache.h:29
ScriptCacheHasher
Definition: scriptcache.cpp:42
ScriptCacheElement::nSigChecks
int nSigChecks
Definition: scriptcache.cpp:29
CTransaction::GetHash
const TxHash GetHash() const
Definition: transaction.h:245
CTransaction
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:194
cuckoocache.h
IsKeyInScriptCache
bool IsKeyInScriptCache(ScriptCacheKey key, bool erase, int &nSigChecksOut)
Check if a given key is in the cache, and if so, return its values.
Definition: scriptcache.cpp:109
random.h
CSHA256::Finalize
void Finalize(uint8_t hash[OUTPUT_SIZE])
Definition: sha256.cpp:844
cs_main
RecursiveMutex cs_main
Global state.
Definition: validation.cpp:103
DEFAULT_MAX_SCRIPT_CACHE_SIZE
static const unsigned int DEFAULT_MAX_SCRIPT_CACHE_SIZE
Definition: scriptcache.h:48
ScriptCacheKey::ScriptCacheKey
ScriptCacheKey()=default
ScriptCacheElement::ScriptCacheElement
ScriptCacheElement()=default
GetRandHash
uint256 GetRandHash() noexcept
Definition: random.cpp:658
ArgsManager::GetArg
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:498
ScriptCacheElement
In future if many more values are added, it should be considered to expand the element size to 64 byt...
Definition: scriptcache.cpp:25
uint256
256-bit opaque blob.
Definition: uint256.h:127
base_blob::begin
uint8_t * begin()
Definition: uint256.h:83
ScriptCacheElement::ScriptCacheElement
ScriptCacheElement(const KeyType &keyIn, int nSigChecksIn)
Definition: scriptcache.cpp:33
sha256.h
system.h
AddKeyInScriptCache
void AddKeyInScriptCache(ScriptCacheKey key, int nSigChecks)
Add an entry in the cache.
Definition: scriptcache.cpp:120
g_scriptExecutionCache
static CuckooCache::cache< ScriptCacheElement, ScriptCacheHasher > g_scriptExecutionCache
Definition: scriptcache.cpp:73
ScriptCacheElement::getKey
const KeyType & getKey() const
Definition: scriptcache.cpp:36
ScriptCacheHasher::operator()
uint32_t operator()(const ScriptCacheKey &k) const
Definition: scriptcache.cpp:45
g_scriptExecutionCacheHasher
static CSHA256 g_scriptExecutionCacheHasher
Definition: scriptcache.cpp:74
gArgs
ArgsManager gArgs
Definition: system.cpp:75
CSHA256
A hasher class for SHA-256.
Definition: sha256.h:13
scriptcache.h
CSHA256::Write
CSHA256 & Write(const uint8_t *data, size_t len)
Definition: sha256.cpp:819
sigcache.h
LogPrintf
static void LogPrintf(const char *fmt, const Args &... args)
Definition: logging.h:175
AssertLockHeld
AssertLockHeld(g_cs_orphans)
ScriptCacheKey
The script cache is a map using a key/value element, that caches the success of executing a specific ...
Definition: scriptcache.h:28