Make signature cache store CPubKeys
This commit is contained in:
parent
dfa23b94c2
commit
896185d7ed
3 changed files with 19 additions and 12 deletions
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue