From 1a16e5523712dce7cc702128499dae41e268a338 Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Thu, 12 Nov 2020 18:07:38 +0100 Subject: [PATCH 1/5] move python packages to pkgs/python-packages Remove obsolete passthru from joinmarket because joinmarket packages are now accessible via pkgs/python-packages. --- pkgs/default.nix | 6 +++- pkgs/joinmarket/default.nix | 28 ++----------------- .../bencoderpyx/default.nix | 0 .../chromalog/default.nix | 0 .../coincurve/default.nix | 0 pkgs/python-packages/default.nix | 19 +++++++++++++ .../jmbase/default.nix | 0 .../jmbitcoin/default.nix | 0 .../jmclient/default.nix | 0 .../jmdaemon/default.nix | 0 .../python-bitcointx/default.nix | 0 .../python-bitcointx/get-sha256.sh | 0 .../secp256k1/default.nix | 0 .../urldecode/default.nix | 0 14 files changed, 27 insertions(+), 26 deletions(-) rename pkgs/{joinmarket => python-packages}/bencoderpyx/default.nix (100%) rename pkgs/{joinmarket => python-packages}/chromalog/default.nix (100%) rename pkgs/{joinmarket => python-packages}/coincurve/default.nix (100%) create mode 100644 pkgs/python-packages/default.nix rename pkgs/{joinmarket => python-packages}/jmbase/default.nix (100%) rename pkgs/{joinmarket => python-packages}/jmbitcoin/default.nix (100%) rename pkgs/{joinmarket => python-packages}/jmclient/default.nix (100%) rename pkgs/{joinmarket => python-packages}/jmdaemon/default.nix (100%) rename pkgs/{joinmarket => python-packages}/python-bitcointx/default.nix (100%) rename pkgs/{joinmarket => python-packages}/python-bitcointx/get-sha256.sh (100%) rename pkgs/{joinmarket => python-packages}/secp256k1/default.nix (100%) rename pkgs/{joinmarket => python-packages}/urldecode/default.nix (100%) diff --git a/pkgs/default.nix b/pkgs/default.nix index 46a4691..e0e285d 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -8,13 +8,17 @@ let self = { hwi = pkgs.callPackage ./hwi { }; pylightning = pkgs.python3Packages.callPackage ./pylightning { }; liquid-swap = pkgs.python3Packages.callPackage ./liquid-swap { }; - joinmarket = pkgs.callPackage ./joinmarket { }; + joinmarket = pkgs.callPackage ./joinmarket { inherit (self) nbPython3Packages; }; generate-secrets = pkgs.callPackage ./generate-secrets { }; nixops19_09 = pkgs.callPackage ./nixops { }; netns-exec = pkgs.callPackage ./netns-exec { }; lightning-loop = pkgs.callPackage ./lightning-loop { }; extra-container = pkgs.callPackage ./extra-container { }; + nbPython3Packages = (pkgs.python3.override { + packageOverrides = pySelf: super: import ./python-packages self pySelf; + }).pkgs; + pinned = import ./pinned.nix; lib = import ./lib.nix { inherit (pkgs) lib; }; diff --git a/pkgs/joinmarket/default.nix b/pkgs/joinmarket/default.nix index 1f0a05c..36bf050 100644 --- a/pkgs/joinmarket/default.nix +++ b/pkgs/joinmarket/default.nix @@ -1,4 +1,4 @@ -{ stdenv, fetchurl, python3, pkgs }: +{ stdenv, lib, fetchurl, python3, nbPython3Packages, pkgs }: let version = "0.7.2"; @@ -7,32 +7,14 @@ let sha256 = "03gvs20d2cfzy9x82l6v4c69w0j9mr4p9zj2hpymnb6xs1yq6dr1"; }; - python = python3.override { - packageOverrides = self: super: let - joinmarketPkg = pkg: self.callPackage pkg { inherit version src; }; - in { - joinmarketbase = joinmarketPkg ./jmbase; - joinmarketclient = joinmarketPkg ./jmclient; - joinmarketbitcoin = joinmarketPkg ./jmbitcoin; - joinmarketdaemon = joinmarketPkg ./jmdaemon; - - chromalog = self.callPackage ./chromalog {}; - bencoderpyx = self.callPackage ./bencoderpyx {}; - coincurve = self.callPackage ./coincurve {}; - urldecode = self.callPackage ./urldecode {}; - python-bitcointx = self.callPackage ./python-bitcointx {}; - secp256k1 = self.callPackage ./secp256k1 {}; - }; - }; - - runtimePackages = with python.pkgs; [ + runtimePackages = with nbPython3Packages; [ joinmarketbase joinmarketclient joinmarketbitcoin joinmarketdaemon ]; - pythonEnv = python.withPackages (_: runtimePackages); + pythonEnv = python3.withPackages (_: runtimePackages); in stdenv.mkDerivation { pname = "joinmarket"; @@ -62,8 +44,4 @@ stdenv.mkDerivation { chmod +x -R $out/bin patchShebangs $out/bin ''; - - passthru = { - inherit python runtimePackages pythonEnv; - }; } diff --git a/pkgs/joinmarket/bencoderpyx/default.nix b/pkgs/python-packages/bencoderpyx/default.nix similarity index 100% rename from pkgs/joinmarket/bencoderpyx/default.nix rename to pkgs/python-packages/bencoderpyx/default.nix diff --git a/pkgs/joinmarket/chromalog/default.nix b/pkgs/python-packages/chromalog/default.nix similarity index 100% rename from pkgs/joinmarket/chromalog/default.nix rename to pkgs/python-packages/chromalog/default.nix diff --git a/pkgs/joinmarket/coincurve/default.nix b/pkgs/python-packages/coincurve/default.nix similarity index 100% rename from pkgs/joinmarket/coincurve/default.nix rename to pkgs/python-packages/coincurve/default.nix diff --git a/pkgs/python-packages/default.nix b/pkgs/python-packages/default.nix new file mode 100644 index 0000000..5dde404 --- /dev/null +++ b/pkgs/python-packages/default.nix @@ -0,0 +1,19 @@ +nbPkgs: +self: +let + inherit (self) callPackage; + + joinmarketPkg = pkg: callPackage pkg { inherit (nbPkgs.joinmarket) version src; }; +in { + bencoderpyx = callPackage ./bencoderpyx {}; + coincurve = callPackage ./coincurve {}; + python-bitcointx = callPackage ./python-bitcointx {}; + secp256k1 = callPackage ./secp256k1 {}; + urldecode = callPackage ./urldecode {}; + chromalog = callPackage ./chromalog {}; + + joinmarketbase = joinmarketPkg ./jmbase; + joinmarketclient = joinmarketPkg ./jmclient; + joinmarketbitcoin = joinmarketPkg ./jmbitcoin; + joinmarketdaemon = joinmarketPkg ./jmdaemon; +} diff --git a/pkgs/joinmarket/jmbase/default.nix b/pkgs/python-packages/jmbase/default.nix similarity index 100% rename from pkgs/joinmarket/jmbase/default.nix rename to pkgs/python-packages/jmbase/default.nix diff --git a/pkgs/joinmarket/jmbitcoin/default.nix b/pkgs/python-packages/jmbitcoin/default.nix similarity index 100% rename from pkgs/joinmarket/jmbitcoin/default.nix rename to pkgs/python-packages/jmbitcoin/default.nix diff --git a/pkgs/joinmarket/jmclient/default.nix b/pkgs/python-packages/jmclient/default.nix similarity index 100% rename from pkgs/joinmarket/jmclient/default.nix rename to pkgs/python-packages/jmclient/default.nix diff --git a/pkgs/joinmarket/jmdaemon/default.nix b/pkgs/python-packages/jmdaemon/default.nix similarity index 100% rename from pkgs/joinmarket/jmdaemon/default.nix rename to pkgs/python-packages/jmdaemon/default.nix diff --git a/pkgs/joinmarket/python-bitcointx/default.nix b/pkgs/python-packages/python-bitcointx/default.nix similarity index 100% rename from pkgs/joinmarket/python-bitcointx/default.nix rename to pkgs/python-packages/python-bitcointx/default.nix diff --git a/pkgs/joinmarket/python-bitcointx/get-sha256.sh b/pkgs/python-packages/python-bitcointx/get-sha256.sh similarity index 100% rename from pkgs/joinmarket/python-bitcointx/get-sha256.sh rename to pkgs/python-packages/python-bitcointx/get-sha256.sh diff --git a/pkgs/joinmarket/secp256k1/default.nix b/pkgs/python-packages/secp256k1/default.nix similarity index 100% rename from pkgs/joinmarket/secp256k1/default.nix rename to pkgs/python-packages/secp256k1/default.nix diff --git a/pkgs/joinmarket/urldecode/default.nix b/pkgs/python-packages/urldecode/default.nix similarity index 100% rename from pkgs/joinmarket/urldecode/default.nix rename to pkgs/python-packages/urldecode/default.nix From e62e163177940574143d27990c861ac8de847f3b Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Thu, 12 Nov 2020 18:07:39 +0100 Subject: [PATCH 2/5] add clightning python pkgs --- pkgs/default.nix | 1 - pkgs/pylightning/default.nix | 11 ------- pkgs/python-packages/default.nix | 5 ++++ pkgs/python-packages/pylightning/default.nix | 17 +++++++++++ pkgs/python-packages/pyln-client/default.nix | 12 ++++++++ pkgs/python-packages/pyln-proto/default.nix | 31 ++++++++++++++++++++ 6 files changed, 65 insertions(+), 12 deletions(-) delete mode 100644 pkgs/pylightning/default.nix create mode 100644 pkgs/python-packages/pylightning/default.nix create mode 100644 pkgs/python-packages/pyln-client/default.nix create mode 100644 pkgs/python-packages/pyln-proto/default.nix diff --git a/pkgs/default.nix b/pkgs/default.nix index e0e285d..f71b22c 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -6,7 +6,6 @@ let self = { electrs = pkgs.callPackage ./electrs { }; elementsd = pkgs.callPackage ./elementsd { withGui = false; }; hwi = pkgs.callPackage ./hwi { }; - pylightning = pkgs.python3Packages.callPackage ./pylightning { }; liquid-swap = pkgs.python3Packages.callPackage ./liquid-swap { }; joinmarket = pkgs.callPackage ./joinmarket { inherit (self) nbPython3Packages; }; generate-secrets = pkgs.callPackage ./generate-secrets { }; diff --git a/pkgs/pylightning/default.nix b/pkgs/pylightning/default.nix deleted file mode 100644 index 852e7d8..0000000 --- a/pkgs/pylightning/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ lib, buildPythonPackage, fetchPypi }: - -buildPythonPackage rec { - pname = "pylightning"; - version = "0.0.7"; - - src = fetchPypi { - inherit pname version; - sha256 = "0anbixqsfk0dsm790yy21f403lwgalxaqlm1s101ifppmxqccgpi"; - }; -} diff --git a/pkgs/python-packages/default.nix b/pkgs/python-packages/default.nix index 5dde404..7077330 100644 --- a/pkgs/python-packages/default.nix +++ b/pkgs/python-packages/default.nix @@ -4,6 +4,7 @@ let inherit (self) callPackage; joinmarketPkg = pkg: callPackage pkg { inherit (nbPkgs.joinmarket) version src; }; + clightningPkg = pkg: callPackage pkg { inherit (nbPkgs.pinned) clightning; }; in { bencoderpyx = callPackage ./bencoderpyx {}; coincurve = callPackage ./coincurve {}; @@ -16,4 +17,8 @@ in { joinmarketclient = joinmarketPkg ./jmclient; joinmarketbitcoin = joinmarketPkg ./jmbitcoin; joinmarketdaemon = joinmarketPkg ./jmdaemon; + + pyln-client = clightningPkg ./pyln-client; + pyln-proto = clightningPkg ./pyln-proto; + pylightning = clightningPkg ./pylightning; } diff --git a/pkgs/python-packages/pylightning/default.nix b/pkgs/python-packages/pylightning/default.nix new file mode 100644 index 0000000..c9dc340 --- /dev/null +++ b/pkgs/python-packages/pylightning/default.nix @@ -0,0 +1,17 @@ +{ buildPythonPackage, clightning, pyln-client }: + +buildPythonPackage rec { + pname = "pylightning"; + version = "0.8.0"; # defined in ${src}/contrib/pyln-client/pyln/client/__init__.py + + inherit (clightning) src; + + propagatedBuildInputs = [ pyln-client ]; + + postUnpack = "sourceRoot=$sourceRoot/contrib/${pname}"; + + # The clightning source contains pyln-client 0.8.0 + postPatch = '' + substituteInPlace requirements.txt --replace pyln-client==0.7.3 pyln-client==0.8.0 + ''; +} diff --git a/pkgs/python-packages/pyln-client/default.nix b/pkgs/python-packages/pyln-client/default.nix new file mode 100644 index 0000000..ea8a392 --- /dev/null +++ b/pkgs/python-packages/pyln-client/default.nix @@ -0,0 +1,12 @@ +{ buildPythonPackage, clightning, recommonmark }: + +buildPythonPackage rec { + pname = "pyln-client"; + version = "0.8.0"; # defined in ${src}/contrib/pyln-client/pyln/client/__init__.py + + inherit (clightning) src; + + propagatedBuildInputs = [ recommonmark ]; + + postUnpack = "sourceRoot=$sourceRoot/contrib/${pname}"; +} diff --git a/pkgs/python-packages/pyln-proto/default.nix b/pkgs/python-packages/pyln-proto/default.nix new file mode 100644 index 0000000..f924a48 --- /dev/null +++ b/pkgs/python-packages/pyln-proto/default.nix @@ -0,0 +1,31 @@ +{ buildPythonPackage, clightning +, bitstring +, cryptography +, coincurve +, base58 +, mypy +}: + +buildPythonPackage rec { + pname = "pyln-proto"; + version = "0.8.4"; # defined in ${src}/contrib/pyln-proto/setup.py + + inherit (clightning) src; + + propagatedBuildInputs = [ + bitstring + cryptography + coincurve + base58 + mypy + ]; + + postUnpack = "sourceRoot=$sourceRoot/contrib/${pname}"; + + postPatch = '' + substituteInPlace requirements.txt \ + --replace base58==1.0.2 base58==2.0.1 \ + --replace bitstring==3.1.6 bitstring==3.1.5 \ + --replace cryptography==2.8 cryptography==3.1 + ''; +} From 5399f73b2010293d3ab84cabdab894023152e844 Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Thu, 12 Nov 2020 18:07:40 +0100 Subject: [PATCH 3/5] add txzmq python pkg --- pkgs/python-packages/default.nix | 1 + pkgs/python-packages/txzmq/default.nix | 28 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 pkgs/python-packages/txzmq/default.nix diff --git a/pkgs/python-packages/default.nix b/pkgs/python-packages/default.nix index 7077330..8e953ba 100644 --- a/pkgs/python-packages/default.nix +++ b/pkgs/python-packages/default.nix @@ -12,6 +12,7 @@ in { secp256k1 = callPackage ./secp256k1 {}; urldecode = callPackage ./urldecode {}; chromalog = callPackage ./chromalog {}; + txzmq = callPackage ./txzmq {}; joinmarketbase = joinmarketPkg ./jmbase; joinmarketclient = joinmarketPkg ./jmclient; diff --git a/pkgs/python-packages/txzmq/default.nix b/pkgs/python-packages/txzmq/default.nix new file mode 100644 index 0000000..fc2ee11 --- /dev/null +++ b/pkgs/python-packages/txzmq/default.nix @@ -0,0 +1,28 @@ +{ lib +, buildPythonPackage +, fetchPypi +, twisted +, pyzmq +}: + +buildPythonPackage rec { + pname = "txzmq"; + version = "0.8.2"; + + src = fetchPypi { + pname = "txZMQ"; + inherit version; + sha256 = "07a9a480e58d4d732eef9efd7e264f2348cbf27ee82b338ec818a8504006e1c0"; + }; + + propagatedBuildInputs = [ + twisted + pyzmq + ]; + + meta = with lib; { + description = "Twisted bindings for ZeroMQ"; + homepage = https://github.com/smira/txZMQ; + license = licenses.gpl2; + }; +} From 4640821f9660cc2231f3fabc88f793b7abbf3a87 Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Thu, 19 Nov 2020 03:01:44 +0100 Subject: [PATCH 4/5] make-test.nix: use writeText Needed for the following commit which adds derivation outputs to `dataFile`. --- test/lib/make-test-vm.nix | 2 +- test/lib/make-test.nix | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/lib/make-test-vm.nix b/test/lib/make-test-vm.nix index c7eccdc..90d3e64 100644 --- a/test/lib/make-test-vm.nix +++ b/test/lib/make-test-vm.nix @@ -3,7 +3,7 @@ testArgs: let pkgs = import { config = {}; overlays = []; }; - test = (import "${pkgs.path}/nixos/tests/make-test-python.nix") testArgs; + test = (import "${pkgs.path}/nixos/tests/make-test-python.nix") (testArgs pkgs); fixedTest = { system ? builtins.currentSystem, ... }@args: let diff --git a/test/lib/make-test.nix b/test/lib/make-test.nix index 9deb067..a0baa17 100644 --- a/test/lib/make-test.nix +++ b/test/lib/make-test.nix @@ -1,7 +1,7 @@ scenario: testConfig: { - vm = import ./make-test-vm.nix { + vm = import ./make-test-vm.nix (pkgs: { name = "nix-bitcoin-${scenario}"; machine = { @@ -16,7 +16,7 @@ scenario: testConfig: data = cfg.test.data; tests = cfg.tests; }; - dataFile = builtins.toFile "test-data" (builtins.toJSON data); + dataFile = pkgs.writeText "test-data" (builtins.toJSON data); initData = '' import json @@ -37,7 +37,7 @@ scenario: testConfig: run_tests() '' ]; - }; + }); container = { # The container name has a 11 char length limit From 1d44b99340eb4535950f53579ff195de22e8b6cc Mon Sep 17 00:00:00 2001 From: Ian Shipman Date: Thu, 19 Nov 2020 03:01:45 +0100 Subject: [PATCH 5/5] add curated clightning plugins --- .travis.yml | 1 + README.md | 2 +- docs/usage.md | 28 ++++++++++ examples/configuration.nix | 4 ++ modules/clightning-plugins/default.nix | 27 ++++++++++ modules/clightning-plugins/prometheus.nix | 21 ++++++++ modules/clightning-plugins/summary.nix | 39 ++++++++++++++ modules/clightning-plugins/zmq.nix | 42 +++++++++++++++ modules/modules.nix | 1 + pkgs/clightning-plugins/default.nix | 63 +++++++++++++++++++++++ pkgs/clightning-plugins/get-sha256.sh | 14 +++++ pkgs/default.nix | 5 ++ test/tests.nix | 36 ++++++++++++- test/tests.py | 15 ++++++ 14 files changed, 295 insertions(+), 3 deletions(-) create mode 100644 modules/clightning-plugins/default.nix create mode 100644 modules/clightning-plugins/prometheus.nix create mode 100644 modules/clightning-plugins/summary.nix create mode 100644 modules/clightning-plugins/zmq.nix create mode 100644 pkgs/clightning-plugins/default.nix create mode 100755 pkgs/clightning-plugins/get-sha256.sh diff --git a/.travis.yml b/.travis.yml index b0ba652..bc953f4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,6 +33,7 @@ env: - PKG=nixops19_09 STABLE=1 - PKG=joinmarket STABLE=1 - PKG=joinmarket STABLE=0 + - PKG=clightning-plugins-all STABLE=1 script: - printf '%s (%s)\n' "$NIX_PATH" "$VER" - | diff --git a/README.md b/README.md index 08ddb14..bc4bd69 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ By default the `configuration.nix` provides: * adds non-root user "operator" which has access to bitcoin-cli and lightning-cli In `configuration.nix` the user can enable: -* a clightning hidden service +* a clightning hidden service with [plugins](https://github.com/lightningd/plugins) * [liquid](https://github.com/elementsproject/elements) * [lightning charge](https://github.com/ElementsProject/lightning-charge) * [nanopos](https://github.com/ElementsProject/nanopos) diff --git a/docs/usage.md b/docs/usage.md index fbf87b3..53d1c8b 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -338,3 +338,31 @@ See [here](https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master ``` 3. Profit + +clightning +--- + +## Plugins + +There are a number of [plugins](https://github.com/lightningd/plugins) available for clightning. Currently `nix-bitcoin` supports: + +- helpme +- monitor +- prometheus +- rebalance +- summary +- zmq + +You can activate and configure these plugins like so: + +```nix +services.clightning = { + enable = true; + plugins = { + prometheus.enable = true; + prometheus.listen = "0.0.0.0:9900"; + }; +}; +``` + +Please have a look at the module for a plugin (e.g. [prometheus.nix](../modules/clightning-plugins/prometheus.nix)) to learn its configuration options. diff --git a/examples/configuration.nix b/examples/configuration.nix index b5dc63f..9c7e9b2 100644 --- a/examples/configuration.nix +++ b/examples/configuration.nix @@ -38,10 +38,14 @@ # Enable this module to use clightning, a Lightning Network implementation # in C. services.clightning.enable = true; + # == TOR # Enable this option to announce our Tor Hidden Service. By default clightning # offers outgoing functionality, but doesn't announce the Tor Hidden Service # under which peers can reach us. # services.clightning.announce-tor = true; + # == Plugins + # See ../docs/usage.md for the list of available plugins. + # services.clightning.plugins.prometheus.enable = true; ### LND # Uncomment the following line in order to enable lnd, a lightning diff --git a/modules/clightning-plugins/default.nix b/modules/clightning-plugins/default.nix new file mode 100644 index 0000000..946cdc2 --- /dev/null +++ b/modules/clightning-plugins/default.nix @@ -0,0 +1,27 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.services.clightning.plugins; + pluginPkgs = config.nix-bitcoin.pkgs.clightning-plugins; +in { + imports = [ + ./prometheus.nix + ./summary.nix + ./zmq.nix + ]; + + options.services.clightning.plugins = { + helpme.enable = mkEnableOption "Help me (clightning plugin)"; + monitor.enable = mkEnableOption "Monitor (clightning plugin)"; + rebalance.enable = mkEnableOption "Rebalance (clightning plugin)"; + }; + + config = { + services.clightning.extraConfig = mkMerge [ + (mkIf cfg.helpme.enable "plugin=${pluginPkgs.helpme.path}") + (mkIf cfg.monitor.enable "plugin=${pluginPkgs.monitor.path}") + (mkIf cfg.rebalance.enable "plugin=${pluginPkgs.rebalance.path}") + ]; + }; +} diff --git a/modules/clightning-plugins/prometheus.nix b/modules/clightning-plugins/prometheus.nix new file mode 100644 index 0000000..94cf4c4 --- /dev/null +++ b/modules/clightning-plugins/prometheus.nix @@ -0,0 +1,21 @@ +{ config, lib, ... }: + +with lib; +let cfg = config.services.clightning.plugins.prometheus; in +{ + options.services.clightning.plugins.prometheus = { + enable = mkEnableOption "Prometheus (clightning plugin)"; + listen = mkOption { + type = types.str; + default = "0.0.0.0:9750"; + description = "Address and port to bind to."; + }; + }; + + config = mkIf cfg.enable { + services.clightning.extraConfig = '' + plugin=${config.nix-bitcoin.pkgs.clightning-plugins.prometheus.path} + prometheus-listen=${cfg.listen} + ''; + }; +} diff --git a/modules/clightning-plugins/summary.nix b/modules/clightning-plugins/summary.nix new file mode 100644 index 0000000..206ca49 --- /dev/null +++ b/modules/clightning-plugins/summary.nix @@ -0,0 +1,39 @@ +{ config, lib, ... }: + +with lib; +let cfg = config.services.clightning.plugins.summary; in +{ + options.services.clightning.plugins.summary = { + enable = mkEnableOption "Summary (clightning plugin)"; + currency = mkOption { + type = types.str; + default = "USD"; + description = "The currency to look up on btcaverage."; + }; + currencyPrefix = mkOption { + type = types.str; + default = "USD $"; + description = "The prefix to use for the currency."; + }; + availabilityInterval = mkOption { + type = types.int; + default = 300; + description = "How often in seconds the availability should be calculated."; + }; + availabilityWindow = mkOption { + type = types.int; + default = 72; + description = "How many hours the availability should be averaged over."; + }; + }; + + config = mkIf cfg.enable { + services.clightning.extraConfig = '' + plugin=${config.nix-bitcoin.pkgs.clightning-plugins.summary.path} + summary-currency="${cfg.currency}" + summary-currency-prefix="${cfg.currencyPrefix}" + summary-availability-interval=${toString cfg.availabilityInterval} + summary-availability-window=${toString cfg.availabilityWindow} + ''; + }; +} diff --git a/modules/clightning-plugins/zmq.nix b/modules/clightning-plugins/zmq.nix new file mode 100644 index 0000000..19eacf4 --- /dev/null +++ b/modules/clightning-plugins/zmq.nix @@ -0,0 +1,42 @@ +{ config, lib, ... }: + +with lib; +let + cfg = config.services.clightning.plugins.zmq; + + endpoints = [ + "channel-opened" + "connect" + "disconnect" + "invoice-payment" + "warning" + "forward-event" + "sendpay-success" + "sendpay-failure" + ]; + + mkEndpointOption = name: + mkOption { + type = types.nullOr types.str; + default = null; + description = "Endpoint for ${name}"; + }; + + setEndpoint = ep: + let value = builtins.getAttr ep cfg; in + optionalString (value != null) '' + zmq-pub-${ep}=${value} + ''; +in +{ + options.services.clightning.plugins.zmq = { + enable = mkEnableOption "ZMQ (clightning plugin)"; + } // lib.genAttrs endpoints mkEndpointOption; + + config = mkIf cfg.enable { + services.clightning.extraConfig = '' + plugin=${config.nix-bitcoin.pkgs.clightning-plugins.zmq.path} + ${concatStrings (map setEndpoint endpoints)} + ''; + }; +} diff --git a/modules/modules.nix b/modules/modules.nix index e77e531..7a3ddf3 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -9,6 +9,7 @@ # Main features ./bitcoind.nix ./clightning.nix + ./clightning-plugins ./lightning-charge.nix ./nanopos.nix ./spark-wallet.nix diff --git a/pkgs/clightning-plugins/default.nix b/pkgs/clightning-plugins/default.nix new file mode 100644 index 0000000..28561af --- /dev/null +++ b/pkgs/clightning-plugins/default.nix @@ -0,0 +1,63 @@ +pkgs: nbPython3Packages: + +let + inherit (pkgs) lib; + + src = pkgs.fetchFromGitHub { + owner = "lightningd"; + repo = "plugins"; + rev = "6cd472636926f05a9c472139fabe1ff11c90aa6a"; + sha256 = "1lisx85vzsfzjhdc6zdz0l6bcrdgg6rp5xbc5jmx93mv8qqg2cns"; + }; + + version = builtins.substring 0 7 src.rev; + + plugins = with nbPython3Packages; { + helpme = {}; + monitor = {}; + prometheus = { + extraPkgs = [ prometheus_client ]; + patchRequirements = "--replace prometheus-client==0.6.0 prometheus-client==0.8.0"; + }; + rebalance = {}; + summary = { + extraPkgs = [ packaging requests ]; + }; + zmq = { + scriptName = "cl-zmq"; + extraPkgs = [ twisted txzmq ]; + }; + }; + + basePkgs = [ nbPython3Packages.pyln-client ]; + + mkPlugin = name: plugin: let + python = pkgs.python3.withPackages (_: basePkgs ++ (plugin.extraPkgs or [])); + script = "${plugin.scriptName or name}.py"; + drv = pkgs.stdenv.mkDerivation { + pname = "clightning-plugin-${name}"; + inherit version; + + buildInputs = [ python ]; + + buildCommand = '' + cp --no-preserve=mode -r ${src}/${name} $out + cd $out + ${lib.optionalString (plugin ? patchRequirements) '' + substituteInPlace requirements.txt ${plugin.patchRequirements} + ''} + + # Check that requirements are met + PYTHONPATH=${toString python}/${python.sitePackages} \ + ${pkgs.python3Packages.pip}/bin/pip install -r requirements.txt --no-cache --no-index + + chmod +x ${script} + patchShebangs ${script} + ''; + + passthru.path = "${drv}/${script}"; + }; + in drv; + +in + builtins.mapAttrs mkPlugin plugins diff --git a/pkgs/clightning-plugins/get-sha256.sh b/pkgs/clightning-plugins/get-sha256.sh new file mode 100755 index 0000000..ccc678b --- /dev/null +++ b/pkgs/clightning-plugins/get-sha256.sh @@ -0,0 +1,14 @@ +#! /usr/bin/env nix-shell +#! nix-shell -i bash -p git +set -euo pipefail + +archive_hash () { + repo=$1 + rev=$2 + nix-prefetch-url --unpack "https://github.com/${repo}/archive/${rev}.tar.gz" 2> /dev/null | tail -n 1 +} + +echo "Fetching latest lightningd/plugins release" +latest=$(git ls-remote https://github.com/lightningd/plugins master | cut -f 1) +echo "rev: ${latest}" +echo "sha256: $(archive_hash lightningd/plugins $latest)" diff --git a/pkgs/default.nix b/pkgs/default.nix index f71b22c..66115c8 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -13,6 +13,7 @@ let self = { netns-exec = pkgs.callPackage ./netns-exec { }; lightning-loop = pkgs.callPackage ./lightning-loop { }; extra-container = pkgs.callPackage ./extra-container { }; + clightning-plugins = import ./clightning-plugins pkgs self.nbPython3Packages; nbPython3Packages = (pkgs.python3.override { packageOverrides = pySelf: super: import ./python-packages self pySelf; @@ -23,4 +24,8 @@ let self = { lib = import ./lib.nix { inherit (pkgs) lib; }; modulesPkgs = self // self.pinned; + + # Used in ../.travis.yml + clightning-plugins-all = pkgs.writeText "clightning-plugins" + (pkgs.lib.concatMapStringsSep "\n" toString (builtins.attrValues self.clightning-plugins)); }; in self diff --git a/test/tests.nix b/test/tests.nix index 07fe9b6..8a1cecc 100644 --- a/test/tests.nix +++ b/test/tests.nix @@ -21,7 +21,11 @@ let testEnv = rec { } ]; - config = { + options.test.features = { + clightningPlugins = mkEnableOption "all clightning plugins"; + }; + + config = mkMerge [{ tests.bitcoind = cfg.bitcoind.enable; services.bitcoind = { enable = true; @@ -31,6 +35,11 @@ let testEnv = rec { tests.clightning = cfg.clightning.enable; # When WAN is disabled, DNS bootstrapping slows down service startup by ~15 s. services.clightning.extraConfig = mkIf config.test.noConnections "disable-dns"; + test.data.clightning-plugins = let + plugins = config.services.clightning.plugins; + enabled = builtins.filter (plugin: plugins.${plugin}.enable) (builtins.attrNames plugins); + pluginPkgs = config.nix-bitcoin.pkgs.clightning-plugins; + in map (plugin: pluginPkgs.${plugin}.path) enabled; tests.spark-wallet = cfg.spark-wallet.enable; @@ -67,7 +76,28 @@ let testEnv = rec { systemd.services.generate-secrets.postStart = mkIfTest "security" '' install -o nobody -g nogroup -m777 <(:) /secrets/dummy ''; - }; + } + (mkIf config.test.features.clightningPlugins { + services.clightning.plugins = { + helpme.enable = true; + monitor.enable = true; + prometheus.enable = true; + rebalance.enable = true; + summary.enable = true; + zmq = let tcpEndpoint = "tcp://127.0.0.1:5501"; in { + enable = true; + channel-opened = tcpEndpoint; + connect = tcpEndpoint; + disconnect = tcpEndpoint; + invoice-payment = tcpEndpoint; + warning = tcpEndpoint; + forward-event = tcpEndpoint; + sendpay-success = tcpEndpoint; + sendpay-failure = tcpEndpoint; + }; + }; + }) + ]; }; scenarios = { @@ -80,6 +110,7 @@ let testEnv = rec { tests.security = true; services.clightning.enable = true; + test.features.clightningPlugins = true; services.spark-wallet.enable = true; services.lightning-charge.enable = true; services.nanopos.enable = true; @@ -120,6 +151,7 @@ let testEnv = rec { regtest = { imports = [ scenarios.regtestBase ]; services.clightning.enable = true; + test.features.clightningPlugins = true; services.spark-wallet.enable = true; services.lnd.enable = true; services.lightning-loop.enable = true; diff --git a/test/tests.py b/test/tests.py index 47d4325..64250a5 100644 --- a/test/tests.py +++ b/test/tests.py @@ -1,4 +1,5 @@ from collections import OrderedDict +import json def succeed(*cmds): @@ -138,6 +139,20 @@ def _(): def _(): assert_running("clightning") assert_matches("su operator -c 'lightning-cli getinfo' | jq", '"id"') + if test_data["clightning-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) + 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: + log.log("Active clightning plugins:") + for p in test_data["clightning-plugins"]: + log.log(os.path.basename(p)) @test("lnd")