mirror of
https://github.com/Retropex/bitcoin.git
synced 2025-05-28 13:02:38 +02:00
AreInputsStandard: Return specific reject reasons
This commit is contained in:
parent
ee375a4c2f
commit
3badcde965
@ -133,6 +133,9 @@ bool IsStandardTx(const CTransaction& tx, const std::optional<unsigned>& max_dat
|
||||
for (const CTxOut& txout : tx.vout) {
|
||||
if (!::IsStandard(txout.scriptPubKey, max_datacarrier_bytes, whichType)) {
|
||||
reason = "scriptpubkey";
|
||||
if (whichType == TxoutType::WITNESS_UNKNOWN) {
|
||||
reason += "-unknown-witnessversion";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -174,7 +177,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.
|
||||
*/
|
||||
bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
|
||||
bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs, const std::string& reason_prefix, std::string& out_reason)
|
||||
{
|
||||
if (tx.IsCoinBase()) {
|
||||
return true; // Coinbases don't use vin normally
|
||||
@ -185,21 +188,32 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
|
||||
|
||||
std::vector<std::vector<unsigned char> > vSolutions;
|
||||
TxoutType whichType = Solver(prev.scriptPubKey, vSolutions);
|
||||
if (whichType == TxoutType::NONSTANDARD || whichType == TxoutType::WITNESS_UNKNOWN) {
|
||||
if (whichType == TxoutType::NONSTANDARD) {
|
||||
out_reason = reason_prefix + "script-unknown";
|
||||
return false;
|
||||
} 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.
|
||||
out_reason = reason_prefix + "witness-unknown";
|
||||
return false;
|
||||
} else if (whichType == TxoutType::SCRIPTHASH) {
|
||||
std::vector<std::vector<unsigned char> > stack;
|
||||
// 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))
|
||||
{
|
||||
out_reason = reason_prefix + "scriptsig-failure";
|
||||
return false;
|
||||
}
|
||||
if (stack.empty())
|
||||
{
|
||||
out_reason = reason_prefix + "scriptcheck-missing";
|
||||
return false;
|
||||
}
|
||||
CScript subscript(stack.back().begin(), stack.back().end());
|
||||
if (subscript.GetSigOpCount(true) > MAX_P2SH_SIGOPS) {
|
||||
out_reason = reason_prefix + "scriptcheck-sigops";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -143,7 +143,13 @@ bool IsStandardTx(const CTransaction& tx, const std::optional<unsigned>& max_dat
|
||||
* @param[in] mapInputs Map of previous transactions that have outputs we're spending
|
||||
* @return True if all inputs (scriptSigs) use only standard transaction forms
|
||||
*/
|
||||
bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs);
|
||||
bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs, const std::string& reason_prefix, std::string& out_reason);
|
||||
|
||||
inline bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) {
|
||||
std::string reason;
|
||||
return AreInputsStandard(tx, mapInputs, reason, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the transaction is over standard P2WSH resources limit:
|
||||
* 3600bytes witnessScript size, 80bytes per witness stack element, 100 witness stack elements
|
||||
|
@ -823,8 +823,8 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
||||
return false; // state filled in by CheckTxInputs
|
||||
}
|
||||
|
||||
if (m_pool.m_require_standard && !AreInputsStandard(tx, m_view)) {
|
||||
return state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "bad-txns-nonstandard-inputs");
|
||||
if (m_pool.m_require_standard && !AreInputsStandard(tx, m_view, "bad-txns-input-", reason)) {
|
||||
return state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, reason);
|
||||
}
|
||||
|
||||
// Check for non-standard witnesses.
|
||||
|
@ -1387,7 +1387,7 @@ class SegWitTest(BitcoinTestFramework):
|
||||
# First we test this transaction against std_node
|
||||
# making sure the txid is added to the reject filter
|
||||
self.std_node.announce_tx_and_wait_for_getdata(tx3)
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, tx3, with_witness=True, accepted=False, reason="bad-txns-nonstandard-inputs")
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, tx3, with_witness=True, accepted=False, reason="bad-txns-input-witness-unknown")
|
||||
# Now the node will no longer ask for getdata of this transaction when advertised by same txid
|
||||
self.std_node.announce_tx_and_wait_for_getdata(tx3, success=False)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user