mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-15 12:51:00 +02:00
Merge bd65a76b9d into merged_master (Bitcoin PR #21330)
This commit is contained in:
commit
9645faf781
14 changed files with 74 additions and 42 deletions
|
|
@ -57,7 +57,7 @@ static void VerifyScriptBench(benchmark::Bench& bench)
|
|||
txCredit.vout[0].scriptPubKey,
|
||||
&txSpend.witness.vtxinwit[0].scriptWitness,
|
||||
flags,
|
||||
MutableTransactionSignatureChecker(&txSpend, 0, txCredit.vout[0].nValue),
|
||||
MutableTransactionSignatureChecker(&txSpend, 0, txCredit.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL),
|
||||
&err);
|
||||
assert(err == SCRIPT_ERR_OK);
|
||||
assert(success);
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ static int verify_script(const unsigned char *scriptPubKey, unsigned int scriptP
|
|||
|
||||
PrecomputedTransactionData txdata(tx);
|
||||
const CScriptWitness* pScriptWitness = (tx.witness.vtxinwit.size() > nIn ? &tx.witness.vtxinwit[nIn].scriptWitness : NULL);
|
||||
return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), pScriptWitness, flags, TransactionSignatureChecker(&tx, nIn, amount, txdata), NULL);
|
||||
return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), pScriptWitness, flags, TransactionSignatureChecker(&tx, nIn, amount, txdata, MissingDataBehavior::FAIL), nullptr);
|
||||
} catch (const std::exception&) {
|
||||
return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1911,8 +1911,20 @@ static const CHashWriter HASHER_TAPLEAF = TaggedHash("TapLeaf");
|
|||
static const CHashWriter HASHER_TAPBRANCH = TaggedHash("TapBranch");
|
||||
static const CHashWriter HASHER_TAPTWEAK = TaggedHash("TapTweak");
|
||||
|
||||
static bool HandleMissingData(MissingDataBehavior mdb)
|
||||
{
|
||||
switch (mdb) {
|
||||
case MissingDataBehavior::ASSERT_FAIL:
|
||||
assert(!"Missing data");
|
||||
break;
|
||||
case MissingDataBehavior::FAIL:
|
||||
return false;
|
||||
}
|
||||
assert(!"Unknown MissingDataBehavior value");
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool SignatureHashSchnorr(uint256& hash_out, const ScriptExecutionData& execdata, const T& tx_to, uint32_t in_pos, uint8_t hash_type, SigVersion sigversion, const PrecomputedTransactionData& cache)
|
||||
bool SignatureHashSchnorr(uint256& hash_out, const ScriptExecutionData& execdata, const T& tx_to, uint32_t in_pos, uint8_t hash_type, SigVersion sigversion, const PrecomputedTransactionData& cache, MissingDataBehavior mdb)
|
||||
{
|
||||
uint8_t ext_flag, key_version;
|
||||
switch (sigversion) {
|
||||
|
|
@ -1932,7 +1944,9 @@ bool SignatureHashSchnorr(uint256& hash_out, const ScriptExecutionData& execdata
|
|||
assert(false);
|
||||
}
|
||||
assert(in_pos < tx_to.vin.size());
|
||||
assert(cache.m_bip341_taproot_ready && cache.m_spent_outputs_ready);
|
||||
if (!(cache.m_bip341_taproot_ready && cache.m_spent_outputs_ready)) {
|
||||
return HandleMissingData(mdb);
|
||||
}
|
||||
|
||||
CHashWriter ss = HASHER_TAPSIGHASH;
|
||||
|
||||
|
|
@ -2128,6 +2142,9 @@ bool GenericTransactionSignatureChecker<T>::CheckECDSASignature(const std::vecto
|
|||
int nHashType = vchSig.back();
|
||||
vchSig.pop_back();
|
||||
|
||||
// Witness sighashes need the amount.
|
||||
if (sigversion == SigVersion::WITNESS_V0 && amount.IsNull()) return HandleMissingData(m_mdb);
|
||||
|
||||
uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion, flags, this->txdata);
|
||||
|
||||
if (!VerifyECDSASignature(vchSig, pubkey, sighash))
|
||||
|
|
@ -2157,7 +2174,7 @@ bool GenericTransactionSignatureChecker<T>::CheckSchnorrSignature(Span<const uns
|
|||
}
|
||||
uint256 sighash;
|
||||
assert(this->txdata);
|
||||
if (!SignatureHashSchnorr(sighash, execdata, *txTo, nIn, hashtype, sigversion, *this->txdata)) {
|
||||
if (!SignatureHashSchnorr(sighash, execdata, *txTo, nIn, hashtype, sigversion, *this->txdata, m_mdb)) {
|
||||
return set_error(serror, SCRIPT_ERR_SCHNORR_SIG_HASHTYPE);
|
||||
}
|
||||
if (!VerifySchnorrSignature(sig, pubkey, sighash)) return set_error(serror, SCRIPT_ERR_SCHNORR_SIG);
|
||||
|
|
|
|||
|
|
@ -261,11 +261,21 @@ public:
|
|||
virtual ~BaseSignatureChecker() {}
|
||||
};
|
||||
|
||||
/** Enum to specify what *TransactionSignatureChecker's behavior should be
|
||||
* when dealing with missing transaction data.
|
||||
*/
|
||||
enum class MissingDataBehavior
|
||||
{
|
||||
ASSERT_FAIL, //!< Abort execution through assertion failure (for consensus code)
|
||||
FAIL, //!< Just act as if the signature was invalid
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class GenericTransactionSignatureChecker : public BaseSignatureChecker
|
||||
{
|
||||
private:
|
||||
const T* txTo;
|
||||
const MissingDataBehavior m_mdb;
|
||||
unsigned int nIn;
|
||||
const CConfidentialValue amount;
|
||||
const PrecomputedTransactionData* txdata;
|
||||
|
|
@ -275,8 +285,8 @@ protected:
|
|||
virtual bool VerifySchnorrSignature(Span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const;
|
||||
|
||||
public:
|
||||
GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CConfidentialValue& amountIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(nullptr) {}
|
||||
GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CConfidentialValue& amountIn, const PrecomputedTransactionData& txdataIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {}
|
||||
GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CConfidentialValue& amountIn, MissingDataBehavior mdb) : txTo(txToIn), m_mdb(mdb), nIn(nInIn), amount(amountIn), txdata(nullptr) {}
|
||||
GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CConfidentialValue& 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, unsigned int flags) 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;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ private:
|
|||
bool store;
|
||||
|
||||
public:
|
||||
CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CConfidentialValue& amountIn, bool storeIn, PrecomputedTransactionData& txdataIn) : TransactionSignatureChecker(txToIn, nInIn, amountIn, txdataIn), store(storeIn) {}
|
||||
CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CConfidentialValue& 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 VerifySchnorrSignature(Span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const override;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
typedef std::vector<unsigned char> valtype;
|
||||
|
||||
MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction* txToIn, unsigned int nInIn, const CConfidentialValue& amountIn, int nHashTypeIn) : txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {}
|
||||
MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction* txToIn, unsigned int nInIn, const CConfidentialValue& 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, unsigned int flags) const
|
||||
{
|
||||
|
|
@ -30,6 +30,9 @@ bool MutableTransactionSignatureCreator::CreateSig(const SigningProvider& provid
|
|||
if (sigversion == SigVersion::WITNESS_V0 && !key.IsCompressed())
|
||||
return false;
|
||||
|
||||
// Signing for witness scripts needs the amount.
|
||||
if (sigversion == SigVersion::WITNESS_V0 && amount.IsNull()) return false;
|
||||
|
||||
uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion, flags);
|
||||
if (!key.Sign(hash, vchSig))
|
||||
return false;
|
||||
|
|
@ -310,7 +313,7 @@ SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nI
|
|||
Stacks stack(data);
|
||||
|
||||
// Get signatures
|
||||
MutableTransactionSignatureChecker tx_checker(&tx, nIn, txout.nValue);
|
||||
MutableTransactionSignatureChecker tx_checker(&tx, nIn, txout.nValue, MissingDataBehavior::FAIL);
|
||||
SignatureExtractorChecker extractor_checker(data, tx_checker);
|
||||
if (VerifyScript(data.scriptSig, txout.scriptPubKey, &data.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, extractor_checker)) {
|
||||
data.complete = true;
|
||||
|
|
@ -533,7 +536,7 @@ bool SignTransaction(CMutableTransaction& mtx, const SigningProvider* keystore,
|
|||
}
|
||||
|
||||
ScriptError serror = SCRIPT_ERR_OK;
|
||||
if (!VerifyScript(txin.scriptSig, prevPubKey, &inWitness.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount), &serror)) {
|
||||
if (!VerifyScript(txin.scriptSig, prevPubKey, &inWitness.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount, MissingDataBehavior::FAIL), &serror)) {
|
||||
if (serror == SCRIPT_ERR_INVALID_STACK_OPERATION) {
|
||||
// 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)";
|
||||
|
|
|
|||
|
|
@ -140,7 +140,9 @@ bool CheckSignetBlockSolution(const CBlock& block, const Consensus::Params& cons
|
|||
const CScript& scriptSig = signet_txs->m_to_sign.vin[0].scriptSig;
|
||||
const CScriptWitness& witness = signet_txs->m_to_sign.witness.vtxinwit[0].scriptWitness;
|
||||
|
||||
TransactionSignatureChecker sigcheck(&signet_txs->m_to_sign, /*nIn=*/ 0, /*amount=*/ signet_txs->m_to_spend.vout[0].nValue);
|
||||
PrecomputedTransactionData txdata;
|
||||
txdata.Init(signet_txs->m_to_sign, {signet_txs->m_to_spend.vout[0]});
|
||||
TransactionSignatureChecker sigcheck(&signet_txs->m_to_sign, /*nIn=*/ 0, /*amount=*/ signet_txs->m_to_spend.vout[0].nValue, txdata, MissingDataBehavior::ASSERT_FAIL);
|
||||
|
||||
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");
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ void Test(const std::string& str)
|
|||
tx.witness.vtxinwit[idx].scriptWitness = ScriptWitnessFromJSON(test["success"]["witness"]);
|
||||
PrecomputedTransactionData txdata;
|
||||
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) {
|
||||
// "final": true tests are valid for all flags. Others are only valid with flags that are
|
||||
// a subset of test_flags.
|
||||
|
|
@ -178,7 +178,7 @@ void Test(const std::string& str)
|
|||
tx.witness.vtxinwit[idx].scriptWitness = ScriptWitnessFromJSON(test["failure"]["witness"]);
|
||||
PrecomputedTransactionData txdata;
|
||||
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) {
|
||||
// If a test is supposed to fail with test_flags, it should also fail with any superset thereof.
|
||||
if ((flags & test_flags) == test_flags) {
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ FUZZ_TARGET_INIT(script_flags, initialize_script_flags)
|
|||
|
||||
for (unsigned i = 0; i < tx.vin.size(); ++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;
|
||||
const CScriptWitness *script_witness = tx.witness.vtxinwit.size() > i ? &tx.witness.vtxinwit[i].scriptWitness : nullptr;
|
||||
|
|
|
|||
|
|
@ -77,20 +77,20 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
|
|||
keys.assign(1,key[0]);
|
||||
keys.push_back(key[1]);
|
||||
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));
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
keys.assign(1,key[i]);
|
||||
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));
|
||||
|
||||
keys.assign(1,key[1]);
|
||||
keys.push_back(key[i]);
|
||||
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));
|
||||
}
|
||||
|
||||
|
|
@ -101,18 +101,18 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
|
|||
s = sign_multisig(a_or_b, keys, CTransaction(txTo[1]), 0);
|
||||
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));
|
||||
}
|
||||
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));
|
||||
}
|
||||
}
|
||||
s.clear();
|
||||
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));
|
||||
|
||||
|
||||
|
|
@ -124,12 +124,12 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
|
|||
s = sign_multisig(escrow, keys, CTransaction(txTo[2]), 0);
|
||||
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));
|
||||
}
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict, Scri
|
|||
txTo.vin[0].scriptSig = scriptSig;
|
||||
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)};
|
||||
CMutableTransaction tx = BuildSpendingTransaction(scriptSig, scriptWitness, txCredit);
|
||||
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);
|
||||
|
||||
// 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.
|
||||
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;
|
||||
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)
|
||||
|
|
@ -1075,18 +1075,18 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12)
|
|||
CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), CScriptWitness(), txFrom12);
|
||||
|
||||
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));
|
||||
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));
|
||||
|
||||
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));
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
|
@ -1108,54 +1108,54 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23)
|
|||
std::vector<CKey> keys;
|
||||
keys.push_back(key1); keys.push_back(key2);
|
||||
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));
|
||||
|
||||
keys.clear();
|
||||
keys.push_back(key1); keys.push_back(key3);
|
||||
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));
|
||||
|
||||
keys.clear();
|
||||
keys.push_back(key2); keys.push_back(key3);
|
||||
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));
|
||||
|
||||
keys.clear();
|
||||
keys.push_back(key2); keys.push_back(key2); // Can't re-use sig
|
||||
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));
|
||||
|
||||
keys.clear();
|
||||
keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order
|
||||
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));
|
||||
|
||||
keys.clear();
|
||||
keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order
|
||||
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));
|
||||
|
||||
keys.clear();
|
||||
keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys
|
||||
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));
|
||||
|
||||
keys.clear();
|
||||
keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys
|
||||
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));
|
||||
|
||||
keys.clear(); // Must have signatures
|
||||
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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ static ScriptError VerifyWithFlag(const CTransaction& output, const CMutableTran
|
|||
output.vout[0].scriptPubKey,
|
||||
&inputi.witness.vtxinwit[0].scriptWitness,
|
||||
flags,
|
||||
TransactionSignatureChecker(&inputi, 0, output.vout[0].nValue),
|
||||
TransactionSignatureChecker(&inputi, 0, output.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL),
|
||||
&error);
|
||||
|
||||
BOOST_CHECK((ret == true) == (error == SCRIPT_ERR_OK));
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ bool CheckTxScripts(const CTransaction& tx, const std::map<COutPoint, CScript>&
|
|||
const CScriptWitness *pScriptWitness = ((tx.witness.vtxinwit.size() > i) ? &tx.witness.vtxinwit[i].scriptWitness : nullptr);
|
||||
flags &= ~SCRIPT_NO_SIGHASH_BYTE; // ELEMENTS: ensure that our random flag-setting doesn't cause the sighash byte to be misinterpreted
|
||||
tx_valid = VerifyScript(input.scriptSig, map_prevout_scriptPubKeys.at(input.prevout),
|
||||
pScriptWitness, flags, TransactionSignatureChecker(&tx, i, amount, txdata), &err);
|
||||
pScriptWitness, flags, TransactionSignatureChecker(&tx, i, amount, txdata, MissingDataBehavior::ASSERT_FAIL), &err);
|
||||
} catch (...) {
|
||||
BOOST_ERROR("Bad test: " << strTest);
|
||||
return true; // The test format is bad and an error is thrown. Return true to silence further error.
|
||||
|
|
@ -441,7 +441,7 @@ static void CheckWithFlag(const CTransactionRef& output, const CMutableTransacti
|
|||
output->vout[0].scriptPubKey,
|
||||
pScriptWitness,
|
||||
flags,
|
||||
TransactionSignatureChecker(&inputi, 0, output->vout[0].nValue),
|
||||
TransactionSignatureChecker(&inputi, 0, output->vout[0].nValue, MissingDataBehavior::ASSERT_FAIL),
|
||||
&error);
|
||||
assert(ret == success);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue