Skip to content

Commit 2089a6c

Browse files
committed
feat(test): add interop test harness for CLN, LND, Eclair
Add a shared interop test framework with: - ExternalNode trait abstracting CLN, LND, and Eclair - Reusable scenario functions (channel lifecycle, payments, disconnect, splice, combo orchestrator with 16 disconnect×payment×close permutations) - Docker Compose and CI workflows for all three implementations - Single-function test pattern matching the original test_cln structure
1 parent eef5142 commit 2089a6c

25 files changed

Lines changed: 3201 additions & 335 deletions

.github/workflows/benchmarks.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
uses: actions/cache@v4
2424
with:
2525
path: bin/bitcoind-${{ runner.os }}-${{ runner.arch }}
26-
key: bitcoind-29.0-${{ runner.os }}-${{ runner.arch }}
26+
key: bitcoind-${{ runner.os }}-${{ runner.arch }}
2727
- name: Enable caching for electrs
2828
id: cache-electrs
2929
uses: actions/cache@v4
@@ -34,7 +34,7 @@ jobs:
3434
if: "(steps.cache-bitcoind.outputs.cache-hit != 'true' || steps.cache-electrs.outputs.cache-hit != 'true')"
3535
run: |
3636
source ./scripts/download_bitcoind_electrs.sh
37-
mkdir -p bin
37+
mkdir bin
3838
mv "$BITCOIND_EXE" bin/bitcoind-${{ runner.os }}-${{ runner.arch }}
3939
mv "$ELECTRS_EXE" bin/electrs-${{ runner.os }}-${{ runner.arch }}
4040
- name: Set bitcoind/electrs environment variables

.github/workflows/cln-integration.yml

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,62 @@ jobs:
1313
- name: Checkout repository
1414
uses: actions/checkout@v4
1515

16-
- name: Install dependencies
17-
run: |
18-
sudo apt-get update -y
19-
sudo apt-get install -y socat
16+
- name: Create temporary directory for CLN data
17+
run: echo "CLN_DATA_DIR=$(mktemp -d)" >> $GITHUB_ENV
2018

2119
- name: Start bitcoind, electrs, and lightningd
2220
run: docker compose -p ldk-node -f tests/docker/docker-compose-cln.yml up -d
2321

24-
- name: Forward lightningd RPC socket
22+
- name: Wait for bitcoind to be healthy
23+
run: |
24+
for i in $(seq 1 30); do
25+
if docker compose -p ldk-node -f tests/docker/docker-compose-cln.yml exec bitcoin bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass getblockchaininfo > /dev/null 2>&1; then
26+
echo "bitcoind is ready"
27+
exit 0
28+
fi
29+
echo "Waiting for bitcoind... ($i/30)"
30+
sleep 2
31+
done
32+
echo "ERROR: bitcoind not ready"
33+
exit 1
34+
35+
- name: Mine initial block for CLN
36+
run: |
37+
docker compose -p ldk-node -f tests/docker/docker-compose-cln.yml exec bitcoin bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass createwallet miner
38+
ADDR=$(docker compose -p ldk-node -f tests/docker/docker-compose-cln.yml exec bitcoin bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass -rpcwallet=miner getnewaddress)
39+
docker compose -p ldk-node -f tests/docker/docker-compose-cln.yml exec bitcoin bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass generatetoaddress 1 "$ADDR"
40+
docker compose -p ldk-node -f tests/docker/docker-compose-cln.yml exec bitcoin bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass unloadwallet miner
41+
42+
- name: Start lightningd
43+
run: docker compose -p ldk-node -f tests/docker/docker-compose-cln.yml up -d cln
44+
env:
45+
CLN_DATA_DIR: ${{ env.CLN_DATA_DIR }}
46+
47+
- name: Wait for CLN to be ready
48+
run: |
49+
for i in $(seq 1 30); do
50+
if docker compose -p ldk-node -f tests/docker/docker-compose-cln.yml exec cln test -S /root/.lightning/regtest/lightning-rpc 2>/dev/null; then
51+
echo "CLN RPC socket found"
52+
break
53+
fi
54+
echo "Waiting for CLN RPC socket... ($i/30)"
55+
sleep 2
56+
done
57+
docker compose -p ldk-node -f tests/docker/docker-compose-cln.yml exec cln test -S /root/.lightning/regtest/lightning-rpc || {
58+
echo "ERROR: CLN RPC socket not found after 60 seconds"
59+
docker compose -p ldk-node -f tests/docker/docker-compose-cln.yml logs cln
60+
exit 1
61+
}
62+
63+
- name: Set permissions for CLN data directory
2564
run: |
26-
docker exec ldk-node-cln-1 sh -c "socat -d -d TCP-LISTEN:9937,fork,reuseaddr UNIX-CONNECT:/root/.lightning/regtest/lightning-rpc&"
27-
socat -d -d UNIX-LISTEN:/tmp/lightning-rpc,reuseaddr,fork TCP:127.0.0.1:9937&
65+
sudo chown -R $(id -u):$(id -g) $CLN_DATA_DIR
66+
sudo chmod -R u+rwX,go+rX $CLN_DATA_DIR
67+
env:
68+
CLN_DATA_DIR: ${{ env.CLN_DATA_DIR }}
2869

