[script] signing and fork replay protection
This commit is contained in:
parent
e6e6ffedea
commit
b3f1d6dab3
|
@ -75,7 +75,7 @@ static void VerifyScriptBench(benchmark::State& state)
|
||||||
CMutableTransaction txSpend = BuildSpendingTransaction(scriptSig, txCredit);
|
CMutableTransaction txSpend = BuildSpendingTransaction(scriptSig, txCredit);
|
||||||
CScriptWitness& witness = txSpend.vin[0].scriptWitness;
|
CScriptWitness& witness = txSpend.vin[0].scriptWitness;
|
||||||
witness.stack.emplace_back();
|
witness.stack.emplace_back();
|
||||||
key.Sign(SignatureHash(witScriptPubkey, txSpend, 0, SIGHASH_ALL, txCredit.vout[0].nValue, SigVersion::WITNESS_V0), witness.stack.back(), 0);
|
key.Sign(SignatureHash(witScriptPubkey, txSpend, 0, SIGHASH_ALL, FORKID_NONE, txCredit.vout[0].nValue, SigVersion::WITNESS_V0), witness.stack.back(), 0);
|
||||||
witness.stack.back().push_back(static_cast<unsigned char>(SIGHASH_ALL));
|
witness.stack.back().push_back(static_cast<unsigned char>(SIGHASH_ALL));
|
||||||
witness.stack.push_back(ToByteVector(pubkey));
|
witness.stack.push_back(ToByteVector(pubkey));
|
||||||
|
|
||||||
|
|
|
@ -169,6 +169,13 @@ bool static IsValidSignatureEncoding(const std::vector<unsigned char> &sig) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t static GetHashType(const valtype &vchSig) {
|
||||||
|
if (vchSig.size() == 0)
|
||||||
|
return 0;
|
||||||
|
// check IsValidSignatureEncoding()'s comment for vchSig format
|
||||||
|
return vchSig.back();
|
||||||
|
}
|
||||||
|
|
||||||
bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) {
|
bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) {
|
||||||
if (!IsValidSignatureEncoding(vchSig)) {
|
if (!IsValidSignatureEncoding(vchSig)) {
|
||||||
return set_error(serror, SCRIPT_ERR_SIG_DER);
|
return set_error(serror, SCRIPT_ERR_SIG_DER);
|
||||||
|
@ -190,13 +197,22 @@ bool static IsDefinedHashtypeSignature(const valtype &vchSig) {
|
||||||
if (vchSig.size() == 0) {
|
if (vchSig.size() == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
unsigned char nHashType = vchSig[vchSig.size() - 1] & (~(SIGHASH_ANYONECANPAY));
|
unsigned char nHashType = GetHashType(vchSig) & (~(SIGHASH_ANYONECANPAY|SIGHASH_FORKID));
|
||||||
if (nHashType < SIGHASH_ALL || nHashType > SIGHASH_SINGLE)
|
if (nHashType < SIGHASH_ALL || nHashType > SIGHASH_SINGLE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool static UsesForkId(uint32_t nHashType) {
|
||||||
|
return nHashType & SIGHASH_FORKID;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool static UsesForkId(const valtype &vchSig) {
|
||||||
|
uint32_t nHashType = GetHashType(vchSig);
|
||||||
|
return UsesForkId(nHashType);
|
||||||
|
}
|
||||||
|
|
||||||
bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, unsigned int flags, ScriptError* serror) {
|
bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, unsigned int flags, ScriptError* serror) {
|
||||||
// Empty signature. Not strictly DER encoded, but allowed to provide a
|
// Empty signature. Not strictly DER encoded, but allowed to provide a
|
||||||
// compact way to provide an invalid signature for use with CHECK(MULTI)SIG
|
// compact way to provide an invalid signature for use with CHECK(MULTI)SIG
|
||||||
|
@ -210,6 +226,8 @@ bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, unsigned i
|
||||||
return false;
|
return false;
|
||||||
} else if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsDefinedHashtypeSignature(vchSig)) {
|
} else if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsDefinedHashtypeSignature(vchSig)) {
|
||||||
return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE);
|
return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE);
|
||||||
|
} else if ((flags & SCRIPT_VERIFY_FORKID) != 0 && !UsesForkId(vchSig)) {
|
||||||
|
return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -300,6 +318,8 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
|
||||||
int nOpCount = 0;
|
int nOpCount = 0;
|
||||||
bool fRequireMinimal = (flags & SCRIPT_VERIFY_MINIMALDATA) != 0;
|
bool fRequireMinimal = (flags & SCRIPT_VERIFY_MINIMALDATA) != 0;
|
||||||
|
|
||||||
|
const int forkid = (flags & SCRIPT_VERIFY_FORKID) ? FORKID_IN_USE : 0;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while (pc < pend)
|
while (pc < pend)
|
||||||
|
@ -924,14 +944,11 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
|
||||||
valtype& vchSig = stacktop(-2);
|
valtype& vchSig = stacktop(-2);
|
||||||
valtype& vchPubKey = stacktop(-1);
|
valtype& vchPubKey = stacktop(-1);
|
||||||
|
|
||||||
// Subset of script starting at the most recent codeseparator
|
|
||||||
CScript scriptCode(pbegincodehash, pend);
|
|
||||||
|
|
||||||
if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, sigversion, serror)) {
|
if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, sigversion, serror)) {
|
||||||
//serror is set
|
//serror is set
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool fSuccess = checker.CheckSig(vchSig, vchPubKey, script, sigversion);
|
bool fSuccess = checker.CheckSig(vchSig, vchPubKey, script, forkid, sigversion);
|
||||||
|
|
||||||
if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && vchSig.size())
|
if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && vchSig.size())
|
||||||
return set_error(serror, SCRIPT_ERR_SIG_NULLFAIL);
|
return set_error(serror, SCRIPT_ERR_SIG_NULLFAIL);
|
||||||
|
@ -995,7 +1012,7 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check signature
|
// Check signature
|
||||||
bool fOk = checker.CheckSig(vchSig, vchPubKey, script, sigversion);
|
bool fOk = checker.CheckSig(vchSig, vchPubKey, script, forkid, sigversion);
|
||||||
|
|
||||||
if (fOk) {
|
if (fOk) {
|
||||||
isig++;
|
isig++;
|
||||||
|
@ -1092,24 +1109,9 @@ public:
|
||||||
/** Serialize the passed scriptCode */
|
/** Serialize the passed scriptCode */
|
||||||
template<typename S>
|
template<typename S>
|
||||||
void SerializeScriptCode(S &s) const {
|
void SerializeScriptCode(S &s) const {
|
||||||
CScript::const_iterator it = scriptCode.begin();
|
auto size = scriptCode.size();
|
||||||
CScript::const_iterator itBegin = it;
|
::WriteCompactSize(s, size);
|
||||||
opcodetype opcode;
|
s.write((char*)&scriptCode.begin()[0], size);
|
||||||
unsigned int nCodeSeparators = 0;
|
|
||||||
while (scriptCode.GetOp(it, opcode)) {
|
|
||||||
if (opcode == OP_CODESEPARATOR)
|
|
||||||
nCodeSeparators++;
|
|
||||||
}
|
|
||||||
::WriteCompactSize(s, scriptCode.size() - nCodeSeparators);
|
|
||||||
it = itBegin;
|
|
||||||
while (scriptCode.GetOp(it, opcode)) {
|
|
||||||
if (opcode == OP_CODESEPARATOR) {
|
|
||||||
s.write((char*)&itBegin[0], it-itBegin-1);
|
|
||||||
itBegin = it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (itBegin != scriptCode.end())
|
|
||||||
s.write((char*)&itBegin[0], it-itBegin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Serialize an input of txTo */
|
/** Serialize an input of txTo */
|
||||||
|
@ -1121,6 +1123,7 @@ public:
|
||||||
// Serialize the prevout
|
// Serialize the prevout
|
||||||
::Serialize(s, txTo.vin[nInput].prevout);
|
::Serialize(s, txTo.vin[nInput].prevout);
|
||||||
// Serialize the script
|
// Serialize the script
|
||||||
|
assert(nInput != NOT_AN_INPUT);
|
||||||
if (nInput != nIn)
|
if (nInput != nIn)
|
||||||
// Blank out other inputs' signatures
|
// Blank out other inputs' signatures
|
||||||
::Serialize(s, CScript());
|
::Serialize(s, CScript());
|
||||||
|
@ -1161,6 +1164,23 @@ public:
|
||||||
SerializeOutput(s, nOutput);
|
SerializeOutput(s, nOutput);
|
||||||
// Serialize nLockTime
|
// Serialize nLockTime
|
||||||
::Serialize(s, txTo.nLockTime);
|
::Serialize(s, txTo.nLockTime);
|
||||||
|
|
||||||
|
// Serialize vjoinsplit
|
||||||
|
if (txTo.nVersion >= 2) {
|
||||||
|
//
|
||||||
|
// SIGHASH_* functions will hash portions of
|
||||||
|
// the transaction for use in signatures. This
|
||||||
|
// keeps the JoinSplit cryptographically bound
|
||||||
|
// to the transaction.
|
||||||
|
//
|
||||||
|
::Serialize(s, txTo.vjoinsplit);
|
||||||
|
if (txTo.vjoinsplit.size() > 0) {
|
||||||
|
::Serialize(s, txTo.joinSplitPubKey);
|
||||||
|
|
||||||
|
CTransaction::joinsplit_sig_t nullSig = {};
|
||||||
|
::Serialize(s, nullSig);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1213,9 +1233,11 @@ template PrecomputedTransactionData::PrecomputedTransactionData(const CTransacti
|
||||||
template PrecomputedTransactionData::PrecomputedTransactionData(const CMutableTransaction& txTo);
|
template PrecomputedTransactionData::PrecomputedTransactionData(const CMutableTransaction& txTo);
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache)
|
uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn, int nHashType, const int forkid, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache)
|
||||||
{
|
{
|
||||||
assert(nIn < txTo.vin.size());
|
if (nIn >= txTo.vin.size() && nIn != NOT_AN_INPUT) {
|
||||||
|
throw std::logic_error("input index is out of range");
|
||||||
|
}
|
||||||
|
|
||||||
if (sigversion == SigVersion::WITNESS_V0) {
|
if (sigversion == SigVersion::WITNESS_V0) {
|
||||||
uint256 hashPrevouts;
|
uint256 hashPrevouts;
|
||||||
|
@ -1263,22 +1285,24 @@ uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn
|
||||||
return ss.GetHash();
|
return ss.GetHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
|
|
||||||
|
|
||||||
// Check for invalid use of SIGHASH_SINGLE
|
// Check for invalid use of SIGHASH_SINGLE
|
||||||
if ((nHashType & 0x1f) == SIGHASH_SINGLE) {
|
if ((nHashType & 0x1f) == SIGHASH_SINGLE) {
|
||||||
if (nIn >= txTo.vout.size()) {
|
if (nIn >= txTo.vout.size()) {
|
||||||
// nOut out of range
|
throw std::logic_error("no matching output for SIGHASH_SINGLE");
|
||||||
return one;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nForkHashType = nHashType;
|
||||||
|
if (UsesForkId(nHashType))
|
||||||
|
nForkHashType |= forkid << 8;
|
||||||
|
|
||||||
// Wrapper to serialize only the necessary parts of the transaction being signed
|
// Wrapper to serialize only the necessary parts of the transaction being signed
|
||||||
CTransactionSignatureSerializer<T> txTmp(txTo, scriptCode, nIn, nHashType);
|
CTransactionSignatureSerializer<T> txTmp(txTo, scriptCode, nIn, nHashType);
|
||||||
|
|
||||||
// Serialize and hash
|
// Serialize and hash
|
||||||
CHashWriter ss(SER_GETHASH, 0);
|
CHashWriter ss(SER_GETHASH, 0);
|
||||||
ss << txTmp << nHashType;
|
ss << txTmp << nForkHashType;
|
||||||
return ss.GetHash();
|
return ss.GetHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1289,7 +1313,7 @@ bool GenericTransactionSignatureChecker<T>::VerifySignature(const std::vector<un
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
bool GenericTransactionSignatureChecker<T>::CheckSig(const std::vector<unsigned char>& vchSigIn, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const
|
bool GenericTransactionSignatureChecker<T>::CheckSig(const std::vector<unsigned char>& vchSigIn, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, const int forkid, SigVersion sigversion) const
|
||||||
{
|
{
|
||||||
CPubKey pubkey(vchPubKey);
|
CPubKey pubkey(vchPubKey);
|
||||||
if (!pubkey.IsValid())
|
if (!pubkey.IsValid())
|
||||||
|
@ -1299,10 +1323,15 @@ bool GenericTransactionSignatureChecker<T>::CheckSig(const std::vector<unsigned
|
||||||
std::vector<unsigned char> vchSig(vchSigIn);
|
std::vector<unsigned char> vchSig(vchSigIn);
|
||||||
if (vchSig.empty())
|
if (vchSig.empty())
|
||||||
return false;
|
return false;
|
||||||
int nHashType = vchSig.back();
|
int nHashType = GetHashType(vchSig);
|
||||||
vchSig.pop_back();
|
vchSig.pop_back();
|
||||||
|
|
||||||
uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion, this->txdata);
|
uint256 sighash;
|
||||||
|
try {
|
||||||
|
sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, forkid, amount, sigversion, this->txdata);
|
||||||
|
} catch (std::logic_error ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!VerifySignature(vchSig, pubkey, sighash))
|
if (!VerifySignature(vchSig, pubkey, sighash))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -12,12 +12,16 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <climits>
|
||||||
|
|
||||||
class CPubKey;
|
class CPubKey;
|
||||||
class CScript;
|
class CScript;
|
||||||
class CTransaction;
|
class CTransaction;
|
||||||
class uint256;
|
class uint256;
|
||||||
|
|
||||||
|
/** Special case nIn for signing JoinSplits. */
|
||||||
|
const unsigned int NOT_AN_INPUT = UINT_MAX;
|
||||||
|
|
||||||
/** Signature hash types/flags */
|
/** Signature hash types/flags */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -28,6 +32,8 @@ enum
|
||||||
SIGHASH_ANYONECANPAY = 0x80,
|
SIGHASH_ANYONECANPAY = 0x80,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const int SIGHASH_FLAGS_MASK = SIGHASH_FORKID | SIGHASH_ANYONECANPAY;
|
||||||
|
static const int SIGHASH_BASE_MASK = ~SIGHASH_FLAGS_MASK;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -158,12 +164,12 @@ static constexpr size_t WITNESS_V0_SCRIPTHASH_SIZE = 32;
|
||||||
static constexpr size_t WITNESS_V0_KEYHASH_SIZE = 20;
|
static constexpr size_t WITNESS_V0_KEYHASH_SIZE = 20;
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache = nullptr);
|
uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn, int nHashType, const int forkid, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache = nullptr);
|
||||||
|
|
||||||
class BaseSignatureChecker
|
class BaseSignatureChecker
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const
|
virtual bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, const int forkid, SigVersion sigversion) const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -196,7 +202,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(nullptr) {}
|
GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(nullptr) {}
|
||||||
GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, const PrecomputedTransactionData& txdataIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {}
|
GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, const PrecomputedTransactionData& txdataIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {}
|
||||||
bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override;
|
bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, const int forkid, SigVersion sigversion) const override;
|
||||||
bool CheckLockTime(const CScriptNum& nLockTime) const override;
|
bool CheckLockTime(const CScriptNum& nLockTime) const override;
|
||||||
bool CheckSequence(const CScriptNum& nSequence) const override;
|
bool CheckSequence(const CScriptNum& nSequence) const override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,7 +26,12 @@ bool MutableTransactionSignatureCreator::CreateSig(const SigningProvider& provid
|
||||||
if (sigversion == SigVersion::WITNESS_V0 && !key.IsCompressed())
|
if (sigversion == SigVersion::WITNESS_V0 && !key.IsCompressed())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion);
|
uint256 hash;
|
||||||
|
try {
|
||||||
|
hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, FORKID_IN_USE, amount, sigversion);
|
||||||
|
} catch (std::logic_error ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (!key.Sign(hash, vchSig))
|
if (!key.Sign(hash, vchSig))
|
||||||
return false;
|
return false;
|
||||||
vchSig.push_back((unsigned char)nHashType);
|
vchSig.push_back((unsigned char)nHashType);
|
||||||
|
@ -209,7 +214,7 @@ bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, C
|
||||||
{
|
{
|
||||||
assert(nIn < txTo.vin.size());
|
assert(nIn < txTo.vin.size());
|
||||||
|
|
||||||
MutableTransactionSignatureCreator creator(&txTo, nIn, amount, nHashType);
|
MutableTransactionSignatureCreator creator(&txTo, nIn, amount, nHashType | SIGHASH_FORKID);
|
||||||
|
|
||||||
SignatureData sigdata;
|
SignatureData sigdata;
|
||||||
bool ret = ProduceSignature(provider, creator, fromPubKey, sigdata);
|
bool ret = ProduceSignature(provider, creator, fromPubKey, sigdata);
|
||||||
|
@ -257,7 +262,7 @@ static std::vector<valtype> CombineMultisig(const CScript& scriptPubKey, const B
|
||||||
if (sigs.count(pubkey))
|
if (sigs.count(pubkey))
|
||||||
continue; // Already got a sig for this pubkey
|
continue; // Already got a sig for this pubkey
|
||||||
|
|
||||||
if (checker.CheckSig(sig, pubkey, scriptPubKey, sigversion))
|
if (checker.CheckSig(sig, pubkey, scriptPubKey, FORKID_IN_USE, sigversion))
|
||||||
{
|
{
|
||||||
sigs[pubkey] = sig;
|
sigs[pubkey] = sig;
|
||||||
break;
|
break;
|
||||||
|
@ -395,7 +400,7 @@ class DummySignatureChecker final : public BaseSignatureChecker
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DummySignatureChecker() {}
|
DummySignatureChecker() {}
|
||||||
bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override { return true; }
|
bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, const int forkid, SigVersion sigversion) const override { return true; }
|
||||||
};
|
};
|
||||||
const DummySignatureChecker DUMMY_CHECKER;
|
const DummySignatureChecker DUMMY_CHECKER;
|
||||||
|
|
||||||
|
@ -415,7 +420,7 @@ public:
|
||||||
vchSig[4 + 33] = 0x02;
|
vchSig[4 + 33] = 0x02;
|
||||||
vchSig[5 + 33] = 32;
|
vchSig[5 + 33] = 32;
|
||||||
vchSig[6 + 33] = 0x01;
|
vchSig[6 + 33] = 0x01;
|
||||||
vchSig[6 + 33 + 32] = SIGHASH_ALL;
|
vchSig[6 + 33 + 32] = SIGHASH_ALL | SIGHASH_FORKID;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,7 +21,7 @@ BOOST_FIXTURE_TEST_SUITE(multisig_tests, BasicTestingSetup)
|
||||||
static CScript
|
static CScript
|
||||||
sign_multisig(const CScript& scriptPubKey, const std::vector<CKey>& keys, const CTransaction& transaction, int whichIn)
|
sign_multisig(const CScript& scriptPubKey, const std::vector<CKey>& keys, const CTransaction& transaction, int whichIn)
|
||||||
{
|
{
|
||||||
uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL, 0, SigVersion::BASE);
|
uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL, FORKID_NONE, 0, SigVersion::BASE);
|
||||||
|
|
||||||
CScript result;
|
CScript result;
|
||||||
result << OP_0; // CHECKMULTISIG bug workaround
|
result << OP_0; // CHECKMULTISIG bug workaround
|
||||||
|
|
|
@ -365,7 +365,7 @@ public:
|
||||||
|
|
||||||
TestBuilder& PushSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32, SigVersion sigversion = SigVersion::BASE, CAmount amount = 0)
|
TestBuilder& PushSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32, SigVersion sigversion = SigVersion::BASE, CAmount amount = 0)
|
||||||
{
|
{
|
||||||
uint256 hash = SignatureHash(script, spendTx, 0, nHashType, amount, sigversion);
|
uint256 hash = SignatureHash(script, spendTx, 0, nHashType, FORKID_NONE, amount, sigversion);
|
||||||
std::vector<unsigned char> vchSig, r, s;
|
std::vector<unsigned char> vchSig, r, s;
|
||||||
uint32_t iter = 0;
|
uint32_t iter = 0;
|
||||||
do {
|
do {
|
||||||
|
@ -515,7 +515,7 @@ BOOST_AUTO_TEST_CASE(script_build)
|
||||||
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG,
|
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG,
|
||||||
"P2SH(P2PK), bad redeemscript", SCRIPT_VERIFY_P2SH, true
|
"P2SH(P2PK), bad redeemscript", SCRIPT_VERIFY_P2SH, true
|
||||||
).PushSig(keys.key0).PushRedeem().DamagePush(10).ScriptError(SCRIPT_ERR_EVAL_FALSE));
|
).PushSig(keys.key0).PushRedeem().DamagePush(10).ScriptError(SCRIPT_ERR_EVAL_FALSE));
|
||||||
|
|
||||||
tests.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey0.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG,
|
tests.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey0.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG,
|
||||||
"P2SH(P2PKH)", SCRIPT_VERIFY_P2SH, true
|
"P2SH(P2PKH)", SCRIPT_VERIFY_P2SH, true
|
||||||
).PushSig(keys.key0).Push(keys.pubkey0).PushRedeem());
|
).PushSig(keys.key0).Push(keys.pubkey0).PushRedeem());
|
||||||
|
@ -1033,7 +1033,7 @@ BOOST_AUTO_TEST_CASE(script_PushData)
|
||||||
static CScript
|
static CScript
|
||||||
sign_multisig(const CScript& scriptPubKey, const std::vector<CKey>& keys, const CTransaction& transaction)
|
sign_multisig(const CScript& scriptPubKey, const std::vector<CKey>& keys, const CTransaction& transaction)
|
||||||
{
|
{
|
||||||
uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL, 0, SigVersion::BASE);
|
uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL, FORKID_NONE, 0, SigVersion::BASE);
|
||||||
|
|
||||||
CScript result;
|
CScript result;
|
||||||
//
|
//
|
||||||
|
@ -1229,15 +1229,15 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
|
||||||
|
|
||||||
// A couple of partially-signed versions:
|
// A couple of partially-signed versions:
|
||||||
std::vector<unsigned char> sig1;
|
std::vector<unsigned char> sig1;
|
||||||
uint256 hash1 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL, 0, SigVersion::BASE);
|
uint256 hash1 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL, FORKID_NONE, 0, SigVersion::BASE);
|
||||||
BOOST_CHECK(keys[0].Sign(hash1, sig1));
|
BOOST_CHECK(keys[0].Sign(hash1, sig1));
|
||||||
sig1.push_back(SIGHASH_ALL);
|
sig1.push_back(SIGHASH_ALL);
|
||||||
std::vector<unsigned char> sig2;
|
std::vector<unsigned char> sig2;
|
||||||
uint256 hash2 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE, 0, SigVersion::BASE);
|
uint256 hash2 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE, FORKID_NONE, 0, SigVersion::BASE);
|
||||||
BOOST_CHECK(keys[1].Sign(hash2, sig2));
|
BOOST_CHECK(keys[1].Sign(hash2, sig2));
|
||||||
sig2.push_back(SIGHASH_NONE);
|
sig2.push_back(SIGHASH_NONE);
|
||||||
std::vector<unsigned char> sig3;
|
std::vector<unsigned char> sig3;
|
||||||
uint256 hash3 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_SINGLE, 0, SigVersion::BASE);
|
uint256 hash3 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_SINGLE, FORKID_NONE, 0, SigVersion::BASE);
|
||||||
BOOST_CHECK(keys[2].Sign(hash3, sig3));
|
BOOST_CHECK(keys[2].Sign(hash3, sig3));
|
||||||
sig3.push_back(SIGHASH_SINGLE);
|
sig3.push_back(SIGHASH_SINGLE);
|
||||||
|
|
||||||
|
@ -1340,116 +1340,6 @@ ScriptFromHex(const char* hex)
|
||||||
return CScript(data.begin(), data.end());
|
return CScript(data.begin(), data.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(script_FindAndDelete)
|
|
||||||
{
|
|
||||||
// Exercise the FindAndDelete functionality
|
|
||||||
CScript s;
|
|
||||||
CScript d;
|
|
||||||
CScript expect;
|
|
||||||
|
|
||||||
s = CScript() << OP_1 << OP_2;
|
|
||||||
d = CScript(); // delete nothing should be a no-op
|
|
||||||
expect = s;
|
|
||||||
BOOST_CHECK_EQUAL(FindAndDelete(s, d), 0);
|
|
||||||
BOOST_CHECK(s == expect);
|
|
||||||
|
|
||||||
s = CScript() << OP_1 << OP_2 << OP_3;
|
|
||||||
d = CScript() << OP_2;
|
|
||||||
expect = CScript() << OP_1 << OP_3;
|
|
||||||
BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1);
|
|
||||||
BOOST_CHECK(s == expect);
|
|
||||||
|
|
||||||
s = CScript() << OP_3 << OP_1 << OP_3 << OP_3 << OP_4 << OP_3;
|
|
||||||
d = CScript() << OP_3;
|
|
||||||
expect = CScript() << OP_1 << OP_4;
|
|
||||||
BOOST_CHECK_EQUAL(FindAndDelete(s, d), 4);
|
|
||||||
BOOST_CHECK(s == expect);
|
|
||||||
|
|
||||||
s = ScriptFromHex("0302ff03"); // PUSH 0x02ff03 onto stack
|
|
||||||
d = ScriptFromHex("0302ff03");
|
|
||||||
expect = CScript();
|
|
||||||
BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1);
|
|
||||||
BOOST_CHECK(s == expect);
|
|
||||||
|
|
||||||
s = ScriptFromHex("0302ff030302ff03"); // PUSH 0x2ff03 PUSH 0x2ff03
|
|
||||||
d = ScriptFromHex("0302ff03");
|
|
||||||
expect = CScript();
|
|
||||||
BOOST_CHECK_EQUAL(FindAndDelete(s, d), 2);
|
|
||||||
BOOST_CHECK(s == expect);
|
|
||||||
|
|
||||||
s = ScriptFromHex("0302ff030302ff03");
|
|
||||||
d = ScriptFromHex("02");
|
|
||||||
expect = s; // FindAndDelete matches entire opcodes
|
|
||||||
BOOST_CHECK_EQUAL(FindAndDelete(s, d), 0);
|
|
||||||
BOOST_CHECK(s == expect);
|
|
||||||
|
|
||||||
s = ScriptFromHex("0302ff030302ff03");
|
|
||||||
d = ScriptFromHex("ff");
|
|
||||||
expect = s;
|
|
||||||
BOOST_CHECK_EQUAL(FindAndDelete(s, d), 0);
|
|
||||||
BOOST_CHECK(s == expect);
|
|
||||||
|
|
||||||
// This is an odd edge case: strip of the push-three-bytes
|
|
||||||
// prefix, leaving 02ff03 which is push-two-bytes:
|
|
||||||
s = ScriptFromHex("0302ff030302ff03");
|
|
||||||
d = ScriptFromHex("03");
|
|
||||||
expect = CScript() << ParseHex("ff03") << ParseHex("ff03");
|
|
||||||
BOOST_CHECK_EQUAL(FindAndDelete(s, d), 2);
|
|
||||||
BOOST_CHECK(s == expect);
|
|
||||||
|
|
||||||
// Byte sequence that spans multiple opcodes:
|
|
||||||
s = ScriptFromHex("02feed5169"); // PUSH(0xfeed) OP_1 OP_VERIFY
|
|
||||||
d = ScriptFromHex("feed51");
|
|
||||||
expect = s;
|
|
||||||
BOOST_CHECK_EQUAL(FindAndDelete(s, d), 0); // doesn't match 'inside' opcodes
|
|
||||||
BOOST_CHECK(s == expect);
|
|
||||||
|
|
||||||
s = ScriptFromHex("02feed5169"); // PUSH(0xfeed) OP_1 OP_VERIFY
|
|
||||||
d = ScriptFromHex("02feed51");
|
|
||||||
expect = ScriptFromHex("69");
|
|
||||||
BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1);
|
|
||||||
BOOST_CHECK(s == expect);
|
|
||||||
|
|
||||||
s = ScriptFromHex("516902feed5169");
|
|
||||||
d = ScriptFromHex("feed51");
|
|
||||||
expect = s;
|
|
||||||
BOOST_CHECK_EQUAL(FindAndDelete(s, d), 0);
|
|
||||||
BOOST_CHECK(s == expect);
|
|
||||||
|
|
||||||
s = ScriptFromHex("516902feed5169");
|
|
||||||
d = ScriptFromHex("02feed51");
|
|
||||||
expect = ScriptFromHex("516969");
|
|
||||||
BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1);
|
|
||||||
BOOST_CHECK(s == expect);
|
|
||||||
|
|
||||||
s = CScript() << OP_0 << OP_0 << OP_1 << OP_1;
|
|
||||||
d = CScript() << OP_0 << OP_1;
|
|
||||||
expect = CScript() << OP_0 << OP_1; // FindAndDelete is single-pass
|
|
||||||
BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1);
|
|
||||||
BOOST_CHECK(s == expect);
|
|
||||||
|
|
||||||
s = CScript() << OP_0 << OP_0 << OP_1 << OP_0 << OP_1 << OP_1;
|
|
||||||
d = CScript() << OP_0 << OP_1;
|
|
||||||
expect = CScript() << OP_0 << OP_1; // FindAndDelete is single-pass
|
|
||||||
BOOST_CHECK_EQUAL(FindAndDelete(s, d), 2);
|
|
||||||
BOOST_CHECK(s == expect);
|
|
||||||
|
|
||||||
// Another weird edge case:
|
|
||||||
// End with invalid push (not enough data)...
|
|
||||||
s = ScriptFromHex("0003feed");
|
|
||||||
d = ScriptFromHex("03feed"); // ... can remove the invalid push
|
|
||||||
expect = ScriptFromHex("00");
|
|
||||||
BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1);
|
|
||||||
BOOST_CHECK(s == expect);
|
|
||||||
|
|
||||||
s = ScriptFromHex("0003feed");
|
|
||||||
d = ScriptFromHex("00");
|
|
||||||
expect = ScriptFromHex("03feed");
|
|
||||||
BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1);
|
|
||||||
BOOST_CHECK(s == expect);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(script_HasValidOps)
|
BOOST_AUTO_TEST_CASE(script_HasValidOps)
|
||||||
{
|
{
|
||||||
// Exercise the HasValidOps functionality
|
// Exercise the HasValidOps functionality
|
||||||
|
|
|
@ -35,7 +35,7 @@ uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, un
|
||||||
|
|
||||||
// In case concatenating two scripts ends up with two codeseparators,
|
// In case concatenating two scripts ends up with two codeseparators,
|
||||||
// or an extra one at the end, this prevents all those possible incompatibilities.
|
// or an extra one at the end, this prevents all those possible incompatibilities.
|
||||||
FindAndDelete(scriptCode, CScript(OP_CODESEPARATOR));
|
//FindAndDelete(scriptCode, CScript(OP_CODESEPARATOR));
|
||||||
|
|
||||||
// Blank out other inputs' signatures
|
// Blank out other inputs' signatures
|
||||||
for (unsigned int i = 0; i < txTmp.vin.size(); i++)
|
for (unsigned int i = 0; i < txTmp.vin.size(); i++)
|
||||||
|
@ -138,7 +138,7 @@ BOOST_AUTO_TEST_CASE(sighash_test)
|
||||||
|
|
||||||
uint256 sh, sho;
|
uint256 sh, sho;
|
||||||
sho = SignatureHashOld(scriptCode, txTo, nIn, nHashType);
|
sho = SignatureHashOld(scriptCode, txTo, nIn, nHashType);
|
||||||
sh = SignatureHash(scriptCode, txTo, nIn, nHashType, 0, SigVersion::BASE);
|
sh = SignatureHash(scriptCode, txTo, nIn, nHashType, FORKID_NONE, 0, SigVersion::BASE);
|
||||||
#if defined(PRINT_SIGHASH_JSON)
|
#if defined(PRINT_SIGHASH_JSON)
|
||||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
ss << txTo;
|
ss << txTo;
|
||||||
|
@ -204,7 +204,7 @@ BOOST_AUTO_TEST_CASE(sighash_from_data)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
sh = SignatureHash(scriptCode, *tx, nIn, nHashType, 0, SigVersion::BASE);
|
sh = SignatureHash(scriptCode, *tx, nIn, nHashType, FORKID_NONE, 0, SigVersion::BASE);
|
||||||
BOOST_CHECK_MESSAGE(sh.GetHex() == sigHashHex, strTest);
|
BOOST_CHECK_MESSAGE(sh.GetHex() == sigHashHex, strTest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,8 @@ std::ostream& operator<<(std::ostream& os, const uint256& num)
|
||||||
|
|
||||||
BasicTestingSetup::BasicTestingSetup(const std::string& chainName)
|
BasicTestingSetup::BasicTestingSetup(const std::string& chainName)
|
||||||
{
|
{
|
||||||
|
assert(init_and_check_sodium() != -1);
|
||||||
|
|
||||||
SHA256AutoDetect();
|
SHA256AutoDetect();
|
||||||
RandomInit();
|
RandomInit();
|
||||||
ECC_Start();
|
ECC_Start();
|
||||||
|
|
|
@ -56,7 +56,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
|
||||||
|
|
||||||
// Sign:
|
// Sign:
|
||||||
std::vector<unsigned char> vchSig;
|
std::vector<unsigned char> vchSig;
|
||||||
uint256 hash = SignatureHash(scriptPubKey, spends[i], 0, SIGHASH_ALL, 0, SigVersion::BASE);
|
uint256 hash = SignatureHash(scriptPubKey, spends[i], 0, SIGHASH_ALL, FORKID_NONE, 0, SigVersion::BASE);
|
||||||
BOOST_CHECK(coinbaseKey.Sign(hash, vchSig));
|
BOOST_CHECK(coinbaseKey.Sign(hash, vchSig));
|
||||||
vchSig.push_back((unsigned char)SIGHASH_ALL);
|
vchSig.push_back((unsigned char)SIGHASH_ALL);
|
||||||
spends[i].vin[0].scriptSig << vchSig;
|
spends[i].vin[0].scriptSig << vchSig;
|
||||||
|
@ -182,7 +182,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
|
||||||
// Sign, with a non-DER signature
|
// Sign, with a non-DER signature
|
||||||
{
|
{
|
||||||
std::vector<unsigned char> vchSig;
|
std::vector<unsigned char> vchSig;
|
||||||
uint256 hash = SignatureHash(p2pk_scriptPubKey, spend_tx, 0, SIGHASH_ALL, 0, SigVersion::BASE);
|
uint256 hash = SignatureHash(p2pk_scriptPubKey, spend_tx, 0, SIGHASH_ALL, FORKID_NONE, 0, SigVersion::BASE);
|
||||||
BOOST_CHECK(coinbaseKey.Sign(hash, vchSig));
|
BOOST_CHECK(coinbaseKey.Sign(hash, vchSig));
|
||||||
vchSig.push_back((unsigned char) 0); // padding byte makes this non-DER
|
vchSig.push_back((unsigned char) 0); // padding byte makes this non-DER
|
||||||
vchSig.push_back((unsigned char)SIGHASH_ALL);
|
vchSig.push_back((unsigned char)SIGHASH_ALL);
|
||||||
|
@ -256,7 +256,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
|
||||||
|
|
||||||
// Sign
|
// Sign
|
||||||
std::vector<unsigned char> vchSig;
|
std::vector<unsigned char> vchSig;
|
||||||
uint256 hash = SignatureHash(spend_tx.vout[2].scriptPubKey, invalid_with_cltv_tx, 0, SIGHASH_ALL, 0, SigVersion::BASE);
|
uint256 hash = SignatureHash(spend_tx.vout[2].scriptPubKey, invalid_with_cltv_tx, 0, SIGHASH_ALL, FORKID_NONE, 0, SigVersion::BASE);
|
||||||
BOOST_CHECK(coinbaseKey.Sign(hash, vchSig));
|
BOOST_CHECK(coinbaseKey.Sign(hash, vchSig));
|
||||||
vchSig.push_back((unsigned char)SIGHASH_ALL);
|
vchSig.push_back((unsigned char)SIGHASH_ALL);
|
||||||
invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 101;
|
invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 101;
|
||||||
|
@ -284,7 +284,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
|
||||||
|
|
||||||
// Sign
|
// Sign
|
||||||
std::vector<unsigned char> vchSig;
|
std::vector<unsigned char> vchSig;
|
||||||
uint256 hash = SignatureHash(spend_tx.vout[3].scriptPubKey, invalid_with_csv_tx, 0, SIGHASH_ALL, 0, SigVersion::BASE);
|
uint256 hash = SignatureHash(spend_tx.vout[3].scriptPubKey, invalid_with_csv_tx, 0, SIGHASH_ALL, FORKID_NONE, 0, SigVersion::BASE);
|
||||||
BOOST_CHECK(coinbaseKey.Sign(hash, vchSig));
|
BOOST_CHECK(coinbaseKey.Sign(hash, vchSig));
|
||||||
vchSig.push_back((unsigned char)SIGHASH_ALL);
|
vchSig.push_back((unsigned char)SIGHASH_ALL);
|
||||||
invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 101;
|
invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 101;
|
||||||
|
|
|
@ -436,7 +436,7 @@ bool CheckSequenceLocks(const CTransaction &tx, int flags, LockPoints* lp, bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the script flags which should be checked for a given block
|
// Returns the script flags which should be checked for a given block
|
||||||
static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consensus::Params& chainparams);
|
static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const CChainParams& chainparams);
|
||||||
|
|
||||||
static void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age) {
|
static void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age) {
|
||||||
int expired = pool.Expire(GetTime() - age);
|
int expired = pool.Expire(GetTime() - age);
|
||||||
|
@ -940,7 +940,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
|
||||||
// There is a similar check in CreateNewBlock() to prevent creating
|
// There is a similar check in CreateNewBlock() to prevent creating
|
||||||
// invalid blocks (using TestBlockValidity), however allowing such
|
// invalid blocks (using TestBlockValidity), however allowing such
|
||||||
// transactions into the mempool can be exploited as a DoS attack.
|
// transactions into the mempool can be exploited as a DoS attack.
|
||||||
unsigned int currentBlockScriptVerifyFlags = GetBlockScriptFlags(chainActive.Tip(), Params().GetConsensus());
|
unsigned int currentBlockScriptVerifyFlags = GetBlockScriptFlags(chainActive.Tip(), Params());
|
||||||
if (!CheckInputsFromMempoolAndCache(tx, state, view, pool, currentBlockScriptVerifyFlags, true, txdata)) {
|
if (!CheckInputsFromMempoolAndCache(tx, state, view, pool, currentBlockScriptVerifyFlags, true, txdata)) {
|
||||||
// If we're using promiscuousmempoolflags, we may hit this normally
|
// If we're using promiscuousmempoolflags, we may hit this normally
|
||||||
// Check if current block has some flags that scriptVerifyFlags
|
// Check if current block has some flags that scriptVerifyFlags
|
||||||
|
@ -1789,9 +1789,11 @@ static bool IsScriptWitnessEnabled(const Consensus::Params& params)
|
||||||
return params.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout != 0;
|
return params.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consensus::Params& consensusparams) {
|
static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const CChainParams& chainparams) {
|
||||||
AssertLockHeld(cs_main);
|
AssertLockHeld(cs_main);
|
||||||
|
|
||||||
|
const Consensus::Params& consensusparams = chainparams.GetConsensus();
|
||||||
|
|
||||||
unsigned int flags = SCRIPT_VERIFY_NONE;
|
unsigned int flags = SCRIPT_VERIFY_NONE;
|
||||||
|
|
||||||
flags |= SCRIPT_VERIFY_P2SH;
|
flags |= SCRIPT_VERIFY_P2SH;
|
||||||
|
@ -1807,9 +1809,9 @@ static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consens
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start enforcing rules for first hard fork
|
// Start enforcing rules for first hard fork
|
||||||
if (isForkEnabled(pindex->nHeight)){
|
if (isForkEnabled(pindex->nHeight, chainparams.ForkStartHeight())){
|
||||||
flags |= SCRIPT_VERIFY_FORKID;
|
flags |= SCRIPT_VERIFY_FORKID;
|
||||||
flags |= SCRIPT_VERIFY_WITNESS_BOOTSTRAP;
|
flags |= SCRIPT_VERIFY_WITNESS_FORK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start enforcing BIP68 (sequence locks) and BIP112 (CHECKSEQUENCEVERIFY) using versionbits logic.
|
// Start enforcing BIP68 (sequence locks) and BIP112 (CHECKSEQUENCEVERIFY) using versionbits logic.
|
||||||
|
@ -1941,7 +1943,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the script flags for this block
|
// Get the script flags for this block
|
||||||
unsigned int flags = GetBlockScriptFlags(pindex, chainparams.GetConsensus());
|
unsigned int flags = GetBlockScriptFlags(pindex, chainparams);
|
||||||
|
|
||||||
int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1;
|
int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1;
|
||||||
LogPrint(BCLog::BENCH, " - Fork checks: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime2 - nTime1), nTimeForks * MICRO, nTimeForks * MILLI / nBlocksTotal);
|
LogPrint(BCLog::BENCH, " - Fork checks: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime2 - nTime1), nTimeForks * MICRO, nTimeForks * MILLI / nBlocksTotal);
|
||||||
|
|
Loading…
Reference in New Issue