kernel: expose witness stack and scriptSig for btck_TransactionInput #35380

pull pzafonte wants to merge 2 commits into bitcoin:master from pzafonte:kernel-api-txin-witness-stack changing 4 files +193 −1
  1. pzafonte commented at 12:53 PM on May 26, 2026: contributor

    Silent payments scanning needs the public key from every input. For SegWit inputs it is in the witness stack. For P2PKH inputs it is in scriptSig. Without these new functions, callers must deserialize the raw transaction themselves to reach that data, which is difficult and error-prone.

    Introduces a btck_WitnessStack type and adds the following functions:

    Witness stack: btck_transaction_input_get_witness_stack: returns a non-owning const btck_WitnessStack* view btck_witness_stack_count_items : item count btck_witness_stack_get_item_at : single item by index via btck_WriteBytes btck_witness_stack_copy / btck_witness_stack_destroy: lifecycle for owned copies

    scriptSig: btck_transaction_input_get_script_sig: full scriptSig via btck_WriteBytes

    All functions are exposed in the C++ wrapper via WitnessStackView, WitnessStack, and WitnessStackApi , and GetScriptSig().

  2. DrahtBot added the label Validation on May 26, 2026
  3. DrahtBot commented at 12:53 PM on May 26, 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/35380.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

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

    Type Reviewers
    Concept ACK theStack, w0xlt, yuvicc, musaHaruna, yancyribbens
    Stale ACK sedited, stickies-v

    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.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  4. sedited added this to a project on May 26, 2026
  5. github-project-automation[bot] changed the project status on May 26, 2026
  6. sedited changed the project status on May 26, 2026
  7. in src/kernel/bitcoinkernel.h:1689 in f09656e96a
    1684 | + * @brief Return the number of witness stack items of a transaction input.
    1685 | + *
    1686 | + * @param[in] transaction_input Non-null.
    1687 | + * @return                      The number of witness stack items.
    1688 | + */
    1689 | +BITCOINKERNEL_API size_t btck_transaction_input_get_witness_stack_num_items(
    


    stickies-v commented at 1:19 PM on May 26, 2026:

    nit: we use _count for similar functions, so would stay consistent with btck_transaction_input_count_witness_stack_items


    pzafonte commented at 2:53 PM on May 26, 2026:

    Done. Updated in 34897f3

  8. in src/test/kernel/test_kernel.cpp:524 in f09656e96a
     519 | +
     520 | +    // P2WSH input: OP_0, sig, sig, redeem_script (0, 71, 71, 105 bytes).
     521 | +    Transaction segwit_tx{hex_string_to_byte_vec("010000000001011f97548fbbe7a0db7588a66e18d803d0089315aa7d4cc28360b6ec50ef36718a0100000000ffffffff02df1776000000000017a9146c002a686959067f4866b8fb493ad7970290ab728757d29f0000000000220020701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d04004730440220565d170eed95ff95027a69b313758450ba84a01224e1f7f130dda46e94d13f8602207bdd20e307f062594022f12ed5017bbf4a055a06aea91c10110a0e3bb23117fc014730440220647d2dc5b15f60bc37dc42618a370b2a1490293f9e5c8464f53ec4fe1dfe067302203598773895b4b16d37485cbe21b337f4e4b650739880098c592553add7dd4355016952210375e00eb72e29da82b89367947f29ef34afb75e8654f6ea368e0acdfd92976b7c2103a1b26313f430c4b15bb1fdce663207659d8cac749a0e53d70eff01874496feff2103c96d495bfdd5ba4145e3e046fee45e84a8a48ad05bd8dbb395c011a32cf9f88053ae00000000")};
     522 | +    TransactionInputView segwit_input = segwit_tx.GetInput(0);
     523 | +    BOOST_CHECK_EQUAL(segwit_input.GetWitnessStackNumItems(), 4);
     524 | +    BOOST_CHECK_EQUAL(segwit_input.GetWitnessStackItem(0).size(), 0);
    


    stickies-v commented at 1:19 PM on May 26, 2026:

    Would be better to test full equality rather than just the size


    pzafonte commented at 2:37 PM on May 26, 2026:

    Updated the tests in 34897f3

  9. in src/kernel/bitcoinkernel.h:1700 in f09656e96a outdated
    1695 | + *
    1696 | + * @param[in] transaction_input Non-null.
    1697 | + * @param[in] index             Index of the witness stack item.
    1698 | + * @param[in] writer            Non-null, function pointer for writing bytes.
    1699 | + * @param[in] user_data         Nullable, passed back through the writer callback.
    1700 | + * @return                      0 on success, -1 if the index is out of bounds.
    


    stickies-v commented at 1:35 PM on May 26, 2026:

    Depending on the writer impl, -1 can also indicate that writing failed. As a general pattern, I wonder if it makes sense to wholesale return the writer error code. Alternatively we could catch the writer error code, log it, and then returning a pre-defined writer error code, so we get e.g. 0 on success, -1 on out of bounds, and -2 on write failure?

  10. DrahtBot added the label CI failed on May 26, 2026
  11. DrahtBot commented at 1:39 PM on May 26, 2026: contributor

    <!--85328a0da195eb286784d51f73fa0af9-->

    🚧 At least one of the CI tasks failed. <sub>Task Alpine (musl): https://github.com/bitcoin/bitcoin/actions/runs/26449143818/job/77864724232</sub> <sub>LLM reason (✨ experimental): CI failed because compilation of test_kernel errored out: bitcoinkernel_wrapper.h used assert(...) without including it (so assert was not declared).</sub>

    <details><summary>Hints</summary>

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

    </details>

  12. stickies-v commented at 1:41 PM on May 26, 2026: contributor

    Concept ACK, seems useful to expose.

    Small motivation nit:

    Without access to it, kernel API callers cannot extract the sender key from these input types which is a requirement for silent payments scanning.

    Callers can, but they have to parse the entire transaction, so exposing these functions obviously makes that easier and less error-prone.

  13. pzafonte force-pushed on May 26, 2026
  14. pzafonte renamed this:
    kernel: expose witness stack items for btck_TransactionInput
    kernel: expose witness stack and scriptSig for btck_TransactionInput
    on May 26, 2026
  15. pzafonte commented at 2:49 PM on May 26, 2026: contributor

    Callers can, but they have to parse the entire transaction, so exposing these functions obviously makes that easier and less error-prone.

    Updated the title and description to clarify motivation and reflect both commits.

  16. theStack commented at 3:23 PM on May 26, 2026: contributor

    Concept ACK

  17. DrahtBot removed the label CI failed on May 26, 2026
  18. w0xlt commented at 9:40 PM on May 26, 2026: contributor

    Concept ACK

  19. in src/kernel/bitcoinkernel_wrapper.h:596 in 34897f32eb outdated
     591 | +    size_t GetWitnessStackNumItems() const
     592 | +    {
     593 | +        return btck_transaction_input_count_witness_stack_items(impl());
     594 | +    }
     595 | +
     596 | +    std::vector<std::byte> GetWitnessStackItem(size_t index) const
    


    yuvicc commented at 10:10 AM on May 27, 2026:

    I think this could crash the program when an invalid index is passed?

    <details> <summary>test</summary>

    BOOST_CHECK_THROW(segwit_input.GetWitnessStackItem(4), std::out_of_range);
    

    </details>

    <details> <summary>output Log</summary>

    unknown location:0: fatal error: in "btck_transaction_input": signal: SIGABRT (application abort requested)
    

    </details>

    I think the cause might be here at L318 - L320:

    <details> <summary>L318 - L320</summary>

    if (to_bytes(object, write, &user_data) != 0) {
        std::rethrow_exception(user_data.exception);
    }
    

    </details>

    When passing an index out of bounds, the C API returns -1, and the user_data.exception remains nullptr. Passing nullptr to std::rethrow_exception results in undefined behaviour (UB). Probably add a bounds check here?

    <details> <summary>diff</summary>

      if (to_bytes(object, write, &user_data) != 0) {
          if (user_data.exception) std::rethrow_exception(user_data.exception);
          throw std::runtime_error("Kernel API call failed");
      }
    

    </details>

  20. yuvicc commented at 10:11 AM on May 27, 2026: contributor

    Concept ACK

  21. pzafonte force-pushed on May 29, 2026
  22. pzafonte commented at 4:21 PM on May 29, 2026: contributor

    Double checking myself.

    Looking at src/validation.cpp:3869-L3871 const auto& witness_stack{block.vtx[0]->vin[0].scriptWitness.stack}; if (witness_stack.size() != 1 || witness_stack[0].size() != 32) {

    And src/core_io.cpp:463-464 txinwitness.reserve(tx.vin[i].scriptWitness.stack.size()); for (const auto& item : tx.vin[i].scriptWitness.stack) {

    I don't think valid usage would ever reach an unverified index given the count function is available, so assert feels more appropriate here?

  23. in src/kernel/bitcoinkernel_wrapper.h:11 in a398cd8405
       7 | @@ -8,6 +8,7 @@
       8 |  #include <kernel/bitcoinkernel.h>
       9 |  
      10 |  #include <array>
      11 | +#include <cassert>
    


    sedited commented at 2:22 PM on June 4, 2026:

    I think this include must be from a prior revision. Can you remove it?

  24. in src/kernel/bitcoinkernel_wrapper.h:591 in a398cd8405
     586 | @@ -586,6 +587,27 @@ class TransactionInputApi
     587 |      {
     588 |          return btck_transaction_input_get_sequence(impl());
     589 |      }
     590 | +
     591 | +    size_t GetWitnessStackNumItems() const
    


    sedited commented at 2:25 PM on June 4, 2026:

    I think this should be called CountWitnessStackItems.

  25. sedited commented at 2:37 PM on June 4, 2026: contributor

    I would drop the description in the commit message of what the witness data is needed for. There are many use cases for this, and I don't think enumerating them is useful.

  26. pzafonte force-pushed on Jun 4, 2026
  27. DrahtBot added the label CI failed on Jun 4, 2026
  28. DrahtBot commented at 5:06 PM on June 4, 2026: contributor

    <!--85328a0da195eb286784d51f73fa0af9-->

    🚧 At least one of the CI tasks failed. <sub>Task test ancestor commits: https://github.com/bitcoin/bitcoin/actions/runs/26962501443/job/79556335400</sub> <sub>LLM reason (✨ experimental): CI failed due to a C++ build error: btck_transaction_input_get_script_sig is an undeclared identifier in bitcoinkernel_wrapper.h (compiling bitcoin-chainstate.cpp).</sub>

    <details><summary>Hints</summary>

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

    </details>

  29. pzafonte force-pushed on Jun 4, 2026
  30. pzafonte force-pushed on Jun 4, 2026
  31. DrahtBot removed the label CI failed on Jun 4, 2026
  32. sedited approved
  33. sedited commented at 7:59 AM on June 11, 2026: contributor

    ACK 269e39b2dc41f99f6184120f648f5ab3c1c93b7d

  34. DrahtBot requested review from theStack on Jun 11, 2026
  35. DrahtBot requested review from stickies-v on Jun 11, 2026
  36. DrahtBot requested review from yuvicc on Jun 11, 2026
  37. in src/kernel/bitcoinkernel.h:1697 in 269e39b2dc
    1692 | +/**
    1693 | + * @brief Serialize a witness stack item at a given index through the passed in
    1694 | + * callback.
    1695 | + *
    1696 | + * @param[in] transaction_input Non-null.
    1697 | + * @param[in] index             Index of the witness stack item.
    


    stickies-v commented at 1:30 PM on June 12, 2026:

    nit: index is a transaction input propery

     * [@param](/github-metadata-backup-bitcoin-bitcoin/contributor/param/)[in] index             Index of the witness stack item in the transaction input.
    
  38. in src/kernel/bitcoinkernel.h:1702 in 269e39b2dc
    1697 | + * @param[in] index             Index of the witness stack item.
    1698 | + * @param[in] writer            Non-null, function pointer for writing bytes.
    1699 | + * @param[in] user_data         Nullable, passed back through the writer callback.
    1700 | + * @return                      The return value of the writer. Aborts if index is out of bounds.
    1701 | + */
    1702 | +BITCOINKERNEL_API int BITCOINKERNEL_WARN_UNUSED_RESULT btck_transaction_input_get_witness_stack_item(
    


    stickies-v commented at 10:24 AM on June 15, 2026:

    I think it makes sense to add a btck_WitnessStack type here. We're mapping a getter onto its parent, and the witness stack is not an implementation detail. If in the future we want to extend functionality (e.g. expose the taproot annex), it will also be much cleaner to do so this way.

    Would be curious to hear more opinions on this. We don't need to overly complicate things either, it just makes sense to me.

    const btck_WitnessStack* btck_transaction_input_get_witness_stack(const btck_TransactionInput*);
    
    size_t btck_witness_stack_count(const btck_WitnessStack*);
    int btck_witness_stack_item_to_bytes(const btck_WitnessStack*, size_t index, btck_WriteBytes, void*);
    btck_WitnessStack* btck_witness_stack_copy(const btck_WitnessStack*);
    void btck_witness_stack_destroy(btck_WitnessStack*);
    

    alexanderwiederin commented at 7:27 PM on June 16, 2026:

    Not an easy decision. When do you expect further functionality, like the annex, to be needed?


    stickies-v commented at 11:09 AM on June 18, 2026:

    I'm not sure when users who want this will show up, but I think it's a very natural extension of the API so I suspect eventually we will.

    Personally, I think even without adding more functionality a separate btck_WitnessStack makes sense from a layering perspective.


    pzafonte commented at 1:38 PM on July 3, 2026:

    I was trying to keep my design flat and simple, but I think the layered design follows a more logical shape, and provides better extensibility like exposing the taproot annex as you mentioned. Pushed a redesign of the witness stack around a btck_WitnessStack type. Happy to squash into the original commit if it looks good and is appropriate here.


    stickies-v commented at 3:47 PM on July 3, 2026:

    I like the btck_WitnessStack approach.

    meta-nit: would suggest to either post a link to an alternative branch if you don't want to update the PR branch yet as you're looking for feedback, or update the PR branch with a properly rebased version, this is kind of the worst of both worlds.

  39. DrahtBot requested review from stickies-v on Jun 15, 2026
  40. musaHaruna commented at 1:33 PM on June 28, 2026: contributor

    Concept ACK

    I don't think valid usage would ever reach an unverified index given the count function is available, so assert feels more appropriate here?

    Looking at the code through the lenses of a newbie, While assert(index < stack.size()); prevents Undefined Behavior by stopping execution immediately, and usage (like in validation.cpp or core_io.cpp) safely guards indices, I don't think it's ideal for the shared library, because the endpoint is consumed by external runtimes and language bindings (Go, Rust, JS) via FFI, we cannot guarantee valid usage from the caller.

    More importantly, in production Release builds where NDEBUG is defined, this assert will be completely stripped out. If an external caller does pass an invalid index by mistake, it will lead to undefined behavior or a segmentation fault via stack[index].

    Would it make sense to perform a runtime bounds check instead?

    int btck_transaction_input_get_witness_stack_item(const btck_TransactionInput* input, size_t index, btck_WriteBytes writer, void* user_data)
    {
        const std::vector<std::vector<unsigned char>>& stack{btck_TransactionInput::get(input).scriptWitness.stack};
        if (index >= stack.size()) {
            return -1; 
        }
        return writer(stack[index].data(), stack[index].size(), user_data);
    }
    

    Then the C++ wrapper utility (write_bytes) could handle non-exception failures, as suggested by @yuvicc:

      if (to_bytes(object, write, &user_data) != 0) {
          if (user_data.exception) std::rethrow_exception(user_data.exception);
          throw std::runtime_error("Kernel API call failed");
      }
    

    That would also allow the proposed unit test to pass:

    BOOST_CHECK_THROW(segwit_input.GetWitnessStackItem(4), std::out_of_range);
    
  41. in src/kernel/bitcoinkernel_wrapper.h:324 in fa221030ac
     319 | @@ -320,6 +320,36 @@ std::vector<std::byte> write_bytes(const T* object, int (*to_bytes)(const T*, bt
     320 |      return bytes;
     321 |  }
     322 |  
     323 | +template <typename T>
     324 | +std::vector<std::byte> write_bytes(const T* object, size_t index, int (*to_bytes)(const T*, size_t, btck_WriteBytes, void*))
    


    stickies-v commented at 3:34 PM on July 3, 2026:

    In your previous approach (c6d532414406cff5d31819e10adbf04042a65746) you, just used a Ctx wrapper. Any reason you changed it to this overload? I thought the wrapper was quite elegant? The new approach is a lot of unnecessary duplication.

    (nit: if you update, Item seems like a more helpful name than Ctx.)

    <details> <summary>git diff on fa221030ac</summary>

    diff --git a/src/kernel/bitcoinkernel_wrapper.h b/src/kernel/bitcoinkernel_wrapper.h
    index d6b06d3c13..3bfd4a48ac 100644
    --- a/src/kernel/bitcoinkernel_wrapper.h
    +++ b/src/kernel/bitcoinkernel_wrapper.h
    @@ -320,36 +320,6 @@ std::vector<std::byte> write_bytes(const T* object, int (*to_bytes)(const T*, bt
         return bytes;
     }
     
    -template <typename T>
    -std::vector<std::byte> write_bytes(const T* object, size_t index, int (*to_bytes)(const T*, size_t, btck_WriteBytes, void*))
    -{
    -    std::vector<std::byte> bytes;
    -    struct UserData {
    -        std::vector<std::byte>* bytes;
    -        std::exception_ptr exception;
    -    };
    -    UserData user_data = UserData{.bytes = &bytes, .exception = nullptr};
    -
    -    constexpr auto const write = +[](const void* buffer, size_t len, void* user_data) -> int {
    -        auto& data = *reinterpret_cast<UserData*>(user_data);
    -        auto& bytes = *data.bytes;
    -        try {
    -            auto const* first = static_cast<const std::byte*>(buffer);
    -            auto const* last = first + len;
    -            bytes.insert(bytes.end(), first, last);
    -            return 0;
    -        } catch (...) {
    -            data.exception = std::current_exception();
    -            return -1;
    -        }
    -    };
    -
    -    if (to_bytes(object, index, write, &user_data) != 0) {
    -        std::rethrow_exception(user_data.exception);
    -    }
    -    return bytes;
    -}
    -
     template <typename CType>
     class View
     {
    @@ -614,7 +584,11 @@ public:
     
         std::vector<std::byte> Item(size_t index) const
         {
    -        return write_bytes(impl(), index, btck_witness_stack_get_item);
    +        struct Item { const btck_WitnessStack* stack; size_t index; };
    +        Item ctx{impl(), index};
    +        return write_bytes(&ctx, +[](const Item* item, btck_WriteBytes w, void* ud) {
    +            return btck_witness_stack_get_item(item->stack, item->index, w, ud);
    +        });
         }
     
         MAKE_RANGE_METHOD(Items, Derived, &WitnessStackApi<Derived>::Count, &WitnessStackApi<Derived>::Item, *static_cast<const Derived*>(this))
    
    

    </details>


    pzafonte commented at 4:53 PM on July 3, 2026:

    Thanks! I was considering consistency with the other write_bytes calls but I agree about duplication that the overload creates. Reducing the duplication would require refactoring write_bytes itself, though I felt that would be of scope for this PR. I'll revert to the Ctx wrapper.

  42. in src/kernel/bitcoinkernel_wrapper.h:615 in fa221030ac
     610 | +    size_t Count() const
     611 | +    {
     612 | +        return btck_witness_stack_count(impl());
     613 | +    }
     614 | +
     615 | +    std::vector<std::byte> Item(size_t index) const
    


    stickies-v commented at 3:43 PM on July 3, 2026:

    nit: quite a few naming inconsistencies wrt other functions, e.g. typically we prefix getters here with Get. Also btck_witness_stack_get_item_at and btck_witness_stack_count_items.

  43. in src/kernel/bitcoinkernel.cpp:720 in fa221030ac
     715 | +    return btck_WitnessStack::ref(&btck_TransactionInput::get(input).scriptWitness);
     716 | +}
     717 | +
     718 | +int btck_transaction_input_get_script_sig(const btck_TransactionInput* input, btck_WriteBytes writer, void* user_data)
     719 | +{
     720 | +    return writer(btck_TransactionInput::get(input).scriptSig.data(), btck_TransactionInput::get(input).scriptSig.size(), user_data);
    


    stickies-v commented at 3:44 PM on July 3, 2026:

    nit: would create a const auto& script_sig{btck_TransactionInput::get(input).scriptSig}; here

  44. stickies-v commented at 3:47 PM on July 3, 2026: contributor

    Approach ACK

  45. pzafonte force-pushed on Jul 3, 2026
  46. yancyribbens commented at 8:13 PM on July 3, 2026: contributor

    Concept ACK

  47. in src/kernel/bitcoinkernel_wrapper.h:588 in d6cc918c48
     583 | +    }
     584 | +
     585 | +    std::vector<std::byte> GetItem(size_t index) const
     586 | +    {
     587 | +        struct Item { const btck_WitnessStack* stack; size_t index; };
     588 | +        Item ctx{impl(), index};
    


    stickies-v commented at 4:47 PM on July 6, 2026:

    nit

            Item item{impl(), index};
    

    pzafonte commented at 10:15 PM on July 7, 2026:

    Done.

  48. in src/kernel/bitcoinkernel.h:1743 in d6cc918c48
    1738 | + *
    1739 | + * @param[in] witness_stack Non-null.
    1740 | + * @param[in] index         Index of the item in the witness stack.
    1741 | + * @param[in] writer        Non-null, function pointer for writing bytes.
    1742 | + * @param[in] user_data     Nullable, passed back through the writer callback.
    1743 | + * @return                  The return value of the writer. Aborts if index is out of bounds.
    


    stickies-v commented at 5:21 PM on July 6, 2026:

    nit: would be more appropriately documented as a @pre, e.g. @pre index < btck_witness_stack_count_items(witness_stack)


    pzafonte commented at 10:17 PM on July 7, 2026:

    Done, I agree with the use of @pre though I dropped it from #34885 since it would have been the first use in bitcoinkernel.h and other functions with similar assert-on-OOB behavior don't document it that way. Noting it here in case it's worth aligning across the file.

  49. in src/kernel/bitcoinkernel.h:301 in d6cc918c48


    stickies-v commented at 5:30 PM on July 6, 2026:

    nit

     * Holds information on the [@ref](/github-metadata-backup-bitcoin-bitcoin/contributor/ref/) btck_TransactionOutPoint, [@ref](/github-metadata-backup-bitcoin-bitcoin/contributor/ref/) btck_WitnessStack and script_sig held within.
    

    pzafonte commented at 10:01 PM on July 7, 2026:

    Done.

  50. stickies-v approved
  51. stickies-v commented at 5:35 PM on July 6, 2026: contributor

    ACK d6cc918c482f16b2caa1e8c56f449136f3aa41f4

    meta-nit: people can already see the PR edit history by clicking on the "edited" link. For new reviewers, and our git tree (PR description gets included in the merge commit) just reflecting the current status rather than a full historical record is more straightforward.

  52. DrahtBot requested review from sedited on Jul 6, 2026
  53. DrahtBot requested review from musaHaruna on Jul 6, 2026
  54. in src/test/kernel/test_kernel.cpp:525 in 6f9c9bc8d8 outdated
     520 | +
     521 | +    // P2WSH input: OP_0, sig, sig, redeem_script (0, 71, 71, 105 bytes); no scriptSig.
     522 | +    Transaction segwit_tx{hex_string_to_byte_vec("010000000001011f97548fbbe7a0db7588a66e18d803d0089315aa7d4cc28360b6ec50ef36718a0100000000ffffffff02df1776000000000017a9146c002a686959067f4866b8fb493ad7970290ab728757d29f0000000000220020701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d04004730440220565d170eed95ff95027a69b313758450ba84a01224e1f7f130dda46e94d13f8602207bdd20e307f062594022f12ed5017bbf4a055a06aea91c10110a0e3bb23117fc014730440220647d2dc5b15f60bc37dc42618a370b2a1490293f9e5c8464f53ec4fe1dfe067302203598773895b4b16d37485cbe21b337f4e4b650739880098c592553add7dd4355016952210375e00eb72e29da82b89367947f29ef34afb75e8654f6ea368e0acdfd92976b7c2103a1b26313f430c4b15bb1fdce663207659d8cac749a0e53d70eff01874496feff2103c96d495bfdd5ba4145e3e046fee45e84a8a48ad05bd8dbb395c011a32cf9f88053ae00000000")};
     523 | +    TransactionInputView segwit_input = segwit_tx.GetInput(0);
     524 | +    WitnessStackView ws = segwit_input.GetWitnessStack();
     525 | +    BOOST_CHECK_EQUAL(ws.CountItems(), 4);
    


    sedited commented at 7:10 PM on July 6, 2026:

    Can you add a CheckRange(ws.Items(), ws.CountItems());?


    pzafonte commented at 10:00 PM on July 7, 2026:

    Done.


    pzafonte commented at 10:05 AM on July 8, 2026:

    CheckRange calls .get() on each element and Items() returns std::vector<std::byte>, which has no .get(), so it won't pass CI as is.


    stickies-v commented at 11:24 AM on July 8, 2026:

    another meta comment: before pushing, always make sure that the code compiles locally for you, and that the unit and functional tests pass


    pzafonte commented at 12:26 PM on July 8, 2026:

    Noted, sorry about that. My local build and test scripts were configured improperly, and it looked like it was passing locally. Fixed the configuration issue on my end.

  55. DrahtBot requested review from sedited on Jul 6, 2026
  56. pzafonte force-pushed on Jul 7, 2026
  57. pzafonte commented at 10:30 PM on July 7, 2026: contributor

    meta-nit: people can already see the PR edit history by clicking on the "edited" link. For new reviewers, and our git tree (PR description gets included in the merge commit) just reflecting the current status rather than a full historical record is more straightforward.

    Thanks & Done, updated the description to reflect the current state.

  58. DrahtBot added the label CI failed on Jul 7, 2026
  59. DrahtBot commented at 11:01 PM on July 7, 2026: contributor

    <!--85328a0da195eb286784d51f73fa0af9-->

    🚧 At least one of the CI tasks failed. <sub>Task test ancestor commits: https://github.com/bitcoin/bitcoin/actions/runs/28901571778/job/85739321433</sub> <sub>LLM reason (✨ experimental): CI failed at build time because src/test/kernel/test_kernel.cpp wouldn’t compile (std::vector<std::byte> has no member get()), causing test_kernel to fail.</sub>

    <details><summary>Hints</summary>

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

    </details>

  60. kernel: expose witness stack for btck_TransactionInput e6de3a2d3c
  61. kernel: expose scriptSig for btck_TransactionInput 6667dc4eec
  62. pzafonte force-pushed on Jul 8, 2026
  63. DrahtBot removed the label CI failed on Jul 8, 2026

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 06:47 UTC