Skip to content

Commit

Permalink
Add ldknode into the stack
Browse files Browse the repository at this point in the history
  • Loading branch information
mrfelton committed Jun 17, 2024
1 parent 3d29f41 commit dbc7f84
Show file tree
Hide file tree
Showing 7 changed files with 212 additions and 14 deletions.
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Bolt 12 Playground

This Bolt 12 Playground provides a docker stack that comprises of bitcoind, [LND](https://github.com/lightningnetwork/lnd), [CLN](https://github.com/ElementsProject/lightning), [Eclair](https://github.com/ACINQ/eclair) and [LNDK](https://github.com/lndk-org/lndk). It connects everything together, initializes wallets, and creates channels between the nodes.
This Bolt 12 Playground provides a docker stack that comprises of bitcoind, [LND](https://github.com/lightningnetwork/lnd), [LNDK](https://github.com/lndk-org/lndk), [CLN](https://github.com/ElementsProject/lightning), [Eclair](https://github.com/ACINQ/eclair) and [LDK Node](https://github.com/lightningdevkit/ldk-node). It connects everything together, initializes wallets, and creates channels between the nodes.

You can use this to get familiar with [Bolt 12](https://bolt12.org/).

Expand All @@ -20,7 +20,7 @@ Run the following command to initialise the nodes:
./scripts/init.sh
```

This script sets up a dockerized network of lightning nodes and channels which are a mix of different Lightning Network implementations, including LND, c-lightning (CLN), and Eclair.
This script sets up a dockerized network of lightning nodes and channels which are a mix of different Lightning Network implementations, including LND, c-lightning (CLN), Eclair, and LDK Node.

***NOTE:** the init script must be run no later than 60 seconds after starting the nodes, otherwise nodes may crash due to an uninitialised blockchain*

Expand All @@ -41,6 +41,7 @@ The script sets up eight nodes:
- `lnd1` and `lnd2`: These are instances of the LND implementation.
- `cln1`, `cln2`, and `cln3`: These are instances of the c-lightning implementation.
- `eclair1`, `eclair2` and `eclair3`: These are instances of the Eclair implementation.
- `ldknode1`, and `ldknode2`: These are instances of the LDK Node implementation.

Each node is funded with Bitcoin through a series of transactions.

Expand All @@ -52,9 +53,11 @@ The script sets up the following channels, which allows for testing of Bolt 12 i
graph LR
lnd1 --10M (5M/5M)--> cln1
lnd1 --10M (5M/5M)--> eclair1
lnd1 --10M (5M/5M)--> ldknode1
lnd1 --10M (5M/5M)--> lnd2
lnd2 --10M (5M/5M)--> cln2
lnd2 --10M (5M/5M)--> eclair2
lnd2 --10M (5M/5M)--> ldknode2
cln2 --10M (5M/5M)--> cln3
eclair2 --10M (5M/5M)--> eclair3
```
Expand All @@ -67,7 +70,12 @@ LN-Visualizer is a tool that allows you to visualize the Lightning Network nodes

You can interact with any of the nodes using CLI commands. The bin scripts provided in the repository allow you to issue commands against any of the nodes.

To use the CLI commands, you need to pass the node name as the first argument to the relevant bin script. The node names are `lnd1`, `lnd2`, `cln1`, `cln2`, `cln3`, `eclair1`, `eclair2`, and `eclair3`.
To use the CLI commands, you need to pass the node name as the first argument to the relevant bin script. The node names are:

- `lnd1`, `lnd2`
- `cln1`, `cln2`, `cln3`
- `eclair1`, `eclair2`, `eclair3`
- `ldknode1`, `ldknode2`

Here's an example of how to use the CLI commands:

Expand Down
31 changes: 31 additions & 0 deletions bin/ldknode-cli
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env bash

# Check if both arguments are provided
if [ "$#" -ne 2 ]; then
echo "Usage: $0 <container_name> {getinfo|offer}"
exit 1
fi

# Function to get node pubkey
getinfo() {
docker compose logs "$1" | tac | grep "NODE_ID" | awk '{print $4}' | head -n 1
}

# Function to get offer
offer() {
docker compose logs "$1" | tac | grep "CREATED_OFFER" | sed 's/.*CREATED_OFFER: //' | head -n 1
}

# Main script logic
case "$2" in
getinfo)
getinfo "$1"
;;
offer)
offer "$1"
;;
*)
echo "Invalid command. Usage: $0 <container_name> {getinfo|offer}"
exit 1
;;
esac
68 changes: 57 additions & 11 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,4 @@
services:

bitcoind:
image: lncm/bitcoind:v27.0
restart: unless-stopped
networks:
testing_net:
ipv4_address: 172.30.1.1
volumes:
- "bitcoind:/data/.bitcoin"
- "./conf/bitcoind/bitcoin.conf:/data/.bitcoin/bitcoin.conf"

