Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for core lightning watchtower TEoS (The Eye of Satoshi) - server and client #543

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
b901f4e
rust-teos: init at 0.1.2
seberm Aug 28, 2022
c5356af
rust-teos: add module
seberm Aug 30, 2022
1541cc8
clightning: add TEoS watchtower plugin
seberm Oct 18, 2022
174124d
teos: add new options and defaults for teos v0.2.0
seberm Mar 3, 2023
fd7e178
teos: fix onion ports to be handled by the nix-bitcoin onion-services…
seberm Jun 28, 2023
e466074
teos: change btc network name to mainnet
seberm Jun 28, 2023
c47eab6
teos: improve the docs in example configuration
seberm Oct 9, 2023
be06246
teos: enable tor in teos conditionally
seberm Oct 9, 2023
d5ae5a4
teos: rename the teos-watchtower-plugin to just teos-watchtower
seberm Oct 9, 2023
e0c5afc
teos: fix the onionServices condition
seberm Oct 9, 2023
9e95d94
teos: just enable onion service for teos, no need to set it public
seberm Oct 9, 2023
a90ced3
teos: fix the onion services port mapping
seberm Oct 9, 2023
aa51b19
teos: add documentation watchtower plugin usage in lightning-cli
seberm Oct 9, 2023
c2bbc7f
teos: tests: improve tests for teos service and teos-cli
seberm Oct 10, 2023
f56346c
teos: tests: add tests for cln watchtower plugin
seberm Oct 10, 2023
2ec0b4f
teos: netns: add possibility of clightning to connect to local teos s…
seberm Oct 12, 2023
25f4db3
teos: final code cleanup
seberm Oct 12, 2023
92113dd
nodeinfo: add teos tower ID
seberm Oct 17, 2023
b1802c3
clightning: watchtower: do not hide the tower data directory
seberm Nov 22, 2023
bd3f0d9
backups: add teos and teos-watchtower to regular backups
seberm Nov 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ NixOS modules ([src](modules/modules.nix))
* [monitor](https://github.com/lightningd/plugins/tree/master/monitor): helps you analyze the health of your peers and channels
* [rebalance](https://github.com/lightningd/plugins/tree/master/rebalance): keeps your channels balanced
* [trustedcoin](https://github.com/nbd-wtf/trustedcoin) ([experimental](docs/services.md#trustedcoin)): replaces bitcoind with trusted public explorers
* [teos-watchtower](https://github.com/talaia-labs/rust-teos/tree/master/watchtower-plugin): watchtower client plugin [to interact](docs/services.md#the-eye-of-satoshi-watchtower-plugin) with an Eye of Satoshi tower
* [zmq](https://github.com/lightningd/plugins/tree/master/zmq): publishes notifications via ZeroMQ to configured endpoints
* [clightning-rest](https://github.com/Ride-The-Lightning/c-lightning-REST): REST server for clightning
* [lnd](https://github.com/lightningnetwork/lnd) with support for announcing an onion service and [static channel backups](https://github.com/lightningnetwork/lnd/blob/master/docs/recovery.md)
Expand All @@ -90,6 +91,7 @@ NixOS modules ([src](modules/modules.nix))
* [mempool](https://github.com/mempool/mempool): Bitcoin visualizer, explorer, and API service
* [electrs](https://github.com/romanz/electrs): Electrum server
* [fulcrum](https://github.com/cculianu/Fulcrum): Electrum server (see [the module](modules/fulcrum.nix) for a comparison with electrs)
* [teos](https://github.com/talaia-labs/rust-teos) a Lightning watchtower
* [btcpayserver](https://github.com/btcpayserver/btcpayserver)
* [liquid](https://github.com/elementsproject/elements): federated sidechain
* [JoinMarket](https://github.com/joinmarket-org/joinmarket-clientserver)
Expand Down
35 changes: 35 additions & 0 deletions docs/services.md
Original file line number Diff line number Diff line change
Expand Up @@ -594,3 +594,38 @@ To work around this and connect via clearnet instead, set this option:
```nix
services.clightning.plugins.trustedcoin.tor.proxy = false;
```

### The Eye of Satoshi watchtower plugin
The basic usage of this plugin you can find in [its documentation](https://github.com/talaia-labs/rust-teos/blob/master/watchtower-plugin/README.md).

The registration of a new tower can be done by calling the command in the
following forms:

```
lightning-cli registertower <tower_id>[@<host>[:<port>]]

or

lightning-cli registertower <tower_id> [<host> [<port>]]
```

The `tower_id` represents the target tower public key. If the target watchtower
server uses TEoS, you can get this id by calling the `teos-cli gettowerinfo`
command.

```
lightning-cli registertower 032f7fa1823ab3c611833f2d61ed7d7e513886f5a6862d33dff71857b9cacb8b45@example.com:9814

or via onion:

lightning-cli registertower 032f7fa1823ab3c611833f2d61ed7d7e513886f5a6862d33dff71857b9cacb8b45 xryayjsnc7j2jhqihd7je7sd2dsi4l33hj5v5xbfnvjjiapdxc4el5ad.onion 9814
```

Please note that the [plugin proxy configuration](https://github.com/talaia-labs/rust-teos/blob/master/watchtower-plugin/README.md#core-lightning-cln-config)
is loaded directly from the clightning. This means you must have a
`services.clightning.tor.proxy` enabled to be able to connect to the tower
behind the Tor. Otherwise you get the following error:

```
Cannot connect to an onion address without a proxy
```
8 changes: 8 additions & 0 deletions examples/configuration.nix
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,14 @@
# services.charge-lnd.policies = ''
# '';

### THE EYE OF SATOSHI
# Set this to enable TEoS, a Lightning watchtower compliant with BOLT13.
# services.teos.enable = true;
#
# Set this to create an onion service by which teos can accept incoming
# connections via Tor.
# nix-bitcoin.onionServices.teos.enable = true;

seberm marked this conversation as resolved.
Show resolved Hide resolved
### JOINMARKET
# Set this to enable the JoinMarket service, including its command-line scripts.
# These scripts have prefix 'jm-', like 'jm-tumbler'.
Expand Down
2 changes: 2 additions & 0 deletions modules/backups.nix
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ let
''}
${config.services.bitcoind.dataDir}
${config.services.clightning.dataDir}
${config.services.clightning.plugins.teos-watchtower.dataDir}
${config.services.clightning-rest.dataDir}
${config.services.lnd.dataDir}
${optionalString (!cfg.with-bulk-data) ''
Expand All @@ -71,6 +72,7 @@ let
''}
${config.services.liquidd.dataDir}
${optionalString cfg.with-bulk-data "${config.services.electrs.dataDir}"}
${optionalString cfg.with-bulk-data "${config.services.teos.dataDir}"}
${config.services.nbxplorer.dataDir}
${config.services.btcpayserver.dataDir}
${config.services.joinmarket.dataDir}
Expand Down
1 change: 1 addition & 0 deletions modules/clightning-plugins/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ in {
./clboss.nix
./feeadjuster.nix
./trustedcoin.nix
./teos-watchtower.nix
./zmq.nix
];

Expand Down
51 changes: 51 additions & 0 deletions modules/clightning-plugins/teos-watchtower.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{ config, lib, ... }:

with lib;
let cfg = config.services.clightning.plugins.teos-watchtower; in
{
# Ref.: https://github.com/talaia-labs/rust-teos/tree/master/watchtower-plugin
options.services.clightning.plugins.teos-watchtower = {
enable = mkEnableOption "TEoS watchtower (clightning plugin)";
package = mkOption {
type = types.package;
default = config.nix-bitcoin.pkgs.teos-watchtower-plugin;
defaultText = "config.nix-bitcoin.pkgs.teos-watchtower-plugin";
description = mdDoc "The package providing TEoS watchtower plugin binaries.";
};
port = mkOption {
type = types.port;
default = config.services.teos.port;
description = mdDoc "Tower API port.";
};
dataDir = mkOption {
type = types.path;
default = "${config.services.clightning.dataDir}/watchtower";
description = mdDoc "The data directory for teos-watchtower.";
};
maxRetryTime = mkOption {
type = types.int;
default = 3600;
description = mdDoc "For how long (in seconds) a retry strategy will try to reach a temporary unreachable tower before giving up.";
};
autoRetryDelay = mkOption {
type = types.int;
default = 28800;
description = mdDoc "For how long (in seconds) the client will wait before auto-retrying a failed tower.";
};
};

config = mkIf cfg.enable {
services.clightning.extraConfig = ''
plugin=${cfg.package}/bin/watchtower-client
watchtower-port=${toString cfg.port}
watchtower-max-retry-time=${toString cfg.maxRetryTime}
watchtower-auto-retry-delay=${toString cfg.autoRetryDelay}
'';

# The data directory of teos-watchtower must be specified and must
# be writeable. Otherwise the plugin fails to load.
systemd.services.clightning.environment = {
TOWERS_DATA_DIR = cfg.dataDir;
};
};
}
1 change: 1 addition & 0 deletions modules/modules.nix
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
./rtl.nix
./mempool.nix
./electrs.nix
./teos.nix
./fulcrum.nix
./liquid.nix
./btcpayserver.nix
Expand Down
13 changes: 12 additions & 1 deletion modules/netns-isolation.nix
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,8 @@ in {
};
clightning = {
id = 13;
connections = [ "bitcoind" ];
connections = [ "bitcoind" ]
++ optional config.services.teos.enable "teos";
};
lnd = {
id = 14;
Expand Down Expand Up @@ -303,6 +304,10 @@ in {
(if (config.services.mempool.electrumServer == "electrs") then "electrs" else "fulcrum")
];
};
teos = {
id = 33;
connections = [ "bitcoind" ];
};
};

services.bitcoind = {
Expand Down Expand Up @@ -335,6 +340,12 @@ in {

services.fulcrum.address = netns.fulcrum.address;

services.teos = {
address = netns.teos.address;
rpc.address = netns.teos.address;
internalApi.address = netns.teos.address;
};

services.lightning-loop.rpcAddress = netns.lightning-loop.address;

services.nbxplorer.address = netns.nbxplorer.address;
Expand Down
5 changes: 5 additions & 0 deletions modules/nodeinfo.nix
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ in {
clightning-rest = mkInfo "";
electrs = mkInfo "";
fulcrum = mkInfo "";
teos = mkInfo ''
info["tower_id"] = shell("teos-cli gettowerinfo | jq -r '.tower_id'")
if 'onion_address' in info:
info["id"] = f"{info['tower_id']}@{info['onion_address']}"
'';
btcpayserver = mkInfo "";
liquidd = mkInfo "";
joinmarket-ob-watcher = mkInfo "";
Expand Down
2 changes: 2 additions & 0 deletions modules/presets/enable-tor.nix
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ in {
#
electrs = defaultEnforceTor;
fulcrum = defaultEnforceTor;
teos = defaultEnforceTor;
nbxplorer = defaultEnforceTor;
rtl = defaultEnforceTor;
joinmarket = defaultEnforceTor;
Expand All @@ -48,6 +49,7 @@ in {
liquidd.enable = defaultTrue;
electrs.enable = defaultTrue;
fulcrum.enable = defaultTrue;
teos.enable = defaultTrue;
joinmarket-ob-watcher.enable = defaultTrue;
rtl.enable = defaultTrue;
};
Expand Down
180 changes: 180 additions & 0 deletions modules/teos.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
{ config, lib, pkgs, ... }:

with lib;
let
options.services.teos = {
enable = mkEnableOption "Lightning watchtower compliant with BOLT13, written in Rust";
address = mkOption {
type = types.str;
default = "127.0.0.1";
description = mdDoc "Address to listen for API connections.";
};
port = mkOption {
type = types.port;
default = 9814;
description = mdDoc "Port to listen for API connections.";
};

rpc = {
address = mkOption {
type = types.str;
default = "127.0.0.1";
description = mdDoc "Address to listen for RPC connections.";
};
port = mkOption {
type = types.port;
default = 8814;
description = mdDoc "Port to listen for RPC connections.";
};
};

internalApi = {
address = mkOption {
type = types.str;
default = "127.0.0.1";
description = mdDoc "Address to listen for internal API connections.";
};
port = mkOption {
type = types.port;
default = 50051;
description = mdDoc "Port to listen for internal API connections.";
};
};

dataDir = mkOption {
type = types.path;
default = "/var/lib/teos";
description = mdDoc "The data directory for teos.";
};
extraArgs = mkOption {
type = types.separatedString " ";
default = "";
description = mdDoc "Extra command line arguments passed to teosd.";
};
user = mkOption {
type = types.str;
default = "teos";
description = mdDoc "The user as which to run teos.";
};
group = mkOption {
type = types.str;
default = cfg.user;
description = mdDoc "The group as which to run teos.";
};
package = mkOption {
type = types.package;
default = nbPkgs.teos;
defaultText = "config.nix-bitcoin.pkgs.teos";
description = mdDoc "The package providing teos binaries.";
};
cli = mkOption {
readOnly = true;
default = pkgs.writeScriptBin "teos-cli" ''
${cfg.package}/bin/teos-cli --datadir='${cfg.dataDir}' "$@"
'';
defaultText = "(See source)";
description = mdDoc "Binary to connect with the teos instance.";
};
tor.enforce = nbLib.tor.enforce;
};

cfg = config.services.teos;
nbLib = config.nix-bitcoin.lib;
nbPkgs = config.nix-bitcoin.pkgs;

secretsDir = config.nix-bitcoin.secretsDir;
bitcoind = config.services.bitcoind;
in {
inherit options;

config = mkIf cfg.enable {
services.bitcoind = {
enable = true;
listenWhitelisted = true;
};

environment.systemPackages = [ cfg.package (hiPrio cfg.cli) ];

systemd.tmpfiles.rules = [
"d '${cfg.dataDir}' 0770 ${cfg.user} ${cfg.group} - -"
];

systemd.services.teos = {
wantedBy = [ "multi-user.target" ];
requires = [ "bitcoind.service" ];
after = [ "bitcoind.service" ];

# Example configuration file:
# Ref.:
# - https://github.com/talaia-labs/rust-teos/blob/master/teos/src/conf_template.toml
#
# Note about tor support:
# We don't want to enable TOR support in teos configuration file, because
# the `tor_support = true` option would create an additional endpoint to
# the clearnet HTTP API. The optional Tor support is configured by
# onionServices.
# Ref.:
# - https://github.com/talaia-labs/rust-teos/issues/174
preStart = ''
install -m 640 /dev/null teos.toml

cat <<EOF > teos.toml
# API
api_bind = "${cfg.address}"
api_port = ${toString cfg.port}

# Tor
tor_support = false

# RPC
rpc_bind = "${cfg.rpc.address}"
rpc_port = ${toString cfg.rpc.port}

# bitcoind
btc_network = "${bitcoind.makeNetworkName "mainnet" "regtest"}"
btc_rpc_user = "${bitcoind.rpc.users.public.name}"
btc_rpc_password = "$(cat ${secretsDir}/bitcoin-rpcpassword-public)"
btc_rpc_connect = "${bitcoind.rpc.address}"
btc_rpc_port = ${toString bitcoind.rpc.port}

# Flags
debug = false
overwrite_key = false

# General
subscription_slots = 10000
subscription_duration = 4320
expiry_delta = 6
min_to_self_delay = 20
polling_delta = 60

# Internal API
internal_api_bind = "${cfg.internalApi.address}"
internal_api_port = ${toString cfg.internalApi.port}
EOF
'';

serviceConfig = nbLib.defaultHardening // {
WorkingDirectory = cfg.dataDir;
ExecStart = ''
${cfg.package}/bin/teosd \
--datadir='${cfg.dataDir}' \
${cfg.extraArgs}
'';
User = cfg.user;
Group = cfg.group;
Restart = "on-failure";
RestartSec = "10s";
ReadWritePaths = [ cfg.dataDir ];
} // nbLib.allowedIPAddresses cfg.tor.enforce;
};

users.users.${cfg.user} = {
isSystemUser = true;
group = cfg.group;
extraGroups = [ "bitcoinrpc-public" ];
};
users.groups.${cfg.group} = {};
nix-bitcoin.operator.groups = [ cfg.group ];
};
}
Loading