2017-01-12 03:12:32 +03:00
|
|
|
### Getting started
|
|
|
|
This document is written for people who are eager to do something with
|
2017-01-13 04:11:46 +03:00
|
|
|
the Lightning Network Daemon (`lnd`). This folder uses `docker-compose` to
|
|
|
|
package `lnd` and `btcd` together to make deploying the two daemons as easy as
|
|
|
|
typing a few commands. All configuration between `lnd` and `btcd` are handled
|
|
|
|
automatically by their `docker-compose` config file.
|
|
|
|
|
|
|
|
|
|
|
|
This document describes a workflow on `simnet`, a development/test network
|
|
|
|
that's similar to Bitcoin Core's `regtest` mode. In `simnet` mode blocks can be
|
|
|
|
generated as will, as the difficulty is very low. This makes it an ideal
|
|
|
|
environment for testing as one doesn't need to wait tens of minutes for blocks
|
|
|
|
to arrive in order to test channel related functionality. Additionally, it's
|
|
|
|
possible to spin up an arbitrary number of `lnd` instances within containers to
|
|
|
|
create a mini development cluster. All state is saved between instances using a
|
|
|
|
shared value.
|
|
|
|
|
|
|
|
Current workflow is big because we recreate the whole network by ourselves,
|
|
|
|
next versions will use the started `btcd` bitcoin node in `testnet` and
|
|
|
|
`faucet` wallet from which you will get the bitcoins.
|
|
|
|
|
|
|
|
In the workflow below, we describe the steps required to recreate following
|
|
|
|
topology, and send a payment from `Alice` to `Bob`.
|
2017-01-12 03:12:32 +03:00
|
|
|
```
|
|
|
|
+ ----- + + --- +
|
|
|
|
| Alice | <--- channel ---> | Bob | <--- Bob and Alice are the lightning network daemons which
|
|
|
|
+ ----- + + --- + creates the channel and interact with each other using
|
|
|
|
| | Bitcoin network as source of truth.
|
|
|
|
| |
|
|
|
|
+ - - - - - + - - - - - - +
|
|
|
|
|
|
|
|
|
+ ---------------- +
|
|
|
|
| Bitcoin network | <--- In current scenario for simplicity we create only one
|
|
|
|
+ ---------------- + "btcd" node which represents the Bitcoin network, in
|
|
|
|
real situation Alice and Bob will likely be
|
|
|
|
connected to different Bitcoin nodes.
|
|
|
|
```
|
|
|
|
|
|
|
|
#### Prerequisites
|
|
|
|
Name | Version
|
|
|
|
--------|---------
|
|
|
|
docker-compose | 1.9.0
|
|
|
|
docker | 1.13.0
|
|
|
|
|
|
|
|
**General workflow is following:**
|
2017-01-13 04:11:46 +03:00
|
|
|
|
|
|
|
* Create a `btcd` node running on a private `simnet`.
|
|
|
|
* Create `Alice`, one of the `lnd` nodes in our test network.
|
|
|
|
* Create `Bob`, the other `lnd` node in our test network.
|
|
|
|
* Mine some blocks to send `Alice` some bitcoin.
|
|
|
|
* Open channel between `Alice` and `Bob`.
|
|
|
|
* Send payment from `Alice` to `Bob`.
|
|
|
|
* Finally, close the channel between `Alice` and Bob`.
|
|
|
|
|
|
|
|
Start `btcd`, and then create an address for `Alice` that we'll directly mine
|
|
|
|
bitcoin into.
|
2017-01-12 03:12:32 +03:00
|
|
|
```bash
|
|
|
|
# Create "btcd" node:
|
|
|
|
$ docker-compose up -d "btcd"
|
|
|
|
|
2017-01-13 04:11:46 +03:00
|
|
|
# Run the "Alice" container and log into it:
|
2017-01-12 03:12:32 +03:00
|
|
|
$ docker-compose up -d "alice"
|
|
|
|
$ docker exec -i -t "alice" bash
|
|
|
|
|
2017-01-13 04:11:46 +03:00
|
|
|
# Generate a new backward compatible nested p2sh for from Alice:
|
2017-01-12 03:12:32 +03:00
|
|
|
alice$ lncli newaddress np2wkh
|
|
|
|
|
2017-01-13 04:11:46 +03:00
|
|
|
# Recreate "btcd" node and set Alice's address as mining address:
|
2017-01-12 03:12:32 +03:00
|
|
|
$ MINING_ADDRESS=<alice_address> docker-compose up -d "btcd"
|
|
|
|
|
|
|
|
# Generate 201 block (we need at least "100 >=" blocks because of coinbase
|
|
|
|
# block maturity and "250 >=" in order to activate segwit):
|
|
|
|
$ docker-compose run btcctl generate 250
|
|
|
|
|
|
|
|
# Check that segwit is active:
|
|
|
|
$ docker-compose run btcctl getblockchaininfo | grep -A 1 segwit
|
|
|
|
```
|
|
|
|
|
2017-01-13 04:11:46 +03:00
|
|
|
Now we have `btcd` running and some amount of bitcoins mined to the `Alice`
|
|
|
|
address. We'll need to restart `Alice` just once so she properly syncs up with
|
|
|
|
`btcd`.
|
2017-01-12 03:12:32 +03:00
|
|
|
```bash
|
|
|
|
# Stop "Alice" container:
|
|
|
|
$ docker-compose stop "alice"
|
|
|
|
|
|
|
|
# Start "Alice" container and log into it:
|
|
|
|
$ docker-compose up --no-recreate -d "alice"
|
|
|
|
$ docker exec -i -t "alice" bash
|
|
|
|
|
|
|
|
# Check "Alice" balance:
|
|
|
|
alice$ lncli walletbalance --witness_only=true
|
|
|
|
```
|
|
|
|
|
|
|
|
Connect `Bob` node to `Alice` node.
|
|
|
|
```bash
|
|
|
|
# Run "Bob" node and log into it:
|
|
|
|
$ docker-compose up --no-recreate -d "bob"
|
|
|
|
$ docker exec -i -t "bob" bash
|
|
|
|
|
2017-01-13 04:11:46 +03:00
|
|
|
# Get the identity pubkey of "Bob" node:
|
2017-01-12 03:12:32 +03:00
|
|
|
bob$ lncli getinfo
|
|
|
|
|
2017-01-13 04:11:46 +03:00
|
|
|
{
|
|
|
|
----> "identity_pubkey": "0290bf454f4b95baf9227801301b331e35d477c6b6e7f36a599983ae58747b3828",
|
|
|
|
"block_height": 3949,
|
|
|
|
"block_hash": "00000000853c9dcccf8879abb0a91f0152aed16efe68015a924156f5845016ee",
|
|
|
|
"synced_to_chain": true,
|
|
|
|
"testnet": false,
|
|
|
|
}
|
|
|
|
|
2017-01-12 03:12:32 +03:00
|
|
|
# Get the IP address of "Bob" node:
|
|
|
|
$ docker inspect "bob" | grep IPAddress
|
|
|
|
|
|
|
|
# Connect "Alice" to the "Bob" node:
|
2017-01-13 04:11:46 +03:00
|
|
|
alice$ lncli connect <bob_pubkey>@<bob_host>:10011
|
2017-01-12 03:12:32 +03:00
|
|
|
|
|
|
|
# Check list of peers on "Alice" side:
|
|
|
|
alice$ lncli listpeers
|
2017-01-13 04:11:46 +03:00
|
|
|
{
|
|
|
|
"peers": [
|
|
|
|
{
|
|
|
|
"pub_key": "0290bf454f4b95baf9227801301b331e35d477c6b6e7f36a599983ae58747b3828",
|
|
|
|
"peer_id": 1,
|
|
|
|
"address": "10.0.0.125:10011",
|
|
|
|
"bytes_sent": 3278,
|
|
|
|
"bytes_recv": 3278
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
2017-01-12 03:12:32 +03:00
|
|
|
|
|
|
|
# Check list of peers on "Bob" side:
|
|
|
|
bob$ lncli listpeers
|
2017-01-13 04:11:46 +03:00
|
|
|
{
|
|
|
|
"peers": [
|
|
|
|
{
|
|
|
|
"pub_key": "036a0c5ea35df8a528b98edf6f290b28676d51d0fe202b073fe677612a39c0aa09",
|
|
|
|
"peer_id": 1,
|
|
|
|
"address": "10.0.0.15:10011",
|
|
|
|
"bytes_sent": 3278,
|
|
|
|
"bytes_recv": 3278
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
2017-01-12 03:12:32 +03:00
|
|
|
```
|
|
|
|
|
2017-01-13 04:11:46 +03:00
|
|
|
Create the `Alice<->Bob` channel.
|
2017-01-12 03:12:32 +03:00
|
|
|
```bash
|
|
|
|
# Open the channel with "Bob":
|
2017-01-13 04:11:46 +03:00
|
|
|
alice$ lncli openchannel --node_key=<bob_lightning_id> --num_confs=1 --local_amt=1000000
|
2017-01-12 03:12:32 +03:00
|
|
|
|
|
|
|
# Include funding transaction in block thereby open the channel:
|
|
|
|
$ docker-compose run btcctl generate 1
|
|
|
|
|
|
|
|
# Check that channel with "Bob" was created:
|
|
|
|
alice$ lncli listchannels
|
2017-01-13 04:11:46 +03:00
|
|
|
{
|
|
|
|
"channels": [
|
|
|
|
{
|
|
|
|
"remote_pubkey": "0290bf454f4b95baf9227801301b331e35d477c6b6e7f36a599983ae58747b3828",
|
|
|
|
"channel_point": "7a632cde9e9e2ae4e9209591c0587bbb03254814c62e2a7fcef35ced743b0025:0",
|
|
|
|
"chan_id": 1170330072213225472,
|
|
|
|
"capacity": 1005000,
|
|
|
|
"local_balance": 1000000,
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
2017-01-12 03:12:32 +03:00
|
|
|
```
|
|
|
|
|
|
|
|
Send the payment form "Alice" to "Bob".
|
|
|
|
```
|
|
|
|
# Add invoice on "Bob" side:
|
|
|
|
bob> lncli addinvoice --value=10000
|
2017-01-13 04:11:46 +03:00
|
|
|
{
|
|
|
|
"r_hash": "<your_random_rhash_here>",
|
|
|
|
"pay_req": "<encoded_invoice>",
|
|
|
|
}
|
2017-01-12 03:12:32 +03:00
|
|
|
|
|
|
|
# Send payment from "Alice" to "Bob":
|
|
|
|
alice> lncli sendpayment --pay_req=<encoded_invoice>
|
|
|
|
|
2017-01-13 04:11:46 +03:00
|
|
|
# Check "Alice"'s channel balance was decremented accordingly by the payment
|
|
|
|
# amount
|
2017-01-12 03:12:32 +03:00
|
|
|
alice> lncli listchannels
|
|
|
|
|
2017-01-13 04:11:46 +03:00
|
|
|
# Check "Bob"'s channel balance was credited with the payment amount
|
2017-01-12 03:12:32 +03:00
|
|
|
bob> lncli listchannels
|
|
|
|
```
|
|
|
|
|
|
|
|
Now we have open channel in which we sent only one payment, lets imagine
|
2017-01-13 04:11:46 +03:00
|
|
|
that we sent a lots of them and we'll now like to close the channel. Lets do
|
|
|
|
it!
|
2017-01-12 03:12:32 +03:00
|
|
|
```
|
|
|
|
# List the "Alice" channel and retrieve "channel_point" which represent
|
|
|
|
# the opened channel:
|
|
|
|
alice> lncli listchannels
|
2017-01-13 04:11:46 +03:00
|
|
|
{
|
|
|
|
"channels": [
|
|
|
|
{
|
|
|
|
"remote_pubkey": "0290bf454f4b95baf9227801301b331e35d477c6b6e7f36a599983ae58747b3828",
|
|
|
|
"channel_point": "7a632cde9e9e2ae4e9209591c0587bbb03254814c62e2a7fcef35ced743b0025:0",
|
|
|
|
"chan_id": 1170330072213225472,
|
|
|
|
"capacity": 1005000,
|
|
|
|
"local_balance": 900000,
|
|
|
|
"remote_balance": 10000,
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
|
|
|
# Channel point consist of two numbers separated by colon the first on is
|
2017-01-12 03:12:32 +03:00
|
|
|
# "funding_txid" and the second one is "output_index":
|
|
|
|
alice> lncli closechannel --funding_txid=<funding_txid> --output_index=<output_index>
|
|
|
|
|
|
|
|
# Include close transaction in block thereby close the channel:
|
|
|
|
$ docker-compose run btcctl generate 1
|
|
|
|
|
2017-01-13 04:11:46 +03:00
|
|
|
# Check "Alice" on-chain balance was credited by her settled amount in the channel:
|
2017-01-12 03:12:32 +03:00
|
|
|
alice> lncli walletbalance
|
|
|
|
|
2017-01-13 04:11:46 +03:00
|
|
|
# Check "Bob" on-chain balance was credited with the funds he received in the
|
|
|
|
# channel:
|
2017-01-12 03:12:32 +03:00
|
|
|
bob> lncli walletbalance
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Questions
|
|
|
|
* How to see `alice` | `bob` | `btcd` logs?
|
|
|
|
```
|
|
|
|
docker-compose logs <alice|bob|btcd>
|
2017-01-13 04:11:46 +03:00
|
|
|
```
|