kernel: Add script evaluation tracer #35641

pull sedited wants to merge 1 commits into bitcoin:master from sedited:kernel_script_tracer changing 9 files +450 −2
  1. sedited commented at 3:00 PM on July 2, 2026: contributor

    This adds a callback hook to the kernel library C header for getting the current script evaluation state on each script evaluation step. This can be used for debugging scripts and gives external applications a view into how Bitcoin Core does script evaluation.

    The initial sketch for this work was prepared on rust-bitcoinkernel: https://github.com/sedited/rust-bitcoinkernel/tree/feature_script_debug . That branch also includes a very rudimentary script debugger showcasing the use case for this patch. Clankers seems to do a decent job at coding up prototypes for more featureful debuggers, which seems like a fun project to hack on if anybody else wants to give it a try.

    This feature is gated behind the ENABLE_SCRIPT_TRACE flag. To compile with the feature enabled, pass -DENABLE_SCRIPT_TRACE=ON. If the feature is not manually enabled, the trace hooks are stubbed out.

    The traces are divided into separate frames. RAII is used to guarantee that every script evaluation has at least its start and end state captured. Each instruction generates a unique frame as well.

    The ScriptError in the VerifyScript invocation run when calling script_pubkey_verify is added in order to be able to surface the error code in the trace frames.

    Another use case could also be using the frames to ensure that the script interpreter is actually doing what we think it is doing during the script tests. This might prevent unit test bugs in the future, i.e. when error conditions shadow actual behaviour, and could also be interesting for fuzzing the script interpreter.

  2. DrahtBot added the label Validation on Jul 2, 2026
  3. DrahtBot commented at 3:00 PM on July 2, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--006a51241073e994b41acfe9ec718e94-->

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/35641.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline and AI policy for information on the review process.

    Type Reviewers
    Concept ACK furszy, w0xlt, theStack

    If your review is incorrectly listed, please copy-paste <code>&lt;!--meta-tag:bot-skip--&gt;</code> into the comment that the bot should ignore.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #35496 (kernel: add btck_set_mock_time for testing time-dependent paths by stringintech)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  4. sedited added this to a project on Jul 2, 2026
  5. github-project-automation[bot] changed the project status on Jul 2, 2026
  6. sedited changed the project status on Jul 2, 2026
  7. furszy commented at 4:04 PM on July 2, 2026: member

    Concept ACK, haven't checked the implementation. But this is something that would benefit testing greatly.

  8. w0xlt commented at 5:57 PM on July 2, 2026: contributor

    Strong Concept ACK

  9. sedited force-pushed on Jul 2, 2026
  10. sedited force-pushed on Jul 2, 2026
  11. DrahtBot added the label CI failed on Jul 2, 2026
  12. sedited marked this as ready for review on Jul 2, 2026
  13. DrahtBot removed the label CI failed on Jul 2, 2026
  14. sedited renamed this:
    kernel: Add script execution tracer
    kernel: Add script evaluation tracer
    on Jul 4, 2026
  15. alexanderwiederin commented at 9:31 AM on July 6, 2026: contributor

    Does this support multi-threaded applications? If not, do we want it to?

  16. sedited commented at 9:37 AM on July 6, 2026: contributor

    Does this support multi-threaded applications? If not, do we want it to?

    It should be thread-safe, but I don't think this is particularly interesting to run in a multi-threaded context. I was thinking of adding an id to the trace frames, but didn't because I felt like the use case is pretty slim.

  17. in src/kernel/bitcoinkernel.h:2025 in 31a5c9869b outdated
    2020 | + *
    2021 | + * @param[in] callback                   The callback function to register.
    2022 | + * @param[in] user_data                  User-defined opaque pointer passed to the callback.
    2023 | + * @param[in] user_data_destroy_callback Nullable, function for freeing the user data.
    2024 | + * @return                               0 if the script trace feature is available.
    2025 | + */
    


    alexanderwiederin commented at 7:38 AM on July 8, 2026:

    I suggest we add something like: "The callback fires once per instruction, after the opcode is decoded and before it is dispatched/executed."


    sedited commented at 3:26 PM on July 8, 2026:

    Taken.

  18. in src/kernel/bitcoinkernel.h:2035 in 31a5c9869b
    2030 | +
    2031 | +/**
    2032 | + * @brief Unregister the global script trace callback.
    2033 | + *
    2034 | + * After calling this function, no new script trace callbacks will be invoked
    2035 | + * once the last invocation returns.
    


    alexanderwiederin commented at 7:42 AM on July 8, 2026:

    Is this accurate? Couldn't a thread that copied the callback still begin an invocation?

    I think it's safe, but the doc comment overpromises if I am not wrong.


    sedited commented at 1:46 PM on July 8, 2026:

    Mmh, not sure how to reword this. Can you suggest something?


    alexanderwiederin commented at 2:20 PM on July 8, 2026:

    Maybe: "Unregistration is not synchronized with callback execution. Pending invocations on other threads may still run to completion after this returns, but no invocations begin thereafter."

    What do you think?


    sedited commented at 3:26 PM on July 8, 2026:

    Taken.

  19. kernel: Add script tracer
    This adds a callback hook to the kernel library C header for getting the
    current script execution state on each script evaluation step. This can
    be used for debugging scripts and gives external applications a view
    into how Bitcoin Core does script evaluation.
    
    This feature is gated behind the ENABLE_SCRIPT_TRACE flag. To compile
    with the feature enabled, pass `-DENABLE_SCRIPT_TRACE=ON`. If the feature
    is not manually enabled, the trace hooks are stubbed out.
    
    The traces are divided into separate frames. RAII is used to guarantee
    that every script execution has at least its start and end state
    captured. Each instruction generates a unique frame as well.
    
    The ScriptError in the VerifyScript invocation run when calling
    script_pubkey_verify is added in order to be able to surface the error
    code in the trace frames.
    2df591d0b8
  20. sedited force-pushed on Jul 8, 2026
  21. theStack commented at 8:22 PM on July 8, 2026: contributor

    Concept ACK


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-07-09 22:51 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me