ipc: Add nonunix platform support #35084

pull ryanofsky wants to merge 11 commits into bitcoin:master from ryanofsky:pr/ipc-wins changing 14 files +365 −302
  1. ryanofsky commented at 4:25 PM on April 15, 2026: contributor

    This PR makes Bitcoin Core changes needed to be compatible with https://github.com/bitcoin-core/libmultiprocess/pull/274, which changes the libmultiprocess API to stop using unix-specific types so it is compatible with windows. (Windows support is added in followups: https://github.com/bitcoin-core/libmultiprocess/pull/231 and #32387.)

    The PR uses some compatibility shims so it can be reviewed and merged without needing to merge https://github.com/bitcoin-core/libmultiprocess/pull/274 first and bump the libmultiprocess subtree. These can be deleted when the subtree is updated.


    Review note: All the changes here are refactoring, and you don't really need to know anything about IPC or Windows to review this code. It is also a mostly move-only change (131 lines added, 96 removed, 215 moved)

  2. DrahtBot commented at 4:25 PM on April 15, 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/35084.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

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

    Type Reviewers
    ACK xyzconstant, enirox001, Sjors, ViniciusCestarii, sedited
    Concept ACK 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.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #35713 (Remove boost as a unit test runner by rustaceanrob)
    • #35037 (ipc: support per-address max-connections options on -ipcbind by enirox001)
    • #32387 (ipc: add windows support by ryanofsky)
    • #19461 (multiprocess: Add bitcoin-gui -ipcconnect option by ryanofsky)
    • #19460 (multiprocess: Add bitcoin-wallet -ipcconnect option by ryanofsky)
    • #10102 (Multiprocess bitcoin by ryanofsky)

    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-->

    LLM Linter (✨ experimental)

    Possible places where comparison-specific test macros should replace generic comparisons:

    • src/ipc/test/ipc_tests.cpp: BOOST_CHECK_THROW(process->bind(datadir, "test_bitcoin", invalid_bind), std::invalid_argument); -> consider BOOST_CHECK_EXCEPTION(..., std::invalid_argument, HasReason("...")) to verify the specific failure message.
    • src/ipc/test/ipc_tests.cpp: BOOST_CHECK_THROW(process->connect(datadir, "test_bitcoin", invalid_bind), std::invalid_argument); -> consider BOOST_CHECK_EXCEPTION(..., std::invalid_argument, HasReason("...")) to verify the specific failure message.

    <sup>2026-07-23 13:25:40</sup>

  3. DrahtBot added the label CI failed on Apr 15, 2026
  4. DrahtBot commented at 5:15 PM on April 15, 2026: contributor

    <!--85328a0da195eb286784d51f73fa0af9-->

    🚧 At least one of the CI tasks failed. <sub>Task FreeBSD Cross: https://github.com/bitcoin/bitcoin/actions/runs/24465865499/job/71492637060</sub> <sub>LLM reason (✨ experimental): CI failed due to a linker error: duplicate symbol mp::SocketPair() in libbitcoin_ipc.a (defined in multiple objects).</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>

  5. stickies-v commented at 5:45 PM on April 15, 2026: contributor

    Concept ACK

  6. ryanofsky force-pushed on Apr 16, 2026
  7. ryanofsky commented at 11:29 PM on April 16, 2026: contributor

    <!-- begin push-2 -->

    Updated 9c39299c7589cb650178f4a411956f2818d1b5c5 -> 012f428e7fe52707ea7421201def84a847328341 (pr/ipc-wins.1 -> pr/ipc-wins.2, compare)<!-- end --> to fix CI failures https://github.com/bitcoin/bitcoin/actions/runs/24465865499: ipc_tests cmake include directory bug and multiple definition link error

    <!-- begin push-3 -->

    Updated 012f428e7fe52707ea7421201def84a847328341 -> 129f48be88f738e6af9960fe81c0a9d05bb8b5f9 (pr/ipc-wins.2 -> pr/ipc-wins.3, compare)<!-- end --> to fix CI failures https://github.com/bitcoin/bitcoin/actions/runs/24539375845: HasReason include error and lint error about ipc_tests filename

    <!-- begin push-4 -->

    Updated 129f48be88f738e6af9960fe81c0a9d05bb8b5f9 -> 236762802185b1c8219e6f567964be1ddc97b839 (pr/ipc-wins.3 -> pr/ipc-wins.4, compare)<!-- end --> adding an extra version check to be able to build against https://github.com/bitcoin-core/libmultiprocess/pull/231 without code changes

    <!-- begin push-5 -->

    Updated 236762802185b1c8219e6f567964be1ddc97b839 -> 1a97f072f887ab95e2ac89b5cf1bc4a75b7255c6 (pr/ipc-wins.4 -> pr/ipc-wins.5, compare)<!-- end --> with MakeStream cleanup from #32387 pr/ipc-win.23

    <!-- begin push-6 -->

    Rebased 1a97f072f887ab95e2ac89b5cf1bc4a75b7255c6 -> 0a16f106c1862d33b64b683089e7aac84446ac69 (pr/ipc-wins.5 -> pr/ipc-wins.6, compare)<!-- end --> due to conflict with #34806

  8. ryanofsky referenced this in commit e563c968b4 on Apr 16, 2026
  9. ryanofsky referenced this in commit b42ec11a5c on Apr 16, 2026
  10. ryanofsky force-pushed on Apr 17, 2026
  11. ryanofsky force-pushed on Apr 17, 2026
  12. ryanofsky referenced this in commit d9fcac6e30 on Apr 17, 2026
  13. ryanofsky referenced this in commit c537b41d09 on Apr 17, 2026
  14. ryanofsky referenced this in commit f813f9f959 on Apr 17, 2026
  15. DrahtBot removed the label CI failed on Apr 17, 2026
  16. ryanofsky referenced this in commit 74fc8ac8c3 on Apr 17, 2026
  17. ryanofsky referenced this in commit 6d87dd7990 on Apr 17, 2026
  18. ryanofsky referenced this in commit 68e367a0aa on Apr 17, 2026
  19. ryanofsky referenced this in commit 97b3bc9e31 on Apr 17, 2026
  20. ryanofsky referenced this in commit eeac89b481 on Apr 17, 2026
  21. ryanofsky referenced this in commit e451de95b3 on Apr 17, 2026
  22. SirMentos-apt commented at 1:14 PM on April 20, 2026: none

    can run bitcoin core on WSL ?

  23. Sjors commented at 3:04 PM on April 20, 2026: member

    @SirMentos-apt: @hebasto might know.

  24. ryanofsky referenced this in commit 323eb3a169 on Apr 20, 2026
  25. ryanofsky force-pushed on Apr 21, 2026
  26. ryanofsky referenced this in commit e2872e28cb on Apr 21, 2026
  27. Sjors referenced this in commit b1199a5604 on Apr 22, 2026
  28. ryanofsky referenced this in commit 926ae3562e on Apr 22, 2026
  29. DrahtBot added the label Needs rebase on May 22, 2026
  30. ryanofsky force-pushed on May 29, 2026
  31. DrahtBot removed the label Needs rebase on May 29, 2026
  32. DrahtBot added the label CI failed on May 29, 2026
  33. DrahtBot removed the label CI failed on Jun 1, 2026
  34. Sjors commented at 2:43 PM on June 17, 2026: member

    IIUC this can (must?) be merged before updating the subtree to https://github.com/bitcoin-core/libmultiprocess/pull/231?

  35. ryanofsky commented at 2:56 PM on June 17, 2026: contributor

    IIUC this can (must?) be merged before updating the subtree to bitcoin-core/libmultiprocess#231?

    Yes this is reviewable and meant to be merged before https://github.com/bitcoin-core/libmultiprocess/pull/231. Technically these changes could be made in the same PR updating the subtree, but seems a little better to keep bitcoin changes and libmultiprocess ones separate for better review. Most of the changes here are pretty small though. The biggest change is merging previously separated test files.

  36. Sjors commented at 3:15 PM on June 17, 2026: member

    Ok, maybe a better PR title would be "ipc: prepare for windows support"?

  37. in src/ipc/util.h:23 in 0a16f106c1 outdated
      18 | +#include <sys/socket.h>
      19 | +
      20 | +namespace mp {
      21 | +// Definitions that can be deleted when libmultiprocess subtree is updated to
      22 | +// v12. Having these allows Bitcoin Core changes to be decoupled from
      23 | +// libmultiprocess changes so they don't have to be reviewed in a single PR.
    


    Sjors commented at 6:32 PM on June 18, 2026:

    This is smart. Would be good to point out in the PR description that this can merged before ~or after~ https://github.com/bitcoin-core/libmultiprocess/pull/274 because of this neat little trick :-)


    ryanofsky commented at 6:44 PM on June 22, 2026:

    re: #35084 (review)

    This is smart. Would be good to point out in the PR description that this can merged before ~or after~ bitcoin-core/libmultiprocess#274 because of this neat little trick :-)

    Thanks, updated PR description to mention https://github.com/bitcoin-core/libmultiprocess/pull/274 and explain this.

  38. in src/ipc/test/ipc_tests.cpp:155 in 3cd19ce33a
     150 | @@ -151,15 +151,15 @@ void IpcSocketTest(const fs::path& datadir)
     151 |  
     152 |      auto bind_and_listen{[&](const std::string& bind_address) {
     153 |          std::string address{bind_address};
     154 | -        int serve_fd = process->bind(datadir, "test_bitcoin", address);
     155 | +        mp::SocketId serve_fd = process->bind(datadir, "test_bitcoin", address);
     156 |          BOOST_CHECK_GE(serve_fd, 0);
    


    Sjors commented at 8:15 AM on June 19, 2026:

    In 3cd19ce33a4d147674af637ab92c7df30176fe0b ipc, refactor: Add SocketId type alias and use it nit:

    BOOST_CHECK_NE(serve_fd, mp::SocketError);
    

    ryanofsky commented at 6:45 PM on June 22, 2026:

    re: #35084 (review)

    BOOST_CHECK_NE(serve_fd, mp::SocketError);
    

    Thanks, added

  39. Sjors commented at 11:30 AM on June 19, 2026: member

    ACK 0a16f106c1862d33b64b683089e7aac84446ac69

    I also checked that the tests still pass if I pull the subtree from #274 and drop the <v12 shim. Ideally we do that in a single PR.

  40. DrahtBot requested review from stickies-v on Jun 19, 2026
  41. ryanofsky referenced this in commit 9d2dd067fc on Jun 22, 2026
  42. ryanofsky force-pushed on Jun 22, 2026
  43. ryanofsky renamed this:
    ipc: Support for windows support
    ipc: Add nonunix platform support
    on Jun 22, 2026
  44. ryanofsky commented at 7:08 PM on June 22, 2026: contributor

    re: #35084 (comment)

    Ok, maybe a better PR title would be "ipc: prepare for windows support"?

    Yeah "support for windows support" was meant to be a little jokey. Renamed to be consistent with https://github.com/bitcoin-core/libmultiprocess/pull/274.


    <!-- begin push-7 -->

    Updated 0a16f106c1862d33b64b683089e7aac84446ac69 -> c8dca662d1a4e2e99035e2f367d865a7b047b53c (pr/ipc-wins.6 -> pr/ipc-wins.7, compare)<!-- end --> adding MSVC compatibility fixes and implementing review suggestions

  45. ryanofsky referenced this in commit 10ca1d46a3 on Jun 22, 2026
  46. ryanofsky referenced this in commit da3767fb40 on Jun 22, 2026
  47. Sjors commented at 5:43 PM on June 23, 2026: member

    utACK c8dca662d1a4e2e99035e2f367d865a7b047b53c

    I only briefly glanced at the MSVC change, didn't test that.

  48. enirox001 commented at 8:38 AM on July 7, 2026: contributor

    Concept ACK

  49. DrahtBot added the label Needs rebase on Jul 7, 2026
  50. ryanofsky referenced this in commit 14c1c202aa on Jul 10, 2026
  51. ryanofsky referenced this in commit 4781bbce25 on Jul 10, 2026
  52. ryanofsky force-pushed on Jul 14, 2026
  53. ryanofsky commented at 12:57 AM on July 14, 2026: contributor

    <!-- begin push-8 -->

    Rebased c8dca662d1a4e2e99035e2f367d865a7b047b53c -> 86bef4083029eb611b786d01bd1dd0284a29ad8e (pr/ipc-wins.7 -> pr/ipc-wins.8, compare)<!-- end --> due to conflict with #34020

  54. ryanofsky referenced this in commit 94e4582d0d on Jul 14, 2026
  55. DrahtBot removed the label Needs rebase on Jul 14, 2026
  56. ipc, moveonly: combine ipc_test.cpp and ipc_tests.cpp
    Previously ipc_test.cpp contained tests which depended on
    libmultiprocess and ipc_tests.cpp contained tests which didn't.
    Separation was needed because libmultiprocess tests need to be built
    with additional include and link paths, and cmake only has good support
    for setting these on libraries, not source files. The separation also
    allowed the add_boost_test custom cmake function to work with no changes,
    because it could find the boost test registration in ipc_tests.cpp, and
    then ipc_tests.cpp would run the tests in ipc_test.cpp without them
    needing to be registered in boost.
    
    But with windows support being added, the parse address test can't
    easily avoid a dependecy on libmultiprocess, because it depends on the
    ipc/process.h header, and ipc/process.h header will now need
    platform-specific ProcessId and SocketId types defined by
    libmultiprocess, rather than plain ints.
    
    With all ipc tests depending on libmultiprocess, there is not really a
    rationale for having separate test files anymore, so this change
    combines them, and move the cmake add_boost_test function definition so
    it can be used instead of target_sources to register ipc_tests.cpp with
    ctest.
    
    The change prevents CI errors from including ipc/process.h in
    ipc_tests.cpp:
    
    In file included from /Users/runner/work/bitcoin/bitcoin/repo_archive/src/ipc/test/ipc_tests.cpp:5:
    In file included from /Users/runner/work/bitcoin/bitcoin/repo_archive/src/ipc/process.h:11:
    /Users/runner/work/bitcoin/bitcoin/repo_archive/src/ipc/util.h:14:10: fatal error: 'kj/debug.h' file not found
       14 | #include <kj/debug.h>
    
    https://github.com/bitcoin/bitcoin/actions/runs/24465865499/job/71492617687?pr=35084
    794940469e
  57. ipc, refactor: Drop connect/listen/serve exe_name parameters
    Pass exe_name parameter to ipc::Protocol class constructor instead. It never
    really made sense to have exe parameters as part of the protocol interface and
    removing them makes adding new features like windows support easier.
    
    The exe name values are only used for logging and debuggging purposes to
    distinguish log messages from different processes.
    33d37f3c35
  58. ipc, refactor: Change Protocol class field order
    This just changes Protocol class field order to make sure class members are not
    destroyed before the event loop thread exits. There is no change in behavior.
    The change is just being made to clarify intent and avoid potential bugs.
    00287b9a34
  59. ipc, refactor: use native path separators in test
    Avoid hardcoded forward slashes is ParseAddress test, use native path
    separators instead.
    7c86d4834e
  60. ipc, refactor: fix include order
    Keep standard headers separate from posix headers
    dbcc192dce
  61. ipc: Avoid 'unistd.h' error with MSVC
    Avoid compile error from MSVC:
    
    D:\a\bitcoin\bitcoin\src\ipc\interfaces.cpp(24,1): error C1083: Cannot open include file: 'unistd.h': No such file or directory
    
    MinGW provides this header but MSVC does not. Header is unneeded on windows
    because HandleCtrlC code that uses it is not compiled on windows.
    3449797141
  62. ipc, refactor: Add ProcessId type alias and use it
    Use ProcessId type instead of int to represent process ids to be
    compatible with an upcoming version of libmultiprocess which adds
    windows support.
    2ee9b69c7a
  63. ipc, refactor: Add SocketId type alias and use it
    Use SocketId type instead of int to represent socket ids to be
    compatible with an upcoming version of libmultiprocess which adds
    windows support.
    3859805f05
  64. ipc, refactor: Add Stream type alias and use it
    Use Stream type to abstract socket ids and be compatible with updated
    mp::ConnectStream() and mp::ServeStream() functions that use streams
    instead of socket ids in an upcoming version of libmultiprocess which
    adds windows support.
    
    Since creating Stream objects from socket ids can require the event loop
    to be running, the ipc::Protocol::serve() method is also updated to
    accept the server stream though a callback parameter instead of a normal
    parameter.
    e9f19815ca
  65. ryanofsky force-pushed on Jul 16, 2026
  66. ryanofsky commented at 12:05 PM on July 16, 2026: contributor

    Pushed a new update. I'd encourage anybody interested in windows IPC support to review this. It should be a pretty easy review because the commits are self-contained refactorings, and no knowledge about IPC or windows is required. The biggest commit is the first commit which moves tests.

    <!-- begin push-9 -->

    Rebased 86bef4083029eb611b786d01bd1dd0284a29ad8e -> 845c6a94d141424cb68ebd69310c6586f3648253 (pr/ipc-wins.8 -> pr/ipc-wins.9, compare)<!-- end --> bumping version number after #35084, and dropping unnecessary MSVC commit

    <!-- begin push-10 -->

    Updated 845c6a94d141424cb68ebd69310c6586f3648253 -> 0ca362a7c71f73243c894f7edf2cc8e8bd25d5fb (pr/ipc-wins.9 -> pr/ipc-wins.10, compare)<!-- end --> using updated mp::MakeStream signature

    <!-- begin push-11 -->

    Updated 0ca362a7c71f73243c894f7edf2cc8e8bd25d5fb -> 2757de229d6bb0a7472ad9b844591e7347c628a8 (pr/ipc-wins.10 -> pr/ipc-wins.11, compare)<!-- end --> dropping SpawnConnectInfo type

  67. ryanofsky referenced this in commit 28e953f02d on Jul 16, 2026
  68. ryanofsky referenced this in commit 2cfe1b326b on Jul 16, 2026
  69. ryanofsky force-pushed on Jul 16, 2026
  70. ryanofsky referenced this in commit fbe5a14ad4 on Jul 16, 2026
  71. DrahtBot added the label IPC on Jul 16, 2026
  72. ipc, refactor: Update mp::SpawnProcess call
    Use new SpawnProcess and StartSpawned functions to be compatible with an
    upcoming version of libmultiprocess which adds windows support.
    2d3f72fd3f
  73. ryanofsky force-pushed on Jul 17, 2026
  74. Sjors commented at 6:06 PM on July 17, 2026: member

    Now that https://github.com/bitcoin-core/libmultiprocess/pull/274 landed, there's probably no point in keeping the shim, and it's better update the subtree here.

  75. ryanofsky commented at 9:02 PM on July 17, 2026: contributor

    Now that bitcoin-core/libmultiprocess#274 landed, there's probably no point in keeping the shim, and it's better update the subtree here.

    I disagree, but if other reviewers would prefer, I can update the subtree in this PR as suggested.

    The shim is 25 lines of very simple code that makes this PR easier for me maintain and update, and not depend on the many changes in flight in the upstream repo.

    I think having this shim also makes this PR easier to review, because most of the refactoring here is internal and doesn't depend on the libmultiprocess changes (the shim is not even introduced until the 7th commit). Maybe 75% of the work here is preparing to use the new libmultiprocess API, and 25% is using it.

  76. Sjors commented at 10:54 AM on July 20, 2026: member

    re-ACK 2757de229d6bb0a7472ad9b844591e7347c628a8

    I'm fine with keeping the shim. I checked again that the relevant tests still pass if I drop it and update the subtree locally.

    I noticed you dropped commit 587fcedb90fdb324ed018bb16530f76805debb04 ipc: fix MSVC build error C3861 in ipc_tests.cpp, which seems fine for this PR since those tests aren't run on MSVC. Do you plan to move it to #32387? Or is not needed there either?

  77. DrahtBot requested review from enirox001 on Jul 20, 2026
  78. in src/ipc/capnp/protocol.cpp:26 in a0c8c9fccc
      22 | @@ -23,7 +23,6 @@
      23 |  #include <mutex>
      24 |  #include <optional>
      25 |  #include <string>
      26 | -#include <sys/socket.h>
    


    ViniciusCestarii commented at 12:43 PM on July 20, 2026:

    In "ipc, refactor: Add Stream type alias and use it" a0c8c9fcccf6022a7b17281b14e1a39c467d9c6d

    nit: this drops sys/socket.h while still calls ::listen()


    ryanofsky commented at 7:59 PM on July 20, 2026:

    re: #35084 (review)

    In "ipc, refactor: Add Stream type alias and use it" a0c8c9f

    nit: this drops sys/socket.h while still calls ::listen()

    Good catch, reverted this change.

  79. in src/ipc/process.h:1 in 7390736ec2 outdated


    ViniciusCestarii commented at 1:36 PM on July 20, 2026:

    In "ipc, refactor: Add SocketId type alias and use it" 7390736ec28e9e2625ec080273b624b56f17b852

    Since this is pr is moving away from unix and being more abstract and generic to support more platforms, I believe it is correct to move away from unix terminology too.

    nit: In this file it says "socket file descriptor" and "socket descriptor" but it could be renamed to "socket id" and this matches the new function makeStream on commit a0c8c9fcccf6022a7b17281b14e1a39c467d9c6d which header also mention socket id.


    ViniciusCestarii commented at 1:48 PM on July 20, 2026:

    In "ipc, refactor: Add Stream type alias and use it" a0c8c9fcccf6022a7b17281b14e1a39c467d9c6d

    nit: doc mentions "over given socket descriptor" but receives a stream on function "connect" now and where is mentioning "socket" on the functions "connect" and "serve" should be stream since it is now handling mp::Stream and not mp::SocketId.


    ryanofsky commented at 8:00 PM on July 20, 2026:

    re: #35084 (review)

    Makes sense, removed mentions of descriptors in all comments.


    ryanofsky commented at 8:01 PM on July 20, 2026:

    re: #35084 (review)

    Thanks, this now refers to streams and socket ids

  80. ViniciusCestarii commented at 1:58 PM on July 20, 2026: contributor

    ACK 2757de229d6bb0a7472ad9b844591e7347c628a8 left a few nits, most about doc comments not being updated to match the new SocketId/Stream terminology

  81. ryanofsky force-pushed on Jul 20, 2026
  82. ryanofsky commented at 8:04 PM on July 20, 2026: contributor

    Thanks for the reviews!

    <!-- begin push-12 -->

    Updated 2757de229d6bb0a7472ad9b844591e7347c628a8 -> 2d3f72fd3fa45ab4e399094c39bfa93bb5a87323 (pr/ipc-wins.11 -> pr/ipc-wins.12, compare)<!-- end --> reverting dropped include and updating comments to avoid mentioning descriptors as suggested

  83. Sjors commented at 8:34 AM on July 21, 2026: member

    re-ACK 2d3f72fd3fa45ab4e399094c39bfa93bb5a87323

  84. DrahtBot requested review from ViniciusCestarii on Jul 21, 2026
  85. ViniciusCestarii commented at 1:54 PM on July 21, 2026: contributor

    re-ACK 2d3f72fd3fa45ab4e399094c39bfa93bb5a87323

  86. ipc, refactor: Update mp::g_thread_context references
    Use new CurrentThread function to be compatible with windows mingw bug
    workaround https://github.com/bitcoin-core/libmultiprocess/pull/318
    d3d74e701f
  87. ryanofsky referenced this in commit 2ae0ba332d on Jul 22, 2026
  88. ryanofsky referenced this in commit 72dde6dc86 on Jul 22, 2026
  89. ryanofsky commented at 1:26 PM on July 23, 2026: contributor

    <!-- begin push-13 -->

    Added 1 commit 2d3f72fd3fa45ab4e399094c39bfa93bb5a87323 -> d3d74e701f761f21d276959c15fb91eaca3c5607 (pr/ipc-wins.12 -> pr/ipc-wins.13, compare)<!-- end --> for compatibility with https://github.com/bitcoin-core/libmultiprocess/pull/318

  90. in src/ipc/capnp/protocol.cpp:83 in d3d74e701f
      81 | -    std::unique_ptr<interfaces::Init> connect(int fd, const char* exe_name) override
      82 | +    std::unique_ptr<interfaces::Init> connect(mp::Stream stream) override
      83 |      {
      84 | -        startLoop(exe_name);
      85 | -        return mp::ConnectStream<messages::Init>(*m_loop, fd);
      86 | +        startLoop();
    


    xyzconstant commented at 9:44 PM on July 25, 2026:

    In commit e9f19815ca "ipc, refactor: Add Stream type alias and use it"

    nit: This startLoop() is now redundant (although harmless, it will always hit the if (m_loop) return; check). Every caller generates the stream using the makeStream method defined below, which also calls startLoop(), so the loop is always created by the time connect() is run.

    Suggest dropping it or replacing it with assert(m_loop);.


    ryanofsky commented at 12:58 PM on July 29, 2026:

    re: #35084 (review)

    This is an interesting suggestion. The Protocol connect() listen() serve() and makeStream()methods all start the loop if it is not started and you are right that unlike the other methods, connect() currently could just assert the loop is started instead of trying to start it.

    I'm not sure I see a benefit to adding this assumption though. Right now all streams come from passing file descriptors to makeStream but it seems plausible there could be other types of streams or other methods returning streams that don't call startLoop or use this event loop.

    I do like symmetry of protocol methods calling startLoop and not caring about what order they are called. There is already a little bit of asymmetry with the serve() method asserting the loop is not started (to allow single-threaded spawned processes and avoid creating unnecessary threads) but it doesn't seem good to add extra assumptions without knowing what way they would be helpful.

  91. xyzconstant commented at 12:47 AM on July 26, 2026: contributor

    tACK d3d74e701f761f21d276959c15fb91eaca3c5607

    LGTM. Left an inline comment.

  92. DrahtBot requested review from ViniciusCestarii on Jul 26, 2026
  93. DrahtBot requested review from Sjors on Jul 26, 2026
  94. in src/ipc/test/ipc_tests.cpp:198 in 794940469e
     194 | +        connect_and_test(addresses[i]);
     195 | +    }
     196 | +}
     197 | +
     198 |  BOOST_FIXTURE_TEST_SUITE(ipc_tests, BasicTestingSetup)
     199 |  BOOST_AUTO_TEST_CASE(ipc_tests)
    


    enirox001 commented at 2:56 PM on July 27, 2026:

    In https://github.com/bitcoin/bitcoin/pull/35084/changes/794940469e77b82462db33011fa4d5e8f533e543 ipc, moveonly: combine ipc_test.cpp and ipc_tests.cpp

    nit: I understand this is a move-only commit, but right now, ipc_tests.cpp groups the IPC tests into a single ipc_tests case. This follows the old pattern from when the tests were in separate files. Now that they have been moved into the same file, I think we can split them further by giving each test its own BOOST_AUTO_TEST_CASE().

    index e353a7ee7c..63345d42cd 100644
    --- a/src/ipc/test/ipc_tests.cpp
    +++ b/src/ipc/test/ipc_tests.cpp
    @@ -51,6 +51,8 @@ static std::string TempPath(std::string_view pattern)
         return temp;
     }
    
    +BOOST_FIXTURE_TEST_SUITE(ipc_tests, BasicTestingSetup)
    +
     //! Unit test that tests execution of IPC calls without actually creating a
     //! separate process. This test is primarily intended to verify behavior of type
     //! conversion code that converts C++ objects to Cap'n Proto messages and vice
    @@ -59,7 +61,8 @@ static std::string TempPath(std::string_view pattern)
     //! The test creates a thread which creates a FooImplementation object (defined
     //! in ipc_test.h) and a two-way pipe accepting IPC requests which call methods
     //! on the object through FooInterface (defined in ipc_test.capnp).
    -void IpcPipeTest()
    +
    +BOOST_AUTO_TEST_CASE(pipe_test)
     {
         // Setup: create FooImplementation object and listen for FooInterface requests
         std::promise<std::unique_ptr<mp::ProxyClient<gen::FooInterface>>> foo_promise;
    @@ -127,7 +130,7 @@ void IpcPipeTest()
     }
    
     //! Test ipc::Protocol connect() and serve() methods connecting over a socketpair.
    -void IpcSocketPairTest()
    +BOOST_AUTO_TEST_CASE(socket_pair_test)
     {
         std::unique_ptr<interfaces::Init> init{std::make_unique<TestInit>()};
         std::unique_ptr<ipc::Protocol> protocol{ipc::capnp::MakeCapnpProtocol("IpcSocketPairTest")};
    @@ -151,8 +154,10 @@ void IpcSocketPairTest()
     }
    
     //! Test ipc::Process bind() and connect() methods connecting over a unix socket.
    -void IpcSocketTest(const fs::path& datadir)
    +BOOST_AUTO_TEST_CASE(socket_test)
     {
    +    const fs::path& datadir{m_args.GetDataDirNet()};
    +
         std::unique_ptr<interfaces::Init> init{std::make_unique<TestInit>()};
         std::unique_ptr<ipc::Protocol> protocol{ipc::capnp::MakeCapnpProtocol("IpcSocketTest")};
         std::unique_ptr<ipc::Process> process{ipc::MakeProcess()};
    @@ -198,14 +203,6 @@ void IpcSocketTest(const fs::path& datadir)
         }
     }
    
    -BOOST_FIXTURE_TEST_SUITE(ipc_tests, BasicTestingSetup)
    -BOOST_AUTO_TEST_CASE(ipc_tests)
    -{
    -    IpcPipeTest();
    -    IpcSocketPairTest();
    -    IpcSocketTest(m_args.GetDataDirNet());
    -}
    -
     // Test address parsing.
     BOOST_AUTO_TEST_CASE(parse_address_test)
     {
    

    This removes the redundant ipc_tests wrapper and provides independent failure reporting and individual test execution. Other c++ tests already follow this pattern.

    It also preserves the current behavior, since running build/bin/test_bitcoin --run_test=ipc_tests will still run all the test cases.

    The tradeoff is that BasicTestingSetup would be constructed four times instead of twice, which may add some runtime overhead. If out of scope, perhaps could be done in a followup


    Sjors commented at 10:12 AM on July 28, 2026:

    This seems better for a followup.


    ryanofsky commented at 1:27 PM on July 29, 2026:

    re: #35084 (review)

    Now that they have been moved into the same file, I think we can split them further by giving each test its own BOOST_AUTO_TEST_CASE().

    Yes this is natural followup. It wasn't done here just to keep the PR mostly move-only and easier to review.

  95. in src/ipc/capnp/protocol.cpp:142 in 33d37f3c35
     138 |              m_loop->loop();
     139 |              m_loop.reset();
     140 |          });
     141 |          promise.get_future().wait();
     142 |      }
     143 | +    const char* m_exe_name;
    


    enirox001 commented at 3:36 PM on July 27, 2026:

    In commit https://github.com/bitcoin/bitcoin/pull/35084/changes/33d37f3c35efaac136863253b91799bf2711fd46 "ipc, refactor: Drop connect/listen/serve exe_name parameters

    Why do we store this as a const char* instead of an std::string? I could not find any documentation describing the lifetime requirement here.

    Right now, CapnpProtocol does not own the text. This is safe for the current callers, but it assumes that the caller keeps the underlying memory alive for the entire lifetime of the protocol. This could leave m_exe_name dangling if, for example, the original string is modified or destroyed after being passed to MakeCapnpProtocol().

    Could we store it as an std::string instead? This would make CapnpProtocol own the value and ensure that its lifetime matches the lifetime of the protocol.

    index e7eaf64301..1e4bdf533a 100644
    --- a/src/ipc/capnp/protocol.cpp
    +++ b/src/ipc/capnp/protocol.cpp
    @@ -71,7 +71,7 @@ void IpcLogFn(mp::LogMessage message)
     class CapnpProtocol : public Protocol
     {
     public:
    -    CapnpProtocol(const char* exe_name) : m_exe_name{exe_name} {}
    +    CapnpProtocol(std::string exe_name) : m_exe_name{std::move(exe_name)} {}
         ~CapnpProtocol() noexcept(true)
         {
             m_loop_ref.reset();
    @@ -94,12 +94,12 @@ public:
         void serve(interfaces::Init& init, const std::function<mp::Stream()>& make_stream) override
         {
             assert(!m_loop);
    -        mp::CurrentThread().thread_name = mp::ThreadName(m_exe_name);
    +        mp::CurrentThread().thread_name = mp::ThreadName(m_exe_name.c_str());
             mp::LogOptions opts = {
                 .log_fn = IpcLogFn,
                 .log_level = GetRequestedIPCLogLevel()
             };
    -        m_loop.emplace(m_exe_name, std::move(opts), &m_context);
    +        m_loop.emplace(m_exe_name.c_str(), std::move(opts), &m_context);
             mp::ServeStream<messages::Init>(*m_loop, make_stream(), init);
             m_parent_connection = &m_loop->m_incoming_connections.back();
             m_loop->loop();
    @@ -135,7 +135,7 @@ public:
                     .log_fn = IpcLogFn,
                     .log_level = GetRequestedIPCLogLevel()
                 };
    -            m_loop.emplace(m_exe_name, std::move(opts), &m_context);
    +            m_loop.emplace(m_exe_name.c_str(), std::move(opts), &m_context);
                 m_loop_ref.emplace(*m_loop);
                 promise.set_value();
                 m_loop->loop();
    @@ -143,7 +143,7 @@ public:
             });
             promise.get_future().wait();
         }
    -    const char* m_exe_name;
    +    std::string m_exe_name;
         Context m_context;
         //! EventLoop object which manages I/O events for all connections.
         std::optional<mp::EventLoop> m_loop;
    

    This is mostly a nice to have and might be out of scope as well and better fit for a followup. Regardless, I think a bit more documentation here might be helpful


    Sjors commented at 10:19 AM on July 28, 2026:

    I couldn't find a rationale for it in #19160 (which introduced the original code). But it seems unrelated to nonunix platform support, so could be a separate PR.


    ryanofsky commented at 1:43 PM on July 29, 2026:

    re: #35084 (review)

    I believe this was done to match the type of the EventLoop::m_exe_name variable. That variable is expected to be set to a string literal that's never allocated and is around for the lifetime of the process, but really would make sense to change to a std::string, and there isn't a good reason it was ever a C string.

    If changing this I think would be good to change the EventLoop::m_exe_name variable type first and then change the code assigning it after. Otherwise the mismatched types could lifetime issues, for example if the CapnpProtocol::m_exe_name was modified after EventLoop::m_exe_name was assigned, the EventLoop variable could contain an invalid pointer.

  96. enirox001 commented at 8:51 AM on July 28, 2026: contributor

    ACK d3d74e701f

    Changes here update the ipc code in bitcoin to match the libmultiprocess api changes and remove assumptions that process ids, sockets, and streams are always represented as unix int values.

    The new type aliases and changes make these interfaces less platform-specific and prepare them for Windows support.

    The changes look good to me. I left a few questions and suggestions inline, but they are non-blocking and may be better suited for follow-ups.

  97. in src/ipc/process.cpp:62 in 2d3f72fd3f
      60 | -        if (!maybe_fd) {
      61 | -            throw std::runtime_error(strprintf("Invalid -ipcfd number '%s'", argv[2]));
      62 | +        try {
      63 | +           socket = mp::StartSpawned(argv[2]);
      64 | +        } catch (const std::exception& e) {
      65 | +           throw std::runtime_error(strprintf("Invalid -ipcfd number '%s' (%s)", argv[2], e.what()));
    


    Sjors commented at 10:53 AM on July 28, 2026:

    In 2d3f72fd3fa45ab4e399094c39bfa93bb5a87323 ipc, refactor: Update mp::SpawnProcess call: suggested test coverage:

    BOOST_AUTO_TEST_CASE(check_spawned_test)
    {
        std::unique_ptr<ipc::Process> process{ipc::MakeProcess()};
        mp::SocketId socket{mp::SocketError};
        char arg0[]{"bitcoin-node"};
        char arg1[]{"-ipcfd"};
        char arg2[]{"invalid"};
        char* argv[]{arg0, arg1, arg2};
        auto check_error{[](const std::runtime_error& e) {
            return std::string_view{e.what()}.starts_with("Invalid -ipcfd number 'invalid'");
        }};
        BOOST_CHECK_EXCEPTION(process->checkSpawned(3, argv, socket), std::runtime_error, check_error);
        BOOST_CHECK_EQUAL(socket, mp::SocketError);
    }
    
    

    ryanofsky commented at 1:24 PM on July 29, 2026:

    re: #35084 (review)

    This is a good test suggestion that would be a nice followup. Note that after https://github.com/bitcoin-core/libmultiprocess/pull/274, the exception will be a little different and look more like "StartSpawned: invalid connect_info" and after https://github.com/bitcoin-core/libmultiprocess/pull/231 the exception on windows will be "CreateFile(pipe) failed" so it could make sense to just check that an exception is thrown and not try to match the text.

    Also:

    • It would be nice to change checkSpawned signature to return optional<SocketId> instead of using bool and an output parameter. (I believe this code is from before C++17 which added std::optional)
    • Could be good to add another test case that doesn't pass an -ipcfd and ensures checkSpawned returns false without throwing an exception.
    • Could be good to add another test case that just passes -ipcfd as the last argument.
    • Could be nice to rename -ipcfd to something more generic like -ipcspawn or -ipcchild since a named pipe path instead of a file descriptor is passed on windows.

    ViniciusCestarii commented at 8:48 PM on August 4, 2026:

    Opened PR #35887 implementing these follow-ups.

  98. Sjors commented at 11:47 AM on July 28, 2026: member

    ACK d3d74e701f761f21d276959c15fb91eaca3c5607

    Tested locally on macOS and by dropping the shim and updating the subtree to https://github.com/bitcoin-core/libmultiprocess/pull/318.

  99. DrahtBot requested review from Sjors on Jul 28, 2026
  100. ViniciusCestarii commented at 1:04 PM on July 28, 2026: contributor

    re-ACK d3d74e701f761f21d276959c15fb91eaca3c5607 tested locally on Linux

  101. sedited approved
  102. sedited commented at 7:37 AM on July 29, 2026: contributor

    ACK d3d74e701f761f21d276959c15fb91eaca3c5607

  103. sedited merged this on Jul 29, 2026
  104. sedited closed this on Jul 29, 2026

  105. hebasto referenced this in commit 8d61a37524 on Jul 29, 2026
  106. hebasto referenced this in commit 07822b7537 on Jul 29, 2026
  107. Sjors referenced this in commit 66298c737f on Jul 29, 2026
  108. ryanofsky commented at 1:55 PM on July 29, 2026: contributor

    Thanks for the reviews! Responded to all the comments, and I'd be happy to review any of the suggested followups.

    re: #35084 (comment)

    I noticed you dropped commit 587fced ipc: fix MSVC build error C3861 in ipc_tests.cpp, which seems fine for this PR since those tests aren't run on MSVC. Do you plan to move it to #32387? Or is not needed there either?

    Good catch. Yes I dropped the commit intentionally and moved it to #32387 because it adds a few lines of conditionally compiled windows code (an _mktemp_s call) that would not be checked by CI if added in this PR. It makes more sense in #32387 where it's actually needed and used.

  109. ryanofsky referenced this in commit f5c15ce33f on Jul 30, 2026
  110. Kino1994 referenced this in commit 33bd9b5d17 on Aug 2, 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-08-06 19:51 UTC

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