[[set_up_a_lightning_node]]
== Lightning Node Software

As we've seen in previous chapters, a Lightning node is a computer system that participates in the Lightning Network. The Lightning Network is not a product or company - it is a set of open standards that define a baseline for interoperability. As such, Lightning node software has been built by a variety of companies and community groups. The vast majority of Lightning software is _open source_, meaning that the source code is open and licensed in such as way as to enable collaboration, sharing and community participation in the development process. Similarly, the Lightning node implementations we will show in this chapter are all open source and collaborative developed.

Unlike Bitcoin, where the standard is defined by a _reference implementation_ in software (Bitcoin Core), in Lightning the standard is defined by a series of standards documents called _Basis of Lightning Technology (BOLT)_, found at the lightning-rfc repository at:

https://github.com/lightningnetwork/lightning-rfc

There is no reference implementation of the Lightning Network, but there are several competing, BOLT-compliant and interoperable implementations developed by different teams and organizations. The teams that develop software for the Lightning Network also contribute in the development and evolution of the BOLTs.

Another major difference between Lightning node software and Bitcoin node software is that Lightning nodes do not need to operate in "lockstep" with consensus rules, and can have extended functionality beyond the baseline of the BOLTS. Therefore, different teams may pursue various experimental features that, if successful and broadly deployed, may become part of the BOLTs later.

In this chapter you will learn how to set up each of the software packages for the most popular Lightning node implementations. We've presented them in alphabetical order to emphasize that we generally do not prefer or recommend one over the other. Each has its strengths and weaknesses and choosing one will depend on a variety of factors. Since they are developed in different programming languages (e.g. Go, C, etc.) your choice may also depend on your level of familiarity and expertise with a specific language and development toolset.

=== Lightning Development Environment

((("development environment", "setup")))If you're a developer, you will want to set up a development environment with all the tools, libraries, and support software for writing and running Lightning software. In this highly technical chapter, we'll walk through that process step-by-step. If the material becomes too dense (and you're not actually setting up a development environment) feel free to skip to the next chapter, which is less technical.

==== Using the command-line

The examples in this chapter, and more broadly in most of this book, use a command-line terminal. That means that you type commands into a terminal and receive text responses. Furthermore, the examples are demonstrated on an operating system based on the Linux kernel and GNU software system, specifically the latest long-term stable release of Ubuntu (Ubuntu 18.04 LTS). The majority of the examples can be replicated on other operating systems such as Windows or Mac OS, with small modifications to the commands. The biggest difference between operating systems is the _package manager_ which installs the various software libraries and pre-requisites. In the examples, we will use +apt+, which is the package manager for Ubuntu. In Mac OS, a common package manager used for open source development is Homebrew (command +brew+) found at https://brew.sh.

In most of the examples here, we will be building the software directly from the source code, which gives us the most power and control, but can be quite challenging. You may choose to use a docker container, pre-compiled package or other installation mechanism instead if you get stuck!

[TIP]
====
((("$ symbol")))((("shell commands")))((("terminal applications")))In many of the examples in this chapter we will be using the operating system's command-line interface (also known as a "shell"), accessed via a "terminal" application. The shell will display a prompt; you type a command; and the shell responds with some text and a new prompt for your next command. The prompt may look different on your system, but in the following examples it is denoted by a +$+ symbol. In the examples, when you see text after a +$+ symbol, don't type the +$+ symbol but type the command immediately following it, then press Enter to execute the command. In the examples, the lines below each command are the operating system's responses to that command. When you see the next +$+ prefix, you'll know it's a new command and you should repeat the process.
====

To keep things consistent, we use the +bash+ shell in all command-line examples. While other shells will behave in a similar way, and you will be able to run all the examples without it, some of the shell scripts are written specifically for the +bash+ shell and may require some changes or customization to run in another shell. For consistency, you can install the +bash+ shell on Windows and Mac OS, and it comes installed by default on most Linux systems.

==== Donwloading the book repository

All the code examples are available in the book's repository. The repository will be kept up-to-date, as much as possible, so you should always look for the latest version in the repository, instead of copying it from the printed book or ebook version of this test.

You can download the repository as a ZIP bundle by visiting +github.com/lnbook/lnbook+ and selecting the "Clone or Download" green button on the right.

Alternatively, you can use the +git+ command, to create a version-controlled clone of the repository on your local computer. Git is a distributed version control system that is used by most developers to collaborate on software development and track changes to software repositories. Donwload and install +git+ by following the instructions on https://git-scm.com/.


To make a local copy of the repository on your computer, run the git command as follows:

[git-clone-lnbook]
----
$ git clone git@github.com:lnbook/lnbook.git
----

You now have a complete copy of the book repository in a folder called +lnbook+. All subsequent examples will assume that you are running commands from that folder.

=== Docker Containers

Many developers use a _container_, which is a type of virtual machine, to install a pre-configured operating system and application with all the necessary dependencies. Much of the Lightning software can also be installed using a container system such as _Docker_ (command +docker+) found at https://docker.com. Container installations are a lot easier, especially for those who are not used to a command-line environment.

The book's repository contains a collection of docker containers that can be used to set up a consistent development environment to practice and replicate the examples on any system. Because the container is a complete operating system that runs with a consistent configuration, you can be sure that the examples will work on your computer and not worry about dependencies, library versions or differences in configuration.

Docker containers are often optimized to be small (less disk space). However, in this book we are using containers to _standardize_ the environment and make it consistent for all readers. Furthermore, these containers are not meant to be used to run services in the background. Instead, they are meant to be used to test the examples and learn by interacting with the software. For these reasons, the containers are quite large and come with a lot of development tools and utilities. Also, the containers are built on Ubuntu, instead of the Alpine distribution (more commonly used for Linux containers), as we want to work with a distribution that is familiar to many developers rather than one that is lightweight.

You can find the latest container definitions and build configurations in the book's repository under the +code/docker+ folder. Each container is in a separate folder beneath:

//// $ tree -F --charset=asciii  code
[docker-dir-list]
----
code
`-- docker/
    |-- bitcoind/
    |   |-- bashrc
    |   |-- bitcoind/
    |   |   |-- bitcoin.conf
    |   |   `-- keys/
    |   |       |-- demo_address.txt
    |   |       |-- demo_mnemonic.txt
    |   |       `-- demo_privkey.txt
    |   |-- bitcoind-entrypoint.sh
    |   |-- Dockerfile
    |   `-- mine.sh*
    |-- c-lightning/
    |   |-- bashrc
    |   |-- c-lightning-entrypoint.sh
    |   |-- Dockerfile
    |   |-- fund-c-lightning.sh
    |   |-- lightningd/
    |   |   `-- config
    |   |-- logtail.sh
    |   `-- wait-for-bitcoind.sh
    |-- eclair/
    |   |-- bashrc
    |   |-- Dockerfile
    |   |-- eclair/
    |   |   `-- eclair.conf
    |   |-- eclair-entrypoint.sh
    |   |-- logtail.sh
    |   `-- wait-for-bitcoind.sh
    |-- lnbook-app/
    |   |-- docker-compose.yml
    |   `-- setup-channels.sh
    `-- lnd/
        |-- bashrc
        |-- Dockerfile
        |-- fund-lnd.sh
        |-- lnd/
        |   `-- lnd.conf
        |-- lnd-entrypoint.sh
        |-- logtail.sh
        `-- wait-for-bitcoind.sh
----

==== Installing Docker

Before we begin, you should install the docker container system on your computer. Docker is an open system that is distributed for free as a _Community Edition_, for many different operating systems including Windows, Mac OS and Linux. The Windows and Mac versions are called _Docker Desktop_, which is GUI desktop application and command-line tools, and the Linux version is called _Docker Engine_, which is a server daemon and command-line tools. We will be using the command-line tools, which are identical across all platforms.

Go ahead and install Docker for your operating system by following the instructions to _"Get Docker"_ from the Docker website found here:

https://docs.docker.com/get-docker/

Select your operating system from the list, and follow the instructions to install.

[TIP]
====
If you install on Linux, follow the post-installation instructions to ensure you can run Docker as a regular user instead of root. Otherwise, you will need to prefix the +docker+ command with +sudo+, running it as root like: +sudo docker+.
====

Once you have Docker installed, you can test your installation by running the demo container +hello-world+, like this:

[docker-hello-world]
----
$ docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

[...]
----

==== Bitcoin Core and Regtest

Most of the Lightning node implementations need access to a full Bitcoin node in order to work.

Installing a full Bitcoin node and synching the Bitcoin blockchain is outside the scope of this book and is a relatively complex endeavor in itself. If you want to try it, refer to _Mastering Bitcoin_ (https://github.com/bitcoinbook/bitcoinbook), "Chapter 3: Bitcoin Core: The Reference Implementation" which discusses the installation and operation of a Bitcoin node.

A Bitcoin node can also be operated in _regtest_ mode, where the node creates a local simulated Bitcoin blockchain for testing purposes. In the following examples, we will be using regtest mode to allow us to demonstrate lightning without having to synchronize a Bitcoin node, or risk any funds.

The container for Bitcoin Core is +bitcoind+ that runs Bitcoin Core in regtest mode and mines a new block every 10 seconds. It's RPC port is exposed on port 18443 and accessible for RPC calls with the username +regtest+ and the password +regtest+. You can also access it with an interactive shell and run +bitcoin-cli+ commands locally.

Let's start by building and running the +bitcoind+ container. First, we use the +docker build+ command to build it:

----
$ cd code/docker
$ docker build -t lnbook/bitcoind bitcoind
Sending build context to Docker daemon  12.29kB
Step 1/25 : FROM ubuntu:18.04 AS bitcoind-base
 ---> c3c304cb4f22
Step 2/25 : RUN apt update && apt install -yqq 	curl gosu jq bash-completion

[...]

Step 25/25 : CMD ["/usr/local/bin/mine.sh"]
 ---> Using cache
 ---> 758051998e72
Successfully built 758051998e72
Successfully tagged lnbook/bitcoind:latest
----

Next, let's run the bitcoind container and have it mine some blocks. We use the +docker run+ command, with the flags for _interactive (i)_ and _terminal (t)_:

----
$ docker run -it lnbook/bitcoind
Starting bitcoind...
Bitcoin Core starting
bitcoind started
================================================
Importing demo private key
Bitcoin address:  2NBKgwSWY5qEmfN2Br4WtMDGuamjpuUc5q1
Private key:  cSaejkcWwU25jMweWEewRSsrVQq2FGTij1xjXv4x1XvxVRF1ZCr3
================================================

Mining 101 blocks to unlock some bitcoin
[
  "579311009cc4dcf9d4cc0bf720bf210bfb0b4950cdbda0670ff56f8856529b39",
 ...
  "33e0a6e811d6c49219ee848604cedceb0ab161485e1195b1f3576049e4d5deb7"
]
Mining 1 block every 10 seconds
[
  "5974aa6da1636013daeaf730b5772ae575104644b8d6fa034203d2bf9dc7a98b"
]
Balance: 100.00000000
----

As you can see, bitcoind starts up and mines 101 blocks to get the chain started. This is because under the bitcoin consensus rules, newly mined bitcoin is not spendable until 100 blocks have elapsed. By mining 101 blocks, we make the 1st block's coinbase spendable. After that initial mining activity, we mine a new block every 10 seconds, to keep the chain moving forward.

For now, there are no transactions. But we now have some test bitcoin that has been mined in the wallet and is available to spend. When we connect some Lightning nodes to this chain, we will send some bitcoin to their wallets so that we can open some Lightning channels between the Lightning nodes. 

=== c-lightning

C-lightning is a lightweight, highly customizable, and standard-compliant implementation of the Lightning Network protocol, developed by Blockstream as part of the Elements project. The project is open source and developed collaboratively on Github:

https://github.com/ElementsProject/lightning

==== Installing c-lightning from source code

The c-lightning developers have provided detailed instructions for building c-lightning from source code. We will be following the instructions here:

https://github.com/ElementsProject/lightning/blob/master/doc/INSTALL.md

==== Installing prerequisite libraries and packages

The first step, as is often the case, is the installation of pre-requisite libraries. We use the +apt+ package manager to install these:

----
$ sudo apt-get update

Get:1 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]
Hit:2 http://eu-north-1b.clouds.archive.ubuntu.com/ubuntu bionic InRelease
Get:3 http://eu-north-1b.clouds.archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]

[...]

Fetched 18.3 MB in 8s (2,180 kB/s)
Reading package lists... Done

$ sudo apt-get install -y \
  autoconf automake build-essential git libtool libgmp-dev \
  libsqlite3-dev python python3 python3-mako net-tools zlib1g-dev libsodium-dev \
  gettext

Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
  autotools-dev binutils binutils-common binutils-x86-64-linux-gnu cpp cpp-7 dpkg-dev fakeroot g++ g++-7 gcc gcc-7 gcc-7-base libalgorithm-diff-perl

 [...]

Setting up libgcc-7-dev:amd64 (7.4.0-1ubuntu1~18.04.1) ...
Setting up cpp-7 (7.4.0-1ubuntu1~18.04.1) ...
Setting up libsodium-dev:amd64 (1.0.16-2) ...
Setting up libstdc++-7-dev:amd64 (7.4.0-1ubuntu1~18.04.1) ...

[...]
$
----

After a few minutes and a lot of on-screen activity, you will have installed all the necessary packages and libraries. Many of these libraries are also used by other Lightning packages and for software development in general.

==== Copying the c-lightning source code

Next, we will copy the latest version of c-lightning from the source code repository. To do this, we will use the +git clone+ command, which clones a version-controlled copy onto your local machine, allowing you to keep it synchronized with subsequent changes without having to download the whole thing again:

----
$ git clone https://github.com/ElementsProject/lightning.git
Cloning into 'lightning'...
remote: Enumerating objects: 24, done.
remote: Counting objects: 100% (24/24), done.
remote: Compressing objects: 100% (22/22), done.
remote: Total 53192 (delta 5), reused 5 (delta 2), pack-reused 53168
Receiving objects: 100% (53192/53192), 29.59 MiB | 19.30 MiB/s, done.
Resolving deltas: 100% (39834/39834), done.

$ cd lightning

----

We now have a copy of c-lightning, cloned into the +lightning+ subfolder, and we have used the +cd+ (change directory) command to enter that subfolder.

Next, we use a set of _build scripts_ that are commonly available on many open source projects. These are +configure+ and +make+, and they allow us to:
* Select the build options and check necessary dependencies (+configure+).
* Build and install the executables and libraries (+make+).

Running the +configure+ with the +help+ option will show us all the options that we can set:

----
$ ./configure --help
Usage: ./configure [--reconfigure] [setting=value] [options]

Options include:
  --prefix= (default /usr/local)
    Prefix for make install
  --enable/disable-developer (default disable)
    Developer mode, good for testing
  --enable/disable-experimental-features (default disable)
    Enable experimental features
  --enable/disable-compat (default enable)
    Compatibility mode, good to disable to see if your software breaks
  --enable/disable-valgrind (default (autodetect))
    Run tests with Valgrind
  --enable/disable-static (default disable)
    Static link sqlite3, gmp and zlib libraries
  --enable/disable-address-sanitizer (default disable)
    Compile with address-sanitizer
----

We don't need to change any of the defaults for this example, so we run +configure+ again, without any options, to set the defaults:

----
$ ./configure

Compiling ccan/tools/configurator/configurator...done
checking for python3-mako... found
Making autoconf users comfortable... yes
checking for off_t is 32 bits... no
checking for __alignof__ support... yes

[...]

Setting COMPAT... 1
PYTEST not found
Setting STATIC... 0
Setting ASAN... 0
Setting TEST_NETWORK... regtest
$
----

Next, we use the +make+ command to build the libraries, components and executables of the c-lightning project. This part will take several minutes to complete and will use your computers CPU and disk aggressively, so expect some noise from the fans! Running make:

----
$ make

cc -DBINTOPKGLIBEXECDIR="\"../libexec/c-lightning\"" -Wall -Wundef -Wmis...

[...]

cc   -Og  ccan-asort.o ccan-autodata.o ccan-bitmap.o ccan-bitops.o ccan-...

----

If all goes well, you will see no +ERROR+ message stopping the execution of the above command. The c-lightning software package has been compiled from source and we are now ready to install the executable packages:

----
$ sudo make install

mkdir -p /usr/local/bin
mkdir -p /usr/local/libexec/c-lightning
mkdir -p /usr/local/libexec/c-lightning/plugins
mkdir -p /usr/local/share/man/man1
mkdir -p /usr/local/share/man/man5
mkdir -p /usr/local/share/man/man7
mkdir -p /usr/local/share/man/man8
mkdir -p /usr/local/share/doc/c-lightning
install cli/lightning-cli lightningd/lightningd /usr/local/bin
[...]
----

Let's check and see if the +lightningd+ and +lightning-cli+ commands have been installed correctly, asking each for their version information:

----
$ lightningd --version
v0.8.1rc2
$ lightning-cli --version
v0.8.1rc2
----

You may see a different version from that shown above, as the software continues to evolve long after this book is printed. However, no matter what version you see, the fact that the commands execute and show you version information means that you have succeeded in building the c-lightning software.

=== eclair
=== lightning network daemon (lnd)



==== The _devenv_ bundle container

As stated above, we have not optimized these containers for size. In that spirit, the +devenv+ folder has everything in a single container. It allows you to run any of the examples in a single environment.

[NOTE]
====
The devenv image is more than 2GB in size. The first time you build the image it will download a lot of data and take quite a while to finish building. However, docker efficiently caches each step, so if you rebuild it or make changes to it, it will be much faster next time!
====

Let's build our +devenv+ container and see how it works. Follow the steps below, while :

[docker-build-devenv]
----
$ cd code/docker
$ docker build devenv/ -t lnbook/devenv
Sending build context to Docker daemon  3.072kB
Step 1/20 : FROM ubuntu:18.04
 ---> 72300a873c2c
 [...]
Step 20/20 : RUN curl -SLO https://github.com/ACINQ/eclair/releases/download/v0.3.3/eclair-node-0.3.3-12ac145.jar
 ---> Using cache
 ---> 3a38f85ba558
Successfully built 3a38f85ba558
Successfully tagged lnbook/devenv:latest
----

Once the +devenv+ docker container is built, we can run it and access and interactive command shell like this:

----
$ docker run -it lnbook/devenv
root@6b5c904d899f:/lnbook#
----

You see a prompt +root@6b5c904d899f:/lnbook#+, which shows you the user (root), the container fingerprint (6b5c904d899f) and the current working directory (/lnbook). The prompt ends in +#+ instead of +$+ because you are the root user inside this container.

Let's give it a quick test, by trying to run the Lightning Network Daemon command +lnd+ and see if it is installed correctly:

----
root@6b5c904d899f:/lnbook# lnd --version
lnd version 0.9.0-beta commit=v0.9.0-beta-148-g38b521d87d3fd9cff628e5dc09b764aeabaf011a
----
[TIP]
====
To exit the container, press +CTRL-D+ or type +exit+. You are returned to the prompt of your own computer's command-line terminal.
====

Great! You have built and ran your first docker container. In order to be able to access the book examples, we will need to connect the folder containing the book repository to our docker container. This is achieved with the +volume+ parameter, which specifies a local volume (where you cloned the book repository) and a container volume (a folder in the container) where the local volume will be mounted.

[TIP]
====
Docker's volume parameter needs an _absolute_ path, so that will depend on your local configuration and where you cloned or extracted the book repository files.
====

In the following example, we will be connecting the book repository files that were extracted in +/home/ubuntu/lnbook+ to the container volume +lnbook+. Your configuration is likely different, so you need to replace +/home/ubuntu/lnbook+ with the absolute path to the folder where you extracted the book repository:

----
$ docker run --volume /home/ubuntu/lnbook:/lnbook -it lnbook/devenv
root@a7da66010491:/lnbook# ls
code                             images		CONTRIBUTING.md              	 README.md
[...]
----

You should now see all the book repository files inside your container, under the folder +/lnbook+. Now you can access the examples from the code directory with all the tools, applications and utilities that are in the container.
