1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8
9 cfg = config.services.erigon;
10
11 settingsFormat = pkgs.formats.toml { };
12 configFile = settingsFormat.generate "config.toml" cfg.settings;
13in
14{
15
16 options = {
17 services.erigon = {
18 enable = lib.mkEnableOption "Ethereum implementation on the efficiency frontier";
19
20 package = lib.mkPackageOption pkgs "erigon" { };
21
22 extraArgs = lib.mkOption {
23 type = lib.types.listOf lib.types.str;
24 description = "Additional arguments passed to Erigon";
25 default = [ ];
26 };
27
28 secretJwtPath = lib.mkOption {
29 type = lib.types.path;
30 description = ''
31 Path to the secret jwt used for the http api authentication.
32 '';
33 default = "";
34 example = "config.age.secrets.ERIGON_JWT.path";
35 };
36
37 settings = lib.mkOption {
38 description = ''
39 Configuration for Erigon
40 Refer to <https://github.com/ledgerwatch/erigon#usage> for details on supported values.
41 '';
42
43 type = settingsFormat.type;
44
45 example = {
46 datadir = "/var/lib/erigon";
47 chain = "mainnet";
48 http = true;
49 "http.port" = 8545;
50 "http.api" = [
51 "eth"
52 "debug"
53 "net"
54 "trace"
55 "web3"
56 "erigon"
57 ];
58 ws = true;
59 port = 30303;
60 "authrpc.port" = 8551;
61 "torrent.port" = 42069;
62 "private.api.addr" = "localhost:9090";
63 "log.console.verbosity" = 3; # info
64 };
65
66 defaultText = lib.literalExpression ''
67 {
68 datadir = "/var/lib/erigon";
69 chain = "mainnet";
70 http = true;
71 "http.port" = 8545;
72 "http.api" = ["eth" "debug" "net" "trace" "web3" "erigon"];
73 ws = true;
74 port = 30303;
75 "authrpc.port" = 8551;
76 "torrent.port" = 42069;
77 "private.api.addr" = "localhost:9090";
78 "log.console.verbosity" = 3; # info
79 }
80 '';
81 };
82 };
83 };
84
85 config = lib.mkIf cfg.enable {
86 # Default values are the same as in the binary, they are just written here for convenience.
87 services.erigon.settings = {
88 datadir = lib.mkDefault "/var/lib/erigon";
89 chain = lib.mkDefault "mainnet";
90 http = lib.mkDefault true;
91 "http.port" = lib.mkDefault 8545;
92 "http.api" = lib.mkDefault [
93 "eth"
94 "debug"
95 "net"
96 "trace"
97 "web3"
98 "erigon"
99 ];
100 ws = lib.mkDefault true;
101 port = lib.mkDefault 30303;
102 "authrpc.port" = lib.mkDefault 8551;
103 "torrent.port" = lib.mkDefault 42069;
104 "private.api.addr" = lib.mkDefault "localhost:9090";
105 "log.console.verbosity" = lib.mkDefault 3; # info
106 };
107
108 systemd.services.erigon = {
109 description = "Erigon ethereum implemenntation";
110 wantedBy = [ "multi-user.target" ];
111 after = [ "network.target" ];
112
113 serviceConfig = {
114 LoadCredential = "ERIGON_JWT:${cfg.secretJwtPath}";
115 ExecStart = "${cfg.package}/bin/erigon --config ${configFile} --authrpc.jwtsecret=%d/ERIGON_JWT ${lib.escapeShellArgs cfg.extraArgs}";
116 DynamicUser = true;
117 Restart = "on-failure";
118 StateDirectory = "erigon";
119 CapabilityBoundingSet = "";
120 NoNewPrivileges = true;
121 PrivateTmp = true;
122 ProtectHome = true;
123 ProtectClock = true;
124 ProtectProc = "noaccess";
125 ProcSubset = "pid";
126 ProtectKernelLogs = true;
127 ProtectKernelModules = true;
128 ProtectKernelTunables = true;
129 ProtectControlGroups = true;
130 ProtectHostname = true;
131 RestrictSUIDSGID = true;
132 RestrictRealtime = true;
133 RestrictNamespaces = true;
134 LockPersonality = true;
135 RemoveIPC = true;
136 SystemCallFilter = [
137 "@system-service"
138 "~@privileged"
139 ];
140 };
141 };
142 };
143}