© Harris Brakmić 2019
H. BrakmićBitcoin and Lightning Network on Raspberry Pihttps://doi.org/10.1007/978-1-4842-5522-3_11

11. LND

Harris Brakmić1 
(1)
Troisdorf, Germany
 

In this chapter we will learn how to use LND,1 an implementation of the BOLT specification written in Go.2 LND is compatible to c-lightning, and everything we have learned so far can be applied on it as well.

Compilation

To compile LND we will have first to download and set up our Go development environment. As LND needs a version of Go that’s not available in the official Raspbian apt packages, we will download a precompiled binary package and extract it manually. The package should be downloaded in the $HOME directory of the current user. Although this book can’t teach you much about Go, let’s just give a short description of it. Go is a relatively new programming language developed by Google. Its primary purpose is development of backend services that should run for a long time without being interrupted. Go has a C-like syntax, but unlike C it uses a garbage collector that takes care of memory management, thus relieving the programmer from all the problematic malloc/free function calls and unsafe pointer operations, that very often sit at the root of so many software vulnerabilities and sudden crashes.
wget https://dl.google.com/go/go1.13.linux-armv6l.tar.gz
tar xvf go1.13.linux-armv6l.tar.gz

A new directory named go will be created. The executables are located under $HOME/go/bin which we want to declare as globally available. For this we open the $HOME/.bashrc file with an editor. This file is where our bash shell settings and other properties are located.

We will then add this line to the end of .bashrc.
export PATH=$PATH:$HOME/go/bin
We save the file and type source .bashrc in the console. Don’t forget the dot before the file. This is the Unix/Linux convention for naming hidden files. To check that our go compiler is now available system-wide, we type this:
go version

It should return: go version go1.13 linux/arm

The next step will be to prepare the source directories for golang’s artifacts and binaries. We will create a directory named gocode in the current $HOME directory and later add two new paths to .bashrc. The first one is $HOME/gocode itself, that will serve as GOPATH, which must always be present, because golang demands it. This directory is where all cloned sources, artifacts, and binaries will be located. The second path points to where our future LND binaries will be, so we want them to be globally available as well.
export GOPATH=$HOME/gocode
export PATH=$PATH:$GOPATH/bin
We are now ready to get LND sources. We only need a single command that will kick off everything and download not only LND but also all of its dependencies.
go get -d github.com/lightningnetwork/lnd
The sources will be located in the GOPATH directory which comprises of three subdirectories: bin, pkg, and src. After the sources have been downloaded, we go into LND’s source path inside GOPATH.
cd $GOPATH/src/github.com/lightningnetwork/lnd
There we execute our well-known tandem:
make && make install

This will kick off various compilations, not only of LND but also of every other dependency it needs to run.

This is one of the advantages of golang’s environment as it offers transparent dependency management. Unlike other environments, where users have to take care of manually downloading and installing every single dependency, golang keeps the compilation and versioning invisible.

The compilation process we just started will need a few moments to complete, because LND references many other packages. Like c-lightning LND is a very modular package that comprises of several binaries. The two we will be dealing with are lnd, the daemon, and lncli, the command line interface. However, there are many other packages, for example, Neutrino, an alternative lightweight Bitcoin client software designed for mobile devices.

After the compilation process has ended, we will have new binaries in $GOPATH/bin.

On the next few pages, we will learn how to set up an lnd configuration file and how to create a separate wallet with lncli. We will see a few differences between c-lightning and LND regarding the configuration structure, but this won’t be reflected on the public interface as both implementations are compatible to each other. It is very easy to connect different types of nodes together, which we will try out later in this chapter.

Configuration

The LND daemon uses a configuration file called lnd.conf that’s by default located in a hidden directory named .lnd. After we have compiled LND sources, we manually create such a directory and put this file into it.
mkdir $HOME/.lnd
touch $HOME/.lnd/lnd.conf
We will then open lnd.conf with a text editor to enter configuration settings that will define the name of the node, the used ports, and the location of the macaroon files, which are decentralized bearer credentials, that can be issued for various tasks and with different access rights.
[Application Options]
debuglevel = info
maxpendingchannels=5
no-macaroons = false
alias = LND_NODE_NAME_HERE
color = #BBA142
datadir = "~/.lnd/data"
listen=:9736
adminmacaroonpath = "~/.lnd/data/chain/bitcoin/testnet/admin.macaroon"
readonlymacaroonpath = "~/.lnd/data/chain/bitcoin/testnet/readonly.macaroon"
invoicemacaroonpath = "~/.lnd/data/chain/bitcoin/testnet/invoice.macaroon"

At the first start, LND will create two of them: admin.macaroon and read_only.macaroon. Also, it will generate a macaroons.db file. For every network being used (mainnet, testnet), there will be a separate set of macaroons that can be found in separate chain-directories inside .lnd. In general, the admin.macaroon file should be treated as a private key, because those who have access to it have also access to all funds that are locked in LND-based nodes. In testnet scenarios this might be a less important issue, but when running on mainnet, one simply can’t be paranoid enough. One should take great care of those files.

