if (nLenS > 1 && (S[0] == 0x00) && !(S[1] & 0x80))
return error("Non-canonical signature: S value excessively padded");
- if (flags & SCRIPT_VERIFY_EVEN_S) {
- if (S[nLenS-1] & 1)
- return error("Non-canonical signature: S value odd");
+ if (flags & SCRIPT_VERIFY_LOW_S) {
+ if (!CKey::CheckSignatureElement(S, nLenS, true))
+ return error("Non-canonical signature: S value is unnecessarily high");
}
return true;
// sigdata_type is (signature hash, signature, public key):
typedef boost::tuple<uint256, std::vector<unsigned char>, CPubKey > sigdata_type;
std::set< sigdata_type> setValid;
- CCriticalSection cs_sigcache;
+ boost::shared_mutex cs_sigcache;
public:
bool
Get(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& 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);
int64 nMaxCacheSize = GetArg("-maxsigcachesize", 50000);
if (nMaxCacheSize <= 0) return;
- LOCK(cs_sigcache);
+ boost::shared_lock<boost::shared_mutex> lock(cs_sigcache);
while (static_cast<int64>(setValid.size()) > nMaxCacheSize)
{
bool operator()(const CScriptID &scriptID) const { return keystore->HaveCScript(scriptID); }
};
-bool IsMine(const CKeyStore &keystore, const CTxDestination &dest)
+isminetype IsMine(const CKeyStore &keystore, const CTxDestination& dest)
{
- return boost::apply_visitor(CKeyStoreIsMineVisitor(&keystore), dest);
+ CScript script;
+ script.SetDestination(dest);
+ return IsMine(keystore, script);
}
-bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
+isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
{
vector<valtype> vSolutions;
txnouttype whichType;
- if (!Solver(scriptPubKey, whichType, vSolutions))
- return false;
+ if (!Solver(scriptPubKey, whichType, vSolutions)) {
+ if (keystore.HaveWatchOnly(scriptPubKey))
+ return MINE_WATCH_ONLY;
+ return MINE_NO;
+ }
CKeyID keyID;
switch (whichType)
{
case TX_NONSTANDARD:
case TX_NULL_DATA:
- return false;
+ break;
case TX_PUBKEY:
keyID = CPubKey(vSolutions[0]).GetID();
- return keystore.HaveKey(keyID);
+ if (keystore.HaveKey(keyID))
+ return MINE_SPENDABLE;
+ break;
case TX_PUBKEYHASH:
keyID = CKeyID(uint160(vSolutions[0]));
- return keystore.HaveKey(keyID);
+ if (keystore.HaveKey(keyID))
+ return MINE_SPENDABLE;
+ break;
case TX_SCRIPTHASH:
{
+ CScriptID scriptID = CScriptID(uint160(vSolutions[0]));
CScript subscript;
- if (!keystore.GetCScript(CScriptID(uint160(vSolutions[0])), subscript))
- return false;
- return IsMine(keystore, subscript);
+ if (keystore.GetCScript(scriptID, subscript)) {
+ isminetype ret = IsMine(keystore, subscript);
+ if (ret == MINE_SPENDABLE)
+ return ret;
+ }
+ break;
}
case TX_MULTISIG:
{
// them) enable spend-out-from-under-you attacks, especially
// in shared-wallet situations.
vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1);
- return HaveKeys(keys, keystore) == keys.size();
+ if (HaveKeys(keys, keystore) == keys.size())
+ return MINE_SPENDABLE;
+ break;
}
}
- return false;
+
+ if (keystore.HaveWatchOnly(scriptPubKey))
+ return MINE_WATCH_ONLY;
+ return MINE_NO;
}
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
}
// Test solution
- return VerifyScript(txin.scriptSig, fromPubKey, txTo, nIn, STANDARD_SCRIPT_VERIFY_FLAGS, 0);
+ return VerifyScript(txin.scriptSig, fromPubKey, txTo, nIn, STRICT_FLAGS, 0);
}
bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType)