nit:
BOOST_REQUIRE(outpoint) seems to be more appropriate than if (!outpoint) return because the outpoint is required for the rest of the test.
If helper setup fails, the test will fail immediately instead of silently passing by returning early.
<details>
<summary>diff 1</summary>
diff --git a/src/test/validation_block_contextual_tests.cpp b/src/test/validation_block_contextual_tests.cpp
index 380218b00e..f4c41a9464 100644
--- a/src/test/validation_block_contextual_tests.cpp
+++ b/src/test/validation_block_contextual_tests.cpp
@@ -72,7 +72,7 @@ BOOST_AUTO_TEST_CASE(tbv_bad_txns_nonfinal)
// Transactions with time-locks (nLockTime) that are not yet satisfied are rejected.
CBlock block = MakeBlock();
const auto outpoint = AddCoin(CScript() << OP_TRUE, 50 * COIN);
- if (!outpoint) return;
+ BOOST_REQUIRE(outpoint);
CMutableTransaction mtx;
mtx.vin.resize(1);
mtx.vin[0].prevout = *outpoint;
@@ -98,7 +98,7 @@ BOOST_AUTO_TEST_CASE(tbv_bip113_locktime_uses_mtp)
CBlock block = MakeBlock();
const int64_t mtp = WITH_LOCK(cs_main, return m_chainstate.m_chain.Tip()->GetMedianTimePast());
const auto outpoint = AddCoin(CScript() << OP_TRUE, 50 * COIN);
- if (!outpoint) return;
+ BOOST_REQUIRE(outpoint);
CMutableTransaction mtx;
mtx.vin.resize(1);
mtx.vin[0].prevout = *outpoint;
@@ -139,7 +139,7 @@ BOOST_AUTO_TEST_CASE(tbv_bad_blk_weight)
const int num_overweight_txns{4};
for (int tx_idx = 0; tx_idx < num_overweight_txns; ++tx_idx) {
const auto outpoint = AddCoin(p2tr, 50 * COIN);
- if (!outpoint) return;
+ BOOST_REQUIRE(outpoint);
CMutableTransaction mtx;
mtx.vin.resize(1);
mtx.vin[0].prevout = *outpoint;
diff --git a/src/test/validation_block_stateful_tests.cpp b/src/test/validation_block_stateful_tests.cpp
index 95eb6285e2..13a42dad92 100644
--- a/src/test/validation_block_stateful_tests.cpp
+++ b/src/test/validation_block_stateful_tests.cpp
@@ -24,7 +24,8 @@ BOOST_AUTO_TEST_CASE(tbv_bad_txns_accumulated_fee_outofrange)
CBlock block = MakeBlock();
const auto outpoint1 = AddCoin(CScript(), MAX_MONEY);
const auto outpoint2 = AddCoin(CScript(), 1);
- if (!outpoint1 || !outpoint2) return;
+ BOOST_REQUIRE(outpoint1);
+ BOOST_REQUIRE(outpoint2);
CMutableTransaction mtx, mtx2;
mtx.vin.resize(1);
mtx.vin[0].prevout = *outpoint1;
@@ -115,7 +116,8 @@ BOOST_AUTO_TEST_CASE(tbv_bad_txns_inputs_sum_overflow)
CScript script = CScript() << OP_TRUE;
auto outpoint1 = AddCoin(script, MAX_MONEY);
auto outpoint2 = AddCoin(script, MAX_MONEY);
- if (!outpoint1 || !outpoint2) return;
+ BOOST_REQUIRE(outpoint1);
+ BOOST_REQUIRE(outpoint2);
CMutableTransaction mtx;
mtx.vin.resize(2);
mtx.vin[0].prevout = outpoint1.value();
@@ -138,7 +140,7 @@ BOOST_AUTO_TEST_CASE(tbv_block_script_verify_flag_failed)
CBlock block = MakeBlock();
const CScript p2pk = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
const auto outpoint = AddCoin(p2pk, 50 * COIN);
- if (!outpoint) return;
+ BOOST_REQUIRE(outpoint);
CMutableTransaction mtx;
mtx.vin.resize(1);
mtx.vin[0].prevout = *outpoint;
@@ -160,7 +162,7 @@ BOOST_AUTO_TEST_CASE(tbv_bip147_null_dummy)
CBlock block = MakeBlock();
CScript multisig = CScript() << 1 << ToByteVector(coinbaseKey.GetPubKey()) << 1 << OP_CHECKMULTISIG;
const auto outpoint = AddCoin(multisig);
- if (!outpoint) return;
+ BOOST_REQUIRE(outpoint);
CMutableTransaction mtx;
mtx.vin.resize(1);
mtx.vin[0].prevout = *outpoint;
@@ -186,7 +188,7 @@ BOOST_AUTO_TEST_CASE(tbv_bip66_non_der_sig)
CBlock block = MakeBlock();
CScript p2pkh = GetScriptForDestination(PKHash(coinbaseKey.GetPubKey()));
const auto outpoint = AddCoin(p2pkh);
- if (!outpoint) return;
+ BOOST_REQUIRE(outpoint);
CMutableTransaction mtx;
mtx.vin.resize(1);
mtx.vin[0].prevout = *outpoint;
@@ -218,7 +220,7 @@ BOOST_AUTO_TEST_CASE(tbv_bip65_cltv_violation)
const int lock_height = WITH_LOCK(cs_main, return m_chainstate.m_chain.Height()) + cltv_height_offset;
const CScript cltv_script = CScript() << lock_height << OP_CHECKLOCKTIMEVERIFY << OP_DROP << OP_TRUE;
const auto outpoint = AddCoin(cltv_script);
- if (!outpoint) return;
+ BOOST_REQUIRE(outpoint);
CMutableTransaction mtx;
mtx.vin.resize(1);
mtx.vin[0].prevout = *outpoint;
@@ -245,7 +247,7 @@ BOOST_AUTO_TEST_CASE(tbv_taproot_invalid_sig)
WitnessV1Taproot taproot = builder.GetOutput();
CScript p2tr_script = GetScriptForDestination(taproot);
const auto outpoint = AddCoin(p2tr_script);
- if (!outpoint) return;
+ BOOST_REQUIRE(outpoint);
CMutableTransaction mtx;
mtx.vin.resize(1);
mtx.vin[0].prevout = *outpoint;
@@ -278,7 +280,7 @@ BOOST_AUTO_TEST_CASE(tbv_bip112_csv_violation)
uint32_t csv_block_offset = 10;
const CScript csv_script = CScript() << csv_block_offset << OP_CHECKSEQUENCEVERIFY << OP_DROP << OP_TRUE;
const auto outpoint = AddCoin(csv_script);
- if (!outpoint) return;
+ BOOST_REQUIRE(outpoint);
CMutableTransaction mtx;
mtx.version = 2; // CSV requires nVersion >= 2
mtx.vin.resize(1);
@@ -303,7 +305,7 @@ BOOST_AUTO_TEST_CASE(tbv_bip16_p2sh_invalid_redeem_script)
const CScript redeem_script = CScript() << OP_FALSE;
const CScript p2sh = GetScriptForDestination(ScriptHash(redeem_script));
const auto outpoint = AddCoin(p2sh);
- if (!outpoint) return;
+ BOOST_REQUIRE(outpoint);
CMutableTransaction mtx;
mtx.vin.resize(1);
mtx.vin[0].prevout = *outpoint;
@@ -326,7 +328,7 @@ BOOST_AUTO_TEST_CASE(tbv_segwit_v0_invalid_witness_script)
const CScript witness_script = CScript() << OP_FALSE;
const CScript p2wsh = GetScriptForDestination(WitnessV0ScriptHash(witness_script));
const auto outpoint = AddCoin(p2wsh);
- if (!outpoint) return;
+ BOOST_REQUIRE(outpoint);
CMutableTransaction mtx;
mtx.vin.resize(1);
mtx.vin[0].prevout = *outpoint;
@@ -357,7 +359,7 @@ BOOST_AUTO_TEST_CASE(tbv_tapscript_invalid_script_path)
WitnessV1Taproot taproot = builder.GetOutput();
const CScript p2tr_script = GetScriptForDestination(taproot);
const auto outpoint = AddCoin(p2tr_script);
- if (!outpoint) return;
+ BOOST_REQUIRE(outpoint);
// Build the control block for the script path
const auto spend_data = builder.GetSpendData();
const auto& control_block = *spend_data.scripts.at(
@@ -390,7 +392,7 @@ BOOST_AUTO_TEST_CASE(tbv_bip143_wrong_amount_in_sighash)
const CScript p2wpkh = GetScriptForDestination(WitnessV0KeyHash(coinbaseKey.GetPubKey()));
const CAmount actual_value = 1 * COIN;
const auto outpoint = AddCoin(p2wpkh, actual_value);
- if (!outpoint) return;
+ BOOST_REQUIRE(outpoint);
CMutableTransaction mtx;
mtx.vin.resize(1);
mtx.vin[0].prevout = *outpoint;
@@ -418,7 +420,7 @@ BOOST_AUTO_TEST_CASE(tbv_empty_scriptsig)
// A non-coinbase transaction with an empty scriptSig spending OP_TRUE is valid.
CBlock block = MakeBlock();
const auto outpoint = AddCoin(CScript() << OP_TRUE);
- if (!outpoint) return;
+ BOOST_REQUIRE(outpoint);
CMutableTransaction mtx;
mtx.vin.resize(1);
@@ -439,7 +441,7 @@ BOOST_AUTO_TEST_CASE(tbv_scriptsig_non_push)
// A scriptSig with non-push opcodes is valid in a block (consensus) even if non-standard.
CBlock block = MakeBlock();
const auto outpoint = AddCoin(CScript() << OP_TRUE);
- if (!outpoint) return;
+ BOOST_REQUIRE(outpoint);
CMutableTransaction mtx;
mtx.vin.resize(1);
mtx.vin[0].prevout = *outpoint;
@@ -459,7 +461,7 @@ BOOST_AUTO_TEST_CASE(tbv_double_spend_same_block)
// A block containing two transactions spending the same UTXO is invalid.
CBlock block = MakeBlock();
const auto outpoint = AddCoin();
- if (!outpoint) return;
+ BOOST_REQUIRE(outpoint);
for (int tx_idx = 0; tx_idx < 2; ++tx_idx) {
CMutableTransaction mtx;
mtx.vin.resize(1);
@@ -483,7 +485,7 @@ BOOST_AUTO_TEST_CASE(tbv_zero_value_output)
// A transaction with a zero-value output is consensus-valid.
CBlock block = MakeBlock();
const auto outpoint = AddCoin();
- if (!outpoint) return;
+ BOOST_REQUIRE(outpoint);
CMutableTransaction mtx;
mtx.vin.resize(1);
mtx.vin[0].prevout = *outpoint;
</details>
Alternatively, this can be centralized in AddCoin() itself by making it return COutPoint directly and fail internally if no unused outpoint can be found.
<details>
<summary>diff 2</summary>
diff --git a/src/test/util/block_validity.cpp b/src/test/util/block_validity.cpp
index 289339d81c..dfc314b4ae 100644
--- a/src/test/util/block_validity.cpp
+++ b/src/test/util/block_validity.cpp
@@ -29,7 +29,7 @@ BlockValidationState ValidationBlockValidityTestingSetup::TestValidity(CBlock& b
return TestBlockValidity(m_chainstate, block, check_pow, check_merkle);
}
-std::optional<COutPoint> ValidationBlockValidityTestingSetup::AddCoin(const CScript& script_pub_key, CAmount amount)
+COutPoint ValidationBlockValidityTestingSetup::AddCoin(const CScript& script_pub_key, CAmount amount)
{
// Max trials to find a unique random outpoint
const int max_trials{5};
@@ -41,7 +41,8 @@ std::optional<COutPoint> ValidationBlockValidityTestingSetup::AddCoin(const CScr
return outpoint;
}
}
- return std::nullopt;
+ BOOST_REQUIRE_MESSAGE(false, "AddCoin: failed to find an unused outpoint");
+ return {};
}
void ValidationBlockValidityTestingSetup::SolveBlockPoW(CBlock& block)
diff --git a/src/test/util/block_validity.h b/src/test/util/block_validity.h
index 90b1aaf763..db6d5c6f8b 100644
--- a/src/test/util/block_validity.h
+++ b/src/test/util/block_validity.h
@@ -10,8 +10,6 @@
#include <validation.h>
#include <validationinterface.h>
-#include <optional>
-
/**
* A CValidationInterface subscriber that records the BlockValidationState from
* each BlockChecked notification. Use ClearCheckedBlockStates() to reset
@@ -63,7 +61,7 @@ struct ValidationBlockValidityTestingSetup : public TestChain100Setup {
BlockValidationState ConnectBlock(CBlock& block);
/** Helper to add a spendable coin to the UTXO set for testing. */
- std::optional<COutPoint> AddCoin(const CScript& script_pub_key = CScript() << OP_TRUE, CAmount amount = 1 * COIN);
+ COutPoint AddCoin(const CScript& script_pub_key = CScript() << OP_TRUE, CAmount amount = 1 * COIN);
/**
* Submit a block via ProcessNewBlock, drain the validation signal queue,
* and return the single BlockChecked notification state.
diff --git a/src/test/validation_block_contextual_tests.cpp b/src/test/validation_block_contextual_tests.cpp
index 380218b00e..5f59193870 100644
--- a/src/test/validation_block_contextual_tests.cpp
+++ b/src/test/validation_block_contextual_tests.cpp
@@ -72,10 +72,9 @@ BOOST_AUTO_TEST_CASE(tbv_bad_txns_nonfinal)
// Transactions with time-locks (nLockTime) that are not yet satisfied are rejected.
CBlock block = MakeBlock();
const auto outpoint = AddCoin(CScript() << OP_TRUE, 50 * COIN);
- if (!outpoint) return;
CMutableTransaction mtx;
mtx.vin.resize(1);
- mtx.vin[0].prevout = *outpoint;
+ mtx.vin[0].prevout = outpoint;
mtx.vin[0].nSequence = 0;
mtx.vout.resize(1);
mtx.vout[0] = CTxOut(49 * COIN, CScript() << OP_TRUE);
@@ -98,10 +97,9 @@ BOOST_AUTO_TEST_CASE(tbv_bip113_locktime_uses_mtp)
CBlock block = MakeBlock();
const int64_t mtp = WITH_LOCK(cs_main, return m_chainstate.m_chain.Tip()->GetMedianTimePast());
const auto outpoint = AddCoin(CScript() << OP_TRUE, 50 * COIN);
- if (!outpoint) return;
CMutableTransaction mtx;
mtx.vin.resize(1);
- mtx.vin[0].prevout = *outpoint;
+ mtx.vin[0].prevout = outpoint;
mtx.vout.resize(1);
mtx.vout[0].nValue = 49 * COIN;
// nLockTime exactly equal to MTP: non-final because IsFinalTx requires strictly less than MTP
@@ -139,10 +137,9 @@ BOOST_AUTO_TEST_CASE(tbv_bad_blk_weight)
const int num_overweight_txns{4};
for (int tx_idx = 0; tx_idx < num_overweight_txns; ++tx_idx) {
const auto outpoint = AddCoin(p2tr, 50 * COIN);
- if (!outpoint) return;
CMutableTransaction mtx;
mtx.vin.resize(1);
- mtx.vin[0].prevout = *outpoint;
+ mtx.vin[0].prevout = outpoint;
mtx.vout.resize(1);
mtx.vout[0].nValue = 49 * COIN;
// 1MB witness item, allowed by OP_SUCCESS bypassing the 520-byte limit
diff --git a/src/test/validation_block_stateful_tests.cpp b/src/test/validation_block_stateful_tests.cpp
index 95eb6285e2..cd36ee377f 100644
--- a/src/test/validation_block_stateful_tests.cpp
+++ b/src/test/validation_block_stateful_tests.cpp
@@ -24,14 +24,13 @@ BOOST_AUTO_TEST_CASE(tbv_bad_txns_accumulated_fee_outofrange)
CBlock block = MakeBlock();
const auto outpoint1 = AddCoin(CScript(), MAX_MONEY);
const auto outpoint2 = AddCoin(CScript(), 1);
- if (!outpoint1 || !outpoint2) return;
CMutableTransaction mtx, mtx2;
mtx.vin.resize(1);
- mtx.vin[0].prevout = *outpoint1;
+ mtx.vin[0].prevout = outpoint1;
mtx.vout.resize(1);
mtx.vout[0].nValue = 0;
mtx2.vin.resize(1);
- mtx2.vin[0].prevout = *outpoint2;
+ mtx2.vin[0].prevout = outpoint2;
mtx2.vout.resize(1);
mtx2.vout[0].nValue = 0;
block.vtx.emplace_back(MakeTransactionRef(mtx));
@@ -115,11 +114,10 @@ BOOST_AUTO_TEST_CASE(tbv_bad_txns_inputs_sum_overflow)
CScript script = CScript() << OP_TRUE;
auto outpoint1 = AddCoin(script, MAX_MONEY);
auto outpoint2 = AddCoin(script, MAX_MONEY);
- if (!outpoint1 || !outpoint2) return;
CMutableTransaction mtx;
mtx.vin.resize(2);
- mtx.vin[0].prevout = outpoint1.value();
- mtx.vin[1].prevout = outpoint2.value();
+ mtx.vin[0].prevout = outpoint1;
+ mtx.vin[1].prevout = outpoint2;
mtx.vout.resize(1);
mtx.vout[0].nValue = MAX_MONEY;
block.vtx.emplace_back(MakeTransactionRef(mtx));
@@ -138,20 +136,19 @@ BOOST_AUTO_TEST_CASE(tbv_block_script_verify_flag_failed)
CBlock block = MakeBlock();
const CScript p2pk = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
const auto outpoint = AddCoin(p2pk, 50 * COIN);
- if (!outpoint) return;
CMutableTransaction mtx;
mtx.vin.resize(1);
- mtx.vin[0].prevout = *outpoint;
+ mtx.vin[0].prevout = outpoint;
mtx.vin[0].scriptSig = CScript() << OP_0;
mtx.vout.resize(1);
mtx.vout[0].nValue = 49 * COIN;
block.vtx.emplace_back(MakeTransactionRef(std::move(mtx)));
RegenerateCommitments(block, *m_node.chainman);
const auto reason = "block-script-verify-flag-failed (Script evaluated without error but finished with a false/empty top stack element)";
- CheckScriptViolation(TestValidity(block), block, *outpoint, reason);
- CheckScriptViolation(ConnectBlock(block), block, *outpoint, reason);
+ CheckScriptViolation(TestValidity(block), block, outpoint, reason);
+ CheckScriptViolation(ConnectBlock(block), block, outpoint, reason);
SolveBlockPoW(block);
- CheckScriptViolation(ProcessNewBlock(block), block, *outpoint, reason);
+ CheckScriptViolation(ProcessNewBlock(block), block, outpoint, reason);
}
BOOST_AUTO_TEST_CASE(tbv_bip147_null_dummy)
@@ -160,10 +157,9 @@ BOOST_AUTO_TEST_CASE(tbv_bip147_null_dummy)
CBlock block = MakeBlock();
CScript multisig = CScript() << 1 << ToByteVector(coinbaseKey.GetPubKey()) << 1 << OP_CHECKMULTISIG;
const auto outpoint = AddCoin(multisig);
- if (!outpoint) return;
CMutableTransaction mtx;
mtx.vin.resize(1);
- mtx.vin[0].prevout = *outpoint;
+ mtx.vin[0].prevout = outpoint;
mtx.vout.resize(1);
mtx.vout[0].nValue = 0.9 * COIN;
std::vector<unsigned char> sig;
@@ -174,10 +170,10 @@ BOOST_AUTO_TEST_CASE(tbv_bip147_null_dummy)
block.vtx.emplace_back(MakeTransactionRef(mtx));
RegenerateCommitments(block, *m_node.chainman);
const auto reason = "block-script-verify-flag-failed (Dummy CHECKMULTISIG argument must be zero)";
- CheckScriptViolation(TestValidity(block), block, *outpoint, reason);
- CheckScriptViolation(ConnectBlock(block), block, *outpoint, reason);
+ CheckScriptViolation(TestValidity(block), block, outpoint, reason);
+ CheckScriptViolation(ConnectBlock(block), block, outpoint, reason);
SolveBlockPoW(block);
- CheckScriptViolation(ProcessNewBlock(block), block, *outpoint, reason);
+ CheckScriptViolation(ProcessNewBlock(block), block, outpoint, reason);
}
BOOST_AUTO_TEST_CASE(tbv_bip66_non_der_sig)
@@ -186,10 +182,9 @@ BOOST_AUTO_TEST_CASE(tbv_bip66_non_der_sig)
CBlock block = MakeBlock();
CScript p2pkh = GetScriptForDestination(PKHash(coinbaseKey.GetPubKey()));
const auto outpoint = AddCoin(p2pkh);
- if (!outpoint) return;
CMutableTransaction mtx;
mtx.vin.resize(1);
- mtx.vin[0].prevout = *outpoint;
+ mtx.vin[0].prevout = outpoint;
mtx.vout.resize(1);
mtx.vout[0].nValue = 0.9 * COIN;
uint256 hash = SignatureHash(p2pkh, mtx, 0, SIGHASH_ALL, 1 * COIN, SigVersion::BASE);
@@ -202,10 +197,10 @@ BOOST_AUTO_TEST_CASE(tbv_bip66_non_der_sig)
block.vtx.emplace_back(MakeTransactionRef(mtx));
RegenerateCommitments(block, *m_node.chainman);
const auto reason = "block-script-verify-flag-failed (Non-canonical DER signature)";
- CheckScriptViolation(TestValidity(block), block, *outpoint, reason);
- CheckScriptViolation(ConnectBlock(block), block, *outpoint, reason);
+ CheckScriptViolation(TestValidity(block), block, outpoint, reason);
+ CheckScriptViolation(ConnectBlock(block), block, outpoint, reason);
SolveBlockPoW(block);
- CheckScriptViolation(ProcessNewBlock(block), block, *outpoint, reason);
+ CheckScriptViolation(ProcessNewBlock(block), block, outpoint, reason);
}
BOOST_AUTO_TEST_CASE(tbv_bip65_cltv_violation)
@@ -218,10 +213,9 @@ BOOST_AUTO_TEST_CASE(tbv_bip65_cltv_violation)
const int lock_height = WITH_LOCK(cs_main, return m_chainstate.m_chain.Height()) + cltv_height_offset;
const CScript cltv_script = CScript() << lock_height << OP_CHECKLOCKTIMEVERIFY << OP_DROP << OP_TRUE;
const auto outpoint = AddCoin(cltv_script);
- if (!outpoint) return;
CMutableTransaction mtx;
mtx.vin.resize(1);
- mtx.vin[0].prevout = *outpoint;
+ mtx.vin[0].prevout = outpoint;
mtx.vin[0].nSequence = CTxIn::SEQUENCE_FINAL; // Makes IsFinalTx pass, but disables CLTV
mtx.nLockTime = 0;
mtx.vout.resize(1);
@@ -229,10 +223,10 @@ BOOST_AUTO_TEST_CASE(tbv_bip65_cltv_violation)
block.vtx.emplace_back(MakeTransactionRef(mtx));
RegenerateCommitments(block, *m_node.chainman);
const auto reason = "block-script-verify-flag-failed (Locktime requirement not satisfied)";
- CheckScriptViolation(TestValidity(block), block, *outpoint, reason);
- CheckScriptViolation(ConnectBlock(block), block, *outpoint, reason);
+ CheckScriptViolation(TestValidity(block), block, outpoint, reason);
+ CheckScriptViolation(ConnectBlock(block), block, outpoint, reason);
SolveBlockPoW(block);
- CheckScriptViolation(ProcessNewBlock(block), block, *outpoint, reason);
+ CheckScriptViolation(ProcessNewBlock(block), block, outpoint, reason);
}
BOOST_AUTO_TEST_CASE(tbv_taproot_invalid_sig)
@@ -245,10 +239,9 @@ BOOST_AUTO_TEST_CASE(tbv_taproot_invalid_sig)
WitnessV1Taproot taproot = builder.GetOutput();
CScript p2tr_script = GetScriptForDestination(taproot);
const auto outpoint = AddCoin(p2tr_script);
- if (!outpoint) return;
CMutableTransaction mtx;
mtx.vin.resize(1);
- mtx.vin[0].prevout = *outpoint;
+ mtx.vin[0].prevout = outpoint;
mtx.vout.resize(1);
mtx.vout[0].nValue = 0.9 * COIN;
// Create the Taproot signature (Keypath spend)
@@ -264,10 +257,10 @@ BOOST_AUTO_TEST_CASE(tbv_taproot_invalid_sig)
block.vtx.emplace_back(MakeTransactionRef(mtx));
RegenerateCommitments(block, *m_node.chainman);
const auto reason = "block-script-verify-flag-failed (Invalid Schnorr signature)";
- CheckScriptViolation(TestValidity(block), block, *outpoint, reason);
- CheckScriptViolation(ConnectBlock(block), block, *outpoint, reason);
+ CheckScriptViolation(TestValidity(block), block, outpoint, reason);
+ CheckScriptViolation(ConnectBlock(block), block, outpoint, reason);
SolveBlockPoW(block);
- CheckScriptViolation(ProcessNewBlock(block), block, *outpoint, reason);
+ CheckScriptViolation(ProcessNewBlock(block), block, outpoint, reason);
}
BOOST_AUTO_TEST_CASE(tbv_bip112_csv_violation)
@@ -278,21 +271,20 @@ BOOST_AUTO_TEST_CASE(tbv_bip112_csv_violation)
uint32_t csv_block_offset = 10;
const CScript csv_script = CScript() << csv_block_offset << OP_CHECKSEQUENCEVERIFY << OP_DROP << OP_TRUE;
const auto outpoint = AddCoin(csv_script);
- if (!outpoint) return;
CMutableTransaction mtx;
mtx.version = 2; // CSV requires nVersion >= 2
mtx.vin.resize(1);
- mtx.vin[0].prevout = *outpoint;
+ mtx.vin[0].prevout = outpoint;
mtx.vin[0].nSequence = csv_block_offset - 1; // One block short of the requirement
mtx.vout.resize(1);
mtx.vout[0].nValue = 0.9 * COIN;
block.vtx.emplace_back(MakeTransactionRef(mtx));
RegenerateCommitments(block, *m_node.chainman);
const auto reason = "block-script-verify-flag-failed (Locktime requirement not satisfied)";
- CheckScriptViolation(TestValidity(block), block, *outpoint, reason);
- CheckScriptViolation(ConnectBlock(block), block, *outpoint, reason);
+ CheckScriptViolation(TestValidity(block), block, outpoint, reason);
+ CheckScriptViolation(ConnectBlock(block), block, outpoint, reason);
SolveBlockPoW(block);
- CheckScriptViolation(ProcessNewBlock(block), block, *outpoint, reason);
+ CheckScriptViolation(ProcessNewBlock(block), block, outpoint, reason);
}
BOOST_AUTO_TEST_CASE(tbv_bip16_p2sh_invalid_redeem_script)
@@ -303,20 +295,19 @@ BOOST_AUTO_TEST_CASE(tbv_bip16_p2sh_invalid_redeem_script)
const CScript redeem_script = CScript() << OP_FALSE;
const CScript p2sh = GetScriptForDestination(ScriptHash(redeem_script));
const auto outpoint = AddCoin(p2sh);
- if (!outpoint) return;
CMutableTransaction mtx;
mtx.vin.resize(1);
- mtx.vin[0].prevout = *outpoint;
+ mtx.vin[0].prevout = outpoint;
mtx.vin[0].scriptSig = CScript() << std::vector<unsigned char>(redeem_script.begin(), redeem_script.end());
mtx.vout.resize(1);
mtx.vout[0].nValue = 0.9 * COIN;
block.vtx.emplace_back(MakeTransactionRef(mtx));
RegenerateCommitments(block, *m_node.chainman);
const auto reason = "block-script-verify-flag-failed (Script evaluated without error but finished with a false/empty top stack element)";
- CheckScriptViolation(TestValidity(block), block, *outpoint, reason);
- CheckScriptViolation(ConnectBlock(block), block, *outpoint, reason);
+ CheckScriptViolation(TestValidity(block), block, outpoint, reason);
+ CheckScriptViolation(ConnectBlock(block), block, outpoint, reason);
SolveBlockPoW(block);
- CheckScriptViolation(ProcessNewBlock(block), block, *outpoint, reason);
+ CheckScriptViolation(ProcessNewBlock(block), block, outpoint, reason);
}
BOOST_AUTO_TEST_CASE(tbv_segwit_v0_invalid_witness_script)
@@ -326,10 +317,9 @@ BOOST_AUTO_TEST_CASE(tbv_segwit_v0_invalid_witness_script)
const CScript witness_script = CScript() << OP_FALSE;
const CScript p2wsh = GetScriptForDestination(WitnessV0ScriptHash(witness_script));
const auto outpoint = AddCoin(p2wsh);
- if (!outpoint) return;
CMutableTransaction mtx;
mtx.vin.resize(1);
- mtx.vin[0].prevout = *outpoint;
+ mtx.vin[0].prevout = outpoint;
// Witness: <witness_script>
mtx.vin[0].scriptWitness.stack = {
std::vector<unsigned char>(witness_script.begin(), witness_script.end())};
@@ -338,10 +328,10 @@ BOOST_AUTO_TEST_CASE(tbv_segwit_v0_invalid_witness_script)
block.vtx.emplace_back(MakeTransactionRef(mtx));
RegenerateCommitments(block, *m_node.chainman);
const auto reason = "block-script-verify-flag-failed (Script evaluated without error but finished with a false/empty top stack element)";
- CheckScriptViolation(TestValidity(block), block, *outpoint, reason);
- CheckScriptViolation(ConnectBlock(block), block, *outpoint, reason);
+ CheckScriptViolation(TestValidity(block), block, outpoint, reason);
+ CheckScriptViolation(ConnectBlock(block), block, outpoint, reason);
SolveBlockPoW(block);
- CheckScriptViolation(ProcessNewBlock(block), block, *outpoint, reason);
+ CheckScriptViolation(ProcessNewBlock(block), block, outpoint, reason);
}
BOOST_AUTO_TEST_CASE(tbv_tapscript_invalid_script_path)
@@ -357,7 +347,6 @@ BOOST_AUTO_TEST_CASE(tbv_tapscript_invalid_script_path)
WitnessV1Taproot taproot = builder.GetOutput();
const CScript p2tr_script = GetScriptForDestination(taproot);
const auto outpoint = AddCoin(p2tr_script);
- if (!outpoint) return;
// Build the control block for the script path
const auto spend_data = builder.GetSpendData();
const auto& control_block = *spend_data.scripts.at(
@@ -365,7 +354,7 @@ BOOST_AUTO_TEST_CASE(tbv_tapscript_invalid_script_path)
.begin();
CMutableTransaction mtx;
mtx.vin.resize(1);
- mtx.vin[0].prevout = *outpoint;
+ mtx.vin[0].prevout = outpoint;
// Witness stack for script path: <leaf_script> <control_block> (OP_FALSE consumes no args)
mtx.vin[0].scriptWitness.stack = {
std::vector<unsigned char>(leaf_script.begin(), leaf_script.end()),
@@ -375,10 +364,10 @@ BOOST_AUTO_TEST_CASE(tbv_tapscript_invalid_script_path)
block.vtx.emplace_back(MakeTransactionRef(mtx));
RegenerateCommitments(block, *m_node.chainman);
const auto reason = "block-script-verify-flag-failed (Script evaluated without error but finished with a false/empty top stack element)";
- CheckScriptViolation(TestValidity(block), block, *outpoint, reason);
- CheckScriptViolation(ConnectBlock(block), block, *outpoint, reason);
+ CheckScriptViolation(TestValidity(block), block, outpoint, reason);
+ CheckScriptViolation(ConnectBlock(block), block, outpoint, reason);
SolveBlockPoW(block);
- CheckScriptViolation(ProcessNewBlock(block), block, *outpoint, reason);
+ CheckScriptViolation(ProcessNewBlock(block), block, outpoint, reason);
}
BOOST_AUTO_TEST_CASE(tbv_bip143_wrong_amount_in_sighash)
@@ -390,10 +379,9 @@ BOOST_AUTO_TEST_CASE(tbv_bip143_wrong_amount_in_sighash)
const CScript p2wpkh = GetScriptForDestination(WitnessV0KeyHash(coinbaseKey.GetPubKey()));
const CAmount actual_value = 1 * COIN;
const auto outpoint = AddCoin(p2wpkh, actual_value);
- if (!outpoint) return;
CMutableTransaction mtx;
mtx.vin.resize(1);
- mtx.vin[0].prevout = *outpoint;
+ mtx.vin[0].prevout = outpoint;
mtx.vout.resize(1);
mtx.vout[0].nValue = 0.9 * COIN;
// Sign over a wrong amount — this is the BIP143-specific failure
@@ -407,10 +395,10 @@ BOOST_AUTO_TEST_CASE(tbv_bip143_wrong_amount_in_sighash)
block.vtx.emplace_back(MakeTransactionRef(mtx));
RegenerateCommitments(block, *m_node.chainman);
const auto reason = "block-script-verify-flag-failed (Script evaluated without error but finished with a false/empty top stack element)";
- CheckScriptViolation(TestValidity(block), block, *outpoint, reason);
- CheckScriptViolation(ConnectBlock(block), block, *outpoint, reason);
+ CheckScriptViolation(TestValidity(block), block, outpoint, reason);
+ CheckScriptViolation(ConnectBlock(block), block, outpoint, reason);
SolveBlockPoW(block);
- CheckScriptViolation(ProcessNewBlock(block), block, *outpoint, reason);
+ CheckScriptViolation(ProcessNewBlock(block), block, outpoint, reason);
}
BOOST_AUTO_TEST_CASE(tbv_empty_scriptsig)
@@ -418,11 +406,10 @@ BOOST_AUTO_TEST_CASE(tbv_empty_scriptsig)
// A non-coinbase transaction with an empty scriptSig spending OP_TRUE is valid.
CBlock block = MakeBlock();
const auto outpoint = AddCoin(CScript() << OP_TRUE);
- if (!outpoint) return;
CMutableTransaction mtx;
mtx.vin.resize(1);
- mtx.vin[0].prevout = *outpoint;
+ mtx.vin[0].prevout = outpoint;
mtx.vin[0].scriptSig = CScript();
mtx.vout.resize(1);
mtx.vout[0].nValue = 1;
@@ -439,10 +426,9 @@ BOOST_AUTO_TEST_CASE(tbv_scriptsig_non_push)
// A scriptSig with non-push opcodes is valid in a block (consensus) even if non-standard.
CBlock block = MakeBlock();
const auto outpoint = AddCoin(CScript() << OP_TRUE);
- if (!outpoint) return;
CMutableTransaction mtx;
mtx.vin.resize(1);
- mtx.vin[0].prevout = *outpoint;
+ mtx.vin[0].prevout = outpoint;
mtx.vin[0].scriptSig = CScript() << OP_1 << OP_DROP;
mtx.vout.resize(1);
mtx.vout[0].nValue = 1;
@@ -459,11 +445,10 @@ BOOST_AUTO_TEST_CASE(tbv_double_spend_same_block)
// A block containing two transactions spending the same UTXO is invalid.
CBlock block = MakeBlock();
const auto outpoint = AddCoin();
- if (!outpoint) return;
for (int tx_idx = 0; tx_idx < 2; ++tx_idx) {
CMutableTransaction mtx;
mtx.vin.resize(1);
- mtx.vin[0].prevout = *outpoint;
+ mtx.vin[0].prevout = outpoint;
mtx.vin[0].scriptSig = CScript() << OP_TRUE;
mtx.vout.resize(1);
mtx.vout[0].nValue = 1;
@@ -483,10 +468,9 @@ BOOST_AUTO_TEST_CASE(tbv_zero_value_output)
// A transaction with a zero-value output is consensus-valid.
CBlock block = MakeBlock();
const auto outpoint = AddCoin();
- if (!outpoint) return;
CMutableTransaction mtx;
mtx.vin.resize(1);
- mtx.vin[0].prevout = *outpoint;
+ mtx.vin[0].prevout = outpoint;
mtx.vin[0].scriptSig = CScript() << OP_TRUE;
mtx.vout.resize(1);
mtx.vout[0].nValue = 0;
</details>