lnd.conf comprises of five parts:
  • Node settings

  • RPC/API settings

  • Network/blockchain settings

  • Autopilot settings

  • Bitcoin daemon settings

Not all of them are mandatory, like autopilot, but it’s always a good strategy to try them out. Apart from macaroon settings, the others are more or less the same as in c-lightning’s configuration. The important difference here is the selected port number that is not the default 9735 to prevent port blocking when c-lightning is running at the same time. Indeed, it is possible to run different daemons as the same time on a single hardware platform, as long as their identities and ports are different. Additionally, LND offers the option of using NAT (network address translation) for scenarios where nodes are running in local non-routable networks.

Similar to Bitcoin’s daemon, LND can listen to API queries via RPC and REST.
rpclisten=localhost:10009
rpclisten=[::1]:10010
restlisten=localhost:8080
restlisten=localhost:8443
The network and blockchain settings define the network and Bitcoin daemon that should be used. In our case this will be testnet and bitcoind daemon.
[Bitcoin]
bitcoin.mainnet = 0
bitcoin.testnet = 1
bitcoin.active = 1
bitcoin.node = bitcoind
The autopilot is an interesting feature of LND as it allows automatic creation of payment channels. In the autopilot settings, we can declare how much of the available funds should be reserved for this functionality and also the number of allowed nodes. In our case, however, the autopilot is deactivated.
[autopilot]
autopilot.active = 0
autopilot.maxchannels = 5
autopilot.allocation = 0.6
The last entry describes the connection settings for bitcoind’s RPC API and the ZMQ messaging interface that we have met in Chapter 6.
[bitcoind]
bitcoind.rpchost = localhost:18332
bitcoind.rpcuser = raspiuser
bitcoind.rpcpass = mypassword
bitcoind.zmqpubrawblock=tcp://127.0.0.1:28332
bitcoind.zmqpubrawtx=tcp://127.0.0.1:28333
After we have saved this file, we can execute lnd in the console and observe its log messages. After a few promising messages, the daemon stops and expects us to unlock its wallet.
LTND: Waiting for wallet encryption password. Use `lncli create` to create a wallet, `lncli unlock` to unlock an existing wallet, or `lncli changepassword` to change the password of an existing wallet and unlock it.

Unlike with c-lightning, where a wallet got created automatically, here we have to manually set up a wallet and also secure the 24-word seed mnemonic, which can be used to recreate this wallet. Therefore, before we continue our journey with LND, we have to use the other binary that got compiled at the beginning: lncli, the command line interface. We type lncli create in the console. A dialog will appear asking us for a password and an optional seed mnemonic. For now, we simply say “no” and let the tool generate a new wallet and mnemonic for us. This mnemonic should be safely stored so we can later restore the wallet.

After we have set up our wallet and secured the mnemonic, we are ready to start LND. We type another command with lncli, but this time to unlock the wallet:
lncli unlock.
For this operation to succeed, the LND should be already running and waiting for the unlock command to complete. This is how the daemon would react after the wallet got unlocked.
LNWL: Opened wallet
Sep 21 22:14:47 lnd lnd[13253]: 2019-09-21 22:14:47.974 [INF] LTND: Primary chain is set to: bitcoin
Sep 21 22:14:47 lnd lnd[13253]: 2019-09-21 22:14:47.986 [INF] LTND: Initializing bitcoind backed fee estimator
Sep 21 22:14:47 lnd lnd[13253]: 2019-09-21 22:14:47.987 [INF] LNWL: Started listening for bitcoind block notifications via ZMQ on 127.0.0.1:28332
Sep 21 22:14:47 lnd lnd[13253]: 2019-09-21 22:14:47.987 [INF] LNWL: Started listening for bitcoind transaction notifications via ZMQ on 127.0.0.1:28333

The daemon is now capable of reading its wallet and communicating with bitcoind process.

It will now take a few moments to synchronize with the current blockchain. For the current setup to work, it is needed to let LND daemon run in a separate window (tab) or shell. Apart from unlocking the wallet, there will be no other interaction with LND so that lncli will serve as the gateway to the daemon and its functionalities, very similar to lightning-cli.

On the next few pages, we will be creating new channels by using similar commands. Most of the time, the commands will even have the same semantic meaning, which is expectable as both daemons implement the same specification, BOLT.

Using LND

Our first step toward a working LND node is to load up some tBTC. Here we can use the previously mentioned tBTC faucets. The command for creating a new address in LND is
lncli -n testnet newaddress p2wkh

The option -n testnet is important to inform lncli about the network currently being used. By default, lncli refers to mainnet which is not the case in this example.

