Merge #209: Lightning loop
e9204946d4
lightning-loop: add tests (nixbitcoin)491d83a658
lightning-loop: add module (nixbitcoin)8f3588b13f
lnd: higher attempt limit for less-powerful machines (nixbitcoin)1bb801ad7b
lightning-loop: add pkg (nixbitcoin) Pull request description: ACKs for top commit: jonasnick: ACKe9204946d4
Tree-SHA512: cc8bb85978350dd530c3c8d2c9aca5ddc4ab1f72cdd27d031bb303eca1d9473f18e45bc119c62bb2991faa32b3e1d42e4439f02a56ab3a6b975b0bd491195604
This commit is contained in:
commit
0baeb2acce
@ -28,6 +28,7 @@ env:
|
|||||||
- PKG=electrs STABLE=1
|
- PKG=electrs STABLE=1
|
||||||
- PKG=electrs STABLE=0
|
- PKG=electrs STABLE=0
|
||||||
- PKG=liquid-swap STABLE=1
|
- PKG=liquid-swap STABLE=1
|
||||||
|
- PKG=lightning-loop STABLE=0
|
||||||
- PKG=nixops19_09 STABLE=1
|
- PKG=nixops19_09 STABLE=1
|
||||||
script:
|
script:
|
||||||
- printf '%s (%s)\n' "$NIX_PATH" "$VER"
|
- printf '%s (%s)\n' "$NIX_PATH" "$VER"
|
||||||
|
@ -129,6 +129,12 @@
|
|||||||
# a network-level as much as possible.
|
# a network-level as much as possible.
|
||||||
# nix-bitcoin.netns-isolation.enable = true;
|
# nix-bitcoin.netns-isolation.enable = true;
|
||||||
|
|
||||||
|
### lightning-loop
|
||||||
|
# Enable this module to use lightninglab's non-custodial off/on chain bridge.
|
||||||
|
# loopd (lightning-loop daemon) will be started automatically. Users can
|
||||||
|
# interact with off/on chain bridge using `loop in` and `loop out`.
|
||||||
|
# services.lightning-loop.enable = true;
|
||||||
|
|
||||||
# FIXME: Define your hostname.
|
# FIXME: Define your hostname.
|
||||||
networking.hostName = "nix-bitcoin";
|
networking.hostName = "nix-bitcoin";
|
||||||
time.timeZone = "UTC";
|
time.timeZone = "UTC";
|
||||||
|
72
modules/lightning-loop.nix
Normal file
72
modules/lightning-loop.nix
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.lightning-loop;
|
||||||
|
inherit (config) nix-bitcoin-services;
|
||||||
|
secretsDir = config.nix-bitcoin.secretsDir;
|
||||||
|
in {
|
||||||
|
|
||||||
|
options.services.lightning-loop = {
|
||||||
|
enable = mkEnableOption "lightning-loop";
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.nix-bitcoin.lightning-loop;
|
||||||
|
defaultText = "pkgs.nix-bitcoin.lightning-loop";
|
||||||
|
description = "The package providing lightning-loop binaries.";
|
||||||
|
};
|
||||||
|
proxy = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "Connect through SOCKS5 proxy";
|
||||||
|
};
|
||||||
|
extraArgs = mkOption {
|
||||||
|
type = types.separatedString " ";
|
||||||
|
default = "";
|
||||||
|
description = "Extra command line arguments passed to loopd.";
|
||||||
|
};
|
||||||
|
cli = mkOption {
|
||||||
|
default = pkgs.writeScriptBin "loop"
|
||||||
|
# Switch user because lnd makes datadir contents readable by user only
|
||||||
|
''
|
||||||
|
exec sudo -u lnd ${cfg.package}/bin/loop "$@"
|
||||||
|
'';
|
||||||
|
description = "Binary to connect with the lnd instance.";
|
||||||
|
};
|
||||||
|
enforceTor = nix-bitcoin-services.enforceTor;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{ assertion = config.services.lnd.enable;
|
||||||
|
message = "lightning-loop requires lnd.";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
environment.systemPackages = [ cfg.package (hiPrio cfg.cli) ];
|
||||||
|
|
||||||
|
systemd.services.lightning-loop = {
|
||||||
|
description = "Run loopd";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
requires = [ "lnd.service" ];
|
||||||
|
after = [ "lnd.service" ];
|
||||||
|
serviceConfig = nix-bitcoin-services.defaultHardening // {
|
||||||
|
ExecStart = ''
|
||||||
|
${cfg.package}/bin/loopd \
|
||||||
|
--lnd.host=${config.services.lnd.listen}:10009 \
|
||||||
|
--lnd.macaroondir=${config.services.lnd.dataDir}/chain/bitcoin/mainnet \
|
||||||
|
--lnd.tlspath=${secretsDir}/lnd-cert \
|
||||||
|
${optionalString (cfg.proxy != null) "--server.proxy=${cfg.proxy}"} \
|
||||||
|
${cfg.extraArgs}
|
||||||
|
'';
|
||||||
|
User = "lnd";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = "10s";
|
||||||
|
ReadWritePaths = "${config.services.lnd.dataDir}";
|
||||||
|
} // (if cfg.enforceTor
|
||||||
|
then nix-bitcoin-services.allowTor
|
||||||
|
else nix-bitcoin-services.allowAnyIP);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -159,7 +159,7 @@ in {
|
|||||||
in [
|
in [
|
||||||
# Run fully privileged for secrets dir write access
|
# Run fully privileged for secrets dir write access
|
||||||
"+${nix-bitcoin-services.script ''
|
"+${nix-bitcoin-services.script ''
|
||||||
attempts=50
|
attempts=250
|
||||||
while ! { exec 3>/dev/tcp/127.0.0.1/${restPort} && exec 3>&-; } &>/dev/null; do
|
while ! { exec 3>/dev/tcp/127.0.0.1/${restPort} && exec 3>&-; } &>/dev/null; do
|
||||||
((attempts-- == 0)) && { echo "lnd REST service unreachable"; exit 1; }
|
((attempts-- == 0)) && { echo "lnd REST service unreachable"; exit 1; }
|
||||||
sleep 0.1
|
sleep 0.1
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
./recurring-donations.nix
|
./recurring-donations.nix
|
||||||
./hardware-wallets.nix
|
./hardware-wallets.nix
|
||||||
./lnd.nix
|
./lnd.nix
|
||||||
|
./lightning-loop.nix
|
||||||
./secrets/secrets.nix
|
./secrets/secrets.nix
|
||||||
./netns-isolation.nix
|
./netns-isolation.nix
|
||||||
./dbus.nix
|
./dbus.nix
|
||||||
|
@ -127,6 +127,10 @@ in {
|
|||||||
id = 21;
|
id = 21;
|
||||||
connections = [];
|
connections = [];
|
||||||
};
|
};
|
||||||
|
lightning-loop = {
|
||||||
|
id = 22;
|
||||||
|
connections = [ "lnd" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services = {
|
systemd.services = {
|
||||||
@ -291,6 +295,14 @@ in {
|
|||||||
# nginx: Custom netns configs
|
# nginx: Custom netns configs
|
||||||
services.nix-bitcoin-webindex.host = mkIf config.services.nix-bitcoin-webindex.enable netns.nginx.address;
|
services.nix-bitcoin-webindex.host = mkIf config.services.nix-bitcoin-webindex.enable netns.nginx.address;
|
||||||
|
|
||||||
|
# loop: Custom netns configs
|
||||||
|
services.lightning-loop = mkIf config.services.lightning-loop.enable {
|
||||||
|
cli = pkgs.writeScriptBin "loop"
|
||||||
|
# Switch user because lnd makes datadir contents readable by user only
|
||||||
|
''
|
||||||
|
netns-exec nb-lightning-loop sudo -u lnd ${config.services.lightning-loop.package}/bin/loop "$@"
|
||||||
|
'';
|
||||||
|
};
|
||||||
})
|
})
|
||||||
# Custom netns config option values if netns-isolation not enabled
|
# Custom netns config option values if netns-isolation not enabled
|
||||||
(mkIf (!cfg.enable) {
|
(mkIf (!cfg.enable) {
|
||||||
|
@ -161,6 +161,12 @@ in {
|
|||||||
};
|
};
|
||||||
services.tor.hiddenServices.lnd = mkIf cfg.lnd.enable (mkHiddenService { port = cfg.lnd.onionport; toHost = cfg.lnd.listen; });
|
services.tor.hiddenServices.lnd = mkIf cfg.lnd.enable (mkHiddenService { port = cfg.lnd.onionport; toHost = cfg.lnd.listen; });
|
||||||
|
|
||||||
|
# lightning-loop
|
||||||
|
services.lightning-loop = {
|
||||||
|
proxy = cfg.tor.client.socksListenAddress;
|
||||||
|
enforceTor = true;
|
||||||
|
};
|
||||||
|
|
||||||
# liquidd
|
# liquidd
|
||||||
services.liquidd = {
|
services.liquidd = {
|
||||||
rpcuser = "liquidrpc";
|
rpcuser = "liquidrpc";
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
generate-secrets = pkgs.callPackage ./generate-secrets { };
|
generate-secrets = pkgs.callPackage ./generate-secrets { };
|
||||||
nixops19_09 = pkgs.callPackage ./nixops { };
|
nixops19_09 = pkgs.callPackage ./nixops { };
|
||||||
netns-exec = pkgs.callPackage ./netns-exec { };
|
netns-exec = pkgs.callPackage ./netns-exec { };
|
||||||
|
lightning-loop = pkgs.callPackage ./lightning-loop { };
|
||||||
|
|
||||||
pinned = import ./pinned.nix;
|
pinned = import ./pinned.nix;
|
||||||
}
|
}
|
||||||
|
23
pkgs/lightning-loop/default.nix
Normal file
23
pkgs/lightning-loop/default.nix
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{ pkgs, buildGoModule, fetchurl, lib }:
|
||||||
|
|
||||||
|
buildGoModule rec {
|
||||||
|
pname = "lightning-loop";
|
||||||
|
version = "0.7.0-beta";
|
||||||
|
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://github.com/lightninglabs/loop/archive/v${version}.tar.gz";
|
||||||
|
# Use ./get-sha256.sh to fetch latest (verified) sha256
|
||||||
|
sha256 = "fbb5ae6dd55002a632a924e41a0bb2ce886eb9e834668be35b312b14e8b68233";
|
||||||
|
};
|
||||||
|
|
||||||
|
subPackages = [ "cmd/loop" "cmd/loopd" ];
|
||||||
|
|
||||||
|
vendorSha256 = "1g0l09zcic5nnrsdyap40dj3zl59gbb2k8iirhph3257ysa52mhr";
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = " Lightning Loop: A Non-Custodial Off/On Chain Bridge";
|
||||||
|
homepage = "https://github.com/lightninglabs/loop";
|
||||||
|
license = lib.licenses.mit;
|
||||||
|
maintainers = with maintainers; [ nixbitcoin ];
|
||||||
|
};
|
||||||
|
}
|
27
pkgs/lightning-loop/get-sha256.sh
Executable file
27
pkgs/lightning-loop/get-sha256.sh
Executable file
@ -0,0 +1,27 @@
|
|||||||
|
#! /usr/bin/env nix-shell
|
||||||
|
#! nix-shell -i bash -p git gnupg
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
TMPDIR="$(mktemp -d -p /tmp)"
|
||||||
|
trap "rm -rf $TMPDIR" EXIT
|
||||||
|
cd $TMPDIR
|
||||||
|
|
||||||
|
echo "Fetching latest release"
|
||||||
|
git clone https://github.com/lightninglabs/loop 2> /dev/null
|
||||||
|
cd loop
|
||||||
|
latest=$(git describe --tags `git rev-list --tags --max-count=1`)
|
||||||
|
echo "Latest release is ${latest}"
|
||||||
|
|
||||||
|
# GPG verification
|
||||||
|
export GNUPGHOME=$TMPDIR
|
||||||
|
echo "Fetching Joost Jager's Key"
|
||||||
|
gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys D146D0F68939436268FA9A130E26BB61B76C4D3A 2> /dev/null
|
||||||
|
echo "Fetching Alex Bosworth's Key"
|
||||||
|
gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys DE23E73BFA8A0AD5587D2FCDE80D2F3F311FD87E 2> /dev/null
|
||||||
|
|
||||||
|
echo "Verifying latest release"
|
||||||
|
git verify-tag ${latest}
|
||||||
|
|
||||||
|
echo "tag: ${latest}"
|
||||||
|
# The prefix option is necessary because GitHub prefixes the archive contents in this format
|
||||||
|
echo "sha256: $(git archive --format tar.gz --prefix=loop-${latest//v}/ ${latest} | sha256sum | cut -d\ -f1)"
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
static char *available_netns[] = {
|
static char *available_netns[] = {
|
||||||
"nb-lnd",
|
"nb-lnd",
|
||||||
|
"nb-lightning-loop",
|
||||||
"nb-bitcoind",
|
"nb-bitcoind",
|
||||||
"nb-liquidd"
|
"nb-liquidd"
|
||||||
};
|
};
|
||||||
|
@ -11,7 +11,9 @@ in
|
|||||||
bitcoind
|
bitcoind
|
||||||
clightning
|
clightning
|
||||||
lnd;
|
lnd;
|
||||||
inherit (nixBitcoinPkgsUnstable) electrs;
|
inherit (nixBitcoinPkgsUnstable)
|
||||||
|
electrs
|
||||||
|
lightning-loop;
|
||||||
|
|
||||||
stable = nixBitcoinPkgsStable;
|
stable = nixBitcoinPkgsStable;
|
||||||
unstable = nixBitcoinPkgsUnstable;
|
unstable = nixBitcoinPkgsUnstable;
|
||||||
|
@ -88,3 +88,13 @@ succeed("systemctl stop nanopos lightning-charge spark-wallet clightning")
|
|||||||
succeed("systemctl start lnd")
|
succeed("systemctl start lnd")
|
||||||
assert_matches("su operator -c 'lncli getinfo' | jq", '"version"')
|
assert_matches("su operator -c 'lncli getinfo' | jq", '"version"')
|
||||||
assert_no_failure("lnd")
|
assert_no_failure("lnd")
|
||||||
|
|
||||||
|
### Test loopd
|
||||||
|
|
||||||
|
succeed("systemctl start lightning-loop")
|
||||||
|
assert_matches("su operator -c 'loop --version'", "version")
|
||||||
|
# Check that lightning-loop fails with the right error, making sure
|
||||||
|
# lightning-loop can connect to lnd
|
||||||
|
machine.wait_until_succeeds(
|
||||||
|
log_has_string("lightning-loop", "chain notifier RPC isstill in the process of starting")
|
||||||
|
)
|
||||||
|
@ -150,3 +150,13 @@ succeed("systemctl stop nanopos lightning-charge spark-wallet clightning")
|
|||||||
succeed("systemctl start lnd")
|
succeed("systemctl start lnd")
|
||||||
assert_matches("su operator -c 'lncli getinfo' | jq", '"version"')
|
assert_matches("su operator -c 'lncli getinfo' | jq", '"version"')
|
||||||
assert_no_failure("lnd")
|
assert_no_failure("lnd")
|
||||||
|
|
||||||
|
### Test loopd
|
||||||
|
|
||||||
|
succeed("systemctl start lightning-loop")
|
||||||
|
assert_matches("su operator -c 'loop --version'", "version")
|
||||||
|
# Check that lightning-loop fails with the right error, making sure
|
||||||
|
# lightning-loop can connect to lnd
|
||||||
|
machine.wait_until_succeeds(
|
||||||
|
log_has_string("lightning-loop", "chain notifier RPC isstill in the process of starting")
|
||||||
|
)
|
||||||
|
@ -34,6 +34,8 @@ import ./make-test.nix rec {
|
|||||||
|
|
||||||
services.lnd.enable = true;
|
services.lnd.enable = true;
|
||||||
systemd.services.lnd.wantedBy = mkForce [];
|
systemd.services.lnd.wantedBy = mkForce [];
|
||||||
|
services.lightning-loop.enable = true;
|
||||||
|
systemd.services.lightning-loop.wantedBy = mkForce [];
|
||||||
|
|
||||||
services.electrs.enable = true;
|
services.electrs.enable = true;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user