Any projects which want to use Hush code from now on will need to be licensed as GPLv3 or we will send the lawyers: https://www.softwarefreedom.org/ Notably, Komodo (KMD) is licensed as GPLv2 and is no longer compatible to receive code changes, without causing legal issues. MIT projects, such as Zcash, also cannot pull in changes from the Hush Full Node without permission from The Hush Developers, which may in some circumstances grant an MIT license on a case-by-case basis.
124 lines
4.9 KiB
C++
124 lines
4.9 KiB
C++
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
|
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
|
// Distributed under the GPLv3 software license, see the accompanying
|
|
// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
|
|
|
/******************************************************************************
|
|
* Copyright © 2014-2019 The SuperNET Developers. *
|
|
* *
|
|
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
|
|
* the top-level directory of this distribution for the individual copyright *
|
|
* holder information and the developer policies on copyright and licensing. *
|
|
* *
|
|
* Unless otherwise agreed in a custom licensing agreement, no part of the *
|
|
* SuperNET software, including this file may be copied, modified, propagated *
|
|
* or distributed except according to the terms contained in the LICENSE file *
|
|
* *
|
|
* Removal or modification of this copyright notice is prohibited. *
|
|
* *
|
|
******************************************************************************/
|
|
|
|
#include "serverchecker.h"
|
|
#include "script/cc.h"
|
|
#include "cc/eval.h"
|
|
|
|
#include "pubkey.h"
|
|
#include "random.h"
|
|
#include "uint256.h"
|
|
#include "util.h"
|
|
|
|
#undef __cpuid
|
|
#include <boost/thread.hpp>
|
|
#include <boost/tuple/tuple_comparison.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)
|
|
*/
|
|
class CSignatureCache
|
|
{
|
|
private:
|
|
//! sigdata_type is (signature hash, signature, public key):
|
|
typedef boost::tuple<uint256, std::vector<unsigned char>, CPubKey> sigdata_type;
|
|
std::set< sigdata_type> setValid;
|
|
boost::shared_mutex cs_serverchecker;
|
|
|
|
public:
|
|
bool
|
|
Get(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey)
|
|
{
|
|
boost::shared_lock<boost::shared_mutex> lock(cs_serverchecker);
|
|
|
|
sigdata_type k(hash, vchSig, pubKey);
|
|
std::set<sigdata_type>::iterator mi = setValid.find(k);
|
|
if (mi != setValid.end())
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
void Set(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey)
|
|
{
|
|
// DoS prevention: limit cache size to less than 10MB
|
|
// (~200 bytes per cache entry times 50,000 entries)
|
|
// Since there can be no more than 20,000 signature operations per block
|
|
// 50,000 is a reasonable default.
|
|
int64_t nMaxCacheSize = GetArg("-maxservercheckersize", 50000);
|
|
if (nMaxCacheSize <= 0) return;
|
|
|
|
boost::unique_lock<boost::shared_mutex> lock(cs_serverchecker);
|
|
|
|
while (static_cast<int64_t>(setValid.size()) > nMaxCacheSize)
|
|
{
|
|
// Evict a random entry. Random because that helps
|
|
// foil would-be DoS attackers who might try to pre-generate
|
|
// and re-use a set of valid signatures just-slightly-greater
|
|
// than our cache size.
|
|
uint256 randomHash = GetRandHash();
|
|
std::vector<unsigned char> unused;
|
|
std::set<sigdata_type>::iterator it =
|
|
setValid.lower_bound(sigdata_type(randomHash, unused, unused));
|
|
if (it == setValid.end())
|
|
it = setValid.begin();
|
|
setValid.erase(*it);
|
|
}
|
|
|
|
sigdata_type k(hash, vchSig, pubKey);
|
|
setValid.insert(k);
|
|
}
|
|
};
|
|
|
|
}
|
|
|
|
bool ServerTransactionSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
|
|
{
|
|
static CSignatureCache signatureCache;
|
|
|
|
if (signatureCache.Get(sighash, vchSig, pubkey))
|
|
return true;
|
|
|
|
if (!TransactionSignatureChecker::VerifySignature(vchSig, pubkey, sighash))
|
|
return false;
|
|
|
|
if (store)
|
|
signatureCache.Set(sighash, vchSig, pubkey);
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* The reason that these functions are here is that the what used to be the
|
|
* CachingTransactionSignatureChecker, now the ServerTransactionSignatureChecker,
|
|
* is an entry point that the server uses to validate signatures and which is not
|
|
* included as part of bitcoin common libs. Since Crypto-Condtions eval methods
|
|
* may call server code (GetTransaction etc), the best way to get it to run this
|
|
* code without pulling the whole bitcoin server code into bitcoin common was
|
|
* using this class. Thus it has been renamed to ServerTransactionSignatureChecker.
|
|
*/
|
|
int ServerTransactionSignatureChecker::CheckEvalCondition(const CC *cond) const
|
|
{
|
|
//fprintf(stderr,"call RunCCeval from ServerTransactionSignatureChecker::CheckEvalCondition\n");
|
|
return RunCCEval(cond, *txTo, nIn);
|
|
}
|