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"; + }; }