···
9
-
cfg = config.services.rippled;
10
-
opt = options.services.rippled;
12
-
b2i = val: if val then "1" else "0";
17
-
${lib.optionalString (db.compression != null) ("compression=${b2i db.compression}")}
18
-
${lib.optionalString (db.onlineDelete != null) ("online_delete=${toString db.onlineDelete}")}
19
-
${lib.optionalString (db.advisoryDelete != null) ("advisory_delete=${b2i db.advisoryDelete}")}
26
-
${lib.concatMapStringsSep "\n" (n: "port_${n}") (lib.attrNames cfg.ports)}
28
-
${lib.concatMapStrings (p: ''
31
-
port=${toString p.port}
32
-
protocol=${lib.concatStringsSep "," p.protocol}
33
-
${lib.optionalString (p.user != "") "user=${p.user}"}
34
-
${lib.optionalString (p.password != "") "user=${p.password}"}
35
-
admin=${lib.concatStringsSep "," p.admin}
36
-
${lib.optionalString (p.ssl.key != null) "ssl_key=${p.ssl.key}"}
37
-
${lib.optionalString (p.ssl.cert != null) "ssl_cert=${p.ssl.cert}"}
38
-
${lib.optionalString (p.ssl.chain != null) "ssl_chain=${p.ssl.chain}"}
39
-
'') (lib.attrValues cfg.ports)}
47
-
${lib.optionalString (cfg.tempDb != null) ''
49
-
${dbCfg cfg.tempDb}''}
51
-
${lib.optionalString (cfg.importDb != null) ''
53
-
${dbCfg cfg.importDb}''}
56
-
${lib.concatStringsSep "\n" cfg.ips}
59
-
${lib.concatStringsSep "\n" cfg.ipsFixed}
62
-
${lib.concatStringsSep "\n" cfg.validators}
68
-
${toString cfg.ledgerHistory}
71
-
${toString cfg.fetchDepth}
74
-
${toString cfg.validationQuorum}
77
-
${lib.concatStringsSep "\n" cfg.sntpServers}
79
-
${lib.optionalString cfg.statsd.enable ''
82
-
address=${cfg.statsd.address}
83
-
prefix=${cfg.statsd.prefix}
87
-
{ "command": "log_level", "severity": "${cfg.logLevel}" }
95
-
name = lib.mkOption {
100
-
ip = lib.mkOption {
101
-
default = "127.0.0.1";
102
-
description = "Ip where rippled listens.";
103
-
type = lib.types.str;
106
-
port = lib.mkOption {
107
-
description = "Port where rippled listens.";
108
-
type = lib.types.port;
111
-
protocol = lib.mkOption {
112
-
description = "Protocols expose by rippled.";
113
-
type = lib.types.listOf (
124
-
user = lib.mkOption {
125
-
description = "When set, these credentials will be required on HTTP/S requests.";
126
-
type = lib.types.str;
130
-
password = lib.mkOption {
131
-
description = "When set, these credentials will be required on HTTP/S requests.";
132
-
type = lib.types.str;
136
-
admin = lib.mkOption {
137
-
description = "A comma-separated list of admin IP addresses.";
138
-
type = lib.types.listOf lib.types.str;
139
-
default = [ "127.0.0.1" ];
143
-
key = lib.mkOption {
145
-
Specifies the filename holding the SSL key in PEM format.
148
-
type = lib.types.nullOr lib.types.path;
151
-
cert = lib.mkOption {
153
-
Specifies the path to the SSL certificate file in PEM format.
154
-
This is not needed if the chain includes it.
157
-
type = lib.types.nullOr lib.types.path;
160
-
chain = lib.mkOption {
162
-
If you need a certificate chain, specify the path to the
163
-
certificate chain here. The chain may include the end certificate.
166
-
type = lib.types.nullOr lib.types.path;
174
-
type = lib.mkOption {
175
-
description = "Rippled database type.";
176
-
type = lib.types.enum [
180
-
default = "rocksdb";
183
-
path = lib.mkOption {
184
-
description = "Location to store the database.";
185
-
type = lib.types.path;
186
-
default = cfg.databasePath;
187
-
defaultText = lib.literalExpression "config.${opt.databasePath}";
190
-
compression = lib.mkOption {
191
-
description = "Whether to enable snappy compression.";
192
-
type = lib.types.nullOr lib.types.bool;
196
-
onlineDelete = lib.mkOption {
197
-
description = "Enable automatic purging of older ledger information.";
198
-
type = lib.types.nullOr (lib.types.addCheck lib.types.int (v: v > 256));
199
-
default = cfg.ledgerHistory;
200
-
defaultText = lib.literalExpression "config.${opt.ledgerHistory}";
203
-
advisoryDelete = lib.mkOption {
205
-
If set, then require administrative RPC call "can_delete"
206
-
to enable online deletion of ledger records.
208
-
type = lib.types.nullOr lib.types.bool;
212
-
extraOpts = lib.mkOption {
213
-
description = "Extra database options.";
214
-
type = lib.types.lines;
227
-
services.rippled = {
228
-
enable = lib.mkEnableOption "rippled, a decentralized cryptocurrency blockchain daemon implementing the XRP Ledger protocol in C++";
230
-
package = lib.mkPackageOption pkgs "rippled" { };
232
-
ports = lib.mkOption {
233
-
description = "Ports exposed by rippled";
234
-
type = with lib.types; attrsOf (submodule portOptions);
238
-
admin = [ "127.0.0.1" ];
239
-
protocol = [ "http" ];
245
-
protocol = [ "peer" ];
259
-
nodeDb = lib.mkOption {
260
-
description = "Rippled main database options.";
261
-
type = with lib.types; nullOr (submodule dbOptions);
274
-
tempDb = lib.mkOption {
275
-
description = "Rippled temporary database options.";
276
-
type = with lib.types; nullOr (submodule dbOptions);
280
-
importDb = lib.mkOption {
281
-
description = "Settings for performing a one-time import.";
282
-
type = with lib.types; nullOr (submodule dbOptions);
286
-
nodeSize = lib.mkOption {
288
-
Rippled size of the node you are running.
289
-
"tiny", "small", "medium", "large", and "huge"
291
-
type = lib.types.enum [
301
-
ips = lib.mkOption {
303
-
List of hostnames or ips where the Ripple protocol is served.
304
-
For a starter list, you can either copy entries from:
305
-
https://ripple.com/ripple.txt or if you prefer you can let it
306
-
default to r.ripple.com 51235
308
-
A port may optionally be specified after adding a space to the
309
-
address. By convention, if known, IPs are listed in from most
312
-
type = lib.types.listOf lib.types.str;
313
-
default = [ "r.ripple.com 51235" ];
316
-
ipsFixed = lib.mkOption {
318
-
List of IP addresses or hostnames to which rippled should always
319
-
attempt to maintain peer connections with. This is useful for
320
-
manually forming private networks, for example to configure a
321
-
validation server that connects to the Ripple network through a
322
-
public-facing server, or for building a set of cluster peers.
324
-
A port may optionally be specified after adding a space to the address
326
-
type = lib.types.listOf lib.types.str;
330
-
validators = lib.mkOption {
332
-
List of nodes to always accept as validators. Nodes are specified by domain
335
-
type = lib.types.listOf lib.types.str;
337
-
"n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7 RL1"
338
-
"n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj RL2"
339
-
"n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C RL3"
340
-
"n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS RL4"
341
-
"n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA RL5"
345
-
databasePath = lib.mkOption {
347
-
Path to the ripple database.
349
-
type = lib.types.path;
350
-
default = "/var/lib/rippled";
353
-
validationQuorum = lib.mkOption {
355
-
The minimum number of trusted validations a ledger must have before
356
-
the server considers it fully validated.
358
-
type = lib.types.int;
362
-
ledgerHistory = lib.mkOption {
364
-
The number of past ledgers to acquire on server startup and the minimum
365
-
to maintain while running.
367
-
type = lib.types.either lib.types.int (lib.types.enum [ "full" ]);
368
-
default = 1296000; # 1 month
371
-
fetchDepth = lib.mkOption {
373
-
The number of past ledgers to serve to other peers that request historical
374
-
ledger data (or "full" for no limit).
376
-
type = lib.types.either lib.types.int (lib.types.enum [ "full" ]);
380
-
sntpServers = lib.mkOption {
382
-
IP address or domain of NTP servers to use for time synchronization.;
384
-
type = lib.types.listOf lib.types.str;
393
-
logLevel = lib.mkOption {
394
-
description = "Logging verbosity.";
395
-
type = lib.types.enum [
404
-
enable = lib.mkEnableOption "statsd monitoring for rippled";
406
-
address = lib.mkOption {
407
-
description = "The UDP address and port of the listening StatsD server.";
408
-
default = "127.0.0.1:8125";
409
-
type = lib.types.str;
412
-
prefix = lib.mkOption {
413
-
description = "A string prepended to each collected metric.";
415
-
type = lib.types.str;
419
-
extraConfig = lib.mkOption {
421
-
type = lib.types.lines;
423
-
Extra lines to be added verbatim to the rippled.cfg configuration file.
427
-
config = lib.mkOption {
429
-
default = pkgs.writeText "rippled.conf" rippledCfg;
430
-
defaultText = lib.literalMD "generated config file";
435
-
###### implementation
437
-
config = lib.mkIf cfg.enable {
439
-
users.users.rippled = {
440
-
description = "Ripple server user";
441
-
isSystemUser = true;
443
-
home = cfg.databasePath;
446
-
users.groups.rippled = { };
448
-
systemd.services.rippled = {
449
-
after = [ "network.target" ];
450
-
wantedBy = [ "multi-user.target" ];
453
-
ExecStart = "${cfg.package}/bin/rippled --fg --conf ${cfg.config}";
455
-
Restart = "on-failure";
456
-
LimitNOFILE = 10000;
460
-
environment.systemPackages = [ cfg.package ];