mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-21 14:34:49 +01:00
Make all SignatureChecker explicit about missing data
Remove the implicit MissingDataBehavior::ASSERT_FAIL in the *TransationSignatureChecker constructors, and instead specify it explicit in all call sites: * Test code uses ASSERT_FAIL * Validation uses ASSERT_FAIL (through CachingTransactionSignatureChecker) (including signet) * libconsensus uses FAIL, matching the existing behavior of the non-amount API (and the extended required data for taproot validation is not available yet) * Signing code uses FAIL
This commit is contained in:
parent
b77b0cc507
commit
3820090bd6
13 changed files with 39 additions and 39 deletions
|
@ -56,7 +56,7 @@ static void VerifyScriptBench(benchmark::Bench& bench)
|
||||||
txCredit.vout[0].scriptPubKey,
|
txCredit.vout[0].scriptPubKey,
|
||||||
&txSpend.vin[0].scriptWitness,
|
&txSpend.vin[0].scriptWitness,
|
||||||
flags,
|
flags,
|
||||||
MutableTransactionSignatureChecker(&txSpend, 0, txCredit.vout[0].nValue),
|
MutableTransactionSignatureChecker(&txSpend, 0, txCredit.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL),
|
||||||
&err);
|
&err);
|
||||||
assert(err == SCRIPT_ERR_OK);
|
assert(err == SCRIPT_ERR_OK);
|
||||||
assert(success);
|
assert(success);
|
||||||
|
|
|
@ -92,7 +92,7 @@ static int verify_script(const unsigned char *scriptPubKey, unsigned int scriptP
|
||||||
set_error(err, bitcoinconsensus_ERR_OK);
|
set_error(err, bitcoinconsensus_ERR_OK);
|
||||||
|
|
||||||
PrecomputedTransactionData txdata(tx);
|
PrecomputedTransactionData txdata(tx);
|
||||||
return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), &tx.vin[nIn].scriptWitness, flags, TransactionSignatureChecker(&tx, nIn, amount, txdata), nullptr);
|
return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), &tx.vin[nIn].scriptWitness, flags, TransactionSignatureChecker(&tx, nIn, amount, txdata, MissingDataBehavior::FAIL), nullptr);
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing
|
return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing
|
||||||
}
|
}
|
||||||
|
|
|
@ -271,8 +271,8 @@ protected:
|
||||||
virtual bool VerifySchnorrSignature(Span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const;
|
virtual bool VerifySchnorrSignature(Span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, MissingDataBehavior mdb = MissingDataBehavior::ASSERT_FAIL) : txTo(txToIn), m_mdb(mdb), nIn(nInIn), amount(amountIn), txdata(nullptr) {}
|
GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, MissingDataBehavior mdb) : txTo(txToIn), m_mdb(mdb), nIn(nInIn), amount(amountIn), txdata(nullptr) {}
|
||||||
GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, const PrecomputedTransactionData& txdataIn, MissingDataBehavior mdb = MissingDataBehavior::ASSERT_FAIL) : txTo(txToIn), m_mdb(mdb), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {}
|
GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, const PrecomputedTransactionData& txdataIn, MissingDataBehavior mdb) : txTo(txToIn), m_mdb(mdb), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {}
|
||||||
bool CheckECDSASignature(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override;
|
bool CheckECDSASignature(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override;
|
||||||
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, const ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override;
|
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, const ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override;
|
||||||
bool CheckLockTime(const CScriptNum& nLockTime) const override;
|
bool CheckLockTime(const CScriptNum& nLockTime) const override;
|
||||||
|
|
|
@ -27,7 +27,7 @@ private:
|
||||||
bool store;
|
bool store;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, bool storeIn, PrecomputedTransactionData& txdataIn) : TransactionSignatureChecker(txToIn, nInIn, amountIn, txdataIn), store(storeIn) {}
|
CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, bool storeIn, PrecomputedTransactionData& txdataIn) : TransactionSignatureChecker(txToIn, nInIn, amountIn, txdataIn, MissingDataBehavior::ASSERT_FAIL), store(storeIn) {}
|
||||||
|
|
||||||
bool VerifyECDSASignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const override;
|
bool VerifyECDSASignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const override;
|
||||||
bool VerifySchnorrSignature(Span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const override;
|
bool VerifySchnorrSignature(Span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const override;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
typedef std::vector<unsigned char> valtype;
|
typedef std::vector<unsigned char> valtype;
|
||||||
|
|
||||||
MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {}
|
MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn, MissingDataBehavior::FAIL) {}
|
||||||
|
|
||||||
bool MutableTransactionSignatureCreator::CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode, SigVersion sigversion) const
|
bool MutableTransactionSignatureCreator::CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode, SigVersion sigversion) const
|
||||||
{
|
{
|
||||||
|
@ -292,7 +292,7 @@ SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nI
|
||||||
Stacks stack(data);
|
Stacks stack(data);
|
||||||
|
|
||||||
// Get signatures
|
// Get signatures
|
||||||
MutableTransactionSignatureChecker tx_checker(&tx, nIn, txout.nValue);
|
MutableTransactionSignatureChecker tx_checker(&tx, nIn, txout.nValue, MissingDataBehavior::FAIL);
|
||||||
SignatureExtractorChecker extractor_checker(data, tx_checker);
|
SignatureExtractorChecker extractor_checker(data, tx_checker);
|
||||||
if (VerifyScript(data.scriptSig, txout.scriptPubKey, &data.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, extractor_checker)) {
|
if (VerifyScript(data.scriptSig, txout.scriptPubKey, &data.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, extractor_checker)) {
|
||||||
data.complete = true;
|
data.complete = true;
|
||||||
|
@ -499,7 +499,7 @@ bool SignTransaction(CMutableTransaction& mtx, const SigningProvider* keystore,
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptError serror = SCRIPT_ERR_OK;
|
ScriptError serror = SCRIPT_ERR_OK;
|
||||||
if (!VerifyScript(txin.scriptSig, prevPubKey, &txin.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount), &serror)) {
|
if (!VerifyScript(txin.scriptSig, prevPubKey, &txin.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount, MissingDataBehavior::FAIL), &serror)) {
|
||||||
if (serror == SCRIPT_ERR_INVALID_STACK_OPERATION) {
|
if (serror == SCRIPT_ERR_INVALID_STACK_OPERATION) {
|
||||||
// Unable to sign input and verification failed (possible attempt to partially sign).
|
// Unable to sign input and verification failed (possible attempt to partially sign).
|
||||||
input_errors[i] = "Unable to sign input, invalid stack size (possibly missing key)";
|
input_errors[i] = "Unable to sign input, invalid stack size (possibly missing key)";
|
||||||
|
|
|
@ -139,7 +139,7 @@ bool CheckSignetBlockSolution(const CBlock& block, const Consensus::Params& cons
|
||||||
const CScript& scriptSig = signet_txs->m_to_sign.vin[0].scriptSig;
|
const CScript& scriptSig = signet_txs->m_to_sign.vin[0].scriptSig;
|
||||||
const CScriptWitness& witness = signet_txs->m_to_sign.vin[0].scriptWitness;
|
const CScriptWitness& witness = signet_txs->m_to_sign.vin[0].scriptWitness;
|
||||||
|
|
||||||
TransactionSignatureChecker sigcheck(&signet_txs->m_to_sign, /*nIn=*/ 0, /*amount=*/ signet_txs->m_to_spend.vout[0].nValue);
|
TransactionSignatureChecker sigcheck(&signet_txs->m_to_sign, /*nIn=*/ 0, /*amount=*/ signet_txs->m_to_spend.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL);
|
||||||
|
|
||||||
if (!VerifyScript(scriptSig, signet_txs->m_to_spend.vout[0].scriptPubKey, &witness, BLOCK_SCRIPT_VERIFY_FLAGS, sigcheck)) {
|
if (!VerifyScript(scriptSig, signet_txs->m_to_spend.vout[0].scriptPubKey, &witness, BLOCK_SCRIPT_VERIFY_FLAGS, sigcheck)) {
|
||||||
LogPrint(BCLog::VALIDATION, "CheckSignetBlockSolution: Errors in block (block solution invalid)\n");
|
LogPrint(BCLog::VALIDATION, "CheckSignetBlockSolution: Errors in block (block solution invalid)\n");
|
||||||
|
|
|
@ -161,7 +161,7 @@ void Test(const std::string& str)
|
||||||
tx.vin[idx].scriptWitness = ScriptWitnessFromJSON(test["success"]["witness"]);
|
tx.vin[idx].scriptWitness = ScriptWitnessFromJSON(test["success"]["witness"]);
|
||||||
PrecomputedTransactionData txdata;
|
PrecomputedTransactionData txdata;
|
||||||
txdata.Init(tx, std::vector<CTxOut>(prevouts));
|
txdata.Init(tx, std::vector<CTxOut>(prevouts));
|
||||||
MutableTransactionSignatureChecker txcheck(&tx, idx, prevouts[idx].nValue, txdata);
|
MutableTransactionSignatureChecker txcheck(&tx, idx, prevouts[idx].nValue, txdata, MissingDataBehavior::ASSERT_FAIL);
|
||||||
for (const auto flags : ALL_FLAGS) {
|
for (const auto flags : ALL_FLAGS) {
|
||||||
// "final": true tests are valid for all flags. Others are only valid with flags that are
|
// "final": true tests are valid for all flags. Others are only valid with flags that are
|
||||||
// a subset of test_flags.
|
// a subset of test_flags.
|
||||||
|
@ -176,7 +176,7 @@ void Test(const std::string& str)
|
||||||
tx.vin[idx].scriptWitness = ScriptWitnessFromJSON(test["failure"]["witness"]);
|
tx.vin[idx].scriptWitness = ScriptWitnessFromJSON(test["failure"]["witness"]);
|
||||||
PrecomputedTransactionData txdata;
|
PrecomputedTransactionData txdata;
|
||||||
txdata.Init(tx, std::vector<CTxOut>(prevouts));
|
txdata.Init(tx, std::vector<CTxOut>(prevouts));
|
||||||
MutableTransactionSignatureChecker txcheck(&tx, idx, prevouts[idx].nValue, txdata);
|
MutableTransactionSignatureChecker txcheck(&tx, idx, prevouts[idx].nValue, txdata, MissingDataBehavior::ASSERT_FAIL);
|
||||||
for (const auto flags : ALL_FLAGS) {
|
for (const auto flags : ALL_FLAGS) {
|
||||||
// If a test is supposed to fail with test_flags, it should also fail with any superset thereof.
|
// If a test is supposed to fail with test_flags, it should also fail with any superset thereof.
|
||||||
if ((flags & test_flags) == test_flags) {
|
if ((flags & test_flags) == test_flags) {
|
||||||
|
|
|
@ -50,7 +50,7 @@ FUZZ_TARGET_INIT(script_flags, initialize_script_flags)
|
||||||
|
|
||||||
for (unsigned i = 0; i < tx.vin.size(); ++i) {
|
for (unsigned i = 0; i < tx.vin.size(); ++i) {
|
||||||
const CTxOut& prevout = txdata.m_spent_outputs.at(i);
|
const CTxOut& prevout = txdata.m_spent_outputs.at(i);
|
||||||
const TransactionSignatureChecker checker{&tx, i, prevout.nValue, txdata};
|
const TransactionSignatureChecker checker{&tx, i, prevout.nValue, txdata, MissingDataBehavior::ASSERT_FAIL};
|
||||||
|
|
||||||
ScriptError serror;
|
ScriptError serror;
|
||||||
const bool ret = VerifyScript(tx.vin.at(i).scriptSig, prevout.scriptPubKey, &tx.vin.at(i).scriptWitness, verify_flags, checker, &serror);
|
const bool ret = VerifyScript(tx.vin.at(i).scriptSig, prevout.scriptPubKey, &tx.vin.at(i).scriptWitness, verify_flags, checker, &serror);
|
||||||
|
|
|
@ -77,20 +77,20 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
|
||||||
keys.assign(1,key[0]);
|
keys.assign(1,key[0]);
|
||||||
keys.push_back(key[1]);
|
keys.push_back(key[1]);
|
||||||
s = sign_multisig(a_and_b, keys, CTransaction(txTo[0]), 0);
|
s = sign_multisig(a_and_b, keys, CTransaction(txTo[0]), 0);
|
||||||
BOOST_CHECK(VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err));
|
BOOST_CHECK(VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err));
|
||||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
keys.assign(1,key[i]);
|
keys.assign(1,key[i]);
|
||||||
s = sign_multisig(a_and_b, keys, CTransaction(txTo[0]), 0);
|
s = sign_multisig(a_and_b, keys, CTransaction(txTo[0]), 0);
|
||||||
BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err), strprintf("a&b 1: %d", i));
|
BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err), strprintf("a&b 1: %d", i));
|
||||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
|
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
|
||||||
|
|
||||||
keys.assign(1,key[1]);
|
keys.assign(1,key[1]);
|
||||||
keys.push_back(key[i]);
|
keys.push_back(key[i]);
|
||||||
s = sign_multisig(a_and_b, keys, CTransaction(txTo[0]), 0);
|
s = sign_multisig(a_and_b, keys, CTransaction(txTo[0]), 0);
|
||||||
BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err), strprintf("a&b 2: %d", i));
|
BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err), strprintf("a&b 2: %d", i));
|
||||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,18 +101,18 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
|
||||||
s = sign_multisig(a_or_b, keys, CTransaction(txTo[1]), 0);
|
s = sign_multisig(a_or_b, keys, CTransaction(txTo[1]), 0);
|
||||||
if (i == 0 || i == 1)
|
if (i == 0 || i == 1)
|
||||||
{
|
{
|
||||||
BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err), strprintf("a|b: %d", i));
|
BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err), strprintf("a|b: %d", i));
|
||||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err), strprintf("a|b: %d", i));
|
BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err), strprintf("a|b: %d", i));
|
||||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.clear();
|
s.clear();
|
||||||
s << OP_0 << OP_1;
|
s << OP_0 << OP_1;
|
||||||
BOOST_CHECK(!VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err));
|
BOOST_CHECK(!VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err));
|
||||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err));
|
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err));
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,12 +124,12 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
|
||||||
s = sign_multisig(escrow, keys, CTransaction(txTo[2]), 0);
|
s = sign_multisig(escrow, keys, CTransaction(txTo[2]), 0);
|
||||||
if (i < j && i < 3 && j < 3)
|
if (i < j && i < 3 && j < 3)
|
||||||
{
|
{
|
||||||
BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, nullptr, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), &err), strprintf("escrow 1: %d %d", i, j));
|
BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, nullptr, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err), strprintf("escrow 1: %d %d", i, j));
|
||||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, nullptr, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), &err), strprintf("escrow 2: %d %d", i, j));
|
BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, nullptr, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err), strprintf("escrow 2: %d %d", i, j));
|
||||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict, Scri
|
||||||
txTo.vin[0].scriptSig = scriptSig;
|
txTo.vin[0].scriptSig = scriptSig;
|
||||||
txTo.vout[0].nValue = 1;
|
txTo.vout[0].nValue = 1;
|
||||||
|
|
||||||
return VerifyScript(scriptSig, scriptPubKey, nullptr, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0, txFrom.vout[0].nValue), &err);
|
return VerifyScript(scriptSig, scriptPubKey, nullptr, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0, txFrom.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScript
|
||||||
const CTransaction txCredit{BuildCreditingTransaction(scriptPubKey, nValue)};
|
const CTransaction txCredit{BuildCreditingTransaction(scriptPubKey, nValue)};
|
||||||
CMutableTransaction tx = BuildSpendingTransaction(scriptSig, scriptWitness, txCredit);
|
CMutableTransaction tx = BuildSpendingTransaction(scriptSig, scriptWitness, txCredit);
|
||||||
CMutableTransaction tx2 = tx;
|
CMutableTransaction tx2 = tx;
|
||||||
BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, &scriptWitness, flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue), &err) == expect, message);
|
BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, &scriptWitness, flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err) == expect, message);
|
||||||
BOOST_CHECK_MESSAGE(err == scriptError, FormatScriptError(err) + " where " + FormatScriptError((ScriptError_t)scriptError) + " expected: " + message);
|
BOOST_CHECK_MESSAGE(err == scriptError, FormatScriptError(err) + " where " + FormatScriptError((ScriptError_t)scriptError) + " expected: " + message);
|
||||||
|
|
||||||
// Verify that removing flags from a passing test or adding flags to a failing test does not change the result.
|
// Verify that removing flags from a passing test or adding flags to a failing test does not change the result.
|
||||||
|
@ -145,7 +145,7 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScript
|
||||||
// Weed out some invalid flag combinations.
|
// Weed out some invalid flag combinations.
|
||||||
if (combined_flags & SCRIPT_VERIFY_CLEANSTACK && ~combined_flags & (SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS)) continue;
|
if (combined_flags & SCRIPT_VERIFY_CLEANSTACK && ~combined_flags & (SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS)) continue;
|
||||||
if (combined_flags & SCRIPT_VERIFY_WITNESS && ~combined_flags & SCRIPT_VERIFY_P2SH) continue;
|
if (combined_flags & SCRIPT_VERIFY_WITNESS && ~combined_flags & SCRIPT_VERIFY_P2SH) continue;
|
||||||
BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, &scriptWitness, combined_flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue), &err) == expect, message + strprintf(" (with flags %x)", combined_flags));
|
BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, &scriptWitness, combined_flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err) == expect, message + strprintf(" (with flags %x)", combined_flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_CONSENSUS_LIB)
|
#if defined(HAVE_CONSENSUS_LIB)
|
||||||
|
@ -1071,18 +1071,18 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12)
|
||||||
CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), CScriptWitness(), txFrom12);
|
CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), CScriptWitness(), txFrom12);
|
||||||
|
|
||||||
CScript goodsig1 = sign_multisig(scriptPubKey12, key1, CTransaction(txTo12));
|
CScript goodsig1 = sign_multisig(scriptPubKey12, key1, CTransaction(txTo12));
|
||||||
BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err));
|
BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
|
||||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
||||||
txTo12.vout[0].nValue = 2;
|
txTo12.vout[0].nValue = 2;
|
||||||
BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err));
|
BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
|
||||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
||||||
|
|
||||||
CScript goodsig2 = sign_multisig(scriptPubKey12, key2, CTransaction(txTo12));
|
CScript goodsig2 = sign_multisig(scriptPubKey12, key2, CTransaction(txTo12));
|
||||||
BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err));
|
BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
|
||||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
||||||
|
|
||||||
CScript badsig1 = sign_multisig(scriptPubKey12, key3, CTransaction(txTo12));
|
CScript badsig1 = sign_multisig(scriptPubKey12, key3, CTransaction(txTo12));
|
||||||
BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err));
|
BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
|
||||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1104,54 +1104,54 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23)
|
||||||
std::vector<CKey> keys;
|
std::vector<CKey> keys;
|
||||||
keys.push_back(key1); keys.push_back(key2);
|
keys.push_back(key1); keys.push_back(key2);
|
||||||
CScript goodsig1 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
|
CScript goodsig1 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
|
||||||
BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
|
BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
|
||||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
||||||
|
|
||||||
keys.clear();
|
keys.clear();
|
||||||
keys.push_back(key1); keys.push_back(key3);
|
keys.push_back(key1); keys.push_back(key3);
|
||||||
CScript goodsig2 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
|
CScript goodsig2 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
|
||||||
BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
|
BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
|
||||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
||||||
|
|
||||||
keys.clear();
|
keys.clear();
|
||||||
keys.push_back(key2); keys.push_back(key3);
|
keys.push_back(key2); keys.push_back(key3);
|
||||||
CScript goodsig3 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
|
CScript goodsig3 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
|
||||||
BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
|
BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
|
||||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
||||||
|
|
||||||
keys.clear();
|
keys.clear();
|
||||||
keys.push_back(key2); keys.push_back(key2); // Can't re-use sig
|
keys.push_back(key2); keys.push_back(key2); // Can't re-use sig
|
||||||
CScript badsig1 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
|
CScript badsig1 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
|
||||||
BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
|
BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
|
||||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
||||||
|
|
||||||
keys.clear();
|
keys.clear();
|
||||||
keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order
|
keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order
|
||||||
CScript badsig2 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
|
CScript badsig2 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
|
||||||
BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
|
BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
|
||||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
||||||
|
|
||||||
keys.clear();
|
keys.clear();
|
||||||
keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order
|
keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order
|
||||||
CScript badsig3 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
|
CScript badsig3 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
|
||||||
BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
|
BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
|
||||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
||||||
|
|
||||||
keys.clear();
|
keys.clear();
|
||||||
keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys
|
keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys
|
||||||
CScript badsig4 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
|
CScript badsig4 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
|
||||||
BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
|
BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
|
||||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
||||||
|
|
||||||
keys.clear();
|
keys.clear();
|
||||||
keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys
|
keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys
|
||||||
CScript badsig5 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
|
CScript badsig5 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
|
||||||
BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
|
BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
|
||||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
||||||
|
|
||||||
keys.clear(); // Must have signatures
|
keys.clear(); // Must have signatures
|
||||||
CScript badsig6 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
|
CScript badsig6 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
|
||||||
BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
|
BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
|
||||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
|
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ static ScriptError VerifyWithFlag(const CTransaction& output, const CMutableTran
|
||||||
{
|
{
|
||||||
ScriptError error;
|
ScriptError error;
|
||||||
CTransaction inputi(input);
|
CTransaction inputi(input);
|
||||||
bool ret = VerifyScript(inputi.vin[0].scriptSig, output.vout[0].scriptPubKey, &inputi.vin[0].scriptWitness, flags, TransactionSignatureChecker(&inputi, 0, output.vout[0].nValue), &error);
|
bool ret = VerifyScript(inputi.vin[0].scriptSig, output.vout[0].scriptPubKey, &inputi.vin[0].scriptWitness, flags, TransactionSignatureChecker(&inputi, 0, output.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &error);
|
||||||
BOOST_CHECK((ret == true) == (error == SCRIPT_ERR_OK));
|
BOOST_CHECK((ret == true) == (error == SCRIPT_ERR_OK));
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
|
|
@ -108,7 +108,7 @@ bool CheckTxScripts(const CTransaction& tx, const std::map<COutPoint, CScript>&
|
||||||
const CAmount amount = map_prevout_values.count(input.prevout) ? map_prevout_values.at(input.prevout) : 0;
|
const CAmount amount = map_prevout_values.count(input.prevout) ? map_prevout_values.at(input.prevout) : 0;
|
||||||
try {
|
try {
|
||||||
tx_valid = VerifyScript(input.scriptSig, map_prevout_scriptPubKeys.at(input.prevout),
|
tx_valid = VerifyScript(input.scriptSig, map_prevout_scriptPubKeys.at(input.prevout),
|
||||||
&input.scriptWitness, flags, TransactionSignatureChecker(&tx, i, amount, txdata), &err);
|
&input.scriptWitness, flags, TransactionSignatureChecker(&tx, i, amount, txdata, MissingDataBehavior::ASSERT_FAIL), &err);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
BOOST_ERROR("Bad test: " << strTest);
|
BOOST_ERROR("Bad test: " << strTest);
|
||||||
return true; // The test format is bad and an error is thrown. Return true to silence further error.
|
return true; // The test format is bad and an error is thrown. Return true to silence further error.
|
||||||
|
@ -427,7 +427,7 @@ static void CheckWithFlag(const CTransactionRef& output, const CMutableTransacti
|
||||||
{
|
{
|
||||||
ScriptError error;
|
ScriptError error;
|
||||||
CTransaction inputi(input);
|
CTransaction inputi(input);
|
||||||
bool ret = VerifyScript(inputi.vin[0].scriptSig, output->vout[0].scriptPubKey, &inputi.vin[0].scriptWitness, flags, TransactionSignatureChecker(&inputi, 0, output->vout[0].nValue), &error);
|
bool ret = VerifyScript(inputi.vin[0].scriptSig, output->vout[0].scriptPubKey, &inputi.vin[0].scriptWitness, flags, TransactionSignatureChecker(&inputi, 0, output->vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &error);
|
||||||
assert(ret == success);
|
assert(ret == success);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue