mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-09 11:27:28 -03:00
[validation] Add detailed txin/txout information for script error messages
Don't just report which script error occurred, but which in which input of which transaction, and which UTXO was being spent.
This commit is contained in:
parent
146a3d5426
commit
7b267c034f
2 changed files with 9 additions and 8 deletions
|
@ -2103,14 +2103,15 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txund
|
|||
AddCoins(inputs, tx, nHeight);
|
||||
}
|
||||
|
||||
std::optional<ScriptError> CScriptCheck::operator()() {
|
||||
std::optional<std::pair<ScriptError, std::string>> CScriptCheck::operator()() {
|
||||
const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
|
||||
const CScriptWitness *witness = &ptxTo->vin[nIn].scriptWitness;
|
||||
ScriptError error{SCRIPT_ERR_UNKNOWN_ERROR};
|
||||
if (VerifyScript(scriptSig, m_tx_out.scriptPubKey, witness, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, m_tx_out.nValue, cacheStore, *m_signature_cache, *txdata), &error)) {
|
||||
return std::nullopt;
|
||||
} else {
|
||||
return error;
|
||||
auto debug_str = strprintf("input %i of %s (wtxid %s), spending %s:%i", nIn, ptxTo->GetHash().ToString(), ptxTo->GetWitnessHash().ToString(), ptxTo->vin[nIn].prevout.hash.ToString(), ptxTo->vin[nIn].prevout.n);
|
||||
return std::make_pair(error, std::move(debug_str));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2214,7 +2215,7 @@ bool CheckInputScripts(const CTransaction& tx, TxValidationState& state,
|
|||
flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheSigStore, &txdata);
|
||||
auto mandatory_result = check2();
|
||||
if (!mandatory_result.has_value()) {
|
||||
return state.Invalid(TxValidationResult::TX_NOT_STANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(*result)));
|
||||
return state.Invalid(TxValidationResult::TX_NOT_STANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(result->first)), result->second);
|
||||
} else {
|
||||
// If the second check failed, it failed due to a mandatory script verification
|
||||
// flag, but the first check might have failed on a non-mandatory script
|
||||
|
@ -2228,7 +2229,7 @@ bool CheckInputScripts(const CTransaction& tx, TxValidationState& state,
|
|||
|
||||
// MANDATORY flag failures correspond to
|
||||
// TxValidationResult::TX_CONSENSUS.
|
||||
return state.Invalid(TxValidationResult::TX_CONSENSUS, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(*result)));
|
||||
return state.Invalid(TxValidationResult::TX_CONSENSUS, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(result->first)), result->second);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2688,7 +2689,7 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
|
|||
// Any transaction validation failure in ConnectBlock is a block consensus failure
|
||||
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS,
|
||||
tx_state.GetRejectReason(), tx_state.GetDebugMessage());
|
||||
LogInfo("Script validation error in block: %s\n", tx_state.GetRejectReason());
|
||||
LogInfo("Script validation error in block: %s\n", state.ToString());
|
||||
return false;
|
||||
}
|
||||
control.Add(std::move(vChecks));
|
||||
|
@ -2716,8 +2717,8 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
|
|||
|
||||
auto parallel_result = control.Complete();
|
||||
if (parallel_result.has_value()) {
|
||||
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(*parallel_result)));
|
||||
LogInfo("Script validation error in block: %s", state.GetRejectReason());
|
||||
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(parallel_result->first)), parallel_result->second);
|
||||
LogInfo("Script validation error in block: %s", state.ToString());
|
||||
return false;
|
||||
}
|
||||
const auto time_4{SteadyClock::now()};
|
||||
|
|
|
@ -347,7 +347,7 @@ public:
|
|||
CScriptCheck(CScriptCheck&&) = default;
|
||||
CScriptCheck& operator=(CScriptCheck&&) = default;
|
||||
|
||||
std::optional<ScriptError> operator()();
|
||||
std::optional<std::pair<ScriptError, std::string>> operator()();
|
||||
};
|
||||
|
||||
// CScriptCheck is used a lot in std::vector, make sure that's efficient
|
||||
|
|
Loading…
Reference in a new issue