lnd1:
image: lightninglabs/lnd:v0.18.0-beta.1
restart: unless-stopped
Expand Down Expand Up @@ -71,6 +60,18 @@ services:
- "./conf/eclair/eclair1.conf:/eclair/eclair.conf"
- "./conf/eclair/logback-custom.xml:/eclair/logback-custom.xml"

ldknode1:
build: ./docker/ldknode
restart: unless-stopped
depends_on:
- electrs
networks:
testing_net:
ipv4_address: 172.30.1.32
command: /root/.ldknode 172.30.1.32:9735 regtest http://electrs:3002
volumes:
- "ldknode1:/root/.ldknode"

lnd2:
image: lightninglabs/lnd:v0.18.0-beta.1
restart: unless-stopped
Expand Down Expand Up @@ -132,6 +133,18 @@ services:
- "./conf/eclair/eclair2.conf:/eclair/eclair.conf"
- "./conf/eclair/logback-custom.xml:/eclair/logback-custom.xml"

ldknode2:
build: ./docker/ldknode
restart: unless-stopped
depends_on:
- electrs
networks:
testing_net:
ipv4_address: 172.30.2.32
command: /root/.ldknode 172.30.2.32:9735 regtest http://electrs:3002
volumes:
- "ldknode2:/root/.ldknode"

cln3:
image: elementsproject/lightningd:v24.05
restart: unless-stopped
Expand Down Expand Up @@ -163,6 +176,37 @@ services:
- "./conf/eclair/eclair3.conf:/eclair/eclair.conf"
- "./conf/eclair/logback-custom.xml:/eclair/logback-custom.xml"

# --- Additional services ---

bitcoind:
image: lncm/bitcoind:v27.0
restart: unless-stopped
networks:
testing_net:
ipv4_address: 172.30.1.1
volumes:
- "bitcoind:/data/.bitcoin"
- "./conf/bitcoind/bitcoin.conf:/data/.bitcoin/bitcoin.conf"

electrs:
image: blockstream/esplora:electrs-cd9f90c115751eb9d2bca9a4da89d10d048ae931
platform: linux/amd64
depends_on:
- bitcoind
command: >
"/app/electrs_bitcoin/bin/electrs"
"-vvvv"
"--timestamp"
"--jsonrpc-import"
"--cookie=user:pass"
"--network=regtest"
"--daemon-rpc-addr=bitcoind:43782"
"--http-addr=0.0.0.0:3002"
ports:
- "3002:3002"
networks:
- testing_net

blockgen:
build: ./docker/blockgen
command: [ "/bin/sh", "/app/blockgen.sh" ]
Expand Down Expand Up @@ -204,10 +248,12 @@ volumes:
lndk1:
cln1:
eclair1:
ldknode1:
lnd2:
lndk2:
cln2:
eclair2:
ldknode2:
cln3:
eclair3:

Expand Down
43 changes: 43 additions & 0 deletions docker/ldknode/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#################
# Builder image #
#################
FROM rust:1.78-bookworm AS builder

# References for lndk
ARG LDK_NODE_REF=e6ff79a6f1d3b6e182baa86a110e75854189dc94

# Add utils
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
protobuf-compiler \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

# Set the working directory in the Docker image
WORKDIR /usr/src

# Grab and install the latest version of lndk
RUN git clone https://github.com/tnull/ldk-node-offers-receive-test.git . \
&& git reset --hard ${LDK_NODE_REF} \
&& cargo build --release

# Copy the compiled binaries to /bin/
RUN cp ./target/release/ldk-node-offers-receive-test /bin/

###############
# final image #
###############
FROM debian:bookworm-slim AS final

# Add utils
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
bash \
curl \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

# Copy the compiled binaries from the builder image
COPY --from=builder /bin/ldk-node-offers-receive-test /usr/local/bin/

ENTRYPOINT ["ldk-node-offers-receive-test"]
36 changes: 36 additions & 0 deletions scripts/init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ eclair1() {
$DIR/../bin/eclair-cli eclair1 $@
}

ldknode1() {
$DIR/../bin/ldknode-cli ldknode1 $@
}

lnd2() {
$DIR/../bin/lncli lnd2 $@
}
Expand All @@ -42,6 +46,10 @@ eclair2() {
$DIR/../bin/eclair-cli eclair2 $@
}

ldknode2() {
$DIR/../bin/ldknode-cli ldknode2 $@
}

