dash/src/script/sigcache.cpp

95 lines
3.2 KiB
C++
Raw Normal View History

2014-09-10 16:16:09 +02:00
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
2014-09-10 16:16:09 +02:00
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "sigcache.h"
#include "memusage.h"
#include "pubkey.h"
2014-09-10 16:16:09 +02:00
#include "random.h"
#include "uint256.h"
#include "util.h"
#include "cuckoocache.h"
2014-09-10 16:16:09 +02:00
#include <boost/thread.hpp>
namespace {
/**
* Valid signature cache, to avoid doing expensive ECDSA signature checking
* twice for every transaction (once when accepted into memory pool, and
* again when accepted into the block chain)
*/
2014-09-10 16:16:09 +02:00
class CSignatureCache
{
private:
//! Entries are SHA256(nonce || signature hash || public key || signature):
uint256 nonce;
typedef CuckooCache::cache<uint256, SignatureCacheHasher> map_type;
map_type setValid;
2014-09-10 16:16:09 +02:00
boost::shared_mutex cs_sigcache;
public:
CSignatureCache()
{
GetRandBytes(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());
}
2014-09-10 16:16:09 +02:00
bool
Get(const uint256& entry, const bool erase)
2014-09-10 16:16:09 +02:00
{
boost::shared_lock<boost::shared_mutex> lock(cs_sigcache);
return setValid.contains(entry, erase);
2014-09-10 16:16:09 +02:00
}
void Set(uint256& entry)
{
boost::unique_lock<boost::shared_mutex> lock(cs_sigcache);
setValid.insert(entry);
}
uint32_t setup_bytes(size_t n)
2014-09-10 16:16:09 +02:00
{
return setValid.setup_bytes(n);
2014-09-10 16:16:09 +02:00
}
};
/* In previous versions of this code, signatureCache was a local static variable
* in CachingTransactionSignatureChecker::VerifySignature. We initialize
* signatureCache outside of VerifySignature to avoid the atomic operation per
* call overhead associated with local static variables even though
* signatureCache could be made local to VerifySignature.
*/
static CSignatureCache signatureCache;
2014-09-10 16:16:09 +02:00
}
Backports 0.15 pr2 (#2597) * Merge #9815: Trivial: use EXIT_ codes instead of magic numbers a87d02a use EXIT_ codes instead of magic numbers (Marko Bencun) * Merge #9801: Removed redundant parameter from mempool.PrioritiseTransaction eaea2bb Removed redundant parameter from mempool.PrioritiseTransaction (gubatron) * remove extra parameter (see 3a3745bb) in dash specific code * Merge #9819: Remove harmless read of unusued priority estimates bc8fd12 Remove harmless read of unusued priority estimates (Alex Morcos) * Merge #9766: Add --exclude option to rpc-tests.py c578408 Add exclude option to rpc-tests.py (John Newbery) * Merge #9577: Fix docstrings in qa tests 3f95a80 Fix docstrings in qa tests (John Newbery) * Merge #9823: qa: Set correct path for binaries in rpc tests 3333ad0 qa: Set correct path for binaries in rpc tests (MarcoFalke) * Merge #9833: Trivial: fix comments referencing AppInit2 ef9f495 Trivial: fix comments referencing AppInit2 (Marko Bencun) * Merge #9612: [trivial] Rephrase the definition of difficulty. dc222f8 Trivial: Rephrase the definition of difficulty in the code. (Karl-Johan Alm) * Merge #9847: Extra test vector for BIP32 30aedcb BIP32 extra test vector (Pieter Wuille) * Merge #9839: [qa] Make import-rescan.py watchonly check reliable 864890a [qa] Make import-rescan.py watchonly check reliable (Russell Yanofsky) Tree-SHA512: ea0e2b1d4fc8f35174c3d575fb751b428daf6ad3aa944fad4e3ddcc9195e4f17051473acabc54203b1d27cca64cf911b737ab92e986c40ef384410652e2dbea1 * Change back file params
2019-01-07 10:55:35 +01:00
// To be called once in AppInitMain/BasicTestingSetup to initialize the
// signatureCache.
void InitSignatureCache()
2014-09-10 16:16:09 +02:00
{
// 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, GetArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE)), MAX_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20);
size_t nElems = signatureCache.setup_bytes(nMaxCacheSize);
LogPrintf("Using %zu MiB out of %zu requested for signature cache, able to store %zu elements\n",
(nElems*sizeof(uint256)) >>20, nMaxCacheSize>>20, nElems);
}
2014-09-10 16:16:09 +02:00
bool CachingTransactionSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
{
uint256 entry;
signatureCache.ComputeEntry(entry, sighash, vchSig, pubkey);
if (signatureCache.Get(entry, !store))
2014-09-10 16:16:09 +02:00
return true;
if (!TransactionSignatureChecker::VerifySignature(vchSig, pubkey, sighash))
2014-09-10 16:16:09 +02:00
return false;
if (store)
signatureCache.Set(entry);
2014-09-10 16:16:09 +02:00
return true;
}