2970
- name: Run CLN integration tests
30-
run: RUSTFLAGS="--cfg cln_test" cargo test --test integration_tests_cln
71+
run: CLN_SOCKET_PATH=$CLN_DATA_DIR/regtest/lightning-rpc
72+
RUSTFLAGS="--cfg cln_test" cargo test --test integration_tests_cln -- --show-output --test-threads=1
73+
env:
74+
CLN_DATA_DIR: ${{ env.CLN_DATA_DIR }}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: CI Checks - Eclair Integration Tests
2+
3+
on: [push, pull_request]
4+
5+
concurrency:
6+
group: ${{ github.workflow }}-${{ github.ref }}
7+
cancel-in-progress: true
8+
9+
jobs:
10+
check-eclair:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Checkout repository
14+
uses: actions/checkout@v4
15+
16+
- name: Start bitcoind and electrs
17+
run: docker compose -p ldk-node -f tests/docker/docker-compose-eclair.yml up -d bitcoin electrs
18+
19+
- name: Wait for bitcoind to be healthy
20+
run: |
21+
for i in $(seq 1 30); do
22+
if docker compose -p ldk-node -f tests/docker/docker-compose-eclair.yml exec bitcoin bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass getblockchaininfo > /dev/null 2>&1; then
23+
echo "bitcoind is ready"
24+
exit 0
25+
fi
26+
echo "Waiting for bitcoind... ($i/30)"
27+
sleep 2
28+
done
29+
echo "ERROR: bitcoind not ready"
30+
exit 1
31+
32+
- name: Create wallets on bitcoind
33+
run: |
34+
docker compose -p ldk-node -f tests/docker/docker-compose-eclair.yml exec bitcoin bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass createwallet eclair
35+
docker compose -p ldk-node -f tests/docker/docker-compose-eclair.yml exec bitcoin bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass -rpcwallet=eclair getnewaddress
36+
docker compose -p ldk-node -f tests/docker/docker-compose-eclair.yml exec bitcoin bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass createwallet ldk_node_test
37+
38+
- name: Start Eclair
39+
run: docker compose -p ldk-node -f tests/docker/docker-compose-eclair.yml up -d eclair
40+
41+
- name: Wait for Eclair to be ready
42+
run: |
43+
for i in $(seq 1 60); do
44+
if curl -sf -u :eclairpassword -X POST http://127.0.0.1:8080/getinfo > /dev/null 2>&1; then
45+
echo "Eclair is ready"
46+
exit 0
47+
fi
48+
echo "Waiting for Eclair... ($i/60)"
49+
sleep 5
50+
done
51+
echo "Eclair failed to start"
52+
docker compose -p ldk-node -f tests/docker/docker-compose-eclair.yml logs eclair
53+
exit 1
54+
55+
- name: Run Eclair integration tests
56+
run: RUSTFLAGS="--cfg eclair_test" cargo test --test integration_tests_eclair -- --show-output --test-threads=1

.github/workflows/lnd-integration.yml

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@ jobs:
1414
uses: actions/checkout@v4
1515

1616
- name: Check and install CMake if needed
17-
# lnd_grpc_rust (via prost-build v0.10.4) requires CMake >= 3.5 but is incompatible with CMake >= 4.0.
18-
# This step checks if CMake is missing, below 3.5, or 4.0 or higher, and installs CMake 3.31.6 if needed,
19-
# ensuring compatibility with prost-build in ubuntu-latest.
2017
run: |
2118
if ! command -v cmake &> /dev/null ||
2219
[ "$(cmake --version | head -n1 | cut -d' ' -f3)" \< "3.5" ] ||
@@ -33,24 +30,54 @@ jobs:
3330
fi
3431
3532
- name: Create temporary directory for LND data
36-
id: create-temp-dir
3733
run: echo "LND_DATA_DIR=$(mktemp -d)" >> $GITHUB_ENV
3834

3935
- name: Start bitcoind, electrs, and LND
4036
run: docker compose -p ldk-node -f tests/docker/docker-compose-lnd.yml up -d
4137
env:
4238
LND_DATA_DIR: ${{ env.LND_DATA_DIR }}
4339

