3.9 KiB
Lightning regtest (NixOS-native)
A reproducible, hermetic Lightning regtest stack — bitcoind(regtest) +
Core Lightning + LND in one VM — replacing the core of the docker
legend-regtest-enviroment (aiolabs/omnixient#27). No docker, no host state;
the whole thing is a NixOS VM built from the bitcoin pack's nix-bitcoin
modules.
There are two ways to use it, sharing one node definition
(tests/regtest-node.nix) so they can't drift:
| Mode | Command | For |
|---|---|---|
| CI test | nix build .#checks.x86_64-linux.regtest-core -L |
automated pass/fail (fund → channel → pay → settle) |
| Interactive dev VM | nix run .#regtest |
poking the nodes by hand in a real shell |
Interactive dev VM — nix run .#regtest
The friendly path. Boots the stack headless and drops you straight into
an SSH shell as the operator user — real terminal, copy/paste,
scrollback, no log spam:
nix run .#regtest
You land in the VM with:
- user
operator, passwordpassword(alsosudo) — a throwaway local VM with fake coins, so the trivial password is fine. Yoursettings.sshKeysare accepted too, if set. - aliases:
btc→bitcoin-cli -rpcwallet=test,cln→lightning-cli;lncliis the LND CLI as-is. (Plainbitcoin-cliworks too — the singletestwallet auto-selects.) - helper:
regtest-fund— funds LND on-chain and opens an LND→CLN channel, so you start with a working channel instead of building it by hand. - nodes:
bitcoind(regtest), Core Lightning p2p:9735, LND p2p:9736. The chain pre-mines 110 blocks on boot (give it a few seconds).
exit shuts the VM down and discards it (ephemeral disk in a tmp file).
A typical spin
regtest-fund # fund + open a channel
bolt11=$(cln invoice 50000000 demo demo | jq -r .bolt11)
lncli payinvoice --force "$bolt11" # LND pays CLN
cln listinvoices demo | jq '.invoices[0].status' # paid
lncli listchannels | jq '.channels[] | {local_balance, remote_balance}'
btc getblockcount
How it boots
nix run .#regtest runs a small wrapper that:
- boots
packages.regtest-vm(asystem.build.vm) headless, with an ephemeral disk andhost:2222 → guest:22forwarded; - waits for SSH, then
ssh operator@localhost; - tears the VM down and cleans up the temp disk on exit.
CI test — regtest-core
The automated assertion that the stack actually settles a payment:
nix build .#checks.x86_64-linux.regtest-core -L # ~60s; exit 0 = passed
nix flake check -L # runs it with the rest
It pre-mines the chain, funds LND, opens an LND→CLN channel, has CLN issue
an invoice, LND pays it, and asserts CLN sees it paid. To poke the test
node by hand instead, use the raw nixos-test driver:
nix build .#checks.x86_64-linux.regtest-core.driverInteractive
./result/bin/nixos-test-driver # Python REPL; regtest.succeed("…")
(The nix run .#regtest dev VM is the nicer interactive experience — the
driver REPL is awkward for ad-hoc use: Ctrl-C tears down the VM, the
QEMU window has no clipboard, and daemon logs flood the console.)
Layout
tests/regtest-node.nix— shared bitcoind + CLN + LND config (the one source of truth). Consumers also importnix-bitcoin.nixosModules.default.tests/regtest-core.nix— the CI test; imports the shared node.tests/regtest-interactive.nix— the dev-VM layer (SSH, operator login, aliases,regtest-fund, port forward); imports nothing about the test.flake.nix— wireschecks.regtest-core,packages.regtest-vm, andapps.regtest.
Follow-up: regtest-full
This is the core tier (#27 tier 1). A regtest-full tier — adding
boltz / elements-liquid / litd / lnbits like the docker stack, and more
directions (CLN→LND, an eclair node) — is the documented follow-up on
aiolabs/omnixient#27.