Skip to content

Commit ddcee61

Browse files
committed
Unify Docker Compose files with profiles for CLN, LND, and Eclair
Consolidate docker-compose-cln.yml and docker-compose-lnd.yml into a single docker-compose.yml using Docker Compose profiles. Add new Eclair service and CI workflow. Bump bitcoind to 29.1 for Eclair compatibility. - Use profiles (cln, lnd, eclair) to selectively start services - Add Eclair integration test workflow with wallet setup - Fix Eclair JAVA_OPTS formatting and config keys - Mine initial block in CLN/Eclair workflows to clear IBD state - Fix CLN socket permissions via chown/chmod - Update corepc-node feature to 29_0 Generated with the assistance of AI (Claude Code).
1 parent 34a888f commit ddcee61

10 files changed

Lines changed: 315 additions & 185 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-${{ runner.os }}-${{ runner.arch }}
26+
key: bitcoind-29.0-${{ 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 bin
37+
mkdir -p 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: 86 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,95 @@ jobs:
1313
- name: Checkout repository
1414
uses: actions/checkout@v4
1515

16-
- name: Install dependencies
16+
- name: Create temporary directory for CLN data
17+
run: echo "CLN_DATA_DIR=$(mktemp -d)" >> $GITHUB_ENV
18+
19+
- name: Start bitcoind and electrs
20+
run: docker compose up -d bitcoin electrs
21+
env:
22+
CLN_DATA_DIR: ${{ env.CLN_DATA_DIR }}
23+
24+
- name: Wait for bitcoind to be healthy
25+
run: |
26+
for i in $(seq 1 30); do
27+
if docker compose exec bitcoin bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass getblockchaininfo > /dev/null 2>&1; then
28+
echo "bitcoind is ready"
29+
exit 0
30+
fi
31+
echo "Waiting for bitcoind... ($i/30)"
32+
sleep 2
33+
done
34+
echo "ERROR: bitcoind not ready"
35+
exit 1
36+
37+
- name: Wait for electrs to be ready
38+
run: |
39+
for i in $(seq 1 30); do
40+
if curl -s http://127.0.0.1:3002/blocks/tip/height 2>/dev/null | grep -q '[0-9]'; then
41+
echo "electrs is ready"
42+
exit 0
43+
fi
44+
echo "Waiting for electrs... ($i/30)"
45+
sleep 2
46+
done
47+
echo "ERROR: electrs not ready"
48+
exit 1
49+
50+
- name: Mine initial block for CLN
51+
# CLN refuses to start until bitcoind's initial block download is complete.
52+
# In regtest with 0 blocks, IBD stays true. Mining one block resolves this.
53+
run: |
54+
docker compose exec bitcoin bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass createwallet miner
55+
ADDR=$(docker compose exec bitcoin bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass -rpcwallet=miner getnewaddress)
56+
docker compose exec bitcoin bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass generatetoaddress 1 "$ADDR"
57+
docker compose exec bitcoin bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass unloadwallet miner
58+
59+
- name: Wait for electrs to index mined block
1760
run: |
18-
sudo apt-get update -y
19-
sudo apt-get install -y socat
61+
for i in $(seq 1 30); do
62+
HEIGHT=$(curl -s http://127.0.0.1:3002/blocks/tip/height 2>/dev/null)
63+
if [ "$HEIGHT" -ge 1 ] 2>/dev/null; then
64+
echo "electrs indexed to height $HEIGHT"
65+
exit 0
66+
fi
67+
echo "Waiting for electrs to index... ($i/30)"
68+
sleep 2
69+
done
70+
echo "ERROR: electrs did not index block"
71+
exit 1
2072
21-
- name: Start bitcoind, electrs, and lightningd
22-
run: docker compose -f docker-compose-cln.yml up -d
73+
- name: Start lightningd
74+
run: docker compose --profile cln up -d cln
75+
env:
76+
CLN_DATA_DIR: ${{ env.CLN_DATA_DIR }}
77+
78+
- name: Wait for CLN to be ready
79+
# CLN creates files as root with restrictive permissions, so we check
80+
# for the socket inside the container rather than on the host volume.
81+
run: |
82+
for i in $(seq 1 30); do
83+
if docker compose exec cln test -S /root/.lightning/regtest/lightning-rpc 2>/dev/null; then
84+
echo "CLN RPC socket found"
85+
break
86+
fi
87+
echo "Waiting for CLN RPC socket... ($i/30)"
88+
sleep 2
89+
done
90+
docker compose exec cln test -S /root/.lightning/regtest/lightning-rpc || {
91+
echo "ERROR: CLN RPC socket not found after 60 seconds"
92+
docker compose --profile cln logs cln
93+
exit 1
94+
}
2395
24-
- name: Forward lightningd RPC socket
96+
- name: Set permissions for CLN data directory
2597
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&
98+
sudo chown -R $(id -u):$(id -g) $CLN_DATA_DIR
99+
sudo chmod -R 755 $CLN_DATA_DIR
100+
env:
101+
CLN_DATA_DIR: ${{ env.CLN_DATA_DIR }}
28102

29103
- name: Run CLN integration tests
30-
run: RUSTFLAGS="--cfg cln_test" cargo test --test integration_tests_cln
104+
run: CLN_SOCKET_PATH=$CLN_DATA_DIR/regtest/lightning-rpc
105+
RUSTFLAGS="--cfg cln_test" cargo test --test integration_tests_cln -- --show-output --test-threads=1
106+
env:
107+
CLN_DATA_DIR: ${{ env.CLN_DATA_DIR }}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
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 up -d
18+
19+
- name: Wait for bitcoind to be healthy
20+
run: |
21+
for i in $(seq 1 30); do
22+
if docker compose 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: Wait for electrs to be ready
33+
run: |
34+
for i in $(seq 1 30); do
35+
if curl -s http://127.0.0.1:3002/blocks/tip/height 2>/dev/null | grep -q '[0-9]'; then
36+
echo "electrs is ready"
37+
exit 0
38+
fi
39+
echo "Waiting for electrs... ($i/30)"
40+
sleep 2
41+
done
42+
echo "ERROR: electrs not ready"
43+
exit 1
44+
45+
- name: Create Eclair wallet and mine initial block
46+
# Eclair requires a named wallet on bitcoind (configured via
47+
# eclair.bitcoind.wallet). Regtest also starts with IBD=true at height 0;
48+
# mining one block clears it so that Eclair can finish startup.
49+
run: |
50+
docker compose exec bitcoin bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass createwallet eclair
51+
ADDR=$(docker compose exec bitcoin bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass -rpcwallet=eclair getnewaddress)
52+
docker compose exec bitcoin bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass generatetoaddress 1 "$ADDR"
53+
54+
- name: Wait for electrs to index mined block
55+
run: |
56+
for i in $(seq 1 30); do
57+
HEIGHT=$(curl -s http://127.0.0.1:3002/blocks/tip/height 2>/dev/null)
58+
if [ "$HEIGHT" -ge 1 ] 2>/dev/null; then
59+
echo "electrs indexed to height $HEIGHT"
60+
exit 0
61+
fi
62+
echo "Waiting for electrs to index... ($i/30)"
63+
sleep 2
64+
done
65+
echo "ERROR: electrs did not index block"
66+
exit 1
67+
68+
- name: Start Eclair
69+
run: docker compose --profile eclair up -d
70+
71+
- name: Wait for Eclair to be ready
72+
run: |
73+
for i in $(seq 1 60); do
74+
if curl -s -u :eclairpassword -X POST http://127.0.0.1:8080/getinfo > /dev/null 2>&1; then
75+
echo "Eclair is ready"
76+
exit 0
77+
fi
78+
echo "Waiting for Eclair... ($i/60)"
79+
sleep 5
80+
done
81+
echo "Eclair failed to start"
82+
docker logs ldk-node-eclair-1
83+
exit 1
84+
85+
- name: Run Eclair integration tests
86+
run: RUSTFLAGS="--cfg eclair_test" cargo test --test integration_tests_eclair -- --show-output --test-threads=1

.github/workflows/lnd-integration.yml

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,31 @@ jobs:
3333
fi
3434
3535
- name: Create temporary directory for LND data
36-
id: create-temp-dir
3736
run: echo "LND_DATA_DIR=$(mktemp -d)" >> $GITHUB_ENV
3837

3938
- name: Start bitcoind, electrs, and LND
40-
run: docker compose -f docker-compose-lnd.yml up -d
39+
run: docker compose --profile lnd up -d
4140
env:
4241
LND_DATA_DIR: ${{ env.LND_DATA_DIR }}
4342

43+
- name: Wait for LND to be ready
44+
# LND sets file permissions to 0700 (PR 4622), so we check for the
45+
# macaroon inside the container rather than on the host volume mount.
46+
run: |
47+
for i in $(seq 1 30); do
48+
if docker exec ldk-node-lnd test -f /root/.lnd/data/chain/bitcoin/regtest/admin.macaroon 2>/dev/null; then
49+
echo "LND macaroon found"
50+
break
51+
fi
52+
echo "Waiting for LND macaroon... ($i/30)"
53+
sleep 2
54+
done
55+
docker exec ldk-node-lnd test -f /root/.lnd/data/chain/bitcoin/regtest/admin.macaroon || {
56+
echo "ERROR: LND macaroon not found after 60 seconds"
57+
docker compose --profile lnd logs lnd
58+
exit 1
59+
}
60+
4461
- name: Set permissions for LND data directory
4562
# In PR 4622 (https://github.com/lightningnetwork/lnd/pull/4622),
4663
# LND sets file permissions to 0700, preventing test code from accessing them.
@@ -49,8 +66,26 @@ jobs:
4966
env:
5067
LND_DATA_DIR: ${{ env.LND_DATA_DIR }}
5168

69+
- name: Wait for LND gRPC to be ready
70+
run: |
71+
for i in $(seq 1 15); do
72+
if docker exec ldk-node-lnd lncli \
73+
--rpcserver=localhost:8081 \
74+
--tlscertpath=/root/.lnd/tls.cert \
75+
--macaroonpath=/root/.lnd/data/chain/bitcoin/regtest/admin.macaroon \
76+
--network=regtest getinfo 2>/dev/null; then
77+
echo "LND gRPC is ready"
78+
exit 0
79+
fi
80+
echo "Waiting for LND gRPC... ($i/15)"
81+
sleep 2
82+
done
83+
echo "ERROR: LND gRPC not ready after 30 seconds"
84+
docker compose --profile lnd logs lnd
85+
exit 1
86+
5287
- name: Run LND integration tests
5388
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
89+
RUSTFLAGS="--cfg lnd_test" cargo test --test integration_tests_lnd -- --show-output --test-threads=1
5590
env:
5691
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
@@ -49,7 +49,7 @@ jobs:
4949
uses: actions/cache@v4
5050
with:
5151
path: bin/bitcoind-${{ runner.os }}-${{ runner.arch }}
52-
key: bitcoind-${{ runner.os }}-${{ runner.arch }}
52+
key: bitcoind-29.0-${{ runner.os }}-${{ runner.arch }}
5353
- name: Enable caching for electrs
5454
id: cache-electrs
5555
uses: actions/cache@v4
@@ -60,7 +60,7 @@ jobs:
6060
if: "matrix.platform != 'windows-latest' && (steps.cache-bitcoind.outputs.cache-hit != 'true' || steps.cache-electrs.outputs.cache-hit != 'true')"
6161
run: |
6262
source ./scripts/download_bitcoind_electrs.sh
63-
mkdir bin
63+
mkdir -p bin
6464
mv "$BITCOIND_EXE" bin/bitcoind-${{ runner.os }}-${{ runner.arch }}
6565
mv "$ELECTRS_EXE" bin/electrs-${{ runner.os }}-${{ runner.arch }}
6666
- name: Set bitcoind/electrs environment variables

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,11 @@ criterion = { version = "0.7.0", features = ["async_tokio"] }
9393
ldk-node-062 = { package = "ldk-node", version = "=0.6.2" }
9494

9595
[target.'cfg(not(no_download))'.dev-dependencies]
96-
electrsd = { version = "0.36.1", default-features = false, features = ["legacy", "esplora_a33e97e1", "corepc-node_27_2"] }
96+
electrsd = { version = "0.36.1", default-features = false, features = ["legacy", "esplora_a33e97e1", "corepc-node_29_0"] }
9797

9898
[target.'cfg(no_download)'.dev-dependencies]
9999
electrsd = { version = "0.36.1", default-features = false, features = ["legacy"] }
100-
corepc-node = { version = "0.10.0", default-features = false, features = ["27_2"] }
100+
corepc-node = { version = "0.10.0", default-features = false, features = ["29_0"] }
101101

102102
[target.'cfg(cln_test)'.dev-dependencies]
103103
clightningrpc = { version = "0.3.0-beta.8", default-features = false }

docker-compose-cln.yml

Lines changed: 0 additions & 73 deletions
This file was deleted.

0 commit comments

Comments
 (0)