Make signature cache store CPubKeys

This commit is contained in:
Pieter Wuille 2013-05-04 16:10:09 +02:00 committed by Pieter Wuille
parent dfa23b94c2
commit 896185d7ed
3 changed files with 19 additions and 12 deletions

View file

@ -176,6 +176,10 @@ private:
{} {}
}; };
//
// Functions for directly locking/unlocking memory objects.
// Intended for non-dynamically allocated structures.
//
template<typename T> void LockObject(const T &t) { template<typename T> void LockObject(const T &t) {
LockedPageManager::instance.LockRange((void*)(&t), sizeof(T)); LockedPageManager::instance.LockRange((void*)(&t), sizeof(T));
} }

View file

@ -84,7 +84,7 @@ public:
Set(vch.begin(), vch.end()); Set(vch.begin(), vch.end());
} }
// Simply read-only vector-like interface to the pubkey data. // Simple read-only vector-like interface to the pubkey data.
unsigned int size() const { return GetLen(vch[0]); } unsigned int size() const { return GetLen(vch[0]); }
const unsigned char *begin() const { return vch; } const unsigned char *begin() const { return vch; }
const unsigned char *end() const { return vch+size(); } const unsigned char *end() const { return vch+size(); }
@ -109,12 +109,11 @@ public:
} }
template<typename Stream> void Serialize(Stream &s, int nType, int nVersion) const { template<typename Stream> void Serialize(Stream &s, int nType, int nVersion) const {
unsigned int len = size(); unsigned int len = size();
::Serialize(s, VARINT(len), nType, nVersion); ::WriteCompactSize(s, len);
s.write((char*)vch, len); s.write((char*)vch, len);
} }
template<typename Stream> void Unserialize(Stream &s, int nType, int nVersion) { template<typename Stream> void Unserialize(Stream &s, int nType, int nVersion) {
unsigned int len; unsigned int len = ::ReadCompactSize(s);
::Unserialize(s, VARINT(len), nType, nVersion);
if (len <= 65) { if (len <= 65) {
s.read((char*)vch, len); s.read((char*)vch, len);
} else { } else {

View file

@ -16,7 +16,7 @@ using namespace boost;
#include "sync.h" #include "sync.h"
#include "util.h" #include "util.h"
bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, int flags); bool CheckSig(vector<unsigned char> vchSig, const vector<unsigned char> &vchPubKey, const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, int flags);
@ -1033,13 +1033,13 @@ class CSignatureCache
{ {
private: private:
// sigdata_type is (signature hash, signature, public key): // sigdata_type is (signature hash, signature, public key):
typedef boost::tuple<uint256, std::vector<unsigned char>, std::vector<unsigned char> > sigdata_type; typedef boost::tuple<uint256, std::vector<unsigned char>, CPubKey> sigdata_type;
std::set< sigdata_type> setValid; std::set< sigdata_type> setValid;
boost::shared_mutex cs_sigcache; boost::shared_mutex cs_sigcache;
public: public:
bool bool
Get(uint256 hash, const std::vector<unsigned char>& vchSig, const std::vector<unsigned char>& pubKey) Get(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey)
{ {
boost::shared_lock<boost::shared_mutex> lock(cs_sigcache); boost::shared_lock<boost::shared_mutex> lock(cs_sigcache);
@ -1050,7 +1050,7 @@ public:
return false; return false;
} }
void Set(uint256 hash, const std::vector<unsigned char>& vchSig, const std::vector<unsigned char>& pubKey) void Set(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey)
{ {
// DoS prevention: limit cache size to less than 10MB // DoS prevention: limit cache size to less than 10MB
// (~200 bytes per cache entry times 50,000 entries) // (~200 bytes per cache entry times 50,000 entries)
@ -1081,11 +1081,15 @@ public:
} }
}; };
bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode, bool CheckSig(vector<unsigned char> vchSig, const vector<unsigned char> &vchPubKey, const CScript &scriptCode,
const CTransaction& txTo, unsigned int nIn, int nHashType, int flags) const CTransaction& txTo, unsigned int nIn, int nHashType, int flags)
{ {
static CSignatureCache signatureCache; static CSignatureCache signatureCache;
CPubKey pubkey(vchPubKey);
if (!pubkey.IsValid())
return false;
// Hash type is one byte tacked on to the end of the signature // Hash type is one byte tacked on to the end of the signature
if (vchSig.empty()) if (vchSig.empty())
return false; return false;
@ -1097,14 +1101,14 @@ bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CSc
uint256 sighash = SignatureHash(scriptCode, txTo, nIn, nHashType); uint256 sighash = SignatureHash(scriptCode, txTo, nIn, nHashType);
if (signatureCache.Get(sighash, vchSig, vchPubKey)) if (signatureCache.Get(sighash, vchSig, pubkey))
return true; return true;
if (!CPubKey(vchPubKey).Verify(sighash, vchSig)) if (!pubkey.Verify(sighash, vchSig))
return false; return false;
if (!(flags & SCRIPT_VERIFY_NOCACHE)) if (!(flags & SCRIPT_VERIFY_NOCACHE))
signatureCache.Set(sighash, vchSig, vchPubKey); signatureCache.Set(sighash, vchSig, pubkey);
return true; return true;
} }