consensus/test: add `MoneyRange` unit tests for `CheckTxInputs`
What changed, and why it matters
This commit only adds new unit tests for an existing Bitcoin Core transaction validation function. It does not change any production consensus, networking, or wallet code. There is no security fix or behavior change in the software itself.
No action required; this is a test-only addition. Reviewers may optionally verify the test expectations match current consensus rules, but the commit introduces no runtime risk.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change adds a single BOOST_AUTO_TEST_CASE named checktxinputs_invalid_transactions_test in src/test/transaction_tests.cpp. It exercises three existing rejection paths in Consensus::CheckTxInputs: input value out of range (MAX_MONEY + 1), inputs below outputs, and premature spend of a coinbase. A new consensus/consensus.h include is added for COINBASE_MATURITY. No implementation code is modified.
Changed components
src/test/transaction_tests.cppInspect captured patch +41 / −0
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index 3919f226..0f175c7d 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -9,6 +9,7 @@
#include <checkqueue.h>
#include <clientversion.h>
#include <consensus/amount.h>
+#include <consensus/consensus.h>
#include <consensus/tx_check.h>
#include <consensus/tx_verify.h>
#include <consensus/validation.h>
@@ -1114,6 +1115,46 @@ BOOST_AUTO_TEST_CASE(max_standard_legacy_sigops)
BOOST_CHECK(!::AreInputsStandard(CTransaction(tx_max_sigops), coins));
}
+BOOST_AUTO_TEST_CASE(checktxinputs_invalid_transactions_test)
+{
+ auto check_invalid{[](CAmount input_value, CAmount output_value, bool coinbase, int spend_height, TxValidationResult expected_result, std::string_view expected_reason) {
+ CCoinsView coins_dummy;
+ CCoinsViewCache inputs(&coins_dummy);
+
+ const COutPoint prevout{Txid::FromUint256(uint256::ONE), 0};
+ inputs.AddCoin(prevout, Coin{{input_value, CScript() << OP_TRUE}, /*nHeightIn=*/1, coinbase}, /*possible_overwrite=*/false);
+
+ CMutableTransaction mtx;
+ mtx.vin.emplace_back(prevout);
+ mtx.vout.emplace_back(output_value, CScript() << OP_TRUE);
+
+ TxValidationState state;
+ CAmount txfee{0};
+ BOOST_CHECK(!Consensus::CheckTxInputs(CTransaction{mtx}, state, inputs, spend_height, txfee));
+ BOOST_CHECK(state.IsInvalid());
+ BOOST_CHECK_EQUAL(state.GetResult(), expected_result);
+ BOOST_CHECK_EQUAL(state.GetRejectReason(), expected_reason);
+ }};
+
+ check_invalid(/*input_value=*/MAX_MONEY + 1,
+ /*output_value=*/0,
+ /*coinbase=*/false,
+ /*spend_height=*/2,
+ TxValidationResult::TX_CONSENSUS, /*expected_reason=*/"bad-txns-inputvalues-outofrange");
+
+ check_invalid(/*input_value=*/1 * COIN,
+ /*output_value=*/2 * COIN,
+ /*coinbase=*/false,
+ /*spend_height=*/2,
+ TxValidationResult::TX_CONSENSUS, /*expected_reason=*/"bad-txns-in-belowout");
+
+ check_invalid(/*input_value=*/1 * COIN,
+ /*output_value=*/0,
+ /*coinbase=*/true,
+ /*spend_height=*/COINBASE_MATURITY,
+ TxValidationResult::TX_PREMATURE_SPEND, /*expected_reason=*/"bad-txns-premature-spend-of-coinbase");
+}
+
/** Sanity check the return value of SpendsNonAnchorWitnessProg for various output types. */
BOOST_AUTO_TEST_CASE(spends_witness_prog)
{
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.