Bitcoin full node and query server

May 18, 2025

View in context in the libbitcoin Slack #general mirror.

evoskuil02:27
Here's that nasty section we talked about at the meeting, and from above... now complete (comments stripped). All of the computation is pushed into verify_commitment(...). That can't be pushed into a script execution as with the other couple scenarios (assured success and simple checksig). But at least verify_commitment is static, so it can be moved out of this witness class parse method.
        case script_version::taproot:
        {
            if (program->size() == ec_xonly_size)
            {
                auto stack_size = out_stack->size();
                if (drop_annex(*out_stack))
                    --stack_size;

                if (stack_size > one)
                {
                    const auto control = pop(*out_stack);
                    if (!is_valid_control_block(*control))
                        return error::invalid_witness;

                    out_script = to_shared<script>(*pop(*out_stack), false);
                    if (const auto tap = taproot::parse(*control))
                    {
                        using namespace taproot;
                        out_leaf = to_shared(leaf_hash(tap.version, *out_script));
                        if (!verify_commitment(*control, *program, *out_leaf,
                            tap.parity)) return error::invalid_commitment;

                        return error::script_success;
                    }

                    out_script = success_script_ptr();
                    out_stack->clear();
                    return error::script_success;
                }

                if (is_one(stack_size))
                {
                    out_stack->push_back(program);
                    out_script = checksig_script_ptr();
                    return error::script_success;
                }

                return error::invalid_witness;
            }

            out_script = success_script_ptr();
            out_stack->clear();
            return error::script_success;
        }