Skip to content

Commit cf3f0db

Browse files
committed
joinmarket: add option settings
Joinmarket settings can now be freely specified.
1 parent da2e473 commit cf3f0db

File tree

3 files changed

+131
-105
lines changed

3 files changed

+131
-105
lines changed

modules/joinmarket-ob-watcher.nix

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,19 @@ let
1919
default = "/var/lib/joinmarket-ob-watcher";
2020
description = "The data directory for JoinMarket orderbook watcher.";
2121
};
22+
settings = mkOption {
23+
type = with types; attrsOf anything;
24+
example = {
25+
LOGGING = {
26+
console_log_level = "DEBUG";
27+
};
28+
};
29+
description = ''
30+
Joinmarket settings.
31+
See here for possible options:
32+
https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/v0.9.11/src/jmclient/configure.py#L98
33+
'';
34+
};
2235
user = mkOption {
2336
type = types.str;
2437
default = "joinmarket-ob-watcher";
@@ -40,17 +53,6 @@ let
4053
secretsDir = config.nix-bitcoin.secretsDir;
4154

4255
inherit (config.services) bitcoind joinmarket;
43-
44-
configFile = builtins.toFile "config" ''
45-
[BLOCKCHAIN]
46-
blockchain_source = bitcoin-rpc
47-
network = ${bitcoind.network}
48-
rpc_host = ${bitcoind.rpc.address}
49-
rpc_port = ${toString bitcoind.rpc.port}
50-
rpc_user = ${bitcoind.rpc.users.joinmarket-ob-watcher.name}
51-
52-
${joinmarket.messagingConfig}
53-
'';
5456
in {
5557
inherit options;
5658

@@ -72,6 +74,18 @@ in {
7274
"d '${cfg.dataDir}' 0770 ${cfg.user} ${cfg.group} - -"
7375
];
7476

77+
services.joinmarket-ob-watcher.settings = {
78+
BLOCKCHAIN = config.services.joinmarket.settings.BLOCKCHAIN // {
79+
rpc_user = bitcoind.rpc.users.joinmarket-ob-watcher.name;
80+
rpc_wallet_file = "";
81+
};
82+
inherit (config.services.joinmarket.settings)
83+
"MESSAGING:onion"
84+
"MESSAGING:server1"
85+
"MESSAGING:server2"
86+
"MESSAGING:server3";
87+
};
88+
7589
systemd.services.joinmarket-ob-watcher = rec {
7690
wantedBy = [ "multi-user.target" ];
7791
requires = [ "tor.service" "bitcoind.service" ];
@@ -80,7 +94,7 @@ in {
8094
environment.HOME = cfg.dataDir;
8195
preStart = ''
8296
{
83-
cat ${configFile}
97+
cat ${builtins.toFile "joinmarket-ob-watcher.cfg" ((generators.toINI {}) cfg.settings)}
8498
echo
8599
echo '[BLOCKCHAIN]'
86100
echo "rpc_password = $(cat ${secretsDir}/bitcoin-rpcpassword-joinmarket-ob-watcher)"

modules/joinmarket.nix

Lines changed: 101 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,31 @@ let
4141
description = "The data directory for JoinMarket.";
4242
};
4343
rpcWalletFile = mkOption {
44-
type = types.nullOr types.str;
44+
type = types.nullOr types.nonEmptyStr;
4545
default = "jm_wallet";
4646
description = ''
4747
Name of the watch-only bitcoind wallet the JoinMarket addresses are imported to.
4848
'';
4949
};
50+
settings = mkOption {
51+
type = with types; attrsOf anything;
52+
example = {
53+
POLICY = {
54+
merge_algorithm = "gradual";
55+
tx_fees = 5;
56+
};
57+
LOGGING = {
58+
console_log_level = "DEBUG";
59+
};
60+
};
61+
description = ''
62+
Joinmarket settings.
63+
See here for possible options:
64+
https://raw.githubusercontent.com/JoinMarket-Org/joinmarket-clientserver/master/src/jmclient/configure.py#:~:text=defaultconfig%20=
65+
If your web browser does not support text fragment URLs, you can can manually
66+
search for string `defaultconfig =` to jump to the correct location.
67+
'';
68+
};
5069
user = mkOption {
5170
type = types.str;
5271
default = "joinmarket";
@@ -61,12 +80,6 @@ let
6180
default = cli;
6281
defaultText = "(See source)";
6382
};
64-
# Used by ./joinmarket-ob-watcher.nix
65-
messagingConfig = mkOption {
66-
readOnly = true;
67-
default = messagingConfig;
68-
defaultText = "(See source)";
69-
};
7083
# This option is only used by netns-isolation.
7184
# Tor is always enabled.
7285
tor.enforce = nbLib.tor.enforce;
@@ -142,88 +155,12 @@ let
142155
inherit (config.services) bitcoind;
143156

144157
torAddress = config.services.tor.client.socksListenAddress;
145-
socks5Settings = ''
146-
socks5 = true
147-
socks5_host = ${torAddress.addr}
148-
socks5_port = ${toString torAddress.port}
149-
'';
150-
151-
messagingConfig = ''
152-
[MESSAGING:onion]
153-
type = onion
154-
${socks5Settings}
155-
tor_control_host = unix:/run/tor/control
156-
# required option, but ignored for unix socket host
157-
tor_control_port = 9051
158-
onion_serving_host = ${cfg.messagingAddress}
159-
onion_serving_port = ${toString cfg.messagingPort}
160-
hidden_service_dir =
161-
directory_nodes = g3hv4uynnmynqqq2mchf3fcm3yd46kfzmcdogejuckgwknwyq5ya6iad.onion:5222,3kxw6lf5vf6y26emzwgibzhrzhmhqiw6ekrek3nqfjjmhwznb2moonad.onion:5222,bqlpq6ak24mwvuixixitift4yu42nxchlilrcqwk2ugn45tdclg42qid.onion:5222
162-
163-
# irc.darkscience.net
164-
[MESSAGING:server1]
165-
host = darkirc6tqgpnwd3blln3yfv5ckl47eg7llfxkmtovrv7c7iwohhb6ad.onion
166-
channel = joinmarket-pit
167-
port = 6697
168-
usessl = true
169-
${socks5Settings}
170-
171-
# ilita
172-
[MESSAGING:server2]
173-
host = ilitafrzzgxymv6umx2ux7kbz3imyeko6cnqkvy4nisjjj4qpqkrptid.onion
174-
channel = joinmarket-pit
175-
port = 6667
176-
usessl = false
177-
${socks5Settings}
178-
179-
# irc.hackint.org
180-
[MESSAGING:server3]
181-
host = ncwkrwxpq2ikcngxq3dy2xctuheniggtqeibvgofixpzvrwpa77tozqd.onion
182-
channel = joinmarket-pit
183-
port = 6667
184-
usessl = false
185-
${socks5Settings}
186-
'';
187-
188-
# Based on https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master/jmclient/jmclient/configure.py
189-
yg = cfg.yieldgenerator;
190-
configFile = builtins.toFile "config" ''
191-
[DAEMON]
192-
no_daemon = 0
193-
daemon_port = 27183
194-
daemon_host = 127.0.0.1
195-
196-
[BLOCKCHAIN]
197-
blockchain_source = ${bitcoind.makeNetworkName "bitcoin-rpc" "regtest"}
198-
network = ${bitcoind.makeNetworkName "mainnet" "testnet"}
199-
rpc_host = ${nbLib.address bitcoind.rpc.address}
200-
rpc_port = ${toString bitcoind.rpc.port}
201-
rpc_user = ${bitcoind.rpc.users.privileged.name}
202-
${optionalString (cfg.rpcWalletFile != null) "rpc_wallet_file = ${cfg.rpcWalletFile}"}
203-
204-
${messagingConfig}
205-
206-
[LOGGING]
207-
color = false
208-
209-
[PAYJOIN]
210-
onion_socks5_host = ${torAddress.addr}
211-
onion_socks5_port = ${toString torAddress.port}
212-
tor_control_host = unix:/run/tor/control
213-
onion_serving_host = ${cfg.payjoinAddress}
214-
onion_serving_port = ${toString cfg.payjoinPort}
215-
hidden_service_ssl = false
216158

217-
[YIELDGENERATOR]
218-
ordertype = ${yg.ordertype}
219-
cjfee_a = ${toString yg.cjfee_a}
220-
cjfee_r = ${toString yg.cjfee_r}
221-
cjfee_factor = ${toString yg.cjfee_factor}
222-
txfee_contribution = 0
223-
txfee_contribution_factor = ${toString yg.txfee_contribution_factor}
224-
minsize = ${toString yg.minsize}
225-
size_factor = ${toString yg.size_factor}
226-
'';
159+
socks5Settings = {
160+
socks5 = true;
161+
socks5_host = torAddress.addr;
162+
socks5_port = torAddress.port;
163+
};
227164

228165
# The jm scripts create a 'logs' dir in the working dir,
229166
# so run them inside dataDir.
@@ -242,7 +179,78 @@ let
242179
in {
243180
inherit options;
244181

245-
config = mkIf cfg.enable (mkMerge [{
182+
config = mkMerge [
183+
{
184+
services.joinmarket.settings = {
185+
DAEMON = {
186+
no_daemon = 0;
187+
daemon_port = 27183;
188+
daemon_host = "127.0.0.1";
189+
};
190+
BLOCKCHAIN = {
191+
blockchain_source = bitcoind.makeNetworkName "bitcoin-rpc" "regtest";
192+
network = bitcoind.makeNetworkName "mainnet" "testnet";
193+
rpc_host = nbLib.address bitcoind.rpc.address;
194+
rpc_port = bitcoind.rpc.port;
195+
rpc_user = bitcoind.rpc.users.privileged.name;
196+
rpc_wallet_file = if cfg.rpcWalletFile == null then "" else cfg.rpcWalletFile;
197+
};
198+
LOGGING = {
199+
color = false;
200+
};
201+
PAYJOIN = {
202+
onion_socks5_host = torAddress.addr;
203+
onion_socks5_port = torAddress.port;
204+
tor_control_host = "unix:/run/tor/control";
205+
onion_serving_host = cfg.payjoinAddress;
206+
onion_serving_port = cfg.payjoinPort;
207+
hidden_service_ssl = false;
208+
};
209+
YIELDGENERATOR = removeAttrs cfg.yieldgenerator [
210+
"enable"
211+
# TODO: This is only needed when ./obsolete-options.nix is imported
212+
"txfee"
213+
];
214+
215+
# Messaging settings have to be fully specified because joinmarket doesn't
216+
# provide default messaging settings.
217+
# (`jmclient/configure.py` actually does contain default messaging settings, but
218+
# they are removed via fn `_remove_unwanted_default_settings`)
219+
"MESSAGING:onion" = socks5Settings // {
220+
type = "onion";
221+
tor_control_host = "unix:/run/tor/control";
222+
# Required option, but ignored because `tor_control_host` is a unix socket
223+
tor_control_port = 9051;
224+
onion_serving_host = cfg.messagingAddress;
225+
onion_serving_port = cfg.messagingPort;
226+
hidden_service_dir = "";
227+
directory_nodes = "g3hv4uynnmynqqq2mchf3fcm3yd46kfzmcdogejuckgwknwyq5ya6iad.onion:5222,3kxw6lf5vf6y26emzwgibzhrzhmhqiw6ekrek3nqfjjmhwznb2moonad.onion:5222,bqlpq6ak24mwvuixixitift4yu42nxchlilrcqwk2ugn45tdclg42qid.onion:5222";
228+
};
229+
# irc.darkscience.net
230+
"MESSAGING:server1" = socks5Settings // {
231+
host = "darkirc6tqgpnwd3blln3yfv5ckl47eg7llfxkmtovrv7c7iwohhb6ad.onion";
232+
channel = "joinmarket-pit";
233+
port = 6697;
234+
usessl = true;
235+
};
236+
# ilita
237+
"MESSAGING:server2" = socks5Settings // {
238+
host = "ilitafrzzgxymv6umx2ux7kbz3imyeko6cnqkvy4nisjjj4qpqkrptid.onion";
239+
channel = "joinmarket-pit";
240+
port = 6667;
241+
usessl = false;
242+
};
243+
# irc.hackint.org
244+
"MESSAGING:server3" = socks5Settings // {
245+
host = "ncwkrwxpq2ikcngxq3dy2xctuheniggtqeibvgofixpzvrwpa77tozqd.onion";
246+
channel = "joinmarket-pit";
247+
port = 6667;
248+
usessl = false;
249+
};
250+
};
251+
}
252+
253+
(mkIf cfg.enable {
246254
services.bitcoind = {
247255
enable = true;
248256
disablewallet = false;
@@ -275,7 +283,7 @@ in {
275283
after = [ "bitcoind.service" "nix-bitcoin-secrets.target" ];
276284
preStart = ''
277285
{
278-
cat ${configFile}
286+
cat ${builtins.toFile "joinmarket.cfg" ((generators.toINI {}) cfg.settings)}
279287
echo
280288
echo '[BLOCKCHAIN]'
281289
echo "rpc_password = $(cat ${secretsDir}/bitcoin-rpcpassword-privileged)"
@@ -350,9 +358,9 @@ in {
350358
nix-bitcoin.generateSecretsCmds.joinmarket = ''
351359
makePasswordSecret jm-wallet-password
352360
'';
353-
}
361+
})
354362

355-
(mkIf cfg.yieldgenerator.enable {
363+
(mkIf (cfg.enable && cfg.yieldgenerator.enable) {
356364
systemd.services.joinmarket-yieldgenerator = {
357365
wantedBy = [ "joinmarket.service" ];
358366
requires = [ "joinmarket.service" ];
@@ -373,5 +381,5 @@ in {
373381
} // nbLib.allowTor;
374382
};
375383
})
376-
]);
384+
];
377385
}

pkgs/joinmarket/default.nix

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
{ stdenv, lib, fetchFromGitHub, python3, nbPython3PackagesJoinmarket }:
22

33
let
4+
# Note:
5+
# After updating this pkg, also update the following items in ../../modules/joinmarket.nix:
6+
# - The `MESSAGING:*` sections in the config value of option `settings`.
7+
# Copy the values from `jmclient/configure.py`.
48
version = "0.9.11";
59
src = fetchFromGitHub {
610
owner = "joinmarket-org";

0 commit comments

Comments
 (0)