A function called AreInputsStandard that returns a falsy value if inputs are standard is counterintuitive. Would suggest renaming to e.g. HasNonStandardInput.
<details>
<summary>git diff on 6ffb9569b7</summary>
diff --git a/src/bench/ccoins_caching.cpp b/src/bench/ccoins_caching.cpp
index c677fb1c16..9a31cecd7a 100644
--- a/src/bench/ccoins_caching.cpp
+++ b/src/bench/ccoins_caching.cpp
@@ -44,7 +44,7 @@ static void CCoinsCaching(benchmark::Bench& bench)
// Benchmark.
const CTransaction tx_1(t1);
bench.run([&] {
- auto result{AreInputsStandard(tx_1, coins)};
+ auto result{HasNonStandardInput(tx_1, coins)};
assert(!result.has_value());
});
ECC_Stop();
diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp
index c093cb3923..aada94d909 100644
--- a/src/policy/policy.cpp
+++ b/src/policy/policy.cpp
@@ -175,7 +175,7 @@ bool IsStandardTx(const CTransaction& tx, const std::optional<unsigned>& max_dat
*
* Note that only the non-witness portion of the transaction is checked here.
*/
-std::optional<NonStandardInputsReason> AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
+std::optional<NonStandardInputsReason> HasNonStandardInput(const CTransaction& tx, const CCoinsViewCache& mapInputs)
{
if (tx.IsCoinBase()) {
return std::nullopt; // Coinbases don't use vin normally
@@ -187,32 +187,27 @@ std::optional<NonStandardInputsReason> AreInputsStandard(const CTransaction& tx,
std::vector<std::vector<unsigned char> > vSolutions;
TxoutType whichType = Solver(prev.scriptPubKey, vSolutions);
if (whichType == TxoutType::NONSTANDARD) {
- auto result = NonStandardInputsReason{"bad-txns-input-script-nonstandard", strprintf("input %u", i)};
- return result;
+ return NonStandardInputsReason{"bad-txns-input-script-nonstandard", strprintf("input %u", i)};
} else if (whichType == TxoutType::WITNESS_UNKNOWN) {
// WITNESS_UNKNOWN failures are typically also caught with a policy
// flag in the script interpreter, but it can be helpful to catch
// this type of NONSTANDARD transaction earlier in transaction
// validation.
- auto result = NonStandardInputsReason{"bad-txns-input-witness-unknown", strprintf("input %u", i)};
- return result;
+ return NonStandardInputsReason{"bad-txns-input-witness-unknown", strprintf("input %u", i)};
} else if (whichType == TxoutType::SCRIPTHASH) {
std::vector<std::vector<unsigned char> > stack;
ScriptError serror;
// convert the scriptSig into a stack, so we can inspect the redeemScript
if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SigVersion::BASE, &serror)) {
- auto result = NonStandardInputsReason{"bad-txns-input-scriptsig-failure", strprintf("input %u: %s", i, ScriptErrorString(serror))};
- return result;
+ return NonStandardInputsReason{"bad-txns-input-scriptsig-failure", strprintf("input %u: %s", i, ScriptErrorString(serror))};
}
if (stack.empty()) {
- auto result = NonStandardInputsReason{"bad-txns-input-p2sh-no-redeemscript", strprintf("input %u", i)};
- return result;
+ return NonStandardInputsReason{"bad-txns-input-p2sh-no-redeemscript", strprintf("input %u", i)};
}
CScript subscript(stack.back().begin(), stack.back().end());
unsigned int sigop_count = subscript.GetSigOpCount(true);
if (sigop_count > MAX_P2SH_SIGOPS) {
- auto result = NonStandardInputsReason{"bad-txns-input-scriptcheck-sigops", strprintf("input %u: %u > %u", i, sigop_count, MAX_P2SH_SIGOPS)};
- return result;
+ return NonStandardInputsReason{"bad-txns-input-scriptcheck-sigops", strprintf("input %u: %u > %u", i, sigop_count, MAX_P2SH_SIGOPS)};
}
}
}
diff --git a/src/policy/policy.h b/src/policy/policy.h
index 3986f7d709..3d7d4b7e5c 100644
--- a/src/policy/policy.h
+++ b/src/policy/policy.h
@@ -149,7 +149,7 @@ bool IsStandardTx(const CTransaction& tx, const std::optional<unsigned>& max_dat
* [@return](/bitcoin-bitcoin/contributor/return/) std::nullopt if all inputs (scriptSigs) use only standard transaction forms else returns
* NonStandardInputsReason which states why an input is not standard.
*/
-std::optional<NonStandardInputsReason> AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs);
+std::optional<NonStandardInputsReason> HasNonStandardInput(const CTransaction& tx, const CCoinsViewCache& mapInputs);
/**
* Check if the transaction is over standard P2WSH resources limit:
* 3600bytes witnessScript size, 80bytes per witness stack element, 100 witness stack elements
diff --git a/src/test/fuzz/coins_view.cpp b/src/test/fuzz/coins_view.cpp
index 8f3e357a84..e210b2a13d 100644
--- a/src/test/fuzz/coins_view.cpp
+++ b/src/test/fuzz/coins_view.cpp
@@ -235,7 +235,7 @@ FUZZ_TARGET(coins_view, .init = initialize_coins_view)
assert(expected_code_path);
},
[&] {
- (void)AreInputsStandard(CTransaction{random_mutable_transaction}, coins_view_cache);
+ (void)HasNonStandardInput(CTransaction{random_mutable_transaction}, coins_view_cache);
},
[&] {
TxValidationState state;
diff --git a/src/test/fuzz/transaction.cpp b/src/test/fuzz/transaction.cpp
index 2a043f7458..785c823e37 100644
--- a/src/test/fuzz/transaction.cpp
+++ b/src/test/fuzz/transaction.cpp
@@ -87,7 +87,7 @@ FUZZ_TARGET(transaction, .init = initialize_transaction)
CCoinsView coins_view;
const CCoinsViewCache coins_view_cache(&coins_view);
- (void)AreInputsStandard(tx, coins_view_cache);
+ (void)HasNonStandardInput(tx, coins_view_cache);
(void)IsWitnessStandard(tx, coins_view_cache);
if (tx.GetTotalSize() < 250'000) { // Avoid high memory usage (with msan) due to json encoding
diff --git a/src/test/script_p2sh_tests.cpp b/src/test/script_p2sh_tests.cpp
index 500ec0bd6b..32907bdd24 100644
--- a/src/test/script_p2sh_tests.cpp
+++ b/src/test/script_p2sh_tests.cpp
@@ -265,7 +265,7 @@ BOOST_AUTO_TEST_CASE(switchover)
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EQUALVERIFY, ScriptErrorString(err));
}
-BOOST_AUTO_TEST_CASE(AreInputsStandard)
+BOOST_AUTO_TEST_CASE(GetFirstNonStandardInput)
{
CCoinsView coinsDummy;
CCoinsViewCache coins(&coinsDummy);
@@ -366,7 +366,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
txTo.vin[3].scriptSig << OP_11 << OP_11 << std::vector<unsigned char>(oneAndTwo.begin(), oneAndTwo.end());
txTo.vin[4].scriptSig << std::vector<unsigned char>(fifteenSigops.begin(), fifteenSigops.end());
- BOOST_CHECK(!::AreInputsStandard(CTransaction(txTo), coins).has_value());
+ BOOST_CHECK(!::HasNonStandardInput(CTransaction(txTo), coins).has_value());
// 22 P2SH sigops for all inputs (1 for vin[0], 6 for vin[3], 15 for vin[4]
BOOST_CHECK_EQUAL(GetP2SHSigOpCount(CTransaction(txTo), coins), 22U);
@@ -380,7 +380,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
txToNonStd1.vin[0].prevout.hash = txFrom.GetHash();
txToNonStd1.vin[0].scriptSig << std::vector<unsigned char>(sixteenSigops.begin(), sixteenSigops.end());
- const auto txToNonStd1_res = ::AreInputsStandard(CTransaction(txToNonStd1), coins);
+ const auto txToNonStd1_res = ::HasNonStandardInput(CTransaction(txToNonStd1), coins);
BOOST_CHECK(txToNonStd1_res.has_value());
BOOST_CHECK_EQUAL(txToNonStd1_res->reason, "bad-txns-input-scriptcheck-sigops");
BOOST_CHECK_EQUAL(txToNonStd1_res->debug, "input 0: 16 > 15");
@@ -398,7 +398,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
std::vector<std::vector<unsigned char>> vSolutions;
BOOST_CHECK_EQUAL(Solver(txFrom.vout[6].scriptPubKey, vSolutions), TxoutType::SCRIPTHASH);
- const auto txToNonStd2_res = ::AreInputsStandard(CTransaction(txToNonStd2), coins);
+ const auto txToNonStd2_res = ::HasNonStandardInput(CTransaction(txToNonStd2), coins);
BOOST_CHECK(txToNonStd2_res.has_value());
BOOST_CHECK_EQUAL(txToNonStd2_res->reason, "bad-txns-input-scriptcheck-sigops");
BOOST_CHECK_EQUAL(txToNonStd2_res->debug, "input 0: 20 > 15");
@@ -413,7 +413,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
txToNonStd2_no_scriptSig.vin[0].prevout.hash = txFrom.GetHash();
BOOST_CHECK_EQUAL(Solver(txFrom.vout[6].scriptPubKey, vSolutions), TxoutType::SCRIPTHASH);
- const auto txToNonStd2_no_scriptSig_res = ::AreInputsStandard(CTransaction(txToNonStd2_no_scriptSig), coins);
+ const auto txToNonStd2_no_scriptSig_res = ::HasNonStandardInput(CTransaction(txToNonStd2_no_scriptSig), coins);
BOOST_CHECK(txToNonStd2_no_scriptSig_res.has_value());
BOOST_CHECK_EQUAL(txToNonStd2_no_scriptSig_res->reason, "bad-txns-input-p2sh-no-redeemscript");
BOOST_CHECK_EQUAL(txToNonStd2_no_scriptSig_res->debug, "input 0");
@@ -429,7 +429,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
txToNonStd3.vin[0].prevout.hash = txFrom.GetHash();
BOOST_CHECK_EQUAL(Solver(txFrom.vout[7].scriptPubKey, vSolutions), TxoutType::NONSTANDARD);
- const auto txToNonStd3_res = ::AreInputsStandard(CTransaction(txToNonStd3), coins);
+ const auto txToNonStd3_res = ::HasNonStandardInput(CTransaction(txToNonStd3), coins);
BOOST_CHECK(txToNonStd3_res.has_value());
BOOST_CHECK_EQUAL(txToNonStd3_res->reason, "bad-txns-input-script-nonstandard");
BOOST_CHECK_EQUAL(txToNonStd3_res->debug, "input 0");
@@ -451,7 +451,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
BOOST_CHECK_EQUAL(Solver(txFrom.vout[8].scriptPubKey, vSolutions), TxoutType::SCRIPTHASH);
BOOST_CHECK(!EvalScript(stack, txToNonStd4.vin[0].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SigVersion::BASE, &serror));
BOOST_CHECK_EQUAL(serror, SCRIPT_ERR_OP_RETURN);
- const auto txToNonStd4_res = ::AreInputsStandard(CTransaction(txToNonStd4), coins);
+ const auto txToNonStd4_res = ::HasNonStandardInput(CTransaction(txToNonStd4), coins);
BOOST_CHECK(txToNonStd4_res.has_value());
BOOST_CHECK_EQUAL(txToNonStd4_res->reason, "bad-txns-input-scriptsig-failure");
BOOST_CHECK_EQUAL(txToNonStd4_res->debug, "input 0: OP_RETURN was encountered");
@@ -465,7 +465,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
txWitnessUnknown.vin[0].prevout.n = 9;
txWitnessUnknown.vin[0].prevout.hash = txFrom.GetHash();
BOOST_CHECK_EQUAL(Solver(txFrom.vout[9].scriptPubKey, vSolutions), TxoutType::WITNESS_UNKNOWN);
- const auto txWitnessUnknown_res = ::AreInputsStandard(CTransaction(txWitnessUnknown), coins);
+ const auto txWitnessUnknown_res = ::HasNonStandardInput(CTransaction(txWitnessUnknown), coins);
BOOST_CHECK(txWitnessUnknown_res.has_value());
BOOST_CHECK_EQUAL(txWitnessUnknown_res->reason, "bad-txns-input-witness-unknown");
BOOST_CHECK_EQUAL(txWitnessUnknown_res->debug, "input 0");
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index e2443a2fce..05074eb631 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -406,7 +406,7 @@ BOOST_AUTO_TEST_CASE(test_Get)
t1.vout[0].nValue = 90*CENT;
t1.vout[0].scriptPubKey << OP_1;
- BOOST_CHECK(!AreInputsStandard(CTransaction(t1), coins).has_value());
+ BOOST_CHECK(!HasNonStandardInput(CTransaction(t1), coins).has_value());
}
static void CreateCreditAndSpend(const FillableSigningProvider& keystore, const CScript& outscript, CTransactionRef& output, CMutableTransaction& input, bool success = true)
diff --git a/src/validation.cpp b/src/validation.cpp
index 96204b2ab4..cdcf56860f 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -822,7 +822,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
return false; // state filled in by CheckTxInputs
}
- const auto inputs_standardness_result = AreInputsStandard(tx, m_view);
+ const auto inputs_standardness_result = HasNonStandardInput(tx, m_view);
if (m_pool.m_require_standard && inputs_standardness_result.has_value()) {
return state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, inputs_standardness_result.value().reason, inputs_standardness_result.value().debug);
}
</details>
Alternatively, could use util::Result failure values after #25665 is merged.