diff --git a/lib/default.nix b/lib/default.nix
index f2af0d93..27f53502 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -168,4 +168,29 @@ in {
gomod2nix --outdir "$CURDIR"
'';
};
+ # `hermesModuleConfigToml { modules }).config.hermes.toml`
+ # will be a string to put into [config.toml](https://hermes.informal.systems/documentation/configuration/configure-hermes.html)
+ hermesModuleConfigToml = {modules}:
+ pkgs.lib.evalModules {
+ modules =
+ [
+ (
+ {
+ lib,
+ config,
+ ...
+ }: let
+ # please note that this is not `nixos service`(systemd/launchd),
+ # but just the "abstract" module that can be used to build other configurations:
+ # static config files, containers, vm, process manager, futher generator.
+ cfg = config.hermes;
+ base = import ../nixosModules/hermes/base.nix {inherit lib nix-std cfg;};
+ in {
+ options.hermes = base.options;
+ config.hermes.toml = base.config.toml;
+ }
+ )
+ ]
+ ++ modules;
+ };
}
diff --git a/modules/nixosModules.nix b/modules/nixosModules.nix
new file mode 100644
index 00000000..7ae9b98d
--- /dev/null
+++ b/modules/nixosModules.nix
@@ -0,0 +1,11 @@
+{
+ inputs,
+ hermes,
+ ...
+}: let
+ std = inputs.nix-std;
+in {
+ flake.nixosModules = {
+ hermes = import ../../nixosModules/hermes/default.nix {inherit nix-std hermes;};
+ };
+}
diff --git a/modules/packages.nix b/modules/packages.nix
index 4080744f..79fd2557 100644
--- a/modules/packages.nix
+++ b/modules/packages.nix
@@ -220,6 +220,15 @@
inherit (inputs) apalache-src;
};
}
+ # fails with gaia nill pointer, so need to have config builder for cosmos-sdk too
+ # {
+ # hermes-test = import ../nixosTests/tests/hermes-test.nix {
+ # inherit pkgs;
+ # inherit (inputs) nix-std;
+ # inherit (self'.packages) hermes;
+ # gaia = self'.packages.gaia14;
+ # };
+ # }
{
stargaze = import ../packages/stargaze.nix {
inherit (inputs) stargaze-src;
diff --git a/nixosModules/hermes/base.nix b/nixosModules/hermes/base.nix
new file mode 100644
index 00000000..7fe39e0e
--- /dev/null
+++ b/nixosModules/hermes/base.nix
@@ -0,0 +1,18 @@
+{
+ lib,
+ nix-std,
+ cfg,
+}:
+with lib; {
+ options = {
+ config = import ./config-options.nix {inherit lib;};
+ toml = mkOption {type = types.unique {message = "only one toml output";} types.str;};
+ };
+ config = {
+ toml = let
+ # remove `null` from toml render
+ sanitizedCfg = filterAttrsRecursive (_: v: v != null) cfg.config;
+ in
+ nix-std.lib.serde.toTOML sanitizedCfg;
+ };
+}
diff --git a/nixosModules/hermes/chain-options.nix b/nixosModules/hermes/chain-options.nix
new file mode 100644
index 00000000..10938feb
--- /dev/null
+++ b/nixosModules/hermes/chain-options.nix
@@ -0,0 +1,256 @@
+# will be used to generate `[[chains]]` part of [config.toml](https://hermes.informal.systems/documentation/configuration/description.html)
+{lib}:
+with lib; {
+ # Required
+ id = mkOption {
+ type = types.str;
+ description = ''
+ Specify the chain ID.
+ '';
+ };
+ rpc_addr = mkOption {
+ type = types.str;
+ description = ''
+ Specify the RPC address and port where the chain RPC server listens on.
+ '';
+ };
+ grpc_addr = mkOption {
+ type = types.str;
+ description = ''
+ Specify the GRPC address and port where the chain GRPC server listens on.
+ '';
+ };
+
+ event_source = mkOption {
+ type = types.submodule {
+ options = {
+ mode = mkOption {
+ type = types.enum ["push" "pull"];
+ default = "push";
+ description = ''
+ Specify the mode of the event source.
+ '';
+ };
+ url = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ description = ''
+ Specify the WebSocket address and port where the chain WebSocket server listens on.
+ '';
+ };
+ batch_delay = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ description = ''
+ Specify the delay between batches of events.
+ '';
+ };
+ interval = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+
+ description = ''
+ Specify the interval between requests for new events.
+ '';
+ };
+ };
+ };
+ };
+
+ account_prefix = mkOption {
+ type = types.str;
+ description = ''
+ Specify the prefix used by the chain.
+ '';
+ };
+ key_name = mkOption {
+ type = types.str;
+ description = ''
+ Specify the name of the private key to use for signing transactions. Required
+
+ See the Adding Keys chapter
+ .
+ '';
+ };
+ key_store_type = mkOption {
+ type = types.enum ["Test" "Memory"];
+ default = "Test";
+ };
+ default_gas = mkOption {
+ type = types.ints.positive;
+ default = 100000000;
+ };
+ gas_price = mkOption {
+ type = types.submodule {
+ options = {
+ price = mkOption {
+ type = types.float;
+ description = ''
+ Specify the price per gas used of the fee to submit a transaction.
+ '';
+ };
+ denom = mkOption {
+ type = types.str;
+ description = ''
+ Specify the denomination of the fee to submit a transaction.
+ '';
+ };
+ };
+ };
+ };
+
+ address_type = mkOption {
+ type = types.submodule {
+ options = {
+ derivation = mkOption {
+ type = types.enum ["cosmos"];
+ default = "cosmos";
+ description = ''
+ Specify the derivation type of the address.
+ '';
+ };
+ };
+ };
+ };
+
+ packet_filter = mkOption {
+ default = {
+ policy = "allow";
+ list = [["*" "*"]];
+ };
+ type = types.submodule {
+ options = {
+ policy = mkOption {
+ type = types.enum ["allow" "deny"];
+ default = "allow";
+ description = ''
+ Specify the policy of the packet filter.
+ '';
+ };
+ list = mkOption {
+ type = types.listOf (types.listOf types.str);
+ default = [["*" "*"]];
+ description = ''
+ Specify the list of packet filters.
+ '';
+ };
+ };
+ };
+ };
+
+ # Optional
+ rpc_timeout = mkOption {
+ type = types.str;
+ default = "10s";
+ description = ''
+ Specify the maximum amount of time (duration) that the RPC requests should
+ take before timing out.
+ '';
+ };
+ store_prefix = mkOption {
+ type = types.str;
+ default = "ibc";
+ description = ''
+ Specify the store prefix used by the on-chain IBC modules.
+ '';
+ };
+ max_gas = mkOption {
+ type = types.ints.positive;
+ default = 3000000;
+ description = ''
+ Specify the maximum amount of gas to be used as the gas limit for a transaction.
+ '';
+ };
+ gas_multiplier = mkOption {
+ type = types.float;
+ default = 0.1;
+ description = ''
+ Specify by ratio to increase the gas estimate used to compute the fee,
+ to account for potential estimation error.
+ '';
+ };
+ max_msg_num = mkOption {
+ type = types.ints.positive;
+ default = 30;
+ description = ''
+ Specify how many IBC messages at most to include in a single transaction.
+ '';
+ };
+ max_tx_size = mkOption {
+ type = types.ints.positive;
+ default = 2097152;
+ description = ''
+ Specify the maximum size, in bytes, of each transaction that Hermes will submit.
+ '';
+ };
+ max_block_time = mkOption {
+ type = types.str;
+ default = "30s";
+ description = ''
+ Specify the maximum amount of time to wait for a new block to be committed.
+ '';
+ };
+ clock_drift = mkOption {
+ type = types.str;
+ default = "5s";
+ description = ''
+ Specify the maximum amount of time to tolerate a clock drift.
+ The clock drift parameter defines how much new (untrusted) header's time
+ can drift into the future.
+ '';
+ };
+ trusting_period = mkOption {
+ type = types.str;
+ default = "14days";
+ description = ''
+ Specify the amount of time to be used as the light client trusting period.
+ It should be significantly less than the unbonding period
+ (e.g. unbonding period = 3 weeks, trusting period = 2 weeks).
+ '';
+ };
+ trusted_node = mkOption {
+ type = types.bool;
+ default = false;
+ };
+ ccv_consumer_chain = mkOption {
+ type = types.bool;
+ default = false;
+ };
+
+ type = mkOption {
+ type = types.enum ["CosmosSdk"];
+ default = "CosmosSdk";
+ description = ''
+ Specify the type of the chain.
+ '';
+ };
+
+ trust_threshold = mkOption {
+ default = {
+ numerator = "1";
+ denominator = "3";
+ };
+ type = types.submodule {
+ options = {
+ numerator = mkOption {
+ type = types.str;
+ default = "1";
+ description = ''
+ Specify the trust threshold for the light client, ie. the maximum fraction of validators
+ which have changed between two blocks.
+ Warning: This is an advanced feature! Modify with caution.
+ '';
+ };
+ denominator = mkOption {
+ type = types.str;
+ default = "3";
+ description = ''
+ Specify the trust threshold for the light client, ie. the maximum fraction of validators
+ which have changed between two blocks.
+ Warning: This is an advanced feature! Modify with caution.
+ '';
+ };
+ };
+ };
+ };
+}
diff --git a/nixosModules/hermes/config-options.nix b/nixosModules/hermes/config-options.nix
new file mode 100644
index 00000000..4a2ee57b
--- /dev/null
+++ b/nixosModules/hermes/config-options.nix
@@ -0,0 +1,247 @@
+# will be used to render [config.toml](https://hermes.informal.systems/documentation/configuration/description.html)
+{lib}:
+with lib; {
+ global = mkOption {
+ type = types.submodule {
+ options = {
+ log_level = mkOption {
+ type = types.enum ["error" "warn" "info" "debug" "trace"];
+ default = "info";
+ description = ''
+ Specify the verbosity for the relayer logging output.
+ '';
+ };
+ };
+ };
+ };
+ mode = mkOption {
+ description = "Specify the mode to be used by the relayer";
+ default = {
+ clients = {
+ enabled = true;
+ refresh = true;
+ misbehaviour = true;
+ };
+ packets = {
+ enabled = true;
+ clear_interval = 100;
+ clear_on_start = false;
+ tx_confirmation = true;
+ };
+ connections.enabled = false;
+ channels.enabled = false;
+ };
+ type = types.submodule {
+ options = {
+ clients = mkOption {
+ description = "Specify the clients mode";
+ default = {
+ enabled = true;
+ refresh = true;
+ misbehaviour = true;
+ };
+ type = types.submodule {
+ options = {
+ enabled = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether or not to enable the client workers.
+ '';
+ };
+ refresh = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether or not to enable periodic refresh of clients. [Default: true]
+ Note: Even if this is disabled, clients will be refreshed automatically if
+ there is activity on a connection or channel they are involved with.
+ '';
+ };
+ misbehaviour = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether or not to enable misbehaviour detection for clients.
+ '';
+ };
+ };
+ };
+ };
+
+ packets = mkOption {
+ description = "Specify the packets mode";
+ default = {
+ enabled = true;
+ clear_interval = 100;
+ clear_on_start = false;
+ tx_confirmation = true;
+ };
+ type = types.submodule {
+ options = {
+ enabled = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether or not to enable the packet workers.
+ '';
+ };
+ clear_interval = mkOption {
+ type = types.ints.u32;
+ default = 100;
+ description = ''
+ Parametrize the periodic packet clearing feature.
+ Interval (in number of blocks) at which pending packets
+ should be eagerly cleared. A value of '0' will disable it.
+ '';
+ };
+ clear_on_start = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether or not to clear packets on start.
+ '';
+ };
+ tx_confirmation = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Toggle the transaction confirmation mechanism.
+ The tx confirmation mechanism periodically queries the `/tx_search` RPC
+ endpoint to check that previously-submitted transactions
+ (to any chain in this config file) have delivered successfully.
+ Experimental feature. Affects telemetry if set to false.
+ '';
+ };
+ };
+ };
+ };
+
+ connections = mkOption {
+ description = "Specify the connections mode";
+ default = {
+ enabled = false;
+ };
+ type = types.submodule {
+ options = {
+ enabled = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether or not to enable the connection workers for handshake completion.
+ '';
+ };
+ };
+ };
+ };
+
+ channels = mkOption {
+ description = "Specify the channels mode";
+ default = {
+ enabled = false;
+ };
+ type = types.submodule {
+ options = {
+ enabled = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether or not to enable the channel workers for handshake completion.
+ '';
+ };
+ };
+ };
+ };
+ };
+ };
+ };
+
+ # REST API submodule options
+ rest = mkOption {
+ description = ''
+ The REST section defines parameters for Hermes' built-in RESTful API.
+ Rest option docs.
+ '';
+ default = {
+ enabled = true;
+ host = "127.0.0.1";
+ port = 3000;
+ };
+ type = types.submodule {
+ options = {
+ enabled = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Where or not to enable the REST service.
+ '';
+ };
+ host = mkOption {
+ type = types.str;
+ default = "127.0.0.1";
+ description = ''
+ Specify the IPv4/6 host over which the built-in HTTP server will serve the RESTful.
+ '';
+ };
+ port = mkOption {
+ type = types.port;
+ default = 3000;
+ description = ''
+ Specify the port over which the built-in HTTP server will serve the restful API.
+ '';
+ };
+ };
+ };
+ };
+
+ # Telemetry API submodule options
+ telemetry = mkOption {
+ description = ''
+ The telemetry section defines parameters for Hermes' built-in telemetry capabilities.
+ Telemetry option docs.
+ '';
+ default = {
+ enabled = true;
+ host = "127.0.0.1";
+ port = 3001;
+ };
+ type = types.submodule {
+ options = {
+ enabled = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether or not to enable the telemetry service.
+ '';
+ };
+ host = mkOption {
+ type = types.str;
+ default = "127.0.0.1";
+ description = ''
+ Specify the IPv4/6 host over which the built-in HTTP server will serve metrics.
+ '';
+ };
+ port = mkOption {
+ type = types.port;
+ default = 3001;
+ description = ''
+ Specify the port over which the built-in HTTP server will serve the metrics gathered.
+ '';
+ };
+ };
+ };
+ };
+
+ # Chain submodule options
+ chains = mkOption {
+ description = ''
+ A chains section includes parameters related to a chain and the full node to which
+ the relayer can send transactions and queries.
+ '';
+ type = types.listOf (
+ types.submodule {
+ options = import ./chain-options.nix {inherit lib;};
+ }
+ );
+ };
+}
diff --git a/nixosModules/hermes/default.nix b/nixosModules/hermes/default.nix
new file mode 100644
index 00000000..ed47374e
--- /dev/null
+++ b/nixosModules/hermes/default.nix
@@ -0,0 +1,48 @@
+{
+ nix-std,
+ hermes,
+}: {
+ lib,
+ config,
+ pkgs,
+ ...
+}: let
+ defaultPackage =
+ if hermes != null
+ then hermes
+ else pkgs.hermes;
+ cfg = config.services.hermes;
+ base = import ./base.nix {inherit lib nix-std cfg;};
+ tomlFile = pkgs.writeTextFile {
+ name = "config.toml";
+ text = base.config.toml;
+ };
+in
+ with lib; {
+ options.services.hermes =
+ base.options
+ // {
+ enable = mkEnableOption "hermes";
+ package = mkOption {
+ type = types.package;
+ default = defaultPackage;
+ description = ''
+ The hermes (ibc-rs) software to run.
+ '';
+ };
+ };
+
+ config = mkIf cfg.enable {
+ services.hermes.toml = base.config.toml;
+ systemd.services.hermes = {
+ description = "Hermes Daemon";
+ wantedBy = ["multi-user.target"];
+ after = ["network.target"];
+ preStart = "echo \"hermes toml can be found here: ${tomlFile}\"";
+ serviceConfig = {
+ Type = "notify";
+ ExecStart = "${pkgs.lib.meta.getExe cfg.package} -c ${tomlFile} start";
+ };
+ };
+ };
+ }
diff --git a/nixosModules/relayer/hermes-toml.nix b/nixosModules/relayer/hermes-toml.nix
deleted file mode 100644
index b8d93a33..00000000
--- a/nixosModules/relayer/hermes-toml.nix
+++ /dev/null
@@ -1,84 +0,0 @@
-{
- pkgs,
- cfg,
-}:
-with cfg; let
- boolToString = bool:
- if bool
- then "true"
- else "false";
- rest = with cfg.rest;
- with builtins; ''
- [rest]
- enabled = ${boolToString enabled}
- host = '${host}'
- port = ${toString port}
- '';
-
- telemetry = with cfg.telemetry; ''
- [telemetry]
- enabled = ${boolToString enabled}
- host = '${host}'
- port = ${toString port}
- '';
-
- chain-fold-op = accumulator: chain:
- with chain;
- accumulator
- + ''
- [[chains]]
- id = '${id}'
- rpc_addr = '${rpc-address}'
- grpc_addr = '${grpc-address}'
- websocket_addr = '${websocket-address}'
- rpc_timeout = '${toString rpc-timeout}'
- account_prefix = '${account-prefix}'
- key_name = '${key-name}'
- store_prefix = '${store-prefix}'
- max_gas = ${toString max-gas}
- gas_price = { price = ${toString gas-price}, denom = '${toString gas-denomination}' }
- gas_adjustment = ${toString gas-adjustment}
- max_msg_num = ${toString max-message-number}
- max_tx_size = ${toString max-transaction-size}
- clock_drift = '${clock-drift}'
- trusting_period = '${trusting-period}'
- trust_threshold = { numerator = '${toString trust-threshold-numerator}', denominator = '${toString trust-threshold-denominator}' }
- '';
- chains = builtins.foldl' chain-fold-op "" cfg.chains;
- mode = with cfg.mode; ''
- [mode]
-
- [mode.clients]
- enabled = ${boolToString clients.enabled}
- refresh = ${boolToString clients.refresh}
- misbehaviour = ${boolToString clients.misbehaviour}
-
- [mode.connections]
- enabled = ${boolToString connections.enabled}
-
- [mode.channels]
- enabled = ${boolToString channels.enabled}
-
- [mode.packets]
- enabled = ${boolToString packets.enabled}
- clear_interval = ${toString packets.clear-interval}
- clear_on_start = ${boolToString packets.clear-on-start}
- tx_confirmation = ${boolToString packets.tx-confirmation}
- '';
-in
- pkgs.writeTextFile {
- name = "config.toml";
- text =
- ''
- [global]
- log_level = '${log-level}'
- ''
- + "\n"
- + mode
- + "\n"
- + rest
- + "\n"
- + telemetry
- + "\n"
- + chains;
- }
diff --git a/nixosModules/relayer/hermes.nix b/nixosModules/relayer/hermes.nix
deleted file mode 100644
index c89bb7bf..00000000
--- a/nixosModules/relayer/hermes.nix
+++ /dev/null
@@ -1,418 +0,0 @@
-{
- lib,
- config,
- pkgs,
- ...
-}: let
- cfg = config.services.hermes;
- hermes-toml = (import ./hermes-toml.nix) {inherit pkgs cfg;};
-in
- with lib; {
- options.services.hermes = {
- enable = mkEnableOption "hermes";
- package = mkOption {
- type = types.package;
- default = pkgs.hermes;
- description = ''
- The hermes (ibc-rs) software to run.
- '';
- };
- log-level = mkOption {
- type = types.enum ["error" "warn" "info" "debug" "trace"];
- default = "info";
- description = ''
- Specify the verbosity for the relayer logging output.
- '';
- };
-
- mode = mkOption {
- description = "Specify the mode to be used by the relayer";
- default = {
- clients = {
- enabled = true;
- refresh = true;
- misbehaviour = true;
- };
- packets = {
- enabled = true;
- clear-interval = 100;
- clear-on-start = false;
- tx-confirmation = true;
- };
- connections.enabled = false;
- channels.enabled = false;
- };
- type = types.submodule {
- options = {
- clients = mkOption {
- description = "Specify the clients mode";
- default = {
- enabled = true;
- refresh = true;
- misbehaviour = true;
- };
- type = types.submodule {
- options = {
- enabled = mkOption {
- type = types.bool;
- default = true;
- description = ''
- Whether or not to enable the client workers.
- '';
- };
- refresh = mkOption {
- type = types.bool;
- default = true;
- description = ''
- Whether or not to enable periodic refresh of clients. [Default: true]
- Note: Even if this is disabled, clients will be refreshed automatically if
- there is activity on a connection or channel they are involved with.
- '';
- };
- misbehaviour = mkOption {
- type = types.bool;
- default = true;
- description = ''
- Whether or not to enable misbehaviour detection for clients.
- '';
- };
- };
- };
- };
-
- packets = mkOption {
- description = "Specify the packets mode";
- default = {
- enabled = true;
- clear-interval = 100;
- clear-on-start = false;
- tx-confirmation = true;
- };
- type = types.submodule {
- options = {
- enabled = mkOption {
- type = types.bool;
- default = true;
- description = ''
- Whether or not to enable the packet workers.
- '';
- };
- clear-interval = mkOption {
- type = types.ints.u32;
- default = 100;
- description = ''
- Parametrize the periodic packet clearing feature.
- Interval (in number of blocks) at which pending packets
- should be eagerly cleared. A value of '0' will disable it.
- '';
- };
- clear-on-start = mkOption {
- type = types.bool;
- default = false;
- description = ''
- Whether or not to clear packets on start.
- '';
- };
- tx-confirmation = mkOption {
- type = types.bool;
- default = true;
- description = ''
- Toggle the transaction confirmation mechanism.
- The tx confirmation mechanism periodically queries the `/tx_search` RPC
- endpoint to check that previously-submitted transactions
- (to any chain in this config file) have delivered successfully.
- Experimental feature. Affects telemetry if set to false.
- '';
- };
- };
- };
- };
-
- connections = mkOption {
- description = "Specify the connections mode";
- default = {
- enabled = false;
- };
- type = types.submodule {
- options = {
- enabled = mkOption {
- type = types.bool;
- default = true;
- description = ''
- Whether or not to enable the connection workers for handshake completion.
- '';
- };
- };
- };
- };
-
- channels = mkOption {
- description = "Specify the channels mode";
- default = {
- enabled = false;
- };
- type = types.submodule {
- options = {
- enabled = mkOption {
- type = types.bool;
- default = true;
- description = ''
- Whether or not to enable the channel workers for handshake completion.
- '';
- };
- };
- };
- };
- };
- };
- };
- tx-confirmation = mkOption {
- type = types.bool;
- default = true;
- description = ''
- Toggle the transaction confirmation mechanism.
- The tx confirmation mechanism periodically queries the `/tx_search` RPC
- endpoint to check that previously-submitted transactions
- (to any chain in this config file) have delivered successfully.
- Experimental feature. Affects telemetry if set to false.
- '';
- };
-
- # REST API submodule options
- rest = mkOption {
- description = ''
- The REST section defines parameters for Hermes' built-in RESTful API.
- Rest option docs.
- '';
- default = {
- enabled = true;
- host = "127.0.0.1";
- port = 3000;
- };
- type = types.submodule {
- options = {
- enabled = mkOption {
- type = types.bool;
- default = true;
- description = ''
- Where or not to enable the REST service.
- '';
- };
- host = mkOption {
- type = types.str;
- default = "127.0.0.1";
- description = ''
- Specify the IPv4/6 host over which the built-in HTTP server will serve the RESTful.
- '';
- };
- port = mkOption {
- type = types.port;
- default = 3000;
- description = ''
- Specify the port over which the built-in HTTP server will serve the restful API.
- '';
- };
- };
- };
- };
-
- # Telemetry API submodule options
- telemetry = mkOption {
- description = ''
- The telemetry section defines parameters for Hermes' built-in telemetry capabilities.
- Telemetry option docs.
- '';
- default = {
- enabled = true;
- host = "127.0.0.1";
- port = 3001;
- };
- type = types.submodule {
- options = {
- enabled = mkOption {
- type = types.bool;
- default = true;
- description = ''
- Whether or not to enable the telemetry service.
- '';
- };
- host = mkOption {
- type = types.str;
- default = "127.0.0.1";
- description = ''
- Specify the IPv4/6 host over which the built-in HTTP server will serve metrics.
- '';
- };
- port = mkOption {
- type = types.port;
- default = 3001;
- description = ''
- Specify the port over which the built-in HTTP server will serve the metrics gathered.
- '';
- };
- };
- };
- };
-
- # Chain submodule options
- chains = mkOption {
- description = ''
- A chains section includes parameters related to a chain and the full node to which
- the relayer can send transactions and queries.
- '';
- type = types.listOf (
- types.submodule {
- options = {
- # Required
- id = mkOption {
- type = types.str;
- description = ''
- Specify the chain ID.
- '';
- };
- rpc-address = mkOption {
- type = types.str;
- description = ''
- Specify the RPC address and port where the chain RPC server listens on.
- '';
- };
- grpc-address = mkOption {
- type = types.str;
- description = ''
- Specify the GRPC address and port where the chain GRPC server listens on.
- '';
- };
- websocket-address = mkOption {
- type = types.str;
- description = ''
- Specify the WebSocket address and port where the chain WebSocket server listens on.
- '';
- };
- account-prefix = mkOption {
- type = types.str;
- description = ''
- Specify the prefix used by the chain.
- '';
- };
- key-name = mkOption {
- type = types.str;
- description = ''
- Specify the name of the private key to use for signing transactions. Required
-
- See the Adding Keys chapter
- .
- '';
- };
- gas-price = mkOption {
- type = types.float;
- description = ''
- Specify the price per gas used of the fee to submit a transaction.
- '';
- };
- gas-denomination = mkOption {
- type = types.str;
- description = ''
- Specify the denomination of the fee to submit a transaction.
- '';
- };
-
- # Optional
- rpc-timeout = mkOption {
- type = types.str;
- default = "10s";
- description = ''
- Specify the maximum amount of time (duration) that the RPC requests should
- take before timing out.
- '';
- };
- store-prefix = mkOption {
- type = types.str;
- default = "ibc";
- description = ''
- Specify the store prefix used by the on-chain IBC modules.
- '';
- };
- max-gas = mkOption {
- type = types.ints.positive;
- default = 3000000;
- description = ''
- Specify the maximum amount of gas to be used as the gas limit for a transaction.
- '';
- };
- gas-adjustment = mkOption {
- type = types.float;
- default = 0.1;
- description = ''
- Specify by ratio to increase the gas estimate used to compute the fee,
- to account for potential estimation error.
- '';
- };
- max-message-number = mkOption {
- type = types.ints.positive;
- default = 30;
- description = ''
- Specify how many IBC messages at most to include in a single transaction.
- '';
- };
- max-transaction-size = mkOption {
- type = types.ints.positive;
- default = 2097152;
- description = ''
- Specify the maximum size, in bytes, of each transaction that Hermes will submit.
- '';
- };
- clock-drift = mkOption {
- type = types.str;
- default = "5s";
- description = ''
- Specify the maximum amount of time to tolerate a clock drift.
- The clock drift parameter defines how much new (untrusted) header's time
- can drift into the future.
- '';
- };
- trusting-period = mkOption {
- type = types.str;
- default = "14days";
- description = ''
- Specify the amount of time to be used as the light client trusting period.
- It should be significantly less than the unbonding period
- (e.g. unbonding period = 3 weeks, trusting period = 2 weeks).
- '';
- };
- trust-threshold-numerator = mkOption {
- type = types.ints.positive;
- default = 1;
- description = ''
- Specify the trust threshold for the light client, ie. the maximum fraction of validators
- which have changed between two blocks.
- Warning: This is an advanced feature! Modify with caution.
- '';
- };
- trust-threshold-denominator = mkOption {
- type = types.ints.positive;
- default = 3;
- description = ''
- Specify the trust threshold for the light client, ie. the maximum fraction of validators
- which have changed between two blocks.
- Warning: This is an advanced feature! Modify with caution.
- '';
- };
- };
- }
- );
- };
- };
-
- config = mkIf cfg.enable {
- systemd.services.hermes = {
- description = "Hermes Daemon";
- wantedBy = ["multi-user.target"];
- after = ["network.target"];
- preStart = "echo \"hermes toml can be found here: ${hermes-toml}\"";
- serviceConfig = {
- Type = "notify";
- ExecStart = "${cfg.package}/bin/hermes -c ${hermes-toml} start";
- };
- };
- };
- }
diff --git a/nixosTests/tests/hermes-test.nix b/nixosTests/tests/hermes-test.nix
index 8bca31d8..2c73ca1e 100644
--- a/nixosTests/tests/hermes-test.nix
+++ b/nixosTests/tests/hermes-test.nix
@@ -1,7 +1,8 @@
{
pkgs,
- hermes,
+ nix-std,
gaia,
+ hermes,
}: let
jsonRpcCurlRequest = addr: port: ''${pkgs.curl}/bin/curl -X POST -H 'Content-Type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"health\",\"params\":[]}' http://${addr}:${builtins.toString port} 2>&1'';
sharedModule = {
@@ -16,7 +17,10 @@ in
name = "hermes-module-test";
nodes = {
validator1 = {
- imports = [sharedModule ../../nixosModules/chains/gaia.nix];
+ imports = [
+ sharedModule
+ ../../nixosModules/chains/gaia.nix
+ ];
networking = {
interfaces = {
eth1 = {
@@ -45,7 +49,10 @@ in
};
validator2 = {
- imports = [sharedModule ../chains/gaia.nix];
+ imports = [
+ sharedModule
+ ../../nixosModules/chains/gaia.nix
+ ];
networking = {
interfaces = {
eth1 = {
@@ -93,7 +100,10 @@ in
};
relayer = {
- imports = [sharedModule ../../nixosModules/relayer/hermes.nix];
+ imports = [
+ sharedModule
+ (import ../../nixosModules/hermes/default.nix {inherit nix-std hermes;})
+ ];
networking = {
interfaces.eth1 = {
@@ -117,36 +127,51 @@ in
services.hermes = {
enable = true;
package = hermes;
- rest = {
- port = defaultRestPort;
- host = "0.0.0.0";
- };
- telemetry = {
- port = defaultMetricsPort;
- host = "0.0.0.0";
+ config = {
+ global.log_level = "trace";
+ rest = {
+ port = defaultRestPort;
+ host = "0.0.0.0";
+ };
+ telemetry = {
+ port = defaultMetricsPort;
+ host = "0.0.0.0";
+ };
+ chains = [
+ {
+ id = "nixos";
+ rpc_addr = "http://validator1:26657";
+ grpc_addr = "http://validator1:9090";
+ account_prefix = "cosmos";
+ address_type = {derivation = "cosmos";};
+ key_name = "testkey";
+ gas_price = {
+ price = 0.001;
+ denom = "stake";
+ };
+ event_source = {
+ mode = "pull";
+ interval = "1s";
+ };
+ }
+ {
+ id = "nixos2";
+ rpc_addr = "http://validator2:26657";
+ grpc_addr = "http://validator2:9090";
+ account_prefix = "cosmos";
+ address_type = {derivation = "cosmos";};
+ key_name = "testkey";
+ gas_price = {
+ price = 0.001;
+ denom = "stake";
+ };
+ event_source = {
+ mode = "pull";
+ interval = "1s";
+ };
+ }
+ ];
};
- chains = [
- {
- id = "nixos";
- rpc-address = "http://validator1:26657";
- grpc-address = "http://validator1:9090";
- websocket-address = "ws://validator1:26657/websocket";
- account-prefix = "cosmos";
- key-name = "testkey";
- gas-price = 0.001;
- gas-denomination = "stake";
- }
- {
- id = "nixos2";
- rpc-address = "http://validator2:26657";
- grpc-address = "http://validator2:9090";
- websocket-address = "ws://validator2:26657/websocket";
- account-prefix = "cosmos";
- key-name = "testkey";
- gas-price = 0.001;
- gas-denomination = "stake";
- }
- ];
};
};
};
diff --git a/nixosTests/tests/validator1/config/app.toml b/nixosTests/tests/validator1/config/app.toml
index ad45a808..56e9b7b6 100644
--- a/nixosTests/tests/validator1/config/app.toml
+++ b/nixosTests/tests/validator1/config/app.toml
@@ -8,7 +8,7 @@
# The minimum gas prices a validator is willing to accept for processing a
# transaction. A transaction's fees must meet the minimum of any denomination
# specified in this config (e.g. 0.25token1;0.0001token2).
-minimum-gas-prices = ""
+minimum-gas-prices = "0.001stake"
# default: the last 100 states are kept in addition to every 500th state; pruning at 10 block intervals
# nothing: all historic states will be saved, nothing will be deleted (i.e. archiving node)
diff --git a/nixosTests/tests/validator2/config/app.toml b/nixosTests/tests/validator2/config/app.toml
index ad45a808..56e9b7b6 100644
--- a/nixosTests/tests/validator2/config/app.toml
+++ b/nixosTests/tests/validator2/config/app.toml
@@ -8,7 +8,7 @@
# The minimum gas prices a validator is willing to accept for processing a
# transaction. A transaction's fees must meet the minimum of any denomination
# specified in this config (e.g. 0.25token1;0.0001token2).
-minimum-gas-prices = ""
+minimum-gas-prices = "0.001stake"
# default: the last 100 states are kept in addition to every 500th state; pruning at 10 block intervals
# nothing: all historic states will be saved, nothing will be deleted (i.e. archiving node)
diff --git a/packages/hermes.nix b/packages/hermes.nix
index 485df873..abe4b2fc 100644
--- a/packages/hermes.nix
+++ b/packages/hermes.nix
@@ -15,4 +15,7 @@ pkgs.rustPlatform.buildRustPackage {
];
cargoSha256 = "sha256-oAsRn0THb5FU1HqgpB60jChGeQZdbrPoPfzTbyt3ozM=";
doCheck = false;
+ meta = {
+ mainProgram = "hermes";
+ };
}