aboutsummaryrefslogtreecommitdiff
path: root/src/script.cpp
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2012-12-08 22:49:04 +0100
committerPieter Wuille <pieter.wuille@gmail.com>2013-01-08 02:00:59 +0100
commitef0f422519de4a3ce47d923e5f8f90cd12349f3e (patch)
treeba208bc61340c76ceba465a05afe1391ea217086 /src/script.cpp
parentf9cae832e6f56c6abe89b3bf05d1f176c2a7c913 (diff)
downloadbitcoin-ef0f422519de4a3ce47d923e5f8f90cd12349f3e.tar.xz
Remove contention on signature cache during block validation
Since block validation happens in parallel, multiple threads may be accessing the signature cache simultaneously. To prevent contention: * Turn the signature cache lock into a shared mutex * Make reading from the cache only acquire a shared lock * Let block validations not store their results in the cache
Diffstat (limited to 'src/script.cpp')
-rw-r--r--src/script.cpp20
1 files changed, 11 insertions, 9 deletions
diff --git a/src/script.cpp b/src/script.cpp
index 52a8f2c117..70adf1f9dc 100644
--- a/src/script.cpp
+++ b/src/script.cpp
@@ -16,7 +16,7 @@ using namespace boost;
#include "sync.h"
#include "util.h"
-bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
+bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, int flags);
@@ -1007,7 +1007,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
bool fSuccess = (!fStrictEncodings || (IsCanonicalSignature(vchSig) && IsCanonicalPubKey(vchPubKey)));
if (fSuccess)
- fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType);
+ fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType, flags);
popstack(stack);
popstack(stack);
@@ -1069,7 +1069,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
// Check signature
bool fOk = (!fStrictEncodings || (IsCanonicalSignature(vchSig) && IsCanonicalPubKey(vchPubKey)));
if (fOk)
- fOk = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType);
+ fOk = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType, flags);
if (fOk) {
isig++;
@@ -1199,13 +1199,13 @@ private:
// sigdata_type is (signature hash, signature, public key):
typedef boost::tuple<uint256, std::vector<unsigned char>, std::vector<unsigned char> > sigdata_type;
std::set< sigdata_type> setValid;
- CCriticalSection cs_sigcache;
+ boost::shared_mutex cs_sigcache;
public:
bool
Get(uint256 hash, const std::vector<unsigned char>& vchSig, const std::vector<unsigned char>& pubKey)
{
- LOCK(cs_sigcache);
+ boost::shared_lock<boost::shared_mutex> lock(cs_sigcache);
sigdata_type k(hash, vchSig, pubKey);
std::set<sigdata_type>::iterator mi = setValid.find(k);
@@ -1223,7 +1223,7 @@ public:
int64 nMaxCacheSize = GetArg("-maxsigcachesize", 50000);
if (nMaxCacheSize <= 0) return;
- LOCK(cs_sigcache);
+ boost::unique_lock<boost::shared_mutex> lock(cs_sigcache);
while (static_cast<int64>(setValid.size()) > nMaxCacheSize)
{
@@ -1246,7 +1246,7 @@ public:
};
bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode,
- const CTransaction& txTo, unsigned int nIn, int nHashType)
+ const CTransaction& txTo, unsigned int nIn, int nHashType, int flags)
{
static CSignatureCache signatureCache;
@@ -1271,7 +1271,9 @@ bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CSc
if (!key.Verify(sighash, vchSig))
return false;
- signatureCache.Set(sighash, vchSig, vchPubKey);
+ if (!(flags & SCRIPT_VERIFY_NOCACHE))
+ signatureCache.Set(sighash, vchSig, vchPubKey);
+
return true;
}
@@ -1761,7 +1763,7 @@ static CScript CombineMultisig(CScript scriptPubKey, const CTransaction& txTo, u
if (sigs.count(pubkey))
continue; // Already got a sig for this pubkey
- if (CheckSig(sig, pubkey, scriptPubKey, txTo, nIn, 0))
+ if (CheckSig(sig, pubkey, scriptPubKey, txTo, nIn, 0, 0))
{
sigs[pubkey] = sig;
break;