To get information about our current balance, we use:
lncli walletbalance.
It will return a JSON object containing the general balance and the information of how much of it is confirmed.
{
    "total_balance": "9504751",
    "confirmed_balance": "9504751",
    "unconfirmed_balance": "0"
}
To open a new payment channel, we need to find a public node, which we can easily find via https://ml1.com/testnet. Our first step will be to open a connection to another node:
lncli -n testnet connect NodeID
The result returned will be an empty JSON file, which is a good indicator. When an error happens, this object contains a description of the error. Now we can try to open a payment channel with this node by using its NodeID with the command openchannel. The parameter --local_amt indicates the amount of satoshis we are going to use to fund the channel.
Lncli -n testnet openchannel NodeID --local_amt SATOSHIS

If the opening was successful, the result would contain the funding transaction ID. The status can be queried with pendingchannels command. After a while the needed confirmation level will be reached, and the returned value from pendingchannels will become empty. We now get our new payment channel shown in the list returned by listchannels.

Payments and Invoices with LNCLI

To pay with LND, we use the lncli’s command payinvoice, which we give the bolt11 string we already approached in the last chapter. The difference between c-lightning and LND is that LND asks for confirmation before the payment is being sent. Apart from the required flag --pay_req for the bolt11 string, the rest of the process is the same.

To create an invoice, we use the addinvoice with parameters --amt for the expected amount in satoshis and --memo which is a short description of the invoice being created.
lncli -n testnet addinvoice --amt 1 --memo
"and invoice with LND"
The property pay_req in the returned JSON contains the bolt11 string that the paying side should use.
{
       "r_hash": "76b9aad1bce2cb3bd76dfe2b6c67e5a9985568cf2f0c0587170a4899c5876b50",
       "pay_req": "lntb10n1pwcdpsupp5w6u645duut9nh4mdlc4kcel94xv926x09uxqtpchpfyfn3v8ddgqdqlv9hzq6twwehkjcm9ypmkjargypxyu3qcqzpgflspyjqv5jamc05w7738k3w5hz8kh7ahe3p04jkf0x9527lzms4jm87ncnefh5q4k6ukvu49m6nd8vkeqrjrmcamk48mphjp72e0p4cqeglj7r",
       "add_index": 1
}

Running LND with systemd

LND is a daemon and therefore perfect for running under systemd . Just like we did with bitcoind and c-lightning, LND too will get its configuration file that will start it on each boot. But unlike c-lightning we will have to provide the password with lncli manually. The content of LND’s configuration file will comprise of settings for its name and requirements, its configuration paths and flags, as well as hardening settings to isolate it from the rest of the operating system.
[Unit]
Description=LND Lightning Daemon
[Service]
ExecStart=/home/pi/gocode/bin/lnd
ExecStop=/home/pi/gocode/bin/lncli stop
PIDFile=/home/pi/.lnd/lnd.pid
User=pi
Group=pi
Type=simple
KillMode=process
TimeoutStartSec=60
TimeoutStopSec=60
Restart=always
RestartSec=60
PrivateTmp=true
ProtectSystem=full
NoNewPrivileges=true
PrivateDevices=true
MemoryDenyWriteExecute=true
 [Install]
WantedBy=multi-user.target

We will activate our new service with sudo systemd enable lnd.

We start the daemon with
sudo systemctl start lnd
We will query its status afterward with
systemctl status lnd

One more step is needed to unlock the wallet. lncli unlock will do this for us.

Signing and Verifying Messages

The lncli tool offers an easy-to-use message signature and verification functionality. With it one can generate messages that will be signed with the node’s private key and can be verified on other nodes. To sign a message, one only needs to use the signmessage command together with the message that should be signed. The returned value would be the signature that will be later used to verify the message.
lncli -n testnet signmessage "hello, world"
{
    "signature": "d6rp9ba383k4xbhiwc3zw5q75wtd5aezrd8kxbm65t9699x848xsw8hrjycqxrtiohy94xqrtyitqfbpoj4k8fxa3ufnrenz1ji7gewz"
}
To verify the message, we need the signature created previously. In the command line, the signature follows the --sig flag.
lncli verifymessage --msg "hello, world" --sig d6rp9ba383k4xbhiwc3zw5q75wtd5aezrd8kxbm65t9699x848xsw8hrjycqxrtiohy94xqrtyitqfbpoj4k8fxa3ufnrenz1ji7gewz
{
    "valid": true,
    "pubkey": "03052ae5c77d75264a13ab0d34520bd8260de9542e7d930cbe6bc5137485f065f3"
}

The returned result will then indicate if the given message and signature fit together.

Summary

In this chapter we have learned how to compile, install, and use the second BOLT implementation, LND. We have learned how to set up a Go programming language environment to compile LND’s sources. We have also created a systemd configuration to start LND at each boot. We have also learned how to open and fund payment channels with LND.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.149.237.26