diff --git a/modules/clightning-plugins/default.nix b/modules/clightning-plugins/default.nix index da30464..36f2937 100644 --- a/modules/clightning-plugins/default.nix +++ b/modules/clightning-plugins/default.nix @@ -14,6 +14,7 @@ in { imports = [ ./clboss.nix ./commando.nix + ./feeadjuster.nix ./prometheus.nix ./summary.nix ./zmq.nix diff --git a/modules/clightning-plugins/feeadjuster.nix b/modules/clightning-plugins/feeadjuster.nix new file mode 100644 index 0000000..2ec4859 --- /dev/null +++ b/modules/clightning-plugins/feeadjuster.nix @@ -0,0 +1,78 @@ +{ config, lib, ... }: + +with lib; +let + options.services.clightning.plugins.feeadjuster = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Enable feeaduster (clightning plugin). + This plugin auto-updates channel fees to keep channels balanced. + + See here for for all available options: + https://github.com/lightningd/plugins/blob/master/feeadjuster/feeadjuster.py + Extra options can be set via `services.clightning.extraConfig`. + ''; + }; + fuzz = mkOption { + type = types.bool; + default = true; + description = "Enable update threshold randomization and hysteresis."; + }; + adjustOnForward = mkOption { + type = types.bool; + default = false; + description = "Automatically update fees on forward events."; + }; + method = mkOption { + type = types.enum [ "soft" "default" "hard" ]; + default = "default"; + description = '' + Adjustment method to calculate channel fees. + `soft`: less difference when adjusting fees. + `hard`: greater difference when adjusting fees. + ''; + }; + adjustDaily = mkOption { + type = types.bool; + default = true; + description = "Automatically update fees daily."; + }; + }; + + cfg = config.services.clightning.plugins.feeadjuster; + inherit (config.services) clightning; +in +{ + inherit options; + + config = mkIf (cfg.enable && clightning.enable) { + services.clightning.extraConfig = '' + plugin=${config.nix-bitcoin.pkgs.clightning-plugins.feeadjuster.path} + feeadjuster-adjustment-method="${cfg.method}" + '' + optionalString (!cfg.fuzz) '' + feeadjuster-deactivate-fuzz + '' + optionalString (!cfg.adjustOnForward) '' + feeadjuster-deactivate-fee-update + ''; + + systemd = mkIf cfg.adjustDaily { + services.clightning-feeadjuster = { + # Only run when clightning is running + requisite = [ "clightning.service" ]; + after = [ "clightning.service" ]; + serviceConfig = { + Type = "oneshot"; + User = "clightning"; + ExecStart = "${clightning.package}/bin/lightning-cli --lightning-dir ${clightning.dataDir} feeadjust"; + }; + unitConfig.JoinsNamespaceOf = [ "clightning.service" ]; + startAt = [ "daily" ]; + }; + timers.clightning-feeadjuster.timerConfig = { + RandomizedDelaySec = "6h"; + }; + }; + }; +} diff --git a/pkgs/clightning-plugins/default.nix b/pkgs/clightning-plugins/default.nix index 49f39c9..d8eb58e 100644 --- a/pkgs/clightning-plugins/default.nix +++ b/pkgs/clightning-plugins/default.nix @@ -39,6 +39,9 @@ let scriptName = "cl-zmq"; extraPkgs = [ twisted txzmq ]; }; + feeadjuster = { + description = "Dynamically changes channel fees to keep your channels more balanced"; + }; }; basePkgs = [ nbPython3Packages.pyln-client ]; diff --git a/test/tests.nix b/test/tests.nix index 7f3e420..77e367a 100644 --- a/test/tests.nix +++ b/test/tests.nix @@ -134,6 +134,7 @@ let (mkIf config.test.features.clightningPlugins { services.clightning.plugins = { clboss.enable = true; + feeadjuster.enable = true; helpme.enable = true; monitor.enable = true; prometheus.enable = true; diff --git a/test/tests.py b/test/tests.py index e1599ab..3b20aa1 100644 --- a/test/tests.py +++ b/test/tests.py @@ -127,20 +127,24 @@ def _(): def _(): assert_running("clightning") assert_matches("runuser -u operator -- lightning-cli getinfo | jq", '"id"') - if test_data["clightning-plugins"]: + + enabled_plugins = test_data["clightning-plugins"] + if enabled_plugins: plugin_list = succeed("lightning-cli plugin list") plugins = json.loads(plugin_list)["plugins"] active = set(plugin["name"] for plugin in plugins if plugin["active"]) - failed = set(test_data["clightning-plugins"]).difference(active) + failed = set(enabled_plugins).difference(active) if failed: raise Exception( f"The following clightning plugins are inactive:\n{failed}.\n\n" f"Output of 'lightning-cli plugin list':\n{plugin_list}" ) - else: - machine.log("Active clightning plugins:") - for p in test_data["clightning-plugins"]: - machine.log(os.path.basename(p)) + active = [os.path.splitext(os.path.basename(p))[0] for p in enabled_plugins] + machine.log("\n".join(["Active clightning plugins:", *active])) + + if "feeadjuster" in active: + # This is a one-shot service, so this command only succeeds if the service succeeds + succeed("systemctl start clightning-feeadjuster") @test("lnd") def _():