Skip to content

Commit e6e44ee

Browse files
committed
Multiprocess build changes
autotools and automake changes to support multiprocess execution. This adds a new --enable-multiprocess flag, and build configuration code to detect libraries needed for multiprocess support. The --enable-multiprocess flag builds new bitcoin-node and bitcoin-gui executables, which are updated in bitcoin/bitcoin#10102 to communicate across processes. But for now they are functionally equivalent to existing bitcoind and bitcoin-qt executables.
1 parent 516ebe8 commit e6e44ee

File tree

5 files changed

+159
-40
lines changed

5 files changed

+159
-40
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
src/bitcoin
66
src/bitcoind
77
src/bitcoin-cli
8+
src/bitcoin-gui
9+
src/bitcoin-node
810
src/bitcoin-tx
911
src/bitcoin-wallet
1012
src/test/fuzz

configure.ac

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,24 @@ if test x$enable_bip70 != xno; then
230230
AC_MSG_ERROR([BIP70 is no longer supported!])
231231
fi
232232

233+
AC_ARG_WITH([libmultiprocess],
234+
[AS_HELP_STRING([--with-libmultiprocess=yes|no|auto],
235+
[Build with libmultiprocess library. (default: auto, i.e. detect with pkg-config)])],
236+
[with_libmultiprocess=$withval],
237+
[with_libmultiprocess=auto])
238+
239+
AC_ARG_WITH([mpgen],
240+
[AS_HELP_STRING([--with-mpgen=yes|no|auto|PREFIX],
241+
[Build with libmultiprocess codegen tool. Useful to specify different libmultiprocess host system library and build system codegen tool prefixes when cross-compiling (default is host system libmultiprocess prefix)])],
242+
[with_mpgen=$withval],
243+
[with_mpgen=auto])
244+
245+
AC_ARG_ENABLE([multiprocess],
246+
[AS_HELP_STRING([--enable-multiprocess],
247+
[build multiprocess bitcoin-node, bitcoin-wallet, and bitcoin-gui executables in addition to monolithic bitcoind and bitcoin-qt executables. Requires libmultiprocess library. Experimental (default is no)])],
248+
[enable_multiprocess=$enableval],
249+
[enable_multiprocess=no])
250+
233251
AC_ARG_ENABLE(man,
234252
[AS_HELP_STRING([--disable-man],
235253
[do not install man pages (default is to install)])],,
@@ -1369,6 +1387,50 @@ AM_CONDITIONAL([EMBEDDED_UNIVALUE],[test x$need_bundled_univalue = xyes])
13691387
AC_SUBST(UNIVALUE_CFLAGS)
13701388
AC_SUBST(UNIVALUE_LIBS)
13711389

1390+
dnl libmultiprocess library check
1391+
1392+
libmultiprocess_found=no
1393+
if test "x$with_libmultiprocess" = xyes || test "x$with_libmultiprocess" = xauto; then
1394+
if test "x$use_pkgconfig" = xyes; then
1395+
m4_ifdef([PKG_CHECK_MODULES], [PKG_CHECK_MODULES([LIBMULTIPROCESS], [libmultiprocess], [
1396+
libmultiprocess_found=yes;
1397+
libmultiprocess_prefix=`$PKG_CONFIG --variable=prefix libmultiprocess`;
1398+
], [true])])
1399+
fi
1400+
elif test "x$with_libmultiprocess" != xno; then
1401+
AC_MSG_ERROR([--with-libmultiprocess=$with_libmultiprocess value is not yes, auto, or no])
1402+
fi
1403+
AC_SUBST(LIBMULTIPROCESS_CFLAGS)
1404+
AC_SUBST(LIBMULTIPROCESS_LIBS)
1405+
1406+
dnl Enable multiprocess check
1407+
1408+
if test "x$enable_multiprocess" = xyes; then
1409+
if test "x$libmultiprocess_found" != xyes; then
1410+
AC_MSG_ERROR([--enable-multiprocess=yes option specified but libmultiprocess library was not found. May need to install libmultiprocess library, or specify install path with PKG_CONFIG_PATH environment variable. Running 'pkg-config --debug libmultiprocess' may be helpful for debugging.])
1411+
fi
1412+
build_multiprocess=yes
1413+
elif test "x$enable_multiprocess" = xauto; then
1414+
build_multiprocess=$libmultiprocess_found
1415+
else
1416+
build_multiprocess=no
1417+
fi
1418+
1419+
AM_CONDITIONAL([BUILD_MULTIPROCESS],[test "x$build_multiprocess" = xyes])
1420+
AM_CONDITIONAL([BUILD_BITCOIN_NODE], [test "x$build_multiprocess" = xyes])
1421+
AM_CONDITIONAL([BUILD_BITCOIN_GUI], [test "x$build_multiprocess" = xyes])
1422+
1423+
dnl codegen tools check
1424+
1425+
if test x$build_multiprocess != xno; then
1426+
if test "x$with_mpgen" = xyes || test "x$with_mpgen" = xauto; then
1427+
MPGEN_PREFIX="$libmultiprocess_prefix"
1428+
elif test "x$with_mpgen" != xno; then
1429+
MPGEN_PREFIX="$with_mpgen";
1430+
fi
1431+
AC_SUBST(MPGEN_PREFIX)
1432+
fi
1433+
13721434
AC_MSG_CHECKING([whether to build bitcoind])
13731435
AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes])
13741436
AC_MSG_RESULT($build_bitcoind)
@@ -1649,6 +1711,7 @@ esac
16491711

