| 3209 | template class GenericTransactionSignatureChecker<CMutableTransaction>; |
| 3210 | |
| 3211 | static bool ExecuteWitnessScript(const Span<const valtype>& stack_span, const CScript& exec_script, unsigned int flags, SigVersion sigversion, const BaseSignatureChecker& checker, ScriptExecutionData& execdata, ScriptError* serror) |
| 3212 | { |
| 3213 | std::vector<valtype> stack{stack_span.begin(), stack_span.end()}; |
| 3214 | |
| 3215 | if (sigversion == SigVersion::TAPSCRIPT) { |
| 3216 | // OP_SUCCESSx processing overrides everything, including stack element size limits |
| 3217 | CScript::const_iterator pc = exec_script.begin(); |
| 3218 | while (pc < exec_script.end()) { |
| 3219 | opcodetype opcode; |
| 3220 | if (!exec_script.GetOp(pc, opcode)) { |
| 3221 | // Note how this condition would not be reached if an unknown OP_SUCCESSx was found |
| 3222 | return set_error(serror, SCRIPT_ERR_BAD_OPCODE); |
| 3223 | } |
| 3224 | // New opcodes will be listed here. May use a different sigversion to modify existing opcodes. |
| 3225 | if (IsOpSuccess(opcode)) { |
| 3226 | if (flags & SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS) { |
| 3227 | return set_error(serror, SCRIPT_ERR_DISCOURAGE_OP_SUCCESS); |
| 3228 | } |
| 3229 | return set_success(serror); |
| 3230 | } |
| 3231 | } |
| 3232 | |
| 3233 | // Tapscript enforces initial stack size limits (altstack is empty here) |
| 3234 | if (stack.size() > MAX_STACK_SIZE) return set_error(serror, SCRIPT_ERR_STACK_SIZE); |
| 3235 | } |
| 3236 | |
| 3237 | // Disallow stack item size > MAX_SCRIPT_ELEMENT_SIZE in witness stack |
| 3238 | for (const valtype& elem : stack) { |
| 3239 | if (elem.size() > MAX_SCRIPT_ELEMENT_SIZE) return set_error(serror, SCRIPT_ERR_PUSH_SIZE); |
| 3240 | } |
| 3241 | |
| 3242 | // Run the script interpreter. |
| 3243 | if (!EvalScript(stack, exec_script, flags, checker, sigversion, execdata, serror)) return false; |
| 3244 | |
| 3245 | // Scripts inside witness implicitly require cleanstack behaviour |
| 3246 | if (stack.size() != 1) return set_error(serror, SCRIPT_ERR_CLEANSTACK); |
| 3247 | if (!CastToBool(stack.back())) return set_error(serror, SCRIPT_ERR_EVAL_FALSE); |
| 3248 | return true; |
| 3249 | } |
| 3250 | |
| 3251 | uint256 ComputeTapleafHash(uint8_t leaf_version, const CScript& script) |
| 3252 | { |
no test coverage detected