40+
- name: Wait for LND to be ready
41+
run: |
42+
for i in $(seq 1 30); do
43+
if docker exec ldk-node-lnd test -f /root/.lnd/data/chain/bitcoin/regtest/admin.macaroon 2>/dev/null; then
44+
echo "LND macaroon found"
45+
break
46+
fi
47+
echo "Waiting for LND macaroon... ($i/30)"
48+
sleep 2
49+
done
50+
docker exec ldk-node-lnd test -f /root/.lnd/data/chain/bitcoin/regtest/admin.macaroon || {
51+
echo "ERROR: LND macaroon not found after 60 seconds"
52+
docker compose -p ldk-node -f tests/docker/docker-compose-lnd.yml logs lnd
53+
exit 1
54+
}
55+
4456
- name: Set permissions for LND data directory
45-
# In PR 4622 (https://github.com/lightningnetwork/lnd/pull/4622),
46-
# LND sets file permissions to 0700, preventing test code from accessing them.
47-
# This step ensures the test suite has the necessary permissions.
48-
run: sudo chmod -R 755 $LND_DATA_DIR
57+
run: sudo chmod -R u+rwX,go+rX $LND_DATA_DIR
4958
env:
5059
LND_DATA_DIR: ${{ env.LND_DATA_DIR }}
5160

61+
- name: Wait for LND gRPC to be ready
62+
run: |
63+
for i in $(seq 1 15); do
64+
if docker exec ldk-node-lnd lncli \
65+
--rpcserver=localhost:8081 \
66+
--tlscertpath=/root/.lnd/tls.cert \
67+
--macaroonpath=/root/.lnd/data/chain/bitcoin/regtest/admin.macaroon \
68+
--network=regtest getinfo 2>/dev/null; then
69+
echo "LND gRPC is ready"
70+
exit 0
71+
fi
72+
echo "Waiting for LND gRPC... ($i/15)"
73+
sleep 2
74+
done
75+
echo "ERROR: LND gRPC not ready after 30 seconds"
76+
docker compose -p ldk-node -f tests/docker/docker-compose-lnd.yml logs lnd
77+
exit 1
78+
5279
- name: Run LND integration tests
5380
run: LND_CERT_PATH=$LND_DATA_DIR/tls.cert LND_MACAROON_PATH=$LND_DATA_DIR/data/chain/bitcoin/regtest/admin.macaroon
54-
RUSTFLAGS="--cfg lnd_test" cargo test --test integration_tests_lnd -- --exact --show-output
81+
RUSTFLAGS="--cfg lnd_test" cargo test --test integration_tests_lnd -- --show-output --test-threads=1
5582
env:
5683
LND_DATA_DIR: ${{ env.LND_DATA_DIR }}

.github/workflows/rust.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ jobs:
5353
uses: actions/cache@v4
5454
with:
5555
path: bin/bitcoind-${{ runner.os }}-${{ runner.arch }}
56-
key: bitcoind-29.0-${{ runner.os }}-${{ runner.arch }}
56+
key: bitcoind-${{ runner.os }}-${{ runner.arch }}
5757
- name: Enable caching for electrs
5858
id: cache-electrs
5959
uses: actions/cache@v4
@@ -64,7 +64,7 @@ jobs:
6464
if: "matrix.platform != 'windows-latest' && (steps.cache-bitcoind.outputs.cache-hit != 'true' || steps.cache-electrs.outputs.cache-hit != 'true')"
6565
run: |
6666
source ./scripts/download_bitcoind_electrs.sh
67-
mkdir -p bin
67+
mkdir bin
6868
mv "$BITCOIND_EXE" bin/bitcoind-${{ runner.os }}-${{ runner.arch }}
6969
mv "$ELECTRS_EXE" bin/electrs-${{ runner.os }}-${{ runner.arch }}
7070
- name: Set bitcoind/electrs environment variables

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ check-cfg = [
125125
"cfg(tokio_unstable)",
126126
"cfg(cln_test)",
127127
"cfg(lnd_test)",
128+
"cfg(eclair_test)",
128129
"cfg(cycle_tests)",
129130
]
130131

docker-compose.yml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
version: '3'
2-
31
services:
42
bitcoin:
5-
image: blockstream/bitcoind:27.2
3+
image: blockstream/bitcoind:30.2
64
platform: linux/amd64
75
command:
86
[
@@ -14,11 +12,15 @@ services:
1412
"-rpcuser=user",
1513
"-rpcpassword=pass",
1614
"-fallbackfee=0.00001",
17-
"-rest"
15+
"-rest",
16+
"-zmqpubrawblock=tcp://0.0.0.0:28332",
17+
"-zmqpubrawtx=tcp://0.0.0.0:28333"
1818
]
1919
ports:
2020
- "18443:18443" # Regtest REST and RPC port
2121
- "18444:18444" # Regtest P2P port
22+
- "28332:28332" # ZMQ block port
23+
- "28333:28333" # ZMQ tx port
2224
networks:
2325
- bitcoin-electrs
2426
healthcheck:
@@ -41,10 +43,12 @@ services:
4143
"--cookie=user:pass",
4244
"--network=regtest",
4345
"--daemon-rpc-addr=bitcoin:18443",
44-
"--http-addr=0.0.0.0:3002"
46+
"--http-addr=0.0.0.0:3002",
47+
"--electrum-rpc-addr=0.0.0.0:50001"
4548
]
4649
ports:
4750
- "3002:3002"
51+
- "50001:50001"
4852
networks:
4953
- bitcoin-electrs
5054

0 commit comments

Comments
 (0)