16501712
echo
16511713
echo "Options used to compile and link:"
1714+
echo " multiprocess = $build_multiprocess"
16521715
echo " with wallet = $enable_wallet"
16531716
echo " with gui / qt = $bitcoin_enable_qt"
16541717
if test x$bitcoin_enable_qt != xno; then

doc/multiprocess.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Multiprocess Bitcoin
2+
3+
On unix systems, the `--enable-multiprocess` build option can be passed to `./configure` to build new `bitcoin-node`, `bitcoin-wallet`, and `bitcoin-gui` executables alongside existing `bitcoind` and `bitcoin-qt` executables.
4+
5+
`bitcoin-node` is a drop-in replacement for `bitcoind`, and `bitcoin-gui` is a drop-in replacement for `bitcoin-qt`, and there are no differences in use or external behavior between the new and old executables. But internally (after [#10102](https://github.com/bitcoin/bitcoin/pull/10102)), `bitcoin-gui` will spawn a `bitcoin-node` process to run P2P and RPC code, communicating with it across a socket pair, and `bitcoin-node` will spawn `bitcoin-wallet` to run wallet code, also communicating over a socket pair. This will let node, wallet, and GUI code run in separate address spaces for better isolation, and allow future improvements like being able to start and stop components independently on different machines and environments.
6+
7+
## Next steps
8+
9+
Specific next steps after [#10102](https://github.com/bitcoin/bitcoin/pull/10102) will be:
10+
11+
- [ ] Adding `-ipcbind` and `-ipcconnect` options to `bitcoin-node`, `bitcoin-wallet`, and `bitcoin-gui` executables so they can listen and connect to TCP ports and unix socket paths. This will allow separate processes to be started and stopped any time and connect to each other.
12+
- [ ] Adding `-server` and `-rpcbind` options to the `bitcoin-wallet` executable so wallet processes can handle RPC requests directly without going through the node.
13+
- [ ] Supporting windows, not just unix systems. The existing socket code is already cross-platform, so the only windows-specific code that needs to be written is code spawning a process and passing a socket descriptor. This can be implemented with `CreateProcess` and `WSADuplicateSocket`. Example: https://memset.wordpress.com/2010/10/13/win32-api-passing-socket-with-ipc-method/.
14+
- [ ] Adding sandbox features, restricting subprocess access to resources and data. See [https://eklitzke.org/multiprocess-bitcoin](https://eklitzke.org/multiprocess-bitcoin).
15+
16+
## Debugging
17+
18+
After [#10102](https://github.com/bitcoin/bitcoin/pull/10102), the `-debug=ipc` command line option can be used to see requests and responses between processes.
19+
20+
## Installation
21+
22+
The multiprocess feature requires [Cap'n Proto](https://capnproto.org/) and [libmultiprocess](https://github.com/chaincodelabs/libmultiprocess) as dependencies. A simple way to get starting using it without installing these dependencies manually is to use the [depends system](../depends) with the `MULTIPROCESS=1` [dependency option](../depends#dependency-options) passed to make:
23+
24+
```
25+
cd <BITCOIN_SOURCE_DIRECTORY>
26+
make -C depends NO_QT=1 MULTIPROCESS=1
27+
./configure --prefix=$PWD/depends/x86_64-pc-linux-gnu
28+
make
29+
src/bitcoin-node -regtest -printtoconsole -debug=ipc
30+
```
31+
32+
The configure script will pick up settings and library locations from the depends directory, so there is no need to pass `--enable-multiprocess` as a separate flag when using the depends system (it's controlled by the `MULTIPROCESS=1` option).
33+
34+
Alternately, you can install [Cap'n Proto](https://capnproto.org/) and [libmultiprocess](https://github.com/chaincodelabs/libmultiprocess) packages on your system, and just run `./configure --enable-multiprocess` without using the depends system. The configure script will be able to locate the installed packages via [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/). See [Installation](https://github.com/chaincodelabs/libmultiprocess#installation) section of the libmultiprocess readme for install steps. See [build-unix.md](build-unix.md) and [build-osx.md](build-osx.md) for information about installing dependencies in general.

src/Makefile.am

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ if BUILD_BITCOIND
8585
bin_PROGRAMS += bitcoind
8686
endif
8787

88+
if BUILD_BITCOIN_NODE
89+
bin_PROGRAMS += bitcoin-node
90+
endif
91+
8892
if BUILD_BITCOIN_CLI
8993
bin_PROGRAMS += bitcoin-cli
9094
endif
@@ -543,22 +547,22 @@ libbitcoin_cli_a_SOURCES = \
543547
nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h
544548
#
545549

546-
# bitcoind binary #
547-
bitcoind_SOURCES = bitcoind.cpp
548-
bitcoind_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
549-
bitcoind_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
550-
bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
550+
# bitcoind & bitcoin-node binaries #
551+
bitcoin_common_sources = bitcoind.cpp
552+
bitcoin_common_cppflags = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
553+
bitcoin_common_cxxflags = $(AM_CXXFLAGS) $(PIE_FLAGS)
554+
bitcoin_common_ldflags = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
551555

552556
if TARGET_WINDOWS
553-
bitcoind_SOURCES += bitcoind-res.rc
557+
bitcoin_common_sources += bitcoind-res.rc
554558
endif
555559

556-
bitcoind_LDADD = \
560+
bitcoin_common_ldadd = \
557561
$(LIBBITCOIN_SERVER) \
558562
$(LIBBITCOIN_WALLET) \
559563
$(LIBBITCOIN_COMMON) \
560-
$(LIBUNIVALUE) \
561564
$(LIBBITCOIN_UTIL) \
565+
$(LIBUNIVALUE) \
562566
$(LIBBITCOIN_ZMQ) \
563567
$(LIBBITCOIN_CONSENSUS) \
564568
$(LIBBITCOIN_CRYPTO) \
@@ -567,7 +571,19 @@ bitcoind_LDADD = \
567571
$(LIBMEMENV) \
568572
$(LIBSECP256K1)
569573

570-
bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS)
574+
bitcoin_common_ldadd += $(BOOST_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS)
575+
576+
bitcoind_SOURCES = $(bitcoin_common_sources)
577+
bitcoind_CPPFLAGS = $(bitcoin_common_cppflags)
578+
bitcoind_CXXFLAGS = $(bitcoin_common_cxxflags)
579+
bitcoind_LDFLAGS = $(bitcoin_common_ldflags)
580+
bitcoind_LDADD = $(bitcoin_common_ldadd)
581+
582+
bitcoin_node_SOURCES = $(bitcoin_common_sources)
583+
bitcoin_node_CPPFLAGS = $(bitcoin_common_cppflags)
584+
bitcoin_node_CXXFLAGS = $(bitcoin_common_cxxflags)
585+
bitcoin_node_LDFLAGS = $(bitcoin_common_ldflags)
586+
bitcoin_node_LDADD = $(bitcoin_common_ldadd)
571587

572588
# bitcoin-cli binary #
573589
bitcoin_cli_SOURCES = bitcoin-cli.cpp
@@ -611,29 +627,14 @@ bitcoin_tx_LDADD += $(BOOST_LIBS)
611627

612628
# bitcoin-wallet binary #
613629
bitcoin_wallet_SOURCES = bitcoin-wallet.cpp
614-
bitcoin_wallet_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
615-
bitcoin_wallet_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
616-
bitcoin_wallet_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
630+
bitcoin_wallet_CPPFLAGS = $(bitcoin_common_cppflags)
631+
bitcoin_wallet_CXXFLAGS = $(bitcoin_common_cxxflags)
632+
bitcoin_wallet_LDFLAGS = $(bitcoin_common_ldflags)
633+
bitcoin_wallet_LDADD = $(LIBBITCOIN_WALLET_TOOL) $(bitcoin_common_ldadd)
617634

618635
if TARGET_WINDOWS
619636
bitcoin_wallet_SOURCES += bitcoin-wallet-res.rc
620637
endif
621-
622-
bitcoin_wallet_LDADD = \
623-
$(LIBBITCOIN_WALLET_TOOL) \
624-
$(LIBBITCOIN_WALLET) \
625-
$(LIBBITCOIN_COMMON) \
626-
$(LIBBITCOIN_CONSENSUS) \
627-
$(LIBBITCOIN_UTIL) \
628-
$(LIBBITCOIN_CRYPTO) \
629-
$(LIBBITCOIN_ZMQ) \
630-
$(LIBLEVELDB) \
631-
$(LIBLEVELDB_SSE42) \
632-
$(LIBMEMENV) \
633-
$(LIBSECP256K1) \
634-
$(LIBUNIVALUE)
635-
636-
bitcoin_wallet_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(MINIUPNPC_LIBS) $(ZMQ_LIBS)
637638
#
638639

639640
# bitcoinconsensus library #

src/Makefile.qt.include

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

55
bin_PROGRAMS += qt/bitcoin-qt
6+
7+
if BUILD_BITCOIN_GUI
8+
bin_PROGRAMS += bitcoin-gui
9+
endif
10+
611
EXTRA_LIBRARIES += qt/libbitcoinqt.a
712

813
# bitcoin qt core #
@@ -294,29 +299,43 @@ QT_FORMS_H=$(join $(dir $(QT_FORMS_UI)),$(addprefix ui_, $(notdir $(QT_FORMS_UI:
294299
# Most files will depend on the forms and moc files as includes. Generate them
295300
# before anything else.
296301
$(QT_MOC): $(QT_FORMS_H)
297-
$(qt_libbitcoinqt_a_OBJECTS) $(qt_bitcoin_qt_OBJECTS) : | $(QT_MOC)
302+
$(qt_libbitcoinqt_a_OBJECTS) $(qt_bitcoin_qt_OBJECTS) $(bitcoin_gui_OBJECTS) : | $(QT_MOC)
298303

299-
# bitcoin-qt binary #
300-
qt_bitcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \
304+
# bitcoin-qt and bitcoin-gui binaries #
305+
bitcoin_qt_common_cppflags = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \
301306
$(QT_INCLUDES) $(QR_CFLAGS)
302-
qt_bitcoin_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS)
307+
bitcoin_qt_common_cxxflags = $(AM_CXXFLAGS) $(QT_PIE_FLAGS)
303308

304-
qt_bitcoin_qt_SOURCES = qt/main.cpp
309+
bitcoin_qt_common_sources = qt/main.cpp
305310
if TARGET_WINDOWS
306-
qt_bitcoin_qt_SOURCES += $(BITCOIN_RC)
311+
bitcoin_qt_common_sources += $(BITCOIN_RC)
307312
endif
308-
qt_bitcoin_qt_LDADD = qt/libbitcoinqt.a $(LIBBITCOIN_SERVER)
313+
bitcoin_qt_common_ldadd = qt/libbitcoinqt.a $(LIBBITCOIN_SERVER)
309314
if ENABLE_WALLET
310-
qt_bitcoin_qt_LDADD += $(LIBBITCOIN_UTIL) $(LIBBITCOIN_WALLET)
315+
bitcoin_qt_common_ldadd += $(LIBBITCOIN_UTIL) $(LIBBITCOIN_WALLET)
311316
endif
312317
if ENABLE_ZMQ
313-
qt_bitcoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
318+
bitcoin_qt_common_ldadd += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
314319
endif
315-
qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) \
320+
bitcoin_qt_common_ldadd += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) \
316321
$(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
317322
$(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
318-
qt_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
319-
qt_bitcoin_qt_LIBTOOLFLAGS = $(AM_LIBTOOLFLAGS) --tag CXX
323+
bitcoin_qt_common_ldflags = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
324+
bitcoin_qt_common_libtoolflags = $(AM_LIBTOOLFLAGS) --tag CXX
325+
326+
qt_bitcoin_qt_CPPFLAGS = $(bitcoin_qt_common_cppflags)
327+
qt_bitcoin_qt_CXXFLAGS = $(bitcoin_qt_common_cxxflags)
328+
qt_bitcoin_qt_SOURCES = $(bitcoin_qt_common_sources)
329+
qt_bitcoin_qt_LDADD = $(bitcoin_qt_common_ldadd)
330+
qt_bitcoin_qt_LDFLAGS = $(bitcoin_qt_common_ldflags)
331+
qt_bitcoin_qt_LIBTOOLFLAGS = $(bitcoin_qt_common_libtoolflags)
332+
333+
bitcoin_gui_CPPFLAGS = $(bitcoin_qt_common_cppflags)
334+
bitcoin_gui_CXXFLAGS = $(bitcoin_qt_common_cxxflags)
335+
bitcoin_gui_SOURCES = $(bitcoin_qt_common_sources)
336+
bitcoin_gui_LDADD = $(bitcoin_qt_common_ldadd)
337+
bitcoin_gui_LDFLAGS = $(bitcoin_qt_common_ldflags)
338+
bitcoin_gui_LIBTOOLFLAGS = $(bitcoin_qt_common_libtoolflags)
320339

321340
#locale/foo.ts -> locale/foo.qm
322341
QT_QM=$(QT_TS:.ts=.qm)

0 commit comments

Comments
 (0)