docker: add send payment alice->bob workflow for newcomers
This commit is contained in:
parent
51d53eab32
commit
a421069dd8
151
docker/README.md
151
docker/README.md
@ -1 +1,152 @@
|
|||||||
|
### Getting started
|
||||||
|
This document is written for people who are eager to do something with
|
||||||
|
lightning network daemon (`lnd`). 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 current readme we decribe the steps which are needed to recreate
|
||||||
|
following schema, and send payment from `Alice` to `Bob`.
|
||||||
|
```
|
||||||
|
+ ----- + + --- +
|
||||||
|
| 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:**
|
||||||
|
* Create Bitcoin network
|
||||||
|
* Create `Alice` node
|
||||||
|
* Create `Bob` node
|
||||||
|
* Initialize `Alice` node with some amount of bitcoins
|
||||||
|
* Open channel between `Alice` and `Bob`
|
||||||
|
* Send payment from `Alice` to `Bob`
|
||||||
|
|
||||||
|
Start the `btcd`, create `Alice` address and mine some bitcoins.
|
||||||
|
```bash
|
||||||
|
# Create "btcd" node:
|
||||||
|
$ docker-compose up -d "btcd"
|
||||||
|
|
||||||
|
# Run "Alice" container and log into it:
|
||||||
|
$ docker-compose up -d "alice"
|
||||||
|
$ docker exec -i -t "alice" bash
|
||||||
|
|
||||||
|
# Generate new backward compatible "segwit" "alice" address:
|
||||||
|
alice$ lncli newaddress np2wkh
|
||||||
|
|
||||||
|
# Recreate "btcd" node and set "alice" address as mining address:
|
||||||
|
$ 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
|
||||||
|
```
|
||||||
|
|
||||||
|
Now we have `btcd` node turned on and some amount of bitcoins mined on
|
||||||
|
`Alice` address. But in order `lnd` saw them lets restart the `lnd`
|
||||||
|
daemon.
|
||||||
|
```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
|
||||||
|
|
||||||
|
# Get the identity address of "Bob" node:
|
||||||
|
bob$ lncli getinfo
|
||||||
|
|
||||||
|
# Get the IP address of "Bob" node:
|
||||||
|
$ docker inspect "bob" | grep IPAddress
|
||||||
|
|
||||||
|
# Connect "Alice" to the "Bob" node:
|
||||||
|
alice$ lncli connect <bob_identity_address>@<bob_host>:10011
|
||||||
|
|
||||||
|
# Check list of peers on "Alice" side:
|
||||||
|
alice$ lncli listpeers
|
||||||
|
|
||||||
|
# Check list of peers on "Bob" side:
|
||||||
|
bob$ lncli listpeers
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `Alice<->Bob` channel.
|
||||||
|
```bash
|
||||||
|
# Open the channel with "Bob":
|
||||||
|
alice$ lncli openchannel --node_key=<bob_lightning_id> --num_confs=1 --local_amt=1000000 --push_amt=0
|
||||||
|
|
||||||
|
# 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
|
||||||
|
```
|
||||||
|
|
||||||
|
Send the payment form "Alice" to "Bob".
|
||||||
|
```
|
||||||
|
# Add invoice on "Bob" side:
|
||||||
|
bob> lncli addinvoice --value=10000
|
||||||
|
|
||||||
|
# Send payment from "Alice" to "Bob":
|
||||||
|
alice> lncli sendpayment --pay_req=<encoded_invoice>
|
||||||
|
|
||||||
|
# Check "Alice" channel balance was descreased on sent amount:
|
||||||
|
alice> lncli listchannels
|
||||||
|
|
||||||
|
# Check "Bob" channel balance was increased on sent amount:
|
||||||
|
bob> lncli listchannels
|
||||||
|
```
|
||||||
|
|
||||||
|
Now we have open channel in which we sent only one payment, lets imagine
|
||||||
|
that we sent a lots of them and we ok to close channel. Lets do it.
|
||||||
|
```
|
||||||
|
# List the "Alice" channel and retrieve "channel_point" which represent
|
||||||
|
# the opened channel:
|
||||||
|
alice> lncli listchannels
|
||||||
|
|
||||||
|
# Channel point consist of two numbers devided by ":" the first on is
|
||||||
|
# "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
|
||||||
|
|
||||||
|
# Check "Alice" on-chain balance was descresed on sent amount:
|
||||||
|
alice> lncli walletbalance
|
||||||
|
|
||||||
|
# Check "Bob" on-chain balance was increased on sent amount:
|
||||||
|
bob> lncli walletbalance
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Questions
|
||||||
|
* How to see `alice` | `bob` | `btcd` logs?
|
||||||
|
```
|
||||||
|
docker-compose logs <alice|bob|btcd>
|
||||||
|
```
|
@ -2,27 +2,36 @@ FROM golang:1.7
|
|||||||
|
|
||||||
MAINTAINER Olaoluwa Osuntokun <laolu@lightning.network>
|
MAINTAINER Olaoluwa Osuntokun <laolu@lightning.network>
|
||||||
|
|
||||||
|
# Expose mainnet ports (server, rpc)
|
||||||
|
EXPOSE 8333 8334
|
||||||
|
|
||||||
|
# Expose testnet ports (server, rpc)
|
||||||
|
EXPOSE 18333 18334
|
||||||
|
|
||||||
|
# Expose simnet ports (server, rpc)
|
||||||
|
EXPOSE 18555 18556
|
||||||
|
|
||||||
|
# Expose segnet ports (server, rpc)
|
||||||
|
EXPOSE 28901 28902
|
||||||
|
|
||||||
# Grab and install the latest version of roasbeef's fork of btcd and all
|
# Grab and install the latest version of roasbeef's fork of btcd and all
|
||||||
# related dependencies.
|
# related dependencies.
|
||||||
RUN go get -u -v github.com/roasbeef/btcd/...
|
RUN go get -u -v github.com/roasbeef/btcd/...
|
||||||
|
|
||||||
# Expose the mainnet, testnet, simnet, and segnet listening ports.
|
RUN mkdir "/rpc" "/root/.btcd" "/root/.btcctl"
|
||||||
EXPOSE 8333 18333 18335 28901
|
RUN touch "/root/.btcd/btcd.conf"
|
||||||
|
|
||||||
# Expose the mainnet, testnet, simnet, and segnet rpc ports.
|
# Manually generate certificate and add all domains, it is needed to connect
|
||||||
EXPOSE 8333 18333 18336 28902
|
# "btcctl" and "lnd" to "btcd" over docker links.
|
||||||
|
RUN "/go/bin/gencerts" --host="*" --directory="/rpc" --force
|
||||||
|
|
||||||
# Create a volume to house the RPC credentials. This will be shared with any
|
# Create a volume to house pregenerated RPC credentials. This will be
|
||||||
# lnd containers so they can securely query btcd's RPC server.
|
# shared with any lnd, btcctl containers so they can securely query btcd's RPC
|
||||||
|
# server.
|
||||||
|
# You should NOT do this before certificate generation!
|
||||||
|
# Otherwise manually generated certificate will be overriden with shared
|
||||||
|
# mounted volume! For more info read dockerfile "VOLUME" documentation.
|
||||||
VOLUME ["/rpc"]
|
VOLUME ["/rpc"]
|
||||||
|
|
||||||
VOLUME ["/data"]
|
COPY "start-btcctl.sh" .
|
||||||
|
COPY "start-btcd.sh" .
|
||||||
RUN mkdir /root/.btcd && mkdir /root/.btcctl
|
|
||||||
|
|
||||||
COPY btcd-start.sh /
|
|
||||||
|
|
||||||
# Finally, execute the shell script that will start btcd. We use a shell script
|
|
||||||
# rather than executing the command directly with ENTRYPOINT in order to ensure
|
|
||||||
# environment variables get properly substitued.
|
|
||||||
ENTRYPOINT ["/btcd-start.sh"]
|
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
|
|
||||||
/go/bin/btcd --datadir=/data --logdir=/data --simnet \
|
|
||||||
--rpccert=/rpc/rpc.cert --rpckey=/rpc/rpc.key \
|
|
||||||
--rpcuser=${RPCUSER} --rpcpass=${RPCPASS} --rpclisten=0.0.0.0 \
|
|
||||||
--debuglevel=debug
|
|
37
docker/btcd/start-btcctl.sh
Executable file
37
docker/btcd/start-btcctl.sh
Executable file
@ -0,0 +1,37 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Check env variable and in case of empty value and default value specified
|
||||||
|
# returns default value, in case of non-empty value returns value.
|
||||||
|
set_env() {
|
||||||
|
# docker initialized env variables with blank string and we can't just
|
||||||
|
# use -z flag as usually.
|
||||||
|
BLANK_STRING='""'
|
||||||
|
|
||||||
|
VARIABLE="$1"
|
||||||
|
NAME="$2"
|
||||||
|
DEFAULT="$3"
|
||||||
|
|
||||||
|
if [[ -z "$VARIABLE" || "$VARIABLE" == "$BLANK_STRING" ]]; then
|
||||||
|
|
||||||
|
if [ -z "$DEFAULT" ]; then
|
||||||
|
echo "You should specify '$NAME' env variable"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
VARIABLE="$DEFAULT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# echo is used as return in case if string values
|
||||||
|
echo "$VARIABLE"
|
||||||
|
}
|
||||||
|
|
||||||
|
RPCUSER=$(set_env "$RPCUSER" "RPCUSER")
|
||||||
|
RPCPASS=$(set_env "$RPCPASS" "RPCPASS")
|
||||||
|
|
||||||
|
btcctl \
|
||||||
|
--simnet \
|
||||||
|
--rpccert="/rpc/rpc.cert" \
|
||||||
|
--rpcuser="$RPCUSER" \
|
||||||
|
--rpcpass="$RPCPASS" \
|
||||||
|
--rpcserver="rpcserver" \
|
||||||
|
"$@"
|
47
docker/btcd/start-btcd.sh
Executable file
47
docker/btcd/start-btcd.sh
Executable file
@ -0,0 +1,47 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Check env variable and in case of empty value and default value specified
|
||||||
|
# returns default value, in case of non-empty value returns value.
|
||||||
|
set_env() {
|
||||||
|
# docker initialized env variables with blank string and we can't just
|
||||||
|
# use -z flag as usually.
|
||||||
|
BLANK_STRING='""'
|
||||||
|
|
||||||
|
VARIABLE="$1"
|
||||||
|
NAME="$2"
|
||||||
|
DEFAULT="$3"
|
||||||
|
|
||||||
|
if [[ -z "$VARIABLE" || "$VARIABLE" == "$BLANK_STRING" ]]; then
|
||||||
|
|
||||||
|
if [ -z "$DEFAULT" ]; then
|
||||||
|
echo "You should specify '$NAME' env variable"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
VARIABLE="$DEFAULT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# echo is used as return in case if string values
|
||||||
|
echo "$VARIABLE"
|
||||||
|
}
|
||||||
|
|
||||||
|
RPCUSER=$(set_env "$RPCUSER" "RPCUSER")
|
||||||
|
RPCPASS=$(set_env "$RPCPASS" "RPCPASS")
|
||||||
|
|
||||||
|
DEBUG=$(set_env "$DEBUG" "DEBUG")
|
||||||
|
|
||||||
|
MINING_ADDRESS=$(set_env "$MINING_ADDRESS" "MINING_ADDRESS" "ScoDuqH7kYA9nvxuRg4Xk7E31AhsSc5zxp")
|
||||||
|
|
||||||
|
btcd \
|
||||||
|
--debuglevel="$DEBUG" \
|
||||||
|
--datadir="/data" \
|
||||||
|
--logdir="/data" \
|
||||||
|
--simnet \
|
||||||
|
--rpccert="/rpc/rpc.cert" \
|
||||||
|
--rpckey="/rpc/rpc.key" \
|
||||||
|
--rpcuser="$RPCUSER" \
|
||||||
|
--rpcpass="$RPCPASS" \
|
||||||
|
--miningaddr="$MINING_ADDRESS" \
|
||||||
|
--rpclisten="0.0.0.0" \
|
||||||
|
"$@"
|
||||||
|
|
@ -1,28 +1,56 @@
|
|||||||
version: '2'
|
version: '2'
|
||||||
services:
|
services:
|
||||||
btcd:
|
|
||||||
environment:
|
btc:
|
||||||
- RPCUSER=devuser
|
image: btcd
|
||||||
- RPCPASS=devpass
|
|
||||||
build:
|
build:
|
||||||
context: btcd/
|
context: btcd/
|
||||||
expose:
|
|
||||||
- "18336"
|
|
||||||
volumes:
|
volumes:
|
||||||
- shared-volume:/rpc
|
- shared:/rpc
|
||||||
lnd:
|
|
||||||
environment:
|
environment:
|
||||||
- RPCUSER=devuser
|
- RPCUSER="devuser"
|
||||||
- RPCPASS=devpass
|
- RPCPASS="devpass"
|
||||||
|
|
||||||
|
btcd:
|
||||||
|
extends: btc
|
||||||
|
container_name: btcd
|
||||||
|
environment:
|
||||||
|
- DEBUG="debug"
|
||||||
|
- MINING_ADDRESS
|
||||||
|
entrypoint: ["./start-btcd.sh"]
|
||||||
|
|
||||||
|
btcctl:
|
||||||
|
extends: btc
|
||||||
|
container_name: btcctl
|
||||||
|
links:
|
||||||
|
- "btcd:rpcserver"
|
||||||
|
entrypoint: ["./start-btcctl.sh"]
|
||||||
|
|
||||||
|
lnd:
|
||||||
|
image: lnd
|
||||||
build:
|
build:
|
||||||
context: ../
|
context: ../
|
||||||
dockerfile: docker/lnd/Dockerfile
|
dockerfile: docker/lnd/Dockerfile
|
||||||
expose:
|
environment:
|
||||||
- "10009"
|
- RPCUSER="devuser"
|
||||||
- "10011"
|
- RPCPASS="devpass"
|
||||||
|
- DEBUG="debug"
|
||||||
volumes:
|
volumes:
|
||||||
- shared-volume:/rpc
|
- shared:/rpc
|
||||||
|
entrypoint: ["./start-lnd.sh"]
|
||||||
|
|
||||||
|
alice:
|
||||||
|
extends: lnd
|
||||||
|
container_name: alice
|
||||||
links:
|
links:
|
||||||
- btcd
|
- btcd
|
||||||
|
|
||||||
|
bob:
|
||||||
|
extends: lnd
|
||||||
|
container_name: bob
|
||||||
|
links:
|
||||||
|
- btcd
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
shared-volume: {}
|
shared:
|
||||||
|
driver: local
|
||||||
|
@ -13,18 +13,7 @@ ENV GODEBUG netdns=cgo
|
|||||||
RUN go build
|
RUN go build
|
||||||
RUN go install . ./cmd/...
|
RUN go install . ./cmd/...
|
||||||
|
|
||||||
# Mount a volume where btcd's RPC credentials are stored. We'll need to read
|
# Expose lnd ports (server, rpc).
|
||||||
# the TLS cert from this directory.
|
EXPOSE 10011 10009
|
||||||
VOLUME ["/rpc"]
|
|
||||||
|
|
||||||
VOLUME ["/data"]
|
COPY "docker/lnd/start-lnd.sh" .
|
||||||
|
|
||||||
# Expose the p2p listening port, and the current RPC port.
|
|
||||||
EXPOSE 10009 10011
|
|
||||||
|
|
||||||
COPY docker/lnd/lnd-start.sh /
|
|
||||||
|
|
||||||
# Finally, execute the shell script that will start lnd. We use a shell script
|
|
||||||
# rather than executing the command directly with ENTRYPOINT in order to ensure
|
|
||||||
# environment variables get properly substitued.
|
|
||||||
ENTRYPOINT ["/lnd-start.sh"]
|
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
/go/bin/lnd --datadir=/data --logdir=/data --simnet \
|
|
||||||
--btcdhost=btcd --rpccert=/rpc/rpc.cert \
|
|
||||||
--rpcuser=${RPCUSER} --rpcpass=${RPCPASS} --debuglevel=debug
|
|
42
docker/lnd/start-lnd.sh
Executable file
42
docker/lnd/start-lnd.sh
Executable file
@ -0,0 +1,42 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Check env variable and in case of empty value and default value specified
|
||||||
|
# returns default value, in case of non-empty value returns value.
|
||||||
|
set_env() {
|
||||||
|
# docker initialized env variables with blank string and we can't just
|
||||||
|
# use -z flag as usually.
|
||||||
|
BLANK_STRING='""'
|
||||||
|
|
||||||
|
VARIABLE="$1"
|
||||||
|
NAME="$2"
|
||||||
|
DEFAULT="$3"
|
||||||
|
|
||||||
|
if [[ -z "$VARIABLE" || "$VARIABLE" == "$BLANK_STRING" ]]; then
|
||||||
|
|
||||||
|
if [ -z "$DEFAULT" ]; then
|
||||||
|
echo "You should specify '$NAME' env variable"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
VARIABLE="$DEFAULT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# echo is used as return in case if string values
|
||||||
|
echo "$VARIABLE"
|
||||||
|
}
|
||||||
|
|
||||||
|
RPCUSER=$(set_env "$RPCUSER" "RPCUSER")
|
||||||
|
RPCPASS=$(set_env "$RPCPASS" "RPCPASS")
|
||||||
|
|
||||||
|
DEBUG=$(set_env "$DEBUG" "DEBUG")
|
||||||
|
|
||||||
|
lnd \
|
||||||
|
--datadir="/data" \
|
||||||
|
--logdir="/data" \
|
||||||
|
--simnet \
|
||||||
|
--btcdhost="btcd" \
|
||||||
|
--rpccert="/rpc/rpc.cert" \
|
||||||
|
--rpcuser="$RPCUSER" \
|
||||||
|
--rpcpass="$RPCPASS" \
|
||||||
|
--debuglevel="$DEBUG" \
|
||||||
|
"$@"
|
Loading…
Reference in New Issue
Block a user