charge-lnd: add module

This commit is contained in:
Martin Milata 2021-06-02 03:11:26 +02:00
parent 842ed44292
commit b666bb2903
9 changed files with 171 additions and 2 deletions

View File

@ -63,13 +63,14 @@ NixOS modules
* [summary](https://github.com/lightningd/plugins/tree/master/summary): print a nice summary of the node status * [summary](https://github.com/lightningd/plugins/tree/master/summary): print a nice summary of the node status
* [zmq](https://github.com/lightningd/plugins/tree/master/zmq): publishes notifications via ZeroMQ to configured endpoints * [zmq](https://github.com/lightningd/plugins/tree/master/zmq): publishes notifications via ZeroMQ to configured endpoints
* [lnd](https://github.com/lightningnetwork/lnd) with support for announcing an onion service * [lnd](https://github.com/lightningnetwork/lnd) with support for announcing an onion service
* [Lightning Loop](https://github.com/lightninglabs/loop)
* [Lightning Pool](https://github.com/lightninglabs/pool)
* [charge-lnd](https://github.com/accumulator/charge-lnd): policy-based channel fee manager
* [lndconnect](https://github.com/LN-Zap/lndconnect) via a REST onion service * [lndconnect](https://github.com/LN-Zap/lndconnect) via a REST onion service
* [spark-wallet](https://github.com/shesek/spark-wallet) * [spark-wallet](https://github.com/shesek/spark-wallet)
* [electrs](https://github.com/romanz/electrs) * [electrs](https://github.com/romanz/electrs)
* [btcpayserver](https://github.com/btcpayserver/btcpayserver) * [btcpayserver](https://github.com/btcpayserver/btcpayserver)
* [liquid](https://github.com/elementsproject/elements) * [liquid](https://github.com/elementsproject/elements)
* [Lightning Loop](https://github.com/lightninglabs/loop)
* [Lightning Pool](https://github.com/lightninglabs/pool)
* [JoinMarket](https://github.com/joinmarket-org/joinmarket-clientserver) * [JoinMarket](https://github.com/joinmarket-org/joinmarket-clientserver)
* [JoinMarket Orderbook Watcher](https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master/docs/orderbook.md) * [JoinMarket Orderbook Watcher](https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master/docs/orderbook.md)
* [recurring-donations](modules/recurring-donations.nix): for periodic lightning payments * [recurring-donations](modules/recurring-donations.nix): for periodic lightning payments

View File

@ -176,6 +176,15 @@
# Set this to create a public onion service for lnd. # Set this to create a public onion service for lnd.
# nix-bitcoin.onionServices.lnd.public = true; # nix-bitcoin.onionServices.lnd.public = true;
### charge-lnd
# Enable this module to use charge-lnd, a simple policy based fee manager for
# LND. With this tool you can set fees to autobalance, recover channel open
# costs, use on-chain fees as reference, or just use static fees. You decide.
# services.charge-lnd.enable = true;
# Define policies as outlined in the project documentation.
# services.charge-lnd.policies = ''
# '';
### Backups ### Backups
# Enable this module to use nix-bitcoin's own backups module. By default, it # Enable this module to use nix-bitcoin's own backups module. By default, it
# uses duplicity to incrementally back up all important files in /var/lib to # uses duplicity to incrementally back up all important files in /var/lib to

141
modules/charge-lnd.nix Normal file
View File

@ -0,0 +1,141 @@
{ config, options, lib, pkgs, ... }:
with lib;
let
cfg = config.services.charge-lnd;
nbLib = config.nix-bitcoin.lib;
lnd = config.services.lnd;
electrs = if (options ? services.electrs) && config.services.electrs.enable
then config.services.electrs
else null;
user = "charge-lnd";
group = user;
dataDir = "/var/lib/charge-lnd";
configFile = builtins.toFile "charge-lnd.config" cfg.policies;
checkedConfig = pkgs.runCommandNoCC "charge-lnd-checked.config" { } ''
${config.nix-bitcoin.pkgs.charge-lnd}/bin/charge-lnd --check --config ${configFile}
cp ${configFile} $out
'';
in
{
options.services.charge-lnd = with types; {
enable = mkEnableOption "charge-lnd, policy-based fee manager";
extraFlags = mkOption {
type = listOf str;
default = [];
example = [ "--verbose" "--dry-run" ];
description = "Extra flags to pass to the charge-lnd command.";
};
interval = mkOption {
type = str;
default = "*-*-* 04:00:00";
example = "hourly";
description = ''
Systemd calendar expression when to adjust fees.
See <citerefentry><refentrytitle>systemd.time</refentrytitle>
<manvolnum>7</manvolnum></citerefentry> for possible values.
Default is once a day.
'';
};
randomDelay = mkOption {
type = str;
default = "1h";
description = ''
Random delay to add to scheduled time.
'';
};
policies = mkOption {
type = types.lines;
default = "";
example = literalExample ''
[discourage-routing-out-of-balance]
chan.max_ratio = 0.1
chan.min_capacity = 250000
strategy = static
base_fee_msat = 10000
fee_ppm = 500
[encourage-routing-to-balance]
chan.min_ratio = 0.9
chan.min_capacity = 250000
strategy = static
base_fee_msat = 1
fee_ppm = 2
[default]
strategy = ignore
'';
description = ''
Policy definitions in INI format.
See https://github.com/accumulator/charge-lnd/blob/master/README.md#usage
for possible properties and parameters.
Policies are evaluated from top to bottom.
The first matching policy (or `default`) is applied.
'';
};
};
config = mkIf cfg.enable {
services.lnd = {
enable = true;
macaroons.charge-lnd = {
user = user;
permissions = ''{"entity":"info","action":"read"},{"entity":"onchain","action":"read"},{"entity":"offchain","action":"read"},{"entity":"offchain","action":"write"}'';
};
};
systemd.services.charge-lnd = {
documentation = [ "https://github.com/accumulator/charge-lnd/blob/master/README.md" ];
after = [ "lnd.service" ];
requires = [ "lnd.service" ];
# lnd's data directory (--lnddir) is not accessible to charge-lnd.
# Instead use directory "lnddir-proxy" as lnddir and link relevant files to it.
preStart = ''
macaroonDir=${dataDir}/lnddir-proxy/data/chain/bitcoin/mainnet
mkdir -p $macaroonDir
ln -sf /run/lnd/charge-lnd.macaroon $macaroonDir
ln -sf ${config.nix-bitcoin.secretsDir}/lnd-cert ${dataDir}/lnddir-proxy/tls.cert
'';
serviceConfig = nbLib.defaultHardening // {
ExecStart = ''
${config.nix-bitcoin.pkgs.charge-lnd}/bin/charge-lnd \
--lnddir ${dataDir}/lnddir-proxy \
--grpc ${lnd.rpcAddress}:${toString lnd.rpcPort} \
--config ${checkedConfig} \
${optionalString (electrs != null) "--electrum-server ${electrs.address}:${toString electrs.port}"} \
${escapeShellArgs cfg.extraFlags}
'';
Type = "oneshot";
User = user;
Group = group;
StateDirectory = "charge-lnd";
} // nbLib.allowLocalIPAddresses;
};
systemd.timers.charge-lnd = {
description = "Adjust LND routing fees";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = cfg.interval;
RandomizedDelaySec = cfg.randomDelay;
};
};
users.users.${user} = {
group = group;
isSystemUser = true;
};
users.groups.${group} = {};
};
}

View File

@ -9,5 +9,6 @@
spark-wallet = ./spark-wallet.nix; spark-wallet = ./spark-wallet.nix;
recurring-donations = ./recurring-donations.nix; recurring-donations = ./recurring-donations.nix;
lnd = ./lnd.nix; lnd = ./lnd.nix;
charge-lnd = ./charge-lnd.nix;
joinmarket = ./joinmarket.nix; joinmarket = ./joinmarket.nix;
} }

View File

@ -16,6 +16,7 @@ with lib;
./lnd-rest-onion-service.nix ./lnd-rest-onion-service.nix
./lightning-loop.nix ./lightning-loop.nix
./lightning-pool.nix ./lightning-pool.nix
./charge-lnd.nix
./btcpayserver.nix ./btcpayserver.nix
./electrs.nix ./electrs.nix
./liquid.nix ./liquid.nix

View File

@ -249,6 +249,10 @@ in {
id = 27; id = 27;
connections = [ "lnd" ]; connections = [ "lnd" ];
}; };
charge-lnd = {
id = 28;
connections = [ "lnd" "electrs" ];
};
}; };
services.bitcoind = { services.bitcoind = {

View File

@ -9,6 +9,7 @@ in
inherit (nixpkgsUnstable) inherit (nixpkgsUnstable)
bitcoin bitcoin
bitcoind bitcoind
charge-lnd
clightning clightning
lnd lnd
lndconnect lndconnect

View File

@ -65,6 +65,8 @@ let
tests.lightning-pool = cfg.lightning-pool.enable; tests.lightning-pool = cfg.lightning-pool.enable;
nix-bitcoin.onionServices.lnd.public = true; nix-bitcoin.onionServices.lnd.public = true;
tests.charge-lnd = cfg.charge-lnd.enable;
tests.electrs = cfg.electrs.enable; tests.electrs = cfg.electrs.enable;
tests.liquidd = cfg.liquidd.enable; tests.liquidd = cfg.liquidd.enable;
@ -136,6 +138,7 @@ let
services.lnd.restOnionService.enable = true; services.lnd.restOnionService.enable = true;
services.lightning-loop.enable = true; services.lightning-loop.enable = true;
services.lightning-pool.enable = true; services.lightning-pool.enable = true;
services.charge-lnd.enable = true;
services.electrs.enable = true; services.electrs.enable = true;
services.liquidd.enable = true; services.liquidd.enable = true;
services.btcpayserver.enable = true; services.btcpayserver.enable = true;
@ -178,6 +181,7 @@ let
services.lnd.enable = true; services.lnd.enable = true;
services.lightning-loop.enable = true; services.lightning-loop.enable = true;
services.lightning-pool.enable = true; services.lightning-pool.enable = true;
services.charge-lnd.enable = true;
services.electrs.enable = true; services.electrs.enable = true;
services.btcpayserver.enable = true; services.btcpayserver.enable = true;
services.joinmarket.enable = true; services.joinmarket.enable = true;

View File

@ -199,6 +199,13 @@ def _():
) )
@test("charge-lnd")
def _():
# charge-lnd is a oneshot service that is started by a timer under regular operation
succeed("systemctl start charge-lnd")
assert_no_failure("charge-lnd")
@test("btcpayserver") @test("btcpayserver")
def _(): def _():
assert_running("nbxplorer") assert_running("nbxplorer")