Skip to content

Commit

Permalink
Merge bitcoin#18677: Multiprocess build support
Browse files Browse the repository at this point in the history
e2bab2a multiprocess: add multiprocess travis configuration (Russell Yanofsky)
603fd6a depends: add MULTIPROCESS depends option (Russell Yanofsky)
5d1377b build: multiprocess autotools changes (Russell Yanofsky)

Pull request description:

  This PR is part of the [process separation project](https://github.com/bitcoin/bitcoin/projects/10).

  ---

  This PR consists of build changes only. It adds an `--enable-multiprocess` autoconf option (off by default and marked experimental), that builds new `bitcoin-node` and `bitcoin-gui` binaries. These currently function the same as existing `bitcoind` and `bitcoin-qt` binaries, but are extended in bitcoin#10102 with IPC features to execute node, wallet, and gui functions in separate processes.

  In addition to adding the `--enable-multiprocess` config flag, it also adds a depends package and autoconf rules to build with the [libmultiprocess](https://github.com/chaincodelabs/libmultiprocess) library, and it adds new travis configuration to exercise the build code and run functional tests with the new binaries.

  The changes in this PR were originally part of bitcoin#10102 but were moved into bitcoin#16367 to be able to develop and review the multiprocess build changes independently of the code changes. bitcoin#16367 was briefly merged and then reverted in bitcoin#18588. Only change since bitcoin#16367 has been dropping the `native_boost.mk` depends package which was pointed out to be no longer necessary in bitcoin#16367 (comment) and bitcoin#18588 (review)

ACKs for top commit:
  practicalswift:
    ACK e2bab2a
  Sjors:
    tACK e2bab2a on macOS 10.15.4
  hebasto:
    ACK e2bab2a, tested on Linux Mint 19.3 (x86_64):

Tree-SHA512: b5a76eab5abf63d9d8b6d628cbdff4cc1888eef15cafa0a5d56369e2f9d02595fed623f4b74b2cf2830c42c05a774f0943e700f9c768a82d9d348cad199e135c
  • Loading branch information
fanquake authored and vijaydasmp committed Nov 20, 2023
1 parent 2406fc3 commit e1339a4
Show file tree
Hide file tree
Showing 21 changed files with 275 additions and 44 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ reset-files.bash
src/dash
src/dashd
src/dash-cli
src/dash-gui
src/dash-node
src/dash-tx
src/dash-wallet
src/test/fuzz/*
Expand Down
7 changes: 7 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,13 @@ after_success:
name: 'x86_64 Linux [GOAL: install] [focal] [no depends, only system libs, sanitizers: address/leak (ASan + LSan) + undefined (UBSan) + integer]'
env: >-
FILE_ENV="./ci/test/00_setup_env_native_asan.sh"
- stage: test

name: 'x86_64 Linux [GOAL: install] [focal] [multiprocess]'
if: type != pull_request OR commit_message =~ /depends:|multiprocess:/ # Skip on non-depends, non-multiprocess PRs
env: >-
FILE_ENV="./ci/test/00_setup_env_native_multiprocess.sh"
- stage: test
name: 'x86_64 Linux [GOAL: install] [focal] [no wallet]'
Expand Down
1 change: 1 addition & 0 deletions ci/test/00_setup_env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export RUN_UNIT_TESTS=${RUN_UNIT_TESTS:-true}
export RUN_INTEGRATION_TESTS=${RUN_INTEGRATION_TESTS:-true}
export RUN_SECURITY_TESTS=${RUN_SECURITY_TESTS:-false}
export TEST_PREVIOUS_RELEASES=${TEST_PREVIOUS_RELEASES:-false}
export TEST_RUNNER_ENV=${TEST_RUNNER_ENV:-}
export RUN_FUZZ_TESTS=${RUN_FUZZ_TESTS:-false}
export RUN_SYMBOL_TESTS=${RUN_SYMBOL_TESTS:-true}
export CONTAINER_NAME=${CONTAINER_NAME:-ci_unnamed}
Expand Down
14 changes: 14 additions & 0 deletions ci/test/00_setup_env_native_multiprocess.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash
#
# Copyright (c) 2020 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

export LC_ALL=C.UTF-8

export CONTAINER_NAME=ci_native_multiprocess
export PACKAGES="cmake python3"
export DEP_OPTS="MULTIPROCESS=1"
export GOAL="install"
export BITCOIN_CONFIG=""
export TEST_RUNNER_ENV="BITCOIND=bitcoin-node"
64 changes: 64 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,25 @@ AC_ARG_ENABLE([zmq],
[use_zmq=$enableval],
[use_zmq=yes])

AC_ARG_WITH([libmultiprocess],
[AS_HELP_STRING([--with-libmultiprocess=yes|no|auto],
[Build with libmultiprocess library. (default: auto, i.e. detect with pkg-config)])],
[with_libmultiprocess=$withval],
[with_libmultiprocess=auto])

AC_ARG_WITH([mpgen],
[AS_HELP_STRING([--with-mpgen=yes|no|auto|PREFIX],
[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)])],
[with_mpgen=$withval],
[with_mpgen=auto])

AC_ARG_ENABLE([multiprocess],
[AS_HELP_STRING([--enable-multiprocess],
[build multiprocess dash-node, dash-wallet, and dash-gui executables in addition to monolithic dashd and dash-qt executables. Requires libmultiprocess library. Experimental (default is no)])],
[enable_multiprocess=$enableval],
[enable_multiprocess=no])


AC_ARG_ENABLE(man,
[AS_HELP_STRING([--disable-man],
[do not install man pages (default is to install)])],,
Expand Down Expand Up @@ -1542,6 +1561,50 @@ AC_CHECK_HEADER([gmp.h],, AC_MSG_ERROR(libgmp headers missing))
AC_CHECK_LIB([gmp], [__gmpz_init],GMP_LIBS=-lgmp, AC_MSG_ERROR(libgmp missing))

AC_MSG_CHECKING([whether to build dashd])
dnl libmultiprocess library check

libmultiprocess_found=no
if test "x$with_libmultiprocess" = xyes || test "x$with_libmultiprocess" = xauto; then
if test "x$use_pkgconfig" = xyes; then
m4_ifdef([PKG_CHECK_MODULES], [PKG_CHECK_MODULES([LIBMULTIPROCESS], [libmultiprocess], [
libmultiprocess_found=yes;
libmultiprocess_prefix=`$PKG_CONFIG --variable=prefix libmultiprocess`;
], [true])])
fi
elif test "x$with_libmultiprocess" != xno; then
AC_MSG_ERROR([--with-libmultiprocess=$with_libmultiprocess value is not yes, auto, or no])
fi
AC_SUBST(LIBMULTIPROCESS_CFLAGS)
AC_SUBST(LIBMULTIPROCESS_LIBS)

dnl Enable multiprocess check

if test "x$enable_multiprocess" = xyes; then
if test "x$libmultiprocess_found" != xyes; then
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.])
fi
build_multiprocess=yes
elif test "x$enable_multiprocess" = xauto; then
build_multiprocess=$libmultiprocess_found
else
build_multiprocess=no
fi

AM_CONDITIONAL([BUILD_MULTIPROCESS],[test "x$build_multiprocess" = xyes])
AM_CONDITIONAL([BUILD_BITCOIN_NODE], [test "x$build_multiprocess" = xyes])
AM_CONDITIONAL([BUILD_BITCOIN_GUI], [test "x$build_multiprocess" = xyes])

dnl codegen tools check

if test x$build_multiprocess != xno; then
if test "x$with_mpgen" = xyes || test "x$with_mpgen" = xauto; then
MPGEN_PREFIX="$libmultiprocess_prefix"
elif test "x$with_mpgen" != xno; then
MPGEN_PREFIX="$with_mpgen";
fi
AC_SUBST(MPGEN_PREFIX)
fi

AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes])
AC_MSG_RESULT($build_bitcoind)

Expand Down Expand Up @@ -1886,6 +1949,7 @@ esac

echo
echo "Options used to compile and link:"
echo " multiprocess = $build_multiprocess"
echo " with wallet = $enable_wallet"
echo " with gui / qt = $bitcoin_enable_qt"
if test "x$enable_wallet" != "xno"; then
Expand Down
8 changes: 8 additions & 0 deletions depends/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ NO_WALLET ?=
NO_ZMQ ?=
NO_UPNP ?=
NO_NATPMP ?=
MULTIPROCESS ?=
FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources

BUILD = $(shell ./config.guess)
Expand Down Expand Up @@ -148,6 +149,7 @@ upnp_packages_$(NO_UPNP) = $(upnp_packages)
natpmp_packages_$(NO_NATPMP) = $(natpmp_packages)

zmq_packages_$(NO_ZMQ) = $(zmq_packages)
multiprocess_packages_$(MULTIPROCESS) = $(multiprocess_packages)

packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(qt_packages_) $(wallet_packages_) $(upnp_packages_) $(natpmp_packages_)
native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages)
Expand All @@ -156,6 +158,11 @@ ifneq ($(zmq_packages_),)
packages += $(zmq_packages)
endif

ifeq ($(multiprocess_packages_),)
packages += $(multiprocess_packages)
native_packages += $(multiprocess_native_packages)
endif

all_packages = $(packages) $(native_packages)

meta_depends = Makefile funcs.mk builders/default.mk hosts/default.mk hosts/$(host_os).mk builders/$(build_os).mk
Expand Down Expand Up @@ -220,6 +227,7 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_
-e 's|@no_wallet@|$(NO_WALLET)|' \
-e 's|@no_upnp@|$(NO_UPNP)|' \
-e 's|@no_natpmp@|$(NO_NATPMP)|' \
-e 's|@multiprocess@|$(MULTIPROCESS)|' \
-e 's|@debug@|$(DEBUG)|' \
$< > $@
touch $@
Expand Down
1 change: 1 addition & 0 deletions depends/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ The following can be set when running make: `make FOO=bar`
- `NO_BDB`: Don't download/build/cache BerkeleyDB
- `NO_SQLITE`: Don't download/build/cache SQLite
- `NO_UPNP`: Don't download/build/cache packages needed for enabling UPnP
- `MULTIPROCESS`: build libmultiprocess (experimental, requires cmake)
- `NO_NATPMP`: Don't download/build/cache packages needed for enabling NAT-PMP
- `DEBUG`: Disable some optimizations and enable more runtime checking
- `HOST_ID_SALT`: Optional salt to use when generating host package ids
Expand Down
7 changes: 7 additions & 0 deletions depends/config.site.in
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ fi
if test -z $with_qt_bindir; then
with_qt_bindir=$depends_prefix/native/bin
fi
if test -z $with_mpgen && test -n "@multiprocess@"; then
with_mpgen=$depends_prefix/native
fi

if test -z $with_qrencode && test -n "@no_qr@"; then
with_qrencode=no
Expand All @@ -35,6 +38,10 @@ if test -z $enable_wallet && test -n "@no_wallet@"; then
enable_wallet=no
fi

if test -z $enable_multiprocess && test -n "@multiprocess@"; then
enable_multiprocess=yes
fi

if test -z $with_miniupnpc && test -n "@no_upnp@"; then
with_miniupnpc=no
fi
Expand Down
11 changes: 10 additions & 1 deletion depends/funcs.mk
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,11 @@ $(1)_config_env+=$($(1)_config_env_$(host_arch)_$(host_os)) $($(1)_config_env_$(

$(1)_config_env+=PKG_CONFIG_LIBDIR=$($($(1)_type)_prefix)/lib/pkgconfig
$(1)_config_env+=PKG_CONFIG_PATH=$($($(1)_type)_prefix)/share/pkgconfig
$(1)_config_env+=CMAKE_MODULE_PATH=$($($(1)_type)_prefix)/lib/cmake
$(1)_config_env+=PATH=$(build_prefix)/bin:$(PATH)
$(1)_build_env+=PATH=$(build_prefix)/bin:$(PATH)
$(1)_stage_env+=PATH=$(build_prefix)/bin:$(PATH)
$(1)_autoconf=./configure --host=$($($(1)_type)_host) --prefix=$($($(1)_type)_prefix) $$($(1)_config_opts) CC="$$($(1)_cc)" CXX="$$($(1)_cxx)"

ifneq ($($(1)_nm),)
$(1)_autoconf += NM="$$($(1)_nm)"
endif
Expand All @@ -164,6 +164,15 @@ endif
ifneq ($($(1)_ldflags),)
$(1)_autoconf += LDFLAGS="$$($(1)_ldflags)"
endif

$(1)_cmake=cmake -DCMAKE_INSTALL_PREFIX=$($($(1)_type)_prefix)
ifneq ($($(1)_type),build)
ifneq ($(host),$(build))
$(1)_cmake += -DCMAKE_SYSTEM_NAME=$($(host_os)_cmake_system) -DCMAKE_SYSROOT=$(host_prefix)
$(1)_cmake += -DCMAKE_C_COMPILER_TARGET=$(host) -DCMAKE_C_COMPILER=$(firstword $($($(1)_type)_CC)) -DCMAKE_C_FLAGS="$(wordlist 2,1000,$($($(1)_type)_CC))"
$(1)_cmake += -DCMAKE_CXX_COMPILER_TARGET=$(host) -DCMAKE_CXX_COMPILER=$(firstword $($($(1)_type)_CXX)) -DCMAKE_CXX_FLAGS="$(wordlist 2,1000,$($($(1)_type)_CXX))"
endif
endif
endef

define int_add_cmds
Expand Down
1 change: 1 addition & 0 deletions depends/hosts/android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ android_CXX=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)$(ANDROID_API_LEVEL)-clang++
android_CC=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)$(ANDROID_API_LEVEL)-clang
android_RANLIB=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)-ranlib
endif
android_cmake_system=Android
1 change: 1 addition & 0 deletions depends/hosts/darwin.mk
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,4 @@ darwin_release_CXXFLAGS=$(darwin_release_CFLAGS)

darwin_debug_CFLAGS=-O1
darwin_debug_CXXFLAGS=$(darwin_debug_CFLAGS)
darwin_cmake_system=Darwin
1 change: 1 addition & 0 deletions depends/hosts/linux.mk
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ i686_linux_CXX=$(default_host_CXX) -m32
x86_64_linux_CC=$(default_host_CC) -m64
x86_64_linux_CXX=$(default_host_CXX) -m64
endif
linux_cmake_system=Linux
2 changes: 2 additions & 0 deletions depends/hosts/mingw32.mk
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ mingw32_debug_CFLAGS=-O1
mingw32_debug_CXXFLAGS=$(mingw32_debug_CFLAGS)

mingw32_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC

mingw_cmake_system=Windows
18 changes: 18 additions & 0 deletions depends/packages/capnp.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package=capnp
$(package)_version=$(native_$(package)_version)
$(package)_download_path=$(native_$(package)_download_path)
$(package)_file_name=$(native_$(package)_file_name)
$(package)_sha256_hash=$(native_$(package)_sha256_hash)
$(package)_dependencies=native_$(package)

define $(package)_config_cmds
$($(package)_autoconf) --with-external-capnp
endef

define $(package)_build_cmds
$(MAKE)
endef

define $(package)_stage_cmds
$(MAKE) DESTDIR=$($(package)_staging_dir) install
endef
18 changes: 18 additions & 0 deletions depends/packages/libmultiprocess.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package=libmultiprocess
$(package)_version=$(native_$(package)_version)
$(package)_download_path=$(native_$(package)_download_path)
$(package)_file_name=$(native_$(package)_file_name)
$(package)_sha256_hash=$(native_$(package)_sha256_hash)
$(package)_dependencies=native_$(package) boost capnp

define $(package)_config_cmds
$($(package)_cmake)
endef

define $(package)_build_cmds
$(MAKE)
endef

define $(package)_stage_cmds
$(MAKE) DESTDIR=$($(package)_staging_dir) install
endef
18 changes: 18 additions & 0 deletions depends/packages/native_capnp.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package=native_capnp
$(package)_version=0.7.0
$(package)_download_path=https://capnproto.org/
$(package)_download_file=capnproto-c++-$($(package)_version).tar.gz
$(package)_file_name=capnproto-cxx-$($(package)_version).tar.gz
$(package)_sha256_hash=c9a4c0bd88123064d483ab46ecee777f14d933359e23bff6fb4f4dbd28b4cd41

define $(package)_config_cmds
$($(package)_autoconf)
endef

define $(package)_build_cmds
$(MAKE)
endef

define $(package)_stage_cmds
$(MAKE) DESTDIR=$($(package)_staging_dir) install
endef
18 changes: 18 additions & 0 deletions depends/packages/native_libmultiprocess.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package=native_libmultiprocess
$(package)_version=5741d750a04e644a03336090d8979c6d033e32c0
$(package)_download_path=https://github.com/chaincodelabs/libmultiprocess/archive
$(package)_file_name=$($(package)_version).tar.gz
$(package)_sha256_hash=ac848db49a6ed53e423c62d54bd87f1f08cbb0326254a8667e10bbfe5bf032a4
$(package)_dependencies=native_capnp

define $(package)_config_cmds
$($(package)_cmake)
endef

define $(package)_build_cmds
$(MAKE)
endef

define $(package)_stage_cmds
$(MAKE) DESTDIR=$($(package)_staging_dir) install
endef
3 changes: 3 additions & 0 deletions depends/packages/packages.mk
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ natpmp_packages=libnatpmp
darwin_native_packages = native_ds_store native_mac_alias

$(host_arch)_$(host_os)_native_packages += native_b2
multiprocess_packages = libmultiprocess capnp
multiprocess_native_packages = native_libmultiprocess native_capnp


ifneq ($(build_os),darwin)
darwin_native_packages += native_cctools native_libtapi native_libdmg-hfsplus
Expand Down
35 changes: 35 additions & 0 deletions doc/multiprocess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Multiprocess Bitcoin

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.

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

## Next steps

Specific next steps after [#10102](https://github.com/bitcoin/bitcoin/pull/10102) will be:

- [ ] 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.
- [ ] Adding `-server` and `-rpcbind` options to the `bitcoin-wallet` executable so wallet processes can handle RPC requests directly without going through the node.
- [ ] 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/.
- [ ] Adding sandbox features, restricting subprocess access to resources and data. See [https://eklitzke.org/multiprocess-bitcoin](https://eklitzke.org/multiprocess-bitcoin).

## Debugging

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.

## Installation

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:

```
cd <BITCOIN_SOURCE_DIRECTORY>
make -C depends NO_QT=1 MULTIPROCESS=1
./configure --prefix=$PWD/depends/x86_64-pc-linux-gnu
make
src/bitcoin-node -regtest -printtoconsole -debug=ipc
BITCOIND=bitcoin-node test/functional/test_runner.py
```

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

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

0 comments on commit e1339a4

Please sign in to comment.