refactor: disable default std::hash for CTransactionRef #35101

pull Sjors wants to merge 2 commits into bitcoin:master from Sjors:2026/04/txref-safety changing 4 files +62 −2
  1. Sjors commented at 7:48 PM on April 17, 2026: member

    While working on #33922 I initially forgot to add CTransactionRefComp to the std::unordered_map<CTransactionRef defined there. This PR turns that into a compiler error.

    This change triggers a false positive IWYU error, and an inconsistent one at that: our CI wants <variant>, while a manual build on Ubuntu (version 0.26 with clang version 22.1.1) wants <string_view>.

    Various workarounds were discussed in:

    Addressed by back-porting:

  2. DrahtBot added the label Refactoring on Apr 17, 2026
  3. DrahtBot commented at 7:48 PM on April 17, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK vasild
    Concept ACK w0xlt
    Approach ACK hebasto

    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. in src/primitives/transaction.h:426 in 276da6236a outdated
     421 | + *  comparing by pointer. Use CTransactionRefSaltedHash or provide a custom
     422 | + *  hasher. */
     423 | +template <>
     424 | +struct hash<CTransactionRef> {
     425 | +    size_t operator()(const CTransactionRef&) const = delete;
     426 | +};
    


    hebasto commented at 5:54 PM on April 18, 2026:

    e5d04fb46a68bd884d8eefae1014aaa3dd79fa6a:

    This approach doesn't handle scenarios where a container is declared, but no member functions involving hashing are explicitly called. For example, this compiles.

    I suggest a more defensive approach relying on the conditions that must be satisfied for the std::hash<CTransactionRef> specialization to be enabled:

    template <>
    struct hash<CTransactionRef> {
        hash() = delete;
    };
    

    Here are two examples on https://godbolt.org/:

    • A container with the default hasher: fails.
    • A container with the custom hasher: passes.

    Sjors commented at 10:21 AM on April 19, 2026:

    Thanks, marking draft while I study this suggestion.


    Sjors commented at 8:35 AM on April 24, 2026:

    I added hash() = delete;, but also kept the earlier variant for clarity.

  5. in src/primitives/transaction.h:419 in 276da6236a
     414 | + * workaround.
     415 | + */
     416 | +#ifndef _LIBCPP_VERSION
     417 | +template <class T>
     418 | +struct hash; // IWYU pragma: keep
     419 | +#endif
    


    hebasto commented at 6:00 PM on April 18, 2026:

    276da6236af12bb7aee12f74f8138f2c9bb16176:

    This changes follows this suggestion, excluding libc++, which is not used in the IWYU CI job.

    Looks fine to me.


    hebasto commented at 8:34 AM on April 20, 2026:

    I can confirm that the bug has been fixed upstream in https://github.com/include-what-you-use/include-what-you-use/pull/2013.

  6. Sjors marked this as a draft on Apr 19, 2026
  7. Sjors commented at 10:55 AM on April 20, 2026: member

    Since this isn't urgent, I think I'll wait for #35101 (review) to land in a release.

  8. Sjors force-pushed on Apr 24, 2026
  9. Sjors commented at 8:19 AM on April 24, 2026: member

    I took the IWYU patch to see if it actually does the job (I still plan to wait for it to be backported to the clang_22 branch).

  10. Sjors force-pushed on Apr 24, 2026
  11. DrahtBot added the label CI failed on Apr 24, 2026
  12. Sjors commented at 8:35 AM on April 24, 2026: member

    The IWYU patch works. I also implemented @hebasto's suggestion: #35101 (review)

  13. Sjors force-pushed on Apr 24, 2026
  14. DrahtBot removed the label CI failed on Apr 24, 2026
  15. Sjors commented at 5:02 PM on April 25, 2026: member

    Apparently the patch won't be backported: https://github.com/include-what-you-use/include-what-you-use/pull/2013#issuecomment-4313034887

    So I'll just keep it here.

  16. Sjors force-pushed on Apr 25, 2026
  17. Sjors marked this as ready for review on Apr 25, 2026
  18. hebasto commented at 6:23 AM on April 27, 2026: member

    Apparently the patch won't be backported: include-what-you-use/include-what-you-use#2013 (comment)

    So I'll just keep it here.

    FWIW, the IWYU maintainer wrote:

    But if actually backported, it should be done along with the two preceding commits.

  19. hebasto commented at 6:24 AM on April 27, 2026: member

    Approach ACK 16a6b05441f0a195b3df89c8b570f57230ad0f1f.

  20. Sjors commented at 8:28 AM on April 27, 2026: member

    Previous two commits, I don't think we need them here:

  21. in ci/test/01_iwyu.patch:635 in 16a6b05441
     631 | @@ -632,3 +632,48 @@ See: https://github.com/include-what-you-use/include-what-you-use/blob/clang_21/
     632 |   };
     633 |   
     634 |   const char* stdlib_cpp_public_headers[] = {
     635 | +
    


    vasild commented at 9:15 AM on April 27, 2026:

    Offtopic, so we maintain patches for IWYU into a single file. Multiple patches appended into a single file. I think that is prone to conflicts when adding / removing stuff from that file and also a maintenance headache when two separate patches that are to be added in 01_iwyu.patch touch the same file.

    In this case the newly patched std_symbol_map.inc was not present before in 01_iwyu.patch. It would be better to keep each patchset into a separate file. So, for example in this PR a new file like 52f85e1f4d99.diff is added.


    Sjors commented at 12:26 PM on April 27, 2026:

    I moved the new patch to its own file.

  22. in ci/test/01_iwyu.patch:639 in 16a6b05441
     631 | @@ -632,3 +632,48 @@ See: https://github.com/include-what-you-use/include-what-you-use/blob/clang_21/
     632 |   };
     633 |   
     634 |   const char* stdlib_cpp_public_headers[] = {
     635 | +
     636 | +
     637 | +Map std::hash to its providing standard headers.
     638 | +Backport of https://github.com/include-what-you-use/include-what-you-use/pull/2013
     639 | +(commit 52f85e1f4d990f55fc6556d543eb051d79364a16) to the clang_22 release
    


    vasild commented at 9:18 AM on April 27, 2026:

    https://github.com/include-what-you-use/include-what-you-use/commit/52f85e1f4d990f55fc6556d543eb051d79364a16 contains changes also to mapgen/iwyu-mapgen-std-symbol.py which are omitted here. I think it is fine, just mentioning.

  23. in src/primitives/transaction.h:408 in 16a6b05441
     402 | @@ -403,4 +403,16 @@ struct CMutableTransaction
     403 |  typedef std::shared_ptr<const CTransaction> CTransactionRef;
     404 |  template <typename Tx> static inline CTransactionRef MakeTransactionRef(Tx&& txIn) { return std::make_shared<const CTransaction>(std::forward<Tx>(txIn)); }
     405 |  
     406 | +namespace std {
     407 | +/** Disable default std::hash for CTransactionRef to prevent accidentally
     408 | + *  comparing by pointer. Use CTransactionRefSaltedHash or provide a custom
    


    vasild commented at 9:20 AM on April 27, 2026:

    There is no CTransactionRefSaltedHash.


    Sjors commented at 10:38 AM on April 27, 2026:

    Indeed, that's introduced in #33922.


    Sjors commented at 12:27 PM on April 27, 2026:

    (switched to CTransactionRefHash)

  24. vasild approved
  25. vasild commented at 9:25 AM on April 27, 2026: contributor

    ACK 16a6b05441f0a195b3df89c8b570f57230ad0f1f (modulo the reference to the nonexistent CTransactionRefSaltedHash)

    <details> <summary>Show Signature</summary>

    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA256
    
    ACK 16a6b05441f0a195b3df89c8b570f57230ad0f1f (modulo the reference to the nonexistent `CTransactionRefSaltedHash`)
    -----BEGIN PGP SIGNATURE-----
    
    iQQyBAEBCAAdFiEE5k2NRWFNsHVF2czBVN8G9ktVy78FAmnvK0gACgkQVN8G9ktV
    y795Ax/48s9aZJBDruwPM6yHeJx3jylMnYyUbFf0wfvwE2k6F1lAuXc4UsOPvbj2
    IHsmOkBiq7I/xA6d33FjMVbL9Hn8pAtfZHk9TJ25zD0FyMto0yIozoS9s2vGLWrE
    i1Q0+ZWk/vxB6FwAOvyxE6j6KTq8GyvplNXToHa42Fph1s5eXv+gr0LN/VeBqr2u
    aomH329Z7F9sVI/MNABVVbllo+5dvs6/4w6ODTMnTQWw/Umx8C9GjnjtyQDJAzVP
    ihSpRVpBLD5IZczv81LwmJth8vZzYA/0d16hUbhV5+IDVxoX658VYE34CHoY/8U9
    9rFiBQeYzTBA0Ky7Hpax1c57AAB+VX+bFhoWt90clfELz42yiQiHQdc5WiRAj1kw
    K/u2QfUzeiEn3tjqkMDe89AUcd3oI4p0jW9/qi3I4h4G/EZj5yzAkIGMgQAbsh6t
    czcFvF3r9qv4dXp0ML2ylmDdgZ7zMyyvaEk9N+z+5SuVkHVmEoX3+qA9Akqh1r0F
    h1RZsX3Whuwmrpq7hopCNlGNaeodludPgiWpxWHyfaFfICQFeLGSzZOg5huRIvbE
    lMlJ5UG9nVBd4cKUBTX+tpzUQbPkDUKy93TqzDiVcfYxDI++kyYLBPIzLH6EIfo1
    +kcEGkEvZSiUezb3XR+gdDccnTiH+vYOXW253zdCAIWAgUnB4xSDc6MGMvD1EbOJ
    xQXgcrvqYtWoQCid2ZrJ8DZWUNgGm8+Fua444sAamXyRPajcts8eT2re8FSN4wqn
    7wNroDhDw62NHM5NckfCFrrxfm5EVMVBAe3W4d2D9jZ0uRpYhbz8NZnzWmnghvi3
    meIr+z8Lf1IWYGHKUQ5KSMtBDSkhmhZFWR6NjLMe7BWJDfXaMem6hnevCxafqopc
    UuSwMpAqNf3oGtRCOrVRmW7G1VnuVcaEQmRq9xf07BkEWuf44WBato3hmqi4BjhE
    l2ipzsa7X1yS1bXxZyMk8KvyU1FHR4vxo64BqRb5a0HHPKQ8UXb83QCVR405vqnx
    6iOcqJGkNAT1LoPmE6RhiRKrZycSnNYhFQ0jOJ0YQX+vxp3xh85OiDarEeOsStsl
    cU+5j5dXH/4yTo3Y+vihyEQIkBoi0krMSXF5KsGpuu/YOrvTDBJBHTLPYL1TR8Q0
    KVGvDi2H1LVkZHg05mz1gaUFAvVKl4xI9Iqa9J7ysJuCphlp40vwEy5urkX0XEJD
    40f/YVldxtw+bQ/jaANfJmrHWWxvGjsWL0xyLKiQ4SfjZSFIwrmfQccmbyhXe6Ah
    8TxtBEgid5v+zP/A0sxOJe/E8Cx/agkKpN8CniftGIvSdY7WLA2jhwyjkLqpaQHZ
    qcNIKOOHCkXVbngyItPYFD4RT7X1
    =b5H5
    -----END PGP SIGNATURE-----
    

    vasild's public key is on openpgp.org

    </details>

  26. DrahtBot requested review from hebasto on Apr 27, 2026
  27. ci: backport iwyu PR 2013 std::hash mapping
    Cherry-pick include-what-you-use commit 52f85e1f4d99 onto the clang_22
    branch tracked by ci/test/00_setup_env_native_iwyu.sh, fixing the false
    positive where std::hash was mapped to <string_view>/<variant> instead of
    its real provider (<functional>, <memory>, etc).
    47d68cd981
  28. refactor: disable default std::hash for CTransactionRef
    The default std::hash for shared_ptr compares by pointer.
    
    CTransactionRefHash or a custom hasher should be used instead.
    
    Co-authored-by: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
    a9301cfa07
  29. Sjors force-pushed on Apr 27, 2026
  30. Sjors commented at 12:31 PM on April 27, 2026: member
    • fixed comment to refer to CTransactionRefHash instead of CTransactionRefSaltedHash, see #35101 (review)
    • moved patch to its own file, see #35101 (review)
    • updated PR description to mention the patch
  31. vasild approved
  32. vasild commented at 1:47 PM on April 29, 2026: contributor

    ACK a9301cfa0730d1d08c9e982f990dfc8aa0b3a27a

    <details> <summary>Show Signature</summary>

    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA256
    
    ACK a9301cfa0730d1d08c9e982f990dfc8aa0b3a27a
    -----BEGIN PGP SIGNATURE-----
    
    iQQzBAEBCAAdFiEE5k2NRWFNsHVF2czBVN8G9ktVy78FAmnyC/IACgkQVN8G9ktV
    y79PnB//YklUD5SSNq23cPz95gqzedTyyztaj34wocJaRJI5/AvaiYI/ASzeqqsQ
    rCl2BTS1uj1GSQu8odF8y4ogJwp4f148aA69xSSSU+qREHal+ftuXmPEgaAuuKPz
    NJpmOxt6L4iPXQKZ06qTRPuQb1R7ufLwXDI4usm6ouzO3rpn5D3zPWcgcU0IkgHK
    2Wd/U2UhRp47PQgzyncTicI6IG4WsRHOesbOCwfDnDo4IDfu9K7apm/KxswZfmzR
    1wV4HJrgLXbic5/XiPvhwxHosKkNsPho3NIAbZ/ELi/zgwEMc+ojVOhe3PJNKahL
    rBKbJi187SQ5+1m7oGQL0+K1wg8TILmZIItVGRXglPqta2CUmNoK1I19J8imt0F1
    Xy8pY9Lb7wzCHiEsdRl55ibdPDvN3ZsXtkDY0jlkevCwvoKJrurd1X130H+g+Alk
    2uGNO2XfnPcDhKSAlSX2pOHEYohB1uuQxuzMF5N7D6WQDo7CjJjEfp6bqWiJYUGA
    WsqhNbR6UJ2gWh7C810RL9lmnu6yVLVwuTRewi5alGsTsGCFvbCY1PepGkvQiDDL
    s3eyUMp3bfglireFfgTD/Qdd2F61XBLPChNo/fIVmuovLHPwT59z+aUycrlGwJFN
    WXakX4w5gnkbLtJ70AlABVyRD/mBsd0fZ8Tg0QC+N4qVIdfPHNxC0gKPT1i073Sv
    lbWUOOlS5v1uLOjzLvIIhiUDY3OmvIG67BZrPt23mDM/LuETHWde3UCz++xAnECT
    z19QX9iIaKEdt5hvAfIufIj+cvr2J06PQUkA/6tMV+NHxdzFjUiR96RSoCK4rqTU
    oFQVbzqAVOnogxec/eDSK5KZJhKa/Db5abVa5P7tU3tdMwaDtYGvaWaT8j2mx86O
    PA93N4FMnYWD06jcIIDMzSuKNxl1neFE0EByktENl2LSfADq5qs8maWJXUkz8ryK
    B7jzRa9dDMkU4g7gt46tsZiSr8t/5pWsLA9sW/XBmFdbiHKlVFR9OqWEFlJb6KlW
    Z32032w9tFV/h7g+NYLUV+GkD5smNMYGCxEK65hHkGvirgPZQa5xSalvV4dAo5v7
    4J+ImguWhJRLvU5d9ZIKAdHdZ6pXFsAtKBDQWmaoZprxxECphVifz1jeAaf4mdvL
    fnIM2/cAwhb98oL0tV662xIutkhATRWHjTDlgzYFhm/K4fgnxokWPj25j5rAlxOW
    uRAS2kEJWKty1uIKUmEa4qvnINnybl0NpJgNGR801vY16VXl0e30IJoMvpRPc8wW
    lo8P52ud4ma3TRbNzAwqtKd16sDrpF9YkDNMLzqfO2mq0/EY5ZUN/Rp1MK3kMFMQ
    E0dK4NdoIctv5docw1z8RnpNzX6NUw==
    =Z4cN
    -----END PGP SIGNATURE-----
    

    vasild's public key is on openpgp.org

    </details>

  33. w0xlt commented at 6:28 PM on April 30, 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-05-12 15:12 UTC

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