Skip to content

Commit 6e208d6

Browse files
committed
Merge #722: joinmarket: Add option settings
cf3f0db joinmarket: add option `settings` (Erik Arvstedt) da2e473 joinmarket: don't set default config options (Erik Arvstedt) 74eb9a1 joinmarket/yieldgenerator: add docs link to description (Erik Arvstedt) 5694408 joinmarket: remove deleted option `txfee` (Erik Arvstedt) Pull request description: ACKs for top commit: jonasnick: utACK cf3f0db Tree-SHA512: 36754539670dedcc494b28fa8383b189bd8fcf4044e0be624f47db953b189d706ed76df305e10fbea69f4e0dd9c419eb1eaf35de75e860883ea3305456fc31ed
2 parents 9429c4a + cf3f0db commit 6e208d6

File tree

6 files changed

+150
-152
lines changed

6 files changed

+150
-152
lines changed

docs/services.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,8 +543,8 @@ See [here](https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master
543543
services.joinmarket.yieldgenerator = {
544544
enable = true;
545545
# Optional: Add custom parameters
546-
txfee = 200;
547546
cjfee_a = 300;
547+
cjfee_r = 0.00003;
548548
};
549549
'';
550550
```

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: 109 additions & 137 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,19 +80,20 @@ 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;
7386
inherit (nbLib) cliExec;
7487

7588
yieldgenerator = {
76-
enable = mkEnableOption "JoinMarket yield generator bot";
89+
enable = mkOption {
90+
type = types.bool;
91+
default = false;
92+
description = ''
93+
Enable the JoinMarket yield generator bot.
94+
Documentation: https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master/docs/YIELDGENERATOR.md
95+
'';
96+
};
7797
ordertype = mkOption {
7898
type = types.enum [ "reloffer" "absoffer" ];
7999
default = "reloffer";
@@ -102,13 +122,6 @@ let
102122
Variance around the average cj fee.
103123
'';
104124
};
105-
txfee = mkOption {
106-
type = types.ints.unsigned;
107-
default = 100;
108-
description = ''
109-
The average transaction fee you're adding to coinjoin transactions.
110-
'';
111-
};
112125
txfee_contribution_factor = mkOption {
113126
type = types.float;
114127
default = 0.3;
@@ -142,124 +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-
use_ssl = false
196-
197-
[BLOCKCHAIN]
198-
blockchain_source = ${bitcoind.makeNetworkName "bitcoin-rpc" "regtest"}
199-
network = ${bitcoind.makeNetworkName "mainnet" "testnet"}
200-
rpc_host = ${nbLib.address bitcoind.rpc.address}
201-
rpc_port = ${toString bitcoind.rpc.port}
202-
rpc_user = ${bitcoind.rpc.users.privileged.name}
203-
${optionalString (cfg.rpcWalletFile != null) "rpc_wallet_file = ${cfg.rpcWalletFile}"}
204-
205-
${messagingConfig}
206158

207-
[LOGGING]
208-
console_log_level = INFO
209-
color = false
210-
211-
[POLICY]
212-
segwit = true
213-
native = true
214-
merge_algorithm = default
215-
gaplimit = 6
216-
tx_fees = 3
217-
tx_fees_factor = 0.2
218-
absurd_fee_per_kb = 350000
219-
max_sweep_fee_change = 0.8
220-
tx_broadcast = self
221-
minimum_makers = 4
222-
max_sats_freeze_reuse = -1
223-
interest_rate = 0.015
224-
bondless_makers_allowance = 0.125
225-
bond_value_exponent = 1.3
226-
taker_utxo_retries = 3
227-
taker_utxo_age = 5
228-
taker_utxo_amtpercent = 20
229-
accept_commitment_broadcasts = 1
230-
commit_file_location = cmtdata/commitments.json
231-
commitment_list_location = cmtdata/commitmentlist
232-
233-
[PAYJOIN]
234-
payjoin_version = 1
235-
disable_output_substitution = 0
236-
max_additional_fee_contribution = default
237-
min_fee_rate = 1.1
238-
onion_socks5_host = ${torAddress.addr}
239-
onion_socks5_port = ${toString torAddress.port}
240-
tor_control_host = unix:/run/tor/control
241-
# Required option, but unused because `tor_control_host` is a Unix socket
242-
tor_control_port = 9051
243-
onion_serving_host = ${cfg.payjoinAddress}
244-
onion_serving_port = ${toString cfg.payjoinPort}
245-
hidden_service_ssl = false
246-
247-
[YIELDGENERATOR]
248-
ordertype = ${yg.ordertype}
249-
cjfee_a = ${toString yg.cjfee_a}
250-
cjfee_r = ${toString yg.cjfee_r}
251-
cjfee_factor = ${toString yg.cjfee_factor}
252-
txfee_contribution = 0
253-
txfee_contribution_factor = ${toString yg.txfee_contribution_factor}
254-
minsize = ${toString yg.minsize}
255-
size_factor = ${toString yg.size_factor}
256-
257-
[SNICKER]
258-
enabled = false
259-
lowest_net_gain = 0
260-
servers = cn5lfwvrswicuxn3gjsxoved6l2gu5hdvwy5l3ev7kg6j7lbji2k7hqd.onion,
261-
polling_interval_minutes = 60
262-
'';
159+
socks5Settings = {
160+
socks5 = true;
161+
socks5_host = torAddress.addr;
162+
socks5_port = torAddress.port;
163+
};
263164

264165
# The jm scripts create a 'logs' dir in the working dir,
265166
# so run them inside dataDir.
@@ -278,7 +179,78 @@ let
278179
in {
279180
inherit options;
280181

281-
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 {
282254
services.bitcoind = {
283255
enable = true;
284256
disablewallet = false;
@@ -311,7 +283,7 @@ in {
311283
after = [ "bitcoind.service" "nix-bitcoin-secrets.target" ];
312284
preStart = ''
313285
{
314-
cat ${configFile}
286+
cat ${builtins.toFile "joinmarket.cfg" ((generators.toINI {}) cfg.settings)}
315287
echo
316288
echo '[BLOCKCHAIN]'
317289
echo "rpc_password = $(cat ${secretsDir}/bitcoin-rpcpassword-privileged)"
@@ -386,9 +358,9 @@ in {
386358
nix-bitcoin.generateSecretsCmds.joinmarket = ''
387359
makePasswordSecret jm-wallet-password
388360
'';
389-
}
361+
})
390362

391-
(mkIf cfg.yieldgenerator.enable {
363+
(mkIf (cfg.enable && cfg.yieldgenerator.enable) {
392364
systemd.services.joinmarket-yieldgenerator = {
393365
wantedBy = [ "joinmarket.service" ];
394366
requires = [ "joinmarket.service" ];
@@ -409,5 +381,5 @@ in {
409381
} // nbLib.allowTor;
410382
};
411383
})
412-
]);
384+
];
413385
}

0 commit comments

Comments
 (0)