github.com/trezor/blockbook@v0.4.1-0.20240328132726-e9a08582ee2c/docs/build.md (about)

     1  # Blockbook Build Guide
     2  
     3  ## Setting up your development environment
     4  
     5  Supported environment to develop Blockbook is Linux. Although it is possible build and run Blockbook on macOS
     6  or Windows our build process is not prepared for it. But you can still build Blockbook [manually](#manual-build).
     7  
     8  The only dependency required to build Blockbook is Docker. You can see how to install Docker [here](https://docs.docker.com/install/linux/docker-ce/debian/).
     9  Manual build require additional dependencies that are described in appropriate section.
    10  
    11  ## Build in Docker environment
    12  
    13  All build operations run in Docker container in order to keep build environment isolated. Makefile in root of repository
    14  defines few targets used for building, testing and packaging of Blockbook. With Docker image definitions and Debian
    15  package templates in *build/docker* and *build/templates* respectively, they are only inputs that make build process.
    16  
    17  Docker build images are created at first execution of Makefile and that information is persisted. (Actually there are
    18  created two files in repository – .bin-image and .deb-image – that are used as tags.) Sometimes it is necessary to
    19  rebuild Docker images, it is possible by executing `make build-images`.
    20  
    21  ### Building binary
    22  
    23  Just run `make` and that is it. Output binary is stored in *build* directory. Note that although Blockbook is Go application
    24  it is dynamically linked with RocksDB dependencies and ZeroMQ. Therefore operating system where Blockbook will be
    25  executed still need that dependencies installed. See [Manual build](#manual-build) instructions below or install
    26  Blockbook via Debian packages.
    27  
    28  ### Building debug binary
    29  
    30  Standard binary contains no debug symbols. Execute `make build-debug` to get binary for debugging.
    31  
    32  ### Testing
    33  
    34  How to execute tests is described in separate document [here](/docs/testing.md).
    35  
    36  ### Building Debian packages
    37  
    38  Blockbook and particular coin back-end are usually deployed together. They are defined in same place as well.
    39  So typical way to build Debian packages is build Blockbook and back-end deb packages by single command. But it is not
    40  mandatory, of course.
    41  
    42  > Early releases of Blockbook weren't so friendly for extending. One had to define back-end package, Blockbook package,
    43  > back-end configuration and Blockbook configuration as well. There were many options that were duplicated across
    44  > configuration files and therefore error prone.
    45  >
    46  > Now, all configuration options and also build options for both Blockbook and back-end are defined in single JSON
    47  > file and all stuff required during build is generated dynamically.
    48  
    49  Makefile targets follow simple pattern, there are a few prefixes that define what to build.
    50  
    51  * *deb-blockbook-<coin>* – Build Blockbook package for given coin.
    52  
    53  * *deb-backend-<coin>* – Build back-end package for given coin.
    54  
    55  * *deb-<coin>* – Build both Blockbook and back-end packages for given coin.
    56  
    57  * *all-<coin>* – Similar to deb-<coin> but clean repository and rebuild Docker image before package build. It is useful
    58    for production deployment.
    59  
    60  * *all* – Build both Blockbook and back-end packages for all coins.
    61  
    62  Which coins are possible to build is defined in *configs/coins*. Each coin has to have JSON config file there.
    63  
    64  For example we want to build some packages for Bitcoin and Bitcoin Testnet.
    65  
    66  ```bash
    67  # make all-bitcoin deb-blockbook-bitcoin_testnet
    68  ...
    69  # ls build/*.deb
    70  build/backend-bitcoin_0.21.0-satoshilabs-1_amd64.deb  build/blockbook-bitcoin_0.3.5_amd64.deb  build/blockbook-bitcoin-testnet_0.3.5_amd64.deb
    71  ```
    72  
    73  We have built one back-end package, for Bitcoin, and two Blockbook packages, for Bitcoin and Bitcoin Testnet. The `all-bitcoin` initially cleaned the build directory and rebuilt the Docker build image.
    74  
    75  ### Extra variables
    76  
    77  There are few variables that can be passed to `make` in order to modify build process:
    78  
    79  `BASE_IMAGE`: Specifies the base image of the Docker build image. By default, it chooses the same Linux distro as the host machine but you can override it this way `make BASE_IMAGE=debian:10 all-bitcoin` to make a build for Debian 10.
    80  
    81  *Please be aware that we are currently running our Blockbooks on Debian 11 and do not offer support with running it on other distros.*
    82  
    83  `NO_CACHE`: Common behaviour of Docker image build is that build steps are cached and next time they are executed much faster.
    84  Although this is a good idea, when something went wrong you will need to override this behaviour somehow. Execute this
    85  command: `make NO_CACHE=true all-bitcoin`.
    86  
    87  `TCMALLOC`: RocksDB, the storage engine used by Blockbook, allows to use alternative memory allocators. Use the `TCMALLOC` variable to specify Google's TCMalloc allocator `make TCMALLOC=true all-bitcoin`. To run Blockbook built with TCMalloc, the library must be installed on the target server, for example by `sudo apt-get install google-perftools`.
    88  
    89  `PORTABLE`: By default, the RocksDB binaries shipped with Blockbook are optimized for the platform you're compiling on (-march=native or the equivalent). If you want to build a portable binary, use `make PORTABLE=1 all-bitcoin`.
    90  
    91  ### Naming conventions and versioning
    92  
    93  All configuration keys described below are in coin definition file in *configs/coins*.
    94  
    95  **install and data directories**
    96  
    97  Both Blockbook and back-end have separated install and data directories. They use common preffix and are defined in
    98  *configs/environ.json* and all templates use them.
    99  
   100  * back-end install directory is */opt/coins/nodes/<coin>*.
   101  * back-end data directory is */opt/coins/data/<coin>/backend*.
   102  * Blockbook install directory is */opt/coins/blockbook/<coin>*.
   103  * Blockbook data directory is */opt/coins/data/<coin>/blockbook*.
   104  
   105  *coin* used above is defined in *coin.alias* in coin definition file.
   106  
   107  **package names**
   108  
   109  Package names are defined in *backend.package_name* and *blockbook.package_name* in coin definition file. We use
   110  simple pattern *<prefix>-<coin>* to name packages where *prefix* is either *blockbook* or *backend* and
   111  *coin* is made similarly to *coin.alias*. We use convention that coin name uses lowercase characters and dash '-' as
   112  a word delimiter. Testnet versions of coins must have *-testnet* suffix. That differs from *coin.alias* because
   113  underscore has a special meaning in Debian packaging. For example there are packages *backend-bitcoin* and
   114  *blockbook-bitcoin-testnet*.
   115  
   116  **user names**
   117  
   118  User names are defined in *backend.system_user* and *blockbook.system_user* in coin definition file. We follow common
   119  Linux conventions, user names use lowercase characters and dash '-' as a word delimiter.
   120  
   121  Back-end user name use coin name only, including testnet services. For example there is *bitcoin* user for both
   122  *backend-bitcoin* and *backend-bitcoin-testnet* packages.
   123  
   124  Blockbook user name has *blockbook-* prefix and coin name (made same as back-end version). For example there is
   125  *blockbook-bitcoin*  user for both *blockbook-bitcoin* and *blockbook-bitcoin-testnet* packages.
   126  
   127  **back-end versioning**
   128  
   129  Since we have to distinguish version of coin distribution and version of our configuration we follow standard Debian
   130  package versioning rules (for details see
   131  [Debian policy](https://www.debian.org/doc/debian-policy/ch-controlfields.html#version)). There is upstream version
   132  and revision both defined in coin definition file in *backend.version* and *backend.package_revision*, respectively.
   133  
   134  **blockbook versioning**
   135  
   136  Blockbook versioning is much simpler. There is only one version defined in *configs/environ.json*.
   137  
   138  ### Back-end building
   139  
   140  Because we don't keep back-end archives inside our repository we download them during build process. Build steps
   141  are these: download, verify and extract archive, prepare distribution and make package.
   142  
   143  All configuration keys described below are in coin definition file in *configs/coins*.
   144  
   145  **download archive**
   146  
   147  URL from where is archive downloaded is defined in *backend.binary_url*.
   148  
   149  **verify archive**
   150  
   151  There are three different approaches how is archive verification done. Some projects use PGP sign of archive, some
   152  have signed sha256 sums and some don't care about verification at all. So there is option *backend.verification_type* that
   153  could be *gpg*, *gpg-sha256* or *sha256* and chooses particular method.
   154  
   155  *gpg* type require file with digital sign and maintainer's public key imported in Docker build image (see below). Sign
   156  file is downloaded from URL defined in *backend.verification_source*. Than is passed to gpg in order to verify archive.
   157  
   158  *gpg-sha256* type require signed checksum file and maintainer's public key imported in Docker build image (see below).
   159  Checksum file is downloaded from URL defined in *backend.verification_source*. Then is verified by gpg and passed to
   160  sha256sum in order to verify archive.
   161  
   162  *sha256* type is used for coins that don't support verification at all. In *backend.verification_source* is defined
   163  hexadecimal string that is compared with output of sha256sum. Although this solution is not secure, it avoid download
   164  errors and other surprises at least.
   165  
   166  *gpg* and *gpg-sha256* types require maintainer's public key imported in Docker build image. It is not expected that
   167  maintainer's key will change requently while sing or checksum files are changed every release, so it is ideal to
   168  store maintainer's key within image definition. Public keys are stored in *build/docker/deb/gpg-keys* directory. Docker
   169  image must be rebuilt by calling `make build-images`.
   170  
   171  **extract archive**
   172  
   173  Extraction command is defined in *backend.extract_command*. Content of archive must be extracted to `./backend` directory.
   174  See bitcoin.json and vertcoin.json for different approaches.
   175  
   176  **prepare distribution**
   177  
   178  There are two steps in this stage – exclude unnecessary files and generate configuration.
   179  
   180  Some files are not required for server deployment, some binaries have unnecessary dependencies, so it is good idea to
   181  extract these files from output package. Files to extract are listed in *backend.exclude_files*. Note that paths are
   182  relative to *backend* directory where archive is extracted.
   183  
   184  Configuration is described in [config.md](/docs/config.md).
   185  
   186  ## Manual build
   187  
   188  Instructions below are focused on Debian 11 on amd64. If you want to use another Linux distribution or operating system
   189  like macOS or Windows, please adapt the instructions to your target system.
   190  
   191  Setup go environment (use newer version of go as available)
   192  
   193  ```
   194  wget https://golang.org/dl/go1.21.4.linux-amd64.tar.gz && tar xf go1.21.4.linux-amd64.tar.gz
   195  sudo mv go /opt/go
   196  sudo ln -s /opt/go/bin/go /usr/bin/go
   197  # see `go help gopath` for details
   198  mkdir $HOME/go
   199  export GOPATH=$HOME/go
   200  export PATH=$PATH:$GOPATH/bin
   201  ```
   202  
   203  Install RocksDB: https://github.com/facebook/rocksdb/blob/master/INSTALL.md
   204  and compile the static_lib and tools. Optionally, consider adding `PORTABLE=1` before the
   205  make command to create a portable binary.
   206  
   207  ```
   208  sudo apt-get update && sudo apt-get install -y \
   209      build-essential git wget pkg-config libzmq3-dev libgflags-dev libsnappy-dev zlib1g-dev libzstd-dev  libbz2-dev liblz4-dev
   210  git clone https://github.com/facebook/rocksdb.git
   211  cd rocksdb
   212  git checkout v7.5.3
   213  CFLAGS=-fPIC CXXFLAGS=-fPIC make release
   214  ```
   215  
   216  Setup variables for grocksdb
   217  
   218  ```
   219  export CGO_CFLAGS="-I/path/to/rocksdb/include"
   220  export CGO_LDFLAGS="-L/path/to/rocksdb -lrocksdb -lstdc++ -lm -lz -ldl -lbz2 -lsnappy -llz4 -lzstd"
   221  ```
   222  
   223  Install ZeroMQ: https://github.com/zeromq/libzmq
   224  
   225  ```
   226  git clone https://github.com/zeromq/libzmq
   227  cd libzmq
   228  ./autogen.sh
   229  ./configure
   230  make
   231  sudo make install
   232  ```
   233  
   234  Get blockbook sources, install dependencies, build:
   235  
   236  ```
   237  cd $GOPATH/src
   238  git clone https://github.com/trezor/blockbook.git
   239  cd blockbook
   240  go build
   241  ```
   242  
   243  ### Example command
   244  
   245  Blockbook require full node daemon as its back-end. You are responsible for proper installation. Port numbers and
   246  daemon configuration are defined in *configs/coins* and *build/templates/backend/config* directories. You should use
   247  specific installation process for particular coin you want run (e.g. https://bitcoin.org/en/full-node#other-linux-distributions for Bitcoin).
   248  
   249  When you have running back-end daemon you can start Blockbook. It is highly recommended use ports described in [ports.md](/docs/ports.md)
   250  for both Blockbook and back-end daemon. You can use *contrib/scripts/build-blockchaincfg.sh* that will generate
   251  Blockbook's blockchain configuration from our coin definition files.
   252  
   253  Also, check that your operating system open files limit is set to high enough value - recommended is at least 20000.
   254  
   255  Example for Bitcoin:
   256  ```
   257  ./contrib/scripts/build-blockchaincfg.sh <coin>
   258  ./blockbook -sync -blockchaincfg=build/blockchaincfg.json -internal=:9030 -public=:9130 -certfile=server/testcert -logtostderr
   259  ```
   260  
   261  This command starts Blockbook with parallel synchronization and providing HTTP and Socket.IO interface, with database
   262  in local directory *data* and established ZeroMQ and RPC connections to back-end daemon specified in configuration
   263  file passed to *-blockchaincfg* option.
   264  
   265  Blockbook logs to stderr (option *-logtostderr*) or to directory specified by parameter *-log_dir* . Verbosity of logs can be tuned
   266  by command line parameters *-v* and *-vmodule*, for details see https://godoc.org/github.com/golang/glog.
   267  
   268  You can check that Blockbook is running by simple HTTP request: `curl https://localhost:9130`. Returned data is JSON with some
   269  run-time information. If the port is closed, Blockbook is syncing data.