cln3() {
$DIR/../bin/lightning-cli cln3 $@
}
Expand Down Expand Up @@ -138,6 +146,12 @@ getNodeInfo() {
echo ECLAIR1_PUBKEY: $ECLAIR1_PUBKEY
echo ECLAIR1_NODE_URI: $ECLAIR1_NODE_URI

LDKNODE1_PUBKEY=$(ldknode1 getinfo)
LDKNODE1_NODE_URI="${LDKNODE1_PUBKEY}@172.30.1.32:9735"
echo LDKNODE1_PUBKEY: $LDKNODE1_PUBKEY
echo LDKNODE1_NODE_URI: $LDKNODE1_NODE_URI



LND2_NODE_INFO=$(lnd2 getinfo)
LND2_NODE_URI=$(echo ${LND2_NODE_INFO} | jq -r .uris[0])
Expand All @@ -146,6 +160,7 @@ getNodeInfo() {
echo LND2_NODE_URI: $LND2_NODE_URI



CLN2_NODE_INFO=$(cln2 getinfo)
CLN2_PUBKEY=$(echo ${CLN2_NODE_INFO} | jq -r .id)
CLN2_IP_ADDRESS=$(echo ${CLN2_NODE_INFO} | jq -r '.address[0].address')
Expand All @@ -161,6 +176,12 @@ getNodeInfo() {
echo ECLAIR2_PUBKEY: $ECLAIR2_PUBKEY
echo ECLAIR2_NODE_URI: $ECLAIR2_NODE_URI

LDKNODE2_PUBKEY=$(ldknode2 getinfo)
LDKNODE2_NODE_URI="${LDKNODE2_PUBKEY}@172.30.2.32:9735"
echo LDKNODE2_PUBKEY: $LDKNODE2_PUBKEY
echo LDKNODE2_NODE_URI: $LDKNODE2_NODE_URI



CLN3_NODE_INFO=$(cln3 getinfo)
CLN3_PUBKEY=$(echo ${CLN3_NODE_INFO} | jq -r .id)
Expand Down Expand Up @@ -223,6 +244,11 @@ openChannel() {
waitFor lnd1 connect $ECLAIR1_NODE_URI
waitFor lnd1 openchannel $ECLAIR1_PUBKEY 10000000 5000000

# Open a channel between lnd1 and ldknode1.
echo "Opening channel between lnd1 and ldknode1"
waitFor lnd1 connect $LDKNODE1_NODE_URI
waitFor lnd1 openchannel $LDKNODE1_PUBKEY 10000000 5000000



# Open a channel between lnd1 and lnd2.
Expand All @@ -231,6 +257,7 @@ openChannel() {
waitFor lnd1 openchannel $LND2_PUBKEY 10000000 5000000



# Open a channel between lnd2 and cln2.
echo "Opening channel between lnd2 and cln2"
waitFor lnd2 connect $CLN2_NODE_URI
Expand All @@ -241,6 +268,11 @@ openChannel() {
waitFor lnd2 connect $ECLAIR2_NODE_URI
waitFor lnd2 openchannel $ECLAIR2_PUBKEY 10000000 5000000

# Open a channel between lnd2 and ldknode2.
echo "Opening channel between lnd2 and ldknode2"
waitFor lnd2 connect $LDKNODE2_NODE_URI
waitFor lnd2 openchannel $LDKNODE2_PUBKEY 10000000 5000000


# Open a channel between cln2 and cln3.
echo "Opening channel between cln2 and cln3"
Expand All @@ -265,10 +297,12 @@ waitForNodes() {
waitFor lnd1 getinfo
waitFor cln1 getinfo
waitFor eclair1 getinfo
waitFor ldknode1 getinfo

waitFor lnd2 getinfo
waitFor cln2 getinfo
waitFor eclair2 getinfo
waitFor ldknode2 getinfo

waitFor cln3 getinfo
waitFor eclair3 getinfo
Expand All @@ -284,6 +318,8 @@ waitForGraphSync() {
["CLN1"]=$CLN1_PUBKEY
["CLN2"]=$CLN2_PUBKEY
["CLN3"]=$CLN3_PUBKEY
["LDKNODE1"]=$LDKNODE1_PUBKEY
["LDKNODE2"]=$LDKNODE2_PUBKEY
)

# Get the current time and set a timeout of 10 minutes
Expand Down
7 changes: 7 additions & 0 deletions test/functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,11 @@ generate_offer_cln() {

run $PROJECT_ROOT/bin/lightning-cli $generate_node offer 1000 "test offer from $generate_node"
echo "$output" | awk -F'"bolt12": "' '{print $2}' | awk -F'"' '{print $1}'
}

generate_offer_ldknode() {
local generate_node=$1

run $PROJECT_ROOT/bin/ldknode-cli $generate_node offer
echo "$output"
}
27 changes: 27 additions & 0 deletions test/test03_payments_ldknode.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env bats

# set -eo pipefail
# set -x

setup() {
load 'test_helper/common-setup'
_common_setup

source "$PROJECT_ROOT/test/functions.sh"
}

@test "Generate bolt12 offer on ldknode1 and pay from lndk1 (lnd1 -> ldknode1)" {
run generate_offer_ldknode 'ldknode1'
assert_line --partial 'lno'

run $PROJECT_ROOT/bin/lndk-cli lndk1 pay-offer $output 10000
assert_line --partial 'Successfully paid for offer!'
}

@test "Generate bolt12 offer on ldknode2 and pay from lndk1 (lnd1 -> ldknode2)" {
run generate_offer_ldknode 'ldknode2'
assert_line --partial 'lno'

run $PROJECT_ROOT/bin/lndk-cli lndk1 pay-offer $output 10000
assert_line --partial 'Successfully paid for offer!'
}

0 comments on commit dbc7f84

Please sign in to comment.