diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 9d0e9b5e3cfb2..8335956aacaf6 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1785,11 +1785,9 @@ bool GenericTransactionSignatureChecker::CheckSequence(const CScriptNum& nSeq template class GenericTransactionSignatureChecker; template class GenericTransactionSignatureChecker; -static bool ExecuteWitnessScript(const Span& stack_span, const CScript& exec_script, unsigned int flags, SigVersion sigversion, const BaseSignatureChecker& checker, ScriptExecutionData& execdata, ScriptError* serror) +std::optional CheckTapscriptOpSuccess(const CScript& exec_script, unsigned int flags, ScriptError* serror) { - std::vector stack{stack_span.begin(), stack_span.end()}; - - if (sigversion == SigVersion::TAPSCRIPT) { + { // OP_SUCCESSx processing overrides everything, including stack element size limits CScript::const_iterator pc = exec_script.begin(); while (pc < exec_script.end()) { @@ -1806,6 +1804,19 @@ static bool ExecuteWitnessScript(const Span& stack_span, const CS return set_success(serror); } } + } + + return std::nullopt; +} + +static bool ExecuteWitnessScript(const Span& stack_span, const CScript& exec_script, unsigned int flags, SigVersion sigversion, const BaseSignatureChecker& checker, ScriptExecutionData& execdata, ScriptError* serror) +{ + std::vector stack{stack_span.begin(), stack_span.end()}; + + if (sigversion == SigVersion::TAPSCRIPT) { + + auto r = CheckTapscriptOpSuccess(exec_script, flags, serror); + if (r.has_value()) return *r; // Tapscript enforces initial stack size limits (altstack is empty here) if (stack.size() > MAX_STACK_SIZE) return set_error(serror, SCRIPT_ERR_STACK_SIZE); diff --git a/src/script/interpreter.h b/src/script/interpreter.h index b78a4551699d9..e952c32fa43ec 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -352,5 +352,6 @@ size_t CountWitnessSigOps(const CScript& scriptSig, const CScript& scriptPubKey, int FindAndDelete(CScript& script, const CScript& b); bool CastToBool(const std::vector& vch); +std::optional CheckTapscriptOpSuccess(const CScript& exec_script, unsigned int flags, ScriptError* serror); #endif // BITCOIN_SCRIPT_INTERPRETER_H