Bitcoin full node and query server

May 9, 2025

View in context in the libbitcoin Slack #general mirror.

evoskuil05:38
I also mentioned that because we can't really know if it will be executed as tapscript at the parse point, we record these for all scripts. But since the definition of invalid opcode has changed (reduced to just op_verif and op_vernotif in tapscript) and the unconditional success codes apply only in tapscript, it seemed that this would present some complexity and require additional parse results. But it turns out that above is all that is required. The last set of comments here explains how it works out, which was quite elegant.
TEMPLATE
INLINE error::script_error_t CLASS::
initialize() const NOEXCEPT
{
    const auto bip141 = is_enabled(flags::bip141_rule);
    const auto bip342 = is_enabled(flags::bip342_rule);

    // Apply stack element limit (520) to initial witness [bip141][bip342].
    if (bip141 && witness_ && !chain::witness::is_push_size(*witness_))
        return error::invalid_witness_stack;

    // Script size limit (10,000) [0.3.7+], removed [bip342].
    if (!bip342 && script_->is_oversized())
        return error::invalid_script_size;

    // Stacks element limit (1,000) applied to initial stack [bip342].
    if (bip342 && is_stack_overflow())
        return error::invalid_stack_size;

    // Succeed if any success code, one overrides all codes [bip342].
    if (bip342 && script_->is_prevalid())
        return error::prevalid_script;

    // Fail if last op underflow, lower priority than success codes [bip342].
    if (script_->is_underflow())
        return error::invalid_script;

    // Fail if any op invalid (invalid codes reduced in tapscript).
    // Should be after underflow check since underflow is also an invalid op.
    // Promoted success codes are not reachable here due to is_prevalid above.
    // So only op_verif/op_vernotif (unpromoted invalids) are caught here for
    // tapscript, otherwise is_prevalid bypassed and all invalids caught here.
    if (script_->is_prefail())
        return error::prefail_script;

    return error::script_success;
}
(edited)