diff --git a/Cargo.lock b/Cargo.lock index e777744c3c..796beca660 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2241,6 +2241,16 @@ dependencies = [ "darling_macro 0.14.4", ] +[[package]] +name = "darling" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +dependencies = [ + "darling_core 0.20.3", + "darling_macro 0.20.3", +] + [[package]] name = "darling_core" version = "0.13.4" @@ -2269,6 +2279,20 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "darling_core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.38", +] + [[package]] name = "darling_macro" version = "0.13.4" @@ -2291,6 +2315,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "darling_macro" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +dependencies = [ + "darling_core 0.20.3", + "quote", + "syn 2.0.38", +] + [[package]] name = "dashmap" version = "5.5.3" @@ -7543,6 +7578,7 @@ dependencies = [ "nym-validator-client", "nyxd-scraper", "serde", + "serde_with", "sha2 0.10.8", "sqlx", "thiserror", @@ -9879,6 +9915,35 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_with" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" +dependencies = [ + "base64 0.21.4", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.0.2", + "serde", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" +dependencies = [ + "darling 0.20.3", + "proc-macro2", + "quote", + "syn 2.0.38", +] + [[package]] name = "serde_yaml" version = "0.9.25" diff --git a/nym-validator-rewarder/Cargo.toml b/nym-validator-rewarder/Cargo.toml index c197889d34..7b7396babd 100644 --- a/nym-validator-rewarder/Cargo.toml +++ b/nym-validator-rewarder/Cargo.toml @@ -25,6 +25,7 @@ time.workspace = true url.workspace = true zeroize.workspace = true +serde_with = "3.4.0" sha2 = "0.10.8" humantime = "2.1.0" humantime-serde = "1.0" diff --git a/nym-validator-rewarder/src/cli/mod.rs b/nym-validator-rewarder/src/cli/mod.rs index c78bfd5c59..0c6493f26f 100644 --- a/nym-validator-rewarder/src/cli/mod.rs +++ b/nym-validator-rewarder/src/cli/mod.rs @@ -66,7 +66,7 @@ pub struct ConfigOverridableArgs { pub credential_monitor_min_validation: Option, #[clap(long)] - pub credential_monitor_sampling_rate: Option, + pub credential_monitor_sampling_rate: Option, #[clap(long)] pub scraper_endpoint: Option, diff --git a/nym-validator-rewarder/src/config/mod.rs b/nym-validator-rewarder/src/config/mod.rs index d859f8401e..ed1efb97a6 100644 --- a/nym-validator-rewarder/src/config/mod.rs +++ b/nym-validator-rewarder/src/config/mod.rs @@ -11,6 +11,7 @@ use nym_config::{ }; use nym_validator_client::nyxd::Coin; use serde::{Deserialize, Serialize}; +use serde_with::{serde_as, DisplayFromStr}; use std::io; use std::path::{Path, PathBuf}; use std::time::Duration; @@ -31,7 +32,7 @@ const DEFAULT_MIX_REWARDING_DENOM: &str = "unym"; const DEFAULT_EPOCH_DURATION: Duration = Duration::from_secs(60 * 60); const DEFAULT_MONITOR_RUN_INTERVAL: Duration = Duration::from_secs(10 * 60); const DEFAULT_MONITOR_MIN_VALIDATE: u32 = 10; -const DEFAULT_MONITOR_SAMPLING_RATE: f32 = 0.10; +const DEFAULT_MONITOR_SAMPLING_RATE: f64 = 0.10; /// Get default path to rewarder's config directory. /// It should get resolved to `$HOME/.nym/validators-rewarder/config` @@ -65,12 +66,15 @@ pub struct Config { pub(crate) save_path: Option, #[zeroize(skip)] + #[serde(default)] pub rewarding: Rewarding, #[zeroize(skip)] + #[serde(default)] pub block_signing: BlockSigning, #[zeroize(skip)] + #[serde(default)] pub issuance_monitor: IssuanceMonitor, #[zeroize(skip)] @@ -169,7 +173,7 @@ impl Config { #[derive(Debug, Deserialize, Serialize, Zeroize, ZeroizeOnDrop)] pub struct Base { - /// Url to the upstream instance of nyxd to use for any queries. + /// Url to the upstream instance of nyxd to use for any queries and rewarding. #[zeroize(skip)] pub upstream_nyxd: Url, @@ -177,9 +181,11 @@ pub struct Base { pub(crate) mnemonic: bip39::Mnemonic, } +#[serde_as] #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Rewarding { /// Specifies total budget for the epoch + #[serde_as(as = "DisplayFromStr")] pub epoch_budget: Coin, #[serde(with = "humantime_serde")] @@ -267,7 +273,7 @@ pub struct IssuanceMonitor { pub min_validate_per_issuer: u32, /// The sampling rate of the issued credentials - pub sampling_rate: f32, + pub sampling_rate: f64, } impl Default for IssuanceMonitor { diff --git a/nym-validator-rewarder/src/config/template.rs b/nym-validator-rewarder/src/config/template.rs index 3bb141e2d8..dbe95a5075 100644 --- a/nym-validator-rewarder/src/config/template.rs +++ b/nym-validator-rewarder/src/config/template.rs @@ -9,6 +9,56 @@ pub(crate) const CONFIG_TEMPLATE: &str = r#" # This is a TOML config file. # For more information, see https://github.com/toml-lang/toml +# Url to the upstream instance of nyxd to use for any queries and rewarding. +upstream_nyxd = '{{ upstream_nyxd }}' +# Mnemonic to the nyx account distributing the rewards +mnemonic = '{{ mnemonic }}' +[storage_paths] + +nyxd_scraper = '{{ storage_paths.nyxd_scraper }}' +reward_history = '{{ storage_paths.reward_history }}' + +[rewarding] +# Specifies total budget for the epoch +epoch_budget = '{{ rewarding.epoch_budget }}' + +epoch_duration = '{{ rewarding.epoch_duration }}' + +[rewarding.ratios] +# The percent of the epoch reward being awarded for block signing. +block_signing = {{ rewarding.ratios.block_signing }} + +# The percent of the epoch reward being awarded for credential issuance. +credential_issuance = {{ rewarding.ratios.credential_issuance }} + +# The percent of the epoch reward being awarded for credential verification. +credential_verification = {{ rewarding.ratios.credential_verification }} + + +[block_signing] +# Specifies whether credential issuance for block signing is enabled. +enabled = {{ block_signing.enabled }} + + +[issuance_monitor] +# Specifies whether credential issuance monitoring (and associated rewards) are enabled. +enabled = {{ issuance_monitor.enabled }} + +run_interval = '{{ issuance_monitor.run_interval }}' + +# Defines the minimum number of credentials the monitor will validate +# regardless of the sampling rate +min_validate_per_issuer = {{ issuance_monitor.min_validate_per_issuer }} + +# The sampling rate of the issued credentials +sampling_rate = {{ issuance_monitor.sampling_rate }} + +[nyxd_scraper] +# Specifies whether the chain scraper is enabled. +enabled = {{ nyxd_scraper.enabled }} + +# Url to the websocket endpoint of a validator, for example `wss://rpc.nymtech.net/websocket` +websocket_url = '{{ nyxd_scraper.websocket_url }}' "#; diff --git a/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs b/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs index 743b8c2a7e..f02cc93e82 100644 --- a/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs +++ b/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs @@ -209,7 +209,7 @@ impl CredentialIssuanceMonitor { credential_range } else { let mut rng = thread_rng(); - let sample_size = (issued as f32 * self.config.sampling_rate) as usize; + let sample_size = (issued as f64 * self.config.sampling_rate) as usize; credential_range .choose_multiple(&mut rng, sample_size) .copied()