multiprocess: Start using init makeNode, makeChain, etc methods #22219

pull ryanofsky wants to merge 1 commits into bitcoin:master from ryanofsky:pr/ipc-make changing 17 files +63 −22
  1. ryanofsky commented at 10:19 pm on June 10, 2021: member

    Use interfaces::Init::make* methods instead of interfaces::Make* functions, so interfaces can be constructed differently in different executable without having to change any code. (So for example bitcoin-gui can make an interfaces::Node pointer that communicates with a bitcoin-node subprocess, while bitcoin-qt can make an interfaces::Node pointer that controls node code in the same process.)


    This PR is part of the process separation project. The commit was first part of larger PR #10102.

  2. ryanofsky added this to the "In progress" column in a project

  3. DrahtBot added the label Build system on Jun 10, 2021
  4. DrahtBot added the label GUI on Jun 10, 2021
  5. DrahtBot added the label interfaces on Jun 10, 2021
  6. DrahtBot added the label RPC/REST/ZMQ on Jun 10, 2021
  7. DrahtBot added the label Wallet on Jun 10, 2021
  8. MarcoFalke commented at 7:23 am on June 11, 2021: member
    ci fails. Maybe this needs rebase on bitcoin/bitcoin#22216 ?
  9. ryanofsky force-pushed on Jun 11, 2021
  10. ryanofsky commented at 9:13 am on June 11, 2021: member
    Rebased 12ca4486bc6237e92e2dcf1bad8dc6fc61cd3e8d -> 40dad10a19802149be588b23968d73cc28c58ad3 (pr/ipc-make.1 -> pr/ipc-make.2, compare) after #22216 to fix implicit dependency on #22216 causing CI failures https://github.com/bitcoin/bitcoin/pull/22219/checks?check_run_id=2798033917
  11. ryanofsky commented at 9:15 am on June 11, 2021: member

    ci fails. Maybe this needs rebase on #22216 ?

    Thanks! Rebased now. Nice catch of this dependency

  12. MarcoFalke commented at 10:12 am on June 11, 2021: member
    windows build is red :grimacing:
  13. ryanofsky force-pushed on Jun 11, 2021
  14. ryanofsky commented at 5:10 pm on June 11, 2021: member

    windows build is red :grimacing:

    Hopefully fixed!


    Updated 40dad10a19802149be588b23968d73cc28c58ad3 -> 7a879afa11d1bc1cf8c2327b377d7b3d1485a9fe (pr/ipc-make.2 -> pr/ipc-make.3, compare) to fix appveyor build error https://ci.appveyor.com/project/DrahtBot/bitcoin/builds/39561119#L32 Updated 7a879afa11d1bc1cf8c2327b377d7b3d1485a9fe -> 8da084ae4de4dfd79694832763e6e92a68e643da (pr/ipc-make.3 -> pr/ipc-make.4, compare) to to fix appveyor build error https://ci.appveyor.com/project/DrahtBot/bitcoin/builds/39567970#L33 Rebased 8da084ae4de4dfd79694832763e6e92a68e643da -> c50facd030ec5bd2c7fc2b55486a3cb77b59b1d8 (pr/ipc-make.4 -> pr/ipc-make.5, compare) after bitcoin-core/gui#361 to revert it because that change is no longer necessary with other changes in this PR

  15. ryanofsky force-pushed on Jun 11, 2021
  16. ryanofsky force-pushed on Jun 15, 2021
  17. jamesob approved
  18. jamesob commented at 8:42 pm on June 15, 2021: member

    ACK c50facd030ec5bd2c7fc2b55486a3cb77b59b1d8 (jamesob/ackr/22219.1.ryanofsky.multiprocess_start_using)

    Built and ran unittests locally. Changes look fine and mostly boil down to naming and some pointer/ref swaps.

     0-----BEGIN PGP SIGNED MESSAGE-----
     1Hash: SHA512
     2
     3ACK c50facd030ec5bd2c7fc2b55486a3cb77b59b1d8 ([`jamesob/ackr/22219.1.ryanofsky.multiprocess_start_using`](https://github.com/jamesob/bitcoin/tree/ackr/22219.1.ryanofsky.multiprocess_start_using))
     4
     5Built and ran unittests locally. Changes look fine and mostly boil down to naming and some pointer/ref swaps.
     6-----BEGIN PGP SIGNATURE-----
     7
     8iQIzBAEBCgAdFiEEGNRVI1NPYuZCSIrGepNdrbLETwUFAmDJEKYACgkQepNdrbLE
     9TwVgRA//UJL92+4xQvu/zOKP4Rv5BnnAx2Tr9g2Zhcxj9dTisiJfXaxBnTrW0Wcx
    10BaHuMZT0oq4aCpoi/rs686a2hR56Kts2SxBv9wKfOmQ5UobuMfgGGrcrr3XYPivG
    11YK+mt7RBc0yRhEUFv+dwvk+dGW9/lCAy3YukvfEGLSu57YGM8Aj/8k69cqOZGkTT
    12XQl1b45Aguk2EWBC56Vp916+qbU1kkGb1Y1Fpph0Ac7IOUeqHaOcBOlsnHIomfpo
    13Rl2K9clVMVG7DKcDAhkj4lWsJEaNszvc/3mgGIOhYc4PY1KMN6BVWN+SOtIk2EEW
    141YqY8NWi0TxUxJ6J1gZKUJTU8TPO5DZw0nnw0YEckaASur34Jklh+q4tXQzFgX1w
    159ZqGNDUa9slCRFy+itfGMtjxQ7dsVntCocw/kEYAlhtfJ7ak5v/IVJFxv5UPHvcB
    16nevRfUsKzN5Llwh49xVRin8BqtlH6292fcT04DXts4tSdmOxCcVjwt4blcmod03P
    17LCoYCAh09Y7srm9U0g/I+T391lsRijU+YYGwT9dm9OsUiZ1FgdXpac9Z45UgP9el
    18SFGMG5hNarFVU4KM/l67e/mT3lFJpOuF6aym7Eh10PYMAiabqGAkETANVtNqd1JY
    192UE3CXf8qkFl65XqfLfATchWkF6GcL3KqSenykclS/wMPsEeVvE=
    20=vjIY
    21-----END PGP SIGNATURE-----
    
    0Tested on Linux-4.19.0-10-amd64-x86_64-with-glibc2.28
    1
    2Configured with ./configure LDFLAGS=-L/home/james/src/bitcoin/db4/lib/ CPPFLAGS=-I/home/james/src/bitcoin/db4/include/ CXXFLAGS=-fPIE -pipe -O2 -g -Wthread-safety-analysis -Wall -Werror=sign-compare -Wsign-compare -Werror=thread-safety-analysis --enable-wallet --enable-debug --with-daemon --enable-natpmp-default CXX=/usr/lib/ccache/clang++ CC=/usr/lib/ccache/clang PYTHONPATH= --with-bignum=no --disable-shared --with-pic --enable-benchmark=no --enable-module-recovery --enable-module-schnorrsig --enable-experimental --disable-shared --with-pic --enable-benchmark=no --enable-module-recovery --enable-module-schnorrsig --enable-experimental --no-create --no-recursion
    3
    4Compiled with /usr/bin/ccache /usr/lib/ccache/clang++ -std=c++17 -mavx -mavx2 -fPIE -pipe -O2 -g -Wthread-safety-analysis -Wall -Werror=sign-compare -Wsign-compare -Werror=thread-safety-analysis -O0 -g3 -ftrapv -fdebug-prefix-map=$(abs_srcdir)=.  -Wstack-protector -fstack-protector-all -fcf-protection=full -msse4 -msha -msse4.1 -msse4.2  i
    5
    6Compiler version: clang version 7.0.1-8+deb10u2 (tags/RELEASE_701/final)
    
  19. DrahtBot commented at 0:09 am on June 17, 2021: member

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

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #15936 (Unify bitcoin-qt and bitcoind persistent settings 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.

  20. in src/init/bitcoind.cpp:31 in c50facd030 outdated
    26+    std::unique_ptr<interfaces::Chain> makeChain() override { return interfaces::MakeChain(m_node); }
    27+    std::unique_ptr<interfaces::WalletClient> makeWalletClient(interfaces::Chain& chain) override
    28+    {
    29+        return MakeWalletClient(chain, *Assert(m_node.args));
    30+    }
    31+    std::unique_ptr<interfaces::Echo> makeEcho() override { return interfaces::MakeEcho(); }
    


    ariard commented at 5:13 pm on July 8, 2021:

    What’s the rational of having an interfaces maker such as makeEcho supported on BitcoindInit, bitcoind program should never be executed as a spawned process/IpcServer ?

    One option is to tread this as a throw returned to the client, as MakeWalletClient is providing, though it means anytime we add a new derived Init interface, we need to add throw stub in all other programs non-supporting the interface functionality ?

    Currently, if the interface maker isn’t implemented-side, what I can observe on one of my local branch is silent failure of the IPC server, followed by a socket disconnection/EventLoop exit.

     02021-07-08T17:07:01Z {bitcoin-altnet-26997/bitcoin-altnet-26997} IPC server recv request  [#1](/bitcoin-bitcoin/1/) Init.construct$Params (threadMap = <external capability>)                                                                                                                                   
     12021-07-08T17:07:01Z
     22021-07-08T17:07:01Z {bitcoin-altnet-26997/bitcoin-altnet-26997} IPC server send response [#1](/bitcoin-bitcoin/1/) Init.construct$Results (threadMap = <external capability>)                                                                                                                                  
     32021-07-08T17:07:01Z
     42021-07-08T17:07:01Z {bitcoin-altnet-26997/bitcoin-altnet-26997} IPC server recv request  [#2](/bitcoin-bitcoin/2/) Init.makeEcho$Params (context = (thread = <external capability>, callbackThread = <external capability>))                                                                                   
     52021-07-08T17:07:01Z
     62021-07-08T17:07:01Z {bitcoin-altnet-26997/bitcoin-altnet-26997} IPC server post request  [#2](/bitcoin-bitcoin/2/) {bitcoin-altnet-26997/bitcoin-altnet-26999 (from bitcoin-node-26897/b-httpworker.0-26916)}                                                                                                  
     72021-07-08T17:07:01Z
     82021-07-08T17:07:01Z {bitcoin-altnet-26997/bitcoin-altnet-26997} IPC server send response [#2](/bitcoin-bitcoin/2/) Init.makeEcho$Results ()
     92021-07-08T17:07:01Z
    102021-07-08T17:07:01Z {bitcoin-altnet-26997/bitcoin-altnet-26997} IPC server: socket disconnected.
    112021-07-08T17:07:01Z
    122021-07-08T17:07:01Z {bitcoin-altnet-26997/bitcoin-altnet-26997} IPC server destroyN2mp11ProxyServerIN3ipc5capnp8messages4InitEEE
    132021-07-08T17:07:01Z
    142021-07-08T17:07:01Z {bitcoin-altnet-26997/bitcoin-altnet-26997} EventLoop::loop done, cancelling event listeners.
    152021-07-08T17:07:01Z
    162021-07-08T17:07:01Z {bitcoin-altnet-26997/bitcoin-altnet-26997} EventLoop::loop bye.
    

    ryanofsky commented at 9:13 pm on July 8, 2021:

    re: #22219 (review)

    Thanks for experimenting with this!

    What’s the rational of having an interfaces maker such as makeEcho supported on BitcoindInit, bitcoind program should never be executed as a spawned process/IpcServer ?

    Just like all interfaces in the src/interfaces/ directory, the interfaces::Init interface can be used remotely or it can be used locally. bitcoind provides the interfaces::Chain interface and it uses the interface::WalletClient interface even though it does not support IPC at all. bitcoin-qt uses the interfaces::Node and interfaces::Wallet interfaces even though it does not support IPC at all.

    The interfaces::Init interface is just the starting interface. When a bitcoin process is created, whether or not uses IPC it can create an instance of the interfaces::Init interface and use it to get access to other interfaces supported by the process. If the current process like bitcoind and bitcoin-qt and bitcoin-node has node code linked in, then makeNode() and makeChain() methods will return non-null. If the current process like bitcoind and bitcoin-qt and bitcoin-wallet has wallet code linked in, then makeWalletClient will return non-null. If the current process like bitcoin-gui has none of these things linked in then all of these methods will return null.

    The point of the Init interface is to allow the same bitcoin init code to be linked into different binaries and work without having to use preprocessor conditions or other build tricks. make* methods just return non-null if the relevant interface implementation is linked in and null if trying to instantiate the interface would cause link errors.

    Everything described above is happens with or without IPC. IPC just adds the option of calling other interface::Init instances that aren’t in the current process. You can spawn a new process and call its Init methods. Or you can connect to an existing process through a socket can call its Init methods. Or you can create a socket and let other processes call your process’s Init methods.

    One option is to tread this as a throw returned to the client, as MakeWalletClient is providing, though it means anytime we add a new derived Init interface, we need to add throw stub in all other programs non-supporting the interface functionality ?

    I’m not clear what this would be trying to do. Is it is related to the bug described below? Returning does null seems more ergonomic than throwing an exception. libmultiprocess does support throwing & catching exceptions remotely, but it requires an extra annotation in capnp interface definitions.

    Currently, if the interface maker isn’t implemented-side, what I can observe on one of my local branch is silent failure of the IPC server, followed by a socket disconnection/EventLoop exit.

    This isn’t expected and sounds like a bug. Can you post a branch or commit hash with the code? I think there should never be much reason to call a make method in a remote process if you know it will return null. But if it does return null you should just see a null return value forwarded. It shouldn’t cause the remote process to exit.

    The log is a little strange, and I’m not sure how to interpret it without looking at the code (it might also help to see the client side log). It looks like the server is successfully returning null from a remote makeEcho request. But then the socket is disconnected and it exits. Maybe the socket is closing because the client is segfaulting?

    Would be great to post details in new issue (https://github.com/chaincodelabs/libmultiprocess/issues/new) since that issue tracker is a convenient place to collect feedback and provide support for these things.


    ariard commented at 3:18 pm on July 12, 2021:

    Thanks to recall the design of interfaces::Init, this is matching the rough mental model I’ve in mind!

    If the current process like bitcoin-gui has none of these things linked in then all of these methods will return null.

    This is where I think the interfaces error handling could be improved. Instead of returning null if the current process doesn’t have linked code, what do you think about throwing back an exception from a stub ?

    AFAIU, this error handling is what the newly introduced MakeWalletClient in src/dummywallet.cpp (https://github.com/bitcoin/bitcoin/pull/22219/files#diff-ccc5d781a55644499897b7329c1544939c0751975d687abbda086d332db21fe7R68) is achieving. I was proposing to extend it to makeEcho on bitcoind build. Like https://github.com/ariard/bitcoin/commit/1dee88ad1bf4434bc495b77566c7e617245095a5.

    But AFAICT, you think it’s more ergonomic to return null rather than throwing an exception where I would prefer more explicit, verbose failure handling ? That said, I’m good with returning null, just a small ergonomic preference here.


    Maybe the socket is closing because the client is segfaulting?

    Yes I’m deliberately calling a method on the returned, null pointer to demonstrate the failure mode, sorry I should have precise that. Hopefully, it’s illustrating that throwing on null make method might be better to recover from logical bugs introduced by programmers mistakenly calling a make.

    Would be great to post details in new issue (https://github.com/chaincodelabs/libmultiprocess/issues/new) since that issue tracker is a convenient place to collect feedback and provide support for these things.

    Still cleaning the code on this branch, will post it for sure for feedback but so far I’m able to chain processes (bitcoind –> altnet_1 –> altnet_2) as intended :)


    ryanofsky commented at 4:29 pm on July 12, 2021:

    re: #22219 (review)

    But AFAICT, you think it’s more ergonomic to return null rather than throwing an exception where I would prefer more explicit, verbose failure handling ? That said, I’m good with returning null, just a small ergonomic preference here.

    I think it’s just a misunderstanding. I like exceptions and think it’s often good to throw when a condition happens that is definitely an error. But if an object can’t be created locally so it has to be created remotely, that may be an error, or it may be fine. The interfaces::Init make methods usually have no way of knowing what their callers are expecting. So I think all they should do is return the objects if they can make them or return null if they can’t make them.

    If you look at the makeNode call in the GUI code:

    https://github.com/ryanofsky/bitcoin/blob/pr/ipc.157/src/qt/bitcoin.cpp#L284-L285

    Or the makeWalletClient code in the node code:

    https://github.com/ryanofsky/bitcoin/blob/pr/ipc.157/src/wallet/init.cpp#L134-L135

    You can see that it’s not an error, but an expected condition for either of these methods to return null. If the node or wallet client object can’t be created locally (the respective make methods return null in bitcoin-gui and bitcoin-node binaries and non-null in bitcoin-qt and bitcoind binaries), the null-handling code simply calls spawnProcess and creates the object remotely.

    If you look at makeEcho code in the echoipc test:

    https://github.com/ryanofsky/bitcoin/blob/pr/ipc.157/src/rpc/misc.cpp#L685

    Then it is doing the opposite. For testing purposes it preferring to create the object remotely, but will fall back and create it locally if IPC is not available. This is a test design decision that I think should be local to the echoipc function, and not something which five different Init classes should be assuming. I think the make methods should all just make the object if they can or return null if they can’t and leave callers to handle the result.

    Still cleaning the code on this branch, will post it for sure for feedback but so far I’m able to chain processes (bitcoind –> altnet_1 –> altnet_2) as intended :)

    Glad to hear it!

  21. ariard commented at 5:28 pm on July 8, 2021: member
    IIUC, in case of non-implemented interfaces maker in server-side programs, is this moving failure from server back to client-side ? See my comment.
  22. DrahtBot added the label Needs rebase on Jul 22, 2021
  23. Start using init makeNode, makeChain, etc methods
    Use interfaces::Init::make* methods instead of interfaces::Make*
    functions, so interfaces can be constructed differently in different
    executables without having to change any code. (So for example
    bitcoin-gui can make an interfaces::Node pointer that communicates with
    a bitcoin-node subprocess, while bitcoin-qt can make an interfaces::Node
    pointer that starts node code in the same process.)
    e4709c7b56
  24. ryanofsky force-pushed on Aug 17, 2021
  25. ryanofsky commented at 11:24 pm on August 17, 2021: member
    Rebased c50facd030ec5bd2c7fc2b55486a3cb77b59b1d8 -> e4709c7b56612553fb7cbf16ef2d5099c5b732d0 (pr/ipc-make.5 -> pr/ipc-make.6, compare) due to conflict with bitcoin-core/gui#381
  26. DrahtBot removed the label Needs rebase on Aug 18, 2021
  27. ryanofsky commented at 7:02 pm on August 23, 2021: member

    @jamesob @ariard could reack this since it has been rebased? The only change was to fix a conflict in Qt includes https://github.com/ryanofsky/bitcoin/compare/pr/ipc-make.5-rebase..pr/ipc-make.6

    This PR is just replacing interfaces::MakeNode() function calls with interfaces::Init::makeNode() virtual method calls, interfaces::MakeChain() function calls with interfaces::Init::makeChain() virtual method calls, interfaces::MakeWalletClient() function calls with interfaces::Init::makeWalletClient() virtual method calls, interfaces::MakeNode() function calls with interfaces::Init::makeEcho() virtual method calls, so in #10102, the interfaces::Init implementation for the current executable will be able to decide whether to instantiate each interface locally in the current process or remotely over IPC in spawned processes.

  28. laanwj added this to the "Blockers" column in a project

  29. benthecarman approved
  30. benthecarman commented at 8:15 pm on August 30, 2021: contributor
    utACK e4709c7b56612553fb7cbf16ef2d5099c5b732d0
  31. MarcoFalke removed the label GUI on Aug 31, 2021
  32. MarcoFalke removed the label Wallet on Aug 31, 2021
  33. MarcoFalke removed the label Build system on Aug 31, 2021
  34. MarcoFalke removed the label RPC/REST/ZMQ on Aug 31, 2021
  35. MarcoFalke added the label Utils/log/libs on Aug 31, 2021
  36. jamesob commented at 3:23 pm on September 8, 2021: member

    reACK https://github.com/bitcoin/bitcoin/commit/e4709c7b56612553fb7cbf16ef2d5099c5b732d0

    Cloned changes and verified interdiff. Only changes are fixing qt imports.

  37. fanquake requested review from ariard on Sep 9, 2021
  38. achow101 commented at 8:34 pm on September 13, 2021: member
    ACK e4709c7b56612553fb7cbf16ef2d5099c5b732d0
  39. ryanofsky commented at 5:15 pm on September 15, 2021: member
    Is this ready for merge? Trivial change with multiple acks
  40. fanquake removed this from the "Blockers" column in a project

  41. fanquake merged this on Sep 16, 2021
  42. fanquake closed this on Sep 16, 2021

  43. fanquake commented at 1:06 am on September 16, 2021: member

    Looks like this has broken the CI. https://github.com/bitcoin/bitcoin/runs/3616387813:

    0PASS   : WalletTests::cleanupTestCase()
    1Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 2431ms
    2********* Finished testing of WalletTests *********
    3********* Start testing of AddressBookTests *********
    4Config: Using QtTest library 5.12.11, Qt 5.12.11 (arm-little_endian-ilp32-eabi-hardfloat static release build; by GCC 8.3.0)
    5PASS   : AddressBookTests::initTestCase()
    6test_bitcoin-qt: node/interfaces.cpp:266: node::{anonymous}::NodeImpl::walletClient()::<lambda()>: Assertion `"m_context->wallet_client" && check' failed.
    7FAIL qt/test/test_bitcoin-qt (exit status: 134)
    
  44. ryanofsky referenced this in commit f2c0afdc01 on Sep 16, 2021
  45. ryanofsky commented at 2:17 am on September 16, 2021: member

    Looks like this has broken the CI. bitcoin/bitcoin/runs/3616387813:

    Sorry about this. I reproduced this locally and posted a fix in #22992. I think there was a silent conflict, maybe with #19101 that prevented this getting caught by CI

  46. ryanofsky referenced this in commit 865ee1af20 on Sep 16, 2021
  47. fanquake referenced this in commit 9424e78f34 on Sep 16, 2021
  48. fanquake moved this from the "In progress" to the "Done" column in a project

  49. sidhujag referenced this in commit 8ced232d01 on Sep 19, 2021
  50. sidhujag referenced this in commit b53aac674a on Sep 19, 2021
  51. hebasto referenced this in commit 5db17dafee on Sep 28, 2021
  52. hebasto referenced this in commit 498a318f86 on Sep 28, 2021
  53. hebasto referenced this in commit bd10162d5c on Oct 3, 2021
  54. hebasto referenced this in commit f19889fc84 on Oct 4, 2021
  55. janus referenced this in commit ef064556db on Nov 11, 2021
  56. DrahtBot locked this on Jan 2, 2023

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: 2024-12-21 15:12 UTC

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