From b4b32bb9073f67cb71ae12fc39a45acf2dacf8c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 4 Dec 2023 14:26:22 +0000 Subject: [PATCH 01/21] wip --- Cargo.lock | 22 ++- Cargo.toml | 2 + mixnode/Cargo.toml | 7 +- nym-validator-rewarder/Cargo.toml | 30 ++++ nym-validator-rewarder/src/cli/build_info.rs | 17 ++ nym-validator-rewarder/src/cli/init.rs | 47 +++++ nym-validator-rewarder/src/cli/mod.rs | 91 ++++++++++ nym-validator-rewarder/src/cli/run.rs | 19 ++ .../src/cli/upgrade_helpers/mod.rs | 10 ++ nym-validator-rewarder/src/config/mod.rs | 166 ++++++++++++++++++ nym-validator-rewarder/src/config/override.rs | 17 ++ .../src/config/persistence/mod.rs | 2 + nym-validator-rewarder/src/config/template.rs | 14 ++ nym-validator-rewarder/src/error.rs | 38 ++++ nym-validator-rewarder/src/main.rs | 26 +++ nym-validator-rewarder/src/rewarder/mod.rs | 98 +++++++++++ .../src/rewarder/tasks/mod.rs | 2 + 17 files changed, 603 insertions(+), 5 deletions(-) create mode 100644 nym-validator-rewarder/Cargo.toml create mode 100644 nym-validator-rewarder/src/cli/build_info.rs create mode 100644 nym-validator-rewarder/src/cli/init.rs create mode 100644 nym-validator-rewarder/src/cli/mod.rs create mode 100644 nym-validator-rewarder/src/cli/run.rs create mode 100644 nym-validator-rewarder/src/cli/upgrade_helpers/mod.rs create mode 100644 nym-validator-rewarder/src/config/mod.rs create mode 100644 nym-validator-rewarder/src/config/override.rs create mode 100644 nym-validator-rewarder/src/config/persistence/mod.rs create mode 100644 nym-validator-rewarder/src/config/template.rs create mode 100644 nym-validator-rewarder/src/error.rs create mode 100644 nym-validator-rewarder/src/main.rs create mode 100644 nym-validator-rewarder/src/rewarder/mod.rs create mode 100644 nym-validator-rewarder/src/rewarder/tasks/mod.rs diff --git a/Cargo.lock b/Cargo.lock index ae25a8c0b0..e46ab8de56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6687,7 +6687,6 @@ dependencies = [ "nym-types", "nym-validator-client", "opentelemetry", - "pretty_env_logger", "rand 0.7.3", "serde", "serde_json", @@ -7492,6 +7491,27 @@ dependencies = [ "zeroize", ] +[[package]] +name = "nym-validator-rewarder" +version = "0.1.0" +dependencies = [ + "anyhow", + "bip39", + "clap 4.4.7", + "nym-bin-common", + "nym-config", + "nym-network-defaults", + "nym-task", + "nym-validator-client", + "serde", + "tendermint-rpc", + "thiserror", + "tokio", + "tracing", + "url", + "zeroize", +] + [[package]] name = "nym-vesting-contract-common" version = "0.7.0" diff --git a/Cargo.toml b/Cargo.toml index bbd1f04c64..d12f2cd6d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -102,6 +102,7 @@ members = [ "nym-node", "nym-node/nym-node-requests", "nym-outfox", + "nym-validator-rewarder", "tools/internal/ssl-inject", "tools/internal/sdk-version-bump", "tools/nym-cli", @@ -124,6 +125,7 @@ default-members = [ "nym-api", "tools/nymvisor", "explorer-api", + "nym-validator-rewarder", ] exclude = ["explorer", "contracts", "nym-wallet", "nym-connect/mobile/src-tauri", "nym-connect/desktop", "nym-vpn/ui/src-tauri", "cpu-cycles"] diff --git a/mixnode/Cargo.toml b/mixnode/Cargo.toml index 25a6a8d5a7..9ad7c5081f 100644 --- a/mixnode/Cargo.toml +++ b/mixnode/Cargo.toml @@ -18,7 +18,7 @@ rust-version = "1.58.1" [dependencies] axum = { workspace = true } -anyhow = "1.0.40" +anyhow = { workspace = true } bs58 = "0.4.0" clap = { workspace = true, features = ["cargo", "derive"] } colored = "2.0" @@ -28,7 +28,6 @@ futures = { workspace = true } humantime-serde = "1.0" lazy_static = "1.4.0" log = { workspace = true } -pretty_env_logger = "0.4.0" rand = "0.7.3" serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } @@ -41,7 +40,7 @@ cfg-if = "1.0.0" thiserror = { workspace = true } ## tracing -tracing = { version = "0.1.37", optional = true } +tracing = { workspace = true, optional = true } opentelemetry = { version = "0.19.0", optional = true } @@ -65,7 +64,7 @@ nym-bin-common = { path = "../common/bin-common", features = ["output_format"] } cpu-cycles = { path = "../cpu-cycles", optional = true } [dev-dependencies] -tokio = { version = "1.21.2", features = [ +tokio = { workspace = true, features = [ "rt-multi-thread", "net", "signal", diff --git a/nym-validator-rewarder/Cargo.toml b/nym-validator-rewarder/Cargo.toml new file mode 100644 index 0000000000..b380e053ba --- /dev/null +++ b/nym-validator-rewarder/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "nym-validator-rewarder" +version = "0.1.0" +authors.workspace = true +repository.workspace = true +homepage.workspace = true +documentation.workspace = true +edition.workspace = true +license = "GPL-3" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow.workspace = true +bip39 = { workspace = true, features = ["zeroize"] } +clap = { workspace = true, features = ["cargo"] } +serde = { workspace = true, features = ["derive"] } +thiserror.workspace = true +tokio = { workspace = true, features = ["rt-multi-thread", "time", "macros"] } +tracing.workspace = true +url.workspace = true +zeroize.workspace = true +tendermint-rpc = { workspace = true, features = ["websocket-client"] } + +# internal +nym-bin-common = { path = "../common/bin-common", features = ["output_format"] } +nym-config = { path = "../common/config" } +nym-network-defaults = { path = "../common/network-defaults" } +nym-task = { path = "../common/task" } +nym-validator-client = { path = "../common/client-libs/validator-client" } diff --git a/nym-validator-rewarder/src/cli/build_info.rs b/nym-validator-rewarder/src/cli/build_info.rs new file mode 100644 index 0000000000..b5328f039c --- /dev/null +++ b/nym-validator-rewarder/src/cli/build_info.rs @@ -0,0 +1,17 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::error::NymRewarderError; +use nym_bin_common::bin_info_owned; +use nym_bin_common::output_format::OutputFormat; + +#[derive(clap::Args, Debug)] +pub(crate) struct Args { + #[clap(short, long, default_value_t = OutputFormat::default())] + output: OutputFormat, +} + +pub(crate) fn execute(args: Args) -> Result<(), NymRewarderError> { + println!("{}", args.output.format(&bin_info_owned!())); + Ok(()) +} diff --git a/nym-validator-rewarder/src/cli/init.rs b/nym-validator-rewarder/src/cli/init.rs new file mode 100644 index 0000000000..c55b6a6806 --- /dev/null +++ b/nym-validator-rewarder/src/cli/init.rs @@ -0,0 +1,47 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::config::Config; +use crate::error::NymRewarderError; +use std::path::PathBuf; + +#[derive(Debug, clap::Args)] +pub struct Args { + #[command(flatten)] + config_override: ConfigOverridableArgs, + + /// Specifies custom location for the configuration file of nym validators rewarder. + #[clap(long)] + custom_config_path: Option, + + /// Mnemonic used for rewarding operations + #[clap(long)] + mnemonic: bip39::Mnemonic, + + /// Overwrite existing configuration file. + #[clap(long, short)] + force: bool, +} + +#[derive(Debug, clap::Args)] +pub struct ConfigOverridableArgs { + // +} + +pub(crate) fn execute(args: Args) -> Result<(), NymRewarderError> { + let path = args + .custom_config_path + .clone() + .unwrap_or(Config::default_location()); + + if path.exists() && !args.force { + return Err(NymRewarderError::ExistingConfig { path }); + } + + Config::new(args.mnemonic) + .with_override(args.config_override) + .save_to_path(&path) + .map_err(|source| NymRewarderError::ConfigSaveFailure { path, source })?; + + Ok(()) +} diff --git a/nym-validator-rewarder/src/cli/mod.rs b/nym-validator-rewarder/src/cli/mod.rs new file mode 100644 index 0000000000..ba64c80e7f --- /dev/null +++ b/nym-validator-rewarder/src/cli/mod.rs @@ -0,0 +1,91 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::config::Config; +use crate::error::NymRewarderError; +use clap::{Parser, Subcommand}; +use nym_bin_common::bin_info; +use std::path::PathBuf; +use std::sync::OnceLock; +use tracing::{debug, error}; + +pub mod build_info; +pub mod init; +pub mod run; +pub mod upgrade_helpers; + +// Helper for passing LONG_VERSION to clap +fn pretty_build_info_static() -> &'static str { + static PRETTY_BUILD_INFORMATION: OnceLock = OnceLock::new(); + PRETTY_BUILD_INFORMATION.get_or_init(|| bin_info!().pretty_print()) +} + +#[derive(Parser, Debug)] +#[clap(author = "Nymtech", version, long_version = pretty_build_info_static(), about)] +pub(crate) struct Cli { + /// Path pointing to an env file that configures the validator rewarder and overrides any preconfigured values. + #[clap(short, long)] + pub(crate) config_env_file: Option, + + /// Flag used for disabling the printed banner in tty. + #[clap(long)] + pub(crate) no_banner: bool, + + #[clap(subcommand)] + command: Commands, +} + +impl Cli { + pub(crate) async fn execute(self) -> Result<(), NymRewarderError> { + match self.command { + Commands::Init(args) => init::execute(args), + Commands::Run(args) => run::execute(args).await, + Commands::BuildInfo(args) => build_info::execute(args), + } + } +} + +#[derive(Subcommand, Debug)] +pub(crate) enum Commands { + /// Initialise a validator rewarder with persistent config.toml file. + Init(init::Args), + + /// Run the validator rewarder with the preconfigured settings. + Run(run::Args), + + /// Show build information of this binary + BuildInfo(build_info::Args), +} + +fn try_load_current_config(custom_path: &Option) -> Result { + let config_path = custom_path.clone().unwrap_or(Config::default_location()); + + debug!( + "attempting to load configuration file from {}", + config_path.display() + ); + + if let Ok(cfg) = Config::read_from_toml_file(&config_path) { + return Ok(cfg); + } + + upgrade_helpers::try_upgrade_config(&config_path)?; + + Config::read_from_toml_file(&config_path).map_err(|err| { + error!( + "Failed to load config. Are you sure you have run `init` before? (Error was: {err})", + ); + err + }) +} + +#[cfg(test)] +mod tests { + use super::*; + use clap::CommandFactory; + + #[test] + fn verify_cli() { + Cli::command().debug_assert(); + } +} diff --git a/nym-validator-rewarder/src/cli/run.rs b/nym-validator-rewarder/src/cli/run.rs new file mode 100644 index 0000000000..717edff440 --- /dev/null +++ b/nym-validator-rewarder/src/cli/run.rs @@ -0,0 +1,19 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::cli::try_load_current_config; +use crate::error::NymRewarderError; +use crate::rewarder::Rewarder; +use std::path::PathBuf; + +#[derive(Debug, clap::Args)] +pub struct Args { + /// Specifies custom location for the configuration file of nym validators rewarder. + custom_config_path: Option, +} + +pub(crate) async fn execute(args: Args) -> Result<(), NymRewarderError> { + let config = try_load_current_config(&args.custom_config_path)?.with_override(args); + + Rewarder::new(config).run().await +} diff --git a/nym-validator-rewarder/src/cli/upgrade_helpers/mod.rs b/nym-validator-rewarder/src/cli/upgrade_helpers/mod.rs new file mode 100644 index 0000000000..d1592df69a --- /dev/null +++ b/nym-validator-rewarder/src/cli/upgrade_helpers/mod.rs @@ -0,0 +1,10 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::error::NymRewarderError; +use std::path::Path; + +pub(crate) fn try_upgrade_config>(config_path: P) -> Result<(), NymRewarderError> { + let _ = config_path; + Ok(()) +} diff --git a/nym-validator-rewarder/src/config/mod.rs b/nym-validator-rewarder/src/config/mod.rs new file mode 100644 index 0000000000..dd79dce7a8 --- /dev/null +++ b/nym-validator-rewarder/src/config/mod.rs @@ -0,0 +1,166 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::config::r#override::ConfigOverride; +use crate::config::template::CONFIG_TEMPLATE; +use crate::error::NymRewarderError; +use nym_config::{ + must_get_home, read_config_from_toml_file, save_formatted_config_to_file, NymConfigTemplate, + DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME, DEFAULT_DATA_DIR, NYM_DIR, +}; +use nym_network_defaults::NymNetworkDetails; +use serde::{Deserialize, Serialize}; +use std::io; +use std::path::{Path, PathBuf}; +use tracing::{debug, warn}; +use url::Url; +use zeroize::{Zeroize, ZeroizeOnDrop}; + +pub mod r#override; +pub mod persistence; +mod template; + +const DEFAULT_REWARDER_DIR: &str = "validators-rewarder"; + +/// Get default path to rewarder's config directory. +/// It should get resolved to `$HOME/.nym/validators-rewarder/config` +pub fn default_config_directory() -> PathBuf { + must_get_home() + .join(NYM_DIR) + .join(DEFAULT_REWARDER_DIR) + .join(DEFAULT_CONFIG_DIR) +} + +/// Get default path to rewarder's config file. +/// It should get resolved to `$HOME/.nym/validators-rewarder/config/config.toml` +pub fn default_config_filepath() -> PathBuf { + default_config_directory().join(DEFAULT_CONFIG_FILENAME) +} + +/// Get default path to rewarder's data directory where files, such as keys, are stored. +/// It should get resolved to `$HOME/.nym/validators-rewarder/data` +pub fn default_data_directory() -> PathBuf { + must_get_home() + .join(NYM_DIR) + .join(DEFAULT_REWARDER_DIR) + .join(DEFAULT_DATA_DIR) +} + +#[derive(Debug, Deserialize, Serialize, Zeroize, ZeroizeOnDrop)] +pub struct Config { + // additional metadata holding on-disk location of this config file + #[serde(skip)] + #[zeroize(skip)] + pub(crate) save_path: Option, + + pub distribution: RewardingRatios, + + #[serde(flatten)] + pub base: Base, +} + +impl NymConfigTemplate for Config { + fn template(&self) -> &'static str { + CONFIG_TEMPLATE + } +} + +impl Config { + pub fn new(mnemonic: bip39::Mnemonic) -> Self { + let network = NymNetworkDetails::new_from_env(); + + Config { + save_path: None, + distribution: RewardingRatios::default(), + base: Base { + upstream_nyxd: network.endpoints[0].nyxd_url(), + mnemonic, + }, + } + } + + pub fn ensure_is_valid(&self) -> Result<(), NymRewarderError> { + self.distribution.ensure_is_valid()?; + Ok(()) + } + + pub fn r#override(&mut self, r#override: O) { + r#override.override_config(self) + } + + pub fn with_override(mut self, r#override: O) -> Self { + self.r#override(r#override); + self + } + + // simple wrapper that reads config file and assigns path location + fn read_from_path>(path: P) -> Result { + let path = path.as_ref(); + let mut loaded: Config = read_config_from_toml_file(path).map_err(|source| { + NymRewarderError::ConfigLoadFailure { + path: path.to_path_buf(), + source, + } + })?; + loaded.ensure_is_valid()?; + loaded.save_path = Some(path.to_path_buf()); + debug!("loaded config file from {}", path.display()); + Ok(loaded) + } + + pub fn read_from_toml_file>(path: P) -> Result { + Self::read_from_path(path) + } + + pub fn default_location() -> PathBuf { + default_config_filepath() + } + + pub fn save_to_default_location(&self) -> io::Result<()> { + let config_save_location: PathBuf = Self::default_location(); + save_formatted_config_to_file(self, config_save_location) + } + + pub fn save_to_path>(&self, path: P) -> io::Result<()> { + save_formatted_config_to_file(self, path) + } +} + +#[derive(Debug, Deserialize, Serialize, Zeroize, ZeroizeOnDrop)] +pub struct Base { + /// Url to the upstream instance of nyxd to use for any queries. + #[zeroize(skip)] + pub upstream_nyxd: Url, + + /// Mnemonic to the nyx account distributing the rewards + pub(crate) mnemonic: bip39::Mnemonic, +} + +#[derive(Debug, Deserialize, Serialize, Zeroize, ZeroizeOnDrop)] +pub struct RewardingRatios { + /// The percent of the epoch reward being awarded for block signing. + pub block_signing: f32, + + /// The percent of the epoch reward being awarded for credential issuance. + pub credential_issuance: f32, + + /// The percent of the epoch reward given to Nym. + pub nym: f32, +} + +impl Default for RewardingRatios { + fn default() -> Self { + RewardingRatios { + // TODO: define proper defaults + block_signing: 67.0, + credential_issuance: 33.0, + nym: 0.0, + } + } +} + +impl RewardingRatios { + pub fn ensure_is_valid(&self) -> Result<(), NymRewarderError> { + Ok(()) + } +} diff --git a/nym-validator-rewarder/src/config/override.rs b/nym-validator-rewarder/src/config/override.rs new file mode 100644 index 0000000000..4c1089b3c3 --- /dev/null +++ b/nym-validator-rewarder/src/config/override.rs @@ -0,0 +1,17 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::cli::{init, run}; +use crate::config::Config; + +pub trait ConfigOverride { + fn override_config(self, config: &mut Config); +} + +impl ConfigOverride for init::ConfigOverridableArgs { + fn override_config(self, config: &mut Config) {} +} + +impl ConfigOverride for run::Args { + fn override_config(self, config: &mut Config) {} +} diff --git a/nym-validator-rewarder/src/config/persistence/mod.rs b/nym-validator-rewarder/src/config/persistence/mod.rs new file mode 100644 index 0000000000..af282c5deb --- /dev/null +++ b/nym-validator-rewarder/src/config/persistence/mod.rs @@ -0,0 +1,2 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only diff --git a/nym-validator-rewarder/src/config/template.rs b/nym-validator-rewarder/src/config/template.rs new file mode 100644 index 0000000000..3bb141e2d8 --- /dev/null +++ b/nym-validator-rewarder/src/config/template.rs @@ -0,0 +1,14 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +// While using normal toml marshalling would have been way simpler with less overhead, +// I think it's useful to have comments attached to the saved config file to explain behaviour of +// particular fields. +// Note: any changes to the template must be reflected in the appropriate structs. +pub(crate) const CONFIG_TEMPLATE: &str = r#" +# This is a TOML config file. +# For more information, see https://github.com/toml-lang/toml + + + +"#; diff --git a/nym-validator-rewarder/src/error.rs b/nym-validator-rewarder/src/error.rs new file mode 100644 index 0000000000..0e68ca6852 --- /dev/null +++ b/nym-validator-rewarder/src/error.rs @@ -0,0 +1,38 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use nym_validator_client::nyxd::error::NyxdError; +use std::io; +use std::path::PathBuf; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum NymRewarderError { + #[error( + "failed to load config file using path '{}'. detailed message: {source}", path.display() + )] + ConfigLoadFailure { + path: PathBuf, + #[source] + source: io::Error, + }, + + #[error( + "failed to save config file using path '{}'. detailed message: {source}", path.display() + )] + ConfigSaveFailure { + path: PathBuf, + #[source] + source: io::Error, + }, + + #[error("there already exists a config file at: {}. if you want to overwrite its content, use --force flag", path.display())] + ExistingConfig { path: PathBuf }, + + // TODO: I think this one should get split into more, explicit, variants + #[error(transparent)] + NyxdFailure(#[from] NyxdError), + + #[error("the provided rewarding ratios don't add up to 1. ratios: {ratios:?}")] + InvalidRewardingRatios { ratios: Vec }, +} diff --git a/nym-validator-rewarder/src/main.rs b/nym-validator-rewarder/src/main.rs new file mode 100644 index 0000000000..5baeace799 --- /dev/null +++ b/nym-validator-rewarder/src/main.rs @@ -0,0 +1,26 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::cli::Cli; +use clap::{crate_name, crate_version, Parser}; +use nym_bin_common::logging::maybe_print_banner; +use nym_network_defaults::setup_env; + +pub mod cli; +pub mod config; +pub mod error; +mod rewarder; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let args = Cli::parse(); + setup_env(args.config_env_file.as_ref()); + + if !args.no_banner { + maybe_print_banner(crate_name!(), crate_version!()); + } + + args.execute().await?; + + Ok(()) +} diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs new file mode 100644 index 0000000000..0c54f8a835 --- /dev/null +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -0,0 +1,98 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::config::Config; +use crate::error::NymRewarderError; +use nym_network_defaults::NymNetworkDetails; +use nym_task::TaskManager; +use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient}; +use tendermint_rpc::WebSocketClient; +use tracing::info; + +mod tasks; + +pub struct Rewarder { + config: Config, +} + +impl Rewarder { + pub fn new(config: Config) -> Self { + Rewarder { config } + } + + pub async fn run(mut self) -> Result<(), NymRewarderError> { + info!("Starting nym validators rewarder"); + + // setup shutdowns + let task_manager = TaskManager::new(5); + + // + // + + // let client_config = + // nyxd::Config::try_from_nym_network_details(&NymNetworkDetails::new_from_env())?; + // + // let client = DirectSigningHttpRpcNyxdClient::connect_with_mnemonic( + // client_config, + // self.config.base.upstream_nyxd.as_str(), + // // note: the clone here is fine as the mnemonic itself implements ZeroizeOnDrop + // self.config.base.mnemonic.clone(), + // )?; + + let (client, driver) = WebSocketClient::new("https://rpc.nymtech.net/") + .await + .unwrap(); + /* + /// #[tokio::main] + /// async fn main() { + /// let (client, driver) = WebSocketClient::new("ws://127.0.0.1:26657/websocket") + /// .await + /// .unwrap(); + /// let driver_handle = tokio::spawn(async move { driver.run().await }); + /// + /// // Standard client functionality + /// let tx = format!("some-key=some-value"); + /// client.broadcast_tx_async(Transaction::from(tx.into_bytes())).await.unwrap(); + /// + /// // Subscription functionality + /// let mut subs = client.subscribe(EventType::NewBlock.into()) + /// .await + /// .unwrap(); + /// + /// // Grab 5 NewBlock events + /// let mut ev_count = 5_i32; + /// + /// while let Some(res) = subs.next().await { + /// let ev = res.unwrap(); + /// println!("Got event: {:?}", ev); + /// ev_count -= 1; + /// if ev_count < 0 { + /// break; + /// } + /// } + /// + /// // Signal to the driver to terminate. + /// client.close().unwrap(); + /// // Await the driver's termination to ensure proper connection closure. + /// let _ = driver_handle.await.unwrap(); + /// } + /// ``` + */ + + /* + task 1: + on timer: + - go to DKG contract + - get all coconut signers + - for each of them get the info, verify, etc + + task 2: + on timer (or maybe per block?): + - query abci endpoint for VP + - also maybe missed blocks, etc + + */ + + todo!() + } +} diff --git a/nym-validator-rewarder/src/rewarder/tasks/mod.rs b/nym-validator-rewarder/src/rewarder/tasks/mod.rs new file mode 100644 index 0000000000..af282c5deb --- /dev/null +++ b/nym-validator-rewarder/src/rewarder/tasks/mod.rs @@ -0,0 +1,2 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only From 37dd20ded12c012a4acb59ed130f29e290b6598f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 6 Dec 2023 12:28:58 +0000 Subject: [PATCH 02/21] wip2 --- Cargo.lock | 48 +- Cargo.toml | 5 +- .../client_traits/query_client.rs | 8 +- .../src/nyxd/cosmwasm_client/mod.rs | 9 +- .../nyxd/cosmwasm_client/module_traits/mod.rs | 8 + .../module_traits/slashing/mod.rs | 4 + .../module_traits/slashing/query.rs | 3 + .../module_traits/staking/mod.rs | 4 + .../module_traits/staking/query.rs | 80 + .../validator-client/src/nyxd/mod.rs | 48 +- nym-connect/desktop/Cargo.lock | 6 +- nym-validator-rewarder/Cargo.toml | 1 + nym-validator-rewarder/foomp | 3936 +++++++++++++++++ nym-validator-rewarder/src/cli/run.rs | 6 +- nym-validator-rewarder/src/rewarder/mod.rs | 103 +- .../src/rewarder/tasks/block_watcher.rs | 5 + .../src/rewarder/tasks/mod.rs | 2 + 17 files changed, 4174 insertions(+), 102 deletions(-) create mode 100644 common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/mod.rs create mode 100644 common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/slashing/mod.rs create mode 100644 common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/slashing/query.rs create mode 100644 common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/mod.rs create mode 100644 common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/query.rs create mode 100644 nym-validator-rewarder/foomp create mode 100644 nym-validator-rewarder/src/rewarder/tasks/block_watcher.rs diff --git a/Cargo.lock b/Cargo.lock index e46ab8de56..ebacb1c6ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1649,6 +1649,16 @@ dependencies = [ "tendermint-proto", ] +[[package]] +name = "cosmos-sdk-proto" +version = "0.20.0" +source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features#67718aa27a96efb9881e927a8f998c94b885093c" +dependencies = [ + "prost 0.12.1", + "prost-types 0.12.1", + "tendermint-proto", +] + [[package]] name = "cosmrs" version = "0.15.0" @@ -1656,7 +1666,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47126f5364df9387b9d8559dcef62e99010e1d4098f39eb3f7ee4b5c254e40ea" dependencies = [ "bip32", - "cosmos-sdk-proto", + "cosmos-sdk-proto 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ecdsa 0.16.8", + "eyre", + "k256", + "rand_core 0.6.4", + "serde", + "serde_json", + "signature 2.1.0", + "subtle-encoding", + "tendermint", + "thiserror", +] + +[[package]] +name = "cosmrs" +version = "0.15.0" +source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features#67718aa27a96efb9881e927a8f998c94b885093c" +dependencies = [ + "bip32", + "cosmos-sdk-proto 0.20.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "ecdsa 0.16.8", "eyre", "k256", @@ -5956,7 +5985,7 @@ name = "nym-api-requests" version = "0.1.0" dependencies = [ "bs58 0.4.0", - "cosmrs", + "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", "getset", "nym-coconut-interface", @@ -6014,7 +6043,7 @@ name = "nym-bity-integration" version = "0.1.0" dependencies = [ "anyhow", - "cosmrs", + "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "eyre", "k256", "nym-cli-commands", @@ -6059,7 +6088,7 @@ dependencies = [ "cfg-if", "clap 4.4.7", "comfy-table", - "cosmrs", + "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", "cw-utils", "handlebars", @@ -6328,7 +6357,7 @@ name = "nym-credentials" version = "0.1.0" dependencies = [ "bls12_381", - "cosmrs", + "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "log", "nym-api-requests", "nym-coconut-interface", @@ -7415,7 +7444,7 @@ name = "nym-types" version = "1.0.0" dependencies = [ "base64 0.21.4", - "cosmrs", + "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", "eyre", "hmac 0.12.1", @@ -7449,7 +7478,7 @@ dependencies = [ "bip32", "bip39", "colored", - "cosmrs", + "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", "cw-controllers", "cw-utils", @@ -7498,6 +7527,7 @@ dependencies = [ "anyhow", "bip39", "clap 4.4.7", + "futures", "nym-bin-common", "nym-config", "nym-network-defaults", @@ -7530,7 +7560,7 @@ dependencies = [ name = "nym-wallet-types" version = "1.0.0" dependencies = [ - "cosmrs", + "cosmrs 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "cosmwasm-std", "hex-literal", "nym-config", @@ -7614,7 +7644,7 @@ version = "0.1.0" dependencies = [ "async-trait", "const_format", - "cosmrs", + "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "eyre", "futures", "nym-bin-common", diff --git a/Cargo.toml b/Cargo.toml index d12f2cd6d2..b64e797cb5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -203,7 +203,10 @@ cw-controllers = { version = "=1.1.0" } # cosmrs-related bip32 = "0.5.1" -cosmrs = "=0.15.0" + +# temporarily using a fork again (yay.) because we need staking and slashing support +cosmrs = { git = "https://github.com/jstuczyn/cosmos-rust", branch ="nym-temp/all-validator-features" } +#cosmrs = "=0.15.0" tendermint = "0.34" # same version as used by cosmrs tendermint-rpc = "0.34" # same version as used by cosmrs prost = "0.12" diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/query_client.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/query_client.rs index a6ed3afddc..7d389adafb 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/query_client.rs @@ -52,10 +52,6 @@ use wasmtimer::tokio::sleep; pub const DEFAULT_BROADCAST_POLLING_RATE: Duration = Duration::from_secs(4); pub const DEFAULT_BROADCAST_TIMEOUT: Duration = Duration::from_secs(60); -#[cfg(feature = "http-client")] -#[async_trait] -impl CosmWasmClient for cosmrs::rpc::HttpClient {} - #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait CosmWasmClient: TendermintRpcClient { @@ -522,3 +518,7 @@ pub trait CosmWasmClient: TendermintRpcClient { res.try_into() } } + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +impl CosmWasmClient for T where T: TendermintRpcClient {} diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/mod.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/mod.rs index ab78a8c418..59086eee99 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/mod.rs @@ -26,6 +26,7 @@ use cosmrs::rpc::{HttpClient, HttpClientUrl}; pub mod client_traits; mod helpers; pub mod logs; +pub mod module_traits; pub mod types; #[derive(Debug)] @@ -329,14 +330,6 @@ where } } -#[async_trait] -impl CosmWasmClient for MaybeSigningClient -where - C: TendermintRpcClient + Send + Sync, - S: Send + Sync, -{ -} - #[async_trait] impl SigningCosmWasmClient for MaybeSigningClient where diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/mod.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/mod.rs new file mode 100644 index 0000000000..74df86a720 --- /dev/null +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/mod.rs @@ -0,0 +1,8 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +pub mod staking; +pub mod slashing; + +pub use staking::query::StakingQueryClient; +// pub use slashing::query \ No newline at end of file diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/slashing/mod.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/slashing/mod.rs new file mode 100644 index 0000000000..f4a7b38548 --- /dev/null +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/slashing/mod.rs @@ -0,0 +1,4 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +pub mod query; \ No newline at end of file diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/slashing/query.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/slashing/query.rs new file mode 100644 index 0000000000..67bf4e9a2d --- /dev/null +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/slashing/query.rs @@ -0,0 +1,3 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/mod.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/mod.rs new file mode 100644 index 0000000000..f4a7b38548 --- /dev/null +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/mod.rs @@ -0,0 +1,4 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +pub mod query; \ No newline at end of file diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/query.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/query.rs new file mode 100644 index 0000000000..9cc5b2e8d4 --- /dev/null +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/query.rs @@ -0,0 +1,80 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::nyxd::error::NyxdError; +use crate::nyxd::{CosmWasmClient, PageRequest}; +use async_trait::async_trait; +use cosmrs::proto::cosmos::staking::v1beta1::{ + QueryHistoricalInfoRequest as ProtoQueryHistoricalInfoRequest, + QueryHistoricalInfoResponse as ProtoQueryHistoricalInfoResponse, + QueryValidatorRequest as ProtoQueryValidatorRequest, + QueryValidatorResponse as ProtoQueryValidatorResponse, + QueryValidatorsRequest as ProtoQueryValidatorsRequest, + QueryValidatorsResponse as ProtoQueryValidatorsResponse, +}; +use cosmrs::staking::{ + QueryHistoricalInfoRequest, QueryHistoricalInfoResponse, QueryValidatorRequest, + QueryValidatorResponse, QueryValidatorsRequest, QueryValidatorsResponse, +}; +use cosmrs::AccountId; + +// TODO: change trait restriction from `CosmWasmClient` to `TendermintRpcClient` +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +pub trait StakingQueryClient: CosmWasmClient { + async fn historical_info(&self, height: i64) -> Result { + let path = Some("/cosmos.staking.v1beta1.Query/HistoricalInfo".to_owned()); + + let req = QueryHistoricalInfoRequest { height }; + + let res = self + .make_abci_query::( + path, + req.into(), + ) + .await?; + + Ok(res.try_into()?) + } + + async fn validator( + &self, + validator_addr: AccountId, + ) -> Result { + let path = Some("/cosmos.staking.v1beta1.Query/Validator".to_owned()); + + let req = QueryValidatorRequest { validator_addr }; + + let res = self + .make_abci_query::( + path, + req.into(), + ) + .await?; + + Ok(res.try_into()?) + } + + async fn validators( + &self, + status: String, + pagination: Option, + ) -> Result { + let path = Some("/cosmos.staking.v1beta1.Query/Validators".to_owned()); + + let req = QueryValidatorsRequest { status, pagination }; + + let res = self + .make_abci_query::( + path, + req.into(), + ) + .await?; + + Ok(res.try_into()?) + } +} + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +impl StakingQueryClient for T where T: CosmWasmClient {} diff --git a/common/client-libs/validator-client/src/nyxd/mod.rs b/common/client-libs/validator-client/src/nyxd/mod.rs index 46f9b0622a..49b6e972a5 100644 --- a/common/client-libs/validator-client/src/nyxd/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/mod.rs @@ -29,24 +29,29 @@ use tendermint_rpc::endpoint::*; use tendermint_rpc::{Error as TendermintRpcError, Order}; use url::Url; -pub use crate::nyxd::cosmwasm_client::client_traits::{CosmWasmClient, SigningCosmWasmClient}; -pub use crate::nyxd::fee::Fee; +pub use crate::nyxd::{ + cosmwasm_client::{ + client_traits::{CosmWasmClient, SigningCosmWasmClient}, + module_traits::{self, StakingQueryClient}, + }, + fee::Fee, +}; pub use crate::rpc::TendermintRpcClient; pub use coin::Coin; -pub use cosmrs::bank::MsgSend; -pub use cosmrs::tendermint::abci::{ - response::DeliverTx, types::ExecTxResult, Event, EventAttribute, +pub use cosmrs::{ + bank::MsgSend, + bip32, + query::{PageRequest, PageResponse}, + tendermint::{ + abci::{response::DeliverTx, types::ExecTxResult, Event, EventAttribute}, + block::Height, + hash::{self, Algorithm, Hash}, + validator::Info as TendermintValidatorInfo, + Time as TendermintTime, + }, + tx::{self, Msg}, + AccountId, Coin as CosmosCoin, Denom, Gas, }; -pub use cosmrs::tendermint::block::Height; -pub use cosmrs::tendermint::hash::{self, Algorithm, Hash}; -pub use cosmrs::tendermint::validator::Info as TendermintValidatorInfo; -pub use cosmrs::tendermint::Time as TendermintTime; -pub use cosmrs::tx::Msg; -pub use cosmrs::tx::{self}; -pub use cosmrs::Any; -pub use cosmrs::Coin as CosmosCoin; -pub use cosmrs::Gas; -pub use cosmrs::{bip32, AccountId, Denom}; pub use cosmwasm_std::Coin as CosmWasmCoin; pub use cw2; pub use cw3; @@ -56,9 +61,8 @@ pub use fee::{gas_price::GasPrice, GasAdjustable, GasAdjustment}; pub use tendermint_rpc::{ endpoint::{tx::Response as TxResponse, validators::Response as ValidatorResponse}, query::Query, - Paging, + Paging, Request, Response, SimpleRequest, }; -pub use tendermint_rpc::{Request, Response, SimpleRequest}; #[cfg(feature = "http-client")] use crate::http_client; @@ -729,7 +733,7 @@ where where H: Into + Send, { - self.client.validators(height, paging).await + TendermintRpcClient::validators(&self.client, height, paging).await } async fn latest_consensus_params( @@ -804,14 +808,6 @@ where } } -#[async_trait] -impl CosmWasmClient for NyxdClient -where - C: TendermintRpcClient + Send + Sync, - S: Send + Sync, -{ -} - impl OfflineSigner for NyxdClient where S: OfflineSigner, diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index d92f3d4b49..240da01001 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -1014,8 +1014,7 @@ dependencies = [ [[package]] name = "cosmos-sdk-proto" version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32560304ab4c365791fd307282f76637213d8083c1a98490c35159cd67852237" +source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features#67718aa27a96efb9881e927a8f998c94b885093c" dependencies = [ "prost", "prost-types", @@ -1025,8 +1024,7 @@ dependencies = [ [[package]] name = "cosmrs" version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47126f5364df9387b9d8559dcef62e99010e1d4098f39eb3f7ee4b5c254e40ea" +source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features#67718aa27a96efb9881e927a8f998c94b885093c" dependencies = [ "bip32", "cosmos-sdk-proto", diff --git a/nym-validator-rewarder/Cargo.toml b/nym-validator-rewarder/Cargo.toml index b380e053ba..2ba72f9411 100644 --- a/nym-validator-rewarder/Cargo.toml +++ b/nym-validator-rewarder/Cargo.toml @@ -14,6 +14,7 @@ license = "GPL-3" anyhow.workspace = true bip39 = { workspace = true, features = ["zeroize"] } clap = { workspace = true, features = ["cargo"] } +futures.workspace = true serde = { workspace = true, features = ["derive"] } thiserror.workspace = true tokio = { workspace = true, features = ["rt-multi-thread", "time", "macros"] } diff --git a/nym-validator-rewarder/foomp b/nym-validator-rewarder/foomp new file mode 100644 index 0000000000..e75e1021d3 --- /dev/null +++ b/nym-validator-rewarder/foomp @@ -0,0 +1,3936 @@ +Got event: Event { + query: "tm.event = 'NewBlock'", + data: LegacyNewBlock { + block: Some( + Block { + header: Header { + version: Version { + block: 11, + app: 0, + }, + chain_id: chain::Id(nyx), + height: block::Height(10104845), + time: Time( + 2023-12-05 10:00:27.168834598, + ), + last_block_id: Some( + Id { + hash: Hash::Sha256(05010DE73764F8DF015B7577831F74A5E289E12E4BA1AB43D2FAF25B71294898), + part_set_header: Header { + total: 1, + hash: Hash::Sha256(25F703C33A060479E582C0894D1B914E3C71C82816A9B68D699CF3B9428FED95), + }, + }, + ), + last_commit_hash: Some( + Hash::Sha256(B549FE4D2FA7286A902EBF04A417509DFE46DA1834A2F90A2A7E76761B044372), + ), + data_hash: Some( + Hash::Sha256(E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855), + ), + validators_hash: Hash::Sha256(97B531291F24462988D2D1B84DF6E21AE95E48C7546AF074554B355FEC76150C), + next_validators_hash: Hash::Sha256(97B531291F24462988D2D1B84DF6E21AE95E48C7546AF074554B355FEC76150C), + consensus_hash: Hash::Sha256(048091BC7DDC283F77BFBF91D73C44DA58C3DF8A9CBC867405D8B7F3DAADA22F), + app_hash: AppHash(46879129F47F945950D0E2E3D3A72F063C4817E13F5EA284C24E80525D25E657), + last_results_hash: Some( + Hash::Sha256(E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855), + ), + evidence_hash: Some( + Hash::Sha256(E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855), + ), + proposer_address: account::Id(F35FDD3B4295AD80FB5D14012E649128C83BE7BC), + }, + data: [], + evidence: List( + [], + ), + last_commit: Some( + Commit { + height: block::Height(10104844), + round: block::Round(0), + block_id: Id { + hash: Hash::Sha256(05010DE73764F8DF015B7577831F74A5E289E12E4BA1AB43D2FAF25B71294898), + part_set_header: Header { + total: 1, + hash: Hash::Sha256(25F703C33A060479E582C0894D1B914E3C71C82816A9B68D699CF3B9428FED95), + }, + }, + signatures: [ + BlockIdFlagCommit { + validator_address: account::Id(9A5783B0CB39B4AE670E0F9215D3C720B56506D1), + timestamp: Time( + 2023-12-05 10:00:27.142741875, + ), + signature: Some( + Signature( + [ + 118, + 63, + 211, + 243, + 145, + 45, + 41, + 51, + 22, + 47, + 69, + 157, + 177, + 81, + 24, + 161, + 119, + 61, + 31, + 79, + 98, + 95, + 216, + 177, + 116, + 100, + 152, + 29, + 152, + 180, + 85, + 237, + 195, + 124, + 143, + 217, + 196, + 225, + 3, + 89, + 206, + 139, + 91, + 26, + 86, + 226, + 30, + 159, + 207, + 252, + 144, + 134, + 76, + 3, + 74, + 25, + 183, + 21, + 47, + 223, + 1, + 10, + 65, + 3, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(E2E65903BAB5344E5CFFDDC2CD638A6BAB2E2E79), + timestamp: Time( + 2023-12-05 10:00:27.141560477, + ), + signature: Some( + Signature( + [ + 89, + 195, + 129, + 61, + 39, + 145, + 26, + 214, + 139, + 109, + 107, + 246, + 106, + 154, + 23, + 178, + 219, + 131, + 237, + 35, + 28, + 75, + 151, + 72, + 163, + 226, + 4, + 65, + 130, + 65, + 176, + 14, + 37, + 32, + 186, + 245, + 182, + 47, + 183, + 110, + 44, + 207, + 34, + 10, + 151, + 152, + 226, + 128, + 45, + 144, + 247, + 184, + 25, + 13, + 92, + 89, + 253, + 67, + 38, + 134, + 98, + 176, + 129, + 7, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(47601B18F0F434375F7219AC5297E156459D2A8C), + timestamp: Time( + 2023-12-05 10:00:27.256161926, + ), + signature: Some( + Signature( + [ + 122, + 126, + 230, + 222, + 202, + 30, + 31, + 20, + 112, + 37, + 239, + 8, + 65, + 0, + 134, + 85, + 206, + 231, + 102, + 99, + 208, + 186, + 243, + 3, + 65, + 113, + 220, + 95, + 92, + 204, + 148, + 8, + 69, + 56, + 172, + 53, + 213, + 103, + 70, + 162, + 219, + 114, + 201, + 174, + 108, + 26, + 65, + 128, + 61, + 76, + 85, + 66, + 25, + 79, + 104, + 48, + 7, + 11, + 32, + 186, + 249, + 143, + 148, + 12, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(4E4A4575F97EDCE249812A7AD125414AFCD86933), + timestamp: Time( + 2023-12-05 10:00:27.180566288, + ), + signature: Some( + Signature( + [ + 238, + 56, + 52, + 98, + 136, + 2, + 124, + 213, + 241, + 29, + 202, + 92, + 155, + 87, + 19, + 90, + 57, + 118, + 225, + 16, + 233, + 74, + 42, + 103, + 195, + 194, + 196, + 45, + 161, + 57, + 128, + 158, + 7, + 96, + 16, + 75, + 110, + 102, + 105, + 175, + 98, + 124, + 83, + 172, + 150, + 8, + 12, + 111, + 147, + 207, + 236, + 185, + 162, + 4, + 137, + 136, + 129, + 151, + 194, + 184, + 194, + 251, + 29, + 7, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(9B9E1D79F825A8339A62A98CA1E42905B6DF8BCD), + timestamp: Time( + 2023-12-05 10:00:27.150643872, + ), + signature: Some( + Signature( + [ + 58, + 32, + 1, + 112, + 164, + 119, + 62, + 176, + 50, + 233, + 150, + 21, + 224, + 92, + 254, + 76, + 158, + 3, + 38, + 116, + 191, + 121, + 202, + 159, + 72, + 61, + 64, + 98, + 145, + 204, + 95, + 171, + 107, + 41, + 211, + 85, + 50, + 22, + 105, + 187, + 25, + 222, + 190, + 45, + 55, + 1, + 203, + 239, + 219, + 39, + 224, + 19, + 32, + 40, + 35, + 164, + 72, + 228, + 185, + 237, + 61, + 168, + 96, + 4, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(645F7AE779B1819C8E622465293234C6AFB04806), + timestamp: Time( + 2023-12-05 10:00:27.176180403, + ), + signature: Some( + Signature( + [ + 163, + 29, + 156, + 186, + 15, + 30, + 249, + 160, + 48, + 174, + 143, + 112, + 54, + 233, + 108, + 14, + 40, + 108, + 203, + 162, + 137, + 209, + 138, + 151, + 5, + 194, + 108, + 220, + 95, + 49, + 55, + 79, + 235, + 246, + 105, + 198, + 79, + 40, + 118, + 32, + 221, + 162, + 165, + 73, + 132, + 47, + 99, + 106, + 107, + 203, + 53, + 146, + 234, + 252, + 149, + 239, + 86, + 16, + 84, + 194, + 250, + 216, + 55, + 1, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(73837BE389D82E7881B504A43F40ADF4855E3B4D), + timestamp: Time( + 2023-12-05 10:00:27.171786111, + ), + signature: Some( + Signature( + [ + 38, + 45, + 136, + 208, + 231, + 238, + 113, + 190, + 220, + 134, + 130, + 41, + 94, + 148, + 163, + 147, + 204, + 48, + 193, + 197, + 45, + 176, + 250, + 121, + 55, + 54, + 51, + 192, + 212, + 238, + 135, + 202, + 79, + 133, + 13, + 3, + 122, + 21, + 214, + 228, + 80, + 138, + 116, + 4, + 83, + 203, + 239, + 233, + 103, + 140, + 31, + 10, + 75, + 106, + 201, + 137, + 187, + 62, + 141, + 133, + 145, + 176, + 167, + 8, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(24CF61027DF3E26A774EBD6A527DDE7F28D1CB32), + timestamp: Time( + 2023-12-05 10:00:27.15429356, + ), + signature: Some( + Signature( + [ + 70, + 121, + 165, + 79, + 208, + 246, + 51, + 248, + 143, + 142, + 166, + 93, + 231, + 154, + 180, + 157, + 123, + 230, + 136, + 206, + 102, + 29, + 126, + 174, + 70, + 58, + 17, + 155, + 110, + 193, + 26, + 138, + 106, + 198, + 230, + 165, + 88, + 36, + 129, + 32, + 21, + 28, + 215, + 94, + 13, + 86, + 111, + 47, + 217, + 216, + 57, + 35, + 212, + 26, + 47, + 195, + 160, + 169, + 194, + 237, + 182, + 216, + 22, + 9, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(A43138580D4EF4571A6E4A5C0CDEC3243EAA7276), + timestamp: Time( + 2023-12-05 10:00:27.168834598, + ), + signature: Some( + Signature( + [ + 230, + 115, + 225, + 156, + 12, + 65, + 130, + 4, + 116, + 136, + 84, + 197, + 182, + 164, + 135, + 110, + 166, + 130, + 169, + 11, + 87, + 145, + 255, + 33, + 56, + 85, + 116, + 234, + 197, + 49, + 135, + 250, + 198, + 87, + 178, + 220, + 113, + 156, + 52, + 240, + 225, + 109, + 210, + 196, + 205, + 177, + 119, + 246, + 41, + 75, + 18, + 116, + 91, + 20, + 51, + 35, + 84, + 217, + 127, + 98, + 214, + 141, + 13, + 8, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(1DB464D43981AA325BC0CE4ACA3EB12EAC076A5D), + timestamp: Time( + 2023-12-05 10:00:27.213820999, + ), + signature: Some( + Signature( + [ + 97, + 83, + 4, + 80, + 197, + 62, + 14, + 154, + 105, + 208, + 149, + 238, + 215, + 185, + 140, + 229, + 209, + 225, + 35, + 253, + 224, + 85, + 136, + 179, + 76, + 162, + 186, + 180, + 52, + 122, + 76, + 152, + 169, + 215, + 109, + 252, + 55, + 10, + 120, + 3, + 69, + 206, + 7, + 42, + 131, + 211, + 161, + 18, + 11, + 52, + 184, + 7, + 84, + 89, + 147, + 3, + 126, + 180, + 118, + 16, + 19, + 240, + 172, + 10, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(AA71546DB40A211CDB8B78D8DEB6F750A611336D), + timestamp: Time( + 2023-12-05 10:00:27.16741474, + ), + signature: Some( + Signature( + [ + 231, + 196, + 212, + 44, + 45, + 140, + 115, + 106, + 181, + 209, + 73, + 210, + 41, + 35, + 35, + 252, + 214, + 47, + 181, + 31, + 195, + 81, + 243, + 157, + 63, + 235, + 117, + 52, + 101, + 83, + 107, + 205, + 222, + 76, + 238, + 119, + 166, + 174, + 247, + 241, + 100, + 55, + 143, + 128, + 21, + 33, + 172, + 64, + 179, + 189, + 211, + 174, + 160, + 39, + 128, + 237, + 184, + 100, + 246, + 145, + 86, + 28, + 239, + 10, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(D72D363E94A7C20E7A3A274F1A074E577F04432A), + timestamp: Time( + 2023-12-05 10:00:27.199784014, + ), + signature: Some( + Signature( + [ + 112, + 94, + 35, + 228, + 120, + 76, + 105, + 81, + 136, + 179, + 249, + 200, + 164, + 98, + 51, + 133, + 138, + 247, + 127, + 128, + 140, + 53, + 73, + 222, + 33, + 237, + 29, + 20, + 39, + 200, + 72, + 61, + 118, + 129, + 112, + 198, + 103, + 254, + 118, + 30, + 184, + 162, + 5, + 196, + 78, + 141, + 158, + 114, + 48, + 59, + 36, + 169, + 207, + 93, + 22, + 13, + 153, + 92, + 38, + 196, + 159, + 254, + 23, + 14, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(6EF6EE46207C59ACA4CDD011FD00A0D8F4172BED), + timestamp: Time( + 2023-12-05 10:00:27.213977579, + ), + signature: Some( + Signature( + [ + 160, + 212, + 29, + 164, + 89, + 216, + 195, + 82, + 214, + 39, + 57, + 169, + 98, + 218, + 26, + 172, + 63, + 115, + 15, + 203, + 46, + 68, + 253, + 79, + 50, + 47, + 134, + 182, + 43, + 55, + 22, + 235, + 118, + 253, + 77, + 254, + 236, + 162, + 183, + 144, + 99, + 85, + 45, + 237, + 176, + 27, + 199, + 21, + 217, + 122, + 163, + 173, + 90, + 235, + 108, + 13, + 132, + 116, + 12, + 174, + 100, + 188, + 36, + 8, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(F35FDD3B4295AD80FB5D14012E649128C83BE7BC), + timestamp: Time( + 2023-12-05 10:00:27.155506091, + ), + signature: Some( + Signature( + [ + 63, + 215, + 16, + 156, + 208, + 102, + 27, + 138, + 155, + 146, + 89, + 25, + 50, + 127, + 120, + 138, + 85, + 237, + 36, + 121, + 99, + 5, + 29, + 96, + 29, + 66, + 213, + 97, + 40, + 197, + 107, + 94, + 206, + 234, + 150, + 167, + 189, + 22, + 22, + 152, + 157, + 130, + 128, + 254, + 9, + 138, + 177, + 112, + 185, + 71, + 119, + 50, + 169, + 61, + 112, + 92, + 0, + 141, + 66, + 93, + 176, + 93, + 2, + 1, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(0C3BA60DDAFFCCB36DD87DF983FD5EB34507084C), + timestamp: Time( + 2023-12-05 10:00:27.118242235, + ), + signature: Some( + Signature( + [ + 195, + 249, + 106, + 237, + 58, + 89, + 167, + 10, + 123, + 94, + 63, + 222, + 142, + 169, + 198, + 95, + 172, + 170, + 20, + 126, + 174, + 24, + 166, + 183, + 138, + 172, + 220, + 102, + 140, + 71, + 20, + 87, + 156, + 195, + 141, + 7, + 253, + 59, + 121, + 142, + 124, + 195, + 31, + 207, + 123, + 33, + 86, + 159, + 207, + 39, + 73, + 129, + 208, + 37, + 98, + 131, + 175, + 110, + 199, + 90, + 223, + 56, + 244, + 9, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(1354CE3615325D1820E451ED8AE09A057BB22753), + timestamp: Time( + 2023-12-05 10:00:27.185198971, + ), + signature: Some( + Signature( + [ + 177, + 152, + 35, + 15, + 89, + 25, + 86, + 151, + 194, + 7, + 193, + 167, + 79, + 248, + 125, + 111, + 32, + 207, + 103, + 243, + 44, + 182, + 94, + 154, + 62, + 27, + 209, + 118, + 67, + 183, + 16, + 94, + 126, + 136, + 157, + 125, + 3, + 35, + 138, + 55, + 209, + 40, + 249, + 101, + 184, + 196, + 218, + 163, + 251, + 154, + 113, + 231, + 71, + 245, + 23, + 74, + 146, + 10, + 251, + 227, + 215, + 128, + 54, + 4, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(7BA8DF346A24B75AD421D747FB13D471D6F26223), + timestamp: Time( + 2023-12-05 10:00:27.195078759, + ), + signature: Some( + Signature( + [ + 59, + 105, + 121, + 153, + 201, + 107, + 205, + 89, + 121, + 79, + 229, + 198, + 240, + 235, + 243, + 185, + 169, + 143, + 206, + 252, + 13, + 92, + 74, + 252, + 78, + 76, + 240, + 138, + 119, + 158, + 225, + 23, + 116, + 101, + 171, + 124, + 125, + 30, + 135, + 249, + 235, + 143, + 236, + 109, + 216, + 189, + 123, + 139, + 151, + 47, + 40, + 206, + 177, + 187, + 175, + 18, + 202, + 14, + 28, + 228, + 83, + 46, + 203, + 6, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(AB2D0A303079ABA286D75C5BC2E95C0FB87546AB), + timestamp: Time( + 2023-12-05 10:00:27.215038418, + ), + signature: Some( + Signature( + [ + 94, + 115, + 223, + 98, + 147, + 203, + 208, + 216, + 205, + 20, + 96, + 203, + 137, + 233, + 170, + 101, + 42, + 63, + 76, + 168, + 176, + 22, + 238, + 81, + 138, + 57, + 202, + 12, + 13, + 116, + 240, + 156, + 191, + 193, + 56, + 148, + 248, + 243, + 116, + 236, + 94, + 56, + 25, + 189, + 56, + 51, + 221, + 214, + 224, + 107, + 109, + 216, + 65, + 237, + 128, + 34, + 148, + 188, + 145, + 217, + 212, + 69, + 132, + 6, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(36591649E77A9932341183563F7D32478383F85F), + timestamp: Time( + 2023-12-05 10:00:27.106239911, + ), + signature: Some( + Signature( + [ + 112, + 176, + 165, + 158, + 44, + 80, + 194, + 135, + 4, + 236, + 153, + 64, + 91, + 88, + 155, + 100, + 124, + 22, + 111, + 61, + 106, + 248, + 19, + 46, + 40, + 73, + 68, + 207, + 118, + 117, + 77, + 187, + 206, + 28, + 47, + 78, + 121, + 166, + 101, + 132, + 102, + 140, + 127, + 253, + 68, + 144, + 70, + 33, + 47, + 145, + 167, + 113, + 25, + 60, + 233, + 98, + 122, + 120, + 221, + 14, + 165, + 48, + 31, + 4, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(56A9F6AD81796EA0AACA8DD9EBCBB6F6539F0903), + timestamp: Time( + 2023-12-05 10:00:27.180075348, + ), + signature: Some( + Signature( + [ + 212, + 84, + 21, + 155, + 86, + 238, + 171, + 220, + 203, + 245, + 73, + 86, + 148, + 118, + 171, + 44, + 3, + 200, + 149, + 253, + 208, + 31, + 100, + 11, + 67, + 153, + 217, + 125, + 178, + 153, + 163, + 57, + 31, + 167, + 65, + 110, + 147, + 154, + 163, + 22, + 209, + 119, + 151, + 0, + 214, + 123, + 137, + 136, + 119, + 144, + 12, + 9, + 7, + 89, + 32, + 130, + 24, + 250, + 137, + 194, + 67, + 164, + 51, + 11, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(E394C2F7625D514B1BF05EDC6033167388DE4793), + timestamp: Time( + 2023-12-05 10:00:27.143046535, + ), + signature: Some( + Signature( + [ + 190, + 60, + 240, + 97, + 138, + 53, + 209, + 62, + 86, + 240, + 221, + 80, + 33, + 69, + 166, + 143, + 114, + 203, + 39, + 46, + 245, + 169, + 142, + 122, + 206, + 244, + 202, + 39, + 212, + 163, + 60, + 113, + 110, + 68, + 71, + 172, + 195, + 201, + 65, + 231, + 236, + 23, + 95, + 205, + 255, + 125, + 237, + 255, + 120, + 139, + 166, + 194, + 77, + 11, + 120, + 107, + 169, + 194, + 216, + 92, + 36, + 80, + 6, + 3, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(519AD7739408413E80010AECFDF1B509A580D0C0), + timestamp: Time( + 2023-12-05 10:00:27.156990374, + ), + signature: Some( + Signature( + [ + 142, + 180, + 152, + 195, + 59, + 36, + 69, + 156, + 169, + 232, + 13, + 198, + 116, + 45, + 108, + 32, + 198, + 109, + 180, + 242, + 61, + 146, + 21, + 107, + 205, + 147, + 247, + 59, + 191, + 101, + 101, + 70, + 226, + 64, + 96, + 179, + 170, + 94, + 127, + 36, + 158, + 168, + 185, + 230, + 96, + 2, + 13, + 192, + 95, + 49, + 179, + 185, + 187, + 138, + 155, + 64, + 142, + 88, + 12, + 48, + 237, + 38, + 200, + 8, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(9B6FF43A70EBDF0A7536E2C712FD7ECC2FC9E1E0), + timestamp: Time( + 2023-12-05 10:00:27.155536869, + ), + signature: Some( + Signature( + [ + 222, + 89, + 209, + 83, + 2, + 33, + 202, + 130, + 32, + 122, + 103, + 184, + 113, + 211, + 192, + 106, + 107, + 177, + 234, + 137, + 134, + 26, + 65, + 64, + 73, + 246, + 73, + 134, + 80, + 92, + 54, + 218, + 82, + 29, + 50, + 111, + 213, + 221, + 8, + 73, + 169, + 149, + 157, + 93, + 108, + 187, + 91, + 137, + 243, + 43, + 210, + 113, + 169, + 7, + 120, + 63, + 95, + 126, + 24, + 209, + 247, + 45, + 115, + 0, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(F15247741FAFBF85DB50C741E21E824D6D90059E), + timestamp: Time( + 2023-12-05 10:00:27.201509258, + ), + signature: Some( + Signature( + [ + 198, + 185, + 130, + 14, + 33, + 118, + 212, + 58, + 22, + 90, + 209, + 207, + 103, + 226, + 99, + 66, + 133, + 232, + 44, + 77, + 255, + 40, + 84, + 168, + 160, + 234, + 235, + 163, + 67, + 33, + 89, + 156, + 82, + 89, + 136, + 47, + 99, + 86, + 6, + 127, + 249, + 30, + 38, + 157, + 22, + 59, + 152, + 127, + 117, + 8, + 179, + 224, + 58, + 123, + 181, + 143, + 245, + 136, + 13, + 83, + 225, + 234, + 82, + 7, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(A466116BC84BEE971FF9B44398B0C29640AF1061), + timestamp: Time( + 2023-12-05 10:00:27.214225884, + ), + signature: Some( + Signature( + [ + 98, + 70, + 192, + 177, + 140, + 4, + 109, + 151, + 18, + 229, + 33, + 101, + 185, + 237, + 197, + 196, + 19, + 18, + 211, + 184, + 76, + 141, + 135, + 125, + 204, + 142, + 41, + 202, + 206, + 224, + 34, + 245, + 229, + 8, + 16, + 37, + 20, + 160, + 251, + 23, + 41, + 6, + 252, + 236, + 2, + 163, + 248, + 29, + 106, + 219, + 8, + 158, + 253, + 129, + 106, + 98, + 97, + 79, + 155, + 102, + 28, + 65, + 61, + 2, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(7A352301525273F08F61DFD2406777AF51FE4EB1), + timestamp: Time( + 2023-12-05 10:00:27.143654607, + ), + signature: Some( + Signature( + [ + 60, + 128, + 164, + 24, + 145, + 158, + 42, + 111, + 163, + 143, + 168, + 114, + 149, + 74, + 176, + 232, + 240, + 15, + 41, + 207, + 171, + 228, + 45, + 222, + 42, + 120, + 7, + 64, + 1, + 120, + 250, + 204, + 9, + 233, + 133, + 164, + 146, + 17, + 83, + 43, + 147, + 69, + 43, + 89, + 174, + 58, + 82, + 37, + 28, + 86, + 96, + 165, + 0, + 212, + 135, + 55, + 249, + 59, + 12, + 34, + 226, + 246, + 185, + 14, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(7808D15FE56C259EA14EE5C8B9A0BA655738425A), + timestamp: Time( + 2023-12-05 10:00:27.116587318, + ), + signature: Some( + Signature( + [ + 28, + 14, + 170, + 201, + 254, + 246, + 109, + 213, + 193, + 92, + 167, + 231, + 21, + 61, + 92, + 247, + 11, + 74, + 132, + 243, + 27, + 91, + 157, + 240, + 178, + 215, + 168, + 224, + 253, + 52, + 30, + 90, + 237, + 176, + 35, + 239, + 150, + 51, + 107, + 113, + 217, + 163, + 48, + 251, + 74, + 213, + 31, + 157, + 73, + 194, + 64, + 31, + 166, + 96, + 253, + 64, + 63, + 35, + 1, + 222, + 235, + 82, + 72, + 2, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(3363E8F97B02ECC00289E72173D827543047ACDA), + timestamp: Time( + 2023-12-05 10:00:27.180490882, + ), + signature: Some( + Signature( + [ + 241, + 222, + 7, + 157, + 182, + 19, + 7, + 71, + 88, + 111, + 117, + 81, + 78, + 230, + 140, + 61, + 6, + 66, + 156, + 53, + 232, + 46, + 56, + 157, + 84, + 241, + 237, + 217, + 64, + 128, + 2, + 66, + 248, + 243, + 96, + 229, + 9, + 99, + 219, + 41, + 8, + 30, + 86, + 30, + 189, + 233, + 80, + 85, + 27, + 216, + 108, + 141, + 253, + 153, + 235, + 209, + 185, + 23, + 17, + 134, + 159, + 182, + 38, + 4, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(74B3DA950977508AAEB105B2B0DEBFD6C54B8F40), + timestamp: Time( + 2023-12-05 10:00:27.167946056, + ), + signature: Some( + Signature( + [ + 33, + 25, + 199, + 164, + 84, + 140, + 121, + 85, + 225, + 168, + 192, + 73, + 65, + 209, + 85, + 200, + 134, + 89, + 197, + 98, + 124, + 70, + 115, + 237, + 238, + 107, + 163, + 126, + 180, + 65, + 110, + 56, + 196, + 229, + 208, + 131, + 244, + 35, + 10, + 6, + 82, + 89, + 188, + 73, + 242, + 83, + 161, + 100, + 170, + 114, + 44, + 193, + 139, + 227, + 255, + 37, + 78, + 215, + 18, + 210, + 218, + 5, + 228, + 10, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(A626601D8837DAB5E9FD6C760B1482A505D45F29), + timestamp: Time( + 2023-12-05 10:00:27.163792384, + ), + signature: Some( + Signature( + [ + 19, + 192, + 60, + 55, + 99, + 7, + 213, + 95, + 177, + 2, + 87, + 19, + 34, + 32, + 225, + 150, + 11, + 242, + 66, + 123, + 164, + 245, + 63, + 123, + 234, + 202, + 245, + 40, + 124, + 206, + 206, + 59, + 187, + 152, + 28, + 173, + 198, + 37, + 85, + 154, + 250, + 238, + 65, + 71, + 47, + 199, + 109, + 247, + 249, + 181, + 147, + 109, + 238, + 140, + 80, + 34, + 252, + 93, + 166, + 182, + 211, + 155, + 4, + 6, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(25219C7188D73816F8B2B7B153F83FA06A9A699E), + timestamp: Time( + 2023-12-05 10:00:27.145333751, + ), + signature: Some( + Signature( + [ + 194, + 209, + 111, + 175, + 16, + 253, + 148, + 210, + 211, + 159, + 246, + 81, + 212, + 137, + 145, + 64, + 26, + 28, + 207, + 244, + 185, + 222, + 112, + 244, + 40, + 4, + 237, + 154, + 253, + 12, + 139, + 36, + 170, + 109, + 64, + 91, + 204, + 172, + 39, + 62, + 207, + 133, + 208, + 188, + 109, + 180, + 74, + 117, + 30, + 40, + 102, + 96, + 62, + 67, + 223, + 20, + 228, + 106, + 14, + 51, + 16, + 165, + 85, + 5, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(4EADB65E0E0EED2FEA7D130AEE764E8FFBE0C6C2), + timestamp: Time( + 2023-12-05 10:00:27.161261575, + ), + signature: Some( + Signature( + [ + 111, + 170, + 186, + 85, + 150, + 115, + 141, + 39, + 73, + 77, + 90, + 191, + 21, + 54, + 244, + 154, + 245, + 169, + 167, + 27, + 108, + 238, + 11, + 43, + 219, + 23, + 65, + 68, + 239, + 231, + 120, + 194, + 204, + 225, + 24, + 4, + 22, + 186, + 67, + 165, + 76, + 249, + 138, + 202, + 219, + 188, + 229, + 184, + 81, + 26, + 109, + 87, + 59, + 199, + 51, + 198, + 13, + 47, + 34, + 251, + 166, + 8, + 240, + 1, + ], + ), + ), + }, + BlockIdFlagCommit { + validator_address: account::Id(50458E3714440C453BCBF6C62B2CC1DA5CC918BA), + timestamp: Time( + 2023-12-05 10:00:27.137629977, + ), + signature: Some( + Signature( + [ + 181, + 122, + 69, + 183, + 65, + 123, + 14, + 42, + 0, + 88, + 27, + 78, + 145, + 65, + 151, + 168, + 100, + 20, + 194, + 93, + 162, + 88, + 100, + 68, + 148, + 42, + 143, + 47, + 106, + 30, + 1, + 60, + 150, + 124, + 240, + 165, + 60, + 193, + 38, + 124, + 233, + 244, + 101, + 232, + 76, + 188, + 171, + 237, + 127, + 185, + 139, + 175, + 52, + 99, + 190, + 26, + 140, + 246, + 32, + 162, + 162, + 166, + 165, + 10, + ], + ), + ), + }, + ], + }, + ), + }, + ), + result_begin_block: Some( + BeginBlock { + events: [ + Event { + kind: "coin_spent", + attributes: [ + EventAttribute { + key: "spender", + value: "n1m3h30wlvsf8llruxtpukdvsy0km2kum864s6c9", + index: true, + }, + EventAttribute { + key: "amount", + value: "", + index: true, + }, + ], + }, + Event { + kind: "coin_received", + attributes: [ + EventAttribute { + key: "receiver", + value: "n17xpfvakm2amg962yls6f84z3kell8c5lza5z5c", + index: true, + }, + EventAttribute { + key: "amount", + value: "", + index: true, + }, + ], + }, + Event { + kind: "transfer", + attributes: [ + EventAttribute { + key: "recipient", + value: "n17xpfvakm2amg962yls6f84z3kell8c5lza5z5c", + index: true, + }, + EventAttribute { + key: "sender", + value: "n1m3h30wlvsf8llruxtpukdvsy0km2kum864s6c9", + index: true, + }, + EventAttribute { + key: "amount", + value: "", + index: true, + }, + ], + }, + Event { + kind: "message", + attributes: [ + EventAttribute { + key: "sender", + value: "n1m3h30wlvsf8llruxtpukdvsy0km2kum864s6c9", + index: true, + }, + ], + }, + Event { + kind: "mint", + attributes: [ + EventAttribute { + key: "bonded_ratio", + value: "0.048174013441366915", + index: true, + }, + EventAttribute { + key: "inflation", + value: "0.000000000000000000", + index: true, + }, + EventAttribute { + key: "annual_provisions", + value: "0.000000000000000000", + index: true, + }, + EventAttribute { + key: "amount", + value: "0", + index: true, + }, + ], + }, + Event { + kind: "coin_spent", + attributes: [ + EventAttribute { + key: "spender", + value: "n17xpfvakm2amg962yls6f84z3kell8c5lza5z5c", + index: true, + }, + EventAttribute { + key: "amount", + value: "", + index: true, + }, + ], + }, + Event { + kind: "coin_received", + attributes: [ + EventAttribute { + key: "receiver", + value: "n1jv65s3grqf6v6jl3dp4t6c9t9rk99cd84mn7k6", + index: true, + }, + EventAttribute { + key: "amount", + value: "", + index: true, + }, + ], + }, + Event { + kind: "transfer", + attributes: [ + EventAttribute { + key: "recipient", + value: "n1jv65s3grqf6v6jl3dp4t6c9t9rk99cd84mn7k6", + index: true, + }, + EventAttribute { + key: "sender", + value: "n17xpfvakm2amg962yls6f84z3kell8c5lza5z5c", + index: true, + }, + EventAttribute { + key: "amount", + value: "", + index: true, + }, + ], + }, + Event { + kind: "message", + attributes: [ + EventAttribute { + key: "sender", + value: "n17xpfvakm2amg962yls6f84z3kell8c5lza5z5c", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1xgyczxuxspeytdpyvp3w840ckzp4env4phq67x", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1xgyczxuxspeytdpyvp3w840ckzp4env4phq67x", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1e22wh85arrkpe6derct4l5r4gp3awvase24pf6", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1e22wh85arrkpe6derct4l5r4gp3awvase24pf6", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1gjtvly9lel6zskvwtvlg5vhwpu9c9wawlfdx8d", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1gjtvly9lel6zskvwtvlg5vhwpu9c9wawlfdx8d", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1ef8fjswyuxnv9779qfug042aca8hevenvnfcfm", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1ef8fjswyuxnv9779qfug042aca8hevenvnfcfm", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper18mgnd9k6rytn6tz7pf8d2d4dawl7e9crunrsxd", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper18mgnd9k6rytn6tz7pf8d2d4dawl7e9crunrsxd", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1h9ywl4ff7tpf8yzp7u9k5w0ks3rdnsercjjs0a", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1h9ywl4ff7tpf8yzp7u9k5w0ks3rdnsercjjs0a", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper14epla9mvgwl8456l4emvvchyj6reqg8a79fayw", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper14epla9mvgwl8456l4emvvchyj6reqg8a79fayw", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper197ml8ded7rpj3ezk55zjsavzemn549vuhy6qrh", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper197ml8ded7rpj3ezk55zjsavzemn549vuhy6qrh", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1q8cnx8s06q7ralnskqvj0acvqgacau6djqkm3z", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1q8cnx8s06q7ralnskqvj0acvqgacau6djqkm3z", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1uw3y3g6du2xxvlsu7qtv9vwvq7nqe5t65u0aph", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1uw3y3g6du2xxvlsu7qtv9vwvq7nqe5t65u0aph", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper166m7e8hxntq8e68whqrfk37f32xyk3eer0t427", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper166m7e8hxntq8e68whqrfk37f32xyk3eer0t427", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1mlmqlkxjttj6m4wwmf5eur35n3hf5zm2ev2vjj", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1mlmqlkxjttj6m4wwmf5eur35n3hf5zm2ev2vjj", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1aqxz5rhsu59tz3fykskqprarq2c2vxqv2jaysv", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1aqxz5rhsu59tz3fykskqprarq2c2vxqv2jaysv", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1upxrtt7nm7dpqe3ee9apaj838j9n2p2rqaswjn", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1upxrtt7nm7dpqe3ee9apaj838j9n2p2rqaswjn", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1v5hrqlv8dqgzvy0pwzqzg0gxy899rm4k062rxd", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1v5hrqlv8dqgzvy0pwzqzg0gxy899rm4k062rxd", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper12uspvr6qnrn9exf083t8l3khmd5n4r746n6ydf", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper12uspvr6qnrn9exf083t8l3khmd5n4r746n6ydf", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1v4ztxdpczle3z0n7ad4sgpe6a3ln4re8emev6n", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1v4ztxdpczle3z0n7ad4sgpe6a3ln4re8emev6n", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1xtzdn5suscpvmsfrm49u0025f8ars4zhwhupln", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1xtzdn5suscpvmsfrm49u0025f8ars4zhwhupln", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1ckz4f7gsqgsgv6q75rn038nsat6e68h4k9pl8g", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1ckz4f7gsqgsgv6q75rn038nsat6e68h4k9pl8g", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper18xr68spwm96vvehuvwf6ay9er0gd7q7ae8w8ns", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper18xr68spwm96vvehuvwf6ay9er0gd7q7ae8w8ns", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1w4slt0un6ac2l6nnwkkrm2yg39mghpgx98v0ka", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1w4slt0un6ac2l6nnwkkrm2yg39mghpgx98v0ka", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1u77g4a7tnt32uy7n4aknp9dtm9a86mypd29svm", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1u77g4a7tnt32uy7n4aknp9dtm9a86mypd29svm", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper12ut47cxmnwgflwwryw4akvkrfda4kn0elzy6jc", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper12ut47cxmnwgflwwryw4akvkrfda4kn0elzy6jc", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1jryrapf54q7gza547t490qkdgsjh5ngmc4xtm7", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1jryrapf54q7gza547t490qkdgsjh5ngmc4xtm7", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper15mxm5zujmm6xrdvp6wjzyupuprzv0a0xrww8cu", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper15mxm5zujmm6xrdvp6wjzyupuprzv0a0xrww8cu", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1l3whttjtav328jntcswfy63p9ell9uk0fp50zh", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1l3whttjtav328jntcswfy63p9ell9uk0fp50zh", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1nf7p9xlqw4jzzhslndtc40hac0g9askzrfplxg", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1nf7p9xlqw4jzzhslndtc40hac0g9askzrfplxg", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1jxv0u20scum4trha72c7ltfgfqef6nsck8t73h", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1jxv0u20scum4trha72c7ltfgfqef6nsck8t73h", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper15urq2dtp9qce4fyc85m6upwm9xul3049ckp6x4", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper15urq2dtp9qce4fyc85m6upwm9xul3049ckp6x4", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1wgdlgrd77vl385xaj6c929hh8lzltl5ajjdzv7", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1wgdlgrd77vl385xaj6c929hh8lzltl5ajjdzv7", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper12xrk9wxmh7z4n5s5d8hk7zumn0hqu6z69a3e9f", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper12xrk9wxmh7z4n5s5d8hk7zumn0hqu6z69a3e9f", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1undq3eavkylu7x8jzx208xgu7asze7xr2kurzp", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1undq3eavkylu7x8jzx208xgu7asze7xr2kurzp", + index: true, + }, + ], + }, + Event { + kind: "commission", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1thl5syhmscgnj7whdyrydw3w6vy80044kt2h0u", + index: true, + }, + ], + }, + Event { + kind: "rewards", + attributes: [ + EventAttribute { + key: "amount", + value: "", + index: true, + }, + EventAttribute { + key: "validator", + value: "nvaloper1thl5syhmscgnj7whdyrydw3w6vy80044kt2h0u", + index: true, + }, + ], + }, + ], + }, + ), + result_end_block: Some( + EndBlock { + validator_updates: [], + consensus_param_updates: Some( + Params { + block: Size { + max_bytes: 22020096, + max_gas: -1, + time_iota_ms: 1000, + }, + evidence: Params { + max_age_num_blocks: 100000, + max_age_duration: Duration( + 172800s, + ), + max_bytes: 1048576, + }, + validator: ValidatorParams { + pub_key_types: [ + Ed25519, + ], + }, + version: None, + abci: AbciParams { + vote_extensions_enable_height: None, + }, + }, + ), + events: [], + }, + ), + }, + events: Some( + { + "coin_received.amount": [ + "", + "", + ], + "coin_received.receiver": [ + "n17xpfvakm2amg962yls6f84z3kell8c5lza5z5c", + "n1jv65s3grqf6v6jl3dp4t6c9t9rk99cd84mn7k6", + ], + "coin_spent.amount": [ + "", + "", + ], + "coin_spent.spender": [ + "n1m3h30wlvsf8llruxtpukdvsy0km2kum864s6c9", + "n17xpfvakm2amg962yls6f84z3kell8c5lza5z5c", + ], + "commission.amount": [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + ], + "commission.validator": [ + "nvaloper1xgyczxuxspeytdpyvp3w840ckzp4env4phq67x", + "nvaloper1e22wh85arrkpe6derct4l5r4gp3awvase24pf6", + "nvaloper1gjtvly9lel6zskvwtvlg5vhwpu9c9wawlfdx8d", + "nvaloper1ef8fjswyuxnv9779qfug042aca8hevenvnfcfm", + "nvaloper18mgnd9k6rytn6tz7pf8d2d4dawl7e9crunrsxd", + "nvaloper1h9ywl4ff7tpf8yzp7u9k5w0ks3rdnsercjjs0a", + "nvaloper14epla9mvgwl8456l4emvvchyj6reqg8a79fayw", + "nvaloper197ml8ded7rpj3ezk55zjsavzemn549vuhy6qrh", + "nvaloper1q8cnx8s06q7ralnskqvj0acvqgacau6djqkm3z", + "nvaloper1uw3y3g6du2xxvlsu7qtv9vwvq7nqe5t65u0aph", + "nvaloper166m7e8hxntq8e68whqrfk37f32xyk3eer0t427", + "nvaloper1mlmqlkxjttj6m4wwmf5eur35n3hf5zm2ev2vjj", + "nvaloper1aqxz5rhsu59tz3fykskqprarq2c2vxqv2jaysv", + "nvaloper1upxrtt7nm7dpqe3ee9apaj838j9n2p2rqaswjn", + "nvaloper1v5hrqlv8dqgzvy0pwzqzg0gxy899rm4k062rxd", + "nvaloper12uspvr6qnrn9exf083t8l3khmd5n4r746n6ydf", + "nvaloper1v4ztxdpczle3z0n7ad4sgpe6a3ln4re8emev6n", + "nvaloper1xtzdn5suscpvmsfrm49u0025f8ars4zhwhupln", + "nvaloper1ckz4f7gsqgsgv6q75rn038nsat6e68h4k9pl8g", + "nvaloper18xr68spwm96vvehuvwf6ay9er0gd7q7ae8w8ns", + "nvaloper1w4slt0un6ac2l6nnwkkrm2yg39mghpgx98v0ka", + "nvaloper1u77g4a7tnt32uy7n4aknp9dtm9a86mypd29svm", + "nvaloper12ut47cxmnwgflwwryw4akvkrfda4kn0elzy6jc", + "nvaloper1jryrapf54q7gza547t490qkdgsjh5ngmc4xtm7", + "nvaloper15mxm5zujmm6xrdvp6wjzyupuprzv0a0xrww8cu", + "nvaloper1l3whttjtav328jntcswfy63p9ell9uk0fp50zh", + "nvaloper1nf7p9xlqw4jzzhslndtc40hac0g9askzrfplxg", + "nvaloper1jxv0u20scum4trha72c7ltfgfqef6nsck8t73h", + "nvaloper15urq2dtp9qce4fyc85m6upwm9xul3049ckp6x4", + "nvaloper1wgdlgrd77vl385xaj6c929hh8lzltl5ajjdzv7", + "nvaloper12xrk9wxmh7z4n5s5d8hk7zumn0hqu6z69a3e9f", + "nvaloper1undq3eavkylu7x8jzx208xgu7asze7xr2kurzp", + "nvaloper1thl5syhmscgnj7whdyrydw3w6vy80044kt2h0u", + ], + "message.sender": [ + "n1m3h30wlvsf8llruxtpukdvsy0km2kum864s6c9", + "n17xpfvakm2amg962yls6f84z3kell8c5lza5z5c", + ], + "mint.amount": [ + "0", + ], + "mint.annual_provisions": [ + "0.000000000000000000", + ], + "mint.bonded_ratio": [ + "0.048174013441366915", + ], + "mint.inflation": [ + "0.000000000000000000", + ], + "rewards.amount": [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + ], + "rewards.validator": [ + "nvaloper1xgyczxuxspeytdpyvp3w840ckzp4env4phq67x", + "nvaloper1e22wh85arrkpe6derct4l5r4gp3awvase24pf6", + "nvaloper1gjtvly9lel6zskvwtvlg5vhwpu9c9wawlfdx8d", + "nvaloper1ef8fjswyuxnv9779qfug042aca8hevenvnfcfm", + "nvaloper18mgnd9k6rytn6tz7pf8d2d4dawl7e9crunrsxd", + "nvaloper1h9ywl4ff7tpf8yzp7u9k5w0ks3rdnsercjjs0a", + "nvaloper14epla9mvgwl8456l4emvvchyj6reqg8a79fayw", + "nvaloper197ml8ded7rpj3ezk55zjsavzemn549vuhy6qrh", + "nvaloper1q8cnx8s06q7ralnskqvj0acvqgacau6djqkm3z", + "nvaloper1uw3y3g6du2xxvlsu7qtv9vwvq7nqe5t65u0aph", + "nvaloper166m7e8hxntq8e68whqrfk37f32xyk3eer0t427", + "nvaloper1mlmqlkxjttj6m4wwmf5eur35n3hf5zm2ev2vjj", + "nvaloper1aqxz5rhsu59tz3fykskqprarq2c2vxqv2jaysv", + "nvaloper1upxrtt7nm7dpqe3ee9apaj838j9n2p2rqaswjn", + "nvaloper1v5hrqlv8dqgzvy0pwzqzg0gxy899rm4k062rxd", + "nvaloper12uspvr6qnrn9exf083t8l3khmd5n4r746n6ydf", + "nvaloper1v4ztxdpczle3z0n7ad4sgpe6a3ln4re8emev6n", + "nvaloper1xtzdn5suscpvmsfrm49u0025f8ars4zhwhupln", + "nvaloper1ckz4f7gsqgsgv6q75rn038nsat6e68h4k9pl8g", + "nvaloper18xr68spwm96vvehuvwf6ay9er0gd7q7ae8w8ns", + "nvaloper1w4slt0un6ac2l6nnwkkrm2yg39mghpgx98v0ka", + "nvaloper1u77g4a7tnt32uy7n4aknp9dtm9a86mypd29svm", + "nvaloper12ut47cxmnwgflwwryw4akvkrfda4kn0elzy6jc", + "nvaloper1jryrapf54q7gza547t490qkdgsjh5ngmc4xtm7", + "nvaloper15mxm5zujmm6xrdvp6wjzyupuprzv0a0xrww8cu", + "nvaloper1l3whttjtav328jntcswfy63p9ell9uk0fp50zh", + "nvaloper1nf7p9xlqw4jzzhslndtc40hac0g9askzrfplxg", + "nvaloper1jxv0u20scum4trha72c7ltfgfqef6nsck8t73h", + "nvaloper15urq2dtp9qce4fyc85m6upwm9xul3049ckp6x4", + "nvaloper1wgdlgrd77vl385xaj6c929hh8lzltl5ajjdzv7", + "nvaloper12xrk9wxmh7z4n5s5d8hk7zumn0hqu6z69a3e9f", + "nvaloper1undq3eavkylu7x8jzx208xgu7asze7xr2kurzp", + "nvaloper1thl5syhmscgnj7whdyrydw3w6vy80044kt2h0u", + ], + "tm.event": [ + "NewBlock", + ], + "transfer.amount": [ + "", + "", + ], + "transfer.recipient": [ + "n17xpfvakm2amg962yls6f84z3kell8c5lza5z5c", + "n1jv65s3grqf6v6jl3dp4t6c9t9rk99cd84mn7k6", + ], + "transfer.sender": [ + "n1m3h30wlvsf8llruxtpukdvsy0km2kum864s6c9", + "n17xpfvakm2amg962yls6f84z3kell8c5lza5z5c", + ], + }, + ), +} diff --git a/nym-validator-rewarder/src/cli/run.rs b/nym-validator-rewarder/src/cli/run.rs index 717edff440..7866053766 100644 --- a/nym-validator-rewarder/src/cli/run.rs +++ b/nym-validator-rewarder/src/cli/run.rs @@ -2,8 +2,10 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::cli::try_load_current_config; +use crate::config::Config; use crate::error::NymRewarderError; use crate::rewarder::Rewarder; +use bip39::Mnemonic; use std::path::PathBuf; #[derive(Debug, clap::Args)] @@ -13,7 +15,9 @@ pub struct Args { } pub(crate) async fn execute(args: Args) -> Result<(), NymRewarderError> { - let config = try_load_current_config(&args.custom_config_path)?.with_override(args); + // let config = try_load_current_config(&args.custom_config_path)?.with_override(args); + + let config = Config::new(Mnemonic::generate(24).unwrap()); Rewarder::new(config).run().await } diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index 0c54f8a835..8dd2534bbc 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -3,10 +3,14 @@ use crate::config::Config; use crate::error::NymRewarderError; +use futures::StreamExt; use nym_network_defaults::NymNetworkDetails; use nym_task::TaskManager; +use nym_validator_client::nyxd::module_traits::StakingQueryClient; +use nym_validator_client::nyxd::{Paging, TendermintRpcClient}; use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient}; -use tendermint_rpc::WebSocketClient; +use tendermint_rpc::query::EventType; +use tendermint_rpc::{SubscriptionClient, WebSocketClient}; use tracing::info; mod tasks; @@ -29,55 +33,56 @@ impl Rewarder { // // - // let client_config = - // nyxd::Config::try_from_nym_network_details(&NymNetworkDetails::new_from_env())?; - // - // let client = DirectSigningHttpRpcNyxdClient::connect_with_mnemonic( - // client_config, - // self.config.base.upstream_nyxd.as_str(), - // // note: the clone here is fine as the mnemonic itself implements ZeroizeOnDrop - // self.config.base.mnemonic.clone(), - // )?; + let client_config = + nyxd::Config::try_from_nym_network_details(&NymNetworkDetails::new_from_env())?; - let (client, driver) = WebSocketClient::new("https://rpc.nymtech.net/") - .await - .unwrap(); - /* - /// #[tokio::main] - /// async fn main() { - /// let (client, driver) = WebSocketClient::new("ws://127.0.0.1:26657/websocket") - /// .await - /// .unwrap(); - /// let driver_handle = tokio::spawn(async move { driver.run().await }); - /// - /// // Standard client functionality - /// let tx = format!("some-key=some-value"); - /// client.broadcast_tx_async(Transaction::from(tx.into_bytes())).await.unwrap(); - /// - /// // Subscription functionality - /// let mut subs = client.subscribe(EventType::NewBlock.into()) - /// .await - /// .unwrap(); - /// - /// // Grab 5 NewBlock events - /// let mut ev_count = 5_i32; - /// - /// while let Some(res) = subs.next().await { - /// let ev = res.unwrap(); - /// println!("Got event: {:?}", ev); - /// ev_count -= 1; - /// if ev_count < 0 { - /// break; - /// } - /// } - /// - /// // Signal to the driver to terminate. - /// client.close().unwrap(); - /// // Await the driver's termination to ensure proper connection closure. - /// let _ = driver_handle.await.unwrap(); - /// } - /// ``` - */ + let client = DirectSigningHttpRpcNyxdClient::connect_with_mnemonic( + client_config, + self.config.base.upstream_nyxd.as_str(), + // note: the clone here is fine as the mnemonic itself implements ZeroizeOnDrop + self.config.base.mnemonic.clone(), + )?; + + let foo = StakingQueryClient::validator( + &client, + "nvaloper1l3whttjtav328jntcswfy63p9ell9uk0fp50zh" + .parse() + .unwrap(), + ) + .await + .unwrap(); + + println!("{:#?}", foo); + + // client.validator("").await.unwrap(); + + // let validators = client.validators(10015526u32, Paging::All).await.unwrap(); + + // println!("{:#?}", validators); + + // let (client, driver) = WebSocketClient::new("wss://rpc.nymtech.net/websocket") + // .await + // .unwrap(); + // + // let driver_handle = tokio::spawn(async move { driver.run().await }); + // + // let mut subs = client.subscribe(EventType::NewBlock.into()).await.unwrap(); + // + // let mut ev_count = 10; + // while let Some(res) = subs.next().await { + // let ev = res.unwrap(); + // println!("Got event: {:#?}", ev); + // break; + // // ev_count -= 1; + // // if ev_count < 0 { + // // break; + // // } + // } + // + // // Signal to the driver to terminate. + // client.close().unwrap(); + // // Await the driver's termination to ensure proper connection closure. + // let _ = driver_handle.await.unwrap(); /* task 1: diff --git a/nym-validator-rewarder/src/rewarder/tasks/block_watcher.rs b/nym-validator-rewarder/src/rewarder/tasks/block_watcher.rs new file mode 100644 index 0000000000..c4a77ff737 --- /dev/null +++ b/nym-validator-rewarder/src/rewarder/tasks/block_watcher.rs @@ -0,0 +1,5 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +// sure, we could subscribe to new block events and watch for signing of every single block +// but realistically we don't need that kind of accuracy so just checking the VP every few minutes is enough diff --git a/nym-validator-rewarder/src/rewarder/tasks/mod.rs b/nym-validator-rewarder/src/rewarder/tasks/mod.rs index af282c5deb..c6656f2a73 100644 --- a/nym-validator-rewarder/src/rewarder/tasks/mod.rs +++ b/nym-validator-rewarder/src/rewarder/tasks/mod.rs @@ -1,2 +1,4 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only + +pub mod block_watcher; From 8f24e8f2081b8fae6c6236a0d0f8c063b3bea654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 12 Dec 2023 15:33:21 +0000 Subject: [PATCH 03/21] starting to integrate scraper into the rewarder --- Cargo.lock | 6 +- .../module_traits/staking/query.rs | 133 +++++++++--------- .../validator-client/src/nyxd/mod.rs | 7 +- common/network-defaults/src/lib.rs | 14 +- common/network-defaults/src/mainnet.rs | 9 +- common/network-defaults/src/var_names.rs | 1 + envs/mainnet.env | 1 + nym-connect/desktop/Cargo.lock | 6 +- nym-validator-rewarder/Cargo.toml | 2 +- nym-validator-rewarder/src/cli/init.rs | 10 +- nym-validator-rewarder/src/cli/run.rs | 2 +- nym-validator-rewarder/src/config/mod.rs | 30 +++- .../src/config/persistence/mod.rs | 2 + .../src/config/persistence/paths.rs | 22 +++ nym-validator-rewarder/src/error.rs | 12 ++ nym-validator-rewarder/src/main.rs | 8 +- nym-validator-rewarder/src/rewarder/mod.rs | 74 ++-------- 17 files changed, 199 insertions(+), 140 deletions(-) create mode 100644 nym-validator-rewarder/src/config/persistence/paths.rs diff --git a/Cargo.lock b/Cargo.lock index ebacb1c6ef..d3ead95bf7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1652,7 +1652,7 @@ dependencies = [ [[package]] name = "cosmos-sdk-proto" version = "0.20.0" -source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features#67718aa27a96efb9881e927a8f998c94b885093c" +source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features#41ed4631e146268b0300033c8bbb993d79a49f58" dependencies = [ "prost 0.12.1", "prost-types 0.12.1", @@ -1682,7 +1682,7 @@ dependencies = [ [[package]] name = "cosmrs" version = "0.15.0" -source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features#67718aa27a96efb9881e927a8f998c94b885093c" +source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features#41ed4631e146268b0300033c8bbb993d79a49f58" dependencies = [ "bip32", "cosmos-sdk-proto 0.20.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", @@ -7533,8 +7533,8 @@ dependencies = [ "nym-network-defaults", "nym-task", "nym-validator-client", + "nyxd-scraper", "serde", - "tendermint-rpc", "thiserror", "tokio", "tracing", diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/query.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/query.rs index 9cc5b2e8d4..28ca15cc57 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/query.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/query.rs @@ -1,78 +1,79 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::nyxd::error::NyxdError; -use crate::nyxd::{CosmWasmClient, PageRequest}; +// use crate::nyxd::error::NyxdError; +// use crate::nyxd::{CosmWasmClient, PageRequest}; +use crate::nyxd::CosmWasmClient; use async_trait::async_trait; -use cosmrs::proto::cosmos::staking::v1beta1::{ - QueryHistoricalInfoRequest as ProtoQueryHistoricalInfoRequest, - QueryHistoricalInfoResponse as ProtoQueryHistoricalInfoResponse, - QueryValidatorRequest as ProtoQueryValidatorRequest, - QueryValidatorResponse as ProtoQueryValidatorResponse, - QueryValidatorsRequest as ProtoQueryValidatorsRequest, - QueryValidatorsResponse as ProtoQueryValidatorsResponse, -}; -use cosmrs::staking::{ - QueryHistoricalInfoRequest, QueryHistoricalInfoResponse, QueryValidatorRequest, - QueryValidatorResponse, QueryValidatorsRequest, QueryValidatorsResponse, -}; -use cosmrs::AccountId; +// use cosmrs::proto::cosmos::staking::v1beta1::{ +// QueryHistoricalInfoRequest as ProtoQueryHistoricalInfoRequest, +// QueryHistoricalInfoResponse as ProtoQueryHistoricalInfoResponse, +// QueryValidatorRequest as ProtoQueryValidatorRequest, +// QueryValidatorResponse as ProtoQueryValidatorResponse, +// QueryValidatorsRequest as ProtoQueryValidatorsRequest, +// QueryValidatorsResponse as ProtoQueryValidatorsResponse, +// }; +// use cosmrs::staking::{ +// QueryHistoricalInfoRequest, QueryHistoricalInfoResponse, QueryValidatorRequest, +// QueryValidatorResponse, QueryValidatorsRequest, QueryValidatorsResponse, +// }; +// use cosmrs::AccountId; // TODO: change trait restriction from `CosmWasmClient` to `TendermintRpcClient` #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait StakingQueryClient: CosmWasmClient { - async fn historical_info(&self, height: i64) -> Result { - let path = Some("/cosmos.staking.v1beta1.Query/HistoricalInfo".to_owned()); - - let req = QueryHistoricalInfoRequest { height }; - - let res = self - .make_abci_query::( - path, - req.into(), - ) - .await?; - - Ok(res.try_into()?) - } - - async fn validator( - &self, - validator_addr: AccountId, - ) -> Result { - let path = Some("/cosmos.staking.v1beta1.Query/Validator".to_owned()); - - let req = QueryValidatorRequest { validator_addr }; - - let res = self - .make_abci_query::( - path, - req.into(), - ) - .await?; - - Ok(res.try_into()?) - } - - async fn validators( - &self, - status: String, - pagination: Option, - ) -> Result { - let path = Some("/cosmos.staking.v1beta1.Query/Validators".to_owned()); - - let req = QueryValidatorsRequest { status, pagination }; - - let res = self - .make_abci_query::( - path, - req.into(), - ) - .await?; - - Ok(res.try_into()?) - } + // async fn historical_info(&self, height: i64) -> Result { + // let path = Some("/cosmos.staking.v1beta1.Query/HistoricalInfo".to_owned()); + // + // let req = QueryHistoricalInfoRequest { height }; + // + // let res = self + // .make_abci_query::( + // path, + // req.into(), + // ) + // .await?; + // + // Ok(res.try_into()?) + // } + // + // async fn validator( + // &self, + // validator_addr: AccountId, + // ) -> Result { + // let path = Some("/cosmos.staking.v1beta1.Query/Validator".to_owned()); + // + // let req = QueryValidatorRequest { validator_addr }; + // + // let res = self + // .make_abci_query::( + // path, + // req.into(), + // ) + // .await?; + // + // Ok(res.try_into()?) + // } + // + // async fn validators( + // &self, + // status: String, + // pagination: Option, + // ) -> Result { + // let path = Some("/cosmos.staking.v1beta1.Query/Validators".to_owned()); + // + // let req = QueryValidatorsRequest { status, pagination }; + // + // let res = self + // .make_abci_query::( + // path, + // req.into(), + // ) + // .await?; + // + // Ok(res.try_into()?) + // } } #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] diff --git a/common/client-libs/validator-client/src/nyxd/mod.rs b/common/client-libs/validator-client/src/nyxd/mod.rs index 49b6e972a5..fbd902dc56 100644 --- a/common/client-libs/validator-client/src/nyxd/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/mod.rs @@ -41,7 +41,7 @@ pub use coin::Coin; pub use cosmrs::{ bank::MsgSend, bip32, - query::{PageRequest, PageResponse}, + // query::{PageRequest, PageResponse}, tendermint::{ abci::{response::DeliverTx, types::ExecTxResult, Event, EventAttribute}, block::Height, @@ -50,7 +50,10 @@ pub use cosmrs::{ Time as TendermintTime, }, tx::{self, Msg}, - AccountId, Coin as CosmosCoin, Denom, Gas, + AccountId, + Coin as CosmosCoin, + Denom, + Gas, }; pub use cosmwasm_std::Coin as CosmWasmCoin; pub use cw2; diff --git a/common/network-defaults/src/lib.rs b/common/network-defaults/src/lib.rs index bcf02d1f02..1d2af785c1 100644 --- a/common/network-defaults/src/lib.rs +++ b/common/network-defaults/src/lib.rs @@ -111,6 +111,7 @@ impl NymNetworkDetails { .with_additional_validator_endpoint(ValidatorDetails::new( var(var_names::NYXD).expect("nyxd validator not set"), Some(var(var_names::NYM_API).expect("nym api not set")), + get_optional_env(var_names::NYXD_WEBSOCKET), )) .with_mixnet_contract(Some( var(var_names::MIXNET_CONTRACT_ADDRESS).expect("mixnet contract not set"), @@ -340,6 +341,9 @@ impl DenomDetailsOwned { pub struct ValidatorDetails { // it is assumed those values are always valid since they're being provided in our defaults file pub nyxd_url: String, + // + pub websocket_url: Option, + // Right now api_url is optional as we are not running the api reliably on all validators // however, later on it should be a mandatory field pub api_url: Option, @@ -347,9 +351,10 @@ pub struct ValidatorDetails { } impl ValidatorDetails { - pub fn new>(nyxd_url: S, api_url: Option) -> Self { + pub fn new>(nyxd_url: S, api_url: Option, websocket_url: Option) -> Self { ValidatorDetails { nyxd_url: nyxd_url.into(), + websocket_url: websocket_url.map(Into::into), api_url: api_url.map(Into::into), } } @@ -357,6 +362,7 @@ impl ValidatorDetails { pub fn new_nyxd_only>(nyxd_url: S) -> Self { ValidatorDetails { nyxd_url: nyxd_url.into(), + websocket_url: None, api_url: None, } } @@ -372,6 +378,12 @@ impl ValidatorDetails { .as_ref() .map(|url| url.parse().expect("the provided api url is invalid!")) } + + pub fn websocket_url(&self) -> Option { + self.websocket_url + .as_ref() + .map(|url| url.parse().expect("the provided websocket url is invalid!")) + } } fn fix_deprecated_environmental_variables() { diff --git a/common/network-defaults/src/mainnet.rs b/common/network-defaults/src/mainnet.rs index 13e8f21024..4cd9d0f53c 100644 --- a/common/network-defaults/src/mainnet.rs +++ b/common/network-defaults/src/mainnet.rs @@ -26,6 +26,7 @@ pub const REWARDING_VALIDATOR_ADDRESS: &str = "n10yyd98e2tuwu0f7ypz9dy3hhjw7v772 pub const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "https://mainnet-stats.nymte.ch:8090/"; pub const NYXD_URL: &str = "https://rpc.nymtech.net"; pub const NYM_API: &str = "https://validator.nymtech.net/api/"; +pub const NYXD_WS: &str = "wss://rpc.nymtech.net/websocket"; pub const EXPLORER_API: &str = "https://explorer.nymtech.net/api/"; // I'm making clippy mad on purpose, because that url HAS TO be updated and deployed before merging @@ -33,7 +34,11 @@ pub const EXIT_POLICY_URL: &str = "https://nymtech.net/.wellknown/network-requester/exit-policy.txt"; pub(crate) fn validators() -> Vec { - vec![ValidatorDetails::new(NYXD_URL, Some(NYM_API))] + vec![ValidatorDetails::new( + NYXD_URL, + Some(NYM_API), + Some(NYXD_WS), + )] } const DEFAULT_SUFFIX: &str = "_MAINNET_DEFAULT"; @@ -111,6 +116,7 @@ pub fn export_to_env() { ); set_var_to_default(var_names::NYXD, NYXD_URL); set_var_to_default(var_names::NYM_API, NYM_API); + set_var_to_default(var_names::NYXD_WEBSOCKET, NYXD_WS); set_var_to_default(var_names::EXPLORER_API, EXPLORER_API); set_var_to_default(var_names::EXIT_POLICY_URL, EXIT_POLICY_URL); } @@ -159,6 +165,7 @@ pub fn export_to_env_if_not_set() { ); set_var_conditionally_to_default(var_names::NYXD, NYXD_URL); set_var_conditionally_to_default(var_names::NYM_API, NYM_API); + set_var_conditionally_to_default(var_names::NYXD_WEBSOCKET, NYXD_WS); set_var_conditionally_to_default(var_names::EXPLORER_API, EXPLORER_API); set_var_conditionally_to_default(var_names::EXIT_POLICY_URL, EXIT_POLICY_URL); } diff --git a/common/network-defaults/src/var_names.rs b/common/network-defaults/src/var_names.rs index c74117630e..edda2686d1 100644 --- a/common/network-defaults/src/var_names.rs +++ b/common/network-defaults/src/var_names.rs @@ -26,6 +26,7 @@ pub const SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS: &str = pub const NAME_SERVICE_CONTRACT_ADDRESS: &str = "NAME_SERVICE_CONTRACT_ADDRESS"; pub const NYXD: &str = "NYXD"; pub const NYM_API: &str = "NYM_API"; +pub const NYXD_WEBSOCKET: &str = "NYXD_WS"; pub const EXPLORER_API: &str = "EXPLORER_API"; pub const EXIT_POLICY_URL: &str = "EXIT_POLICY"; diff --git a/envs/mainnet.env b/envs/mainnet.env index 9dc5b5272d..018b4f2e38 100644 --- a/envs/mainnet.env +++ b/envs/mainnet.env @@ -22,6 +22,7 @@ REWARDING_VALIDATOR_ADDRESS=n10yyd98e2tuwu0f7ypz9dy3hhjw7v772q6287gy STATISTICS_SERVICE_DOMAIN_ADDRESS="https://mainnet-stats.nymte.ch:8090" NYXD="https://rpc.nymtech.net" NYM_API="https://validator.nymtech.net/api/" +NYXD_WS="wss://rpc.nymtech.net/websocket" EXPLORER_API="https://explorer.nymtech.net/api/" DKG_TIME_CONFIGURATION="259200,300,300,60,60,1209600" diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 240da01001..d92f3d4b49 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -1014,7 +1014,8 @@ dependencies = [ [[package]] name = "cosmos-sdk-proto" version = "0.20.0" -source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features#67718aa27a96efb9881e927a8f998c94b885093c" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32560304ab4c365791fd307282f76637213d8083c1a98490c35159cd67852237" dependencies = [ "prost", "prost-types", @@ -1024,7 +1025,8 @@ dependencies = [ [[package]] name = "cosmrs" version = "0.15.0" -source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features#67718aa27a96efb9881e927a8f998c94b885093c" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47126f5364df9387b9d8559dcef62e99010e1d4098f39eb3f7ee4b5c254e40ea" dependencies = [ "bip32", "cosmos-sdk-proto", diff --git a/nym-validator-rewarder/Cargo.toml b/nym-validator-rewarder/Cargo.toml index 2ba72f9411..7e30f98073 100644 --- a/nym-validator-rewarder/Cargo.toml +++ b/nym-validator-rewarder/Cargo.toml @@ -21,7 +21,6 @@ tokio = { workspace = true, features = ["rt-multi-thread", "time", "macros"] } tracing.workspace = true url.workspace = true zeroize.workspace = true -tendermint-rpc = { workspace = true, features = ["websocket-client"] } # internal nym-bin-common = { path = "../common/bin-common", features = ["output_format"] } @@ -29,3 +28,4 @@ nym-config = { path = "../common/config" } nym-network-defaults = { path = "../common/network-defaults" } nym-task = { path = "../common/task" } nym-validator-client = { path = "../common/client-libs/validator-client" } +nyxd-scraper = { path = "../common/nyxd-scraper" } \ No newline at end of file diff --git a/nym-validator-rewarder/src/cli/init.rs b/nym-validator-rewarder/src/cli/init.rs index c55b6a6806..946b50c476 100644 --- a/nym-validator-rewarder/src/cli/init.rs +++ b/nym-validator-rewarder/src/cli/init.rs @@ -1,9 +1,10 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use crate::config::Config; +use crate::config::{default_config_directory, default_data_directory, Config}; use crate::error::NymRewarderError; use std::path::PathBuf; +use std::{fs, io}; #[derive(Debug, clap::Args)] pub struct Args { @@ -28,6 +29,11 @@ pub struct ConfigOverridableArgs { // } +fn init_paths() -> io::Result<()> { + fs::create_dir_all(default_data_directory())?; + fs::create_dir_all(default_config_directory()) +} + pub(crate) fn execute(args: Args) -> Result<(), NymRewarderError> { let path = args .custom_config_path @@ -38,6 +44,8 @@ pub(crate) fn execute(args: Args) -> Result<(), NymRewarderError> { return Err(NymRewarderError::ExistingConfig { path }); } + init_paths().map_err(|source| NymRewarderError::PathInitialisationFailure { source })?; + Config::new(args.mnemonic) .with_override(args.config_override) .save_to_path(&path) diff --git a/nym-validator-rewarder/src/cli/run.rs b/nym-validator-rewarder/src/cli/run.rs index 7866053766..aec8ac6981 100644 --- a/nym-validator-rewarder/src/cli/run.rs +++ b/nym-validator-rewarder/src/cli/run.rs @@ -19,5 +19,5 @@ pub(crate) async fn execute(args: Args) -> Result<(), NymRewarderError> { let config = Config::new(Mnemonic::generate(24).unwrap()); - Rewarder::new(config).run().await + Rewarder::new(config).await?.run().await } diff --git a/nym-validator-rewarder/src/config/mod.rs b/nym-validator-rewarder/src/config/mod.rs index dd79dce7a8..3ff795360a 100644 --- a/nym-validator-rewarder/src/config/mod.rs +++ b/nym-validator-rewarder/src/config/mod.rs @@ -1,6 +1,7 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only +use crate::config::persistence::paths::ValidatorRewarderPaths; use crate::config::r#override::ConfigOverride; use crate::config::template::CONFIG_TEMPLATE; use crate::error::NymRewarderError; @@ -12,7 +13,7 @@ use nym_network_defaults::NymNetworkDetails; use serde::{Deserialize, Serialize}; use std::io; use std::path::{Path, PathBuf}; -use tracing::{debug, warn}; +use tracing::debug; use url::Url; use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -55,8 +56,14 @@ pub struct Config { pub distribution: RewardingRatios, + #[zeroize(skip)] + pub nyxd_scraper: NyxdScraper, + #[serde(flatten)] pub base: Base, + + #[zeroize(skip)] + pub storage_paths: ValidatorRewarderPaths, } impl NymConfigTemplate for Config { @@ -72,10 +79,24 @@ impl Config { Config { save_path: None, distribution: RewardingRatios::default(), + nyxd_scraper: NyxdScraper { + websocket_url: network.endpoints[0] + .websocket_url() + .expect("TODO: hardcoded websocket url is not available"), + }, base: Base { upstream_nyxd: network.endpoints[0].nyxd_url(), mnemonic, }, + storage_paths: Default::default(), + } + } + + pub fn scraper_config(&self) -> nyxd_scraper::Config { + nyxd_scraper::Config { + websocket_url: self.nyxd_scraper.websocket_url.clone(), + rpc_url: self.base.upstream_nyxd.clone(), + database_path: self.storage_paths.nyxd_scraper.clone(), } } @@ -164,3 +185,10 @@ impl RewardingRatios { Ok(()) } } + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct NyxdScraper { + /// Url to the websocket endpoint of a validator, for example `wss://rpc.nymtech.net/websocket` + pub websocket_url: Url, + // TODO: debug with everything that's currently hardcoded in the scraper +} diff --git a/nym-validator-rewarder/src/config/persistence/mod.rs b/nym-validator-rewarder/src/config/persistence/mod.rs index af282c5deb..fcead5e8ef 100644 --- a/nym-validator-rewarder/src/config/persistence/mod.rs +++ b/nym-validator-rewarder/src/config/persistence/mod.rs @@ -1,2 +1,4 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only + +pub mod paths; diff --git a/nym-validator-rewarder/src/config/persistence/paths.rs b/nym-validator-rewarder/src/config/persistence/paths.rs new file mode 100644 index 0000000000..4317339677 --- /dev/null +++ b/nym-validator-rewarder/src/config/persistence/paths.rs @@ -0,0 +1,22 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::config::default_data_directory; +use serde::{Deserialize, Serialize}; +use std::path::PathBuf; + +pub const DEFAULT_SCRAPER_DB_FILENAME: &str = "nyxd_blocks.sqlite"; +pub const DEFAULT_REWARD_HISTORY_DB_FILENAME: &str = "rewards.sqlite"; + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct ValidatorRewarderPaths { + pub nyxd_scraper: PathBuf, +} + +impl Default for ValidatorRewarderPaths { + fn default() -> Self { + ValidatorRewarderPaths { + nyxd_scraper: default_data_directory().join(DEFAULT_SCRAPER_DB_FILENAME), + } + } +} diff --git a/nym-validator-rewarder/src/error.rs b/nym-validator-rewarder/src/error.rs index 0e68ca6852..655620cb68 100644 --- a/nym-validator-rewarder/src/error.rs +++ b/nym-validator-rewarder/src/error.rs @@ -26,6 +26,12 @@ pub enum NymRewarderError { source: io::Error, }, + #[error("failed to initialise paths")] + PathInitialisationFailure { + #[source] + source: io::Error, + }, + #[error("there already exists a config file at: {}. if you want to overwrite its content, use --force flag", path.display())] ExistingConfig { path: PathBuf }, @@ -35,4 +41,10 @@ pub enum NymRewarderError { #[error("the provided rewarding ratios don't add up to 1. ratios: {ratios:?}")] InvalidRewardingRatios { ratios: Vec }, + + #[error("chain scraping failure: {source}")] + ScraperFailure { + #[from] + source: nyxd_scraper::error::ScraperError, + }, } diff --git a/nym-validator-rewarder/src/main.rs b/nym-validator-rewarder/src/main.rs index 5baeace799..921a66c2bd 100644 --- a/nym-validator-rewarder/src/main.rs +++ b/nym-validator-rewarder/src/main.rs @@ -3,7 +3,7 @@ use crate::cli::Cli; use clap::{crate_name, crate_version, Parser}; -use nym_bin_common::logging::maybe_print_banner; +use nym_bin_common::logging::{maybe_print_banner, setup_tracing_logger}; use nym_network_defaults::setup_env; pub mod cli; @@ -13,8 +13,14 @@ mod rewarder; #[tokio::main] async fn main() -> anyhow::Result<()> { + std::env::set_var( + "RUST_LOG", + "debug,tendermint_rpc=warn,h2=warn,hyper=warn,rustls=warn,reqwest=warn,tungstenite=warn,async_tungstenite=warn", + ); + let args = Cli::parse(); setup_env(args.config_env_file.as_ref()); + setup_tracing_logger(); if !args.no_banner { maybe_print_banner(crate_name!(), crate_version!()); diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index 8dd2534bbc..27ad1564ae 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -3,25 +3,27 @@ use crate::config::Config; use crate::error::NymRewarderError; -use futures::StreamExt; use nym_network_defaults::NymNetworkDetails; use nym_task::TaskManager; -use nym_validator_client::nyxd::module_traits::StakingQueryClient; -use nym_validator_client::nyxd::{Paging, TendermintRpcClient}; -use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient}; -use tendermint_rpc::query::EventType; -use tendermint_rpc::{SubscriptionClient, WebSocketClient}; +use nyxd_scraper::NyxdScraper; +use std::time::Duration; use tracing::info; mod tasks; pub struct Rewarder { config: Config, + nyxd_scraper: NyxdScraper, } impl Rewarder { - pub fn new(config: Config) -> Self { - Rewarder { config } + pub async fn new(config: Config) -> Result { + let nyxd_scraper = NyxdScraper::new(config.scraper_config()).await?; + + Ok(Rewarder { + config, + nyxd_scraper, + }) } pub async fn run(mut self) -> Result<(), NymRewarderError> { @@ -30,59 +32,9 @@ impl Rewarder { // setup shutdowns let task_manager = TaskManager::new(5); - // - // + self.nyxd_scraper.start().await?; - let client_config = - nyxd::Config::try_from_nym_network_details(&NymNetworkDetails::new_from_env())?; - - let client = DirectSigningHttpRpcNyxdClient::connect_with_mnemonic( - client_config, - self.config.base.upstream_nyxd.as_str(), - // note: the clone here is fine as the mnemonic itself implements ZeroizeOnDrop - self.config.base.mnemonic.clone(), - )?; - - let foo = StakingQueryClient::validator( - &client, - "nvaloper1l3whttjtav328jntcswfy63p9ell9uk0fp50zh" - .parse() - .unwrap(), - ) - .await - .unwrap(); - - println!("{:#?}", foo); - - // client.validator("").await.unwrap(); - - // let validators = client.validators(10015526u32, Paging::All).await.unwrap(); - - // println!("{:#?}", validators); - - // let (client, driver) = WebSocketClient::new("wss://rpc.nymtech.net/websocket") - // .await - // .unwrap(); - // - // let driver_handle = tokio::spawn(async move { driver.run().await }); - // - // let mut subs = client.subscribe(EventType::NewBlock.into()).await.unwrap(); - // - // let mut ev_count = 10; - // while let Some(res) = subs.next().await { - // let ev = res.unwrap(); - // println!("Got event: {:#?}", ev); - // break; - // // ev_count -= 1; - // // if ev_count < 0 { - // // break; - // // } - // } - // - // // Signal to the driver to terminate. - // client.close().unwrap(); - // // Await the driver's termination to ensure proper connection closure. - // let _ = driver_handle.await.unwrap(); + tokio::time::sleep(Duration::from_secs(30)).await; /* task 1: @@ -98,6 +50,8 @@ impl Rewarder { */ + self.nyxd_scraper.stop().await; + todo!() } } From 13fa2119fcbd02c9dd76a1bd81e16e559009fcd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 13 Dec 2023 11:03:05 +0000 Subject: [PATCH 04/21] wip --- nym-validator-rewarder/src/main.rs | 8 ++++---- nym-validator-rewarder/src/rewarder/mod.rs | 12 +++++++++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/nym-validator-rewarder/src/main.rs b/nym-validator-rewarder/src/main.rs index 921a66c2bd..f5d59b57c2 100644 --- a/nym-validator-rewarder/src/main.rs +++ b/nym-validator-rewarder/src/main.rs @@ -13,10 +13,10 @@ mod rewarder; #[tokio::main] async fn main() -> anyhow::Result<()> { - std::env::set_var( - "RUST_LOG", - "debug,tendermint_rpc=warn,h2=warn,hyper=warn,rustls=warn,reqwest=warn,tungstenite=warn,async_tungstenite=warn", - ); + // std::env::set_var( + // "RUST_LOG", + // "debug,tendermint_rpc=warn,h2=warn,hyper=warn,rustls=warn,reqwest=warn,tungstenite=warn,async_tungstenite=warn", + // ); let args = Cli::parse(); setup_env(args.config_env_file.as_ref()); diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index 27ad1564ae..a61924d1c2 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -34,7 +34,17 @@ impl Rewarder { self.nyxd_scraper.start().await?; - tokio::time::sleep(Duration::from_secs(30)).await; + tokio::time::sleep(Duration::from_secs(3000)).await; + + loop { + tokio::select! { + biased; + interrupted = task_manager.catch_interrupt() => { + todo!() + } + + } + } /* task 1: From e1c0638f1e66ceadd089e1cf0140214af6e3f657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 13 Dec 2023 15:59:34 +0000 Subject: [PATCH 05/21] getting signing rewards --- Cargo.lock | 3 + .../src/nyxd/cosmwasm_client/mod.rs | 2 +- common/nyxd-scraper/src/scraper/mod.rs | 2 +- common/nyxd-scraper/src/storage/manager.rs | 30 +- common/nyxd-scraper/src/storage/mod.rs | 32 +- common/task/src/manager.rs | 6 +- nym-validator-rewarder/Cargo.toml | 5 + nym-validator-rewarder/foomp | 3936 ----------------- nym-validator-rewarder/src/config/mod.rs | 58 +- nym-validator-rewarder/src/error.rs | 12 + .../src/rewarder/block_signing.rs | 77 + nym-validator-rewarder/src/rewarder/epoch.rs | 60 + .../src/rewarder/helpers.rs | 24 + nym-validator-rewarder/src/rewarder/mod.rs | 242 +- .../src/rewarder/tasks/block_watcher.rs | 5 - .../src/rewarder/tasks/mod.rs | 2 - 16 files changed, 526 insertions(+), 3970 deletions(-) delete mode 100644 nym-validator-rewarder/foomp create mode 100644 nym-validator-rewarder/src/rewarder/block_signing.rs create mode 100644 nym-validator-rewarder/src/rewarder/epoch.rs create mode 100644 nym-validator-rewarder/src/rewarder/helpers.rs delete mode 100644 nym-validator-rewarder/src/rewarder/tasks/block_watcher.rs diff --git a/Cargo.lock b/Cargo.lock index d3ead95bf7..3fb552cc7c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7527,7 +7527,9 @@ dependencies = [ "anyhow", "bip39", "clap 4.4.7", + "cosmwasm-std", "futures", + "humantime-serde", "nym-bin-common", "nym-config", "nym-network-defaults", @@ -7536,6 +7538,7 @@ dependencies = [ "nyxd-scraper", "serde", "thiserror", + "time", "tokio", "tracing", "url", diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/mod.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/mod.rs index 59086eee99..98f2f8d07c 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/mod.rs @@ -1,7 +1,7 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::nyxd::cosmwasm_client::client_traits::{CosmWasmClient, SigningCosmWasmClient}; +use crate::nyxd::cosmwasm_client::client_traits::SigningCosmWasmClient; use crate::nyxd::error::NyxdError; use crate::nyxd::{Config, GasPrice, Hash, Height}; use crate::rpc::TendermintRpcClient; diff --git a/common/nyxd-scraper/src/scraper/mod.rs b/common/nyxd-scraper/src/scraper/mod.rs index 656cd6c921..e5038e98ee 100644 --- a/common/nyxd-scraper/src/scraper/mod.rs +++ b/common/nyxd-scraper/src/scraper/mod.rs @@ -112,7 +112,7 @@ pub struct NyxdScraper { task_tracker: TaskTracker, cancel_token: CancellationToken, - storage: ScraperStorage, + pub storage: ScraperStorage, } impl NyxdScraper { diff --git a/common/nyxd-scraper/src/storage/manager.rs b/common/nyxd-scraper/src/storage/manager.rs index 67ea50d610..1843634714 100644 --- a/common/nyxd-scraper/src/storage/manager.rs +++ b/common/nyxd-scraper/src/storage/manager.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::storage::models::Validator; +use crate::storage::models::{CommitSignature, Validator}; use sqlx::types::time::OffsetDateTime; use sqlx::{Executor, Sqlite}; use tracing::{instrument, trace}; @@ -84,8 +84,8 @@ impl StorageManager { SELECT COUNT(*) as count FROM pre_commit WHERE validator_address == ? - AND height > ? - AND height < ? + AND height >= ? + AND height <= ? "#, consensus_address, start_height, @@ -98,6 +98,24 @@ impl StorageManager { Ok(count) } + pub(crate) async fn get_precommit( + &self, + consensus_address: &str, + height: i64, + ) -> Result, sqlx::Error> { + sqlx::query_as( + r#" + SELECT * FROM pre_commit + WHERE validator_address = ? + AND height = ? + "#, + ) + .bind(consensus_address) + .bind(height) + .fetch_optional(&self.connection_pool) + .await + } + pub(crate) async fn get_block_validators( &self, height: i64, @@ -118,6 +136,12 @@ impl StorageManager { .await } + pub(crate) async fn get_validators(&self) -> Result, sqlx::Error> { + sqlx::query_as("SELECT * FROM validator") + .fetch_all(&self.connection_pool) + .await + } + pub(crate) async fn get_last_processed_height(&self) -> Result { let maybe_record = sqlx::query!( r#" diff --git a/common/nyxd-scraper/src/storage/mod.rs b/common/nyxd-scraper/src/storage/mod.rs index 1889752a97..761b4a4f7b 100644 --- a/common/nyxd-scraper/src/storage/mod.rs +++ b/common/nyxd-scraper/src/storage/mod.rs @@ -7,7 +7,7 @@ use crate::storage::manager::{ insert_block, insert_message, insert_precommit, insert_transaction, insert_validator, update_last_processed, StorageManager, }; -use crate::storage::models::Validator; +use crate::storage::models::{CommitSignature, Validator}; use sqlx::types::time::OffsetDateTime; use sqlx::{ConnectOptions, Sqlite, Transaction}; use std::fmt::Debug; @@ -91,6 +91,21 @@ impl ScraperStorage { Ok(self.manager.get_last_block_height_before(time).await?) } + pub async fn get_blocks_between( + &self, + start_time: OffsetDateTime, + end_time: OffsetDateTime, + ) -> Result { + let Some(block_start) = self.get_first_block_height_after(start_time).await? else { + return Ok(0); + }; + let Some(block_end) = self.get_last_block_height_before(end_time).await? else { + return Ok(0); + }; + + Ok(block_end - block_start + 1) + } + pub async fn get_signed_between( &self, consensus_address: &str, @@ -120,10 +135,25 @@ impl ScraperStorage { .await } + pub async fn get_precommit( + &self, + consensus_address: &str, + height: i64, + ) -> Result, ScraperError> { + Ok(self + .manager + .get_precommit(consensus_address, height) + .await?) + } + pub async fn get_block_signers(&self, height: i64) -> Result, ScraperError> { Ok(self.manager.get_block_validators(height).await?) } + pub async fn get_all_known_validators(&self) -> Result, ScraperError> { + Ok(self.manager.get_validators().await?) + } + pub async fn get_last_processed_height(&self) -> Result { Ok(self.manager.get_last_processed_height().await?) } diff --git a/common/task/src/manager.rs b/common/task/src/manager.rs index 35b4df3bf8..6a913fdc47 100644 --- a/common/task/src/manager.rs +++ b/common/task/src/manager.rs @@ -116,8 +116,8 @@ impl TaskManager { } #[cfg(not(target_arch = "wasm32"))] - pub async fn catch_interrupt(mut self) -> Result<(), SentError> { - let res = crate::wait_for_signal_and_error(&mut self).await; + pub async fn catch_interrupt(&mut self) -> Result<(), SentError> { + let res = crate::wait_for_signal_and_error(self).await; log::info!("Sending shutdown"); self.signal_shutdown().ok(); @@ -629,7 +629,7 @@ impl TaskHandle { #[cfg(not(target_arch = "wasm32"))] pub async fn wait_for_shutdown(self) -> Result<(), SentError> { match self { - TaskHandle::Internal(task_manager) => task_manager.catch_interrupt().await, + TaskHandle::Internal(mut task_manager) => task_manager.catch_interrupt().await, TaskHandle::External(mut task_client) => { task_client.recv().await; Ok(()) diff --git a/nym-validator-rewarder/Cargo.toml b/nym-validator-rewarder/Cargo.toml index 7e30f98073..cca6b7b422 100644 --- a/nym-validator-rewarder/Cargo.toml +++ b/nym-validator-rewarder/Cargo.toml @@ -13,15 +13,20 @@ license = "GPL-3" [dependencies] anyhow.workspace = true bip39 = { workspace = true, features = ["zeroize"] } +cosmwasm-std.workspace = true clap = { workspace = true, features = ["cargo"] } futures.workspace = true serde = { workspace = true, features = ["derive"] } thiserror.workspace = true tokio = { workspace = true, features = ["rt-multi-thread", "time", "macros"] } tracing.workspace = true +time.workspace = true url.workspace = true zeroize.workspace = true +humantime-serde = "1.0" + + # internal nym-bin-common = { path = "../common/bin-common", features = ["output_format"] } nym-config = { path = "../common/config" } diff --git a/nym-validator-rewarder/foomp b/nym-validator-rewarder/foomp deleted file mode 100644 index e75e1021d3..0000000000 --- a/nym-validator-rewarder/foomp +++ /dev/null @@ -1,3936 +0,0 @@ -Got event: Event { - query: "tm.event = 'NewBlock'", - data: LegacyNewBlock { - block: Some( - Block { - header: Header { - version: Version { - block: 11, - app: 0, - }, - chain_id: chain::Id(nyx), - height: block::Height(10104845), - time: Time( - 2023-12-05 10:00:27.168834598, - ), - last_block_id: Some( - Id { - hash: Hash::Sha256(05010DE73764F8DF015B7577831F74A5E289E12E4BA1AB43D2FAF25B71294898), - part_set_header: Header { - total: 1, - hash: Hash::Sha256(25F703C33A060479E582C0894D1B914E3C71C82816A9B68D699CF3B9428FED95), - }, - }, - ), - last_commit_hash: Some( - Hash::Sha256(B549FE4D2FA7286A902EBF04A417509DFE46DA1834A2F90A2A7E76761B044372), - ), - data_hash: Some( - Hash::Sha256(E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855), - ), - validators_hash: Hash::Sha256(97B531291F24462988D2D1B84DF6E21AE95E48C7546AF074554B355FEC76150C), - next_validators_hash: Hash::Sha256(97B531291F24462988D2D1B84DF6E21AE95E48C7546AF074554B355FEC76150C), - consensus_hash: Hash::Sha256(048091BC7DDC283F77BFBF91D73C44DA58C3DF8A9CBC867405D8B7F3DAADA22F), - app_hash: AppHash(46879129F47F945950D0E2E3D3A72F063C4817E13F5EA284C24E80525D25E657), - last_results_hash: Some( - Hash::Sha256(E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855), - ), - evidence_hash: Some( - Hash::Sha256(E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855), - ), - proposer_address: account::Id(F35FDD3B4295AD80FB5D14012E649128C83BE7BC), - }, - data: [], - evidence: List( - [], - ), - last_commit: Some( - Commit { - height: block::Height(10104844), - round: block::Round(0), - block_id: Id { - hash: Hash::Sha256(05010DE73764F8DF015B7577831F74A5E289E12E4BA1AB43D2FAF25B71294898), - part_set_header: Header { - total: 1, - hash: Hash::Sha256(25F703C33A060479E582C0894D1B914E3C71C82816A9B68D699CF3B9428FED95), - }, - }, - signatures: [ - BlockIdFlagCommit { - validator_address: account::Id(9A5783B0CB39B4AE670E0F9215D3C720B56506D1), - timestamp: Time( - 2023-12-05 10:00:27.142741875, - ), - signature: Some( - Signature( - [ - 118, - 63, - 211, - 243, - 145, - 45, - 41, - 51, - 22, - 47, - 69, - 157, - 177, - 81, - 24, - 161, - 119, - 61, - 31, - 79, - 98, - 95, - 216, - 177, - 116, - 100, - 152, - 29, - 152, - 180, - 85, - 237, - 195, - 124, - 143, - 217, - 196, - 225, - 3, - 89, - 206, - 139, - 91, - 26, - 86, - 226, - 30, - 159, - 207, - 252, - 144, - 134, - 76, - 3, - 74, - 25, - 183, - 21, - 47, - 223, - 1, - 10, - 65, - 3, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(E2E65903BAB5344E5CFFDDC2CD638A6BAB2E2E79), - timestamp: Time( - 2023-12-05 10:00:27.141560477, - ), - signature: Some( - Signature( - [ - 89, - 195, - 129, - 61, - 39, - 145, - 26, - 214, - 139, - 109, - 107, - 246, - 106, - 154, - 23, - 178, - 219, - 131, - 237, - 35, - 28, - 75, - 151, - 72, - 163, - 226, - 4, - 65, - 130, - 65, - 176, - 14, - 37, - 32, - 186, - 245, - 182, - 47, - 183, - 110, - 44, - 207, - 34, - 10, - 151, - 152, - 226, - 128, - 45, - 144, - 247, - 184, - 25, - 13, - 92, - 89, - 253, - 67, - 38, - 134, - 98, - 176, - 129, - 7, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(47601B18F0F434375F7219AC5297E156459D2A8C), - timestamp: Time( - 2023-12-05 10:00:27.256161926, - ), - signature: Some( - Signature( - [ - 122, - 126, - 230, - 222, - 202, - 30, - 31, - 20, - 112, - 37, - 239, - 8, - 65, - 0, - 134, - 85, - 206, - 231, - 102, - 99, - 208, - 186, - 243, - 3, - 65, - 113, - 220, - 95, - 92, - 204, - 148, - 8, - 69, - 56, - 172, - 53, - 213, - 103, - 70, - 162, - 219, - 114, - 201, - 174, - 108, - 26, - 65, - 128, - 61, - 76, - 85, - 66, - 25, - 79, - 104, - 48, - 7, - 11, - 32, - 186, - 249, - 143, - 148, - 12, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(4E4A4575F97EDCE249812A7AD125414AFCD86933), - timestamp: Time( - 2023-12-05 10:00:27.180566288, - ), - signature: Some( - Signature( - [ - 238, - 56, - 52, - 98, - 136, - 2, - 124, - 213, - 241, - 29, - 202, - 92, - 155, - 87, - 19, - 90, - 57, - 118, - 225, - 16, - 233, - 74, - 42, - 103, - 195, - 194, - 196, - 45, - 161, - 57, - 128, - 158, - 7, - 96, - 16, - 75, - 110, - 102, - 105, - 175, - 98, - 124, - 83, - 172, - 150, - 8, - 12, - 111, - 147, - 207, - 236, - 185, - 162, - 4, - 137, - 136, - 129, - 151, - 194, - 184, - 194, - 251, - 29, - 7, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(9B9E1D79F825A8339A62A98CA1E42905B6DF8BCD), - timestamp: Time( - 2023-12-05 10:00:27.150643872, - ), - signature: Some( - Signature( - [ - 58, - 32, - 1, - 112, - 164, - 119, - 62, - 176, - 50, - 233, - 150, - 21, - 224, - 92, - 254, - 76, - 158, - 3, - 38, - 116, - 191, - 121, - 202, - 159, - 72, - 61, - 64, - 98, - 145, - 204, - 95, - 171, - 107, - 41, - 211, - 85, - 50, - 22, - 105, - 187, - 25, - 222, - 190, - 45, - 55, - 1, - 203, - 239, - 219, - 39, - 224, - 19, - 32, - 40, - 35, - 164, - 72, - 228, - 185, - 237, - 61, - 168, - 96, - 4, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(645F7AE779B1819C8E622465293234C6AFB04806), - timestamp: Time( - 2023-12-05 10:00:27.176180403, - ), - signature: Some( - Signature( - [ - 163, - 29, - 156, - 186, - 15, - 30, - 249, - 160, - 48, - 174, - 143, - 112, - 54, - 233, - 108, - 14, - 40, - 108, - 203, - 162, - 137, - 209, - 138, - 151, - 5, - 194, - 108, - 220, - 95, - 49, - 55, - 79, - 235, - 246, - 105, - 198, - 79, - 40, - 118, - 32, - 221, - 162, - 165, - 73, - 132, - 47, - 99, - 106, - 107, - 203, - 53, - 146, - 234, - 252, - 149, - 239, - 86, - 16, - 84, - 194, - 250, - 216, - 55, - 1, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(73837BE389D82E7881B504A43F40ADF4855E3B4D), - timestamp: Time( - 2023-12-05 10:00:27.171786111, - ), - signature: Some( - Signature( - [ - 38, - 45, - 136, - 208, - 231, - 238, - 113, - 190, - 220, - 134, - 130, - 41, - 94, - 148, - 163, - 147, - 204, - 48, - 193, - 197, - 45, - 176, - 250, - 121, - 55, - 54, - 51, - 192, - 212, - 238, - 135, - 202, - 79, - 133, - 13, - 3, - 122, - 21, - 214, - 228, - 80, - 138, - 116, - 4, - 83, - 203, - 239, - 233, - 103, - 140, - 31, - 10, - 75, - 106, - 201, - 137, - 187, - 62, - 141, - 133, - 145, - 176, - 167, - 8, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(24CF61027DF3E26A774EBD6A527DDE7F28D1CB32), - timestamp: Time( - 2023-12-05 10:00:27.15429356, - ), - signature: Some( - Signature( - [ - 70, - 121, - 165, - 79, - 208, - 246, - 51, - 248, - 143, - 142, - 166, - 93, - 231, - 154, - 180, - 157, - 123, - 230, - 136, - 206, - 102, - 29, - 126, - 174, - 70, - 58, - 17, - 155, - 110, - 193, - 26, - 138, - 106, - 198, - 230, - 165, - 88, - 36, - 129, - 32, - 21, - 28, - 215, - 94, - 13, - 86, - 111, - 47, - 217, - 216, - 57, - 35, - 212, - 26, - 47, - 195, - 160, - 169, - 194, - 237, - 182, - 216, - 22, - 9, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(A43138580D4EF4571A6E4A5C0CDEC3243EAA7276), - timestamp: Time( - 2023-12-05 10:00:27.168834598, - ), - signature: Some( - Signature( - [ - 230, - 115, - 225, - 156, - 12, - 65, - 130, - 4, - 116, - 136, - 84, - 197, - 182, - 164, - 135, - 110, - 166, - 130, - 169, - 11, - 87, - 145, - 255, - 33, - 56, - 85, - 116, - 234, - 197, - 49, - 135, - 250, - 198, - 87, - 178, - 220, - 113, - 156, - 52, - 240, - 225, - 109, - 210, - 196, - 205, - 177, - 119, - 246, - 41, - 75, - 18, - 116, - 91, - 20, - 51, - 35, - 84, - 217, - 127, - 98, - 214, - 141, - 13, - 8, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(1DB464D43981AA325BC0CE4ACA3EB12EAC076A5D), - timestamp: Time( - 2023-12-05 10:00:27.213820999, - ), - signature: Some( - Signature( - [ - 97, - 83, - 4, - 80, - 197, - 62, - 14, - 154, - 105, - 208, - 149, - 238, - 215, - 185, - 140, - 229, - 209, - 225, - 35, - 253, - 224, - 85, - 136, - 179, - 76, - 162, - 186, - 180, - 52, - 122, - 76, - 152, - 169, - 215, - 109, - 252, - 55, - 10, - 120, - 3, - 69, - 206, - 7, - 42, - 131, - 211, - 161, - 18, - 11, - 52, - 184, - 7, - 84, - 89, - 147, - 3, - 126, - 180, - 118, - 16, - 19, - 240, - 172, - 10, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(AA71546DB40A211CDB8B78D8DEB6F750A611336D), - timestamp: Time( - 2023-12-05 10:00:27.16741474, - ), - signature: Some( - Signature( - [ - 231, - 196, - 212, - 44, - 45, - 140, - 115, - 106, - 181, - 209, - 73, - 210, - 41, - 35, - 35, - 252, - 214, - 47, - 181, - 31, - 195, - 81, - 243, - 157, - 63, - 235, - 117, - 52, - 101, - 83, - 107, - 205, - 222, - 76, - 238, - 119, - 166, - 174, - 247, - 241, - 100, - 55, - 143, - 128, - 21, - 33, - 172, - 64, - 179, - 189, - 211, - 174, - 160, - 39, - 128, - 237, - 184, - 100, - 246, - 145, - 86, - 28, - 239, - 10, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(D72D363E94A7C20E7A3A274F1A074E577F04432A), - timestamp: Time( - 2023-12-05 10:00:27.199784014, - ), - signature: Some( - Signature( - [ - 112, - 94, - 35, - 228, - 120, - 76, - 105, - 81, - 136, - 179, - 249, - 200, - 164, - 98, - 51, - 133, - 138, - 247, - 127, - 128, - 140, - 53, - 73, - 222, - 33, - 237, - 29, - 20, - 39, - 200, - 72, - 61, - 118, - 129, - 112, - 198, - 103, - 254, - 118, - 30, - 184, - 162, - 5, - 196, - 78, - 141, - 158, - 114, - 48, - 59, - 36, - 169, - 207, - 93, - 22, - 13, - 153, - 92, - 38, - 196, - 159, - 254, - 23, - 14, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(6EF6EE46207C59ACA4CDD011FD00A0D8F4172BED), - timestamp: Time( - 2023-12-05 10:00:27.213977579, - ), - signature: Some( - Signature( - [ - 160, - 212, - 29, - 164, - 89, - 216, - 195, - 82, - 214, - 39, - 57, - 169, - 98, - 218, - 26, - 172, - 63, - 115, - 15, - 203, - 46, - 68, - 253, - 79, - 50, - 47, - 134, - 182, - 43, - 55, - 22, - 235, - 118, - 253, - 77, - 254, - 236, - 162, - 183, - 144, - 99, - 85, - 45, - 237, - 176, - 27, - 199, - 21, - 217, - 122, - 163, - 173, - 90, - 235, - 108, - 13, - 132, - 116, - 12, - 174, - 100, - 188, - 36, - 8, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(F35FDD3B4295AD80FB5D14012E649128C83BE7BC), - timestamp: Time( - 2023-12-05 10:00:27.155506091, - ), - signature: Some( - Signature( - [ - 63, - 215, - 16, - 156, - 208, - 102, - 27, - 138, - 155, - 146, - 89, - 25, - 50, - 127, - 120, - 138, - 85, - 237, - 36, - 121, - 99, - 5, - 29, - 96, - 29, - 66, - 213, - 97, - 40, - 197, - 107, - 94, - 206, - 234, - 150, - 167, - 189, - 22, - 22, - 152, - 157, - 130, - 128, - 254, - 9, - 138, - 177, - 112, - 185, - 71, - 119, - 50, - 169, - 61, - 112, - 92, - 0, - 141, - 66, - 93, - 176, - 93, - 2, - 1, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(0C3BA60DDAFFCCB36DD87DF983FD5EB34507084C), - timestamp: Time( - 2023-12-05 10:00:27.118242235, - ), - signature: Some( - Signature( - [ - 195, - 249, - 106, - 237, - 58, - 89, - 167, - 10, - 123, - 94, - 63, - 222, - 142, - 169, - 198, - 95, - 172, - 170, - 20, - 126, - 174, - 24, - 166, - 183, - 138, - 172, - 220, - 102, - 140, - 71, - 20, - 87, - 156, - 195, - 141, - 7, - 253, - 59, - 121, - 142, - 124, - 195, - 31, - 207, - 123, - 33, - 86, - 159, - 207, - 39, - 73, - 129, - 208, - 37, - 98, - 131, - 175, - 110, - 199, - 90, - 223, - 56, - 244, - 9, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(1354CE3615325D1820E451ED8AE09A057BB22753), - timestamp: Time( - 2023-12-05 10:00:27.185198971, - ), - signature: Some( - Signature( - [ - 177, - 152, - 35, - 15, - 89, - 25, - 86, - 151, - 194, - 7, - 193, - 167, - 79, - 248, - 125, - 111, - 32, - 207, - 103, - 243, - 44, - 182, - 94, - 154, - 62, - 27, - 209, - 118, - 67, - 183, - 16, - 94, - 126, - 136, - 157, - 125, - 3, - 35, - 138, - 55, - 209, - 40, - 249, - 101, - 184, - 196, - 218, - 163, - 251, - 154, - 113, - 231, - 71, - 245, - 23, - 74, - 146, - 10, - 251, - 227, - 215, - 128, - 54, - 4, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(7BA8DF346A24B75AD421D747FB13D471D6F26223), - timestamp: Time( - 2023-12-05 10:00:27.195078759, - ), - signature: Some( - Signature( - [ - 59, - 105, - 121, - 153, - 201, - 107, - 205, - 89, - 121, - 79, - 229, - 198, - 240, - 235, - 243, - 185, - 169, - 143, - 206, - 252, - 13, - 92, - 74, - 252, - 78, - 76, - 240, - 138, - 119, - 158, - 225, - 23, - 116, - 101, - 171, - 124, - 125, - 30, - 135, - 249, - 235, - 143, - 236, - 109, - 216, - 189, - 123, - 139, - 151, - 47, - 40, - 206, - 177, - 187, - 175, - 18, - 202, - 14, - 28, - 228, - 83, - 46, - 203, - 6, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(AB2D0A303079ABA286D75C5BC2E95C0FB87546AB), - timestamp: Time( - 2023-12-05 10:00:27.215038418, - ), - signature: Some( - Signature( - [ - 94, - 115, - 223, - 98, - 147, - 203, - 208, - 216, - 205, - 20, - 96, - 203, - 137, - 233, - 170, - 101, - 42, - 63, - 76, - 168, - 176, - 22, - 238, - 81, - 138, - 57, - 202, - 12, - 13, - 116, - 240, - 156, - 191, - 193, - 56, - 148, - 248, - 243, - 116, - 236, - 94, - 56, - 25, - 189, - 56, - 51, - 221, - 214, - 224, - 107, - 109, - 216, - 65, - 237, - 128, - 34, - 148, - 188, - 145, - 217, - 212, - 69, - 132, - 6, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(36591649E77A9932341183563F7D32478383F85F), - timestamp: Time( - 2023-12-05 10:00:27.106239911, - ), - signature: Some( - Signature( - [ - 112, - 176, - 165, - 158, - 44, - 80, - 194, - 135, - 4, - 236, - 153, - 64, - 91, - 88, - 155, - 100, - 124, - 22, - 111, - 61, - 106, - 248, - 19, - 46, - 40, - 73, - 68, - 207, - 118, - 117, - 77, - 187, - 206, - 28, - 47, - 78, - 121, - 166, - 101, - 132, - 102, - 140, - 127, - 253, - 68, - 144, - 70, - 33, - 47, - 145, - 167, - 113, - 25, - 60, - 233, - 98, - 122, - 120, - 221, - 14, - 165, - 48, - 31, - 4, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(56A9F6AD81796EA0AACA8DD9EBCBB6F6539F0903), - timestamp: Time( - 2023-12-05 10:00:27.180075348, - ), - signature: Some( - Signature( - [ - 212, - 84, - 21, - 155, - 86, - 238, - 171, - 220, - 203, - 245, - 73, - 86, - 148, - 118, - 171, - 44, - 3, - 200, - 149, - 253, - 208, - 31, - 100, - 11, - 67, - 153, - 217, - 125, - 178, - 153, - 163, - 57, - 31, - 167, - 65, - 110, - 147, - 154, - 163, - 22, - 209, - 119, - 151, - 0, - 214, - 123, - 137, - 136, - 119, - 144, - 12, - 9, - 7, - 89, - 32, - 130, - 24, - 250, - 137, - 194, - 67, - 164, - 51, - 11, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(E394C2F7625D514B1BF05EDC6033167388DE4793), - timestamp: Time( - 2023-12-05 10:00:27.143046535, - ), - signature: Some( - Signature( - [ - 190, - 60, - 240, - 97, - 138, - 53, - 209, - 62, - 86, - 240, - 221, - 80, - 33, - 69, - 166, - 143, - 114, - 203, - 39, - 46, - 245, - 169, - 142, - 122, - 206, - 244, - 202, - 39, - 212, - 163, - 60, - 113, - 110, - 68, - 71, - 172, - 195, - 201, - 65, - 231, - 236, - 23, - 95, - 205, - 255, - 125, - 237, - 255, - 120, - 139, - 166, - 194, - 77, - 11, - 120, - 107, - 169, - 194, - 216, - 92, - 36, - 80, - 6, - 3, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(519AD7739408413E80010AECFDF1B509A580D0C0), - timestamp: Time( - 2023-12-05 10:00:27.156990374, - ), - signature: Some( - Signature( - [ - 142, - 180, - 152, - 195, - 59, - 36, - 69, - 156, - 169, - 232, - 13, - 198, - 116, - 45, - 108, - 32, - 198, - 109, - 180, - 242, - 61, - 146, - 21, - 107, - 205, - 147, - 247, - 59, - 191, - 101, - 101, - 70, - 226, - 64, - 96, - 179, - 170, - 94, - 127, - 36, - 158, - 168, - 185, - 230, - 96, - 2, - 13, - 192, - 95, - 49, - 179, - 185, - 187, - 138, - 155, - 64, - 142, - 88, - 12, - 48, - 237, - 38, - 200, - 8, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(9B6FF43A70EBDF0A7536E2C712FD7ECC2FC9E1E0), - timestamp: Time( - 2023-12-05 10:00:27.155536869, - ), - signature: Some( - Signature( - [ - 222, - 89, - 209, - 83, - 2, - 33, - 202, - 130, - 32, - 122, - 103, - 184, - 113, - 211, - 192, - 106, - 107, - 177, - 234, - 137, - 134, - 26, - 65, - 64, - 73, - 246, - 73, - 134, - 80, - 92, - 54, - 218, - 82, - 29, - 50, - 111, - 213, - 221, - 8, - 73, - 169, - 149, - 157, - 93, - 108, - 187, - 91, - 137, - 243, - 43, - 210, - 113, - 169, - 7, - 120, - 63, - 95, - 126, - 24, - 209, - 247, - 45, - 115, - 0, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(F15247741FAFBF85DB50C741E21E824D6D90059E), - timestamp: Time( - 2023-12-05 10:00:27.201509258, - ), - signature: Some( - Signature( - [ - 198, - 185, - 130, - 14, - 33, - 118, - 212, - 58, - 22, - 90, - 209, - 207, - 103, - 226, - 99, - 66, - 133, - 232, - 44, - 77, - 255, - 40, - 84, - 168, - 160, - 234, - 235, - 163, - 67, - 33, - 89, - 156, - 82, - 89, - 136, - 47, - 99, - 86, - 6, - 127, - 249, - 30, - 38, - 157, - 22, - 59, - 152, - 127, - 117, - 8, - 179, - 224, - 58, - 123, - 181, - 143, - 245, - 136, - 13, - 83, - 225, - 234, - 82, - 7, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(A466116BC84BEE971FF9B44398B0C29640AF1061), - timestamp: Time( - 2023-12-05 10:00:27.214225884, - ), - signature: Some( - Signature( - [ - 98, - 70, - 192, - 177, - 140, - 4, - 109, - 151, - 18, - 229, - 33, - 101, - 185, - 237, - 197, - 196, - 19, - 18, - 211, - 184, - 76, - 141, - 135, - 125, - 204, - 142, - 41, - 202, - 206, - 224, - 34, - 245, - 229, - 8, - 16, - 37, - 20, - 160, - 251, - 23, - 41, - 6, - 252, - 236, - 2, - 163, - 248, - 29, - 106, - 219, - 8, - 158, - 253, - 129, - 106, - 98, - 97, - 79, - 155, - 102, - 28, - 65, - 61, - 2, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(7A352301525273F08F61DFD2406777AF51FE4EB1), - timestamp: Time( - 2023-12-05 10:00:27.143654607, - ), - signature: Some( - Signature( - [ - 60, - 128, - 164, - 24, - 145, - 158, - 42, - 111, - 163, - 143, - 168, - 114, - 149, - 74, - 176, - 232, - 240, - 15, - 41, - 207, - 171, - 228, - 45, - 222, - 42, - 120, - 7, - 64, - 1, - 120, - 250, - 204, - 9, - 233, - 133, - 164, - 146, - 17, - 83, - 43, - 147, - 69, - 43, - 89, - 174, - 58, - 82, - 37, - 28, - 86, - 96, - 165, - 0, - 212, - 135, - 55, - 249, - 59, - 12, - 34, - 226, - 246, - 185, - 14, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(7808D15FE56C259EA14EE5C8B9A0BA655738425A), - timestamp: Time( - 2023-12-05 10:00:27.116587318, - ), - signature: Some( - Signature( - [ - 28, - 14, - 170, - 201, - 254, - 246, - 109, - 213, - 193, - 92, - 167, - 231, - 21, - 61, - 92, - 247, - 11, - 74, - 132, - 243, - 27, - 91, - 157, - 240, - 178, - 215, - 168, - 224, - 253, - 52, - 30, - 90, - 237, - 176, - 35, - 239, - 150, - 51, - 107, - 113, - 217, - 163, - 48, - 251, - 74, - 213, - 31, - 157, - 73, - 194, - 64, - 31, - 166, - 96, - 253, - 64, - 63, - 35, - 1, - 222, - 235, - 82, - 72, - 2, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(3363E8F97B02ECC00289E72173D827543047ACDA), - timestamp: Time( - 2023-12-05 10:00:27.180490882, - ), - signature: Some( - Signature( - [ - 241, - 222, - 7, - 157, - 182, - 19, - 7, - 71, - 88, - 111, - 117, - 81, - 78, - 230, - 140, - 61, - 6, - 66, - 156, - 53, - 232, - 46, - 56, - 157, - 84, - 241, - 237, - 217, - 64, - 128, - 2, - 66, - 248, - 243, - 96, - 229, - 9, - 99, - 219, - 41, - 8, - 30, - 86, - 30, - 189, - 233, - 80, - 85, - 27, - 216, - 108, - 141, - 253, - 153, - 235, - 209, - 185, - 23, - 17, - 134, - 159, - 182, - 38, - 4, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(74B3DA950977508AAEB105B2B0DEBFD6C54B8F40), - timestamp: Time( - 2023-12-05 10:00:27.167946056, - ), - signature: Some( - Signature( - [ - 33, - 25, - 199, - 164, - 84, - 140, - 121, - 85, - 225, - 168, - 192, - 73, - 65, - 209, - 85, - 200, - 134, - 89, - 197, - 98, - 124, - 70, - 115, - 237, - 238, - 107, - 163, - 126, - 180, - 65, - 110, - 56, - 196, - 229, - 208, - 131, - 244, - 35, - 10, - 6, - 82, - 89, - 188, - 73, - 242, - 83, - 161, - 100, - 170, - 114, - 44, - 193, - 139, - 227, - 255, - 37, - 78, - 215, - 18, - 210, - 218, - 5, - 228, - 10, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(A626601D8837DAB5E9FD6C760B1482A505D45F29), - timestamp: Time( - 2023-12-05 10:00:27.163792384, - ), - signature: Some( - Signature( - [ - 19, - 192, - 60, - 55, - 99, - 7, - 213, - 95, - 177, - 2, - 87, - 19, - 34, - 32, - 225, - 150, - 11, - 242, - 66, - 123, - 164, - 245, - 63, - 123, - 234, - 202, - 245, - 40, - 124, - 206, - 206, - 59, - 187, - 152, - 28, - 173, - 198, - 37, - 85, - 154, - 250, - 238, - 65, - 71, - 47, - 199, - 109, - 247, - 249, - 181, - 147, - 109, - 238, - 140, - 80, - 34, - 252, - 93, - 166, - 182, - 211, - 155, - 4, - 6, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(25219C7188D73816F8B2B7B153F83FA06A9A699E), - timestamp: Time( - 2023-12-05 10:00:27.145333751, - ), - signature: Some( - Signature( - [ - 194, - 209, - 111, - 175, - 16, - 253, - 148, - 210, - 211, - 159, - 246, - 81, - 212, - 137, - 145, - 64, - 26, - 28, - 207, - 244, - 185, - 222, - 112, - 244, - 40, - 4, - 237, - 154, - 253, - 12, - 139, - 36, - 170, - 109, - 64, - 91, - 204, - 172, - 39, - 62, - 207, - 133, - 208, - 188, - 109, - 180, - 74, - 117, - 30, - 40, - 102, - 96, - 62, - 67, - 223, - 20, - 228, - 106, - 14, - 51, - 16, - 165, - 85, - 5, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(4EADB65E0E0EED2FEA7D130AEE764E8FFBE0C6C2), - timestamp: Time( - 2023-12-05 10:00:27.161261575, - ), - signature: Some( - Signature( - [ - 111, - 170, - 186, - 85, - 150, - 115, - 141, - 39, - 73, - 77, - 90, - 191, - 21, - 54, - 244, - 154, - 245, - 169, - 167, - 27, - 108, - 238, - 11, - 43, - 219, - 23, - 65, - 68, - 239, - 231, - 120, - 194, - 204, - 225, - 24, - 4, - 22, - 186, - 67, - 165, - 76, - 249, - 138, - 202, - 219, - 188, - 229, - 184, - 81, - 26, - 109, - 87, - 59, - 199, - 51, - 198, - 13, - 47, - 34, - 251, - 166, - 8, - 240, - 1, - ], - ), - ), - }, - BlockIdFlagCommit { - validator_address: account::Id(50458E3714440C453BCBF6C62B2CC1DA5CC918BA), - timestamp: Time( - 2023-12-05 10:00:27.137629977, - ), - signature: Some( - Signature( - [ - 181, - 122, - 69, - 183, - 65, - 123, - 14, - 42, - 0, - 88, - 27, - 78, - 145, - 65, - 151, - 168, - 100, - 20, - 194, - 93, - 162, - 88, - 100, - 68, - 148, - 42, - 143, - 47, - 106, - 30, - 1, - 60, - 150, - 124, - 240, - 165, - 60, - 193, - 38, - 124, - 233, - 244, - 101, - 232, - 76, - 188, - 171, - 237, - 127, - 185, - 139, - 175, - 52, - 99, - 190, - 26, - 140, - 246, - 32, - 162, - 162, - 166, - 165, - 10, - ], - ), - ), - }, - ], - }, - ), - }, - ), - result_begin_block: Some( - BeginBlock { - events: [ - Event { - kind: "coin_spent", - attributes: [ - EventAttribute { - key: "spender", - value: "n1m3h30wlvsf8llruxtpukdvsy0km2kum864s6c9", - index: true, - }, - EventAttribute { - key: "amount", - value: "", - index: true, - }, - ], - }, - Event { - kind: "coin_received", - attributes: [ - EventAttribute { - key: "receiver", - value: "n17xpfvakm2amg962yls6f84z3kell8c5lza5z5c", - index: true, - }, - EventAttribute { - key: "amount", - value: "", - index: true, - }, - ], - }, - Event { - kind: "transfer", - attributes: [ - EventAttribute { - key: "recipient", - value: "n17xpfvakm2amg962yls6f84z3kell8c5lza5z5c", - index: true, - }, - EventAttribute { - key: "sender", - value: "n1m3h30wlvsf8llruxtpukdvsy0km2kum864s6c9", - index: true, - }, - EventAttribute { - key: "amount", - value: "", - index: true, - }, - ], - }, - Event { - kind: "message", - attributes: [ - EventAttribute { - key: "sender", - value: "n1m3h30wlvsf8llruxtpukdvsy0km2kum864s6c9", - index: true, - }, - ], - }, - Event { - kind: "mint", - attributes: [ - EventAttribute { - key: "bonded_ratio", - value: "0.048174013441366915", - index: true, - }, - EventAttribute { - key: "inflation", - value: "0.000000000000000000", - index: true, - }, - EventAttribute { - key: "annual_provisions", - value: "0.000000000000000000", - index: true, - }, - EventAttribute { - key: "amount", - value: "0", - index: true, - }, - ], - }, - Event { - kind: "coin_spent", - attributes: [ - EventAttribute { - key: "spender", - value: "n17xpfvakm2amg962yls6f84z3kell8c5lza5z5c", - index: true, - }, - EventAttribute { - key: "amount", - value: "", - index: true, - }, - ], - }, - Event { - kind: "coin_received", - attributes: [ - EventAttribute { - key: "receiver", - value: "n1jv65s3grqf6v6jl3dp4t6c9t9rk99cd84mn7k6", - index: true, - }, - EventAttribute { - key: "amount", - value: "", - index: true, - }, - ], - }, - Event { - kind: "transfer", - attributes: [ - EventAttribute { - key: "recipient", - value: "n1jv65s3grqf6v6jl3dp4t6c9t9rk99cd84mn7k6", - index: true, - }, - EventAttribute { - key: "sender", - value: "n17xpfvakm2amg962yls6f84z3kell8c5lza5z5c", - index: true, - }, - EventAttribute { - key: "amount", - value: "", - index: true, - }, - ], - }, - Event { - kind: "message", - attributes: [ - EventAttribute { - key: "sender", - value: "n17xpfvakm2amg962yls6f84z3kell8c5lza5z5c", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1xgyczxuxspeytdpyvp3w840ckzp4env4phq67x", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1xgyczxuxspeytdpyvp3w840ckzp4env4phq67x", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1e22wh85arrkpe6derct4l5r4gp3awvase24pf6", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1e22wh85arrkpe6derct4l5r4gp3awvase24pf6", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1gjtvly9lel6zskvwtvlg5vhwpu9c9wawlfdx8d", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1gjtvly9lel6zskvwtvlg5vhwpu9c9wawlfdx8d", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1ef8fjswyuxnv9779qfug042aca8hevenvnfcfm", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1ef8fjswyuxnv9779qfug042aca8hevenvnfcfm", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper18mgnd9k6rytn6tz7pf8d2d4dawl7e9crunrsxd", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper18mgnd9k6rytn6tz7pf8d2d4dawl7e9crunrsxd", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1h9ywl4ff7tpf8yzp7u9k5w0ks3rdnsercjjs0a", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1h9ywl4ff7tpf8yzp7u9k5w0ks3rdnsercjjs0a", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper14epla9mvgwl8456l4emvvchyj6reqg8a79fayw", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper14epla9mvgwl8456l4emvvchyj6reqg8a79fayw", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper197ml8ded7rpj3ezk55zjsavzemn549vuhy6qrh", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper197ml8ded7rpj3ezk55zjsavzemn549vuhy6qrh", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1q8cnx8s06q7ralnskqvj0acvqgacau6djqkm3z", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1q8cnx8s06q7ralnskqvj0acvqgacau6djqkm3z", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1uw3y3g6du2xxvlsu7qtv9vwvq7nqe5t65u0aph", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1uw3y3g6du2xxvlsu7qtv9vwvq7nqe5t65u0aph", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper166m7e8hxntq8e68whqrfk37f32xyk3eer0t427", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper166m7e8hxntq8e68whqrfk37f32xyk3eer0t427", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1mlmqlkxjttj6m4wwmf5eur35n3hf5zm2ev2vjj", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1mlmqlkxjttj6m4wwmf5eur35n3hf5zm2ev2vjj", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1aqxz5rhsu59tz3fykskqprarq2c2vxqv2jaysv", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1aqxz5rhsu59tz3fykskqprarq2c2vxqv2jaysv", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1upxrtt7nm7dpqe3ee9apaj838j9n2p2rqaswjn", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1upxrtt7nm7dpqe3ee9apaj838j9n2p2rqaswjn", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1v5hrqlv8dqgzvy0pwzqzg0gxy899rm4k062rxd", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1v5hrqlv8dqgzvy0pwzqzg0gxy899rm4k062rxd", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper12uspvr6qnrn9exf083t8l3khmd5n4r746n6ydf", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper12uspvr6qnrn9exf083t8l3khmd5n4r746n6ydf", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1v4ztxdpczle3z0n7ad4sgpe6a3ln4re8emev6n", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1v4ztxdpczle3z0n7ad4sgpe6a3ln4re8emev6n", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1xtzdn5suscpvmsfrm49u0025f8ars4zhwhupln", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1xtzdn5suscpvmsfrm49u0025f8ars4zhwhupln", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1ckz4f7gsqgsgv6q75rn038nsat6e68h4k9pl8g", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1ckz4f7gsqgsgv6q75rn038nsat6e68h4k9pl8g", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper18xr68spwm96vvehuvwf6ay9er0gd7q7ae8w8ns", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper18xr68spwm96vvehuvwf6ay9er0gd7q7ae8w8ns", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1w4slt0un6ac2l6nnwkkrm2yg39mghpgx98v0ka", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1w4slt0un6ac2l6nnwkkrm2yg39mghpgx98v0ka", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1u77g4a7tnt32uy7n4aknp9dtm9a86mypd29svm", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1u77g4a7tnt32uy7n4aknp9dtm9a86mypd29svm", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper12ut47cxmnwgflwwryw4akvkrfda4kn0elzy6jc", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper12ut47cxmnwgflwwryw4akvkrfda4kn0elzy6jc", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1jryrapf54q7gza547t490qkdgsjh5ngmc4xtm7", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1jryrapf54q7gza547t490qkdgsjh5ngmc4xtm7", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper15mxm5zujmm6xrdvp6wjzyupuprzv0a0xrww8cu", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper15mxm5zujmm6xrdvp6wjzyupuprzv0a0xrww8cu", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1l3whttjtav328jntcswfy63p9ell9uk0fp50zh", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1l3whttjtav328jntcswfy63p9ell9uk0fp50zh", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1nf7p9xlqw4jzzhslndtc40hac0g9askzrfplxg", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1nf7p9xlqw4jzzhslndtc40hac0g9askzrfplxg", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1jxv0u20scum4trha72c7ltfgfqef6nsck8t73h", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1jxv0u20scum4trha72c7ltfgfqef6nsck8t73h", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper15urq2dtp9qce4fyc85m6upwm9xul3049ckp6x4", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper15urq2dtp9qce4fyc85m6upwm9xul3049ckp6x4", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1wgdlgrd77vl385xaj6c929hh8lzltl5ajjdzv7", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1wgdlgrd77vl385xaj6c929hh8lzltl5ajjdzv7", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper12xrk9wxmh7z4n5s5d8hk7zumn0hqu6z69a3e9f", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper12xrk9wxmh7z4n5s5d8hk7zumn0hqu6z69a3e9f", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1undq3eavkylu7x8jzx208xgu7asze7xr2kurzp", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1undq3eavkylu7x8jzx208xgu7asze7xr2kurzp", - index: true, - }, - ], - }, - Event { - kind: "commission", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1thl5syhmscgnj7whdyrydw3w6vy80044kt2h0u", - index: true, - }, - ], - }, - Event { - kind: "rewards", - attributes: [ - EventAttribute { - key: "amount", - value: "", - index: true, - }, - EventAttribute { - key: "validator", - value: "nvaloper1thl5syhmscgnj7whdyrydw3w6vy80044kt2h0u", - index: true, - }, - ], - }, - ], - }, - ), - result_end_block: Some( - EndBlock { - validator_updates: [], - consensus_param_updates: Some( - Params { - block: Size { - max_bytes: 22020096, - max_gas: -1, - time_iota_ms: 1000, - }, - evidence: Params { - max_age_num_blocks: 100000, - max_age_duration: Duration( - 172800s, - ), - max_bytes: 1048576, - }, - validator: ValidatorParams { - pub_key_types: [ - Ed25519, - ], - }, - version: None, - abci: AbciParams { - vote_extensions_enable_height: None, - }, - }, - ), - events: [], - }, - ), - }, - events: Some( - { - "coin_received.amount": [ - "", - "", - ], - "coin_received.receiver": [ - "n17xpfvakm2amg962yls6f84z3kell8c5lza5z5c", - "n1jv65s3grqf6v6jl3dp4t6c9t9rk99cd84mn7k6", - ], - "coin_spent.amount": [ - "", - "", - ], - "coin_spent.spender": [ - "n1m3h30wlvsf8llruxtpukdvsy0km2kum864s6c9", - "n17xpfvakm2amg962yls6f84z3kell8c5lza5z5c", - ], - "commission.amount": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - ], - "commission.validator": [ - "nvaloper1xgyczxuxspeytdpyvp3w840ckzp4env4phq67x", - "nvaloper1e22wh85arrkpe6derct4l5r4gp3awvase24pf6", - "nvaloper1gjtvly9lel6zskvwtvlg5vhwpu9c9wawlfdx8d", - "nvaloper1ef8fjswyuxnv9779qfug042aca8hevenvnfcfm", - "nvaloper18mgnd9k6rytn6tz7pf8d2d4dawl7e9crunrsxd", - "nvaloper1h9ywl4ff7tpf8yzp7u9k5w0ks3rdnsercjjs0a", - "nvaloper14epla9mvgwl8456l4emvvchyj6reqg8a79fayw", - "nvaloper197ml8ded7rpj3ezk55zjsavzemn549vuhy6qrh", - "nvaloper1q8cnx8s06q7ralnskqvj0acvqgacau6djqkm3z", - "nvaloper1uw3y3g6du2xxvlsu7qtv9vwvq7nqe5t65u0aph", - "nvaloper166m7e8hxntq8e68whqrfk37f32xyk3eer0t427", - "nvaloper1mlmqlkxjttj6m4wwmf5eur35n3hf5zm2ev2vjj", - "nvaloper1aqxz5rhsu59tz3fykskqprarq2c2vxqv2jaysv", - "nvaloper1upxrtt7nm7dpqe3ee9apaj838j9n2p2rqaswjn", - "nvaloper1v5hrqlv8dqgzvy0pwzqzg0gxy899rm4k062rxd", - "nvaloper12uspvr6qnrn9exf083t8l3khmd5n4r746n6ydf", - "nvaloper1v4ztxdpczle3z0n7ad4sgpe6a3ln4re8emev6n", - "nvaloper1xtzdn5suscpvmsfrm49u0025f8ars4zhwhupln", - "nvaloper1ckz4f7gsqgsgv6q75rn038nsat6e68h4k9pl8g", - "nvaloper18xr68spwm96vvehuvwf6ay9er0gd7q7ae8w8ns", - "nvaloper1w4slt0un6ac2l6nnwkkrm2yg39mghpgx98v0ka", - "nvaloper1u77g4a7tnt32uy7n4aknp9dtm9a86mypd29svm", - "nvaloper12ut47cxmnwgflwwryw4akvkrfda4kn0elzy6jc", - "nvaloper1jryrapf54q7gza547t490qkdgsjh5ngmc4xtm7", - "nvaloper15mxm5zujmm6xrdvp6wjzyupuprzv0a0xrww8cu", - "nvaloper1l3whttjtav328jntcswfy63p9ell9uk0fp50zh", - "nvaloper1nf7p9xlqw4jzzhslndtc40hac0g9askzrfplxg", - "nvaloper1jxv0u20scum4trha72c7ltfgfqef6nsck8t73h", - "nvaloper15urq2dtp9qce4fyc85m6upwm9xul3049ckp6x4", - "nvaloper1wgdlgrd77vl385xaj6c929hh8lzltl5ajjdzv7", - "nvaloper12xrk9wxmh7z4n5s5d8hk7zumn0hqu6z69a3e9f", - "nvaloper1undq3eavkylu7x8jzx208xgu7asze7xr2kurzp", - "nvaloper1thl5syhmscgnj7whdyrydw3w6vy80044kt2h0u", - ], - "message.sender": [ - "n1m3h30wlvsf8llruxtpukdvsy0km2kum864s6c9", - "n17xpfvakm2amg962yls6f84z3kell8c5lza5z5c", - ], - "mint.amount": [ - "0", - ], - "mint.annual_provisions": [ - "0.000000000000000000", - ], - "mint.bonded_ratio": [ - "0.048174013441366915", - ], - "mint.inflation": [ - "0.000000000000000000", - ], - "rewards.amount": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - ], - "rewards.validator": [ - "nvaloper1xgyczxuxspeytdpyvp3w840ckzp4env4phq67x", - "nvaloper1e22wh85arrkpe6derct4l5r4gp3awvase24pf6", - "nvaloper1gjtvly9lel6zskvwtvlg5vhwpu9c9wawlfdx8d", - "nvaloper1ef8fjswyuxnv9779qfug042aca8hevenvnfcfm", - "nvaloper18mgnd9k6rytn6tz7pf8d2d4dawl7e9crunrsxd", - "nvaloper1h9ywl4ff7tpf8yzp7u9k5w0ks3rdnsercjjs0a", - "nvaloper14epla9mvgwl8456l4emvvchyj6reqg8a79fayw", - "nvaloper197ml8ded7rpj3ezk55zjsavzemn549vuhy6qrh", - "nvaloper1q8cnx8s06q7ralnskqvj0acvqgacau6djqkm3z", - "nvaloper1uw3y3g6du2xxvlsu7qtv9vwvq7nqe5t65u0aph", - "nvaloper166m7e8hxntq8e68whqrfk37f32xyk3eer0t427", - "nvaloper1mlmqlkxjttj6m4wwmf5eur35n3hf5zm2ev2vjj", - "nvaloper1aqxz5rhsu59tz3fykskqprarq2c2vxqv2jaysv", - "nvaloper1upxrtt7nm7dpqe3ee9apaj838j9n2p2rqaswjn", - "nvaloper1v5hrqlv8dqgzvy0pwzqzg0gxy899rm4k062rxd", - "nvaloper12uspvr6qnrn9exf083t8l3khmd5n4r746n6ydf", - "nvaloper1v4ztxdpczle3z0n7ad4sgpe6a3ln4re8emev6n", - "nvaloper1xtzdn5suscpvmsfrm49u0025f8ars4zhwhupln", - "nvaloper1ckz4f7gsqgsgv6q75rn038nsat6e68h4k9pl8g", - "nvaloper18xr68spwm96vvehuvwf6ay9er0gd7q7ae8w8ns", - "nvaloper1w4slt0un6ac2l6nnwkkrm2yg39mghpgx98v0ka", - "nvaloper1u77g4a7tnt32uy7n4aknp9dtm9a86mypd29svm", - "nvaloper12ut47cxmnwgflwwryw4akvkrfda4kn0elzy6jc", - "nvaloper1jryrapf54q7gza547t490qkdgsjh5ngmc4xtm7", - "nvaloper15mxm5zujmm6xrdvp6wjzyupuprzv0a0xrww8cu", - "nvaloper1l3whttjtav328jntcswfy63p9ell9uk0fp50zh", - "nvaloper1nf7p9xlqw4jzzhslndtc40hac0g9askzrfplxg", - "nvaloper1jxv0u20scum4trha72c7ltfgfqef6nsck8t73h", - "nvaloper15urq2dtp9qce4fyc85m6upwm9xul3049ckp6x4", - "nvaloper1wgdlgrd77vl385xaj6c929hh8lzltl5ajjdzv7", - "nvaloper12xrk9wxmh7z4n5s5d8hk7zumn0hqu6z69a3e9f", - "nvaloper1undq3eavkylu7x8jzx208xgu7asze7xr2kurzp", - "nvaloper1thl5syhmscgnj7whdyrydw3w6vy80044kt2h0u", - ], - "tm.event": [ - "NewBlock", - ], - "transfer.amount": [ - "", - "", - ], - "transfer.recipient": [ - "n17xpfvakm2amg962yls6f84z3kell8c5lza5z5c", - "n1jv65s3grqf6v6jl3dp4t6c9t9rk99cd84mn7k6", - ], - "transfer.sender": [ - "n1m3h30wlvsf8llruxtpukdvsy0km2kum864s6c9", - "n17xpfvakm2amg962yls6f84z3kell8c5lza5z5c", - ], - }, - ), -} diff --git a/nym-validator-rewarder/src/config/mod.rs b/nym-validator-rewarder/src/config/mod.rs index 3ff795360a..bb416f0d08 100644 --- a/nym-validator-rewarder/src/config/mod.rs +++ b/nym-validator-rewarder/src/config/mod.rs @@ -10,9 +10,11 @@ use nym_config::{ DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME, DEFAULT_DATA_DIR, NYM_DIR, }; use nym_network_defaults::NymNetworkDetails; +use nym_validator_client::nyxd::Coin; use serde::{Deserialize, Serialize}; use std::io; use std::path::{Path, PathBuf}; +use std::time::Duration; use tracing::debug; use url::Url; use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -23,6 +25,12 @@ mod template; const DEFAULT_REWARDER_DIR: &str = "validators-rewarder"; +#[allow(clippy::inconsistent_digit_grouping)] +const DEFAULT_MIX_REWARDING_BUDGET: u128 = 1000_000000; +const DEFAULT_MIX_REWARDING_DENOM: &str = "unym"; + +const DEFAULT_EPOCH_DURATION: Duration = Duration::from_secs(60 * 60); + /// Get default path to rewarder's config directory. /// It should get resolved to `$HOME/.nym/validators-rewarder/config` pub fn default_config_directory() -> PathBuf { @@ -54,7 +62,8 @@ pub struct Config { #[zeroize(skip)] pub(crate) save_path: Option, - pub distribution: RewardingRatios, + #[zeroize(skip)] + pub rewarding: Rewarding, #[zeroize(skip)] pub nyxd_scraper: NyxdScraper, @@ -78,7 +87,7 @@ impl Config { Config { save_path: None, - distribution: RewardingRatios::default(), + rewarding: Rewarding::default(), nyxd_scraper: NyxdScraper { websocket_url: network.endpoints[0] .websocket_url() @@ -101,7 +110,7 @@ impl Config { } pub fn ensure_is_valid(&self) -> Result<(), NymRewarderError> { - self.distribution.ensure_is_valid()?; + self.rewarding.ratios.ensure_is_valid()?; Ok(()) } @@ -157,24 +166,48 @@ pub struct Base { pub(crate) mnemonic: bip39::Mnemonic, } -#[derive(Debug, Deserialize, Serialize, Zeroize, ZeroizeOnDrop)] +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct Rewarding { + /// + pub epoch_budget: Coin, + + #[serde(with = "humantime_serde")] + pub epoch_duration: Duration, + + pub ratios: RewardingRatios, +} + +impl Default for Rewarding { + fn default() -> Self { + Rewarding { + epoch_budget: Coin::new(DEFAULT_MIX_REWARDING_BUDGET, DEFAULT_MIX_REWARDING_DENOM), + epoch_duration: DEFAULT_EPOCH_DURATION, + ratios: RewardingRatios::default(), + } + } +} + +#[derive(Debug, Clone, Copy, Deserialize, Serialize)] pub struct RewardingRatios { /// The percent of the epoch reward being awarded for block signing. - pub block_signing: f32, + pub block_signing: f64, /// The percent of the epoch reward being awarded for credential issuance. - pub credential_issuance: f32, + pub credential_issuance: f64, + + /// The percent of the epoch reward being awarded for credential verification. + pub credential_verification: f64, /// The percent of the epoch reward given to Nym. - pub nym: f32, + pub nym: f64, } impl Default for RewardingRatios { fn default() -> Self { RewardingRatios { - // TODO: define proper defaults - block_signing: 67.0, - credential_issuance: 33.0, + block_signing: 0.67, + credential_issuance: 0.33, + credential_verification: 0.0, nym: 0.0, } } @@ -182,6 +215,11 @@ impl Default for RewardingRatios { impl RewardingRatios { pub fn ensure_is_valid(&self) -> Result<(), NymRewarderError> { + if self.block_signing + self.credential_verification + self.credential_issuance + self.nym + != 1.0 + { + todo!() + } Ok(()) } } diff --git a/nym-validator-rewarder/src/error.rs b/nym-validator-rewarder/src/error.rs index 655620cb68..c2309793a5 100644 --- a/nym-validator-rewarder/src/error.rs +++ b/nym-validator-rewarder/src/error.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only use nym_validator_client::nyxd::error::NyxdError; +use nym_validator_client::nyxd::tx::ErrorReport; use std::io; use std::path::PathBuf; use thiserror::Error; @@ -47,4 +48,15 @@ pub enum NymRewarderError { #[from] source: nyxd_scraper::error::ScraperError, }, + + // this should never happen but unwrapping everywhere was more cumbersome than just propagating the error + #[error("failed to determine epoch boundaries: {0}")] + TimeComponentFailure(#[from] time::error::ComponentRange), + + #[error("could not convert validators conesnsus address: {consensus_address} to a nym account address: {source}")] + MalformedBech32Address { + consensus_address: String, + #[source] + source: ErrorReport, + }, } diff --git a/nym-validator-rewarder/src/rewarder/block_signing.rs b/nym-validator-rewarder/src/rewarder/block_signing.rs new file mode 100644 index 0000000000..929db290a0 --- /dev/null +++ b/nym-validator-rewarder/src/rewarder/block_signing.rs @@ -0,0 +1,77 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use cosmwasm_std::{Decimal, Uint128}; +use nym_validator_client::nyxd::Coin; +use std::collections::HashMap; + +#[derive(Debug)] +pub struct ValidatorSigning { + pub consensus_address: String, + + pub voting_power_at_epoch_start: i64, + pub voting_power_ratio: Decimal, + + pub signed_blocks: i32, + pub ratio_signed: Decimal, +} + +#[derive(Debug)] +pub struct EpochSigning { + pub blocks: i64, + pub total_voting_power_at_epoch_start: i64, + + pub validators: Vec, +} + +impl EpochSigning { + pub fn construct( + blocks: i64, + total_vp: i64, + validator_results: HashMap, + ) -> Self { + assert!(total_vp >= 0, "negative voting power!"); + assert!(blocks >= 0, "negative blocks!"); + let total_vp_u64: u64 = total_vp.try_into().unwrap_or_default(); + let blocks_u64: u64 = blocks.try_into().unwrap_or_default(); + + let validators = validator_results + .into_iter() + .map( + |(consensus_address, (signed_blocks, voting_power_at_epoch_start))| { + let vp: u64 = voting_power_at_epoch_start.try_into().unwrap_or_default(); + let signed: u64 = signed_blocks.try_into().unwrap_or_default(); + + let voting_power_ratio = Decimal::from_ratio(vp, total_vp_u64); + let ratio_signed = Decimal::from_ratio(signed, blocks_u64); + + ValidatorSigning { + consensus_address, + voting_power_at_epoch_start, + voting_power_ratio, + signed_blocks, + ratio_signed, + } + }, + ) + .collect(); + + EpochSigning { + blocks, + total_voting_power_at_epoch_start: total_vp, + validators, + } + } + + pub fn rewarding_amounts(&self, budget: &Coin) -> HashMap { + let denom = &budget.denom; + self.validators + .iter() + .map(|v| { + let amount = Uint128::new(budget.amount) * v.ratio_signed * v.voting_power_ratio; + + (v.consensus_address.clone(), Coin::new(amount.u128(), denom)) + }) + .collect() + } +} diff --git a/nym-validator-rewarder/src/rewarder/epoch.rs b/nym-validator-rewarder/src/rewarder/epoch.rs new file mode 100644 index 0000000000..9d248f3fe6 --- /dev/null +++ b/nym-validator-rewarder/src/rewarder/epoch.rs @@ -0,0 +1,60 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::error::NymRewarderError; +use std::ops::Add; +use std::time::Duration; +use time::format_description::well_known::Rfc3339; +use time::OffsetDateTime; + +const HOUR: Duration = Duration::from_secs(60 * 60); + +pub struct Epoch { + pub id: i64, + + pub start: OffsetDateTime, + pub end: OffsetDateTime, +} + +impl Epoch { + pub const LENGTH: Duration = HOUR; + + pub fn first() -> Result { + let start = OffsetDateTime::now_utc() + .add(HOUR) + .replace_nanosecond(0)? + .replace_microsecond(0)? + .replace_second(0)?; + + Ok(Epoch { + id: 0, + start, + end: start + Self::LENGTH, + }) + } + + pub fn until_end(&self) -> Duration { + let now = OffsetDateTime::now_utc(); + (self.end - now).try_into().unwrap_or_default() + } + + pub fn next(&self) -> Self { + Epoch { + id: self.id + 1, + start: self.end, + end: self.end + Self::LENGTH, + } + } + + pub fn start_rfc3339(&self) -> String { + // safety: unwrap here is fine as we're using a predefined formatter + #[allow(clippy::unwrap_used)] + self.start.format(&Rfc3339).unwrap() + } + + pub fn end_rfc3339(&self) -> String { + // safety: unwrap here is fine as we're using a predefined formatter + #[allow(clippy::unwrap_used)] + self.end.format(&Rfc3339).unwrap() + } +} diff --git a/nym-validator-rewarder/src/rewarder/helpers.rs b/nym-validator-rewarder/src/rewarder/helpers.rs new file mode 100644 index 0000000000..f236d0ff5e --- /dev/null +++ b/nym-validator-rewarder/src/rewarder/helpers.rs @@ -0,0 +1,24 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::error::NymRewarderError; +use nym_validator_client::nyxd::AccountId; +use nyxd_scraper::constants::BECH32_PREFIX; + +pub(crate) fn consensus_address_to_account( + consensus_address: &str, +) -> Result { + let consensus_addr: AccountId = + consensus_address + .parse() + .map_err(|source| NymRewarderError::MalformedBech32Address { + consensus_address: consensus_address.to_string(), + source, + })?; + AccountId::new(BECH32_PREFIX, &consensus_addr.to_bytes()).map_err(|source| { + NymRewarderError::MalformedBech32Address { + consensus_address: consensus_address.to_string(), + source, + } + }) +} diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index a61924d1c2..946e460d00 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -3,15 +3,30 @@ use crate::config::Config; use crate::error::NymRewarderError; +use crate::rewarder::block_signing::EpochSigning; +use crate::rewarder::epoch::Epoch; +use crate::rewarder::helpers::consensus_address_to_account; use nym_network_defaults::NymNetworkDetails; use nym_task::TaskManager; +use nym_validator_client::nyxd::{AccountId, Coin}; use nyxd_scraper::NyxdScraper; +use std::cmp::min; +use std::collections::HashMap; +use std::ops::{Add, Range}; use std::time::Duration; -use tracing::info; +use time::format_description::well_known::Rfc3339; +use time::OffsetDateTime; +use tokio::time::{interval_at, Instant}; +use tracing::{debug, error, info, instrument}; +mod block_signing; +mod epoch; +mod helpers; mod tasks; pub struct Rewarder { + current_epoch: Epoch, + config: Config, nyxd_scraper: NyxdScraper, } @@ -21,31 +36,220 @@ impl Rewarder { let nyxd_scraper = NyxdScraper::new(config.scraper_config()).await?; Ok(Rewarder { + current_epoch: Epoch::first()?, config, nyxd_scraper, }) } + async fn get_voting_power( + &self, + address: &str, + height_range: Range, + ) -> Result, NymRewarderError> { + for height in height_range { + if let Some(precommit) = self + .nyxd_scraper + .storage + .get_precommit(address, height) + .await? + { + return Ok(Some(precommit.voting_power)); + } + } + + Ok(None) + } + + async fn get_signed_blocks(&self) -> Result { + info!( + "looking up block signers for epoch {} ({} - {})", + self.current_epoch.id, + self.current_epoch.start_rfc3339(), + self.current_epoch.end_rfc3339() + ); + + let validators = self.nyxd_scraper.storage.get_all_known_validators().await?; + let epoch_start = self.current_epoch.start; + let epoch_end = self.current_epoch.end; + let first_block = self + .nyxd_scraper + .storage + .get_first_block_height_after(epoch_start) + .await? + .unwrap_or_default(); + let last_block = self + .nyxd_scraper + .storage + .get_last_block_height_before(epoch_end) + .await? + .unwrap_or_default(); + + // each validator MUST be online at some point during the first 20 blocks, otherwise they're not getting anything. + let vp_range_end = min(first_block + 20, last_block); + let vp_range = first_block..vp_range_end; + + let mut total_vp = 0; + let mut signed_in_epoch = HashMap::new(); + for validator in validators { + let Some(vp) = self + .get_voting_power(&validator.consensus_address, vp_range.clone()) + .await? + else { + continue; + }; + total_vp += vp; + + let signed = self + .nyxd_scraper + .storage + .get_signed_between_times(&validator.consensus_address, epoch_start, epoch_end) + .await?; + signed_in_epoch.insert(validator.consensus_address, (signed, vp)); + } + + let total = self + .nyxd_scraper + .storage + .get_blocks_between(epoch_start, epoch_end) + .await?; + + Ok(EpochSigning::construct(total, total_vp, signed_in_epoch)) + } + + #[instrument(skip(self,budget), fields(budget = %budget))] + + async fn calculate_block_signing_rewards( + &mut self, + budget: Coin, + ) -> Result, NymRewarderError> { + info!("calculating reward shares"); + let signed = self.get_signed_blocks().await?; + + debug!("details: {signed:?}"); + + Ok(signed.rewarding_amounts(&budget)) + } + + #[instrument(skip(self,budget), fields(budget = %budget))] + async fn calculate_credential_rewards( + &mut self, + budget: Coin, + ) -> Result, NymRewarderError> { + info!("calculating reward shares"); + Ok(HashMap::new()) + } + + async fn determine_epoch_rewards( + &mut self, + ) -> Result, NymRewarderError> { + let epoch_budget = &self.config.rewarding.epoch_budget; + let denom = &epoch_budget.denom; + let signing_budget = Coin::new( + (self.config.rewarding.ratios.block_signing * epoch_budget.amount as f64) as u128, + denom, + ); + let credential_budget = Coin::new( + (self.config.rewarding.ratios.credential_issuance * epoch_budget.amount as f64) as u128, + denom, + ); + + let signing_rewards = self.calculate_block_signing_rewards(signing_budget).await?; + let credential_rewards = self.calculate_credential_rewards(credential_budget).await?; + + let mut rewards = HashMap::new(); + for (validator, amount) in signing_rewards { + let account = consensus_address_to_account(&validator)?; + rewards.insert(validator, (account, amount)); + } + + for (validator, amount) in credential_rewards { + let account = consensus_address_to_account(&validator)?; + + if let Some(existing) = rewards.get_mut(&validator) { + assert_eq!(existing.0, account); + existing.1.amount += amount.amount; + } else { + rewards.insert(validator, (account, amount)); + } + } + + Ok(rewards) + } + + async fn send_rewards( + &self, + amounts: HashMap, + ) -> Result<(), NymRewarderError> { + Ok(()) + } + + async fn handle_epoch_end(&mut self) { + info!("handling the epoch end"); + + let rewards = match self.determine_epoch_rewards().await { + Ok(rewards) => rewards, + Err(err) => { + error!("failed to determine epoch rewards: {err}"); + return; + } + }; + + /* + + let budget = Coin::new(667_000_000, "unym"); + let rewards = foo.rewarding_amounts(&budget); + + println!("{rewards:#?}"); + 666_378_383 + let bar: u128 = rewards.into_values().map(|v| v.amount).sum(); + println!("summed: {bar}"); + + */ + self.current_epoch = self.current_epoch.next(); + } + pub async fn run(mut self) -> Result<(), NymRewarderError> { info!("Starting nym validators rewarder"); // setup shutdowns - let task_manager = TaskManager::new(5); + let mut task_manager = TaskManager::new(5); self.nyxd_scraper.start().await?; + // + // tokio::time::sleep(Duration::from_secs(3000)).await; - tokio::time::sleep(Duration::from_secs(3000)).await; + // rewarding epochs last from :00 to :00 + self.current_epoch.end = OffsetDateTime::now_utc(); + self.current_epoch.start = self.current_epoch.end - Duration::from_secs(60 * 60); + + println!("sleepiing for 60"); + tokio::time::sleep(Duration::from_secs(60)).await; + + let until_end = self.current_epoch.until_end(); + + info!( + "the first epoch will finish in {} secs", + until_end.as_secs() + ); + let mut epoch_ticker = interval_at(Instant::now().add(until_end), Epoch::LENGTH); loop { tokio::select! { biased; - interrupted = task_manager.catch_interrupt() => { - todo!() + interrupt_res = task_manager.catch_interrupt() => { + info!("received interrupt"); + if let Err(err) = interrupt_res { + error!("runtime interrupt failure: {err}") + } + break; } - + _ = epoch_ticker.tick() => self.handle_epoch_end().await } } + self.nyxd_scraper.stop().await; + /* task 1: on timer: @@ -60,8 +264,30 @@ impl Rewarder { */ - self.nyxd_scraper.stop().await; - todo!() } } + +fn val_to_nym(addr: &str) -> String { + let foo: AccountId = addr.parse().unwrap(); + let bar = AccountId::new("n", &foo.to_bytes()).unwrap(); + bar.to_string() +} + +#[cfg(test)] +mod tests { + use super::*; + use std::str::FromStr; + + #[test] + fn aaa() { + let addr = AccountId::from_str("nvaloper18xr68spwm96vvehuvwf6ay9er0gd7q7ae8w8ns").unwrap(); + println!("{}", AccountId::new("n", &addr.to_bytes()).unwrap()); + println!("{}", AccountId::new("nvaloper", &addr.to_bytes()).unwrap()); + println!("{}", AccountId::new("nvalcons", &addr.to_bytes()).unwrap()); + // println!("{}", AccountId::new("n", &addr.to_bytes()).unwrap()); + + // let b = val_to_nym("nvaloper1q8cnx8s06q7ralnskqvj0acvqgacau6djqkm3z"); + // println!("{b}"); + } +} diff --git a/nym-validator-rewarder/src/rewarder/tasks/block_watcher.rs b/nym-validator-rewarder/src/rewarder/tasks/block_watcher.rs deleted file mode 100644 index c4a77ff737..0000000000 --- a/nym-validator-rewarder/src/rewarder/tasks/block_watcher.rs +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: GPL-3.0-only - -// sure, we could subscribe to new block events and watch for signing of every single block -// but realistically we don't need that kind of accuracy so just checking the VP every few minutes is enough diff --git a/nym-validator-rewarder/src/rewarder/tasks/mod.rs b/nym-validator-rewarder/src/rewarder/tasks/mod.rs index c6656f2a73..af282c5deb 100644 --- a/nym-validator-rewarder/src/rewarder/tasks/mod.rs +++ b/nym-validator-rewarder/src/rewarder/tasks/mod.rs @@ -1,4 +1,2 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only - -pub mod block_watcher; From 2c2223947cb6509e8bb8e04277c7cf7301e2dc90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 13 Dec 2023 16:47:25 +0000 Subject: [PATCH 06/21] wip --- Cargo.lock | 1275 +++++++++-------- Cargo.toml | 2 +- .../module_traits/staking/query.rs | 133 +- .../validator-client/src/nyxd/mod.rs | 7 +- common/nyxd-scraper/src/lib.rs | 1 + common/nyxd-scraper/src/storage/mod.rs | 2 +- common/nyxd-scraper/src/storage/models.rs | 2 +- nym-connect/desktop/Cargo.lock | 6 +- nym-validator-rewarder/Cargo.toml | 4 + nym-validator-rewarder/src/config/mod.rs | 6 + .../src/rewarder/block_signing.rs | 13 +- nym-validator-rewarder/src/rewarder/mod.rs | 146 +- nym-wallet/Cargo.lock | 41 +- 13 files changed, 915 insertions(+), 723 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3fb552cc7c..fd683e5250 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,8 +35,8 @@ dependencies = [ "actix-rt", "actix-service", "actix-utils", - "ahash 0.8.3", - "base64 0.21.4", + "ahash 0.8.6", + "base64 0.21.5", "bitflags 2.4.1", "brotli", "bytes", @@ -71,7 +71,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -109,7 +109,7 @@ dependencies = [ "futures-core", "futures-util", "mio", - "socket2 0.5.4", + "socket2 0.5.5", "tokio", "tracing", ] @@ -150,7 +150,7 @@ dependencies = [ "actix-service", "actix-utils", "actix-web-codegen", - "ahash 0.8.3", + "ahash 0.8.6", "bytes", "bytestring", "cfg-if", @@ -170,7 +170,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "smallvec", - "socket2 0.5.4", + "socket2 0.5.5", "time", "url", ] @@ -184,7 +184,7 @@ dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -316,25 +316,26 @@ dependencies = [ [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.11", "once_cell", "version_check", ] [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" dependencies = [ "cfg-if", - "getrandom 0.2.10", + "getrandom 0.2.11", "once_cell", "version_check", + "zerocopy", ] [[package]] @@ -386,7 +387,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c494134f746c14dc653a35a4ea5aca24ac368529da5370ecf41fe0341c35772f" dependencies = [ "android_log-sys", - "env_logger 0.10.0", + "env_logger 0.10.1", "log", "once_cell", ] @@ -408,9 +409,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" dependencies = [ "anstyle", "anstyle-parse", @@ -428,30 +429,30 @@ checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -483,9 +484,9 @@ dependencies = [ [[package]] name = "array-bytes" -version = "6.1.0" +version = "6.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b1c5a481ec30a5abd8dfbd94ab5cf1bb4e9a66be7f1b3b322f2f1170c200fd" +checksum = "6f840fb7195bcfc5e17ea40c26e5ce6d5b9ce5d584466e17703209657e459ae0" [[package]] name = "arrayref" @@ -585,7 +586,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" dependencies = [ "concurrent-queue", - "event-listener", + "event-listener 2.5.3", "futures-core", ] @@ -601,31 +602,32 @@ dependencies = [ [[package]] name = "async-io" -version = "1.13.0" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +checksum = "6afaa937395a620e33dc6a742c593c01aced20aa376ffb0f628121198578ccc7" dependencies = [ "async-lock", - "autocfg 1.1.0", "cfg-if", "concurrent-queue", - "futures-lite", - "log", + "futures-io", + "futures-lite 2.1.0", "parking", - "polling", - "rustix 0.37.25", + "polling 3.3.1", + "rustix", "slab", - "socket2 0.4.9", - "waker-fn", + "tracing", + "windows-sys 0.52.0", ] [[package]] name = "async-lock" -version = "2.8.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +checksum = "7125e42787d53db9dd54261812ef17e937c95a51e4d291373b670342fa44310c" dependencies = [ - "event-listener", + "event-listener 4.0.0", + "event-listener-strategy", + "pin-project-lite 0.2.13", ] [[package]] @@ -647,7 +649,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -658,7 +660,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -836,9 +838,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.4" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" @@ -1025,9 +1027,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "2.5.0" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da74e2b81409b1b743f8f0c62cc6254afefb8b8e50bbfe3735550f7aeefa3448" +checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -1093,9 +1095,9 @@ dependencies = [ [[package]] name = "bytestring" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238e4886760d98c4f899360c834fa93e62cf7f721ac3c2da375cbdf4b8679aae" +checksum = "74d80203ea6b29df88012294f62733de21cfeab47f17b41af3a38bc30a03ee72" dependencies = [ "bytes", ] @@ -1117,7 +1119,7 @@ checksum = "f769ab9e8c1652d78dd0b3ec59cdaa1e2bcb3b6b39f6681b256abcdbe101cc14" dependencies = [ "anyhow", "cargo_metadata", - "clap 4.4.7", + "clap 4.4.11", "concolor-control", "crates-index", "dirs-next", @@ -1142,9 +1144,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12024c4645c97566567129c204f65d5815a8c9aecf30fcbe682b2fe034996d36" +checksum = "e34637b3140142bdf929fb439e8aa4ebad7651ebf7b1080b3930aa16ac1459ff" dependencies = [ "serde", ] @@ -1218,18 +1220,6 @@ dependencies = [ "keystream", ] -[[package]] -name = "chacha20" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c80e5460aa66fe3b91d40bcbdab953a597b60053e34d684ac6903f863b680a6" -dependencies = [ - "cfg-if", - "cipher 0.3.0", - "cpufeatures", - "zeroize", -] - [[package]] name = "chacha20" version = "0.9.1" @@ -1241,19 +1231,6 @@ dependencies = [ "cpufeatures", ] -[[package]] -name = "chacha20poly1305" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18446b09be63d457bbec447509e85f662f32952b035ce892290396bc0b0cff5" -dependencies = [ - "aead 0.4.3", - "chacha20 0.8.2", - "cipher 0.3.0", - "poly1305 0.7.2", - "zeroize", -] - [[package]] name = "chacha20poly1305" version = "0.10.1" @@ -1261,9 +1238,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ "aead 0.5.2", - "chacha20 0.9.1", + "chacha20", "cipher 0.4.4", - "poly1305 0.8.0", + "poly1305", "zeroize", ] @@ -1352,9 +1329,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.7" +version = "4.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" +checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" dependencies = [ "clap_builder", "clap_derive", @@ -1362,9 +1339,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.7" +version = "4.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" +checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" dependencies = [ "anstream", "anstyle", @@ -1375,20 +1352,20 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.4.3" +version = "4.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ae8ba90b9d8b007efe66e55e48fb936272f5ca00349b5b0e89877520d35ea7" +checksum = "bffe91f06a11b4b9420f62103854e90867812cd5d01557f853c5ee8e791b12ae" dependencies = [ - "clap 4.4.7", + "clap 4.4.11", ] [[package]] name = "clap_complete_fig" -version = "4.4.1" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29bdbe21a263b628f83fcbeac86a4416a1d588c7669dd41473bc4149e4e7d2f1" +checksum = "87e571d70e22ec91d34e1c5317c8308035a2280d925167646bf094fc5de1737c" dependencies = [ - "clap 4.4.7", + "clap 4.4.11", "clap_complete", ] @@ -1401,7 +1378,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -1436,11 +1413,10 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "colored" -version = "2.0.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" dependencies = [ - "is-terminal", "lazy_static", "windows-sys 0.48.0", ] @@ -1486,18 +1462,18 @@ checksum = "ad159cc964ac8f9d407cbc0aa44b02436c054b541f2b4b5f06972e1efdc54bc7" [[package]] name = "concurrent-queue" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f057a694a54f12365049b0958a1685bb52d567f5593b355fbf685838e873d400" +checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" dependencies = [ "crossbeam-utils", ] [[package]] name = "config" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7" +checksum = "23738e11972c7643e4ec947840fc463b6a571afcd3e735bdfce7d03c7a784aca" dependencies = [ "async-trait", "lazy_static", @@ -1615,9 +1591,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -1625,9 +1601,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "core2" @@ -1644,8 +1620,8 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32560304ab4c365791fd307282f76637213d8083c1a98490c35159cd67852237" dependencies = [ - "prost 0.12.1", - "prost-types 0.12.1", + "prost 0.12.3", + "prost-types 0.12.3", "tendermint-proto", ] @@ -1654,8 +1630,8 @@ name = "cosmos-sdk-proto" version = "0.20.0" source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features#41ed4631e146268b0300033c8bbb993d79a49f58" dependencies = [ - "prost 0.12.1", - "prost-types 0.12.1", + "prost 0.12.3", + "prost-types 0.12.3", "tendermint-proto", ] @@ -1667,13 +1643,13 @@ checksum = "47126f5364df9387b9d8559dcef62e99010e1d4098f39eb3f7ee4b5c254e40ea" dependencies = [ "bip32", "cosmos-sdk-proto 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ecdsa 0.16.8", + "ecdsa 0.16.9", "eyre", "k256", "rand_core 0.6.4", "serde", "serde_json", - "signature 2.1.0", + "signature 2.2.0", "subtle-encoding", "tendermint", "thiserror", @@ -1686,13 +1662,13 @@ source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-valida dependencies = [ "bip32", "cosmos-sdk-proto 0.20.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", - "ecdsa 0.16.8", + "ecdsa 0.16.9", "eyre", "k256", "rand_core 0.6.4", "serde", "serde_json", - "signature 2.1.0", + "signature 2.2.0", "subtle-encoding", "tendermint", "tendermint-rpc", @@ -1701,11 +1677,12 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6fb22494cf7d23d0c348740e06e5c742070b2991fd41db77bba0bcfbae1a723" +checksum = "d8bb3c77c3b7ce472056968c745eb501c440fbc07be5004eba02782c35bfbbe3" dependencies = [ "digest 0.10.7", + "ecdsa 0.16.9", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -1714,9 +1691,9 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e199424486ea97d6b211db6387fd72e26b4a439d40cc23140b2d8305728055b" +checksum = "fea73e9162e6efde00018d55ed0061e93a108b5d6ec4548b4f8ce3c706249687" dependencies = [ "syn 1.0.109", ] @@ -1775,9 +1752,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] @@ -1814,9 +1791,9 @@ dependencies = [ [[package]] name = "crc-catalog" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] name = "crc32fast" @@ -1865,9 +1842,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "14c3242926edf34aec4ac3a77108ad4854bffaa2e4ddc1824124ce59231302d5" dependencies = [ "cfg-if", "crossbeam-utils", @@ -1875,9 +1852,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -1886,22 +1863,21 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.15" +version = "0.9.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "2d2fe95351b870527a5d09bf563ed3c97c0cffb87cf1c78a591bf48bb218d9aa" dependencies = [ "autocfg 1.1.0", "cfg-if", "crossbeam-utils", "memoffset 0.9.0", - "scopeguard", ] [[package]] name = "crossbeam-queue" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +checksum = "b9bcf5bdbfdd6030fb4a1c497b5d5fc5921aa2f60d359a17e249c0e6df3de153" dependencies = [ "cfg-if", "crossbeam-utils", @@ -1909,9 +1885,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f" dependencies = [ "cfg-if", ] @@ -1961,9 +1937,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array 0.14.7", "rand_core 0.6.4", @@ -2051,15 +2027,15 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "socket2 0.4.9", + "socket2 0.4.10", "winapi", ] [[package]] name = "curl-sys" -version = "0.4.68+curl-8.4.0" +version = "0.4.70+curl-8.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4a0d18d88360e374b16b2273c832b5e57258ffc1d4aa4f96b108e0738d5752f" +checksum = "3c0333d8849afe78a4c8102a429a446bfdd055832af071945520e835ae2d841e" dependencies = [ "cc", "libc", @@ -2103,13 +2079,13 @@ dependencies = [ [[package]] name = "curve25519-dalek-derive" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -2298,7 +2274,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.1", + "hashbrown 0.14.3", "lock_api", "once_cell", "parking_lot_core 0.9.9", @@ -2306,15 +2282,15 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "data-encoding-macro" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c904b33cc60130e1aeea4956ab803d08a3f4a0ca82d64ed757afac3891f2bb99" +checksum = "20c01c06f5f429efdf2bae21eb67c28b3df3cf85b7dd2d8ef09c0838dac5d33e" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -2322,9 +2298,9 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fdf3fce3ce863539ec1d7fd1b6dcc3c645663376b43ed376bbf887733e4f772" +checksum = "0047d07f2c89b17dd631c80450d69841a6b5d7fb17278cbc43d7e4cfcf2576f3" dependencies = [ "data-encoding", "syn 1.0.109", @@ -2335,7 +2311,7 @@ name = "defguard_wireguard_rs" version = "0.3.0" source = "git+https://github.com/neacsu/wireguard-rs.git?rev=c2cd0c1119f699f4bc43f5e6ffd6fc242caa42ed#c2cd0c1119f699f4bc43f5e6ffd6fc242caa42ed" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", "libc", "log", "netlink-packet-core 0.7.0", @@ -2400,9 +2376,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" dependencies = [ "powerfmt", "serde", @@ -2493,7 +2469,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -2596,7 +2572,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -2625,9 +2601,9 @@ checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" [[package]] name = "dyn-clone" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" [[package]] name = "ecdsa" @@ -2643,16 +2619,16 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.16.8" +version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der 0.7.8", "digest 0.10.7", - "elliptic-curve 0.13.6", + "elliptic-curve 0.13.7", "rfc6979 0.4.0", - "signature 2.1.0", - "spki 0.7.2", + "signature 2.2.0", + "spki 0.7.3", ] [[package]] @@ -2672,7 +2648,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ "pkcs8 0.10.2", - "signature 2.1.0", + "signature 2.2.0", ] [[package]] @@ -2705,15 +2681,16 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" dependencies = [ "curve25519-dalek 4.1.1", "ed25519 2.2.3", "rand_core 0.6.4", "serde", "sha2 0.10.8", + "subtle 2.4.1", "zeroize", ] @@ -2751,7 +2728,7 @@ dependencies = [ "ff 0.12.1", "generic-array 0.14.7", "group 0.12.1", - "hkdf 0.12.3", + "hkdf 0.12.4", "pem-rfc7468", "pkcs8 0.9.0", "rand_core 0.6.4", @@ -2762,12 +2739,12 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.6" +version = "0.13.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" +checksum = "e9775b22bc152ad86a0cf23f0f348b884b26add12bf741e7ffc4d4ab2ab4d205" dependencies = [ "base16ct 0.2.0", - "crypto-bigint 0.5.3", + "crypto-bigint 0.5.5", "digest 0.10.7", "ff 0.13.0", "generic-array 0.14.7", @@ -2817,7 +2794,7 @@ checksum = "eecf8589574ce9b895052fa12d69af7a233f99e6107f5cb8dd1044f2a17bfdcb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -2835,9 +2812,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" dependencies = [ "log", "regex", @@ -2868,7 +2845,7 @@ dependencies = [ "bytes", "cfg-if", "chrono", - "clap 4.4.7", + "clap 4.4.11", "config", "digest 0.10.7", "dirs 5.0.1", @@ -2876,7 +2853,7 @@ dependencies = [ "futures", "futures-util", "lazy_static", - "libp2p 0.51.3", + "libp2p 0.51.4", "libp2p-identity", "log", "lru 0.10.1", @@ -2899,7 +2876,7 @@ dependencies = [ "unsigned-varint", "utoipa", "utoipa-swagger-ui", - "uuid 1.5.0", + "uuid 1.6.1", ] [[package]] @@ -2910,12 +2887,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2933,12 +2910,33 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +[[package]] +name = "event-listener" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "770d968249b5d99410d61f5bf89057f3199a077a04d087092f58e7d10692baae" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite 0.2.13", +] + +[[package]] +name = "event-listener-strategy" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +dependencies = [ + "event-listener 4.0.0", + "pin-project-lite 0.2.13", +] + [[package]] name = "explorer-api" version = "1.1.32" dependencies = [ "chrono", - "clap 4.4.7", + "clap 4.4.11", "dotenvy", "humantime-serde", "isocountry", @@ -3074,34 +3072,34 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.1" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d" +checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" [[package]] name = "figment" -version = "0.10.11" +version = "0.10.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a014ac935975a70ad13a3bff2463b1c1b083b35ae4cb6309cfc59476aa7a181f" +checksum = "649f3e5d826594057e9a519626304d8da859ea8a0b18ce99500c586b8d45faee" dependencies = [ "atomic 0.6.0", "pear", "serde", - "toml 0.8.2", + "toml 0.8.8", "uncased", "version_check", ] [[package]] name = "filetime" -version = "0.2.22" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", - "windows-sys 0.48.0", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", ] [[package]] @@ -3172,9 +3170,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -3208,9 +3206,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" dependencies = [ "futures-channel", "futures-core", @@ -3223,9 +3221,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" dependencies = [ "futures-core", "futures-sink", @@ -3233,15 +3231,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" dependencies = [ "futures-core", "futures-task", @@ -3262,9 +3260,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" [[package]] name = "futures-lite" @@ -3282,14 +3280,24 @@ dependencies = [ ] [[package]] -name = "futures-macro" -version = "0.3.28" +name = "futures-lite" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "aeee267a1883f7ebef3700f262d2d54de95dfaf38189015a74fdc4e0c7ad8143" +dependencies = [ + "futures-core", + "pin-project-lite 0.2.13", +] + +[[package]] +name = "futures-macro" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -3305,15 +3313,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" [[package]] name = "futures-timer" @@ -3323,9 +3331,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" dependencies = [ "futures-channel", "futures-core", @@ -3394,9 +3402,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", "js-sys", @@ -3439,20 +3447,20 @@ dependencies = [ [[package]] name = "ghost" -version = "0.1.14" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba330b70a5341d3bc730b8e205aaee97ddab5d9c448c4f51a7c2d924266fa8f9" +checksum = "ef81e7cedce6ab54cd5dc7b3400c442c8d132fe03200a1be0637db7ef308ff17" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] name = "gimli" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "git2" @@ -3545,9 +3553,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.21" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" dependencies = [ "bytes", "fnv", @@ -3555,7 +3563,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap 2.1.0", "slab", "tokio", "tokio-util", @@ -3588,7 +3596,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.7", ] [[package]] @@ -3597,7 +3605,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.7", ] [[package]] @@ -3606,16 +3614,16 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.6", ] [[package]] name = "hashbrown" -version = "0.14.1" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.6", "allocator-api2", ] @@ -3634,16 +3642,16 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "hashbrown 0.14.1", + "hashbrown 0.14.3", ] [[package]] name = "hdrhistogram" -version = "7.5.2" +version = "7.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f19b9f54f7c7f55e31401bb647626ce0cf0f67b0004982ce815b3ee72a02aa8" +checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" dependencies = [ - "base64 0.13.1", + "base64 0.21.5", "byteorder", "flate2", "nom", @@ -3728,9 +3736,9 @@ dependencies = [ [[package]] name = "hkdf" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ "hmac 0.12.1", ] @@ -3776,9 +3784,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", @@ -3801,9 +3809,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http", @@ -3880,7 +3888,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite 0.2.13", - "socket2 0.4.9", + "socket2 0.4.10", "tokio", "tower-service", "tracing", @@ -3889,14 +3897,14 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http", "hyper", - "rustls 0.21.7", + "rustls 0.21.10", "tokio", "tokio-rustls 0.24.1", ] @@ -3968,9 +3976,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -3978,19 +3986,19 @@ dependencies = [ [[package]] name = "if-addrs" -version = "0.7.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc0fa01ffc752e9dbc72818cdb072cd028b86be5e09dd04c5a643704fe101a9" +checksum = "cabb0019d51a643781ff15c9c8a3e5dedc365c47211270f4e8f82812fedd8f0a" dependencies = [ "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] name = "if-watch" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb892e5777fe09e16f3d44de7802f4daa7267ecbe8c466f19d94e25bb0c303e" +checksum = "d6b0422c86d7ce0e97169cc42e04ae643caf278874a7a3c87b8150a220dc7e1e" dependencies = [ "async-io", "core-foundation", @@ -4019,7 +4027,7 @@ checksum = "bfbcff6ae46750b15cc594bfd277b188cbddcfdc1817848f97f03f26f8625b9e" dependencies = [ "cfg-if", "js-sys", - "uuid 1.5.0", + "uuid 1.6.1", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -4038,12 +4046,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown 0.14.1", + "hashbrown 0.14.3", "serde", ] @@ -4138,17 +4146,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi 0.3.3", - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "ip_network" version = "0.4.1" @@ -4161,7 +4158,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2 0.5.4", + "socket2 0.5.5", "widestring", "windows-sys 0.48.0", "winreg", @@ -4169,9 +4166,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "ipnetwork" @@ -4207,7 +4204,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi 0.3.3", - "rustix 0.38.19", + "rustix", "windows-sys 0.48.0", ] @@ -4222,12 +4219,12 @@ dependencies = [ "crossbeam-utils", "curl", "curl-sys", - "event-listener", - "futures-lite", + "event-listener 2.5.3", + "futures-lite 1.13.0", "http", "log", "once_cell", - "polling", + "polling 2.8.0", "slab", "sluice", "tracing", @@ -4275,9 +4272,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jni" @@ -4312,25 +4309,25 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" dependencies = [ "wasm-bindgen", ] [[package]] name = "k256" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +checksum = "3f01b677d82ef7a676aa37e099defd83a28e15687112cafdd112d60236b6115b" dependencies = [ "cfg-if", - "ecdsa 0.16.8", - "elliptic-curve 0.13.6", + "ecdsa 0.16.9", + "elliptic-curve 0.13.7", "once_cell", "sha2 0.10.8", - "signature 2.1.0", + "signature 2.2.0", ] [[package]] @@ -4430,9 +4427,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.149" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "libgit2-sys" @@ -4462,7 +4459,7 @@ dependencies = [ "bytes", "futures", "futures-timer", - "getrandom 0.2.10", + "getrandom 0.2.11", "instant", "libp2p-core 0.39.0", "libp2p-dns 0.39.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", @@ -4476,7 +4473,7 @@ dependencies = [ "libp2p-quic 0.7.0-alpha.2", "libp2p-swarm 0.42.0", "libp2p-tcp 0.39.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", - "libp2p-webrtc 0.4.0-alpha.2", + "libp2p-webrtc", "libp2p-websocket", "libp2p-yamux 0.43.0", "multiaddr 0.17.0", @@ -4485,14 +4482,14 @@ dependencies = [ [[package]] name = "libp2p" -version = "0.51.3" +version = "0.51.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f210d259724eae82005b5c48078619b7745edb7b76de370b03f8ba59ea103097" +checksum = "f35eae38201a993ece6bdc823292d6abd1bffed1c4d0f4a3517d2bd8e1d917fe" dependencies = [ "bytes", "futures", "futures-timer", - "getrandom 0.2.10", + "getrandom 0.2.11", "instant", "libp2p-allow-block-list", "libp2p-connection-limits", @@ -4508,7 +4505,6 @@ dependencies = [ "libp2p-request-response", "libp2p-swarm 0.42.2", "libp2p-tcp 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-webrtc 0.4.0-alpha.4", "libp2p-yamux 0.43.1", "multiaddr 0.17.1", "pin-project", @@ -4633,7 +4629,7 @@ version = "0.44.0" source = "git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6#e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6" dependencies = [ "asynchronous-codec", - "base64 0.21.4", + "base64 0.21.5", "byteorder", "bytes", "fnv", @@ -4663,7 +4659,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70b34b6da8165c0bde35c82db8efda39b824776537e73973549e76cadb3a77c5" dependencies = [ "asynchronous-codec", - "base64 0.21.4", + "base64 0.21.5", "byteorder", "bytes", "either", @@ -4717,7 +4713,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "276bb57e7af15d8f100d3c11cbdd32c6752b7eef4ba7a18ecf464972c07abcce" dependencies = [ "bs58 0.4.0", - "ed25519-dalek 2.0.0", + "ed25519-dalek 2.1.0", "log", "multiaddr 0.17.1", "multihash", @@ -4771,7 +4767,7 @@ dependencies = [ "log", "rand 0.8.5", "smallvec", - "socket2 0.4.9", + "socket2 0.4.10", "tokio", "trust-dns-proto", "void", @@ -4792,7 +4788,7 @@ dependencies = [ "log", "rand 0.8.5", "smallvec", - "socket2 0.4.9", + "socket2 0.4.10", "tokio", "trust-dns-proto", "void", @@ -5033,7 +5029,7 @@ dependencies = [ "libc", "libp2p-core 0.39.2", "log", - "socket2 0.4.9", + "socket2 0.4.10", "tokio", ] @@ -5048,7 +5044,7 @@ dependencies = [ "libc", "libp2p-core 0.39.0", "log", - "socket2 0.4.9", + "socket2 0.4.10", "tokio", ] @@ -5118,37 +5114,6 @@ dependencies = [ "webrtc", ] -[[package]] -name = "libp2p-webrtc" -version = "0.4.0-alpha.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dba48592edbc2f60b4bc7c10d65445b0c3964c07df26fdf493b6880d33be36f8" -dependencies = [ - "async-trait", - "asynchronous-codec", - "bytes", - "futures", - "futures-timer", - "hex", - "if-watch", - "libp2p-core 0.39.2", - "libp2p-identity", - "libp2p-noise 0.42.2", - "log", - "multihash", - "quick-protobuf", - "quick-protobuf-codec", - "rand 0.8.5", - "rcgen 0.9.3", - "serde", - "stun", - "thiserror", - "tinytemplate", - "tokio", - "tokio-util", - "webrtc", -] - [[package]] name = "libp2p-websocket" version = "0.41.0" @@ -5192,6 +5157,17 @@ dependencies = [ "yamux", ] +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.1", + "libc", + "redox_syscall 0.4.1", +] + [[package]] name = "libsqlite3-sys" version = "0.24.2" @@ -5237,15 +5213,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.3.8" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - -[[package]] -name = "linux-raw-sys" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] name = "lioness" @@ -5261,9 +5231,9 @@ dependencies = [ [[package]] name = "local-channel" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a493488de5f18c8ffcba89eebb8532ffc562dc400490eb65b84893fae0b178" +checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8" dependencies = [ "futures-core", "futures-sink", @@ -5272,9 +5242,9 @@ dependencies = [ [[package]] name = "local-waker" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1" +checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" [[package]] name = "lock_api" @@ -5456,9 +5426,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "log", @@ -5911,7 +5881,7 @@ dependencies = [ "bs58 0.4.0", "cfg-if", "chrono", - "clap 4.4.7", + "clap 4.4.11", "console-subscriber", "cosmwasm-std", "cw-utils", @@ -5976,7 +5946,7 @@ dependencies = [ "tokio-stream", "ts-rs", "url", - "uuid 1.5.0", + "uuid 1.6.1", "zeroize", ] @@ -6020,7 +5990,7 @@ name = "nym-bin-common" version = "0.6.0" dependencies = [ "atty", - "clap 4.4.7", + "clap 4.4.11", "clap_complete", "clap_complete_fig", "log", @@ -6061,7 +6031,7 @@ dependencies = [ "base64 0.13.1", "bip39", "bs58 0.4.0", - "clap 4.4.7", + "clap 4.4.11", "clap_complete", "clap_complete_fig", "dotenvy", @@ -6086,7 +6056,7 @@ dependencies = [ "bip39", "bs58 0.4.0", "cfg-if", - "clap 4.4.7", + "clap 4.4.11", "comfy-table", "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", @@ -6130,7 +6100,7 @@ dependencies = [ name = "nym-client" version = "1.1.32" dependencies = [ - "clap 4.4.7", + "clap 4.4.11", "dirs 4.0.0", "futures", "lazy_static", @@ -6167,9 +6137,9 @@ name = "nym-client-core" version = "1.1.15" dependencies = [ "async-trait", - "base64 0.21.4", + "base64 0.21.5", "cfg-if", - "clap 4.4.7", + "clap 4.4.11", "dashmap", "dirs 4.0.0", "futures", @@ -6254,7 +6224,7 @@ dependencies = [ "digest 0.9.0", "doc-comment", "ff 0.13.0", - "getrandom 0.2.10", + "getrandom 0.2.11", "group 0.13.0", "itertools 0.10.5", "nym-dkg", @@ -6380,7 +6350,7 @@ dependencies = [ "digest 0.10.7", "ed25519-dalek 1.0.1", "generic-array 0.14.7", - "hkdf 0.12.3", + "hkdf 0.12.4", "hmac 0.12.1", "nym-pemstore", "nym-sphinx-types", @@ -6481,7 +6451,7 @@ dependencies = [ "atty", "bip39", "bs58 0.4.0", - "clap 4.4.7", + "clap 4.4.11", "colored", "dashmap", "defguard_wireguard_rs", @@ -6536,7 +6506,7 @@ name = "nym-gateway-client" version = "0.1.0" dependencies = [ "futures", - "getrandom 0.2.10", + "getrandom 0.2.11", "gloo-utils", "log", "nym-bandwidth-controller", @@ -6690,7 +6660,7 @@ dependencies = [ "axum", "bs58 0.4.0", "cfg-if", - "clap 4.4.7", + "clap 4.4.11", "colored", "cpu-cycles", "cupid", @@ -6809,7 +6779,7 @@ dependencies = [ "async-file-watcher", "async-trait", "bs58 0.4.0", - "clap 4.4.7", + "clap 4.4.11", "dirs 4.0.0", "futures", "humantime-serde", @@ -6905,7 +6875,7 @@ name = "nym-node-requests" version = "0.1.0" dependencies = [ "async-trait", - "base64 0.21.4", + "base64 0.21.5", "http-api-client", "nym-bin-common", "nym-crypto", @@ -6973,7 +6943,7 @@ name = "nym-nr-query" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.4.7", + "clap 4.4.11", "log", "nym-bin-common", "nym-network-defaults", @@ -6997,12 +6967,12 @@ name = "nym-outfox" version = "0.1.0" dependencies = [ "blake3", - "chacha20 0.9.1", - "chacha20poly1305 0.10.1", + "chacha20", + "chacha20poly1305", "criterion", "curve25519-dalek 3.2.0", "fastrand 1.9.0", - "getrandom 0.2.10", + "getrandom 0.2.11", "log", "rand 0.7.3", "rayon", @@ -7098,7 +7068,7 @@ dependencies = [ name = "nym-socks5-client" version = "1.1.32" dependencies = [ - "clap 4.4.7", + "clap 4.4.11", "lazy_static", "log", "nym-bin-common", @@ -7381,7 +7351,7 @@ dependencies = [ "aes-gcm 0.10.3", "argon2", "generic-array 0.14.7", - "getrandom 0.2.10", + "getrandom 0.2.11", "rand 0.8.5", "serde", "serde_json", @@ -7443,7 +7413,7 @@ dependencies = [ name = "nym-types" version = "1.0.0" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", "eyre", @@ -7506,7 +7476,7 @@ dependencies = [ "nym-service-provider-directory-common", "nym-vesting-contract-common", "openssl", - "prost 0.12.1", + "prost 0.12.3", "reqwest", "serde", "serde_json", @@ -7526,7 +7496,7 @@ version = "0.1.0" dependencies = [ "anyhow", "bip39", - "clap 4.4.7", + "clap 4.4.11", "cosmwasm-std", "futures", "humantime-serde", @@ -7536,7 +7506,10 @@ dependencies = [ "nym-task", "nym-validator-client", "nyxd-scraper", + "reqwest", "serde", + "serde_json", + "sha2 0.10.8", "thiserror", "time", "tokio", @@ -7582,7 +7555,7 @@ dependencies = [ name = "nym-wireguard" version = "0.1.0" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", "defguard_wireguard_rs", "ip_network", "log", @@ -7597,7 +7570,7 @@ dependencies = [ name = "nym-wireguard-types" version = "0.1.0" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", "dashmap", "hmac 0.12.1", "log", @@ -7618,7 +7591,7 @@ dependencies = [ "anyhow", "async-file-watcher", "bytes", - "clap 4.4.7", + "clap 4.4.11", "dotenvy", "flate2", "futures", @@ -7704,9 +7677,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "oorandom" @@ -7728,9 +7701,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.57" +version = "0.10.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" +checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45" dependencies = [ "bitflags 2.4.1", "cfg-if", @@ -7749,7 +7722,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -7760,18 +7733,18 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.1.5+3.1.3" +version = "300.2.1+3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "559068e4c12950d7dcaa1857a61725c0d38d4fc03ff8e070ab31a75d6e316491" +checksum = "3fe476c29791a5ca0d1273c697e96085bbabbbea2ef7afd5617e78a4b40332d3" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.93" +version = "0.9.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" +checksum = "c3eaad34cdd97d81de97964fc7f29e2d104f483840d906ef56daa1912338460b" dependencies = [ "cc", "libc", @@ -8017,9 +7990,9 @@ dependencies = [ [[package]] name = "pear" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a386cd715229d399604b50d1361683fe687066f42d56f54be995bc6868f71c" +checksum = "4ccca0f6c17acc81df8e242ed473ec144cbf5c98037e69aa6d144780aad103c8" dependencies = [ "inlinable_string", "pear_codegen", @@ -8028,14 +8001,14 @@ dependencies = [ [[package]] name = "pear_codegen" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f0f13dac8069c139e8300a6510e3f4143ecf5259c60b116a9b271b4ca0d54" +checksum = "2e22670e8eb757cff11d6c199ca7b987f352f0346e0be4dd23869ec72cb53c77" dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -8096,15 +8069,15 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c022f1e7b65d6a24c0dbbd5fb344c66881bc01f3e5ae74a1c8100f2f985d98a4" +checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" dependencies = [ "memchr", "thiserror", @@ -8113,9 +8086,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35513f630d46400a977c4cb58f78e1bfbe01434316e60c37d27b9ad6139c66d8" +checksum = "81d78524685f5ef2a3b3bd1cafbc9fcabb036253d9b1463e726a91cd16e2dfc2" dependencies = [ "pest", "pest_generator", @@ -8123,22 +8096,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc9fc1b9e7057baba189b5c626e2d6f40681ae5b6eb064dc7c7834101ec8123a" +checksum = "68bd1206e71118b5356dae5ddc61c8b11e28b09ef6a31acbd15ea48a28e0c227" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] name = "pest_meta" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df74e9e7ec4053ceb980e7c0c8bd3594e977fde1af91daba9c928e8e8c6708d" +checksum = "7c747191d4ad9e4a4ab9c8798f1e82a39affe7ef9648390b7e5548d18e099de6" dependencies = [ "once_cell", "pest", @@ -8152,7 +8125,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.0.2", + "indexmap 2.1.0", ] [[package]] @@ -8172,7 +8145,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -8210,7 +8183,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der 0.7.8", - "spki 0.7.2", + "spki 0.7.3", ] [[package]] @@ -8221,9 +8194,9 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "platforms" -version = "3.1.2" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" +checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" [[package]] name = "plotters" @@ -8270,14 +8243,17 @@ dependencies = [ ] [[package]] -name = "poly1305" -version = "0.7.2" +name = "polling" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" +checksum = "cf63fa624ab313c11656b4cda960bfc46c410187ad493c41f6ba2d8c1e991c9e" dependencies = [ - "cpufeatures", - "opaque-debug 0.3.0", - "universal-hash 0.4.1", + "cfg-if", + "concurrent-queue", + "pin-project-lite 0.2.13", + "rustix", + "tracing", + "windows-sys 0.52.0", ] [[package]] @@ -8383,9 +8359,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -8398,7 +8374,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", "version_check", "yansi 1.0.0-rc.1", ] @@ -8423,7 +8399,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -8438,12 +8414,12 @@ dependencies = [ [[package]] name = "prost" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fdd22f3b9c31b53c060df4a0613a1c7f062d4115a2b984dd15b1858f7e340d" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" dependencies = [ "bytes", - "prost-derive 0.12.1", + "prost-derive 0.12.3", ] [[package]] @@ -8495,15 +8471,15 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "265baba7fabd416cf5078179f7d2cbeca4ce7a9041111900675ea7c4cb8a4c32" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" dependencies = [ "anyhow", "itertools 0.11.0", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -8517,11 +8493,11 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e081b29f63d83a4bc75cfc9f3fe424f9156cf92d8a4f0c9407cce9a1b67327cf" +checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" dependencies = [ - "prost 0.12.1", + "prost 0.12.3", ] [[package]] @@ -8716,7 +8692,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.11", ] [[package]] @@ -8881,15 +8857,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -8901,12 +8868,12 @@ dependencies = [ [[package]] name = "redox_users" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" dependencies = [ - "getrandom 0.2.10", - "redox_syscall 0.2.16", + "getrandom 0.2.11", + "libredox", "thiserror", ] @@ -8927,7 +8894,7 @@ checksum = "7f7473c2cfcf90008193dd0e3e16599455cb601a9fce322b5bb55de799664925" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -8971,7 +8938,7 @@ dependencies = [ "quote", "refinery-core", "regex", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -9024,7 +8991,7 @@ version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", "bytes", "encoding_rs", "futures-core", @@ -9043,7 +9010,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite 0.2.13", - "rustls 0.21.7", + "rustls 0.21.10", "rustls-native-certs", "rustls-pemfile", "serde", @@ -9112,12 +9079,12 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.4" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fce3045ffa7c981a6ee93f640b538952e155f1ae3a1a02b84547fc7a56b7059a" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" dependencies = [ "cc", - "getrandom 0.2.10", + "getrandom 0.2.11", "libc", "spin 0.9.8", "untrusted 0.9.0", @@ -9184,7 +9151,7 @@ dependencies = [ "proc-macro2", "quote", "rocket_http", - "syn 2.0.38", + "syn 2.0.41", "unicode-xid", ] @@ -9335,7 +9302,7 @@ dependencies = [ "quote", "rust-embed-utils", "shellexpand", - "syn 2.0.38", + "syn 2.0.41", "walkdir", ] @@ -9390,29 +9357,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.25" +version = "0.38.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4eb579851244c2c03e7c24f501c3432bed80b8f720af1d6e5b0e0f01555a035" -dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys 0.48.0", -] - -[[package]] -name = "rustix" -version = "0.38.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "745ecfa778e66b2b63c88a61cb36e0eea109e803b0b86bf9879fbc77c70e86ed" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" dependencies = [ "bitflags 2.4.1", "errno", "libc", - "linux-raw-sys 0.4.10", - "windows-sys 0.48.0", + "linux-raw-sys", + "windows-sys 0.52.0", ] [[package]] @@ -9436,20 +9389,20 @@ checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" dependencies = [ "log", "ring 0.16.20", - "sct 0.7.0", + "sct 0.7.1", "webpki 0.22.4", ] [[package]] name = "rustls" -version = "0.21.7" +version = "0.21.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", - "ring 0.16.20", + "ring 0.17.7", "rustls-webpki", - "sct 0.7.0", + "sct 0.7.1", ] [[package]] @@ -9466,21 +9419,21 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", ] [[package]] name = "rustls-webpki" -version = "0.101.6" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", + "ring 0.17.7", + "untrusted 0.9.0", ] [[package]] @@ -9512,9 +9465,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "safer-ffi" @@ -9566,9 +9519,9 @@ dependencies = [ [[package]] name = "schemars" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" dependencies = [ "dyn-clone", "indexmap 1.9.3", @@ -9579,9 +9532,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" dependencies = [ "proc-macro2", "quote", @@ -9613,12 +9566,12 @@ dependencies = [ [[package]] name = "sct" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", + "ring 0.17.7", + "untrusted 0.9.0", ] [[package]] @@ -9627,7 +9580,7 @@ version = "0.1.0" dependencies = [ "anyhow", "cargo-edit", - "clap 4.4.7", + "clap 4.4.11", "semver 1.0.20", "serde", "serde_json", @@ -9740,9 +9693,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.189" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] @@ -9787,13 +9740,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.189" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -9815,7 +9768,7 @@ checksum = "e578a843d40b4189a4d66bba51d7684f57da5bd7c304c64e14bd63efbef49509" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -9841,20 +9794,20 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" +checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] name = "serde_spanned" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" dependencies = [ "serde", ] @@ -9873,11 +9826,11 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.25" +version = "0.9.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a49e178e4452f45cb61d0cd8cebc1b0fafd3e41929e996cef79aa3aca91f574" +checksum = "3cc7a1570e38322cfe4154732e5110f887ea57e22b76f4bfd32b5bdd3368666c" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.1.0", "itoa", "ryu", "serde", @@ -9992,9 +9945,9 @@ dependencies = [ [[package]] name = "signature" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest 0.10.7", "rand_core 0.6.4", @@ -10028,9 +9981,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "smartstring" @@ -10068,16 +10021,16 @@ dependencies = [ [[package]] name = "snow" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9d1425eb528a21de2755c75af4c9b5d57f50a0d4c3b7f1828a4cd03f8ba155" +checksum = "58021967fd0a5eeeb23b08df6cc244a4d4a5b4aec1d27c9e02fad1a58b4cd74e" dependencies = [ - "aes-gcm 0.9.4", + "aes-gcm 0.10.3", "blake2 0.10.6", - "chacha20poly1305 0.9.1", + "chacha20poly1305", "curve25519-dalek 4.1.1", "rand_core 0.6.4", - "ring 0.16.20", + "ring 0.17.7", "rustc_version 0.4.0", "sha2 0.10.8", "subtle 2.4.1", @@ -10085,9 +10038,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ "libc", "winapi", @@ -10095,9 +10048,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", "windows-sys 0.48.0", @@ -10181,9 +10134,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der 0.7.8", @@ -10191,11 +10144,11 @@ dependencies = [ [[package]] name = "sqlformat" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b7b278788e7be4d0d29c0f39497a0eef3fba6bbc8e70d8bf7fde46edeaa9e85" +checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" dependencies = [ - "itertools 0.11.0", + "itertools 0.12.0", "nom", "unicode_categories", ] @@ -10216,7 +10169,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.7", "atoi", "bitflags 1.3.2", "byteorder", @@ -10226,7 +10179,7 @@ dependencies = [ "crossbeam-queue", "dotenvy", "either", - "event-listener", + "event-listener 2.5.3", "flume", "futures-channel", "futures-core", @@ -10293,7 +10246,7 @@ name = "ssl-inject" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.4.7", + "clap 4.4.11", "hex", "tokio", ] @@ -10399,7 +10352,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -10480,9 +10433,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" dependencies = [ "proc-macro2", "quote", @@ -10562,14 +10515,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.8.0" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" dependencies = [ "cfg-if", "fastrand 2.0.1", - "redox_syscall 0.3.5", - "rustix 0.38.19", + "redox_syscall 0.4.1", + "rustix", "windows-sys 0.48.0", ] @@ -10588,15 +10541,15 @@ dependencies = [ "k256", "num-traits", "once_cell", - "prost 0.12.1", - "prost-types 0.12.1", + "prost 0.12.3", + "prost-types 0.12.3", "ripemd", "serde", "serde_bytes", "serde_json", "serde_repr", "sha2 0.10.8", - "signature 2.1.0", + "signature 2.2.0", "subtle 2.4.1", "subtle-encoding", "tendermint-proto", @@ -10628,8 +10581,8 @@ dependencies = [ "flex-error", "num-derive", "num-traits", - "prost 0.12.1", - "prost-types 0.12.1", + "prost 0.12.3", + "prost-types 0.12.3", "serde", "serde_bytes", "subtle-encoding", @@ -10647,7 +10600,7 @@ dependencies = [ "bytes", "flex-error", "futures", - "getrandom 0.2.10", + "getrandom 0.2.11", "peg", "pin-project", "reqwest", @@ -10671,9 +10624,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" +checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" dependencies = [ "winapi-util", ] @@ -10684,7 +10637,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ - "rustix 0.38.19", + "rustix", "windows-sys 0.48.0", ] @@ -10696,22 +10649,22 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -10803,9 +10756,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.33.0" +version = "1.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" dependencies = [ "backtrace", "bytes", @@ -10815,7 +10768,7 @@ dependencies = [ "parking_lot 0.12.1", "pin-project-lite 0.2.13", "signal-hook-registry", - "socket2 0.5.4", + "socket2 0.5.5", "tokio-macros", "tracing", "windows-sys 0.48.0", @@ -10833,13 +10786,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -10869,7 +10822,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.7", + "rustls 0.21.10", "tokio", ] @@ -10947,7 +10900,7 @@ dependencies = [ "futures-io", "futures-sink", "futures-util", - "hashbrown 0.14.1", + "hashbrown 0.14.3", "pin-project-lite 0.2.13", "slab", "tokio", @@ -10971,20 +10924,20 @@ checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" dependencies = [ "serde", "serde_spanned", - "toml_datetime 0.6.3", + "toml_datetime 0.6.5", "toml_edit 0.19.15", ] [[package]] name = "toml" -version = "0.8.2" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" dependencies = [ "serde", "serde_spanned", - "toml_datetime 0.6.3", - "toml_edit 0.20.2", + "toml_datetime 0.6.5", + "toml_edit 0.21.0", ] [[package]] @@ -10998,9 +10951,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ "serde", ] @@ -11025,23 +10978,23 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.1.0", "serde", "serde_spanned", - "toml_datetime 0.6.3", + "toml_datetime 0.6.5", "winnow", ] [[package]] name = "toml_edit" -version = "0.20.2" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.1.0", "serde", "serde_spanned", - "toml_datetime 0.6.3", + "toml_datetime 0.6.5", "winnow", ] @@ -11053,7 +11006,7 @@ checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" dependencies = [ "async-trait", "axum", - "base64 0.21.4", + "base64 0.21.5", "bytes", "futures-core", "futures-util", @@ -11132,9 +11085,9 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.39" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2ef2af84856a50c1d430afce2fdded0a4ec7eda868db86409b4543df0797f9" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ "log", "pin-project-lite 0.2.13", @@ -11150,7 +11103,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -11175,12 +11128,23 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" dependencies = [ - "lazy_static", "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", "tracing-core", ] @@ -11194,15 +11158,15 @@ dependencies = [ "opentelemetry", "tracing", "tracing-core", - "tracing-log", + "tracing-log 0.1.4", "tracing-subscriber", ] [[package]] name = "tracing-subscriber" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "matchers", "nu-ansi-term", @@ -11213,7 +11177,7 @@ dependencies = [ "thread_local", "tracing", "tracing-core", - "tracing-log", + "tracing-log 0.2.0", ] [[package]] @@ -11224,7 +11188,7 @@ checksum = "2ec6adcab41b1391b08a308cc6302b79f8095d1673f6947c2dc65ffb028b0b2d" dependencies = [ "nu-ansi-term", "tracing-core", - "tracing-log", + "tracing-log 0.1.4", "tracing-subscriber", ] @@ -11275,7 +11239,7 @@ dependencies = [ "lazy_static", "rand 0.8.5", "smallvec", - "socket2 0.4.9", + "socket2 0.4.10", "thiserror", "tinyvec", "tokio", @@ -11305,9 +11269,9 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "ts-rs" @@ -11343,7 +11307,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", "termcolor", ] @@ -11370,7 +11334,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals 0.28.0", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -11387,7 +11351,7 @@ dependencies = [ "log", "native-tls", "rand 0.8.5", - "rustls 0.21.7", + "rustls 0.21.10", "sha1", "thiserror", "url", @@ -11477,9 +11441,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" [[package]] name = "unicode-ident" @@ -11589,27 +11553,27 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5ccd538d4a604753ebc2f17cd9946e89b77bf87f6a8e2309667c6f2e87855e3" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", "log", "native-tls", "once_cell", - "rustls 0.21.7", + "rustls 0.21.10", "rustls-webpki", "serde", "serde_json", "socks", "url", - "webpki-roots 0.25.2", + "webpki-roots 0.25.3", ] [[package]] name = "url" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", - "idna 0.4.0", + "idna 0.5.0", "percent-encoding", "serde", ] @@ -11638,7 +11602,7 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d82b1bc5417102a73e8464c686eef947bdfb99fcdfc0a4f228e81afa9526470a" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.1.0", "serde", "serde_json", "utoipa-gen", @@ -11654,7 +11618,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -11682,11 +11646,11 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" [[package]] name = "uuid" -version = "1.5.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.11", "serde", "wasm-bindgen", ] @@ -11780,9 +11744,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -11790,24 +11754,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" dependencies = [ "cfg-if", "js-sys", @@ -11817,9 +11781,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -11827,28 +11791,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "wasm-bindgen-test" -version = "0.3.37" +version = "0.3.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e6e302a7ea94f83a6d09e78e7dc7d9ca7b186bc2829c24a22d0753efd680671" +checksum = "2cf9242c0d27999b831eae4767b2a146feb0b27d332d553e605864acd2afd403" dependencies = [ "console_error_panic_hook", "js-sys", @@ -11860,12 +11824,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.37" +version = "0.3.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecb993dd8c836930ed130e020e77d9b2e65dd0fbab1b67c790b0f5d80b11a575" +checksum = "794645f5408c9a039fd09f4d113cdfb2e7eba5ff1956b07bcf701cf4b394fe89" dependencies = [ "proc-macro2", "quote", + "syn 2.0.41", ] [[package]] @@ -11948,7 +11913,7 @@ name = "wasm-utils" version = "0.1.0" dependencies = [ "futures", - "getrandom 0.2.10", + "getrandom 0.2.11", "gloo-net", "gloo-utils", "js-sys", @@ -11974,9 +11939,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" dependencies = [ "js-sys", "wasm-bindgen", @@ -11998,7 +11963,7 @@ version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" dependencies = [ - "ring 0.17.4", + "ring 0.17.7", "untrusted 0.9.0", ] @@ -12013,9 +11978,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.2" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" +checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" [[package]] name = "webrtc" @@ -12089,7 +12054,7 @@ dependencies = [ "curve25519-dalek 3.2.0", "der-parser 8.2.0", "elliptic-curve 0.12.3", - "hkdf 0.12.3", + "hkdf 0.12.4", "hmac 0.12.1", "log", "p256", @@ -12131,7 +12096,7 @@ dependencies = [ "tokio", "turn", "url", - "uuid 1.5.0", + "uuid 1.6.1", "waitgroup", "webrtc-mdns", "webrtc-util", @@ -12144,7 +12109,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f08dfd7a6e3987e255c4dbe710dde5d94d0f0574f8a21afa95d171376c143106" dependencies = [ "log", - "socket2 0.4.9", + "socket2 0.4.10", "thiserror", "tokio", "webrtc-util", @@ -12234,7 +12199,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.19", + "rustix", ] [[package]] @@ -12320,6 +12285,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -12350,6 +12324,21 @@ dependencies = [ "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -12362,6 +12351,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -12374,6 +12369,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -12386,6 +12387,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -12398,6 +12405,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -12410,6 +12423,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -12422,6 +12441,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -12435,10 +12460,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] -name = "winnow" -version = "0.5.17" +name = "windows_x86_64_msvc" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3b801d0e0a6726477cc207f60162da452f3a95adb368399bef20a946e06f65c" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "winnow" +version = "0.5.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c830786f7720c2fd27a1a0e27a709dbd3c4d009b56d098fc742d4f4eab91fe2" dependencies = [ "memchr", ] @@ -12545,11 +12576,13 @@ dependencies = [ [[package]] name = "xattr" -version = "1.0.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985" +checksum = "a7dae5072fe1f8db8f8d29059189ac175196e410e40ba42d5d4684ae2f750995" dependencies = [ "libc", + "linux-raw-sys", + "rustix", ] [[package]] @@ -12587,6 +12620,26 @@ dependencies = [ "time", ] +[[package]] +name = "zerocopy" +version = "0.7.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "306dca4455518f1f31635ec308b6b3e4eb1b11758cefafc782827d0aa7acb5c7" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be912bf68235a88fbefd1b73415cb218405958d1655b2ece9035a19920bdf6ba" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.41", +] + [[package]] name = "zeroize" version = "1.6.0" @@ -12604,7 +12657,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index b64e797cb5..f319ff744f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -206,7 +206,7 @@ bip32 = "0.5.1" # temporarily using a fork again (yay.) because we need staking and slashing support cosmrs = { git = "https://github.com/jstuczyn/cosmos-rust", branch ="nym-temp/all-validator-features" } -#cosmrs = "=0.15.0" +#cosmrs = { git = "https://github.com/jstuczyn/cosmos-rust", branch = "nym-temp/all-validator-features" } # unfortuntely we need a fork by yours truly to get the staking support tendermint = "0.34" # same version as used by cosmrs tendermint-rpc = "0.34" # same version as used by cosmrs prost = "0.12" diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/query.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/query.rs index 28ca15cc57..9cc5b2e8d4 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/query.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/query.rs @@ -1,79 +1,78 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -// use crate::nyxd::error::NyxdError; -// use crate::nyxd::{CosmWasmClient, PageRequest}; -use crate::nyxd::CosmWasmClient; +use crate::nyxd::error::NyxdError; +use crate::nyxd::{CosmWasmClient, PageRequest}; use async_trait::async_trait; -// use cosmrs::proto::cosmos::staking::v1beta1::{ -// QueryHistoricalInfoRequest as ProtoQueryHistoricalInfoRequest, -// QueryHistoricalInfoResponse as ProtoQueryHistoricalInfoResponse, -// QueryValidatorRequest as ProtoQueryValidatorRequest, -// QueryValidatorResponse as ProtoQueryValidatorResponse, -// QueryValidatorsRequest as ProtoQueryValidatorsRequest, -// QueryValidatorsResponse as ProtoQueryValidatorsResponse, -// }; -// use cosmrs::staking::{ -// QueryHistoricalInfoRequest, QueryHistoricalInfoResponse, QueryValidatorRequest, -// QueryValidatorResponse, QueryValidatorsRequest, QueryValidatorsResponse, -// }; -// use cosmrs::AccountId; +use cosmrs::proto::cosmos::staking::v1beta1::{ + QueryHistoricalInfoRequest as ProtoQueryHistoricalInfoRequest, + QueryHistoricalInfoResponse as ProtoQueryHistoricalInfoResponse, + QueryValidatorRequest as ProtoQueryValidatorRequest, + QueryValidatorResponse as ProtoQueryValidatorResponse, + QueryValidatorsRequest as ProtoQueryValidatorsRequest, + QueryValidatorsResponse as ProtoQueryValidatorsResponse, +}; +use cosmrs::staking::{ + QueryHistoricalInfoRequest, QueryHistoricalInfoResponse, QueryValidatorRequest, + QueryValidatorResponse, QueryValidatorsRequest, QueryValidatorsResponse, +}; +use cosmrs::AccountId; // TODO: change trait restriction from `CosmWasmClient` to `TendermintRpcClient` #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait StakingQueryClient: CosmWasmClient { - // async fn historical_info(&self, height: i64) -> Result { - // let path = Some("/cosmos.staking.v1beta1.Query/HistoricalInfo".to_owned()); - // - // let req = QueryHistoricalInfoRequest { height }; - // - // let res = self - // .make_abci_query::( - // path, - // req.into(), - // ) - // .await?; - // - // Ok(res.try_into()?) - // } - // - // async fn validator( - // &self, - // validator_addr: AccountId, - // ) -> Result { - // let path = Some("/cosmos.staking.v1beta1.Query/Validator".to_owned()); - // - // let req = QueryValidatorRequest { validator_addr }; - // - // let res = self - // .make_abci_query::( - // path, - // req.into(), - // ) - // .await?; - // - // Ok(res.try_into()?) - // } - // - // async fn validators( - // &self, - // status: String, - // pagination: Option, - // ) -> Result { - // let path = Some("/cosmos.staking.v1beta1.Query/Validators".to_owned()); - // - // let req = QueryValidatorsRequest { status, pagination }; - // - // let res = self - // .make_abci_query::( - // path, - // req.into(), - // ) - // .await?; - // - // Ok(res.try_into()?) - // } + async fn historical_info(&self, height: i64) -> Result { + let path = Some("/cosmos.staking.v1beta1.Query/HistoricalInfo".to_owned()); + + let req = QueryHistoricalInfoRequest { height }; + + let res = self + .make_abci_query::( + path, + req.into(), + ) + .await?; + + Ok(res.try_into()?) + } + + async fn validator( + &self, + validator_addr: AccountId, + ) -> Result { + let path = Some("/cosmos.staking.v1beta1.Query/Validator".to_owned()); + + let req = QueryValidatorRequest { validator_addr }; + + let res = self + .make_abci_query::( + path, + req.into(), + ) + .await?; + + Ok(res.try_into()?) + } + + async fn validators( + &self, + status: String, + pagination: Option, + ) -> Result { + let path = Some("/cosmos.staking.v1beta1.Query/Validators".to_owned()); + + let req = QueryValidatorsRequest { status, pagination }; + + let res = self + .make_abci_query::( + path, + req.into(), + ) + .await?; + + Ok(res.try_into()?) + } } #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] diff --git a/common/client-libs/validator-client/src/nyxd/mod.rs b/common/client-libs/validator-client/src/nyxd/mod.rs index fbd902dc56..49b6e972a5 100644 --- a/common/client-libs/validator-client/src/nyxd/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/mod.rs @@ -41,7 +41,7 @@ pub use coin::Coin; pub use cosmrs::{ bank::MsgSend, bip32, - // query::{PageRequest, PageResponse}, + query::{PageRequest, PageResponse}, tendermint::{ abci::{response::DeliverTx, types::ExecTxResult, Event, EventAttribute}, block::Height, @@ -50,10 +50,7 @@ pub use cosmrs::{ Time as TendermintTime, }, tx::{self, Msg}, - AccountId, - Coin as CosmosCoin, - Denom, - Gas, + AccountId, Coin as CosmosCoin, Denom, Gas, }; pub use cosmwasm_std::Coin as CosmWasmCoin; pub use cw2; diff --git a/common/nyxd-scraper/src/lib.rs b/common/nyxd-scraper/src/lib.rs index 79372e0e30..af084c4471 100644 --- a/common/nyxd-scraper/src/lib.rs +++ b/common/nyxd-scraper/src/lib.rs @@ -16,3 +16,4 @@ pub mod storage; pub use modules::{BlockModule, MsgModule, TxModule}; pub use scraper::{Config, NyxdScraper}; +pub use storage::models; diff --git a/common/nyxd-scraper/src/storage/mod.rs b/common/nyxd-scraper/src/storage/mod.rs index 761b4a4f7b..2722a8558d 100644 --- a/common/nyxd-scraper/src/storage/mod.rs +++ b/common/nyxd-scraper/src/storage/mod.rs @@ -19,7 +19,7 @@ use tracing::{debug, error, info, instrument, trace, warn}; mod helpers; mod manager; -mod models; +pub mod models; pub type StorageTransaction = Transaction<'static, Sqlite>; diff --git a/common/nyxd-scraper/src/storage/models.rs b/common/nyxd-scraper/src/storage/models.rs index 38006bfdaf..74a3dd9b1c 100644 --- a/common/nyxd-scraper/src/storage/models.rs +++ b/common/nyxd-scraper/src/storage/models.rs @@ -4,7 +4,7 @@ use sqlx::types::time::OffsetDateTime; use sqlx::FromRow; -#[derive(Debug, Clone, FromRow)] +#[derive(Debug, Clone, Eq, PartialEq, Hash, FromRow)] pub struct Validator { pub consensus_address: String, pub consensus_pubkey: String, diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index d92f3d4b49..240da01001 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -1014,8 +1014,7 @@ dependencies = [ [[package]] name = "cosmos-sdk-proto" version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32560304ab4c365791fd307282f76637213d8083c1a98490c35159cd67852237" +source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features#67718aa27a96efb9881e927a8f998c94b885093c" dependencies = [ "prost", "prost-types", @@ -1025,8 +1024,7 @@ dependencies = [ [[package]] name = "cosmrs" version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47126f5364df9387b9d8559dcef62e99010e1d4098f39eb3f7ee4b5c254e40ea" +source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features#67718aa27a96efb9881e927a8f998c94b885093c" dependencies = [ "bip32", "cosmos-sdk-proto", diff --git a/nym-validator-rewarder/Cargo.toml b/nym-validator-rewarder/Cargo.toml index cca6b7b422..a126777c4d 100644 --- a/nym-validator-rewarder/Cargo.toml +++ b/nym-validator-rewarder/Cargo.toml @@ -24,9 +24,13 @@ time.workspace = true url.workspace = true zeroize.workspace = true +sha2 = "0.10.8" humantime-serde = "1.0" +reqwest = { workspace = true, features = ["json"] } +serde_json = "1.0.108" + # internal nym-bin-common = { path = "../common/bin-common", features = ["output_format"] } nym-config = { path = "../common/config" } diff --git a/nym-validator-rewarder/src/config/mod.rs b/nym-validator-rewarder/src/config/mod.rs index bb416f0d08..d02cd97672 100644 --- a/nym-validator-rewarder/src/config/mod.rs +++ b/nym-validator-rewarder/src/config/mod.rs @@ -10,6 +10,7 @@ use nym_config::{ DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME, DEFAULT_DATA_DIR, NYM_DIR, }; use nym_network_defaults::NymNetworkDetails; +use nym_validator_client::nyxd; use nym_validator_client::nyxd::Coin; use serde::{Deserialize, Serialize}; use std::io; @@ -109,6 +110,11 @@ impl Config { } } + pub fn rpc_client_config(&self) -> nyxd::Config { + // TEMP + nyxd::Config::try_from_nym_network_details(&NymNetworkDetails::new_from_env()).unwrap() + } + pub fn ensure_is_valid(&self) -> Result<(), NymRewarderError> { self.rewarding.ratios.ensure_is_valid()?; Ok(()) diff --git a/nym-validator-rewarder/src/rewarder/block_signing.rs b/nym-validator-rewarder/src/rewarder/block_signing.rs index 929db290a0..40a4ce6340 100644 --- a/nym-validator-rewarder/src/rewarder/block_signing.rs +++ b/nym-validator-rewarder/src/rewarder/block_signing.rs @@ -3,11 +3,12 @@ use cosmwasm_std::{Decimal, Uint128}; use nym_validator_client::nyxd::Coin; +use nyxd_scraper::models; use std::collections::HashMap; #[derive(Debug)] pub struct ValidatorSigning { - pub consensus_address: String, + pub validator: models::Validator, pub voting_power_at_epoch_start: i64, pub voting_power_ratio: Decimal, @@ -28,7 +29,7 @@ impl EpochSigning { pub fn construct( blocks: i64, total_vp: i64, - validator_results: HashMap, + validator_results: HashMap, ) -> Self { assert!(total_vp >= 0, "negative voting power!"); assert!(blocks >= 0, "negative blocks!"); @@ -38,7 +39,7 @@ impl EpochSigning { let validators = validator_results .into_iter() .map( - |(consensus_address, (signed_blocks, voting_power_at_epoch_start))| { + |(validator, (signed_blocks, voting_power_at_epoch_start))| { let vp: u64 = voting_power_at_epoch_start.try_into().unwrap_or_default(); let signed: u64 = signed_blocks.try_into().unwrap_or_default(); @@ -46,7 +47,7 @@ impl EpochSigning { let ratio_signed = Decimal::from_ratio(signed, blocks_u64); ValidatorSigning { - consensus_address, + validator, voting_power_at_epoch_start, voting_power_ratio, signed_blocks, @@ -63,14 +64,14 @@ impl EpochSigning { } } - pub fn rewarding_amounts(&self, budget: &Coin) -> HashMap { + pub fn rewarding_amounts(&self, budget: &Coin) -> HashMap { let denom = &budget.denom; self.validators .iter() .map(|v| { let amount = Uint128::new(budget.amount) * v.ratio_signed * v.voting_power_ratio; - (v.consensus_address.clone(), Coin::new(amount.u128(), denom)) + (v.validator.clone(), Coin::new(amount.u128(), denom)) }) .collect() } diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index 946e460d00..c9cdc63681 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -8,11 +8,14 @@ use crate::rewarder::epoch::Epoch; use crate::rewarder::helpers::consensus_address_to_account; use nym_network_defaults::NymNetworkDetails; use nym_task::TaskManager; -use nym_validator_client::nyxd::{AccountId, Coin}; -use nyxd_scraper::NyxdScraper; +use nym_validator_client::nyxd::{AccountId, Coin, StakingQueryClient}; +use nym_validator_client::QueryHttpRpcNyxdClient; +use nyxd_scraper::{models, NyxdScraper}; +use sha2::{Digest, Sha256}; use std::cmp::min; use std::collections::HashMap; use std::ops::{Add, Range}; +use std::str::FromStr; use std::time::Duration; use time::format_description::well_known::Rfc3339; use time::OffsetDateTime; @@ -26,6 +29,7 @@ mod tasks; pub struct Rewarder { current_epoch: Epoch, + rpc_client: QueryHttpRpcNyxdClient, config: Config, nyxd_scraper: NyxdScraper, @@ -34,9 +38,14 @@ pub struct Rewarder { impl Rewarder { pub async fn new(config: Config) -> Result { let nyxd_scraper = NyxdScraper::new(config.scraper_config()).await?; + let rpc_client = QueryHttpRpcNyxdClient::connect( + config.rpc_client_config(), + config.base.upstream_nyxd.as_str(), + )?; Ok(Rewarder { current_epoch: Epoch::first()?, + rpc_client, config, nyxd_scraper, }) @@ -105,7 +114,7 @@ impl Rewarder { .storage .get_signed_between_times(&validator.consensus_address, epoch_start, epoch_end) .await?; - signed_in_epoch.insert(validator.consensus_address, (signed, vp)); + signed_in_epoch.insert(validator, (signed, vp)); } let total = self @@ -122,7 +131,7 @@ impl Rewarder { async fn calculate_block_signing_rewards( &mut self, budget: Coin, - ) -> Result, NymRewarderError> { + ) -> Result, NymRewarderError> { info!("calculating reward shares"); let signed = self.get_signed_blocks().await?; @@ -135,14 +144,14 @@ impl Rewarder { async fn calculate_credential_rewards( &mut self, budget: Coin, - ) -> Result, NymRewarderError> { + ) -> Result, NymRewarderError> { info!("calculating reward shares"); Ok(HashMap::new()) } async fn determine_epoch_rewards( &mut self, - ) -> Result, NymRewarderError> { + ) -> Result, NymRewarderError> { let epoch_budget = &self.config.rewarding.epoch_budget; let denom = &epoch_budget.denom; let signing_budget = Coin::new( @@ -157,23 +166,57 @@ impl Rewarder { let signing_rewards = self.calculate_block_signing_rewards(signing_budget).await?; let credential_rewards = self.calculate_credential_rewards(credential_budget).await?; - let mut rewards = HashMap::new(); - for (validator, amount) in signing_rewards { - let account = consensus_address_to_account(&validator)?; - rewards.insert(validator, (account, amount)); + let mut rewards: HashMap = HashMap::new(); + let validators2 = self + .rpc_client + .validators("".to_string(), None) + .await + .unwrap(); + + let mut monikers = HashMap::new(); + for v in validators2.validators { + let val = v.consensus_pubkey.unwrap(); + // println!("{:?}", val); + + let digest = Sha256::digest(&val.to_bytes()).to_vec(); + + // println!("{}", String::from_utf8_lossy(&val)); + // assert_eq!(val.len(), 32); + + let consensus_key = AccountId::new("nvalcons", &digest[..20]) + .unwrap() + .to_string(); + let moniker = v.description.unwrap().moniker; + let acc = v.operator_address; + let acc = AccountId::new("n", &acc.to_bytes()).unwrap(); + monikers.insert(consensus_key, (moniker, acc)); } - for (validator, amount) in credential_rewards { - let account = consensus_address_to_account(&validator)?; + for (val, amount) in &signing_rewards { + // let oper = AccountId::new("nvaloper", &acc.to_bytes()).unwrap(); + // let moniker = get_moniker(acc.clone()).await; - if let Some(existing) = rewards.get_mut(&validator) { - assert_eq!(existing.0, account); - existing.1.amount += amount.amount; - } else { - rewards.insert(validator, (account, amount)); - } + let (moniker, acc) = monikers.get(&val.consensus_address).unwrap(); + println!("{moniker}: {acc} signing: {amount} credentials: XXX") + // } + // for (validator, amount) in signing_rewards { + // let account = consensus_address_to_account(&validator)?; + // rewards.insert(validator, (account, amount)); + // } + // + // for (validator, amount) in credential_rewards { + // let account = consensus_address_to_account(&validator)?; + // + // if let Some(existing) = rewards.get_mut(&validator) { + // assert_eq!(existing.0, account); + // existing.1.amount += amount.amount; + // } else { + // rewards.insert(validator, (account, amount)); + // } + // } + Ok(rewards) } @@ -195,6 +238,19 @@ impl Rewarder { } }; + // for (_, (acc, amount)) in rewards { + // // let oper = AccountId::new("nvaloper", &acc.to_bytes()).unwrap(); + // // let moniker = get_moniker(acc.clone()).await; + // + // let moniker = validators2.validators.iter().find(|v| { + // v.consensus_pubkey + // + // }) + // + // println!("{moniker}: {acc} signing: {amount} credentials: XXX") + // // + // } + /* let budget = Coin::new(667_000_000, "unym"); @@ -223,8 +279,8 @@ impl Rewarder { self.current_epoch.end = OffsetDateTime::now_utc(); self.current_epoch.start = self.current_epoch.end - Duration::from_secs(60 * 60); - println!("sleepiing for 60"); - tokio::time::sleep(Duration::from_secs(60)).await; + println!("sleepiing for 10"); + tokio::time::sleep(Duration::from_secs(10)).await; let until_end = self.current_epoch.until_end(); @@ -274,6 +330,37 @@ fn val_to_nym(addr: &str) -> String { bar.to_string() } +fn make_url(oper: &str) -> String { + format!("https://rpc.nymtech.net/api/cosmos/staking/v1beta1/validators/{oper}") +} + +async fn get_moniker(addr: AccountId) -> String { + let oper = AccountId::new("nvaloper", &addr.to_bytes()) + .unwrap() + .to_string(); + + let foo: serde_json::Value = reqwest::get(make_url(&oper)) + .await + .unwrap() + .json() + .await + .unwrap(); + + println!("raw: {foo:?}"); + + let Some(a) = foo.as_object() else { + return "UNKNOWN".to_string(); + }; + let Some(b) = a.get("validator").and_then(|o| o.as_object()) else { + return "UNKNOWN".to_string(); + }; + let Some(c) = b.get("description").and_then(|o| o.as_object()) else { + return "UNKNOWN".to_string(); + }; + let moniker = c.get("moniker").unwrap().as_str().unwrap(); + moniker.to_string() +} + #[cfg(test)] mod tests { use super::*; @@ -281,7 +368,7 @@ mod tests { #[test] fn aaa() { - let addr = AccountId::from_str("nvaloper18xr68spwm96vvehuvwf6ay9er0gd7q7ae8w8ns").unwrap(); + let addr = AccountId::from_str("nvalcons1yn8kzqna703x5a6wh449ylw70u5drjejx5t6dz").unwrap(); println!("{}", AccountId::new("n", &addr.to_bytes()).unwrap()); println!("{}", AccountId::new("nvaloper", &addr.to_bytes()).unwrap()); println!("{}", AccountId::new("nvalcons", &addr.to_bytes()).unwrap()); @@ -290,4 +377,21 @@ mod tests { // let b = val_to_nym("nvaloper1q8cnx8s06q7ralnskqvj0acvqgacau6djqkm3z"); // println!("{b}"); } + + #[tokio::test] + async fn bar() { + let oper = "nvaloper18xr68spwm96vvehuvwf6ay9er0gd7q7ae8w8ns"; + let foo: serde_json::Value = reqwest::get(make_url(oper)) + .await + .unwrap() + .json() + .await + .unwrap(); + + let a = foo.as_object().unwrap(); + let b = a.get("validator").unwrap().as_object().unwrap(); + let c = b.get("description").unwrap().as_object().unwrap(); + let moniker = c.get("moniker").unwrap().as_str().unwrap(); + println!("moniker: {moniker}") + } } diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 89cfcaf991..fdb976b948 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -808,6 +808,16 @@ dependencies = [ "tendermint-proto", ] +[[package]] +name = "cosmos-sdk-proto" +version = "0.20.0" +source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features#67718aa27a96efb9881e927a8f998c94b885093c" +dependencies = [ + "prost", + "prost-types", + "tendermint-proto", +] + [[package]] name = "cosmrs" version = "0.15.0" @@ -815,7 +825,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47126f5364df9387b9d8559dcef62e99010e1d4098f39eb3f7ee4b5c254e40ea" dependencies = [ "bip32", - "cosmos-sdk-proto", + "cosmos-sdk-proto 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ecdsa 0.16.8", + "eyre", + "k256 0.13.1", + "rand_core 0.6.4", + "serde", + "serde_json", + "signature 2.1.0", + "subtle-encoding", + "tendermint", + "thiserror", +] + +[[package]] +name = "cosmrs" +version = "0.15.0" +source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features#67718aa27a96efb9881e927a8f998c94b885093c" +dependencies = [ + "bip32", + "cosmos-sdk-proto 0.20.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "ecdsa 0.16.8", "eyre", "k256 0.13.1", @@ -3127,7 +3156,7 @@ name = "nym-api-requests" version = "0.1.0" dependencies = [ "bs58 0.4.0", - "cosmrs", + "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", "getset", "nym-coconut-interface", @@ -3422,7 +3451,7 @@ name = "nym-types" version = "1.0.0" dependencies = [ "base64 0.21.4", - "cosmrs", + "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", "eyre", "hmac 0.12.1", @@ -3455,7 +3484,7 @@ dependencies = [ "bip32", "bip39", "colored 2.0.4", - "cosmrs", + "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", "cw-controllers", "cw-utils", @@ -3527,7 +3556,7 @@ dependencies = [ name = "nym-wallet-types" version = "1.0.0" dependencies = [ - "cosmrs", + "cosmrs 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "cosmwasm-std", "hex-literal", "nym-config", @@ -3564,7 +3593,7 @@ dependencies = [ "bip39", "cfg-if", "colored 2.0.4", - "cosmrs", + "cosmrs 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "cosmwasm-std", "dirs 4.0.0", "dotenvy", From 397ef8723d4083d2b41f077522b02f07eba7cc77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 14 Dec 2023 15:01:59 +0000 Subject: [PATCH 07/21] block signing related code --- Cargo.lock | 2 - .../validator-client/src/client.rs | 8 + .../client_traits/signing_client.rs | 2 +- .../module_traits/staking/mod.rs | 6 +- .../module_traits/staking/query.rs | 6 +- .../validator-client/src/nyxd/mod.rs | 11 +- common/nyxd-scraper/src/scraper/mod.rs | 4 + nym-validator-rewarder/Cargo.toml | 4 - .../migrations/01_initial.sql | 4 + nym-validator-rewarder/src/error.rs | 24 +- .../src/rewarder/block_signing.rs | 78 ----- .../src/rewarder/block_signing/mod.rs | 142 +++++++++ .../src/rewarder/block_signing/types.rs | 121 ++++++++ nym-validator-rewarder/src/rewarder/epoch.rs | 3 +- .../src/rewarder/helpers.rs | 39 ++- nym-validator-rewarder/src/rewarder/mod.rs | 286 ++---------------- .../src/rewarder/nyxd_client.rs | 35 +++ 17 files changed, 413 insertions(+), 362 deletions(-) create mode 100644 nym-validator-rewarder/migrations/01_initial.sql delete mode 100644 nym-validator-rewarder/src/rewarder/block_signing.rs create mode 100644 nym-validator-rewarder/src/rewarder/block_signing/mod.rs create mode 100644 nym-validator-rewarder/src/rewarder/block_signing/types.rs create mode 100644 nym-validator-rewarder/src/rewarder/nyxd_client.rs diff --git a/Cargo.lock b/Cargo.lock index fd683e5250..04b9c19eb7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7506,9 +7506,7 @@ dependencies = [ "nym-task", "nym-validator-client", "nyxd-scraper", - "reqwest", "serde", - "serde_json", "sha2 0.10.8", "thiserror", "time", diff --git a/common/client-libs/validator-client/src/client.rs b/common/client-libs/validator-client/src/client.rs index a04b8f05d5..f28e45bd37 100644 --- a/common/client-libs/validator-client/src/client.rs +++ b/common/client-libs/validator-client/src/client.rs @@ -42,6 +42,14 @@ pub struct Config { nyxd_config: nyxd::Config, } +impl TryFrom for Config { + type Error = ValidatorClientError; + + fn try_from(value: NymNetworkDetails) -> Result { + Config::try_from_nym_network_details(&value) + } +} + impl Config { pub fn try_from_nym_network_details( details: &NymNetworkDetails, diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/signing_client.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/signing_client.rs index 5b3deadb68..d5baa96499 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/signing_client.rs @@ -425,7 +425,7 @@ where amount: amount.into_iter().map(Into::into).collect(), } .to_any() - .map_err(|_| NyxdError::SerializationError("MsgExecuteContract".to_owned())) + .map_err(|_| NyxdError::SerializationError("MsgSend".to_owned())) }) .collect::>()?; diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/mod.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/mod.rs index f4a7b38548..a0fddf08e9 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/mod.rs @@ -1,4 +1,8 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -pub mod query; \ No newline at end of file +pub mod query; + +pub use cosmrs::staking::{ + QueryHistoricalInfoResponse, QueryValidatorResponse, QueryValidatorsResponse, Validator, +}; diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/query.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/query.rs index 9cc5b2e8d4..1ae27138ff 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/query.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/staking/query.rs @@ -1,6 +1,7 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use super::{QueryHistoricalInfoResponse, QueryValidatorResponse, QueryValidatorsResponse}; use crate::nyxd::error::NyxdError; use crate::nyxd::{CosmWasmClient, PageRequest}; use async_trait::async_trait; @@ -12,10 +13,7 @@ use cosmrs::proto::cosmos::staking::v1beta1::{ QueryValidatorsRequest as ProtoQueryValidatorsRequest, QueryValidatorsResponse as ProtoQueryValidatorsResponse, }; -use cosmrs::staking::{ - QueryHistoricalInfoRequest, QueryHistoricalInfoResponse, QueryValidatorRequest, - QueryValidatorResponse, QueryValidatorsRequest, QueryValidatorsResponse, -}; +use cosmrs::staking::{QueryHistoricalInfoRequest, QueryValidatorRequest, QueryValidatorsRequest}; use cosmrs::AccountId; // TODO: change trait restriction from `CosmWasmClient` to `TendermintRpcClient` diff --git a/common/client-libs/validator-client/src/nyxd/mod.rs b/common/client-libs/validator-client/src/nyxd/mod.rs index 49b6e972a5..da8910a46f 100644 --- a/common/client-libs/validator-client/src/nyxd/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/mod.rs @@ -41,6 +41,7 @@ pub use coin::Coin; pub use cosmrs::{ bank::MsgSend, bip32, + crypto::PublicKey, query::{PageRequest, PageResponse}, tendermint::{ abci::{response::DeliverTx, types::ExecTxResult, Event, EventAttribute}, @@ -50,7 +51,7 @@ pub use cosmrs::{ Time as TendermintTime, }, tx::{self, Msg}, - AccountId, Coin as CosmosCoin, Denom, Gas, + AccountId, Any, Coin as CosmosCoin, Denom, Gas, }; pub use cosmwasm_std::Coin as CosmWasmCoin; pub use cw2; @@ -102,6 +103,14 @@ impl Config { } } +impl TryFrom for Config { + type Error = NyxdError; + + fn try_from(value: NymNetworkDetails) -> Result { + Config::try_from_nym_network_details(&value) + } +} + #[derive(Debug)] pub struct NyxdClient { client: MaybeSigningClient, diff --git a/common/nyxd-scraper/src/scraper/mod.rs b/common/nyxd-scraper/src/scraper/mod.rs index e5038e98ee..fc994c3908 100644 --- a/common/nyxd-scraper/src/scraper/mod.rs +++ b/common/nyxd-scraper/src/scraper/mod.rs @@ -9,8 +9,10 @@ use crate::rpc_client::RpcClient; use crate::scraper::subscriber::{run_websocket_driver, ChainSubscriber}; use crate::storage::ScraperStorage; use std::path::PathBuf; +use std::time::Duration; use tendermint_rpc::WebSocketClientDriver; use tokio::sync::mpsc::{channel, unbounded_channel}; +use tokio::time::interval; use tokio_util::sync::CancellationToken; use tokio_util::task::TaskTracker; use tracing::info; @@ -191,6 +193,8 @@ impl NyxdScraper { pub async fn stop(self) { info!("stopping the chain scrapper"); + assert!(self.task_tracker.is_closed()); + self.cancel_token.cancel(); self.task_tracker.wait().await } diff --git a/nym-validator-rewarder/Cargo.toml b/nym-validator-rewarder/Cargo.toml index a126777c4d..d4e908955b 100644 --- a/nym-validator-rewarder/Cargo.toml +++ b/nym-validator-rewarder/Cargo.toml @@ -27,10 +27,6 @@ zeroize.workspace = true sha2 = "0.10.8" humantime-serde = "1.0" - -reqwest = { workspace = true, features = ["json"] } -serde_json = "1.0.108" - # internal nym-bin-common = { path = "../common/bin-common", features = ["output_format"] } nym-config = { path = "../common/config" } diff --git a/nym-validator-rewarder/migrations/01_initial.sql b/nym-validator-rewarder/migrations/01_initial.sql new file mode 100644 index 0000000000..0719d1f4fb --- /dev/null +++ b/nym-validator-rewarder/migrations/01_initial.sql @@ -0,0 +1,4 @@ +/* + * Copyright 2023 - Nym Technologies SA + * SPDX-License-Identifier: GPL-3.0-only + */ \ No newline at end of file diff --git a/nym-validator-rewarder/src/error.rs b/nym-validator-rewarder/src/error.rs index c2309793a5..aca9dd61a3 100644 --- a/nym-validator-rewarder/src/error.rs +++ b/nym-validator-rewarder/src/error.rs @@ -53,10 +53,30 @@ pub enum NymRewarderError { #[error("failed to determine epoch boundaries: {0}")] TimeComponentFailure(#[from] time::error::ComponentRange), - #[error("could not convert validators conesnsus address: {consensus_address} to a nym account address: {source}")] + #[error( + "could not convert operator address: {operator_address} to a nym account address: {source}" + )] MalformedBech32Address { - consensus_address: String, + operator_address: String, #[source] source: ErrorReport, }, + + #[error( + "could not convert validator public key: {public_key} into a consensus address: {source}" + )] + MalformedConsensusPublicKey { + public_key: String, + #[source] + source: ErrorReport, + }, + + #[error("somehow the total voting power was negative: {val}")] + NegativeTotalVotingPower { val: i64 }, + + #[error("somehow the signed blocks was negative: {val}")] + NegativeSignedBlocks { val: i64 }, + + #[error("could not find details for validator {consensus_address}")] + MissingValidatorDetails { consensus_address: String }, } diff --git a/nym-validator-rewarder/src/rewarder/block_signing.rs b/nym-validator-rewarder/src/rewarder/block_signing.rs deleted file mode 100644 index 40a4ce6340..0000000000 --- a/nym-validator-rewarder/src/rewarder/block_signing.rs +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use cosmwasm_std::{Decimal, Uint128}; -use nym_validator_client::nyxd::Coin; -use nyxd_scraper::models; -use std::collections::HashMap; - -#[derive(Debug)] -pub struct ValidatorSigning { - pub validator: models::Validator, - - pub voting_power_at_epoch_start: i64, - pub voting_power_ratio: Decimal, - - pub signed_blocks: i32, - pub ratio_signed: Decimal, -} - -#[derive(Debug)] -pub struct EpochSigning { - pub blocks: i64, - pub total_voting_power_at_epoch_start: i64, - - pub validators: Vec, -} - -impl EpochSigning { - pub fn construct( - blocks: i64, - total_vp: i64, - validator_results: HashMap, - ) -> Self { - assert!(total_vp >= 0, "negative voting power!"); - assert!(blocks >= 0, "negative blocks!"); - let total_vp_u64: u64 = total_vp.try_into().unwrap_or_default(); - let blocks_u64: u64 = blocks.try_into().unwrap_or_default(); - - let validators = validator_results - .into_iter() - .map( - |(validator, (signed_blocks, voting_power_at_epoch_start))| { - let vp: u64 = voting_power_at_epoch_start.try_into().unwrap_or_default(); - let signed: u64 = signed_blocks.try_into().unwrap_or_default(); - - let voting_power_ratio = Decimal::from_ratio(vp, total_vp_u64); - let ratio_signed = Decimal::from_ratio(signed, blocks_u64); - - ValidatorSigning { - validator, - voting_power_at_epoch_start, - voting_power_ratio, - signed_blocks, - ratio_signed, - } - }, - ) - .collect(); - - EpochSigning { - blocks, - total_voting_power_at_epoch_start: total_vp, - validators, - } - } - - pub fn rewarding_amounts(&self, budget: &Coin) -> HashMap { - let denom = &budget.denom; - self.validators - .iter() - .map(|v| { - let amount = Uint128::new(budget.amount) * v.ratio_signed * v.voting_power_ratio; - - (v.validator.clone(), Coin::new(amount.u128(), denom)) - }) - .collect() - } -} diff --git a/nym-validator-rewarder/src/rewarder/block_signing/mod.rs b/nym-validator-rewarder/src/rewarder/block_signing/mod.rs new file mode 100644 index 0000000000..caaf2be59d --- /dev/null +++ b/nym-validator-rewarder/src/rewarder/block_signing/mod.rs @@ -0,0 +1,142 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::error::NymRewarderError; +use crate::rewarder::block_signing::types::EpochSigningResults; +use crate::rewarder::epoch::Epoch; +use nym_validator_client::nyxd::module_traits::staking; +use nym_validator_client::nyxd::{PageRequest, StakingQueryClient}; +use nym_validator_client::QueryHttpRpcNyxdClient; +use nyxd_scraper::NyxdScraper; +use std::cmp::min; +use std::collections::HashMap; +use std::ops::Range; +use tracing::info; + +pub(crate) mod types; + +pub struct EpochSigning { + pub(crate) rpc_client: QueryHttpRpcNyxdClient, + pub(crate) nyxd_scraper: NyxdScraper, +} + +impl EpochSigning { + async fn get_voting_power( + &self, + address: &str, + height_range: Range, + ) -> Result, NymRewarderError> { + for height in height_range { + if let Some(precommit) = self + .nyxd_scraper + .storage + .get_precommit(address, height) + .await? + { + return Ok(Some(precommit.voting_power)); + } + } + + Ok(None) + } + + // TODO: eventually this will be replaced by scraping the data from the staking module in the scraper itself + async fn get_validator_details( + &self, + height: i64, + ) -> Result, NymRewarderError> { + // first attempt to get it via the historical info. + // if that fails, attempt to use current block information to at least get **something** + if let Some(validators) = self.rpc_client.historical_info(height).await?.hist { + Ok(validators.valset) + } else { + let mut page_request = None; + let mut response = Vec::new(); + + loop { + let mut res = self + .rpc_client + .validators("".to_string(), page_request) + .await?; + response.append(&mut res.validators); + + let Some(pagination) = res.pagination else { + break; + }; + + page_request = Some(PageRequest { + key: pagination.next_key, + offset: 0, + limit: 0, + count_total: false, + reverse: false, + }); + } + + Ok(response) + } + } + + pub(crate) async fn get_signed_blocks_results( + &self, + current_epoch: Epoch, + ) -> Result { + info!( + "looking up block signers for epoch {} ({} - {})", + current_epoch.id, + current_epoch.start_rfc3339(), + current_epoch.end_rfc3339() + ); + + let validators = self.nyxd_scraper.storage.get_all_known_validators().await?; + let epoch_start = current_epoch.start; + let epoch_end = current_epoch.end; + let first_block = self + .nyxd_scraper + .storage + .get_first_block_height_after(epoch_start) + .await? + .unwrap_or_default(); + let last_block = self + .nyxd_scraper + .storage + .get_last_block_height_before(epoch_end) + .await? + .unwrap_or_default(); + + // each validator MUST be online at some point during the first 20 blocks, otherwise they're not getting anything. + let vp_range_end = min(first_block + 20, last_block); + let vp_range = first_block..vp_range_end; + + let mut total_vp = 0; + let mut signed_in_epoch = HashMap::new(); + + // for each validator, with a valid voting power, get number of signed blocks in the rewarding epoch + for validator in validators { + let Some(vp) = self + .get_voting_power(&validator.consensus_address, vp_range.clone()) + .await? + else { + continue; + }; + total_vp += vp; + + let signed = self + .nyxd_scraper + .storage + .get_signed_between_times(&validator.consensus_address, epoch_start, epoch_end) + .await?; + signed_in_epoch.insert(validator, (signed, vp)); + } + + let total = self + .nyxd_scraper + .storage + .get_blocks_between(epoch_start, epoch_end) + .await?; + + let details = self.get_validator_details(last_block).await?; + + EpochSigningResults::construct(total, total_vp, signed_in_epoch, details) + } +} diff --git a/nym-validator-rewarder/src/rewarder/block_signing/types.rs b/nym-validator-rewarder/src/rewarder/block_signing/types.rs new file mode 100644 index 0000000000..a0e533e348 --- /dev/null +++ b/nym-validator-rewarder/src/rewarder/block_signing/types.rs @@ -0,0 +1,121 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::error::NymRewarderError; +use crate::rewarder::helpers::{consensus_pubkey_to_address, operator_account_to_owner_account}; +use cosmwasm_std::{Decimal, Uint128}; +use nym_validator_client::nyxd::module_traits::staking; +use nym_validator_client::nyxd::{AccountId, Coin}; +use nyxd_scraper::models; +use std::collections::HashMap; +use tracing::info; + +#[derive(Debug)] +pub struct ValidatorSigning { + pub validator: models::Validator, + pub staking_details: staking::Validator, + pub operator_account: AccountId, + + pub voting_power_at_epoch_start: i64, + pub voting_power_ratio: Decimal, + + pub signed_blocks: i32, + pub ratio_signed: Decimal, +} + +impl ValidatorSigning { + pub fn reward_amount(&self, signing_budget: &Coin) -> Coin { + let amount = + Uint128::new(signing_budget.amount) * self.ratio_signed * self.voting_power_ratio; + + let amount = Coin::new(amount.u128(), &signing_budget.denom); + let moniker = self + .staking_details + .description + .as_ref() + .map(|d| d.moniker.clone()) + .unwrap_or("UNKNOWN MONIKER".to_string()); + + info!( + "validator {moniker} will receive {amount} at address {} for block signing work", + self.operator_account + ); + amount + } +} + +#[derive(Debug)] +pub struct EpochSigningResults { + pub blocks: i64, + pub total_voting_power_at_epoch_start: i64, + + pub validators: Vec, +} + +impl EpochSigningResults { + pub fn construct( + blocks: i64, + total_vp: i64, + validator_results: HashMap, + validator_details: Vec, + ) -> Result { + let Ok(total_vp_u64): Result = total_vp.try_into() else { + return Err(NymRewarderError::NegativeTotalVotingPower { val: total_vp }); + }; + let Ok(blocks_u64): Result = blocks.try_into() else { + return Err(NymRewarderError::NegativeSignedBlocks { val: blocks }); + }; + + let mut validator_details: HashMap<_, _> = validator_details + .into_iter() + .filter(|v| v.consensus_pubkey.is_some()) + .map(|v| { + // safety: we know the key is definitely set as we just filtered the iterator based on that condition + #[allow(clippy::unwrap_used)] + consensus_pubkey_to_address(v.consensus_pubkey.unwrap()) + .map(|addr| (addr.to_string(), v)) + }) + .collect::>()?; + + let mut validators = Vec::new(); + + for (validator, (signed_blocks, voting_power_at_epoch_start)) in validator_results { + let vp: u64 = voting_power_at_epoch_start.try_into().unwrap_or_default(); + let signed: u64 = signed_blocks.try_into().unwrap_or_default(); + + let voting_power_ratio = Decimal::from_ratio(vp, total_vp_u64); + let ratio_signed = Decimal::from_ratio(signed, blocks_u64); + let staking_details = validator_details + .remove(&validator.consensus_address) + .ok_or_else(|| NymRewarderError::MissingValidatorDetails { + consensus_address: validator.consensus_address.clone(), + })?; + + let operator_account = + operator_account_to_owner_account(&staking_details.operator_address)?; + + validators.push(ValidatorSigning { + validator, + staking_details, + operator_account, + voting_power_at_epoch_start, + voting_power_ratio, + signed_blocks, + ratio_signed, + }) + } + + Ok(EpochSigningResults { + blocks, + total_voting_power_at_epoch_start: total_vp, + validators, + }) + } + + pub fn rewarding_amounts(&self, budget: &Coin) -> Vec<(AccountId, Vec)> { + self.validators + .iter() + .map(|v| (v.operator_account.clone(), vec![v.reward_amount(budget)])) + .collect() + } +} diff --git a/nym-validator-rewarder/src/rewarder/epoch.rs b/nym-validator-rewarder/src/rewarder/epoch.rs index 9d248f3fe6..f906f215f3 100644 --- a/nym-validator-rewarder/src/rewarder/epoch.rs +++ b/nym-validator-rewarder/src/rewarder/epoch.rs @@ -1,5 +1,5 @@ // Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: GPL-3.0-only use crate::error::NymRewarderError; use std::ops::Add; @@ -9,6 +9,7 @@ use time::OffsetDateTime; const HOUR: Duration = Duration::from_secs(60 * 60); +#[derive(Debug, Clone, Copy)] pub struct Epoch { pub id: i64, diff --git a/nym-validator-rewarder/src/rewarder/helpers.rs b/nym-validator-rewarder/src/rewarder/helpers.rs index f236d0ff5e..578d49c498 100644 --- a/nym-validator-rewarder/src/rewarder/helpers.rs +++ b/nym-validator-rewarder/src/rewarder/helpers.rs @@ -1,23 +1,32 @@ // Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: GPL-3.0-only use crate::error::NymRewarderError; -use nym_validator_client::nyxd::AccountId; -use nyxd_scraper::constants::BECH32_PREFIX; +use nym_validator_client::nyxd::{AccountId, PublicKey}; +use nyxd_scraper::constants::{BECH32_CONSENSUS_ADDRESS_PREFIX, BECH32_PREFIX}; +use sha2::{Digest, Sha256}; -pub(crate) fn consensus_address_to_account( - consensus_address: &str, +pub(crate) fn consensus_pubkey_to_address( + pubkey: PublicKey, ) -> Result { - let consensus_addr: AccountId = - consensus_address - .parse() - .map_err(|source| NymRewarderError::MalformedBech32Address { - consensus_address: consensus_address.to_string(), - source, - })?; - AccountId::new(BECH32_PREFIX, &consensus_addr.to_bytes()).map_err(|source| { - NymRewarderError::MalformedBech32Address { - consensus_address: consensus_address.to_string(), + let digest = Sha256::digest(pubkey.to_bytes()).to_vec(); + + // TODO: make those configurable, etc + AccountId::new(BECH32_CONSENSUS_ADDRESS_PREFIX, &digest[..20]).map_err(|source| { + NymRewarderError::MalformedConsensusPublicKey { + public_key: pubkey.to_string(), + source, + } + }) +} + +// it's just a matter of swapping bech32 prefixes and recalculating the checksum +pub(crate) fn operator_account_to_owner_account( + operator_address: &AccountId, +) -> Result { + AccountId::new(BECH32_PREFIX, &operator_address.to_bytes()).map_err(|source| { + NymRewarderError::MalformedBech32Address { + operator_address: operator_address.to_string(), source, } }) diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index c9cdc63681..a464b3f8dc 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -5,34 +5,28 @@ use crate::config::Config; use crate::error::NymRewarderError; use crate::rewarder::block_signing::EpochSigning; use crate::rewarder::epoch::Epoch; -use crate::rewarder::helpers::consensus_address_to_account; -use nym_network_defaults::NymNetworkDetails; use nym_task::TaskManager; -use nym_validator_client::nyxd::{AccountId, Coin, StakingQueryClient}; +use nym_validator_client::nyxd::{AccountId, Coin}; use nym_validator_client::QueryHttpRpcNyxdClient; -use nyxd_scraper::{models, NyxdScraper}; -use sha2::{Digest, Sha256}; -use std::cmp::min; -use std::collections::HashMap; -use std::ops::{Add, Range}; -use std::str::FromStr; +use nyxd_scraper::NyxdScraper; +use std::ops::Add; use std::time::Duration; -use time::format_description::well_known::Rfc3339; use time::OffsetDateTime; +use tokio::pin; use tokio::time::{interval_at, Instant}; use tracing::{debug, error, info, instrument}; mod block_signing; mod epoch; mod helpers; +mod nyxd_client; mod tasks; pub struct Rewarder { - current_epoch: Epoch, - rpc_client: QueryHttpRpcNyxdClient, - config: Config, - nyxd_scraper: NyxdScraper, + current_epoch: Epoch, + + epoch_signing: EpochSigning, } impl Rewarder { @@ -45,95 +39,24 @@ impl Rewarder { Ok(Rewarder { current_epoch: Epoch::first()?, - rpc_client, config, - nyxd_scraper, + epoch_signing: EpochSigning { + nyxd_scraper, + rpc_client, + }, }) } - async fn get_voting_power( - &self, - address: &str, - height_range: Range, - ) -> Result, NymRewarderError> { - for height in height_range { - if let Some(precommit) = self - .nyxd_scraper - .storage - .get_precommit(address, height) - .await? - { - return Ok(Some(precommit.voting_power)); - } - } - - Ok(None) - } - - async fn get_signed_blocks(&self) -> Result { - info!( - "looking up block signers for epoch {} ({} - {})", - self.current_epoch.id, - self.current_epoch.start_rfc3339(), - self.current_epoch.end_rfc3339() - ); - - let validators = self.nyxd_scraper.storage.get_all_known_validators().await?; - let epoch_start = self.current_epoch.start; - let epoch_end = self.current_epoch.end; - let first_block = self - .nyxd_scraper - .storage - .get_first_block_height_after(epoch_start) - .await? - .unwrap_or_default(); - let last_block = self - .nyxd_scraper - .storage - .get_last_block_height_before(epoch_end) - .await? - .unwrap_or_default(); - - // each validator MUST be online at some point during the first 20 blocks, otherwise they're not getting anything. - let vp_range_end = min(first_block + 20, last_block); - let vp_range = first_block..vp_range_end; - - let mut total_vp = 0; - let mut signed_in_epoch = HashMap::new(); - for validator in validators { - let Some(vp) = self - .get_voting_power(&validator.consensus_address, vp_range.clone()) - .await? - else { - continue; - }; - total_vp += vp; - - let signed = self - .nyxd_scraper - .storage - .get_signed_between_times(&validator.consensus_address, epoch_start, epoch_end) - .await?; - signed_in_epoch.insert(validator, (signed, vp)); - } - - let total = self - .nyxd_scraper - .storage - .get_blocks_between(epoch_start, epoch_end) - .await?; - - Ok(EpochSigning::construct(total, total_vp, signed_in_epoch)) - } - #[instrument(skip(self,budget), fields(budget = %budget))] - async fn calculate_block_signing_rewards( &mut self, budget: Coin, - ) -> Result, NymRewarderError> { + ) -> Result)>, NymRewarderError> { info!("calculating reward shares"); - let signed = self.get_signed_blocks().await?; + let signed = self + .epoch_signing + .get_signed_blocks_results(self.current_epoch) + .await?; debug!("details: {signed:?}"); @@ -144,14 +67,14 @@ impl Rewarder { async fn calculate_credential_rewards( &mut self, budget: Coin, - ) -> Result, NymRewarderError> { + ) -> Result)>, NymRewarderError> { info!("calculating reward shares"); - Ok(HashMap::new()) + Ok(Vec::new()) } async fn determine_epoch_rewards( &mut self, - ) -> Result, NymRewarderError> { + ) -> Result)>, NymRewarderError> { let epoch_budget = &self.config.rewarding.epoch_budget; let denom = &epoch_budget.denom; let signing_budget = Coin::new( @@ -164,65 +87,16 @@ impl Rewarder { ); let signing_rewards = self.calculate_block_signing_rewards(signing_budget).await?; - let credential_rewards = self.calculate_credential_rewards(credential_budget).await?; - - let mut rewards: HashMap = HashMap::new(); - let validators2 = self - .rpc_client - .validators("".to_string(), None) - .await - .unwrap(); - - let mut monikers = HashMap::new(); - for v in validators2.validators { - let val = v.consensus_pubkey.unwrap(); - // println!("{:?}", val); - - let digest = Sha256::digest(&val.to_bytes()).to_vec(); - - // println!("{}", String::from_utf8_lossy(&val)); - // assert_eq!(val.len(), 32); - - let consensus_key = AccountId::new("nvalcons", &digest[..20]) - .unwrap() - .to_string(); - let moniker = v.description.unwrap().moniker; - let acc = v.operator_address; - let acc = AccountId::new("n", &acc.to_bytes()).unwrap(); - monikers.insert(consensus_key, (moniker, acc)); - } - - for (val, amount) in &signing_rewards { - // let oper = AccountId::new("nvaloper", &acc.to_bytes()).unwrap(); - // let moniker = get_moniker(acc.clone()).await; - - let (moniker, acc) = monikers.get(&val.consensus_address).unwrap(); - println!("{moniker}: {acc} signing: {amount} credentials: XXX") - // - } - - // for (validator, amount) in signing_rewards { - // let account = consensus_address_to_account(&validator)?; - // rewards.insert(validator, (account, amount)); - // } - // - // for (validator, amount) in credential_rewards { - // let account = consensus_address_to_account(&validator)?; - // - // if let Some(existing) = rewards.get_mut(&validator) { - // assert_eq!(existing.0, account); - // existing.1.amount += amount.amount; - // } else { - // rewards.insert(validator, (account, amount)); - // } - // } + let mut credential_rewards = self.calculate_credential_rewards(credential_budget).await?; + let mut rewards = signing_rewards; + rewards.append(&mut credential_rewards); Ok(rewards) } async fn send_rewards( &self, - amounts: HashMap, + amounts: Vec<(AccountId, Vec)>, ) -> Result<(), NymRewarderError> { Ok(()) } @@ -238,30 +112,11 @@ impl Rewarder { } }; - // for (_, (acc, amount)) in rewards { - // // let oper = AccountId::new("nvaloper", &acc.to_bytes()).unwrap(); - // // let moniker = get_moniker(acc.clone()).await; - // - // let moniker = validators2.validators.iter().find(|v| { - // v.consensus_pubkey - // - // }) - // - // println!("{moniker}: {acc} signing: {amount} credentials: XXX") - // // - // } + if let Err(err) = self.send_rewards(rewards).await { + error!("failed to send epoch rewards: {err}"); + return; + }; - /* - - let budget = Coin::new(667_000_000, "unym"); - let rewards = foo.rewarding_amounts(&budget); - - println!("{rewards:#?}"); - 666_378_383 - let bar: u128 = rewards.into_values().map(|v| v.amount).sum(); - println!("summed: {bar}"); - - */ self.current_epoch = self.current_epoch.next(); } @@ -271,17 +126,12 @@ impl Rewarder { // setup shutdowns let mut task_manager = TaskManager::new(5); - self.nyxd_scraper.start().await?; - // - // tokio::time::sleep(Duration::from_secs(3000)).await; + self.epoch_signing.nyxd_scraper.start().await?; // rewarding epochs last from :00 to :00 self.current_epoch.end = OffsetDateTime::now_utc(); self.current_epoch.start = self.current_epoch.end - Duration::from_secs(60 * 60); - println!("sleepiing for 10"); - tokio::time::sleep(Duration::from_secs(10)).await; - let until_end = self.current_epoch.until_end(); info!( @@ -289,11 +139,13 @@ impl Rewarder { until_end.as_secs() ); let mut epoch_ticker = interval_at(Instant::now().add(until_end), Epoch::LENGTH); + let shutdown_future = task_manager.catch_interrupt(); + pin!(shutdown_future); loop { tokio::select! { biased; - interrupt_res = task_manager.catch_interrupt() => { + interrupt_res = &mut shutdown_future => { info!("received interrupt"); if let Err(err) = interrupt_res { error!("runtime interrupt failure: {err}") @@ -304,7 +156,7 @@ impl Rewarder { } } - self.nyxd_scraper.stop().await; + self.epoch_signing.nyxd_scraper.stop().await; /* task 1: @@ -323,75 +175,3 @@ impl Rewarder { todo!() } } - -fn val_to_nym(addr: &str) -> String { - let foo: AccountId = addr.parse().unwrap(); - let bar = AccountId::new("n", &foo.to_bytes()).unwrap(); - bar.to_string() -} - -fn make_url(oper: &str) -> String { - format!("https://rpc.nymtech.net/api/cosmos/staking/v1beta1/validators/{oper}") -} - -async fn get_moniker(addr: AccountId) -> String { - let oper = AccountId::new("nvaloper", &addr.to_bytes()) - .unwrap() - .to_string(); - - let foo: serde_json::Value = reqwest::get(make_url(&oper)) - .await - .unwrap() - .json() - .await - .unwrap(); - - println!("raw: {foo:?}"); - - let Some(a) = foo.as_object() else { - return "UNKNOWN".to_string(); - }; - let Some(b) = a.get("validator").and_then(|o| o.as_object()) else { - return "UNKNOWN".to_string(); - }; - let Some(c) = b.get("description").and_then(|o| o.as_object()) else { - return "UNKNOWN".to_string(); - }; - let moniker = c.get("moniker").unwrap().as_str().unwrap(); - moniker.to_string() -} - -#[cfg(test)] -mod tests { - use super::*; - use std::str::FromStr; - - #[test] - fn aaa() { - let addr = AccountId::from_str("nvalcons1yn8kzqna703x5a6wh449ylw70u5drjejx5t6dz").unwrap(); - println!("{}", AccountId::new("n", &addr.to_bytes()).unwrap()); - println!("{}", AccountId::new("nvaloper", &addr.to_bytes()).unwrap()); - println!("{}", AccountId::new("nvalcons", &addr.to_bytes()).unwrap()); - // println!("{}", AccountId::new("n", &addr.to_bytes()).unwrap()); - - // let b = val_to_nym("nvaloper1q8cnx8s06q7ralnskqvj0acvqgacau6djqkm3z"); - // println!("{b}"); - } - - #[tokio::test] - async fn bar() { - let oper = "nvaloper18xr68spwm96vvehuvwf6ay9er0gd7q7ae8w8ns"; - let foo: serde_json::Value = reqwest::get(make_url(oper)) - .await - .unwrap() - .json() - .await - .unwrap(); - - let a = foo.as_object().unwrap(); - let b = a.get("validator").unwrap().as_object().unwrap(); - let c = b.get("description").unwrap().as_object().unwrap(); - let moniker = c.get("moniker").unwrap().as_str().unwrap(); - println!("moniker: {moniker}") - } -} diff --git a/nym-validator-rewarder/src/rewarder/nyxd_client.rs b/nym-validator-rewarder/src/rewarder/nyxd_client.rs new file mode 100644 index 0000000000..7084e7c7f0 --- /dev/null +++ b/nym-validator-rewarder/src/rewarder/nyxd_client.rs @@ -0,0 +1,35 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::config::Config; +use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient}; +use std::sync::Arc; +use tokio::sync::RwLock; + +#[derive(Clone)] +pub struct NyxdClient { + inner: Arc>, +} + +impl NyxdClient { + pub(crate) fn new(config: &Config) -> Self { + let details = config.get_network_details(); + let nyxd_url = config.get_nyxd_url(); + + let client_config = nyxd::Config::try_from_nym_network_details(&details) + .expect("failed to construct valid validator client config with the provided network"); + + let mnemonic = config.base.mnemonic.clone(); + + let inner = DirectSigningHttpRpcNyxdClient::connect_with_mnemonic( + client_config, + nyxd_url.as_str(), + mnemonic, + ) + .expect("Failed to connect to nyxd!"); + + NyxdClient { + inner: Arc::new(RwLock::new(inner)), + } + } +} From 4f6fe88b4cb0ebb84f6a6d456f8e18f10d5bf56c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 14 Dec 2023 17:17:41 +0000 Subject: [PATCH 08/21] starting on persistence --- Cargo.lock | 1 + common/nyxd-scraper/src/storage/mod.rs | 2 - nym-validator-rewarder/Cargo.toml | 7 +- nym-validator-rewarder/build.rs | 28 ++++ .../migrations/01_initial.sql | 65 ++++++++- nym-validator-rewarder/src/config/mod.rs | 3 +- .../src/config/persistence/paths.rs | 3 + nym-validator-rewarder/src/error.rs | 6 + .../src/rewarder/block_signing/mod.rs | 13 +- .../src/rewarder/credential_issuance/mod.rs | 27 ++++ .../src/rewarder/credential_issuance/types.rs | 13 ++ nym-validator-rewarder/src/rewarder/mod.rs | 133 +++++++++++------- .../src/rewarder/nyxd_client.rs | 38 ++++- .../src/rewarder/storage/manager.rs | 52 +++++++ .../src/rewarder/storage/mod.rs | 64 +++++++++ 15 files changed, 383 insertions(+), 72 deletions(-) create mode 100644 nym-validator-rewarder/build.rs create mode 100644 nym-validator-rewarder/src/rewarder/credential_issuance/mod.rs create mode 100644 nym-validator-rewarder/src/rewarder/credential_issuance/types.rs create mode 100644 nym-validator-rewarder/src/rewarder/storage/manager.rs create mode 100644 nym-validator-rewarder/src/rewarder/storage/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 04b9c19eb7..eb1e717ee6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7508,6 +7508,7 @@ dependencies = [ "nyxd-scraper", "serde", "sha2 0.10.8", + "sqlx", "thiserror", "time", "tokio", diff --git a/common/nyxd-scraper/src/storage/mod.rs b/common/nyxd-scraper/src/storage/mod.rs index 2722a8558d..6dba07ae0e 100644 --- a/common/nyxd-scraper/src/storage/mod.rs +++ b/common/nyxd-scraper/src/storage/mod.rs @@ -31,8 +31,6 @@ pub struct ScraperStorage { impl ScraperStorage { #[instrument] pub async fn init + Debug>(database_path: P) -> Result { - // TODO: we can inject here more stuff based on our nym-api global config - // struct. Maybe different pool size or timeout intervals? let mut opts = sqlx::sqlite::SqliteConnectOptions::new() .filename(database_path) .create_if_missing(true); diff --git a/nym-validator-rewarder/Cargo.toml b/nym-validator-rewarder/Cargo.toml index d4e908955b..081d32c925 100644 --- a/nym-validator-rewarder/Cargo.toml +++ b/nym-validator-rewarder/Cargo.toml @@ -17,6 +17,7 @@ cosmwasm-std.workspace = true clap = { workspace = true, features = ["cargo"] } futures.workspace = true serde = { workspace = true, features = ["derive"] } +sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate", "time"] } thiserror.workspace = true tokio = { workspace = true, features = ["rt-multi-thread", "time", "macros"] } tracing.workspace = true @@ -33,4 +34,8 @@ nym-config = { path = "../common/config" } nym-network-defaults = { path = "../common/network-defaults" } nym-task = { path = "../common/task" } nym-validator-client = { path = "../common/client-libs/validator-client" } -nyxd-scraper = { path = "../common/nyxd-scraper" } \ No newline at end of file +nyxd-scraper = { path = "../common/nyxd-scraper" } + +[build-dependencies] +sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] } +tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } diff --git a/nym-validator-rewarder/build.rs b/nym-validator-rewarder/build.rs new file mode 100644 index 0000000000..6bd3636b5e --- /dev/null +++ b/nym-validator-rewarder/build.rs @@ -0,0 +1,28 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +#[tokio::main] +async fn main() { + use sqlx::{Connection, SqliteConnection}; + use std::env; + + let out_dir = env::var("OUT_DIR").unwrap(); + let database_path = format!("{out_dir}/scraper-example.sqlite"); + + let mut conn = SqliteConnection::connect(&format!("sqlite://{database_path}?mode=rwc")) + .await + .expect("Failed to create SQLx database connection"); + + sqlx::migrate!("./migrations") + .run(&mut conn) + .await + .expect("Failed to perform SQLx migrations"); + + #[cfg(target_family = "unix")] + println!("cargo:rustc-env=DATABASE_URL=sqlite://{}", &database_path); + + #[cfg(target_family = "windows")] + // for some strange reason we need to add a leading `/` to the windows path even though it's + // not a valid windows path... but hey, it works... + println!("cargo:rustc-env=DATABASE_URL=sqlite:///{}", &database_path); +} diff --git a/nym-validator-rewarder/migrations/01_initial.sql b/nym-validator-rewarder/migrations/01_initial.sql index 0719d1f4fb..ab618ffc91 100644 --- a/nym-validator-rewarder/migrations/01_initial.sql +++ b/nym-validator-rewarder/migrations/01_initial.sql @@ -1,4 +1,67 @@ /* * Copyright 2023 - Nym Technologies SA * SPDX-License-Identifier: GPL-3.0-only - */ \ No newline at end of file + */ + +CREATE TABLE rewarding_epoch +( + id INTEGER NOT NULL PRIMARY KEY, + start_time TIMESTAMP WITHOUT TIME ZONE NOT NULL, + end_time TIMESTAMP WITHOUT TIME ZONE NOT NULL, + budget TEXT NOT NULL, + rewarding_tx TEXT, + rewarding_error TEXT +); + +CREATE TABLE epoch_block_signing +( + rewarding_epoch_id INTEGER NOT NULL PRIMARY KEY REFERENCES rewarding_epoch (id), + total_voting_power_at_epoch_start INTEGER NOT NULL, + num_blocks INTEGER NOT NULL, + budget TEXT NOT NULL +); + +CREATE TABLE block_signing_reward +( + rewarding_epoch_id INTEGER NOT NULL REFERENCES rewarding_epoch (id), + validator_consensus_address TEXT NOT NULL, + operator_account TEXT NOT NULL, + amount TEXT NOT NULL, + voting_power BIGINT NOT NULL, + voting_power_share DECIMAL NOT NULL, + signed_blocks INTEGER NOT NULL, + signed_blocks_percent DECIMAL NOT NULL, + + UNIQUE (rewarding_epoch_id, operator_account) +); + +CREATE TABLE epoch_credential_issuance +( + rewarding_epoch_id INTEGER NOT NULL PRIMARY KEY REFERENCES rewarding_epoch (id), + dkg_epoch_id INTEGER NOT NULL,-- currently not incrementing, needs to change + total_issued_credentials INTEGER NOT NULL, + budget TEXT NOT NULL +); + +CREATE TABLE malformed_credential +( + rewarding_epoch_id INTEGER NOT NULL REFERENCES rewarding_epoch (id) + +); + +CREATE TABLE credential_issuance_reward +( + rewarding_epoch_id INTEGER NOT NULL REFERENCES rewarding_epoch (id), + amount TEXT NOT NULL, + operator_account TEXT NOT NULL, + api_endpoint TEXT NOT NULL, + + + UNIQUE (rewarding_epoch_id, operator_account) +); + +-- CREATE TABLE credential_verification_reward +-- ( +-- +-- ); + diff --git a/nym-validator-rewarder/src/config/mod.rs b/nym-validator-rewarder/src/config/mod.rs index d02cd97672..6c9c86cbac 100644 --- a/nym-validator-rewarder/src/config/mod.rs +++ b/nym-validator-rewarder/src/config/mod.rs @@ -112,7 +112,8 @@ impl Config { pub fn rpc_client_config(&self) -> nyxd::Config { // TEMP - nyxd::Config::try_from_nym_network_details(&NymNetworkDetails::new_from_env()).unwrap() + nyxd::Config::try_from_nym_network_details(&NymNetworkDetails::new_from_env()) + .expect("failed to create nyxd client config") } pub fn ensure_is_valid(&self) -> Result<(), NymRewarderError> { diff --git a/nym-validator-rewarder/src/config/persistence/paths.rs b/nym-validator-rewarder/src/config/persistence/paths.rs index 4317339677..daee529076 100644 --- a/nym-validator-rewarder/src/config/persistence/paths.rs +++ b/nym-validator-rewarder/src/config/persistence/paths.rs @@ -11,12 +11,15 @@ pub const DEFAULT_REWARD_HISTORY_DB_FILENAME: &str = "rewards.sqlite"; #[derive(Debug, Clone, Deserialize, Serialize)] pub struct ValidatorRewarderPaths { pub nyxd_scraper: PathBuf, + + pub reward_history: PathBuf, } impl Default for ValidatorRewarderPaths { fn default() -> Self { ValidatorRewarderPaths { nyxd_scraper: default_data_directory().join(DEFAULT_SCRAPER_DB_FILENAME), + reward_history: default_data_directory().join(DEFAULT_REWARD_HISTORY_DB_FILENAME), } } } diff --git a/nym-validator-rewarder/src/error.rs b/nym-validator-rewarder/src/error.rs index aca9dd61a3..c6d722e415 100644 --- a/nym-validator-rewarder/src/error.rs +++ b/nym-validator-rewarder/src/error.rs @@ -9,6 +9,12 @@ use thiserror::Error; #[derive(Debug, Error)] pub enum NymRewarderError { + #[error("experienced internal database error: {0}")] + InternalDatabaseError(#[from] sqlx::Error), + + #[error("failed to perform startup SQL migration: {0}")] + StartupMigrationFailure(#[from] sqlx::migrate::MigrateError), + #[error( "failed to load config file using path '{}'. detailed message: {source}", path.display() )] diff --git a/nym-validator-rewarder/src/rewarder/block_signing/mod.rs b/nym-validator-rewarder/src/rewarder/block_signing/mod.rs index caaf2be59d..18f4e85f3a 100644 --- a/nym-validator-rewarder/src/rewarder/block_signing/mod.rs +++ b/nym-validator-rewarder/src/rewarder/block_signing/mod.rs @@ -4,9 +4,9 @@ use crate::error::NymRewarderError; use crate::rewarder::block_signing::types::EpochSigningResults; use crate::rewarder::epoch::Epoch; +use crate::rewarder::nyxd_client::NyxdClient; use nym_validator_client::nyxd::module_traits::staking; -use nym_validator_client::nyxd::{PageRequest, StakingQueryClient}; -use nym_validator_client::QueryHttpRpcNyxdClient; +use nym_validator_client::nyxd::PageRequest; use nyxd_scraper::NyxdScraper; use std::cmp::min; use std::collections::HashMap; @@ -16,7 +16,7 @@ use tracing::info; pub(crate) mod types; pub struct EpochSigning { - pub(crate) rpc_client: QueryHttpRpcNyxdClient, + pub(crate) nyxd_client: NyxdClient, pub(crate) nyxd_scraper: NyxdScraper, } @@ -47,17 +47,14 @@ impl EpochSigning { ) -> Result, NymRewarderError> { // first attempt to get it via the historical info. // if that fails, attempt to use current block information to at least get **something** - if let Some(validators) = self.rpc_client.historical_info(height).await?.hist { + if let Some(validators) = self.nyxd_client.historical_info(height).await?.hist { Ok(validators.valset) } else { let mut page_request = None; let mut response = Vec::new(); loop { - let mut res = self - .rpc_client - .validators("".to_string(), page_request) - .await?; + let mut res = self.nyxd_client.validators(page_request).await?; response.append(&mut res.validators); let Some(pagination) = res.pagination else { diff --git a/nym-validator-rewarder/src/rewarder/credential_issuance/mod.rs b/nym-validator-rewarder/src/rewarder/credential_issuance/mod.rs new file mode 100644 index 0000000000..697d33d779 --- /dev/null +++ b/nym-validator-rewarder/src/rewarder/credential_issuance/mod.rs @@ -0,0 +1,27 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::error::NymRewarderError; +use crate::rewarder::credential_issuance::types::CredentialIssuanceResults; +use crate::rewarder::epoch::Epoch; +use tracing::info; + +pub mod types; + +pub struct CredentialIssuance {} + +impl CredentialIssuance { + pub(crate) async fn get_signed_blocks_results( + &self, + current_epoch: Epoch, + ) -> Result { + info!( + "looking up credential issuers for epoch {} ({} - {})", + current_epoch.id, + current_epoch.start_rfc3339(), + current_epoch.end_rfc3339() + ); + + Ok(CredentialIssuanceResults {}) + } +} diff --git a/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs b/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs new file mode 100644 index 0000000000..a0766af2a9 --- /dev/null +++ b/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs @@ -0,0 +1,13 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use nym_validator_client::nyxd::{AccountId, Coin}; + +pub struct CredentialIssuanceResults {} + +impl CredentialIssuanceResults { + pub fn rewarding_amounts(&self, budget: &Coin) -> Vec<(AccountId, Vec)> { + let _ = budget; + Vec::new() + } +} \ No newline at end of file diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index a464b3f8dc..3372fad544 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -3,102 +3,138 @@ use crate::config::Config; use crate::error::NymRewarderError; +use crate::rewarder::block_signing::types::EpochSigningResults; use crate::rewarder::block_signing::EpochSigning; +use crate::rewarder::credential_issuance::types::CredentialIssuanceResults; +use crate::rewarder::credential_issuance::CredentialIssuance; use crate::rewarder::epoch::Epoch; +use crate::rewarder::nyxd_client::NyxdClient; +use crate::rewarder::storage::RewarderStorage; use nym_task::TaskManager; -use nym_validator_client::nyxd::{AccountId, Coin}; -use nym_validator_client::QueryHttpRpcNyxdClient; +use nym_validator_client::nyxd::{AccountId, Coin, Hash}; use nyxd_scraper::NyxdScraper; use std::ops::Add; use std::time::Duration; use time::OffsetDateTime; use tokio::pin; use tokio::time::{interval_at, Instant}; -use tracing::{debug, error, info, instrument}; +use tracing::{error, info, instrument}; mod block_signing; +mod credential_issuance; mod epoch; mod helpers; mod nyxd_client; +mod storage; mod tasks; +pub struct EpochRewards { + pub epoch: Epoch, + pub signing: EpochSigningResults, + pub credentials: CredentialIssuanceResults, + + pub total_budget: Coin, + pub signing_budget: Coin, + pub credentials_budget: Coin, +} + +impl EpochRewards { + pub fn amounts(&self) -> Vec<(AccountId, Vec)> { + let signing = self.signing.rewarding_amounts(&self.signing_budget); + let mut credentials = Vec::new(); + + let mut amounts = signing; + amounts.append(&mut credentials); + + amounts + } +} + pub struct Rewarder { config: Config, current_epoch: Epoch, + storage: RewarderStorage, + nyxd_client: NyxdClient, epoch_signing: EpochSigning, + credential_issuance: CredentialIssuance, } impl Rewarder { pub async fn new(config: Config) -> Result { let nyxd_scraper = NyxdScraper::new(config.scraper_config()).await?; - let rpc_client = QueryHttpRpcNyxdClient::connect( - config.rpc_client_config(), - config.base.upstream_nyxd.as_str(), - )?; + let nyxd_client = NyxdClient::new(&config); + let storage = RewarderStorage::init(&config.storage_paths.reward_history).await?; Ok(Rewarder { current_epoch: Epoch::first()?, config, epoch_signing: EpochSigning { nyxd_scraper, - rpc_client, + nyxd_client: nyxd_client.clone(), }, + nyxd_client, + storage, + credential_issuance: CredentialIssuance {}, }) } - #[instrument(skip(self,budget), fields(budget = %budget))] + #[instrument(skip(self))] async fn calculate_block_signing_rewards( &mut self, - budget: Coin, - ) -> Result)>, NymRewarderError> { + ) -> Result { info!("calculating reward shares"); - let signed = self - .epoch_signing + self.epoch_signing .get_signed_blocks_results(self.current_epoch) - .await?; - - debug!("details: {signed:?}"); - - Ok(signed.rewarding_amounts(&budget)) + .await } - #[instrument(skip(self,budget), fields(budget = %budget))] + #[instrument(skip(self))] async fn calculate_credential_rewards( &mut self, - budget: Coin, - ) -> Result)>, NymRewarderError> { + ) -> Result { info!("calculating reward shares"); - Ok(Vec::new()) + self.credential_issuance + .get_signed_blocks_results(self.current_epoch) + .await } - async fn determine_epoch_rewards( - &mut self, - ) -> Result)>, NymRewarderError> { - let epoch_budget = &self.config.rewarding.epoch_budget; + async fn determine_epoch_rewards(&mut self) -> Result { + let epoch_budget = self.config.rewarding.epoch_budget.clone(); let denom = &epoch_budget.denom; let signing_budget = Coin::new( (self.config.rewarding.ratios.block_signing * epoch_budget.amount as f64) as u128, denom, ); - let credential_budget = Coin::new( + let credentials_budget = Coin::new( (self.config.rewarding.ratios.credential_issuance * epoch_budget.amount as f64) as u128, denom, ); - let signing_rewards = self.calculate_block_signing_rewards(signing_budget).await?; - let mut credential_rewards = self.calculate_credential_rewards(credential_budget).await?; + let signing_rewards = self.calculate_block_signing_rewards().await?; + let credential_rewards = self.calculate_credential_rewards().await?; - let mut rewards = signing_rewards; - rewards.append(&mut credential_rewards); - Ok(rewards) + Ok(EpochRewards { + epoch: self.current_epoch, + signing: signing_rewards, + credentials: credential_rewards, + total_budget: epoch_budget.clone(), + signing_budget, + credentials_budget, + }) } async fn send_rewards( &self, amounts: Vec<(AccountId, Vec)>, - ) -> Result<(), NymRewarderError> { - Ok(()) + ) -> Result { + let address = self.nyxd_client.address().await; + info!("here we ({address}) will be sending the following rewards:"); + for (target, amount) in amounts { + info!("{amount:?} to {target}") + } + + Ok(Hash::Sha256([0u8; 32])) } async fn handle_epoch_end(&mut self) { @@ -112,10 +148,14 @@ impl Rewarder { } }; - if let Err(err) = self.send_rewards(rewards).await { - error!("failed to send epoch rewards: {err}"); - return; - }; + let rewarding_result = self.send_rewards(rewards.amounts()).await; + if let Err(err) = self + .storage + .save_rewarding_information(rewards, rewarding_result) + .await + { + error!("failed to persist rewarding information: {err}") + } self.current_epoch = self.current_epoch.next(); } @@ -139,6 +179,7 @@ impl Rewarder { until_end.as_secs() ); let mut epoch_ticker = interval_at(Instant::now().add(until_end), Epoch::LENGTH); + let shutdown_future = task_manager.catch_interrupt(); pin!(shutdown_future); @@ -158,20 +199,6 @@ impl Rewarder { self.epoch_signing.nyxd_scraper.stop().await; - /* - task 1: - on timer: - - go to DKG contract - - get all coconut signers - - for each of them get the info, verify, etc - - task 2: - on timer (or maybe per block?): - - query abci endpoint for VP - - also maybe missed blocks, etc - - */ - - todo!() + Ok(()) } } diff --git a/nym-validator-rewarder/src/rewarder/nyxd_client.rs b/nym-validator-rewarder/src/rewarder/nyxd_client.rs index 7084e7c7f0..25f8bc46c6 100644 --- a/nym-validator-rewarder/src/rewarder/nyxd_client.rs +++ b/nym-validator-rewarder/src/rewarder/nyxd_client.rs @@ -2,6 +2,12 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::config::Config; +use crate::error::NymRewarderError; +use nym_validator_client::nyxd::error::NyxdError; +use nym_validator_client::nyxd::module_traits::staking::{ + QueryHistoricalInfoResponse, QueryValidatorResponse, QueryValidatorsResponse, +}; +use nym_validator_client::nyxd::{AccountId, CosmWasmClient, PageRequest, StakingQueryClient}; use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient}; use std::sync::Arc; use tokio::sync::RwLock; @@ -13,17 +19,14 @@ pub struct NyxdClient { impl NyxdClient { pub(crate) fn new(config: &Config) -> Self { - let details = config.get_network_details(); - let nyxd_url = config.get_nyxd_url(); - - let client_config = nyxd::Config::try_from_nym_network_details(&details) - .expect("failed to construct valid validator client config with the provided network"); + let client_config = config.rpc_client_config(); + let nyxd_url = config.base.upstream_nyxd.as_str(); let mnemonic = config.base.mnemonic.clone(); let inner = DirectSigningHttpRpcNyxdClient::connect_with_mnemonic( client_config, - nyxd_url.as_str(), + nyxd_url, mnemonic, ) .expect("Failed to connect to nyxd!"); @@ -32,4 +35,27 @@ impl NyxdClient { inner: Arc::new(RwLock::new(inner)), } } + + pub(crate) async fn address(&self) -> AccountId { + self.inner.read().await.address() + } + + pub(crate) async fn historical_info( + &self, + height: i64, + ) -> Result { + Ok(self.inner.read().await.historical_info(height).await?) + } + + pub(crate) async fn validators( + &self, + pagination: Option, + ) -> Result { + Ok(self + .inner + .read() + .await + .validators("".to_string(), pagination) + .await?) + } } diff --git a/nym-validator-rewarder/src/rewarder/storage/manager.rs b/nym-validator-rewarder/src/rewarder/storage/manager.rs new file mode 100644 index 0000000000..4c4c2d59fb --- /dev/null +++ b/nym-validator-rewarder/src/rewarder/storage/manager.rs @@ -0,0 +1,52 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::rewarder::epoch::Epoch; +use sqlx::types::time::OffsetDateTime; +use sqlx::{Executor, Sqlite}; +use tracing::{instrument, trace}; + +#[derive(Clone)] +pub(crate) struct StorageManager { + pub(crate) connection_pool: sqlx::SqlitePool, +} + +impl StorageManager { + pub(crate) async fn insert_rewarding_epoch( + &self, + epoch: Epoch, + rewarding_budget: String, + rewarding_tx: Option, + rewarding_error: Option, + ) -> Result<(), sqlx::Error> { + todo!() + } + + pub(crate) async fn insert_rewarding_epoch_block_signing( + &self, + epoch: i64, + total_voting_power_at_epoch_start: i64, + num_blocks: i64, + budget: String, + ) -> Result<(), sqlx::Error> { + todo!() + } + + pub(crate) async fn insert_rewarding_epoch_block_signing_reward( + &self, + ) -> Result<(), sqlx::Error> { + todo!() + } + + pub(crate) async fn insert_rewarding_epoch_credential_issuance( + &self, + ) -> Result<(), sqlx::Error> { + todo!() + } + + pub(crate) async fn insert_rewarding_epoch_credential_issuance_reward( + &self, + ) -> Result<(), sqlx::Error> { + todo!() + } +} diff --git a/nym-validator-rewarder/src/rewarder/storage/mod.rs b/nym-validator-rewarder/src/rewarder/storage/mod.rs new file mode 100644 index 0000000000..8227231f24 --- /dev/null +++ b/nym-validator-rewarder/src/rewarder/storage/mod.rs @@ -0,0 +1,64 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::error::NymRewarderError; +use crate::rewarder::storage::manager::StorageManager; +use crate::rewarder::EpochRewards; +use nym_validator_client::nyxd::Hash; +use sqlx::ConnectOptions; +use std::fmt::Debug; +use std::path::Path; +use tracing::{error, info, instrument}; + +mod manager; + +pub struct RewarderStorage { + pub(crate) manager: StorageManager, +} + +impl RewarderStorage { + #[instrument] + pub async fn init + Debug>(database_path: P) -> Result { + let mut opts = sqlx::sqlite::SqliteConnectOptions::new() + .filename(database_path) + .create_if_missing(true); + + // TODO: do we want auto_vacuum ? + + opts.disable_statement_logging(); + + let connection_pool = match sqlx::SqlitePool::connect_with(opts).await { + Ok(db) => db, + Err(err) => { + error!("Failed to connect to SQLx database: {err}"); + return Err(err.into()); + } + }; + + if let Err(err) = sqlx::migrate!("./migrations").run(&connection_pool).await { + error!("Failed to initialize SQLx database: {err}"); + return Err(err.into()); + } + + info!("Database migration finished!"); + + let manager = StorageManager { connection_pool }; + let storage = RewarderStorage { manager }; + + Ok(storage) + } + + pub(crate) async fn save_rewarding_information( + &self, + reward: EpochRewards, + rewarding_tx: Result, + ) -> Result<(), NymRewarderError> { + info!("persisting reward details"); + let (reward_tx, reward_err) = match rewarding_tx { + Ok(hash) => (Some(hash.to_string()), None), + Err(err) => (None, Some(err.to_string())), + }; + + Ok(()) + } +} From 31d8352621a5c1ffdf1429968f706c3ece1d74e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 15 Dec 2023 10:19:14 +0000 Subject: [PATCH 09/21] persisting rewarding data --- .../nyxd-scraper/src/block_processor/mod.rs | 11 +- common/nyxd-scraper/src/scraper/mod.rs | 11 ++ common/nyxd-scraper/src/storage/mod.rs | 2 +- .../migrations/01_initial.sql | 16 ++- .../src/rewarder/block_signing/mod.rs | 4 +- .../src/rewarder/block_signing/types.rs | 32 +++-- .../src/rewarder/credential_issuance/mod.rs | 4 +- .../src/rewarder/credential_issuance/types.rs | 6 +- nym-validator-rewarder/src/rewarder/epoch.rs | 21 +-- .../src/rewarder/helpers.rs | 1 + nym-validator-rewarder/src/rewarder/mod.rs | 17 ++- .../src/rewarder/storage/manager.rs | 125 +++++++++++++++++- .../src/rewarder/storage/mod.rs | 53 ++++++++ 13 files changed, 258 insertions(+), 45 deletions(-) diff --git a/common/nyxd-scraper/src/block_processor/mod.rs b/common/nyxd-scraper/src/block_processor/mod.rs index bb3e886b0e..d60be91e77 100644 --- a/common/nyxd-scraper/src/block_processor/mod.rs +++ b/common/nyxd-scraper/src/block_processor/mod.rs @@ -11,8 +11,10 @@ use crate::storage::{persist_block, ScraperStorage}; use futures::StreamExt; use std::collections::{BTreeMap, HashSet, VecDeque}; use std::ops::{Add, Range}; +use std::sync::Arc; use std::time::Duration; use tokio::sync::mpsc::{Sender, UnboundedReceiver}; +use tokio::sync::Notify; use tokio::time::{interval_at, Instant}; use tokio_stream::wrappers::UnboundedReceiverStream; use tokio_util::sync::CancellationToken; @@ -39,6 +41,7 @@ impl PendingSync { pub struct BlockProcessor { cancel: CancellationToken, + synced: Arc, last_processed_height: u32, last_processed_at: Instant, pending_sync: PendingSync, @@ -60,6 +63,7 @@ pub struct BlockProcessor { impl BlockProcessor { pub async fn new( cancel: CancellationToken, + synced: Arc, incoming: UnboundedReceiver, block_requester: Sender, storage: ScraperStorage, @@ -69,6 +73,7 @@ impl BlockProcessor { Ok(BlockProcessor { cancel, + synced, last_processed_height: last_processed.try_into().unwrap_or_default(), last_processed_at: Instant::now(), pending_sync: Default::default(), @@ -243,6 +248,10 @@ impl BlockProcessor { } self.try_request_pending().await; + + if self.pending_sync.is_empty() { + self.synced.notify_one(); + } } async fn try_request_pending(&mut self) -> bool { @@ -294,7 +303,7 @@ impl BlockProcessor { error!("failed to perform startup sync: {err}"); self.cancel.cancel(); return; - } + }; loop { tokio::select! { diff --git a/common/nyxd-scraper/src/scraper/mod.rs b/common/nyxd-scraper/src/scraper/mod.rs index fc994c3908..1e2529d9cd 100644 --- a/common/nyxd-scraper/src/scraper/mod.rs +++ b/common/nyxd-scraper/src/scraper/mod.rs @@ -9,9 +9,11 @@ use crate::rpc_client::RpcClient; use crate::scraper::subscriber::{run_websocket_driver, ChainSubscriber}; use crate::storage::ScraperStorage; use std::path::PathBuf; +use std::sync::Arc; use std::time::Duration; use tendermint_rpc::WebSocketClientDriver; use tokio::sync::mpsc::{channel, unbounded_channel}; +use tokio::sync::Notify; use tokio::time::interval; use tokio_util::sync::CancellationToken; use tokio_util::task::TaskTracker; @@ -56,6 +58,7 @@ impl NyxdScraperBuilder { ); let mut block_processor = BlockProcessor::new( scraper.cancel_token.clone(), + scraper.startup_sync.clone(), processing_rx, req_tx, scraper.storage.clone(), @@ -114,6 +117,7 @@ pub struct NyxdScraper { task_tracker: TaskTracker, cancel_token: CancellationToken, + startup_sync: Arc, pub storage: ScraperStorage, } @@ -129,6 +133,7 @@ impl NyxdScraper { config, task_tracker: TaskTracker::new(), cancel_token: CancellationToken::new(), + startup_sync: Arc::new(Default::default()), storage, }) } @@ -166,6 +171,7 @@ impl NyxdScraper { ); let block_processor = BlockProcessor::new( self.cancel_token.clone(), + self.startup_sync.clone(), processing_rx, req_tx, self.storage.clone(), @@ -191,6 +197,11 @@ impl NyxdScraper { Ok(()) } + pub async fn wait_for_startup_sync(&self) { + info!("awaiting startup chain sync"); + self.startup_sync.notified().await + } + pub async fn stop(self) { info!("stopping the chain scrapper"); assert!(self.task_tracker.is_closed()); diff --git a/common/nyxd-scraper/src/storage/mod.rs b/common/nyxd-scraper/src/storage/mod.rs index 6dba07ae0e..564f74d352 100644 --- a/common/nyxd-scraper/src/storage/mod.rs +++ b/common/nyxd-scraper/src/storage/mod.rs @@ -101,7 +101,7 @@ impl ScraperStorage { return Ok(0); }; - Ok(block_end - block_start + 1) + Ok(block_end - block_start) } pub async fn get_signed_between( diff --git a/nym-validator-rewarder/migrations/01_initial.sql b/nym-validator-rewarder/migrations/01_initial.sql index ab618ffc91..dfb1b33d01 100644 --- a/nym-validator-rewarder/migrations/01_initial.sql +++ b/nym-validator-rewarder/migrations/01_initial.sql @@ -28,9 +28,9 @@ CREATE TABLE block_signing_reward operator_account TEXT NOT NULL, amount TEXT NOT NULL, voting_power BIGINT NOT NULL, - voting_power_share DECIMAL NOT NULL, + voting_power_share TEXT NOT NULL, signed_blocks INTEGER NOT NULL, - signed_blocks_percent DECIMAL NOT NULL, + signed_blocks_percent TEXT NOT NULL, UNIQUE (rewarding_epoch_id, operator_account) ); @@ -51,11 +51,13 @@ CREATE TABLE malformed_credential CREATE TABLE credential_issuance_reward ( - rewarding_epoch_id INTEGER NOT NULL REFERENCES rewarding_epoch (id), - amount TEXT NOT NULL, - operator_account TEXT NOT NULL, - api_endpoint TEXT NOT NULL, - + rewarding_epoch_id INTEGER NOT NULL REFERENCES rewarding_epoch (id), + operator_account TEXT NOT NULL, + amount TEXT NOT NULL, + api_endpoint TEXT NOT NULL, + issued_partial_credentials INTEGER NOT NULL, + issued_credentials_share TEXT NOT NULL, + validated_issued_credentials INTEGER NOT NULL, UNIQUE (rewarding_epoch_id, operator_account) ); diff --git a/nym-validator-rewarder/src/rewarder/block_signing/mod.rs b/nym-validator-rewarder/src/rewarder/block_signing/mod.rs index 18f4e85f3a..01b05cbecf 100644 --- a/nym-validator-rewarder/src/rewarder/block_signing/mod.rs +++ b/nym-validator-rewarder/src/rewarder/block_signing/mod.rs @@ -86,8 +86,8 @@ impl EpochSigning { ); let validators = self.nyxd_scraper.storage.get_all_known_validators().await?; - let epoch_start = current_epoch.start; - let epoch_end = current_epoch.end; + let epoch_start = current_epoch.start_time; + let epoch_end = current_epoch.end_time; let first_block = self .nyxd_scraper .storage diff --git a/nym-validator-rewarder/src/rewarder/block_signing/types.rs b/nym-validator-rewarder/src/rewarder/block_signing/types.rs index a0e533e348..0b1b48f0f2 100644 --- a/nym-validator-rewarder/src/rewarder/block_signing/types.rs +++ b/nym-validator-rewarder/src/rewarder/block_signing/types.rs @@ -24,23 +24,19 @@ pub struct ValidatorSigning { } impl ValidatorSigning { + pub fn moniker(&self) -> String { + self.staking_details + .description + .as_ref() + .map(|d| d.moniker.clone()) + .unwrap_or("UNKNOWN MONIKER".to_string()) + } + pub fn reward_amount(&self, signing_budget: &Coin) -> Coin { let amount = Uint128::new(signing_budget.amount) * self.ratio_signed * self.voting_power_ratio; - let amount = Coin::new(amount.u128(), &signing_budget.denom); - let moniker = self - .staking_details - .description - .as_ref() - .map(|d| d.moniker.clone()) - .unwrap_or("UNKNOWN MONIKER".to_string()); - - info!( - "validator {moniker} will receive {amount} at address {} for block signing work", - self.operator_account - ); - amount + Coin::new(amount.u128(), &signing_budget.denom) } } @@ -84,6 +80,8 @@ impl EpochSigningResults { let signed: u64 = signed_blocks.try_into().unwrap_or_default(); let voting_power_ratio = Decimal::from_ratio(vp, total_vp_u64); + + debug_assert!(signed <= blocks_u64); let ratio_signed = Decimal::from_ratio(signed, blocks_u64); let staking_details = validator_details .remove(&validator.consensus_address) @@ -115,6 +113,14 @@ impl EpochSigningResults { pub fn rewarding_amounts(&self, budget: &Coin) -> Vec<(AccountId, Vec)> { self.validators .iter() + .inspect(|v| { + info!( + "validator {} will receive {} at address {} for block signing work", + v.moniker(), + v.reward_amount(budget), + v.operator_account + ); + }) .map(|v| (v.operator_account.clone(), vec![v.reward_amount(budget)])) .collect() } diff --git a/nym-validator-rewarder/src/rewarder/credential_issuance/mod.rs b/nym-validator-rewarder/src/rewarder/credential_issuance/mod.rs index 697d33d779..dfcad8507d 100644 --- a/nym-validator-rewarder/src/rewarder/credential_issuance/mod.rs +++ b/nym-validator-rewarder/src/rewarder/credential_issuance/mod.rs @@ -22,6 +22,8 @@ impl CredentialIssuance { current_epoch.end_rfc3339() ); - Ok(CredentialIssuanceResults {}) + Ok(CredentialIssuanceResults { + api_runners: Vec::new(), + }) } } diff --git a/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs b/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs index a0766af2a9..e2a4abcdc9 100644 --- a/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs +++ b/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs @@ -3,11 +3,13 @@ use nym_validator_client::nyxd::{AccountId, Coin}; -pub struct CredentialIssuanceResults {} +pub struct CredentialIssuanceResults { + pub api_runners: Vec<()>, +} impl CredentialIssuanceResults { pub fn rewarding_amounts(&self, budget: &Coin) -> Vec<(AccountId, Vec)> { let _ = budget; Vec::new() } -} \ No newline at end of file +} diff --git a/nym-validator-rewarder/src/rewarder/epoch.rs b/nym-validator-rewarder/src/rewarder/epoch.rs index f906f215f3..6df15b1e2b 100644 --- a/nym-validator-rewarder/src/rewarder/epoch.rs +++ b/nym-validator-rewarder/src/rewarder/epoch.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::error::NymRewarderError; +use sqlx::FromRow; use std::ops::Add; use std::time::Duration; use time::format_description::well_known::Rfc3339; @@ -9,12 +10,12 @@ use time::OffsetDateTime; const HOUR: Duration = Duration::from_secs(60 * 60); -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, FromRow)] pub struct Epoch { pub id: i64, - pub start: OffsetDateTime, - pub end: OffsetDateTime, + pub start_time: OffsetDateTime, + pub end_time: OffsetDateTime, } impl Epoch { @@ -29,33 +30,33 @@ impl Epoch { Ok(Epoch { id: 0, - start, - end: start + Self::LENGTH, + start_time: start, + end_time: start + Self::LENGTH, }) } pub fn until_end(&self) -> Duration { let now = OffsetDateTime::now_utc(); - (self.end - now).try_into().unwrap_or_default() + (self.end_time - now).try_into().unwrap_or_default() } pub fn next(&self) -> Self { Epoch { id: self.id + 1, - start: self.end, - end: self.end + Self::LENGTH, + start_time: self.end_time, + end_time: self.end_time + Self::LENGTH, } } pub fn start_rfc3339(&self) -> String { // safety: unwrap here is fine as we're using a predefined formatter #[allow(clippy::unwrap_used)] - self.start.format(&Rfc3339).unwrap() + self.start_time.format(&Rfc3339).unwrap() } pub fn end_rfc3339(&self) -> String { // safety: unwrap here is fine as we're using a predefined formatter #[allow(clippy::unwrap_used)] - self.end.format(&Rfc3339).unwrap() + self.end_time.format(&Rfc3339).unwrap() } } diff --git a/nym-validator-rewarder/src/rewarder/helpers.rs b/nym-validator-rewarder/src/rewarder/helpers.rs index 578d49c498..6b58fc60c1 100644 --- a/nym-validator-rewarder/src/rewarder/helpers.rs +++ b/nym-validator-rewarder/src/rewarder/helpers.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::error::NymRewarderError; +use cosmwasm_std::Decimal; use nym_validator_client::nyxd::{AccountId, PublicKey}; use nyxd_scraper::constants::{BECH32_CONSENSUS_ADDRESS_PREFIX, BECH32_PREFIX}; use sha2::{Digest, Sha256}; diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index 3372fad544..1619f297ab 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -65,9 +65,14 @@ impl Rewarder { let nyxd_scraper = NyxdScraper::new(config.scraper_config()).await?; let nyxd_client = NyxdClient::new(&config); let storage = RewarderStorage::init(&config.storage_paths.reward_history).await?; + let current_epoch = if let Some(last_epoch) = storage.load_last_rewarding_epoch().await? { + last_epoch.next() + } else { + Epoch::first()? + }; Ok(Rewarder { - current_epoch: Epoch::first()?, + current_epoch, config, epoch_signing: EpochSigning { nyxd_scraper, @@ -167,10 +172,16 @@ impl Rewarder { let mut task_manager = TaskManager::new(5); self.epoch_signing.nyxd_scraper.start().await?; + self.epoch_signing + .nyxd_scraper + .wait_for_startup_sync() + .await; // rewarding epochs last from :00 to :00 - self.current_epoch.end = OffsetDateTime::now_utc(); - self.current_epoch.start = self.current_epoch.end - Duration::from_secs(60 * 60); + // \/\/\/\/\/\/\/ TEMP TESTING!!! + self.current_epoch.end_time = OffsetDateTime::now_utc(); + self.current_epoch.start_time = self.current_epoch.end_time - Duration::from_secs(60 * 60); + // ^^^^^^^^^^^ TEMP TESTING!!! let until_end = self.current_epoch.until_end(); diff --git a/nym-validator-rewarder/src/rewarder/storage/manager.rs b/nym-validator-rewarder/src/rewarder/storage/manager.rs index 4c4c2d59fb..124589baaf 100644 --- a/nym-validator-rewarder/src/rewarder/storage/manager.rs +++ b/nym-validator-rewarder/src/rewarder/storage/manager.rs @@ -12,6 +12,19 @@ pub(crate) struct StorageManager { } impl StorageManager { + pub(crate) async fn load_last_rewarding_epoch(&self) -> Result, sqlx::Error> { + sqlx::query_as( + r#" + SELECT id, start_time, end_time + FROM rewarding_epoch + ORDER BY id DESC + LIMIT 1 + "#, + ) + .fetch_optional(&self.connection_pool) + .await + } + pub(crate) async fn insert_rewarding_epoch( &self, epoch: Epoch, @@ -19,7 +32,20 @@ impl StorageManager { rewarding_tx: Option, rewarding_error: Option, ) -> Result<(), sqlx::Error> { - todo!() + sqlx::query!( + r#" + INSERT INTO rewarding_epoch (id, start_time, end_time, budget, rewarding_tx, rewarding_error) + VALUES (?, ?, ? ,?, ?, ?) + "#, + epoch.id, + epoch.start_time, + epoch.end_time, + rewarding_budget, + rewarding_tx, + rewarding_error + ).execute(&self.connection_pool).await?; + + Ok(()) } pub(crate) async fn insert_rewarding_epoch_block_signing( @@ -29,24 +55,113 @@ impl StorageManager { num_blocks: i64, budget: String, ) -> Result<(), sqlx::Error> { - todo!() + sqlx::query!( + r#" + INSERT INTO epoch_block_signing (rewarding_epoch_id, total_voting_power_at_epoch_start, num_blocks, budget) + VALUES (?, ?, ?, ?) + "#, + epoch, + total_voting_power_at_epoch_start, + num_blocks, + budget, + ).execute(&self.connection_pool).await?; + + Ok(()) } pub(crate) async fn insert_rewarding_epoch_block_signing_reward( &self, + epoch: i64, + consensus_address: String, + operator_account: String, + amount: String, + voting_power: i64, + voting_power_share: String, + signed_blocks: i32, + signed_blocks_percent: String, ) -> Result<(), sqlx::Error> { - todo!() + sqlx::query!( + r#" + INSERT INTO block_signing_reward ( + rewarding_epoch_id, + validator_consensus_address, + operator_account, + amount, + voting_power, + voting_power_share, + signed_blocks, + signed_blocks_percent + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?) + "#, + epoch, + consensus_address, + operator_account, + amount, + voting_power, + voting_power_share, + signed_blocks, + signed_blocks_percent, + ) + .execute(&self.connection_pool) + .await?; + + Ok(()) } pub(crate) async fn insert_rewarding_epoch_credential_issuance( &self, + epoch: i64, + dkg_epoch_id: u32, + total_issued_credentials: u32, + budget: String, ) -> Result<(), sqlx::Error> { - todo!() + sqlx::query!( + r#" + INSERT INTO epoch_credential_issuance (rewarding_epoch_id, dkg_epoch_id, total_issued_credentials, budget) + VALUES (?, ?, ?, ?) + "#, + epoch, + dkg_epoch_id, + total_issued_credentials, + budget, + ).execute(&self.connection_pool).await?; + + Ok(()) } pub(crate) async fn insert_rewarding_epoch_credential_issuance_reward( &self, + epoch: i64, + operator_account: String, + amount: String, + api_endpoint: String, + issued_partial_credentials: u32, + issued_credentials_share: String, + validated_issued_credentials: u32, ) -> Result<(), sqlx::Error> { - todo!() + sqlx::query!( + r#" + INSERT INTO credential_issuance_reward ( + rewarding_epoch_id, + operator_account, + amount, + api_endpoint, + issued_partial_credentials, + issued_credentials_share, + validated_issued_credentials + ) VALUES (?, ?, ?, ?, ?, ?, ?) + "#, + epoch, + operator_account, + amount, + api_endpoint, + issued_partial_credentials, + issued_credentials_share, + validated_issued_credentials, + ) + .execute(&self.connection_pool) + .await?; + + Ok(()) } } diff --git a/nym-validator-rewarder/src/rewarder/storage/mod.rs b/nym-validator-rewarder/src/rewarder/storage/mod.rs index 8227231f24..5c204ac811 100644 --- a/nym-validator-rewarder/src/rewarder/storage/mod.rs +++ b/nym-validator-rewarder/src/rewarder/storage/mod.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::error::NymRewarderError; +use crate::rewarder::epoch::Epoch; use crate::rewarder::storage::manager::StorageManager; use crate::rewarder::EpochRewards; use nym_validator_client::nyxd::Hash; @@ -48,6 +49,12 @@ impl RewarderStorage { Ok(storage) } + pub(crate) async fn load_last_rewarding_epoch( + &self, + ) -> Result, NymRewarderError> { + Ok(self.manager.load_last_rewarding_epoch().await?) + } + pub(crate) async fn save_rewarding_information( &self, reward: EpochRewards, @@ -59,6 +66,52 @@ impl RewarderStorage { Err(err) => (None, Some(err.to_string())), }; + let epoch_id = reward.epoch.id; + + self.manager + .insert_rewarding_epoch( + reward.epoch, + reward.total_budget.to_string(), + reward_tx, + reward_err, + ) + .await?; + + self.manager + .insert_rewarding_epoch_block_signing( + epoch_id, + reward.signing.total_voting_power_at_epoch_start, + reward.signing.blocks, + reward.signing_budget.to_string(), + ) + .await?; + + for validator in reward.signing.validators { + let reward_amount = validator.reward_amount(&reward.signing_budget).to_string(); + self.manager + .insert_rewarding_epoch_block_signing_reward( + epoch_id, + validator.validator.consensus_address, + validator.operator_account.to_string(), + reward_amount, + validator.voting_power_at_epoch_start, + validator.voting_power_ratio.to_string(), + validator.signed_blocks, + validator.ratio_signed.to_string(), + ) + .await?; + } + // + // self.manager + // .insert_rewarding_epoch_credential_issuance(epoch_id) + // .await?; + // + // for api_runner in reward.credentials.api_runners { + // self.manager + // .insert_rewarding_epoch_credential_issuance_reward(epoch_id) + // .await?; + // } + Ok(()) } } From 668a255e0d4b06d8edc512d9a22b67b45080a841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 15 Dec 2023 11:46:57 +0000 Subject: [PATCH 10/21] issuance score calculation logic --- common/nyxd-scraper/src/scraper/mod.rs | 2 - nym-validator-rewarder/src/config/mod.rs | 42 ++++- .../src/rewarder/block_signing/mod.rs | 4 +- .../src/rewarder/block_signing/types.rs | 26 ++- .../src/rewarder/credential_issuance/mod.rs | 44 ++++- .../rewarder/credential_issuance/monitor.rs | 56 ++++++ .../src/rewarder/credential_issuance/types.rs | 173 +++++++++++++++++- nym-validator-rewarder/src/rewarder/epoch.rs | 9 +- nym-validator-rewarder/src/rewarder/mod.rs | 22 ++- 9 files changed, 347 insertions(+), 31 deletions(-) create mode 100644 nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs diff --git a/common/nyxd-scraper/src/scraper/mod.rs b/common/nyxd-scraper/src/scraper/mod.rs index 1e2529d9cd..f417318227 100644 --- a/common/nyxd-scraper/src/scraper/mod.rs +++ b/common/nyxd-scraper/src/scraper/mod.rs @@ -10,11 +10,9 @@ use crate::scraper::subscriber::{run_websocket_driver, ChainSubscriber}; use crate::storage::ScraperStorage; use std::path::PathBuf; use std::sync::Arc; -use std::time::Duration; use tendermint_rpc::WebSocketClientDriver; use tokio::sync::mpsc::{channel, unbounded_channel}; use tokio::sync::Notify; -use tokio::time::interval; use tokio_util::sync::CancellationToken; use tokio_util::task::TaskTracker; use tracing::info; diff --git a/nym-validator-rewarder/src/config/mod.rs b/nym-validator-rewarder/src/config/mod.rs index 6c9c86cbac..ae3c175236 100644 --- a/nym-validator-rewarder/src/config/mod.rs +++ b/nym-validator-rewarder/src/config/mod.rs @@ -11,7 +11,7 @@ use nym_config::{ }; use nym_network_defaults::NymNetworkDetails; use nym_validator_client::nyxd; -use nym_validator_client::nyxd::Coin; +use nym_validator_client::nyxd::{AccountId, Coin}; use serde::{Deserialize, Serialize}; use std::io; use std::path::{Path, PathBuf}; @@ -31,6 +31,9 @@ const DEFAULT_MIX_REWARDING_BUDGET: u128 = 1000_000000; 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; /// Get default path to rewarder's config directory. /// It should get resolved to `$HOME/.nym/validators-rewarder/config` @@ -66,6 +69,9 @@ pub struct Config { #[zeroize(skip)] pub rewarding: Rewarding, + #[zeroize(skip)] + pub issuance_monitor: IssuanceMonitor, + #[zeroize(skip)] pub nyxd_scraper: NyxdScraper, @@ -89,6 +95,7 @@ impl Config { Config { save_path: None, rewarding: Rewarding::default(), + issuance_monitor: IssuanceMonitor::default(), nyxd_scraper: NyxdScraper { websocket_url: network.endpoints[0] .websocket_url() @@ -116,6 +123,16 @@ impl Config { .expect("failed to create nyxd client config") } + pub fn dkg_contract_address(&self) -> AccountId { + // TEMP + NymNetworkDetails::new_from_env() + .contracts + .coconut_dkg_contract_address + .expect("missing contract address") + .parse() + .expect("invalid contract address") + } + pub fn ensure_is_valid(&self) -> Result<(), NymRewarderError> { self.rewarding.ratios.ensure_is_valid()?; Ok(()) @@ -237,3 +254,26 @@ pub struct NyxdScraper { pub websocket_url: Url, // TODO: debug with everything that's currently hardcoded in the scraper } + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct IssuanceMonitor { + #[serde(with = "humantime_serde")] + pub run_interval: Duration, + + /// Defines the minimum number of credentials the monitor will validate + /// regardless of the sampling rate + pub min_validate_per_issuer: u32, + + /// The sampling rate of the issued credentials + pub sampling_rate: f32, +} + +impl Default for IssuanceMonitor { + fn default() -> Self { + IssuanceMonitor { + run_interval: DEFAULT_MONITOR_RUN_INTERVAL, + min_validate_per_issuer: DEFAULT_MONITOR_MIN_VALIDATE, + sampling_rate: DEFAULT_MONITOR_SAMPLING_RATE, + } + } +} diff --git a/nym-validator-rewarder/src/rewarder/block_signing/mod.rs b/nym-validator-rewarder/src/rewarder/block_signing/mod.rs index 01b05cbecf..4fcc75bc66 100644 --- a/nym-validator-rewarder/src/rewarder/block_signing/mod.rs +++ b/nym-validator-rewarder/src/rewarder/block_signing/mod.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::error::NymRewarderError; -use crate::rewarder::block_signing::types::EpochSigningResults; +use crate::rewarder::block_signing::types::{EpochSigningResults, RawValidatorResult}; use crate::rewarder::epoch::Epoch; use crate::rewarder::nyxd_client::NyxdClient; use nym_validator_client::nyxd::module_traits::staking; @@ -123,7 +123,7 @@ impl EpochSigning { .storage .get_signed_between_times(&validator.consensus_address, epoch_start, epoch_end) .await?; - signed_in_epoch.insert(validator, (signed, vp)); + signed_in_epoch.insert(validator, RawValidatorResult::new(signed, vp)); } let total = self diff --git a/nym-validator-rewarder/src/rewarder/block_signing/types.rs b/nym-validator-rewarder/src/rewarder/block_signing/types.rs index 0b1b48f0f2..bd28b2f49d 100644 --- a/nym-validator-rewarder/src/rewarder/block_signing/types.rs +++ b/nym-validator-rewarder/src/rewarder/block_signing/types.rs @@ -48,11 +48,25 @@ pub struct EpochSigningResults { pub validators: Vec, } +pub struct RawValidatorResult { + pub signed_blocks: i32, + pub voting_power: i64, +} + +impl RawValidatorResult { + pub fn new(signed_blocks: i32, voting_power: i64) -> Self { + Self { + signed_blocks, + voting_power, + } + } +} + impl EpochSigningResults { pub fn construct( blocks: i64, total_vp: i64, - validator_results: HashMap, + validator_results: HashMap, validator_details: Vec, ) -> Result { let Ok(total_vp_u64): Result = total_vp.try_into() else { @@ -75,9 +89,9 @@ impl EpochSigningResults { let mut validators = Vec::new(); - for (validator, (signed_blocks, voting_power_at_epoch_start)) in validator_results { - let vp: u64 = voting_power_at_epoch_start.try_into().unwrap_or_default(); - let signed: u64 = signed_blocks.try_into().unwrap_or_default(); + for (validator, raw_results) in validator_results { + let vp: u64 = raw_results.voting_power.try_into().unwrap_or_default(); + let signed: u64 = raw_results.signed_blocks.try_into().unwrap_or_default(); let voting_power_ratio = Decimal::from_ratio(vp, total_vp_u64); @@ -96,9 +110,9 @@ impl EpochSigningResults { validator, staking_details, operator_account, - voting_power_at_epoch_start, + voting_power_at_epoch_start: raw_results.voting_power, voting_power_ratio, - signed_blocks, + signed_blocks: raw_results.signed_blocks, ratio_signed, }) } diff --git a/nym-validator-rewarder/src/rewarder/credential_issuance/mod.rs b/nym-validator-rewarder/src/rewarder/credential_issuance/mod.rs index dfcad8507d..3dbcc008c9 100644 --- a/nym-validator-rewarder/src/rewarder/credential_issuance/mod.rs +++ b/nym-validator-rewarder/src/rewarder/credential_issuance/mod.rs @@ -2,16 +2,48 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::error::NymRewarderError; -use crate::rewarder::credential_issuance::types::CredentialIssuanceResults; +use crate::rewarder::credential_issuance::monitor::CredentialIssuanceMonitor; +use crate::rewarder::credential_issuance::types::{CredentialIssuanceResults, MonitoringResults}; use crate::rewarder::epoch::Epoch; +use nym_task::TaskClient; +use nym_validator_client::nyxd::AccountId; +use std::time::Duration; use tracing::info; +mod monitor; pub mod types; -pub struct CredentialIssuance {} +pub struct CredentialIssuance { + monitoring_run_interval: Duration, + monitoring_results: MonitoringResults, + dkg_contract_address: AccountId, +} impl CredentialIssuance { - pub(crate) async fn get_signed_blocks_results( + pub(crate) fn new( + epoch: Epoch, + monitoring_run_interval: Duration, + dkg_contract_address: AccountId, + ) -> Self { + CredentialIssuance { + monitoring_run_interval, + monitoring_results: MonitoringResults::new(epoch), + dkg_contract_address, + } + } + + pub(crate) fn start_monitor(&self, task_client: TaskClient) { + let monitoring_results = self.monitoring_results.clone(); + let mut monitor = CredentialIssuanceMonitor::new( + self.monitoring_run_interval, + self.dkg_contract_address.clone(), + monitoring_results, + ); + + tokio::spawn(async move { monitor.run(task_client).await }); + } + + pub(crate) async fn get_issued_credentials_results( &self, current_epoch: Epoch, ) -> Result { @@ -22,8 +54,8 @@ impl CredentialIssuance { current_epoch.end_rfc3339() ); - Ok(CredentialIssuanceResults { - api_runners: Vec::new(), - }) + let raw_results = self.monitoring_results.finish_epoch().await; + + Ok(raw_results.into()) } } diff --git a/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs b/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs new file mode 100644 index 0000000000..f18dd35a96 --- /dev/null +++ b/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs @@ -0,0 +1,56 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::error::NymRewarderError; +use crate::rewarder::credential_issuance::types::MonitoringResults; +use nym_task::TaskClient; +use nym_validator_client::nyxd::AccountId; +use std::time::Duration; +use tokio::time::interval; +use tracing::{error, info}; + +pub struct CredentialIssuanceMonitor { + run_interval: Duration, + dkg_contract_address: AccountId, + monitoring_results: MonitoringResults, +} + +impl CredentialIssuanceMonitor { + pub fn new( + run_interval: Duration, + dkg_contract_address: AccountId, + monitoring_results: MonitoringResults, + ) -> CredentialIssuanceMonitor { + CredentialIssuanceMonitor { + run_interval, + dkg_contract_address, + monitoring_results, + } + } + + // 1. if not present -> go to DKG contract and grab the accounts + endpoints + + async fn check_issuers(&mut self) -> Result<(), NymRewarderError> { + Ok(()) + } + + pub async fn run(&mut self, mut task_client: TaskClient) { + info!("starting"); + let mut run_interval = interval(self.run_interval); + + while !task_client.is_shutdown() { + tokio::select! { + biased; + _ = task_client.recv() => { + info!("received shutdown"); + break + } + _ = run_interval.tick() => { + if let Err(err) = self.check_issuers().await { + error!("failed to perform credential issuance check: {err}") + } + } + } + } + } +} diff --git a/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs b/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs index e2a4abcdc9..b086efb2d2 100644 --- a/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs +++ b/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs @@ -1,15 +1,182 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::rewarder::epoch::Epoch; +use cosmwasm_std::{Decimal, Uint128}; use nym_validator_client::nyxd::{AccountId, Coin}; +use std::mem; +use std::sync::Arc; +use tokio::sync::Mutex; +use tracing::{error, info}; + +#[derive(Clone)] +pub struct MonitoringResults { + inner: Arc>, +} + +impl MonitoringResults { + pub(crate) fn new(initial_epoch: Epoch) -> Self { + MonitoringResults { + inner: Arc::new(Mutex::new(MonitoringResultsInner::new(initial_epoch))), + } + } + + pub(crate) async fn api_endpoints(&self) -> Vec { + self.inner + .lock() + .await + .operators + .iter() + .map(|o| o.api_runner.clone()) + .collect() + } + + pub(crate) async fn set_epoch_operators( + &self, + dkg_epoch: u32, + operators: Vec<(String, AccountId)>, + ) { + let mut guard = self.inner.lock().await; + guard.operators = operators + .into_iter() + .map(|(api_runner, runner_account)| RawOperatorIssuing { + api_runner, + runner_account, + issued_credentials: 0, + validated_credentials: 0, + }) + .collect(); + guard.dkg_epoch = Some(dkg_epoch) + } + + pub(crate) async fn append_run_results(&self, results: Vec<(String, RawOperatorResult)>) { + let mut guard = self.inner.lock().await; + + // sure, a hashmap would have been quicker, but we'll have at most 30-40 runners so + // performance overhead is negligible + for (api_runner, results) in results { + if let Some(entry) = guard + .operators + .iter_mut() + .find(|o| o.api_runner == api_runner) + { + entry.issued_credentials += results.issued_credentials; + entry.validated_credentials += results.validated_credentials; + } else { + error!("somehow could not find operator results for runner {api_runner}!") + } + } + } + + pub(crate) async fn finish_epoch(&self) -> MonitoringResultsInner { + let mut guard = self.inner.lock().await; + let next_epoch = guard.epoch.next(); + let next_results = MonitoringResultsInner::new(next_epoch); + mem::replace(&mut guard, next_results) + } +} + +pub(crate) struct MonitoringResultsInner { + pub(crate) epoch: Epoch, + pub(crate) dkg_epoch: Option, + pub(crate) operators: Vec, +} + +impl From for CredentialIssuanceResults { + fn from(value: MonitoringResultsInner) -> Self { + // approximation! + let total_issued = value + .operators + .iter() + .map(|o| o.issued_credentials) + .max() + .unwrap_or_default(); + + CredentialIssuanceResults { + total_issued, + dkg_epoch: value.dkg_epoch, + api_runners: value + .operators + .into_iter() + .map(|runner| { + let issued_ratio = if total_issued == 0 { + Decimal::zero() + } else { + Decimal::from_ratio(runner.issued_credentials, total_issued) + }; + OperatorIssuing { + api_runner: runner.api_runner, + runner_account: runner.runner_account, + issued_ratio, + issued_credentials: runner.issued_credentials, + validated_credentials: runner.validated_credentials, + } + }) + .collect(), + } + } +} + +impl MonitoringResultsInner { + fn new(epoch: Epoch) -> MonitoringResultsInner { + MonitoringResultsInner { + epoch, + dkg_epoch: None, + operators: vec![], + } + } +} + +pub(crate) struct RawOperatorResult { + pub(crate) issued_credentials: u32, + pub(crate) validated_credentials: u32, +} + +pub struct RawOperatorIssuing { + pub api_runner: String, + pub runner_account: AccountId, + + pub issued_credentials: u32, + pub validated_credentials: u32, +} + +pub struct OperatorIssuing { + pub api_runner: String, + pub runner_account: AccountId, + + pub issued_ratio: Decimal, + pub issued_credentials: u32, + pub validated_credentials: u32, +} + +impl OperatorIssuing { + pub fn reward_amount(&self, signing_budget: &Coin) -> Coin { + let amount = Uint128::new(signing_budget.amount) * self.issued_ratio; + + Coin::new(amount.u128(), &signing_budget.denom) + } +} pub struct CredentialIssuanceResults { - pub api_runners: Vec<()>, + // note: this is an approximation! + pub total_issued: u32, + pub dkg_epoch: Option, + pub api_runners: Vec, } impl CredentialIssuanceResults { pub fn rewarding_amounts(&self, budget: &Coin) -> Vec<(AccountId, Vec)> { - let _ = budget; - Vec::new() + self.api_runners + .iter() + .inspect(|a| { + info!( + "operator {} will receive {} at address {} for credential issuance work", + a.api_runner, + a.reward_amount(budget), + a.runner_account, + ); + }) + .map(|v| (v.runner_account.clone(), vec![v.reward_amount(budget)])) + .collect() } } diff --git a/nym-validator-rewarder/src/rewarder/epoch.rs b/nym-validator-rewarder/src/rewarder/epoch.rs index 6df15b1e2b..1b828da883 100644 --- a/nym-validator-rewarder/src/rewarder/epoch.rs +++ b/nym-validator-rewarder/src/rewarder/epoch.rs @@ -19,9 +19,7 @@ pub struct Epoch { } impl Epoch { - pub const LENGTH: Duration = HOUR; - - pub fn first() -> Result { + pub fn first(epoch_duration: Duration) -> Result { let start = OffsetDateTime::now_utc() .add(HOUR) .replace_nanosecond(0)? @@ -31,7 +29,7 @@ impl Epoch { Ok(Epoch { id: 0, start_time: start, - end_time: start + Self::LENGTH, + end_time: start + epoch_duration, }) } @@ -41,10 +39,11 @@ impl Epoch { } pub fn next(&self) -> Self { + let duration = self.end_time - self.start_time; Epoch { id: self.id + 1, start_time: self.end_time, - end_time: self.end_time + Self::LENGTH, + end_time: self.end_time + duration, } } diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index 1619f297ab..a1604f133f 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -41,7 +41,7 @@ pub struct EpochRewards { impl EpochRewards { pub fn amounts(&self) -> Vec<(AccountId, Vec)> { let signing = self.signing.rewarding_amounts(&self.signing_budget); - let mut credentials = Vec::new(); + let mut credentials = self.credentials.rewarding_amounts(&self.credentials_budget); let mut amounts = signing; amounts.append(&mut credentials); @@ -63,24 +63,29 @@ pub struct Rewarder { impl Rewarder { pub async fn new(config: Config) -> Result { let nyxd_scraper = NyxdScraper::new(config.scraper_config()).await?; + let dkg_contract = config.dkg_contract_address(); let nyxd_client = NyxdClient::new(&config); let storage = RewarderStorage::init(&config.storage_paths.reward_history).await?; let current_epoch = if let Some(last_epoch) = storage.load_last_rewarding_epoch().await? { last_epoch.next() } else { - Epoch::first()? + Epoch::first(config.rewarding.epoch_duration)? }; Ok(Rewarder { current_epoch, - config, + credential_issuance: CredentialIssuance::new( + current_epoch, + config.issuance_monitor.run_interval, + dkg_contract, + ), epoch_signing: EpochSigning { nyxd_scraper, nyxd_client: nyxd_client.clone(), }, nyxd_client, storage, - credential_issuance: CredentialIssuance {}, + config, }) } @@ -100,7 +105,7 @@ impl Rewarder { ) -> Result { info!("calculating reward shares"); self.credential_issuance - .get_signed_blocks_results(self.current_epoch) + .get_issued_credentials_results(self.current_epoch) .await } @@ -171,6 +176,8 @@ impl Rewarder { // setup shutdowns let mut task_manager = TaskManager::new(5); + self.credential_issuance + .start_monitor(task_manager.subscribe()); self.epoch_signing.nyxd_scraper.start().await?; self.epoch_signing .nyxd_scraper @@ -189,7 +196,10 @@ impl Rewarder { "the first epoch will finish in {} secs", until_end.as_secs() ); - let mut epoch_ticker = interval_at(Instant::now().add(until_end), Epoch::LENGTH); + let mut epoch_ticker = interval_at( + Instant::now().add(until_end), + self.config.rewarding.epoch_duration, + ); let shutdown_future = task_manager.catch_interrupt(); pin!(shutdown_future); From cfc13671a4c4e3bf99ce924de1c2c0e04965c7a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 15 Dec 2023 16:52:02 +0000 Subject: [PATCH 11/21] most of the issuance monitoring logic --- Cargo.lock | 1272 ++++++++--------- .../validator-client/src/nym_api/mod.rs | 31 +- .../nyxd/contract_traits/dkg_query_client.rs | 10 +- common/nymcoconut/src/lib.rs | 2 + common/nymcoconut/src/scheme/issuance.rs | 15 +- .../nym-api-requests/src/coconut/models.rs | 6 +- nym-api/src/coconut/api_routes/helpers.rs | 4 +- nym-api/src/coconut/storage/models.rs | 9 +- nym-api/src/coconut/tests/mod.rs | 4 +- nym-validator-rewarder/Cargo.toml | 4 + .../migrations/01_initial.sql | 13 +- nym-validator-rewarder/src/config/mod.rs | 2 +- nym-validator-rewarder/src/error.rs | 58 + .../src/rewarder/credential_issuance/mod.rs | 25 +- .../rewarder/credential_issuance/monitor.rs | 240 +++- .../src/rewarder/credential_issuance/types.rs | 96 +- .../src/rewarder/helpers.rs | 1 - nym-validator-rewarder/src/rewarder/mod.rs | 18 +- .../src/rewarder/nyxd_client.rs | 62 +- .../src/rewarder/storage/manager.rs | 6 +- .../src/rewarder/storage/mod.rs | 1 + 21 files changed, 1095 insertions(+), 784 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eb1e717ee6..f6b5946315 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,8 +35,8 @@ dependencies = [ "actix-rt", "actix-service", "actix-utils", - "ahash 0.8.6", - "base64 0.21.5", + "ahash 0.8.3", + "base64 0.21.4", "bitflags 2.4.1", "brotli", "bytes", @@ -71,7 +71,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -109,7 +109,7 @@ dependencies = [ "futures-core", "futures-util", "mio", - "socket2 0.5.5", + "socket2 0.5.4", "tokio", "tracing", ] @@ -150,7 +150,7 @@ dependencies = [ "actix-service", "actix-utils", "actix-web-codegen", - "ahash 0.8.6", + "ahash 0.8.3", "bytes", "bytestring", "cfg-if", @@ -170,7 +170,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "smallvec", - "socket2 0.5.5", + "socket2 0.5.4", "time", "url", ] @@ -184,7 +184,7 @@ dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -316,26 +316,25 @@ dependencies = [ [[package]] name = "ahash" -version = "0.7.7" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom 0.2.11", + "getrandom 0.2.10", "once_cell", "version_check", ] [[package]] name = "ahash" -version = "0.8.6" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ "cfg-if", - "getrandom 0.2.11", + "getrandom 0.2.10", "once_cell", "version_check", - "zerocopy", ] [[package]] @@ -387,7 +386,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c494134f746c14dc653a35a4ea5aca24ac368529da5370ecf41fe0341c35772f" dependencies = [ "android_log-sys", - "env_logger 0.10.1", + "env_logger 0.10.0", "log", "once_cell", ] @@ -409,9 +408,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.5" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" dependencies = [ "anstyle", "anstyle-parse", @@ -429,30 +428,30 @@ checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.48.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.48.0", ] [[package]] @@ -484,9 +483,9 @@ dependencies = [ [[package]] name = "array-bytes" -version = "6.2.2" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f840fb7195bcfc5e17ea40c26e5ce6d5b9ce5d584466e17703209657e459ae0" +checksum = "d9b1c5a481ec30a5abd8dfbd94ab5cf1bb4e9a66be7f1b3b322f2f1170c200fd" [[package]] name = "arrayref" @@ -586,7 +585,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" dependencies = [ "concurrent-queue", - "event-listener 2.5.3", + "event-listener", "futures-core", ] @@ -602,32 +601,31 @@ dependencies = [ [[package]] name = "async-io" -version = "2.2.2" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6afaa937395a620e33dc6a742c593c01aced20aa376ffb0f628121198578ccc7" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" dependencies = [ "async-lock", + "autocfg 1.1.0", "cfg-if", "concurrent-queue", - "futures-io", - "futures-lite 2.1.0", + "futures-lite", + "log", "parking", - "polling 3.3.1", - "rustix", + "polling", + "rustix 0.37.25", "slab", - "tracing", - "windows-sys 0.52.0", + "socket2 0.4.9", + "waker-fn", ] [[package]] name = "async-lock" -version = "3.2.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7125e42787d53db9dd54261812ef17e937c95a51e4d291373b670342fa44310c" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" dependencies = [ - "event-listener 4.0.0", - "event-listener-strategy", - "pin-project-lite 0.2.13", + "event-listener", ] [[package]] @@ -649,7 +647,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -660,7 +658,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -838,9 +836,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.5" +version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" [[package]] name = "base64ct" @@ -1027,9 +1025,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "2.5.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" +checksum = "da74e2b81409b1b743f8f0c62cc6254afefb8b8e50bbfe3735550f7aeefa3448" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -1095,9 +1093,9 @@ dependencies = [ [[package]] name = "bytestring" -version = "1.3.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d80203ea6b29df88012294f62733de21cfeab47f17b41af3a38bc30a03ee72" +checksum = "238e4886760d98c4f899360c834fa93e62cf7f721ac3c2da375cbdf4b8679aae" dependencies = [ "bytes", ] @@ -1119,7 +1117,7 @@ checksum = "f769ab9e8c1652d78dd0b3ec59cdaa1e2bcb3b6b39f6681b256abcdbe101cc14" dependencies = [ "anyhow", "cargo_metadata", - "clap 4.4.11", + "clap 4.4.7", "concolor-control", "crates-index", "dirs-next", @@ -1144,9 +1142,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.5" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34637b3140142bdf929fb439e8aa4ebad7651ebf7b1080b3930aa16ac1459ff" +checksum = "12024c4645c97566567129c204f65d5815a8c9aecf30fcbe682b2fe034996d36" dependencies = [ "serde", ] @@ -1220,6 +1218,18 @@ dependencies = [ "keystream", ] +[[package]] +name = "chacha20" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c80e5460aa66fe3b91d40bcbdab953a597b60053e34d684ac6903f863b680a6" +dependencies = [ + "cfg-if", + "cipher 0.3.0", + "cpufeatures", + "zeroize", +] + [[package]] name = "chacha20" version = "0.9.1" @@ -1231,6 +1241,19 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "chacha20poly1305" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18446b09be63d457bbec447509e85f662f32952b035ce892290396bc0b0cff5" +dependencies = [ + "aead 0.4.3", + "chacha20 0.8.2", + "cipher 0.3.0", + "poly1305 0.7.2", + "zeroize", +] + [[package]] name = "chacha20poly1305" version = "0.10.1" @@ -1238,9 +1261,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ "aead 0.5.2", - "chacha20", + "chacha20 0.9.1", "cipher 0.4.4", - "poly1305", + "poly1305 0.8.0", "zeroize", ] @@ -1329,9 +1352,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.11" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" +checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" dependencies = [ "clap_builder", "clap_derive", @@ -1339,9 +1362,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.11" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" +checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" dependencies = [ "anstream", "anstyle", @@ -1352,20 +1375,20 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.4.4" +version = "4.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffe91f06a11b4b9420f62103854e90867812cd5d01557f853c5ee8e791b12ae" +checksum = "e3ae8ba90b9d8b007efe66e55e48fb936272f5ca00349b5b0e89877520d35ea7" dependencies = [ - "clap 4.4.11", + "clap 4.4.7", ] [[package]] name = "clap_complete_fig" -version = "4.4.2" +version = "4.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87e571d70e22ec91d34e1c5317c8308035a2280d925167646bf094fc5de1737c" +checksum = "29bdbe21a263b628f83fcbeac86a4416a1d588c7669dd41473bc4149e4e7d2f1" dependencies = [ - "clap 4.4.11", + "clap 4.4.7", "clap_complete", ] @@ -1378,7 +1401,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -1413,10 +1436,11 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "colored" -version = "2.1.0" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" dependencies = [ + "is-terminal", "lazy_static", "windows-sys 0.48.0", ] @@ -1462,18 +1486,18 @@ checksum = "ad159cc964ac8f9d407cbc0aa44b02436c054b541f2b4b5f06972e1efdc54bc7" [[package]] name = "concurrent-queue" -version = "2.4.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +checksum = "f057a694a54f12365049b0958a1685bb52d567f5593b355fbf685838e873d400" dependencies = [ "crossbeam-utils", ] [[package]] name = "config" -version = "0.13.4" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23738e11972c7643e4ec947840fc463b6a571afcd3e735bdfce7d03c7a784aca" +checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7" dependencies = [ "async-trait", "lazy_static", @@ -1591,9 +1615,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.4" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ "core-foundation-sys", "libc", @@ -1601,9 +1625,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "core2" @@ -1620,8 +1644,8 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32560304ab4c365791fd307282f76637213d8083c1a98490c35159cd67852237" dependencies = [ - "prost 0.12.3", - "prost-types 0.12.3", + "prost 0.12.1", + "prost-types 0.12.1", "tendermint-proto", ] @@ -1630,8 +1654,8 @@ name = "cosmos-sdk-proto" version = "0.20.0" source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features#41ed4631e146268b0300033c8bbb993d79a49f58" dependencies = [ - "prost 0.12.3", - "prost-types 0.12.3", + "prost 0.12.1", + "prost-types 0.12.1", "tendermint-proto", ] @@ -1643,13 +1667,13 @@ checksum = "47126f5364df9387b9d8559dcef62e99010e1d4098f39eb3f7ee4b5c254e40ea" dependencies = [ "bip32", "cosmos-sdk-proto 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ecdsa 0.16.9", + "ecdsa 0.16.8", "eyre", "k256", "rand_core 0.6.4", "serde", "serde_json", - "signature 2.2.0", + "signature 2.1.0", "subtle-encoding", "tendermint", "thiserror", @@ -1662,13 +1686,13 @@ source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-valida dependencies = [ "bip32", "cosmos-sdk-proto 0.20.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", - "ecdsa 0.16.9", + "ecdsa 0.16.8", "eyre", "k256", "rand_core 0.6.4", "serde", "serde_json", - "signature 2.2.0", + "signature 2.1.0", "subtle-encoding", "tendermint", "tendermint-rpc", @@ -1677,12 +1701,11 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.5.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8bb3c77c3b7ce472056968c745eb501c440fbc07be5004eba02782c35bfbbe3" +checksum = "a6fb22494cf7d23d0c348740e06e5c742070b2991fd41db77bba0bcfbae1a723" dependencies = [ "digest 0.10.7", - "ecdsa 0.16.9", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -1691,9 +1714,9 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.5.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea73e9162e6efde00018d55ed0061e93a108b5d6ec4548b4f8ce3c706249687" +checksum = "6e199424486ea97d6b211db6387fd72e26b4a439d40cc23140b2d8305728055b" dependencies = [ "syn 1.0.109", ] @@ -1752,9 +1775,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] @@ -1791,9 +1814,9 @@ dependencies = [ [[package]] name = "crc-catalog" -version = "2.4.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" +checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" [[package]] name = "crc32fast" @@ -1842,9 +1865,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.9" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c3242926edf34aec4ac3a77108ad4854bffaa2e4ddc1824124ce59231302d5" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" dependencies = [ "cfg-if", "crossbeam-utils", @@ -1852,9 +1875,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.4" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -1863,21 +1886,22 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.16" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d2fe95351b870527a5d09bf563ed3c97c0cffb87cf1c78a591bf48bb218d9aa" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg 1.1.0", "cfg-if", "crossbeam-utils", "memoffset 0.9.0", + "scopeguard", ] [[package]] name = "crossbeam-queue" -version = "0.3.9" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9bcf5bdbfdd6030fb4a1c497b5d5fc5921aa2f60d359a17e249c0e6df3de153" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" dependencies = [ "cfg-if", "crossbeam-utils", @@ -1885,9 +1909,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.17" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ "cfg-if", ] @@ -1937,9 +1961,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.5.5" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array 0.14.7", "rand_core 0.6.4", @@ -2027,15 +2051,15 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "socket2 0.4.10", + "socket2 0.4.9", "winapi", ] [[package]] name = "curl-sys" -version = "0.4.70+curl-8.5.0" +version = "0.4.68+curl-8.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c0333d8849afe78a4c8102a429a446bfdd055832af071945520e835ae2d841e" +checksum = "b4a0d18d88360e374b16b2273c832b5e57258ffc1d4aa4f96b108e0738d5752f" dependencies = [ "cc", "libc", @@ -2079,13 +2103,13 @@ dependencies = [ [[package]] name = "curve25519-dalek-derive" -version = "0.1.1" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -2274,7 +2298,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.3", + "hashbrown 0.14.1", "lock_api", "once_cell", "parking_lot_core 0.9.9", @@ -2282,15 +2306,15 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.5.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "data-encoding-macro" -version = "0.1.14" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20c01c06f5f429efdf2bae21eb67c28b3df3cf85b7dd2d8ef09c0838dac5d33e" +checksum = "c904b33cc60130e1aeea4956ab803d08a3f4a0ca82d64ed757afac3891f2bb99" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -2298,9 +2322,9 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.12" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0047d07f2c89b17dd631c80450d69841a6b5d7fb17278cbc43d7e4cfcf2576f3" +checksum = "8fdf3fce3ce863539ec1d7fd1b6dcc3c645663376b43ed376bbf887733e4f772" dependencies = [ "data-encoding", "syn 1.0.109", @@ -2311,7 +2335,7 @@ name = "defguard_wireguard_rs" version = "0.3.0" source = "git+https://github.com/neacsu/wireguard-rs.git?rev=c2cd0c1119f699f4bc43f5e6ffd6fc242caa42ed#c2cd0c1119f699f4bc43f5e6ffd6fc242caa42ed" dependencies = [ - "base64 0.21.5", + "base64 0.21.4", "libc", "log", "netlink-packet-core 0.7.0", @@ -2376,9 +2400,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.10" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" dependencies = [ "powerfmt", "serde", @@ -2469,7 +2493,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -2572,7 +2596,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -2601,9 +2625,9 @@ checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" [[package]] name = "dyn-clone" -version = "1.0.16" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" +checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" [[package]] name = "ecdsa" @@ -2619,16 +2643,16 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.16.9" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der 0.7.8", "digest 0.10.7", - "elliptic-curve 0.13.7", + "elliptic-curve 0.13.6", "rfc6979 0.4.0", - "signature 2.2.0", - "spki 0.7.3", + "signature 2.1.0", + "spki 0.7.2", ] [[package]] @@ -2648,7 +2672,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ "pkcs8 0.10.2", - "signature 2.2.0", + "signature 2.1.0", ] [[package]] @@ -2681,16 +2705,15 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.1.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" +checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" dependencies = [ "curve25519-dalek 4.1.1", "ed25519 2.2.3", "rand_core 0.6.4", "serde", "sha2 0.10.8", - "subtle 2.4.1", "zeroize", ] @@ -2728,7 +2751,7 @@ dependencies = [ "ff 0.12.1", "generic-array 0.14.7", "group 0.12.1", - "hkdf 0.12.4", + "hkdf 0.12.3", "pem-rfc7468", "pkcs8 0.9.0", "rand_core 0.6.4", @@ -2739,12 +2762,12 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.7" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9775b22bc152ad86a0cf23f0f348b884b26add12bf741e7ffc4d4ab2ab4d205" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" dependencies = [ "base16ct 0.2.0", - "crypto-bigint 0.5.5", + "crypto-bigint 0.5.3", "digest 0.10.7", "ff 0.13.0", "generic-array 0.14.7", @@ -2794,7 +2817,7 @@ checksum = "eecf8589574ce9b895052fa12d69af7a233f99e6107f5cb8dd1044f2a17bfdcb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -2812,9 +2835,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.10.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" dependencies = [ "log", "regex", @@ -2845,7 +2868,7 @@ dependencies = [ "bytes", "cfg-if", "chrono", - "clap 4.4.11", + "clap 4.4.7", "config", "digest 0.10.7", "dirs 5.0.1", @@ -2853,7 +2876,7 @@ dependencies = [ "futures", "futures-util", "lazy_static", - "libp2p 0.51.4", + "libp2p 0.51.3", "libp2p-identity", "log", "lru 0.10.1", @@ -2876,7 +2899,7 @@ dependencies = [ "unsigned-varint", "utoipa", "utoipa-swagger-ui", - "uuid 1.6.1", + "uuid 1.5.0", ] [[package]] @@ -2887,12 +2910,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.48.0", ] [[package]] @@ -2910,33 +2933,12 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" -[[package]] -name = "event-listener" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "770d968249b5d99410d61f5bf89057f3199a077a04d087092f58e7d10692baae" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite 0.2.13", -] - -[[package]] -name = "event-listener-strategy" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" -dependencies = [ - "event-listener 4.0.0", - "pin-project-lite 0.2.13", -] - [[package]] name = "explorer-api" version = "1.1.32" dependencies = [ "chrono", - "clap 4.4.11", + "clap 4.4.7", "dotenvy", "humantime-serde", "isocountry", @@ -3072,34 +3074,34 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.5" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" +checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d" [[package]] name = "figment" -version = "0.10.12" +version = "0.10.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "649f3e5d826594057e9a519626304d8da859ea8a0b18ce99500c586b8d45faee" +checksum = "a014ac935975a70ad13a3bff2463b1c1b083b35ae4cb6309cfc59476aa7a181f" dependencies = [ "atomic 0.6.0", "pear", "serde", - "toml 0.8.8", + "toml 0.8.2", "uncased", "version_check", ] [[package]] name = "filetime" -version = "0.2.23" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", - "windows-sys 0.52.0", + "redox_syscall 0.3.5", + "windows-sys 0.48.0", ] [[package]] @@ -3170,9 +3172,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ "percent-encoding", ] @@ -3206,9 +3208,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.29" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" dependencies = [ "futures-channel", "futures-core", @@ -3221,9 +3223,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.29" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", "futures-sink", @@ -3231,15 +3233,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.29" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-executor" -version = "0.3.29" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" dependencies = [ "futures-core", "futures-task", @@ -3260,9 +3262,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.29" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" [[package]] name = "futures-lite" @@ -3279,25 +3281,15 @@ dependencies = [ "waker-fn", ] -[[package]] -name = "futures-lite" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeee267a1883f7ebef3700f262d2d54de95dfaf38189015a74fdc4e0c7ad8143" -dependencies = [ - "futures-core", - "pin-project-lite 0.2.13", -] - [[package]] name = "futures-macro" -version = "0.3.29" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -3313,15 +3305,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.29" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" -version = "0.3.29" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-timer" @@ -3331,9 +3323,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.29" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-channel", "futures-core", @@ -3402,9 +3394,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.11" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "js-sys", @@ -3447,20 +3439,20 @@ dependencies = [ [[package]] name = "ghost" -version = "0.1.16" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef81e7cedce6ab54cd5dc7b3400c442c8d132fe03200a1be0637db7ef308ff17" +checksum = "ba330b70a5341d3bc730b8e205aaee97ddab5d9c448c4f51a7c2d924266fa8f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] name = "gimli" -version = "0.28.1" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "git2" @@ -3553,9 +3545,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.22" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" dependencies = [ "bytes", "fnv", @@ -3563,7 +3555,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.1.0", + "indexmap 1.9.3", "slab", "tokio", "tokio-util", @@ -3596,7 +3588,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" dependencies = [ - "ahash 0.7.7", + "ahash 0.7.6", ] [[package]] @@ -3605,7 +3597,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash 0.7.7", + "ahash 0.7.6", ] [[package]] @@ -3614,16 +3606,16 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.3", ] [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.3", "allocator-api2", ] @@ -3642,16 +3634,16 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "hashbrown 0.14.3", + "hashbrown 0.14.1", ] [[package]] name = "hdrhistogram" -version = "7.5.4" +version = "7.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" +checksum = "7f19b9f54f7c7f55e31401bb647626ce0cf0f67b0004982ce815b3ee72a02aa8" dependencies = [ - "base64 0.21.5", + "base64 0.13.1", "byteorder", "flate2", "nom", @@ -3736,9 +3728,9 @@ dependencies = [ [[package]] name = "hkdf" -version = "0.12.4" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" dependencies = [ "hmac 0.12.1", ] @@ -3784,9 +3776,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.11" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ "bytes", "fnv", @@ -3809,9 +3801,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.6" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", "http", @@ -3888,7 +3880,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite 0.2.13", - "socket2 0.4.10", + "socket2 0.4.9", "tokio", "tower-service", "tracing", @@ -3897,14 +3889,14 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.24.2" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" dependencies = [ "futures-util", "http", "hyper", - "rustls 0.21.10", + "rustls 0.21.7", "tokio", "tokio-rustls 0.24.1", ] @@ -3976,9 +3968,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.5.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -3986,19 +3978,19 @@ dependencies = [ [[package]] name = "if-addrs" -version = "0.10.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cabb0019d51a643781ff15c9c8a3e5dedc365c47211270f4e8f82812fedd8f0a" +checksum = "cbc0fa01ffc752e9dbc72818cdb072cd028b86be5e09dd04c5a643704fe101a9" dependencies = [ "libc", - "windows-sys 0.48.0", + "winapi", ] [[package]] name = "if-watch" -version = "3.2.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6b0422c86d7ce0e97169cc42e04ae643caf278874a7a3c87b8150a220dc7e1e" +checksum = "bbb892e5777fe09e16f3d44de7802f4daa7267ecbe8c466f19d94e25bb0c303e" dependencies = [ "async-io", "core-foundation", @@ -4027,7 +4019,7 @@ checksum = "bfbcff6ae46750b15cc594bfd277b188cbddcfdc1817848f97f03f26f8625b9e" dependencies = [ "cfg-if", "js-sys", - "uuid 1.6.1", + "uuid 1.5.0", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -4046,12 +4038,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.14.1", "serde", ] @@ -4146,6 +4138,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi 0.3.3", + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "ip_network" version = "0.4.1" @@ -4158,7 +4161,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2 0.5.5", + "socket2 0.5.4", "widestring", "windows-sys 0.48.0", "winreg", @@ -4166,9 +4169,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.9.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" [[package]] name = "ipnetwork" @@ -4204,7 +4207,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi 0.3.3", - "rustix", + "rustix 0.38.19", "windows-sys 0.48.0", ] @@ -4219,12 +4222,12 @@ dependencies = [ "crossbeam-utils", "curl", "curl-sys", - "event-listener 2.5.3", - "futures-lite 1.13.0", + "event-listener", + "futures-lite", "http", "log", "once_cell", - "polling 2.8.0", + "polling", "slab", "sluice", "tracing", @@ -4272,9 +4275,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "jni" @@ -4309,25 +4312,25 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.66" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] [[package]] name = "k256" -version = "0.13.2" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f01b677d82ef7a676aa37e099defd83a28e15687112cafdd112d60236b6115b" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", - "ecdsa 0.16.9", - "elliptic-curve 0.13.7", + "ecdsa 0.16.8", + "elliptic-curve 0.13.6", "once_cell", "sha2 0.10.8", - "signature 2.2.0", + "signature 2.1.0", ] [[package]] @@ -4427,9 +4430,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.151" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "libgit2-sys" @@ -4459,7 +4462,7 @@ dependencies = [ "bytes", "futures", "futures-timer", - "getrandom 0.2.11", + "getrandom 0.2.10", "instant", "libp2p-core 0.39.0", "libp2p-dns 0.39.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", @@ -4473,7 +4476,7 @@ dependencies = [ "libp2p-quic 0.7.0-alpha.2", "libp2p-swarm 0.42.0", "libp2p-tcp 0.39.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", - "libp2p-webrtc", + "libp2p-webrtc 0.4.0-alpha.2", "libp2p-websocket", "libp2p-yamux 0.43.0", "multiaddr 0.17.0", @@ -4482,14 +4485,14 @@ dependencies = [ [[package]] name = "libp2p" -version = "0.51.4" +version = "0.51.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f35eae38201a993ece6bdc823292d6abd1bffed1c4d0f4a3517d2bd8e1d917fe" +checksum = "f210d259724eae82005b5c48078619b7745edb7b76de370b03f8ba59ea103097" dependencies = [ "bytes", "futures", "futures-timer", - "getrandom 0.2.11", + "getrandom 0.2.10", "instant", "libp2p-allow-block-list", "libp2p-connection-limits", @@ -4505,6 +4508,7 @@ dependencies = [ "libp2p-request-response", "libp2p-swarm 0.42.2", "libp2p-tcp 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-webrtc 0.4.0-alpha.4", "libp2p-yamux 0.43.1", "multiaddr 0.17.1", "pin-project", @@ -4629,7 +4633,7 @@ version = "0.44.0" source = "git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6#e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6" dependencies = [ "asynchronous-codec", - "base64 0.21.5", + "base64 0.21.4", "byteorder", "bytes", "fnv", @@ -4659,7 +4663,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70b34b6da8165c0bde35c82db8efda39b824776537e73973549e76cadb3a77c5" dependencies = [ "asynchronous-codec", - "base64 0.21.5", + "base64 0.21.4", "byteorder", "bytes", "either", @@ -4713,7 +4717,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "276bb57e7af15d8f100d3c11cbdd32c6752b7eef4ba7a18ecf464972c07abcce" dependencies = [ "bs58 0.4.0", - "ed25519-dalek 2.1.0", + "ed25519-dalek 2.0.0", "log", "multiaddr 0.17.1", "multihash", @@ -4767,7 +4771,7 @@ dependencies = [ "log", "rand 0.8.5", "smallvec", - "socket2 0.4.10", + "socket2 0.4.9", "tokio", "trust-dns-proto", "void", @@ -4788,7 +4792,7 @@ dependencies = [ "log", "rand 0.8.5", "smallvec", - "socket2 0.4.10", + "socket2 0.4.9", "tokio", "trust-dns-proto", "void", @@ -5029,7 +5033,7 @@ dependencies = [ "libc", "libp2p-core 0.39.2", "log", - "socket2 0.4.10", + "socket2 0.4.9", "tokio", ] @@ -5044,7 +5048,7 @@ dependencies = [ "libc", "libp2p-core 0.39.0", "log", - "socket2 0.4.10", + "socket2 0.4.9", "tokio", ] @@ -5114,6 +5118,37 @@ dependencies = [ "webrtc", ] +[[package]] +name = "libp2p-webrtc" +version = "0.4.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dba48592edbc2f60b4bc7c10d65445b0c3964c07df26fdf493b6880d33be36f8" +dependencies = [ + "async-trait", + "asynchronous-codec", + "bytes", + "futures", + "futures-timer", + "hex", + "if-watch", + "libp2p-core 0.39.2", + "libp2p-identity", + "libp2p-noise 0.42.2", + "log", + "multihash", + "quick-protobuf", + "quick-protobuf-codec", + "rand 0.8.5", + "rcgen 0.9.3", + "serde", + "stun", + "thiserror", + "tinytemplate", + "tokio", + "tokio-util", + "webrtc", +] + [[package]] name = "libp2p-websocket" version = "0.41.0" @@ -5157,17 +5192,6 @@ dependencies = [ "yamux", ] -[[package]] -name = "libredox" -version = "0.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" -dependencies = [ - "bitflags 2.4.1", - "libc", - "redox_syscall 0.4.1", -] - [[package]] name = "libsqlite3-sys" version = "0.24.2" @@ -5213,9 +5237,15 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "linux-raw-sys" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" [[package]] name = "lioness" @@ -5231,9 +5261,9 @@ dependencies = [ [[package]] name = "local-channel" -version = "0.1.5" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8" +checksum = "e0a493488de5f18c8ffcba89eebb8532ffc562dc400490eb65b84893fae0b178" dependencies = [ "futures-core", "futures-sink", @@ -5242,9 +5272,9 @@ dependencies = [ [[package]] name = "local-waker" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" +checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1" [[package]] name = "lock_api" @@ -5426,9 +5456,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.10" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "log", @@ -5881,7 +5911,7 @@ dependencies = [ "bs58 0.4.0", "cfg-if", "chrono", - "clap 4.4.11", + "clap 4.4.7", "console-subscriber", "cosmwasm-std", "cw-utils", @@ -5946,7 +5976,7 @@ dependencies = [ "tokio-stream", "ts-rs", "url", - "uuid 1.6.1", + "uuid 1.5.0", "zeroize", ] @@ -5990,7 +6020,7 @@ name = "nym-bin-common" version = "0.6.0" dependencies = [ "atty", - "clap 4.4.11", + "clap 4.4.7", "clap_complete", "clap_complete_fig", "log", @@ -6031,7 +6061,7 @@ dependencies = [ "base64 0.13.1", "bip39", "bs58 0.4.0", - "clap 4.4.11", + "clap 4.4.7", "clap_complete", "clap_complete_fig", "dotenvy", @@ -6056,7 +6086,7 @@ dependencies = [ "bip39", "bs58 0.4.0", "cfg-if", - "clap 4.4.11", + "clap 4.4.7", "comfy-table", "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", @@ -6100,7 +6130,7 @@ dependencies = [ name = "nym-client" version = "1.1.32" dependencies = [ - "clap 4.4.11", + "clap 4.4.7", "dirs 4.0.0", "futures", "lazy_static", @@ -6137,9 +6167,9 @@ name = "nym-client-core" version = "1.1.15" dependencies = [ "async-trait", - "base64 0.21.5", + "base64 0.21.4", "cfg-if", - "clap 4.4.11", + "clap 4.4.7", "dashmap", "dirs 4.0.0", "futures", @@ -6224,7 +6254,7 @@ dependencies = [ "digest 0.9.0", "doc-comment", "ff 0.13.0", - "getrandom 0.2.11", + "getrandom 0.2.10", "group 0.13.0", "itertools 0.10.5", "nym-dkg", @@ -6350,7 +6380,7 @@ dependencies = [ "digest 0.10.7", "ed25519-dalek 1.0.1", "generic-array 0.14.7", - "hkdf 0.12.4", + "hkdf 0.12.3", "hmac 0.12.1", "nym-pemstore", "nym-sphinx-types", @@ -6451,7 +6481,7 @@ dependencies = [ "atty", "bip39", "bs58 0.4.0", - "clap 4.4.11", + "clap 4.4.7", "colored", "dashmap", "defguard_wireguard_rs", @@ -6506,7 +6536,7 @@ name = "nym-gateway-client" version = "0.1.0" dependencies = [ "futures", - "getrandom 0.2.11", + "getrandom 0.2.10", "gloo-utils", "log", "nym-bandwidth-controller", @@ -6660,7 +6690,7 @@ dependencies = [ "axum", "bs58 0.4.0", "cfg-if", - "clap 4.4.11", + "clap 4.4.7", "colored", "cpu-cycles", "cupid", @@ -6779,7 +6809,7 @@ dependencies = [ "async-file-watcher", "async-trait", "bs58 0.4.0", - "clap 4.4.11", + "clap 4.4.7", "dirs 4.0.0", "futures", "humantime-serde", @@ -6875,7 +6905,7 @@ name = "nym-node-requests" version = "0.1.0" dependencies = [ "async-trait", - "base64 0.21.5", + "base64 0.21.4", "http-api-client", "nym-bin-common", "nym-crypto", @@ -6943,7 +6973,7 @@ name = "nym-nr-query" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.4.11", + "clap 4.4.7", "log", "nym-bin-common", "nym-network-defaults", @@ -6967,12 +6997,12 @@ name = "nym-outfox" version = "0.1.0" dependencies = [ "blake3", - "chacha20", - "chacha20poly1305", + "chacha20 0.9.1", + "chacha20poly1305 0.10.1", "criterion", "curve25519-dalek 3.2.0", "fastrand 1.9.0", - "getrandom 0.2.11", + "getrandom 0.2.10", "log", "rand 0.7.3", "rayon", @@ -7068,7 +7098,7 @@ dependencies = [ name = "nym-socks5-client" version = "1.1.32" dependencies = [ - "clap 4.4.11", + "clap 4.4.7", "lazy_static", "log", "nym-bin-common", @@ -7351,7 +7381,7 @@ dependencies = [ "aes-gcm 0.10.3", "argon2", "generic-array 0.14.7", - "getrandom 0.2.11", + "getrandom 0.2.10", "rand 0.8.5", "serde", "serde_json", @@ -7413,7 +7443,7 @@ dependencies = [ name = "nym-types" version = "1.0.0" dependencies = [ - "base64 0.21.5", + "base64 0.21.4", "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", "eyre", @@ -7476,7 +7506,7 @@ dependencies = [ "nym-service-provider-directory-common", "nym-vesting-contract-common", "openssl", - "prost 0.12.3", + "prost 0.12.1", "reqwest", "serde", "serde_json", @@ -7496,12 +7526,16 @@ version = "0.1.0" dependencies = [ "anyhow", "bip39", - "clap 4.4.11", + "clap 4.4.7", "cosmwasm-std", "futures", "humantime-serde", "nym-bin-common", + "nym-coconut", + "nym-coconut-bandwidth-contract-common", + "nym-coconut-dkg-common", "nym-config", + "nym-credentials", "nym-network-defaults", "nym-task", "nym-validator-client", @@ -7554,7 +7588,7 @@ dependencies = [ name = "nym-wireguard" version = "0.1.0" dependencies = [ - "base64 0.21.5", + "base64 0.21.4", "defguard_wireguard_rs", "ip_network", "log", @@ -7569,7 +7603,7 @@ dependencies = [ name = "nym-wireguard-types" version = "0.1.0" dependencies = [ - "base64 0.21.5", + "base64 0.21.4", "dashmap", "hmac 0.12.1", "log", @@ -7590,7 +7624,7 @@ dependencies = [ "anyhow", "async-file-watcher", "bytes", - "clap 4.4.11", + "clap 4.4.7", "dotenvy", "flate2", "futures", @@ -7676,9 +7710,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "oorandom" @@ -7700,9 +7734,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.61" +version = "0.10.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45" +checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" dependencies = [ "bitflags 2.4.1", "cfg-if", @@ -7721,7 +7755,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -7732,18 +7766,18 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.2.1+3.2.0" +version = "300.1.5+3.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fe476c29791a5ca0d1273c697e96085bbabbbea2ef7afd5617e78a4b40332d3" +checksum = "559068e4c12950d7dcaa1857a61725c0d38d4fc03ff8e070ab31a75d6e316491" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.97" +version = "0.9.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3eaad34cdd97d81de97964fc7f29e2d104f483840d906ef56daa1912338460b" +checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" dependencies = [ "cc", "libc", @@ -7989,9 +8023,9 @@ dependencies = [ [[package]] name = "pear" -version = "0.2.8" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ccca0f6c17acc81df8e242ed473ec144cbf5c98037e69aa6d144780aad103c8" +checksum = "61a386cd715229d399604b50d1361683fe687066f42d56f54be995bc6868f71c" dependencies = [ "inlinable_string", "pear_codegen", @@ -8000,14 +8034,14 @@ dependencies = [ [[package]] name = "pear_codegen" -version = "0.2.8" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e22670e8eb757cff11d6c199ca7b987f352f0346e0be4dd23869ec72cb53c77" +checksum = "da9f0f13dac8069c139e8300a6510e3f4143ecf5259c60b116a9b271b4ca0d54" dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -8068,15 +8102,15 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pest" -version = "2.7.5" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" +checksum = "c022f1e7b65d6a24c0dbbd5fb344c66881bc01f3e5ae74a1c8100f2f985d98a4" dependencies = [ "memchr", "thiserror", @@ -8085,9 +8119,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.5" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81d78524685f5ef2a3b3bd1cafbc9fcabb036253d9b1463e726a91cd16e2dfc2" +checksum = "35513f630d46400a977c4cb58f78e1bfbe01434316e60c37d27b9ad6139c66d8" dependencies = [ "pest", "pest_generator", @@ -8095,22 +8129,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.5" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68bd1206e71118b5356dae5ddc61c8b11e28b09ef6a31acbd15ea48a28e0c227" +checksum = "bc9fc1b9e7057baba189b5c626e2d6f40681ae5b6eb064dc7c7834101ec8123a" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] name = "pest_meta" -version = "2.7.5" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c747191d4ad9e4a4ab9c8798f1e82a39affe7ef9648390b7e5548d18e099de6" +checksum = "1df74e9e7ec4053ceb980e7c0c8bd3594e977fde1af91daba9c928e8e8c6708d" dependencies = [ "once_cell", "pest", @@ -8124,7 +8158,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.1.0", + "indexmap 2.0.2", ] [[package]] @@ -8144,7 +8178,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -8182,7 +8216,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der 0.7.8", - "spki 0.7.3", + "spki 0.7.2", ] [[package]] @@ -8193,9 +8227,9 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "platforms" -version = "3.2.0" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" +checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" [[package]] name = "plotters" @@ -8242,17 +8276,14 @@ dependencies = [ ] [[package]] -name = "polling" -version = "3.3.1" +name = "poly1305" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf63fa624ab313c11656b4cda960bfc46c410187ad493c41f6ba2d8c1e991c9e" +checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" dependencies = [ - "cfg-if", - "concurrent-queue", - "pin-project-lite 0.2.13", - "rustix", - "tracing", - "windows-sys 0.52.0", + "cpufeatures", + "opaque-debug 0.3.0", + "universal-hash 0.4.1", ] [[package]] @@ -8358,9 +8389,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -8373,7 +8404,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", "version_check", "yansi 1.0.0-rc.1", ] @@ -8398,7 +8429,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -8413,12 +8444,12 @@ dependencies = [ [[package]] name = "prost" -version = "0.12.3" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +checksum = "f4fdd22f3b9c31b53c060df4a0613a1c7f062d4115a2b984dd15b1858f7e340d" dependencies = [ "bytes", - "prost-derive 0.12.3", + "prost-derive 0.12.1", ] [[package]] @@ -8470,15 +8501,15 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.12.3" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +checksum = "265baba7fabd416cf5078179f7d2cbeca4ce7a9041111900675ea7c4cb8a4c32" dependencies = [ "anyhow", "itertools 0.11.0", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -8492,11 +8523,11 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.12.3" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" +checksum = "e081b29f63d83a4bc75cfc9f3fe424f9156cf92d8a4f0c9407cce9a1b67327cf" dependencies = [ - "prost 0.12.3", + "prost 0.12.1", ] [[package]] @@ -8691,7 +8722,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.11", + "getrandom 0.2.10", ] [[package]] @@ -8856,6 +8887,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "redox_syscall" version = "0.4.1" @@ -8867,12 +8907,12 @@ dependencies = [ [[package]] name = "redox_users" -version = "0.4.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.11", - "libredox", + "getrandom 0.2.10", + "redox_syscall 0.2.16", "thiserror", ] @@ -8893,7 +8933,7 @@ checksum = "7f7473c2cfcf90008193dd0e3e16599455cb601a9fce322b5bb55de799664925" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -8937,7 +8977,7 @@ dependencies = [ "quote", "refinery-core", "regex", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -8990,7 +9030,7 @@ version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ - "base64 0.21.5", + "base64 0.21.4", "bytes", "encoding_rs", "futures-core", @@ -9009,7 +9049,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite 0.2.13", - "rustls 0.21.10", + "rustls 0.21.7", "rustls-native-certs", "rustls-pemfile", "serde", @@ -9078,12 +9118,12 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.7" +version = "0.17.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "fce3045ffa7c981a6ee93f640b538952e155f1ae3a1a02b84547fc7a56b7059a" dependencies = [ "cc", - "getrandom 0.2.11", + "getrandom 0.2.10", "libc", "spin 0.9.8", "untrusted 0.9.0", @@ -9150,7 +9190,7 @@ dependencies = [ "proc-macro2", "quote", "rocket_http", - "syn 2.0.41", + "syn 2.0.38", "unicode-xid", ] @@ -9301,7 +9341,7 @@ dependencies = [ "quote", "rust-embed-utils", "shellexpand", - "syn 2.0.41", + "syn 2.0.38", "walkdir", ] @@ -9356,15 +9396,29 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.28" +version = "0.37.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +checksum = "d4eb579851244c2c03e7c24f501c3432bed80b8f720af1d6e5b0e0f01555a035" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "745ecfa778e66b2b63c88a61cb36e0eea109e803b0b86bf9879fbc77c70e86ed" dependencies = [ "bitflags 2.4.1", "errno", "libc", - "linux-raw-sys", - "windows-sys 0.52.0", + "linux-raw-sys 0.4.10", + "windows-sys 0.48.0", ] [[package]] @@ -9388,20 +9442,20 @@ checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" dependencies = [ "log", "ring 0.16.20", - "sct 0.7.1", + "sct 0.7.0", "webpki 0.22.4", ] [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" dependencies = [ "log", - "ring 0.17.7", + "ring 0.16.20", "rustls-webpki", - "sct 0.7.1", + "sct 0.7.0", ] [[package]] @@ -9418,21 +9472,21 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.4" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.5", + "base64 0.21.4", ] [[package]] name = "rustls-webpki" -version = "0.101.7" +version = "0.101.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" dependencies = [ - "ring 0.17.7", - "untrusted 0.9.0", + "ring 0.16.20", + "untrusted 0.7.1", ] [[package]] @@ -9464,9 +9518,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "safer-ffi" @@ -9518,9 +9572,9 @@ dependencies = [ [[package]] name = "schemars" -version = "0.8.16" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" +checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" dependencies = [ "dyn-clone", "indexmap 1.9.3", @@ -9531,9 +9585,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.16" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" +checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" dependencies = [ "proc-macro2", "quote", @@ -9565,12 +9619,12 @@ dependencies = [ [[package]] name = "sct" -version = "0.7.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" dependencies = [ - "ring 0.17.7", - "untrusted 0.9.0", + "ring 0.16.20", + "untrusted 0.7.1", ] [[package]] @@ -9579,7 +9633,7 @@ version = "0.1.0" dependencies = [ "anyhow", "cargo-edit", - "clap 4.4.11", + "clap 4.4.7", "semver 1.0.20", "serde", "serde_json", @@ -9692,9 +9746,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.193" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" dependencies = [ "serde_derive", ] @@ -9739,13 +9793,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -9767,7 +9821,7 @@ checksum = "e578a843d40b4189a4d66bba51d7684f57da5bd7c304c64e14bd63efbef49509" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -9793,20 +9847,20 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.17" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145" +checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] name = "serde_spanned" -version = "0.6.4" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" dependencies = [ "serde", ] @@ -9825,11 +9879,11 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.27" +version = "0.9.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cc7a1570e38322cfe4154732e5110f887ea57e22b76f4bfd32b5bdd3368666c" +checksum = "1a49e178e4452f45cb61d0cd8cebc1b0fafd3e41929e996cef79aa3aca91f574" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.0.2", "itoa", "ryu", "serde", @@ -9944,9 +9998,9 @@ dependencies = [ [[package]] name = "signature" -version = "2.2.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ "digest 0.10.7", "rand_core 0.6.4", @@ -9980,9 +10034,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.2" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "smartstring" @@ -10020,16 +10074,16 @@ dependencies = [ [[package]] name = "snow" -version = "0.9.4" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58021967fd0a5eeeb23b08df6cc244a4d4a5b4aec1d27c9e02fad1a58b4cd74e" +checksum = "0c9d1425eb528a21de2755c75af4c9b5d57f50a0d4c3b7f1828a4cd03f8ba155" dependencies = [ - "aes-gcm 0.10.3", + "aes-gcm 0.9.4", "blake2 0.10.6", - "chacha20poly1305", + "chacha20poly1305 0.9.1", "curve25519-dalek 4.1.1", "rand_core 0.6.4", - "ring 0.17.7", + "ring 0.16.20", "rustc_version 0.4.0", "sha2 0.10.8", "subtle 2.4.1", @@ -10037,9 +10091,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.10" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", "winapi", @@ -10047,9 +10101,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" dependencies = [ "libc", "windows-sys 0.48.0", @@ -10133,9 +10187,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.7.3" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der 0.7.8", @@ -10143,11 +10197,11 @@ dependencies = [ [[package]] name = "sqlformat" -version = "0.2.3" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" +checksum = "6b7b278788e7be4d0d29c0f39497a0eef3fba6bbc8e70d8bf7fde46edeaa9e85" dependencies = [ - "itertools 0.12.0", + "itertools 0.11.0", "nom", "unicode_categories", ] @@ -10168,7 +10222,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" dependencies = [ - "ahash 0.7.7", + "ahash 0.7.6", "atoi", "bitflags 1.3.2", "byteorder", @@ -10178,7 +10232,7 @@ dependencies = [ "crossbeam-queue", "dotenvy", "either", - "event-listener 2.5.3", + "event-listener", "flume", "futures-channel", "futures-core", @@ -10245,7 +10299,7 @@ name = "ssl-inject" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.4.11", + "clap 4.4.7", "hex", "tokio", ] @@ -10351,7 +10405,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -10432,9 +10486,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.41" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", @@ -10514,14 +10568,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.8.1" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ "cfg-if", "fastrand 2.0.1", - "redox_syscall 0.4.1", - "rustix", + "redox_syscall 0.3.5", + "rustix 0.38.19", "windows-sys 0.48.0", ] @@ -10540,15 +10594,15 @@ dependencies = [ "k256", "num-traits", "once_cell", - "prost 0.12.3", - "prost-types 0.12.3", + "prost 0.12.1", + "prost-types 0.12.1", "ripemd", "serde", "serde_bytes", "serde_json", "serde_repr", "sha2 0.10.8", - "signature 2.2.0", + "signature 2.1.0", "subtle 2.4.1", "subtle-encoding", "tendermint-proto", @@ -10580,8 +10634,8 @@ dependencies = [ "flex-error", "num-derive", "num-traits", - "prost 0.12.3", - "prost-types 0.12.3", + "prost 0.12.1", + "prost-types 0.12.1", "serde", "serde_bytes", "subtle-encoding", @@ -10599,7 +10653,7 @@ dependencies = [ "bytes", "flex-error", "futures", - "getrandom 0.2.11", + "getrandom 0.2.10", "peg", "pin-project", "reqwest", @@ -10623,9 +10677,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.4.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" dependencies = [ "winapi-util", ] @@ -10636,7 +10690,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ - "rustix", + "rustix 0.38.19", "windows-sys 0.48.0", ] @@ -10648,22 +10702,22 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -10755,9 +10809,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.0" +version = "1.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" dependencies = [ "backtrace", "bytes", @@ -10767,7 +10821,7 @@ dependencies = [ "parking_lot 0.12.1", "pin-project-lite 0.2.13", "signal-hook-registry", - "socket2 0.5.5", + "socket2 0.5.4", "tokio-macros", "tracing", "windows-sys 0.48.0", @@ -10785,13 +10839,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -10821,7 +10875,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.10", + "rustls 0.21.7", "tokio", ] @@ -10899,7 +10953,7 @@ dependencies = [ "futures-io", "futures-sink", "futures-util", - "hashbrown 0.14.3", + "hashbrown 0.14.1", "pin-project-lite 0.2.13", "slab", "tokio", @@ -10923,20 +10977,20 @@ checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" dependencies = [ "serde", "serde_spanned", - "toml_datetime 0.6.5", + "toml_datetime 0.6.3", "toml_edit 0.19.15", ] [[package]] name = "toml" -version = "0.8.8" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" +checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" dependencies = [ "serde", "serde_spanned", - "toml_datetime 0.6.5", - "toml_edit 0.21.0", + "toml_datetime 0.6.3", + "toml_edit 0.20.2", ] [[package]] @@ -10950,9 +11004,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" dependencies = [ "serde", ] @@ -10977,23 +11031,23 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.0.2", "serde", "serde_spanned", - "toml_datetime 0.6.5", + "toml_datetime 0.6.3", "winnow", ] [[package]] name = "toml_edit" -version = "0.21.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.0.2", "serde", "serde_spanned", - "toml_datetime 0.6.5", + "toml_datetime 0.6.3", "winnow", ] @@ -11005,7 +11059,7 @@ checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" dependencies = [ "async-trait", "axum", - "base64 0.21.5", + "base64 0.21.4", "bytes", "futures-core", "futures-util", @@ -11084,9 +11138,9 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "ee2ef2af84856a50c1d430afce2fdded0a4ec7eda868db86409b4543df0797f9" dependencies = [ "log", "pin-project-lite 0.2.13", @@ -11102,7 +11156,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -11127,23 +11181,12 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" dependencies = [ + "lazy_static", "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", "tracing-core", ] @@ -11157,15 +11200,15 @@ dependencies = [ "opentelemetry", "tracing", "tracing-core", - "tracing-log 0.1.4", + "tracing-log", "tracing-subscriber", ] [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" dependencies = [ "matchers", "nu-ansi-term", @@ -11176,7 +11219,7 @@ dependencies = [ "thread_local", "tracing", "tracing-core", - "tracing-log 0.2.0", + "tracing-log", ] [[package]] @@ -11187,7 +11230,7 @@ checksum = "2ec6adcab41b1391b08a308cc6302b79f8095d1673f6947c2dc65ffb028b0b2d" dependencies = [ "nu-ansi-term", "tracing-core", - "tracing-log 0.1.4", + "tracing-log", "tracing-subscriber", ] @@ -11238,7 +11281,7 @@ dependencies = [ "lazy_static", "rand 0.8.5", "smallvec", - "socket2 0.4.10", + "socket2 0.4.9", "thiserror", "tinyvec", "tokio", @@ -11268,9 +11311,9 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.5" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "ts-rs" @@ -11306,7 +11349,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", "termcolor", ] @@ -11333,7 +11376,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals 0.28.0", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -11350,7 +11393,7 @@ dependencies = [ "log", "native-tls", "rand 0.8.5", - "rustls 0.21.10", + "rustls 0.21.7", "sha1", "thiserror", "url", @@ -11440,9 +11483,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.14" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" @@ -11552,27 +11595,27 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5ccd538d4a604753ebc2f17cd9946e89b77bf87f6a8e2309667c6f2e87855e3" dependencies = [ - "base64 0.21.5", + "base64 0.21.4", "log", "native-tls", "once_cell", - "rustls 0.21.10", + "rustls 0.21.7", "rustls-webpki", "serde", "serde_json", "socks", "url", - "webpki-roots 0.25.3", + "webpki-roots 0.25.2", ] [[package]] name = "url" -version = "2.5.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", - "idna 0.5.0", + "idna 0.4.0", "percent-encoding", "serde", ] @@ -11601,7 +11644,7 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d82b1bc5417102a73e8464c686eef947bdfb99fcdfc0a4f228e81afa9526470a" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.0.2", "serde", "serde_json", "utoipa-gen", @@ -11617,7 +11660,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] @@ -11645,11 +11688,11 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" [[package]] name = "uuid" -version = "1.6.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" dependencies = [ - "getrandom 0.2.11", + "getrandom 0.2.10", "serde", "wasm-bindgen", ] @@ -11743,9 +11786,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.89" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -11753,24 +11796,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.89" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.39" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" dependencies = [ "cfg-if", "js-sys", @@ -11780,9 +11823,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -11790,28 +11833,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wasm-bindgen-test" -version = "0.3.39" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cf9242c0d27999b831eae4767b2a146feb0b27d332d553e605864acd2afd403" +checksum = "6e6e302a7ea94f83a6d09e78e7dc7d9ca7b186bc2829c24a22d0753efd680671" dependencies = [ "console_error_panic_hook", "js-sys", @@ -11823,13 +11866,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.39" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "794645f5408c9a039fd09f4d113cdfb2e7eba5ff1956b07bcf701cf4b394fe89" +checksum = "ecb993dd8c836930ed130e020e77d9b2e65dd0fbab1b67c790b0f5d80b11a575" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", ] [[package]] @@ -11912,7 +11954,7 @@ name = "wasm-utils" version = "0.1.0" dependencies = [ "futures", - "getrandom 0.2.11", + "getrandom 0.2.10", "gloo-net", "gloo-utils", "js-sys", @@ -11938,9 +11980,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.66" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ "js-sys", "wasm-bindgen", @@ -11962,7 +12004,7 @@ version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" dependencies = [ - "ring 0.17.7", + "ring 0.17.4", "untrusted 0.9.0", ] @@ -11977,9 +12019,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.3" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "webrtc" @@ -12053,7 +12095,7 @@ dependencies = [ "curve25519-dalek 3.2.0", "der-parser 8.2.0", "elliptic-curve 0.12.3", - "hkdf 0.12.4", + "hkdf 0.12.3", "hmac 0.12.1", "log", "p256", @@ -12095,7 +12137,7 @@ dependencies = [ "tokio", "turn", "url", - "uuid 1.6.1", + "uuid 1.5.0", "waitgroup", "webrtc-mdns", "webrtc-util", @@ -12108,7 +12150,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f08dfd7a6e3987e255c4dbe710dde5d94d0f0574f8a21afa95d171376c143106" dependencies = [ "log", - "socket2 0.4.10", + "socket2 0.4.9", "thiserror", "tokio", "webrtc-util", @@ -12198,7 +12240,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix", + "rustix 0.38.19", ] [[package]] @@ -12284,15 +12326,6 @@ dependencies = [ "windows-targets 0.48.5", ] -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.0", -] - [[package]] name = "windows-targets" version = "0.42.2" @@ -12323,21 +12356,6 @@ dependencies = [ "windows_x86_64_msvc 0.48.5", ] -[[package]] -name = "windows-targets" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" -dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", -] - [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -12350,12 +12368,6 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" - [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -12368,12 +12380,6 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" - [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -12386,12 +12392,6 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" -[[package]] -name = "windows_i686_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" - [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -12404,12 +12404,6 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" -[[package]] -name = "windows_i686_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" - [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -12422,12 +12416,6 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" - [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -12440,12 +12428,6 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" - [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -12458,17 +12440,11 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" - [[package]] name = "winnow" -version = "0.5.28" +version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c830786f7720c2fd27a1a0e27a709dbd3c4d009b56d098fc742d4f4eab91fe2" +checksum = "a3b801d0e0a6726477cc207f60162da452f3a95adb368399bef20a946e06f65c" dependencies = [ "memchr", ] @@ -12575,13 +12551,11 @@ dependencies = [ [[package]] name = "xattr" -version = "1.1.3" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7dae5072fe1f8db8f8d29059189ac175196e410e40ba42d5d4684ae2f750995" +checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985" dependencies = [ "libc", - "linux-raw-sys", - "rustix", ] [[package]] @@ -12619,26 +12593,6 @@ dependencies = [ "time", ] -[[package]] -name = "zerocopy" -version = "0.7.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "306dca4455518f1f31635ec308b6b3e4eb1b11758cefafc782827d0aa7acb5c7" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be912bf68235a88fbefd1b73415cb218405958d1655b2ece9035a19920bdf6ba" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.41", -] - [[package]] name = "zeroize" version = "1.6.0" @@ -12656,7 +12610,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.38", ] [[package]] diff --git a/common/client-libs/validator-client/src/nym_api/mod.rs b/common/client-libs/validator-client/src/nym_api/mod.rs index d4902bd1a1..217ed0d0e6 100644 --- a/common/client-libs/validator-client/src/nym_api/mod.rs +++ b/common/client-libs/validator-client/src/nym_api/mod.rs @@ -5,21 +5,24 @@ use crate::nym_api::error::NymAPIError; use crate::nym_api::routes::{CORE_STATUS_COUNT, SINCE_ARG}; use async_trait::async_trait; use http_api_client::{ApiClient, NO_PARAMS}; -use nym_api_requests::coconut::models::{ - EpochCredentialsResponse, IssuedCredentialResponse, IssuedCredentialsResponse, +pub use nym_api_requests::{ + coconut::{ + models::{ + EpochCredentialsResponse, IssuedCredentialBody, IssuedCredentialResponse, + IssuedCredentialsResponse, + }, + BlindSignRequestBody, BlindedSignatureResponse, CredentialsRequestBody, + VerifyCredentialBody, VerifyCredentialResponse, + }, + models::{ + ComputeRewardEstParam, DescribedGateway, GatewayBondAnnotated, GatewayCoreStatusResponse, + GatewayStatusReportResponse, GatewayUptimeHistoryResponse, InclusionProbabilityResponse, + MixNodeBondAnnotated, MixnodeCoreStatusResponse, MixnodeStatusReportResponse, + MixnodeStatusResponse, MixnodeUptimeHistoryResponse, RewardEstimationResponse, + StakeSaturationResponse, UptimeResponse, + }, }; -use nym_api_requests::coconut::{ - BlindSignRequestBody, BlindedSignatureResponse, CredentialsRequestBody, VerifyCredentialBody, - VerifyCredentialResponse, -}; -use nym_api_requests::models::{ - ComputeRewardEstParam, DescribedGateway, GatewayBondAnnotated, GatewayCoreStatusResponse, - GatewayStatusReportResponse, GatewayUptimeHistoryResponse, InclusionProbabilityResponse, - MixNodeBondAnnotated, MixnodeCoreStatusResponse, MixnodeStatusReportResponse, - MixnodeStatusResponse, MixnodeUptimeHistoryResponse, RewardEstimationResponse, - StakeSaturationResponse, UptimeResponse, -}; -use nym_coconut_dkg_common::types::EpochId; +pub use nym_coconut_dkg_common::types::EpochId; use nym_mixnet_contract_common::mixnode::MixNodeDetails; use nym_mixnet_contract_common::{GatewayBond, IdentityKeyRef, MixId}; use nym_name_service_common::response::NamesListResponse; diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs index d3ac4807e8..46712cb81b 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs @@ -7,12 +7,12 @@ use crate::nyxd::error::NyxdError; use crate::nyxd::CosmWasmClient; use async_trait::async_trait; use cosmrs::AccountId; -use nym_coconut_dkg_common::dealer::{ - ContractDealing, DealerDetailsResponse, PagedDealerResponse, PagedDealingsResponse, +use nym_coconut_dkg_common::{ + dealer::{ContractDealing, DealerDetailsResponse, PagedDealerResponse, PagedDealingsResponse}, + msg::QueryMsg as DkgQueryMsg, + types::{DealerDetails, Epoch, EpochId, InitialReplacementData}, + verification_key::{ContractVKShare, PagedVKSharesResponse}, }; -use nym_coconut_dkg_common::msg::QueryMsg as DkgQueryMsg; -use nym_coconut_dkg_common::types::{DealerDetails, Epoch, EpochId, InitialReplacementData}; -use nym_coconut_dkg_common::verification_key::{ContractVKShare, PagedVKSharesResponse}; use serde::Deserialize; #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] diff --git a/common/nymcoconut/src/lib.rs b/common/nymcoconut/src/lib.rs index 4f0db30a15..7f1631f801 100644 --- a/common/nymcoconut/src/lib.rs +++ b/common/nymcoconut/src/lib.rs @@ -43,3 +43,5 @@ mod utils; pub type Attribute = bls12_381::Scalar; pub type PrivateAttribute = Attribute; pub type PublicAttribute = Attribute; + +pub use bls12_381::G1Projective; diff --git a/common/nymcoconut/src/scheme/issuance.rs b/common/nymcoconut/src/scheme/issuance.rs index 11d0dcb35b..1126e24d98 100644 --- a/common/nymcoconut/src/scheme/issuance.rs +++ b/common/nymcoconut/src/scheme/issuance.rs @@ -362,12 +362,12 @@ pub fn blind_sign( /// The function returns `true` if the partial blind signature is valid, and `false` otherwise. pub fn verify_partial_blind_signature( params: &Parameters, - blind_sign_request: &BlindSignRequest, + private_attribute_commitments: &[G1Projective], public_attributes: &[&Attribute], blind_sig: &BlindedSignature, partial_verification_key: &VerificationKey, ) -> bool { - let num_private_attributes = blind_sign_request.private_attributes_commitments.len(); + let num_private_attributes = private_attribute_commitments.len(); if num_private_attributes + public_attributes.len() > partial_verification_key.beta_g2.len() { return false; } @@ -388,8 +388,7 @@ pub fn verify_partial_blind_signature( ]; // for each private attribute, add (cm_i, beta_i) to the miller terms - for (private_attr_commit, beta_g2) in blind_sign_request - .private_attributes_commitments + for (private_attr_commit, beta_g2) in private_attribute_commitments .iter() .zip(&partial_verification_key.beta_g2) { @@ -422,7 +421,7 @@ pub fn verify_partial_blind_signature( // is equivalent to checking e(a, b) • e(c, d)^{-1} == id // and thus to e(a, b) • e(c^{-1}, d) == id // - // compute e(c^1, g2) • e(s, alpha) • e(cm_0, beta_0) • e(cm_i, beta_i) • (s^pub_0, beta_{i+1}) (s^pub_j, beta_{i + j}) + // compute e(c^{-1}, g2) • e(s, alpha) • e(cm_0, beta_0) • e(cm_i, beta_i) • (s^pub_0, beta_{i+1}) (s^pub_j, beta_{i + j}) multi_miller_loop(&terms_refs) .final_exponentiation() .is_identity() @@ -519,7 +518,7 @@ mod tests { assert!(verify_partial_blind_signature( ¶ms, - &request, + &request.private_attributes_commitments, &public_attributes, &blind_sig, validator_keypair.verification_key() @@ -539,7 +538,7 @@ mod tests { assert!(verify_partial_blind_signature( ¶ms, - &request, + &request.private_attributes_commitments, &[], &blind_sig, validator_keypair.verification_key() @@ -568,7 +567,7 @@ mod tests { // this assertion should fail, as we try to verify with a wrong validator key assert!(!verify_partial_blind_signature( ¶ms, - &request, + &request.private_attributes_commitments, &public_attributes, &blind_sig, validator2_keypair.verification_key() diff --git a/nym-api/nym-api-requests/src/coconut/models.rs b/nym-api/nym-api-requests/src/coconut/models.rs index 79db872288..aa6e82ef00 100644 --- a/nym-api/nym-api-requests/src/coconut/models.rs +++ b/nym-api/nym-api-requests/src/coconut/models.rs @@ -187,18 +187,18 @@ pub struct EpochCredentialsResponse { #[serde(rename_all = "camelCase")] pub struct IssuedCredentialsResponse { // note: BTreeMap returns ordered results so it's fine to use it with pagination - pub credentials: BTreeMap, + pub credentials: BTreeMap, } #[derive(Clone, Serialize, Deserialize, Debug)] #[serde(rename_all = "camelCase")] pub struct IssuedCredentialResponse { - pub credential: Option, + pub credential: Option, } #[derive(Clone, Serialize, Deserialize, Debug, PartialEq)] #[serde(rename_all = "camelCase")] -pub struct IssuedCredentialInner { +pub struct IssuedCredentialBody { pub credential: IssuedCredential, pub signature: identity::Signature, diff --git a/nym-api/src/coconut/api_routes/helpers.rs b/nym-api/src/coconut/api_routes/helpers.rs index 6589499767..93446d0d15 100644 --- a/nym-api/src/coconut/api_routes/helpers.rs +++ b/nym-api/src/coconut/api_routes/helpers.rs @@ -3,7 +3,7 @@ use crate::coconut::error::Result; use crate::coconut::storage::models::IssuedCredential; -use nym_api_requests::coconut::models::IssuedCredentialInner; +use nym_api_requests::coconut::models::IssuedCredentialBody; use nym_api_requests::coconut::models::IssuedCredentialsResponse; use std::collections::BTreeMap; @@ -14,7 +14,7 @@ pub(crate) fn build_credentials_response( for raw_credential in raw { let id = raw_credential.id; - let api_issued = IssuedCredentialInner::try_from(raw_credential)?; + let api_issued = IssuedCredentialBody::try_from(raw_credential)?; let old = credentials.insert(id, api_issued); if old.is_some() { // why do we panic here rather than return an error? because it's a critical failure because diff --git a/nym-api/src/coconut/storage/models.rs b/nym-api/src/coconut/storage/models.rs index fe1afbac22..4d2935c057 100644 --- a/nym-api/src/coconut/storage/models.rs +++ b/nym-api/src/coconut/storage/models.rs @@ -4,7 +4,7 @@ use crate::coconut::error::CoconutError; use nym_api_requests::coconut::models::{ EpochCredentialsResponse, IssuedCredential as ApiIssuedCredential, - IssuedCredentialInner as ApiIssuedCredentialInner, + IssuedCredentialBody as ApiIssuedCredentialInner, }; use nym_api_requests::coconut::BlindedSignatureResponse; use nym_coconut::{Base58, BlindedSignature}; @@ -97,13 +97,6 @@ impl TryFrom for BlindedSignature { } } -impl IssuedCredential { - // safety: this should only ever be called on sanitized data from the database, - // thus the unwraps are fine (if somebody manually entered their db file and modified it, it's on them) - // pub fn private_attribute_commitments(&self) -> Vec - // pub fn public_attributes(&self) -} - pub fn join_attributes(attrs: I) -> String where I: IntoIterator, diff --git a/nym-api/src/coconut/tests/mod.rs b/nym-api/src/coconut/tests/mod.rs index 446a85eab6..6c7f70ad41 100644 --- a/nym-api/src/coconut/tests/mod.rs +++ b/nym-api/src/coconut/tests/mod.rs @@ -9,7 +9,7 @@ use async_trait::async_trait; use cosmwasm_std::{coin, to_binary, Addr, CosmosMsg, Decimal, WasmMsg}; use cw3::ProposalResponse; use cw4::MemberResponse; -use nym_api_requests::coconut::models::{IssuedCredentialInner, IssuedCredentialResponse}; +use nym_api_requests::coconut::models::{IssuedCredentialBody, IssuedCredentialResponse}; use nym_api_requests::coconut::{ BlindSignRequestBody, BlindedSignatureResponse, VerifyCredentialBody, VerifyCredentialResponse, }; @@ -716,7 +716,7 @@ impl TestFixture { serde_json::from_str(&response.into_string().await.unwrap()).unwrap() } - async fn issued_unchecked(&self, id: i64) -> IssuedCredentialInner { + async fn issued_unchecked(&self, id: i64) -> IssuedCredentialBody { self.issued_credential(id) .await .unwrap() diff --git a/nym-validator-rewarder/Cargo.toml b/nym-validator-rewarder/Cargo.toml index 081d32c925..39579cc691 100644 --- a/nym-validator-rewarder/Cargo.toml +++ b/nym-validator-rewarder/Cargo.toml @@ -31,9 +31,13 @@ humantime-serde = "1.0" # internal nym-bin-common = { path = "../common/bin-common", features = ["output_format"] } nym-config = { path = "../common/config" } +nym-coconut = { path = "../common/nymcoconut" } +nym-credentials = { path = "../common/credentials" } nym-network-defaults = { path = "../common/network-defaults" } nym-task = { path = "../common/task" } nym-validator-client = { path = "../common/client-libs/validator-client" } +nym-coconut-dkg-common = { path = "../common/cosmwasm-smart-contracts/coconut-dkg"} +nym-coconut-bandwidth-contract-common = { path = "../common/cosmwasm-smart-contracts/coconut-bandwidth-contract"} nyxd-scraper = { path = "../common/nyxd-scraper" } [build-dependencies] diff --git a/nym-validator-rewarder/migrations/01_initial.sql b/nym-validator-rewarder/migrations/01_initial.sql index dfb1b33d01..00fd324530 100644 --- a/nym-validator-rewarder/migrations/01_initial.sql +++ b/nym-validator-rewarder/migrations/01_initial.sql @@ -9,6 +9,7 @@ CREATE TABLE rewarding_epoch start_time TIMESTAMP WITHOUT TIME ZONE NOT NULL, end_time TIMESTAMP WITHOUT TIME ZONE NOT NULL, budget TEXT NOT NULL, + spent TEXT NOT NULL, rewarding_tx TEXT, rewarding_error TEXT ); @@ -51,12 +52,12 @@ CREATE TABLE malformed_credential CREATE TABLE credential_issuance_reward ( - rewarding_epoch_id INTEGER NOT NULL REFERENCES rewarding_epoch (id), - operator_account TEXT NOT NULL, - amount TEXT NOT NULL, - api_endpoint TEXT NOT NULL, - issued_partial_credentials INTEGER NOT NULL, - issued_credentials_share TEXT NOT NULL, + rewarding_epoch_id INTEGER NOT NULL REFERENCES rewarding_epoch (id), + operator_account TEXT NOT NULL, + amount TEXT NOT NULL, + api_endpoint TEXT NOT NULL, + issued_partial_credentials INTEGER NOT NULL, + issued_credentials_share TEXT NOT NULL, validated_issued_credentials INTEGER NOT NULL, UNIQUE (rewarding_epoch_id, operator_account) diff --git a/nym-validator-rewarder/src/config/mod.rs b/nym-validator-rewarder/src/config/mod.rs index ae3c175236..0f696febdd 100644 --- a/nym-validator-rewarder/src/config/mod.rs +++ b/nym-validator-rewarder/src/config/mod.rs @@ -255,7 +255,7 @@ pub struct NyxdScraper { // TODO: debug with everything that's currently hardcoded in the scraper } -#[derive(Debug, Clone, Deserialize, Serialize)] +#[derive(Debug, Clone, Deserialize, Serialize, Copy)] pub struct IssuanceMonitor { #[serde(with = "humantime_serde")] pub run_interval: Duration, diff --git a/nym-validator-rewarder/src/error.rs b/nym-validator-rewarder/src/error.rs index c6d722e415..be080355a3 100644 --- a/nym-validator-rewarder/src/error.rs +++ b/nym-validator-rewarder/src/error.rs @@ -1,8 +1,11 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only +use nym_coconut::CoconutError; +use nym_validator_client::nym_api::error::NymAPIError; use nym_validator_client::nyxd::error::NyxdError; use nym_validator_client::nyxd::tx::ErrorReport; +use nym_validator_client::nyxd::{AccountId, Hash}; use std::io; use std::path::PathBuf; use thiserror::Error; @@ -85,4 +88,59 @@ pub enum NymRewarderError { #[error("could not find details for validator {consensus_address}")] MissingValidatorDetails { consensus_address: String }, + + #[error("api url ({raw}) provided by {runner_account} is invalid: {source}")] + MalformedApiUrl { + raw: String, + runner_account: AccountId, + #[source] + source: url::ParseError, + }, + + #[error("failed to resolve nym-api query: {0}")] + ApiQueryFailure(#[from] NymAPIError), + + #[error("operator {runner_account} didn't return all requested credentials! requested {requested} but got only {received}")] + IncompleteRequest { + runner_account: AccountId, + requested: usize, + received: usize, + }, + + #[error("the following private attribute commitment is malformed: {raw}: {source}")] + MalformedCredentialCommitment { + raw: String, + #[source] + source: CoconutError, + }, + + #[error("could not verify the blinded credential")] + BlindVerificationFailure, + + #[error("the same deposit transaction ({tx_hash}) has been used for multiple issued credentials! {first} and {other}")] + DuplicateDepositHash { + tx_hash: Hash, + first: i64, + other: i64, + }, + + #[error("could not find the deposit value in the event of transaction {tx_hash}")] + DepositValueNotFound { tx_hash: Hash }, + + #[error("could not find the deposit info in the event of transaction {tx_hash}")] + DepositInfoNotFound { tx_hash: Hash }, + + #[error("the provided deposit value of transaction {tx_hash} is inconsistent. got '{request:?}' while the value on chain is '{on_chain}'")] + InconsistentDepositValue { + tx_hash: Hash, + request: Option, + on_chain: String, + }, + + #[error("the provided deposit info of transaction {tx_hash}is inconsistent. got '{request:?}' while the value on chain is '{on_chain}'")] + InconsistentDepositInfo { + tx_hash: Hash, + request: Option, + on_chain: String, + }, } diff --git a/nym-validator-rewarder/src/rewarder/credential_issuance/mod.rs b/nym-validator-rewarder/src/rewarder/credential_issuance/mod.rs index 3dbcc008c9..5f4f13cc34 100644 --- a/nym-validator-rewarder/src/rewarder/credential_issuance/mod.rs +++ b/nym-validator-rewarder/src/rewarder/credential_issuance/mod.rs @@ -1,12 +1,13 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only +use crate::config; use crate::error::NymRewarderError; use crate::rewarder::credential_issuance::monitor::CredentialIssuanceMonitor; use crate::rewarder::credential_issuance::types::{CredentialIssuanceResults, MonitoringResults}; use crate::rewarder::epoch::Epoch; +use crate::rewarder::nyxd_client::NyxdClient; use nym_task::TaskClient; -use nym_validator_client::nyxd::AccountId; use std::time::Duration; use tracing::info; @@ -16,29 +17,25 @@ pub mod types; pub struct CredentialIssuance { monitoring_run_interval: Duration, monitoring_results: MonitoringResults, - dkg_contract_address: AccountId, } impl CredentialIssuance { - pub(crate) fn new( - epoch: Epoch, - monitoring_run_interval: Duration, - dkg_contract_address: AccountId, - ) -> Self { + pub(crate) fn new(epoch: Epoch, monitoring_run_interval: Duration) -> Self { CredentialIssuance { monitoring_run_interval, monitoring_results: MonitoringResults::new(epoch), - dkg_contract_address, } } - pub(crate) fn start_monitor(&self, task_client: TaskClient) { + pub(crate) fn start_monitor( + &self, + monitor_config: config::IssuanceMonitor, + nyxd_client: NyxdClient, + task_client: TaskClient, + ) { let monitoring_results = self.monitoring_results.clone(); - let mut monitor = CredentialIssuanceMonitor::new( - self.monitoring_run_interval, - self.dkg_contract_address.clone(), - monitoring_results, - ); + let mut monitor = + CredentialIssuanceMonitor::new(monitor_config, nyxd_client, monitoring_results); tokio::spawn(async move { monitor.run(task_client).await }); } diff --git a/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs b/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs index f18dd35a96..e2a36b526a 100644 --- a/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs +++ b/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs @@ -1,42 +1,258 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::config; use crate::error::NymRewarderError; -use crate::rewarder::credential_issuance::types::MonitoringResults; +use crate::rewarder::credential_issuance::types::{CredentialIssuer, MonitoringResults}; +use crate::rewarder::nyxd_client::NyxdClient; +use bip39::rand::prelude::SliceRandom; +use bip39::rand::thread_rng; +use nym_coconut::{ + hash_to_scalar, verify_partial_blind_signature, Base58, G1Projective, Parameters, + VerificationKey, +}; +use nym_coconut_dkg_common::types::EpochId; +use nym_credentials::coconut::bandwidth::BandwidthVoucher; use nym_task::TaskClient; -use nym_validator_client::nyxd::AccountId; -use std::time::Duration; +use nym_validator_client::nym_api; +use nym_validator_client::nym_api::{IssuedCredentialBody, NymApiClientExt}; +use nym_validator_client::nyxd::Hash; +use std::collections::HashMap; +use std::sync::OnceLock; use tokio::time::interval; -use tracing::{error, info}; +use tracing::{debug, error, info, warn}; + +pub(crate) fn bandwidth_voucher_params() -> &'static Parameters { + static BANDWIDTH_CREDENTIAL_PARAMS: OnceLock = OnceLock::new(); + BANDWIDTH_CREDENTIAL_PARAMS.get_or_init(|| BandwidthVoucher::default_parameters()) +} pub struct CredentialIssuanceMonitor { - run_interval: Duration, - dkg_contract_address: AccountId, + nyxd_client: NyxdClient, monitoring_results: MonitoringResults, + config: config::IssuanceMonitor, + // map of validator address -> transaction hash -> issued credential + // (ideally we'd have hashed the AccountId directly, but it doesn't implement `Hash`) + seen_deposits: HashMap>, } impl CredentialIssuanceMonitor { pub fn new( - run_interval: Duration, - dkg_contract_address: AccountId, + config: config::IssuanceMonitor, + nyxd_client: NyxdClient, monitoring_results: MonitoringResults, ) -> CredentialIssuanceMonitor { CredentialIssuanceMonitor { - run_interval, - dkg_contract_address, + config, + nyxd_client, monitoring_results, + seen_deposits: Default::default(), } } - // 1. if not present -> go to DKG contract and grab the accounts + endpoints + // TODO: currently we can't obtain public key of the runner in order to verify the signature + async fn validate_issued_credential( + &mut self, + runner: String, + credential_id: i64, + issued_credential: IssuedCredentialBody, + vk: &VerificationKey, + ) -> Result<(), NymRewarderError> { + warn!("unimplemented: public key sharing mechanism"); + // let plaintext = issued_credential.credential.signable_plaintext(); + // if !operator_public_key.verify(&plaintext) { + // ... + // } + let tx_hash = issued_credential.credential.tx_hash; + + // check if we've seen this tx hash before + // TODO: we should persist them in the database in case we crash + if let Some(known_runner) = self.seen_deposits.get_mut(&runner) { + if let Some(&used) = known_runner.get(&tx_hash) { + return if used != credential_id { + Err(NymRewarderError::DuplicateDepositHash { + tx_hash, + first: used, + other: credential_id, + }) + } else { + debug!("we have already verified this credential before"); + Ok(()) + }; + } else { + known_runner.insert(tx_hash, credential_id); + } + } + + // check if this deposit even exists + let (deposit_value, deposit_info) = self + .nyxd_client + .get_deposit_transaction_attributes(tx_hash) + .await?; + + // check if the deposit values match + let credential_value = issued_credential.credential.public_attributes.get(0); + let credential_info = issued_credential.credential.public_attributes.get(1); + + if credential_value != Some(&deposit_value) { + return Err(NymRewarderError::InconsistentDepositValue { + tx_hash, + request: credential_value.cloned(), + on_chain: deposit_value, + }); + } + + if credential_info != Some(&deposit_info) { + return Err(NymRewarderError::InconsistentDepositInfo { + tx_hash, + request: credential_info.cloned(), + on_chain: deposit_info, + }); + } + + let public_attributes = issued_credential + .credential + .public_attributes + .iter() + .map(hash_to_scalar) + .collect::>(); + #[allow(clippy::map_identity)] + let attributes_refs = public_attributes.iter().collect::>(); + + let mut public_attribute_commitments = Vec::with_capacity( + issued_credential + .credential + .bs58_encoded_private_attributes_commitments + .len(), + ); + + for raw_cm in issued_credential + .credential + .bs58_encoded_private_attributes_commitments + { + match G1Projective::try_from_bs58(&raw_cm) { + Ok(cm) => public_attribute_commitments.push(cm), + Err(source) => { + return Err(NymRewarderError::MalformedCredentialCommitment { + raw: raw_cm, + source, + }) + } + } + } + + // actually do verify the credential now + if !verify_partial_blind_signature( + bandwidth_voucher_params(), + &public_attribute_commitments, + &attributes_refs, + &issued_credential.credential.blinded_partial_credential, + vk, + ) { + return Err(NymRewarderError::BlindVerificationFailure); + } + + Ok(()) + } + + async fn check_issuer( + &mut self, + epoch_id: EpochId, + issuer: CredentialIssuer, + ) -> Result<(), NymRewarderError> { + let url = match issuer.api_runner.parse() { + Ok(url) => url, + Err(source) => { + return Err(NymRewarderError::MalformedApiUrl { + raw: issuer.api_runner, + runner_account: issuer.operator_account, + source, + }) + } + }; + + let api_client = nym_api::Client::new(url, None); + + let epoch_credentials = api_client.epoch_credentials(epoch_id).await?; + let Some(first_id) = epoch_credentials.first_epoch_credential_id else { + // no point in doing anything more - if they haven't issued anything, there's nothing to verify + debug!( + "{} hasn't issued any credentials this epoch", + issuer.operator_account + ); + return Ok(()); + }; + + let credential_range: Vec<_> = + (first_id..first_id + epoch_credentials.total_issued as i64).collect(); + let issued = credential_range.len(); + + let sampled = if issued <= self.config.min_validate_per_issuer as usize { + credential_range + } else { + let mut rng = thread_rng(); + let sample_size = (issued as f32 * self.config.sampling_rate) as usize; + credential_range + .choose_multiple(&mut rng, sample_size) + .copied() + .collect::>() + }; + let request_size = sampled.len(); + + let credentials = api_client.issued_credentials(sampled).await?; + if credentials.credentials.len() != request_size { + // TODO: we need some signatures here to actually show the validator is cheating + return Err(NymRewarderError::IncompleteRequest { + runner_account: issuer.operator_account, + requested: request_size, + received: credentials.credentials.len(), + }); + } + + for (id, credential) in credentials.credentials { + // TODO: insert the failure information, alongside the signature, to the evidence db + if let Err(err) = self + .validate_issued_credential( + issuer.operator_account.to_string(), + id, + credential, + &issuer.verification_key, + ) + .await + { + error!( + "failed to verify credential {id} from {}!!: {err}", + issuer.operator_account + ); + return Err(err); + } + } + + Ok(()) + } async fn check_issuers(&mut self) -> Result<(), NymRewarderError> { + let epoch = self.nyxd_client.dkg_epoch().await?; + let issuers = self + .nyxd_client + .get_credential_issuers(epoch.epoch_id) + .await?; + + for issuer in issuers { + let address = issuer.operator_account.clone(); + // we could parallelize it, but we're running the test so infrequently (relatively speaking) + // that doing it sequentially is fine + if let Err(err) = self.check_issuer(epoch.epoch_id, issuer).await { + // TODO: insert info to the db + error!("failed to check credential issuance of {address}: {err}") + } + } Ok(()) } pub async fn run(&mut self, mut task_client: TaskClient) { info!("starting"); - let mut run_interval = interval(self.run_interval); + let mut run_interval = interval(self.config.run_interval); while !task_client.is_shutdown() { tokio::select! { diff --git a/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs b/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs index b086efb2d2..fc0e161094 100644 --- a/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs +++ b/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs @@ -1,13 +1,15 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::error::NymRewarderError; use crate::rewarder::epoch::Epoch; -use cosmwasm_std::{Decimal, Uint128}; +use cosmwasm_std::{Addr, Decimal, Uint128}; +use nym_coconut::VerificationKey; +use nym_coconut_dkg_common::verification_key::ContractVKShare; use nym_validator_client::nyxd::{AccountId, Coin}; -use std::mem; use std::sync::Arc; use tokio::sync::Mutex; -use tracing::{error, info}; +use tracing::info; #[derive(Clone)] pub struct MonitoringResults { @@ -36,43 +38,46 @@ impl MonitoringResults { dkg_epoch: u32, operators: Vec<(String, AccountId)>, ) { - let mut guard = self.inner.lock().await; - guard.operators = operators - .into_iter() - .map(|(api_runner, runner_account)| RawOperatorIssuing { - api_runner, - runner_account, - issued_credentials: 0, - validated_credentials: 0, - }) - .collect(); - guard.dkg_epoch = Some(dkg_epoch) + todo!() + // let mut guard = self.inner.lock().await; + // guard.operators = operators + // .into_iter() + // .map(|(api_runner, runner_account)| RawOperatorIssuing { + // api_runner, + // runner_account, + // issued_credentials: 0, + // validated_credentials: 0, + // }) + // .collect(); + // guard.dkg_epoch = Some(dkg_epoch) } pub(crate) async fn append_run_results(&self, results: Vec<(String, RawOperatorResult)>) { - let mut guard = self.inner.lock().await; - - // sure, a hashmap would have been quicker, but we'll have at most 30-40 runners so - // performance overhead is negligible - for (api_runner, results) in results { - if let Some(entry) = guard - .operators - .iter_mut() - .find(|o| o.api_runner == api_runner) - { - entry.issued_credentials += results.issued_credentials; - entry.validated_credentials += results.validated_credentials; - } else { - error!("somehow could not find operator results for runner {api_runner}!") - } - } + todo!() + // let mut guard = self.inner.lock().await; + // + // // sure, a hashmap would have been quicker, but we'll have at most 30-40 runners so + // // performance overhead is negligible + // for (api_runner, results) in results { + // if let Some(entry) = guard + // .operators + // .iter_mut() + // .find(|o| o.api_runner == api_runner) + // { + // entry.issued_credentials += results.issued_credentials; + // entry.validated_credentials += results.validated_credentials; + // } else { + // error!("somehow could not find operator results for runner {api_runner}!") + // } + // } } pub(crate) async fn finish_epoch(&self) -> MonitoringResultsInner { - let mut guard = self.inner.lock().await; - let next_epoch = guard.epoch.next(); - let next_results = MonitoringResultsInner::new(next_epoch); - mem::replace(&mut guard, next_results) + todo!() + // let mut guard = self.inner.lock().await; + // let next_epoch = guard.epoch.next(); + // let next_results = MonitoringResultsInner::new(next_epoch); + // mem::replace(&mut guard, next_results) } } @@ -138,6 +143,8 @@ pub struct RawOperatorIssuing { pub issued_credentials: u32, pub validated_credentials: u32, + + pub(crate) starting_credential_id: u32, } pub struct OperatorIssuing { @@ -180,3 +187,24 @@ impl CredentialIssuanceResults { .collect() } } + +pub struct CredentialIssuer { + pub operator_account: AccountId, + pub api_runner: String, + pub verification_key: VerificationKey, +} + +impl TryFrom for CredentialIssuer { + type Error = NymRewarderError; + + fn try_from(value: ContractVKShare) -> Result { + todo!() + } +} + +// safety: we're converting between different wrappers for bech32 addresses +// and we trust (reasonably so), the values coming out of registered dealers in the DKG contract +fn addr_to_account_id(addr: Addr) -> AccountId { + #[allow(clippy::unwrap_used)] + addr.as_str().parse().unwrap() +} diff --git a/nym-validator-rewarder/src/rewarder/helpers.rs b/nym-validator-rewarder/src/rewarder/helpers.rs index 6b58fc60c1..578d49c498 100644 --- a/nym-validator-rewarder/src/rewarder/helpers.rs +++ b/nym-validator-rewarder/src/rewarder/helpers.rs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::error::NymRewarderError; -use cosmwasm_std::Decimal; use nym_validator_client::nyxd::{AccountId, PublicKey}; use nyxd_scraper::constants::{BECH32_CONSENSUS_ADDRESS_PREFIX, BECH32_PREFIX}; use sha2::{Digest, Sha256}; diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index a1604f133f..5bdfc131f7 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -48,6 +48,15 @@ impl EpochRewards { amounts } + + pub fn total_spent(&self) -> Coin { + let amount = self + .amounts() + .into_iter() + .map(|(_, amount)| amount[0].amount) + .sum(); + Coin::new(amount, &self.total_budget.denom) + } } pub struct Rewarder { @@ -63,7 +72,6 @@ pub struct Rewarder { impl Rewarder { pub async fn new(config: Config) -> Result { let nyxd_scraper = NyxdScraper::new(config.scraper_config()).await?; - let dkg_contract = config.dkg_contract_address(); let nyxd_client = NyxdClient::new(&config); let storage = RewarderStorage::init(&config.storage_paths.reward_history).await?; let current_epoch = if let Some(last_epoch) = storage.load_last_rewarding_epoch().await? { @@ -77,7 +85,6 @@ impl Rewarder { credential_issuance: CredentialIssuance::new( current_epoch, config.issuance_monitor.run_interval, - dkg_contract, ), epoch_signing: EpochSigning { nyxd_scraper, @@ -176,8 +183,11 @@ impl Rewarder { // setup shutdowns let mut task_manager = TaskManager::new(5); - self.credential_issuance - .start_monitor(task_manager.subscribe()); + self.credential_issuance.start_monitor( + self.config.issuance_monitor, + self.nyxd_client.clone(), + task_manager.subscribe(), + ); self.epoch_signing.nyxd_scraper.start().await?; self.epoch_signing .nyxd_scraper diff --git a/nym-validator-rewarder/src/rewarder/nyxd_client.rs b/nym-validator-rewarder/src/rewarder/nyxd_client.rs index 25f8bc46c6..4ccc675ff7 100644 --- a/nym-validator-rewarder/src/rewarder/nyxd_client.rs +++ b/nym-validator-rewarder/src/rewarder/nyxd_client.rs @@ -3,12 +3,23 @@ use crate::config::Config; use crate::error::NymRewarderError; -use nym_validator_client::nyxd::error::NyxdError; -use nym_validator_client::nyxd::module_traits::staking::{ - QueryHistoricalInfoResponse, QueryValidatorResponse, QueryValidatorsResponse, +use crate::rewarder::credential_issuance::types::CredentialIssuer; +use cosmwasm_std::Addr; +use nym_coconut::VerificationKey; +use nym_coconut_bandwidth_contract_common::events::{ + COSMWASM_DEPOSITED_FUNDS_EVENT_TYPE, DEPOSIT_INFO, DEPOSIT_VALUE, }; -use nym_validator_client::nyxd::{AccountId, CosmWasmClient, PageRequest, StakingQueryClient}; -use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient}; +use nym_coconut_dkg_common::types::Epoch; +use nym_validator_client::nyxd::contract_traits::{DkgQueryClient, PagedDkgQueryClient}; +use nym_validator_client::nyxd::helpers::find_tx_attribute; +use nym_validator_client::nyxd::module_traits::staking::{ + QueryHistoricalInfoResponse, QueryValidatorsResponse, +}; +use nym_validator_client::nyxd::{ + AccountId, CosmWasmClient, Hash, PageRequest, StakingQueryClient, +}; +use nym_validator_client::DirectSigningHttpRpcNyxdClient; +use std::ops::Deref; use std::sync::Arc; use tokio::sync::RwLock; @@ -51,11 +62,44 @@ impl NyxdClient { &self, pagination: Option, ) -> Result { - Ok(self - .inner + let guard = self.inner.read().await; + Ok(StakingQueryClient::validators(guard.deref(), "".to_string(), pagination).await?) + } + + pub(crate) async fn dkg_epoch(&self) -> Result { + Ok(self.inner.read().await.get_current_epoch().await?) + } + + pub(crate) async fn get_credential_issuers( + &self, + dkg_epoch: u64, + ) -> Result, NymRewarderError> { + self.inner .read() .await - .validators("".to_string(), pagination) - .await?) + .get_all_verification_key_shares(dkg_epoch) + .await? + .into_iter() + .map(TryInto::try_into) + .collect() + } + + pub(crate) async fn get_deposit_transaction_attributes( + &self, + tx_hash: Hash, + ) -> Result<(String, String), NymRewarderError> { + let tx = self.inner.read().await.get_tx(tx_hash).await?; + + // todo: we need to make it more concrete that the first attribute is the deposit value + // and the second one is the deposit info + let deposit_value = + find_tx_attribute(&tx, COSMWASM_DEPOSITED_FUNDS_EVENT_TYPE, DEPOSIT_VALUE) + .ok_or(NymRewarderError::DepositValueNotFound { tx_hash })?; + + let deposit_info = + find_tx_attribute(&tx, COSMWASM_DEPOSITED_FUNDS_EVENT_TYPE, DEPOSIT_INFO) + .ok_or(NymRewarderError::DepositInfoNotFound { tx_hash })?; + + Ok((deposit_value, deposit_info)) } } diff --git a/nym-validator-rewarder/src/rewarder/storage/manager.rs b/nym-validator-rewarder/src/rewarder/storage/manager.rs index 124589baaf..56cf4a2646 100644 --- a/nym-validator-rewarder/src/rewarder/storage/manager.rs +++ b/nym-validator-rewarder/src/rewarder/storage/manager.rs @@ -29,18 +29,20 @@ impl StorageManager { &self, epoch: Epoch, rewarding_budget: String, + total_spent: String, rewarding_tx: Option, rewarding_error: Option, ) -> Result<(), sqlx::Error> { sqlx::query!( r#" - INSERT INTO rewarding_epoch (id, start_time, end_time, budget, rewarding_tx, rewarding_error) - VALUES (?, ?, ? ,?, ?, ?) + INSERT INTO rewarding_epoch (id, start_time, end_time, budget, spent, rewarding_tx, rewarding_error) + VALUES (?, ?, ? ,?, ?, ?, ?) "#, epoch.id, epoch.start_time, epoch.end_time, rewarding_budget, + total_spent: String, rewarding_tx, rewarding_error ).execute(&self.connection_pool).await?; diff --git a/nym-validator-rewarder/src/rewarder/storage/mod.rs b/nym-validator-rewarder/src/rewarder/storage/mod.rs index 5c204ac811..edf648b586 100644 --- a/nym-validator-rewarder/src/rewarder/storage/mod.rs +++ b/nym-validator-rewarder/src/rewarder/storage/mod.rs @@ -72,6 +72,7 @@ impl RewarderStorage { .insert_rewarding_epoch( reward.epoch, reward.total_budget.to_string(), + reward.total_spent().to_string(), reward_tx, reward_err, ) From 5c864cb055f4b6ec61f6d58b91304e5e7c8b17b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 18 Dec 2023 13:49:48 +0000 Subject: [PATCH 12/21] monitoring done --- Cargo.lock | 1 + .../validator-client/src/nym_api/mod.rs | 4 +- ephemera/src/cli/run_node.rs | 2 +- nym-api/src/support/cli/run.rs | 2 +- nym-validator-rewarder/Cargo.toml | 1 + .../migrations/01_initial.sql | 3 +- nym-validator-rewarder/src/error.rs | 9 +- .../src/rewarder/credential_issuance/mod.rs | 14 +- .../rewarder/credential_issuance/monitor.rs | 186 +++++++---- .../src/rewarder/credential_issuance/types.rs | 297 +++++++++++++----- .../src/rewarder/helpers.rs | 17 + nym-validator-rewarder/src/rewarder/mod.rs | 5 +- .../src/rewarder/nyxd_client.rs | 2 - .../src/rewarder/storage/manager.rs | 23 +- .../src/rewarder/storage/mod.rs | 42 ++- 15 files changed, 431 insertions(+), 177 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f6b5946315..83d13f5e18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7536,6 +7536,7 @@ dependencies = [ "nym-coconut-dkg-common", "nym-config", "nym-credentials", + "nym-crypto", "nym-network-defaults", "nym-task", "nym-validator-client", diff --git a/common/client-libs/validator-client/src/nym_api/mod.rs b/common/client-libs/validator-client/src/nym_api/mod.rs index 217ed0d0e6..ced2e4caff 100644 --- a/common/client-libs/validator-client/src/nym_api/mod.rs +++ b/common/client-libs/validator-client/src/nym_api/mod.rs @@ -8,8 +8,8 @@ use http_api_client::{ApiClient, NO_PARAMS}; pub use nym_api_requests::{ coconut::{ models::{ - EpochCredentialsResponse, IssuedCredentialBody, IssuedCredentialResponse, - IssuedCredentialsResponse, + EpochCredentialsResponse, IssuedCredential, IssuedCredentialBody, + IssuedCredentialResponse, IssuedCredentialsResponse, }, BlindSignRequestBody, BlindedSignatureResponse, CredentialsRequestBody, VerifyCredentialBody, VerifyCredentialResponse, diff --git a/ephemera/src/cli/run_node.rs b/ephemera/src/cli/run_node.rs index a33854f52d..adbc36ec41 100644 --- a/ephemera/src/cli/run_node.rs +++ b/ephemera/src/cli/run_node.rs @@ -60,7 +60,7 @@ impl RunExternalNodeCmd { .with_members_provider(members_provider)? .build(); - let shutdown = TaskManager::new(10); + let mut shutdown = TaskManager::new(10); let shutdown_listener = shutdown.subscribe(); tokio::spawn(ephemera.run(shutdown_listener)); diff --git a/nym-api/src/support/cli/run.rs b/nym-api/src/support/cli/run.rs index 549438d095..b796044cd1 100644 --- a/nym-api/src/support/cli/run.rs +++ b/nym-api/src/support/cli/run.rs @@ -65,7 +65,7 @@ pub(crate) async fn execute(args: Args) -> anyhow::Result<()> { config.validate()?; - let shutdown_handlers = start_nym_api_tasks(config).await?; + let mut shutdown_handlers = start_nym_api_tasks(config).await?; let res = shutdown_handlers .task_manager_handle diff --git a/nym-validator-rewarder/Cargo.toml b/nym-validator-rewarder/Cargo.toml index 39579cc691..272b542ddc 100644 --- a/nym-validator-rewarder/Cargo.toml +++ b/nym-validator-rewarder/Cargo.toml @@ -32,6 +32,7 @@ humantime-serde = "1.0" nym-bin-common = { path = "../common/bin-common", features = ["output_format"] } nym-config = { path = "../common/config" } nym-coconut = { path = "../common/nymcoconut" } +nym-crypto = { path = "../common/crypto", features = ["asymmetric"] } nym-credentials = { path = "../common/credentials" } nym-network-defaults = { path = "../common/network-defaults" } nym-task = { path = "../common/task" } diff --git a/nym-validator-rewarder/migrations/01_initial.sql b/nym-validator-rewarder/migrations/01_initial.sql index 00fd324530..ec7758fcb5 100644 --- a/nym-validator-rewarder/migrations/01_initial.sql +++ b/nym-validator-rewarder/migrations/01_initial.sql @@ -39,7 +39,8 @@ CREATE TABLE block_signing_reward CREATE TABLE epoch_credential_issuance ( rewarding_epoch_id INTEGER NOT NULL PRIMARY KEY REFERENCES rewarding_epoch (id), - dkg_epoch_id INTEGER NOT NULL,-- currently not incrementing, needs to change + starting_dkg_epoch INTEGER NOT NULL, + ending_dkg_epoch INTEGER NOT NULL, total_issued_credentials INTEGER NOT NULL, budget TEXT NOT NULL ); diff --git a/nym-validator-rewarder/src/error.rs b/nym-validator-rewarder/src/error.rs index be080355a3..62b92cd398 100644 --- a/nym-validator-rewarder/src/error.rs +++ b/nym-validator-rewarder/src/error.rs @@ -114,6 +114,13 @@ pub enum NymRewarderError { source: CoconutError, }, + #[error("the partial verification key for runner {runner} is malformed: {source}")] + MalformedPartialVerificationKey { + runner: String, + #[source] + source: CoconutError, + }, + #[error("could not verify the blinded credential")] BlindVerificationFailure, @@ -137,7 +144,7 @@ pub enum NymRewarderError { on_chain: String, }, - #[error("the provided deposit info of transaction {tx_hash}is inconsistent. got '{request:?}' while the value on chain is '{on_chain}'")] + #[error("the provided deposit info of transaction {tx_hash} is inconsistent. got '{request:?}' while the value on chain is '{on_chain}'")] InconsistentDepositInfo { tx_hash: Hash, request: Option, diff --git a/nym-validator-rewarder/src/rewarder/credential_issuance/mod.rs b/nym-validator-rewarder/src/rewarder/credential_issuance/mod.rs index 5f4f13cc34..5807a60dec 100644 --- a/nym-validator-rewarder/src/rewarder/credential_issuance/mod.rs +++ b/nym-validator-rewarder/src/rewarder/credential_issuance/mod.rs @@ -8,23 +8,23 @@ use crate::rewarder::credential_issuance::types::{CredentialIssuanceResults, Mon use crate::rewarder::epoch::Epoch; use crate::rewarder::nyxd_client::NyxdClient; use nym_task::TaskClient; -use std::time::Duration; use tracing::info; mod monitor; pub mod types; pub struct CredentialIssuance { - monitoring_run_interval: Duration, monitoring_results: MonitoringResults, } impl CredentialIssuance { - pub(crate) fn new(epoch: Epoch, monitoring_run_interval: Duration) -> Self { - CredentialIssuance { - monitoring_run_interval, - monitoring_results: MonitoringResults::new(epoch), - } + pub(crate) async fn new( + epoch: Epoch, + nyxd_client: &NyxdClient, + ) -> Result { + Ok(CredentialIssuance { + monitoring_results: MonitoringResults::new_initial(epoch, nyxd_client).await?, + }) } pub(crate) fn start_monitor( diff --git a/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs b/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs index e2a36b526a..743b8c2a7e 100644 --- a/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs +++ b/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs @@ -3,7 +3,10 @@ use crate::config; use crate::error::NymRewarderError; -use crate::rewarder::credential_issuance::types::{CredentialIssuer, MonitoringResults}; +use crate::rewarder::credential_issuance::types::{ + CredentialIssuer, MonitoringResults, RawOperatorResult, +}; +use crate::rewarder::helpers::api_client; use crate::rewarder::nyxd_client::NyxdClient; use bip39::rand::prelude::SliceRandom; use bip39::rand::thread_rng; @@ -14,23 +17,23 @@ use nym_coconut::{ use nym_coconut_dkg_common::types::EpochId; use nym_credentials::coconut::bandwidth::BandwidthVoucher; use nym_task::TaskClient; -use nym_validator_client::nym_api; -use nym_validator_client::nym_api::{IssuedCredentialBody, NymApiClientExt}; +use nym_validator_client::nym_api::{IssuedCredential, IssuedCredentialBody, NymApiClientExt}; use nym_validator_client::nyxd::Hash; use std::collections::HashMap; use std::sync::OnceLock; use tokio::time::interval; -use tracing::{debug, error, info, warn}; +use tracing::{debug, error, info, instrument, trace, warn}; pub(crate) fn bandwidth_voucher_params() -> &'static Parameters { static BANDWIDTH_CREDENTIAL_PARAMS: OnceLock = OnceLock::new(); - BANDWIDTH_CREDENTIAL_PARAMS.get_or_init(|| BandwidthVoucher::default_parameters()) + BANDWIDTH_CREDENTIAL_PARAMS.get_or_init(BandwidthVoucher::default_parameters) } pub struct CredentialIssuanceMonitor { nyxd_client: NyxdClient, monitoring_results: MonitoringResults, config: config::IssuanceMonitor, + // map of validator address -> transaction hash -> issued credential // (ideally we'd have hashed the AccountId directly, but it doesn't implement `Hash`) seen_deposits: HashMap>, @@ -50,45 +53,57 @@ impl CredentialIssuanceMonitor { } } - // TODO: currently we can't obtain public key of the runner in order to verify the signature - async fn validate_issued_credential( + fn validate_credential_signature( &mut self, - runner: String, - credential_id: i64, - issued_credential: IssuedCredentialBody, - vk: &VerificationKey, + _issued_credential: &IssuedCredentialBody, ) -> Result<(), NymRewarderError> { warn!("unimplemented: public key sharing mechanism"); // let plaintext = issued_credential.credential.signable_plaintext(); // if !operator_public_key.verify(&plaintext) { // ... // } - let tx_hash = issued_credential.credential.tx_hash; + Ok(()) + } + fn check_deposit_reuse( + &mut self, + runner: &str, + credential_id: i64, + deposit_tx: Hash, + ) -> Result { // check if we've seen this tx hash before // TODO: we should persist them in the database in case we crash - if let Some(known_runner) = self.seen_deposits.get_mut(&runner) { - if let Some(&used) = known_runner.get(&tx_hash) { + if let Some(known_runner) = self.seen_deposits.get_mut(runner) { + if let Some(&used) = known_runner.get(&deposit_tx) { return if used != credential_id { Err(NymRewarderError::DuplicateDepositHash { - tx_hash, + tx_hash: deposit_tx, first: used, other: credential_id, }) } else { debug!("we have already verified this credential before"); - Ok(()) + Ok(true) }; } else { - known_runner.insert(tx_hash, credential_id); + known_runner.insert(deposit_tx, credential_id); } } + Ok(false) + } + async fn validate_deposit( + &mut self, + issued_credential: &IssuedCredentialBody, + ) -> Result<(), NymRewarderError> { // check if this deposit even exists + let deposit_tx = issued_credential.credential.tx_hash; + let (deposit_value, deposit_info) = self .nyxd_client - .get_deposit_transaction_attributes(tx_hash) + .get_deposit_transaction_attributes(deposit_tx) .await?; + trace!("deposit exists"); // check if the deposit values match let credential_value = issued_credential.credential.public_attributes.get(0); @@ -96,40 +111,42 @@ impl CredentialIssuanceMonitor { if credential_value != Some(&deposit_value) { return Err(NymRewarderError::InconsistentDepositValue { - tx_hash, + tx_hash: deposit_tx, request: credential_value.cloned(), on_chain: deposit_value, }); } + trace!("credential values matches the deposit"); if credential_info != Some(&deposit_info) { return Err(NymRewarderError::InconsistentDepositInfo { - tx_hash, + tx_hash: deposit_tx, request: credential_info.cloned(), on_chain: deposit_info, }); } + trace!("credential info matches the deposit"); + Ok(()) + } - let public_attributes = issued_credential - .credential + fn verify_credential( + &mut self, + vk: &VerificationKey, + credential: IssuedCredential, + ) -> Result<(), NymRewarderError> { + let public_attributes = credential .public_attributes .iter() .map(hash_to_scalar) .collect::>(); + #[allow(clippy::map_identity)] let attributes_refs = public_attributes.iter().collect::>(); - let mut public_attribute_commitments = Vec::with_capacity( - issued_credential - .credential - .bs58_encoded_private_attributes_commitments - .len(), - ); + let mut public_attribute_commitments = + Vec::with_capacity(credential.bs58_encoded_private_attributes_commitments.len()); - for raw_cm in issued_credential - .credential - .bs58_encoded_private_attributes_commitments - { + for raw_cm in credential.bs58_encoded_private_attributes_commitments { match G1Projective::try_from_bs58(&raw_cm) { Ok(cm) => public_attribute_commitments.push(cm), Err(source) => { @@ -146,45 +163,46 @@ impl CredentialIssuanceMonitor { bandwidth_voucher_params(), &public_attribute_commitments, &attributes_refs, - &issued_credential.credential.blinded_partial_credential, + &credential.blinded_partial_credential, vk, ) { return Err(NymRewarderError::BlindVerificationFailure); } + trace!("credential correctly verifies"); Ok(()) } - async fn check_issuer( + // TODO: currently we can't obtain public key of the runner in order to verify the signature + #[instrument(skip_all, fields(credential_id = credential_id, deposit = %issued_credential.credential.tx_hash))] + async fn validate_issued_credential( &mut self, - epoch_id: EpochId, - issuer: CredentialIssuer, + runner: String, + credential_id: i64, + issued_credential: IssuedCredentialBody, + vk: &VerificationKey, ) -> Result<(), NymRewarderError> { - let url = match issuer.api_runner.parse() { - Ok(url) => url, - Err(source) => { - return Err(NymRewarderError::MalformedApiUrl { - raw: issuer.api_runner, - runner_account: issuer.operator_account, - source, - }) - } - }; + self.validate_credential_signature(&issued_credential)?; - let api_client = nym_api::Client::new(url, None); + let deposit_tx = issued_credential.credential.tx_hash; - let epoch_credentials = api_client.epoch_credentials(epoch_id).await?; - let Some(first_id) = epoch_credentials.first_epoch_credential_id else { - // no point in doing anything more - if they haven't issued anything, there's nothing to verify - debug!( - "{} hasn't issued any credentials this epoch", - issuer.operator_account - ); + // make sure the issuer is not using the same deposit for multiple credentials + let already_checked = self.check_deposit_reuse(&runner, credential_id, deposit_tx)?; + if already_checked { return Ok(()); - }; + } - let credential_range: Vec<_> = - (first_id..first_id + epoch_credentials.total_issued as i64).collect(); + // check the correctness of the deposit itself + self.validate_deposit(&issued_credential).await?; + + // check if the partial credential correctly verifies + self.verify_credential(vk, issued_credential.credential)?; + + Ok(()) + } + + fn sample_credential_ids(&self, first_id: i64, total_issued: i64) -> Vec { + let credential_range: Vec<_> = (first_id..first_id + total_issued).collect(); let issued = credential_range.len(); let sampled = if issued <= self.config.min_validate_per_issuer as usize { @@ -197,9 +215,37 @@ impl CredentialIssuanceMonitor { .copied() .collect::>() }; + + sampled + } + + #[instrument(skip(self, issuer, epoch_id), fields(dkg_epoch = epoch_id, issuer = %issuer.operator_account, url = issuer.api_runner), err(Display))] + async fn check_issuer( + &mut self, + epoch_id: EpochId, + issuer: CredentialIssuer, + ) -> Result { + debug!("checking the issuer's credentials..."); + + let api_client = api_client(&issuer)?; + + let epoch_credentials = api_client.epoch_credentials(epoch_id).await?; + let Some(first_id) = epoch_credentials.first_epoch_credential_id else { + // no point in doing anything more - if they haven't issued anything, there's nothing to verify + debug!("no credentials issued this epoch",); + return Ok(RawOperatorResult::new_empty( + issuer.operator_account, + issuer.api_runner, + )); + }; + trace!("issued credentials: {epoch_credentials:?}"); + + let sampled = self.sample_credential_ids(first_id, epoch_credentials.total_issued as i64); let request_size = sampled.len(); - let credentials = api_client.issued_credentials(sampled).await?; + trace!("sampled credentials to validate: {sampled:?}"); + + let credentials = api_client.issued_credentials(sampled.clone()).await?; if credentials.credentials.len() != request_size { // TODO: we need some signatures here to actually show the validator is cheating return Err(NymRewarderError::IncompleteRequest { @@ -210,6 +256,7 @@ impl CredentialIssuanceMonitor { } for (id, credential) in credentials.credentials { + trace!("checking credential {id}..."); // TODO: insert the failure information, alongside the signature, to the evidence db if let Err(err) = self .validate_issued_credential( @@ -228,7 +275,12 @@ impl CredentialIssuanceMonitor { } } - Ok(()) + Ok(RawOperatorResult { + operator_account: issuer.operator_account, + api_runner: issuer.api_runner, + issued_credentials: epoch_credentials.total_issued, + validated_credentials: sampled, + }) } async fn check_issuers(&mut self) -> Result<(), NymRewarderError> { @@ -238,15 +290,25 @@ impl CredentialIssuanceMonitor { .get_credential_issuers(epoch.epoch_id) .await?; + let mut results = Vec::with_capacity(issuers.len()); + for issuer in issuers { let address = issuer.operator_account.clone(); // we could parallelize it, but we're running the test so infrequently (relatively speaking) // that doing it sequentially is fine - if let Err(err) = self.check_issuer(epoch.epoch_id, issuer).await { - // TODO: insert info to the db - error!("failed to check credential issuance of {address}: {err}") + match self.check_issuer(epoch.epoch_id, issuer).await { + Ok(res) => results.push(res), + Err(err) => { + // TODO: insert info to the db + error!("failed to check credential issuance of {address}: {err}") + } } } + + self.monitoring_results + .append_run_results(epoch.epoch_id as u32, results) + .await; + Ok(()) } diff --git a/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs b/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs index fc0e161094..a4be44047d 100644 --- a/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs +++ b/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs @@ -3,13 +3,18 @@ use crate::error::NymRewarderError; use crate::rewarder::epoch::Epoch; +use crate::rewarder::helpers::api_client; +use crate::rewarder::nyxd_client::NyxdClient; use cosmwasm_std::{Addr, Decimal, Uint128}; -use nym_coconut::VerificationKey; +use nym_coconut::{Base58, VerificationKey}; use nym_coconut_dkg_common::verification_key::ContractVKShare; +use nym_validator_client::nym_api::NymApiClientExt; use nym_validator_client::nyxd::{AccountId, Coin}; +use std::collections::{HashMap, HashSet}; +use std::mem; use std::sync::Arc; use tokio::sync::Mutex; -use tracing::info; +use tracing::{info, warn}; #[derive(Clone)] pub struct MonitoringResults { @@ -17,104 +22,173 @@ pub struct MonitoringResults { } impl MonitoringResults { - pub(crate) fn new(initial_epoch: Epoch) -> Self { - MonitoringResults { - inner: Arc::new(Mutex::new(MonitoringResultsInner::new(initial_epoch))), + pub(crate) async fn new_initial( + initial_epoch: Epoch, + nyxd_client: &NyxdClient, + ) -> Result { + let epoch = nyxd_client.dkg_epoch().await?; + let issuers = nyxd_client.get_credential_issuers(epoch.epoch_id).await?; + + let mut initial_results = HashMap::new(); + + for issuer in issuers { + let issuer_account = issuer.operator_account.to_string(); + let mut raw_issuer = RawOperatorIssuing { + api_runner: issuer.api_runner.clone(), + runner_account: issuer.operator_account.clone(), + per_epoch: Default::default(), + }; + + let Ok(api_client) = api_client(&issuer) else { + warn!("failed to create api client for {issuer_account}"); + initial_results.insert(issuer_account, raw_issuer); + continue; + }; + + let Ok(epoch_credentials) = api_client.epoch_credentials(epoch.epoch_id).await else { + warn!("failed to get initial epoch credentials from {issuer_account}"); + initial_results.insert(issuer_account, raw_issuer); + continue; + }; + + raw_issuer.per_epoch.insert( + epoch.epoch_id as u32, + IssuedEpochCredentials { + issued_since_monitor_started: 0, + validated_ids: Default::default(), + last_total_issued: epoch_credentials.total_issued, + }, + ); + initial_results.insert(issuer_account, raw_issuer); + } + + Ok(MonitoringResults { + inner: Arc::new(Mutex::new(MonitoringResultsInner::new( + initial_epoch, + epoch.epoch_id as u32, + initial_results, + ))), + }) + } + + pub(crate) async fn append_run_results(&self, dkg_epoch: u32, results: Vec) { + let mut guard = self.inner.lock().await; + + for result in results { + let Some(entry) = guard.operators.get_mut(result.operator_account.as_ref()) else { + // if this is the first time we're seeing this data, make sure to set the current results as the starting point + guard.operators.insert( + result.operator_account.to_string(), + RawOperatorIssuing::new_empty(dkg_epoch, result), + ); + + continue; + }; + + let Some(epoch_data) = entry.per_epoch.get_mut(&dkg_epoch) else { + // similar situation to the above, if we don't have the proper initial data, set it to what we got now + entry + .per_epoch + .insert(dkg_epoch, IssuedEpochCredentials::new_initial(&result)); + continue; + }; + + let issued = result.issued_credentials - epoch_data.last_total_issued; + epoch_data.last_total_issued = result.issued_credentials; + + for validated in result.validated_credentials { + epoch_data.validated_ids.insert(validated); + } + + epoch_data.issued_since_monitor_started += issued; } } - pub(crate) async fn api_endpoints(&self) -> Vec { - self.inner - .lock() - .await - .operators - .iter() - .map(|o| o.api_runner.clone()) - .collect() - } - - pub(crate) async fn set_epoch_operators( - &self, - dkg_epoch: u32, - operators: Vec<(String, AccountId)>, - ) { - todo!() - // let mut guard = self.inner.lock().await; - // guard.operators = operators - // .into_iter() - // .map(|(api_runner, runner_account)| RawOperatorIssuing { - // api_runner, - // runner_account, - // issued_credentials: 0, - // validated_credentials: 0, - // }) - // .collect(); - // guard.dkg_epoch = Some(dkg_epoch) - } - - pub(crate) async fn append_run_results(&self, results: Vec<(String, RawOperatorResult)>) { - todo!() - // let mut guard = self.inner.lock().await; - // - // // sure, a hashmap would have been quicker, but we'll have at most 30-40 runners so - // // performance overhead is negligible - // for (api_runner, results) in results { - // if let Some(entry) = guard - // .operators - // .iter_mut() - // .find(|o| o.api_runner == api_runner) - // { - // entry.issued_credentials += results.issued_credentials; - // entry.validated_credentials += results.validated_credentials; - // } else { - // error!("somehow could not find operator results for runner {api_runner}!") - // } - // } - } - pub(crate) async fn finish_epoch(&self) -> MonitoringResultsInner { - todo!() - // let mut guard = self.inner.lock().await; - // let next_epoch = guard.epoch.next(); - // let next_results = MonitoringResultsInner::new(next_epoch); - // mem::replace(&mut guard, next_results) + let mut guard = self.inner.lock().await; + let next_epoch = guard.epoch.next(); + + // safety: whenever the monitor results are constructed, we always have at least a single value there + let latest_dkg_epoch = guard.dkg_epochs.pop().unwrap(); + + // only keep results from the latest dkg epoch (but after resetting the counters) + let mut to_keep = HashMap::new(); + for (runner, result) in &guard.operators { + let mut kept_epoch = HashMap::new(); + if let Some(data) = result.per_epoch.get(&latest_dkg_epoch) { + kept_epoch.insert( + latest_dkg_epoch, + IssuedEpochCredentials { + issued_since_monitor_started: 0, + validated_ids: Default::default(), + last_total_issued: data.last_total_issued, + }, + ); + } + + to_keep.insert( + runner.clone(), + RawOperatorIssuing { + api_runner: result.api_runner.clone(), + runner_account: result.runner_account.clone(), + per_epoch: kept_epoch, + }, + ); + } + + let next_results = MonitoringResultsInner { + epoch: next_epoch, + dkg_epochs: vec![latest_dkg_epoch], + operators: to_keep, + }; + + mem::replace(&mut guard, next_results) } } pub(crate) struct MonitoringResultsInner { pub(crate) epoch: Epoch, - pub(crate) dkg_epoch: Option, - pub(crate) operators: Vec, + pub(crate) dkg_epochs: Vec, + + // map from operator's account to their results + pub(crate) operators: HashMap, } impl From for CredentialIssuanceResults { fn from(value: MonitoringResultsInner) -> Self { // approximation! + // get the maximum number of issued credentials of all apis + // (we sum values if they cross dkg epochs) let total_issued = value .operators - .iter() - .map(|o| o.issued_credentials) + .values() + .map(|o| { + o.per_epoch + .values() + .map(|e| e.issued_since_monitor_started) + .sum() + }) .max() .unwrap_or_default(); CredentialIssuanceResults { total_issued, - dkg_epoch: value.dkg_epoch, + dkg_epochs: value.dkg_epochs, api_runners: value .operators - .into_iter() + .into_values() .map(|runner| { let issued_ratio = if total_issued == 0 { Decimal::zero() } else { - Decimal::from_ratio(runner.issued_credentials, total_issued) + Decimal::from_ratio(runner.issued_credentials(), total_issued) }; OperatorIssuing { + issued_ratio, + issued_credentials: runner.issued_credentials(), + validated_credentials: runner.validated_credentials(), api_runner: runner.api_runner, runner_account: runner.runner_account, - issued_ratio, - issued_credentials: runner.issued_credentials, - validated_credentials: runner.validated_credentials, } }) .collect(), @@ -123,28 +197,84 @@ impl From for CredentialIssuanceResults { } impl MonitoringResultsInner { - fn new(epoch: Epoch) -> MonitoringResultsInner { + fn new( + epoch: Epoch, + initial_dkg_epoch: u32, + initial_operators: HashMap, + ) -> MonitoringResultsInner { MonitoringResultsInner { epoch, - dkg_epoch: None, - operators: vec![], + dkg_epochs: vec![initial_dkg_epoch], + operators: initial_operators, } } } pub(crate) struct RawOperatorResult { + pub(crate) operator_account: AccountId, + pub(crate) api_runner: String, + + // how many credentials the operator claims to have issued in **TOTAL** in this **DKG** epoch pub(crate) issued_credentials: u32, - pub(crate) validated_credentials: u32, + pub(crate) validated_credentials: Vec, +} + +impl RawOperatorResult { + pub(crate) fn new_empty(operator_account: AccountId, api_runner: String) -> RawOperatorResult { + RawOperatorResult { + operator_account, + api_runner, + issued_credentials: 0, + validated_credentials: Default::default(), + } + } } pub struct RawOperatorIssuing { pub api_runner: String, pub runner_account: AccountId, - pub issued_credentials: u32, - pub validated_credentials: u32, + pub per_epoch: HashMap, +} - pub(crate) starting_credential_id: u32, +impl RawOperatorIssuing { + pub fn new_empty(epoch: u32, raw_result: RawOperatorResult) -> RawOperatorIssuing { + let mut per_epoch = HashMap::new(); + per_epoch.insert(epoch, IssuedEpochCredentials::new_initial(&raw_result)); + RawOperatorIssuing { + api_runner: raw_result.api_runner, + runner_account: raw_result.operator_account, + per_epoch, + } + } + + pub fn issued_credentials(&self) -> u32 { + self.per_epoch + .values() + .map(|e| e.issued_since_monitor_started) + .sum() + } + + pub fn validated_credentials(&self) -> u32 { + let ids: usize = self.per_epoch.values().map(|e| e.validated_ids.len()).sum(); + ids as u32 + } +} + +pub struct IssuedEpochCredentials { + pub issued_since_monitor_started: u32, + pub validated_ids: HashSet, + pub last_total_issued: u32, +} + +impl IssuedEpochCredentials { + pub fn new_initial(raw: &RawOperatorResult) -> Self { + IssuedEpochCredentials { + issued_since_monitor_started: 0, + validated_ids: raw.validated_credentials.iter().copied().collect(), + last_total_issued: raw.issued_credentials, + } + } } pub struct OperatorIssuing { @@ -167,7 +297,7 @@ impl OperatorIssuing { pub struct CredentialIssuanceResults { // note: this is an approximation! pub total_issued: u32, - pub dkg_epoch: Option, + pub dkg_epochs: Vec, pub api_runners: Vec, } @@ -188,7 +318,9 @@ impl CredentialIssuanceResults { } } +#[derive(Debug)] pub struct CredentialIssuer { + // pub public_key: identity::PublicKey, pub operator_account: AccountId, pub api_runner: String, pub verification_key: VerificationKey, @@ -198,7 +330,16 @@ impl TryFrom for CredentialIssuer { type Error = NymRewarderError; fn try_from(value: ContractVKShare) -> Result { - todo!() + Ok(CredentialIssuer { + operator_account: addr_to_account_id(value.owner.clone()), + api_runner: value.announce_address, + verification_key: VerificationKey::try_from_bs58(value.share).map_err(|source| { + NymRewarderError::MalformedPartialVerificationKey { + runner: value.owner.to_string(), + source, + } + })?, + }) } } diff --git a/nym-validator-rewarder/src/rewarder/helpers.rs b/nym-validator-rewarder/src/rewarder/helpers.rs index 578d49c498..f49d96e5fb 100644 --- a/nym-validator-rewarder/src/rewarder/helpers.rs +++ b/nym-validator-rewarder/src/rewarder/helpers.rs @@ -2,6 +2,8 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::error::NymRewarderError; +use crate::rewarder::credential_issuance::types::CredentialIssuer; +use nym_validator_client::nym_api; use nym_validator_client::nyxd::{AccountId, PublicKey}; use nyxd_scraper::constants::{BECH32_CONSENSUS_ADDRESS_PREFIX, BECH32_PREFIX}; use sha2::{Digest, Sha256}; @@ -31,3 +33,18 @@ pub(crate) fn operator_account_to_owner_account( } }) } + +pub(crate) fn api_client(issuer: &CredentialIssuer) -> Result { + let url = match issuer.api_runner.parse() { + Ok(url) => url, + Err(source) => { + return Err(NymRewarderError::MalformedApiUrl { + raw: issuer.api_runner.clone(), + runner_account: issuer.operator_account.clone(), + source, + }) + } + }; + + Ok(nym_api::Client::new(url, None)) +} diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index 5bdfc131f7..332fe86ff7 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -82,10 +82,7 @@ impl Rewarder { Ok(Rewarder { current_epoch, - credential_issuance: CredentialIssuance::new( - current_epoch, - config.issuance_monitor.run_interval, - ), + credential_issuance: CredentialIssuance::new(current_epoch, &nyxd_client).await?, epoch_signing: EpochSigning { nyxd_scraper, nyxd_client: nyxd_client.clone(), diff --git a/nym-validator-rewarder/src/rewarder/nyxd_client.rs b/nym-validator-rewarder/src/rewarder/nyxd_client.rs index 4ccc675ff7..2806a7cd55 100644 --- a/nym-validator-rewarder/src/rewarder/nyxd_client.rs +++ b/nym-validator-rewarder/src/rewarder/nyxd_client.rs @@ -4,8 +4,6 @@ use crate::config::Config; use crate::error::NymRewarderError; use crate::rewarder::credential_issuance::types::CredentialIssuer; -use cosmwasm_std::Addr; -use nym_coconut::VerificationKey; use nym_coconut_bandwidth_contract_common::events::{ COSMWASM_DEPOSITED_FUNDS_EVENT_TYPE, DEPOSIT_INFO, DEPOSIT_VALUE, }; diff --git a/nym-validator-rewarder/src/rewarder/storage/manager.rs b/nym-validator-rewarder/src/rewarder/storage/manager.rs index 56cf4a2646..ddcb05049c 100644 --- a/nym-validator-rewarder/src/rewarder/storage/manager.rs +++ b/nym-validator-rewarder/src/rewarder/storage/manager.rs @@ -2,9 +2,6 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::rewarder::epoch::Epoch; -use sqlx::types::time::OffsetDateTime; -use sqlx::{Executor, Sqlite}; -use tracing::{instrument, trace}; #[derive(Clone)] pub(crate) struct StorageManager { @@ -113,20 +110,30 @@ impl StorageManager { pub(crate) async fn insert_rewarding_epoch_credential_issuance( &self, epoch: i64, - dkg_epoch_id: u32, + starting_dkg_epoch: u32, + ending_dkg_epoch: u32, total_issued_credentials: u32, budget: String, ) -> Result<(), sqlx::Error> { sqlx::query!( r#" - INSERT INTO epoch_credential_issuance (rewarding_epoch_id, dkg_epoch_id, total_issued_credentials, budget) - VALUES (?, ?, ?, ?) + INSERT INTO epoch_credential_issuance ( + rewarding_epoch_id, + starting_dkg_epoch, + ending_dkg_epoch, + total_issued_credentials, + budget + ) + VALUES (?, ?, ?, ?, ?) "#, epoch, - dkg_epoch_id, + starting_dkg_epoch, + ending_dkg_epoch, total_issued_credentials, budget, - ).execute(&self.connection_pool).await?; + ) + .execute(&self.connection_pool) + .await?; Ok(()) } diff --git a/nym-validator-rewarder/src/rewarder/storage/mod.rs b/nym-validator-rewarder/src/rewarder/storage/mod.rs index edf648b586..784361a37c 100644 --- a/nym-validator-rewarder/src/rewarder/storage/mod.rs +++ b/nym-validator-rewarder/src/rewarder/storage/mod.rs @@ -102,16 +102,38 @@ impl RewarderStorage { ) .await?; } - // - // self.manager - // .insert_rewarding_epoch_credential_issuance(epoch_id) - // .await?; - // - // for api_runner in reward.credentials.api_runners { - // self.manager - // .insert_rewarding_epoch_credential_issuance_reward(epoch_id) - // .await?; - // } + + // safety: we must have at least a single value here + let dkg_epoch_start = reward.credentials.dkg_epochs.first().unwrap(); + let dkg_epoch_end = reward.credentials.dkg_epochs.last().unwrap(); + + self.manager + .insert_rewarding_epoch_credential_issuance( + epoch_id, + *dkg_epoch_start, + *dkg_epoch_end, + reward.credentials.total_issued, + reward.credentials_budget.to_string(), + ) + .await?; + + for api_runner in reward.credentials.api_runners { + let reward_amount = api_runner + .reward_amount(&reward.credentials_budget) + .to_string(); + + self.manager + .insert_rewarding_epoch_credential_issuance_reward( + epoch_id, + api_runner.runner_account.to_string(), + reward_amount, + api_runner.api_runner, + api_runner.issued_credentials, + api_runner.issued_ratio.to_string(), + api_runner.validated_credentials, + ) + .await?; + } Ok(()) } From 162ff7181412d1302deca595c3573139514ccdf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 18 Dec 2023 14:05:02 +0000 Subject: [PATCH 13/21] more granual configs --- envs/sandbox.env | 1 + .../migrations/01_initial.sql | 2 +- nym-validator-rewarder/src/config/mod.rs | 42 +++++-- nym-validator-rewarder/src/error.rs | 3 + nym-validator-rewarder/src/main.rs | 3 + nym-validator-rewarder/src/rewarder/mod.rs | 110 ++++++++++++------ .../src/rewarder/storage/mod.rs | 96 +++++++++------ 7 files changed, 175 insertions(+), 82 deletions(-) diff --git a/envs/sandbox.env b/envs/sandbox.env index 856550cca0..5349798f41 100644 --- a/envs/sandbox.env +++ b/envs/sandbox.env @@ -24,4 +24,5 @@ SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS=n1ps5yutd7sufwg058qd7ac7ldnlazsvmhzq STATISTICS_SERVICE_DOMAIN_ADDRESS="http://0.0.0.0" EXPLORER_API=https://sandbox-explorer.nymtech.net/api NYXD="https://rpc.sandbox.nymtech.net" +NYXD_WS="wss://rpc.sandbox.nymtech.net/websocket" NYM_API="https://sandbox-nym-api1.nymtech.net/api" diff --git a/nym-validator-rewarder/migrations/01_initial.sql b/nym-validator-rewarder/migrations/01_initial.sql index ec7758fcb5..b59fdfe383 100644 --- a/nym-validator-rewarder/migrations/01_initial.sql +++ b/nym-validator-rewarder/migrations/01_initial.sql @@ -40,7 +40,7 @@ CREATE TABLE epoch_credential_issuance ( rewarding_epoch_id INTEGER NOT NULL PRIMARY KEY REFERENCES rewarding_epoch (id), starting_dkg_epoch INTEGER NOT NULL, - ending_dkg_epoch INTEGER NOT NULL, + ending_dkg_epoch INTEGER NOT NULL, total_issued_credentials INTEGER NOT NULL, budget TEXT NOT NULL ); diff --git a/nym-validator-rewarder/src/config/mod.rs b/nym-validator-rewarder/src/config/mod.rs index 0f696febdd..5ff7bde1bc 100644 --- a/nym-validator-rewarder/src/config/mod.rs +++ b/nym-validator-rewarder/src/config/mod.rs @@ -11,7 +11,7 @@ use nym_config::{ }; use nym_network_defaults::NymNetworkDetails; use nym_validator_client::nyxd; -use nym_validator_client::nyxd::{AccountId, Coin}; +use nym_validator_client::nyxd::Coin; use serde::{Deserialize, Serialize}; use std::io; use std::path::{Path, PathBuf}; @@ -69,6 +69,9 @@ pub struct Config { #[zeroize(skip)] pub rewarding: Rewarding, + #[zeroize(skip)] + pub block_signing: BlockSigning, + #[zeroize(skip)] pub issuance_monitor: IssuanceMonitor, @@ -95,8 +98,10 @@ impl Config { Config { save_path: None, rewarding: Rewarding::default(), + block_signing: Default::default(), issuance_monitor: IssuanceMonitor::default(), nyxd_scraper: NyxdScraper { + enabled: true, websocket_url: network.endpoints[0] .websocket_url() .expect("TODO: hardcoded websocket url is not available"), @@ -123,17 +128,11 @@ impl Config { .expect("failed to create nyxd client config") } - pub fn dkg_contract_address(&self) -> AccountId { - // TEMP - NymNetworkDetails::new_from_env() - .contracts - .coconut_dkg_contract_address - .expect("missing contract address") - .parse() - .expect("invalid contract address") - } - pub fn ensure_is_valid(&self) -> Result<(), NymRewarderError> { + if self.block_signing.enabled && !self.nyxd_scraper.enabled { + return Err(NymRewarderError::BlockSigningRewardWithoutScraper); + } + self.rewarding.ratios.ensure_is_valid()?; Ok(()) } @@ -192,7 +191,7 @@ pub struct Base { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Rewarding { - /// + /// Specifies total budget for the epoch pub epoch_budget: Coin, #[serde(with = "humantime_serde")] @@ -250,13 +249,31 @@ impl RewardingRatios { #[derive(Debug, Clone, Deserialize, Serialize)] pub struct NyxdScraper { + /// Specifies whether the chain scraper is enabled. + pub enabled: bool, + /// Url to the websocket endpoint of a validator, for example `wss://rpc.nymtech.net/websocket` pub websocket_url: Url, // TODO: debug with everything that's currently hardcoded in the scraper } +#[derive(Debug, Clone, Deserialize, Serialize, Copy)] +pub struct BlockSigning { + /// Specifies whether credential issuance for block signing is enabled. + pub enabled: bool, +} + +impl Default for BlockSigning { + fn default() -> Self { + BlockSigning { enabled: true } + } +} + #[derive(Debug, Clone, Deserialize, Serialize, Copy)] pub struct IssuanceMonitor { + /// Specifies whether credential issuance monitoring (and associated rewards) are enabled. + pub enabled: bool, + #[serde(with = "humantime_serde")] pub run_interval: Duration, @@ -271,6 +288,7 @@ pub struct IssuanceMonitor { impl Default for IssuanceMonitor { fn default() -> Self { IssuanceMonitor { + enabled: true, run_interval: DEFAULT_MONITOR_RUN_INTERVAL, min_validate_per_issuer: DEFAULT_MONITOR_MIN_VALIDATE, sampling_rate: DEFAULT_MONITOR_SAMPLING_RATE, diff --git a/nym-validator-rewarder/src/error.rs b/nym-validator-rewarder/src/error.rs index 62b92cd398..03c3fc4d60 100644 --- a/nym-validator-rewarder/src/error.rs +++ b/nym-validator-rewarder/src/error.rs @@ -150,4 +150,7 @@ pub enum NymRewarderError { request: Option, on_chain: String, }, + + #[error("can't enable block signing rewarding without the block scraper")] + BlockSigningRewardWithoutScraper, } diff --git a/nym-validator-rewarder/src/main.rs b/nym-validator-rewarder/src/main.rs index f5d59b57c2..fb03008a9a 100644 --- a/nym-validator-rewarder/src/main.rs +++ b/nym-validator-rewarder/src/main.rs @@ -1,6 +1,9 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only +#![warn(clippy::expect_used)] +#![warn(clippy::unwrap_used)] + use crate::cli::Cli; use clap::{crate_name, crate_version, Parser}; use nym_bin_common::logging::{maybe_print_banner, setup_tracing_logger}; diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index 332fe86ff7..0193dd4b4e 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -30,8 +30,8 @@ mod tasks; pub struct EpochRewards { pub epoch: Epoch, - pub signing: EpochSigningResults, - pub credentials: CredentialIssuanceResults, + pub signing: Option, + pub credentials: Option, pub total_budget: Coin, pub signing_budget: Coin, @@ -40,11 +40,17 @@ pub struct EpochRewards { impl EpochRewards { pub fn amounts(&self) -> Vec<(AccountId, Vec)> { - let signing = self.signing.rewarding_amounts(&self.signing_budget); - let mut credentials = self.credentials.rewarding_amounts(&self.credentials_budget); + let mut amounts = Vec::new(); - let mut amounts = signing; - amounts.append(&mut credentials); + if let Some(signing) = &self.signing { + let mut signing_amounts = signing.rewarding_amounts(&self.signing_budget); + amounts.append(&mut signing_amounts); + } + + if let Some(credentials) = &self.credentials { + let mut credentials_amounts = credentials.rewarding_amounts(&self.credentials_budget); + amounts.append(&mut credentials_amounts); + } amounts } @@ -65,13 +71,18 @@ pub struct Rewarder { storage: RewarderStorage, nyxd_client: NyxdClient, - epoch_signing: EpochSigning, - credential_issuance: CredentialIssuance, + epoch_signing: Option, + credential_issuance: Option, } impl Rewarder { pub async fn new(config: Config) -> Result { - let nyxd_scraper = NyxdScraper::new(config.scraper_config()).await?; + let nyxd_scraper = if config.nyxd_scraper.enabled { + Some(NyxdScraper::new(config.scraper_config()).await?) + } else { + None + }; + let nyxd_client = NyxdClient::new(&config); let storage = RewarderStorage::init(&config.storage_paths.reward_history).await?; let current_epoch = if let Some(last_epoch) = storage.load_last_rewarding_epoch().await? { @@ -80,13 +91,28 @@ impl Rewarder { Epoch::first(config.rewarding.epoch_duration)? }; + let epoch_signing = if config.block_signing.enabled { + // safety: our config has been validated at load time to ensure that if block signing is enabled, + // so is the scraper + Some(EpochSigning { + #[allow(clippy::unwrap_used)] + nyxd_scraper: nyxd_scraper.unwrap(), + nyxd_client: nyxd_client.clone(), + }) + } else { + None + }; + + let credential_issuance = if config.issuance_monitor.enabled { + Some(CredentialIssuance::new(current_epoch, &nyxd_client).await?) + } else { + None + }; + Ok(Rewarder { current_epoch, - credential_issuance: CredentialIssuance::new(current_epoch, &nyxd_client).await?, - epoch_signing: EpochSigning { - nyxd_scraper, - nyxd_client: nyxd_client.clone(), - }, + credential_issuance, + epoch_signing, nyxd_client, storage, config, @@ -96,21 +122,35 @@ impl Rewarder { #[instrument(skip(self))] async fn calculate_block_signing_rewards( &mut self, - ) -> Result { + ) -> Result, NymRewarderError> { info!("calculating reward shares"); - self.epoch_signing - .get_signed_blocks_results(self.current_epoch) - .await + if let Some(epoch_signing) = &mut self.epoch_signing { + Some( + epoch_signing + .get_signed_blocks_results(self.current_epoch) + .await, + ) + } else { + None + } + .transpose() } #[instrument(skip(self))] async fn calculate_credential_rewards( &mut self, - ) -> Result { + ) -> Result, NymRewarderError> { info!("calculating reward shares"); - self.credential_issuance - .get_issued_credentials_results(self.current_epoch) - .await + if let Some(credential_issuance) = &mut self.credential_issuance { + Some( + credential_issuance + .get_issued_credentials_results(self.current_epoch) + .await, + ) + } else { + None + } + .transpose() } async fn determine_epoch_rewards(&mut self) -> Result { @@ -180,16 +220,18 @@ impl Rewarder { // setup shutdowns let mut task_manager = TaskManager::new(5); - self.credential_issuance.start_monitor( - self.config.issuance_monitor, - self.nyxd_client.clone(), - task_manager.subscribe(), - ); - self.epoch_signing.nyxd_scraper.start().await?; - self.epoch_signing - .nyxd_scraper - .wait_for_startup_sync() - .await; + if let Some(ref credential_issuance) = self.credential_issuance { + credential_issuance.start_monitor( + self.config.issuance_monitor, + self.nyxd_client.clone(), + task_manager.subscribe(), + ); + } + + if let Some(epoch_signing) = &self.epoch_signing { + epoch_signing.nyxd_scraper.start().await?; + epoch_signing.nyxd_scraper.wait_for_startup_sync().await; + } // rewarding epochs last from :00 to :00 // \/\/\/\/\/\/\/ TEMP TESTING!!! @@ -225,7 +267,9 @@ impl Rewarder { } } - self.epoch_signing.nyxd_scraper.stop().await; + if let Some(epoch_signing) = self.epoch_signing { + epoch_signing.nyxd_scraper.stop().await; + } Ok(()) } diff --git a/nym-validator-rewarder/src/rewarder/storage/mod.rs b/nym-validator-rewarder/src/rewarder/storage/mod.rs index 784361a37c..36a2c23790 100644 --- a/nym-validator-rewarder/src/rewarder/storage/mod.rs +++ b/nym-validator-rewarder/src/rewarder/storage/mod.rs @@ -81,58 +81,82 @@ impl RewarderStorage { self.manager .insert_rewarding_epoch_block_signing( epoch_id, - reward.signing.total_voting_power_at_epoch_start, - reward.signing.blocks, + reward + .signing + .as_ref() + .map(|s| s.total_voting_power_at_epoch_start) + .unwrap_or_default(), + reward + .signing + .as_ref() + .map(|s| s.blocks) + .unwrap_or_default(), reward.signing_budget.to_string(), ) .await?; - for validator in reward.signing.validators { - let reward_amount = validator.reward_amount(&reward.signing_budget).to_string(); - self.manager - .insert_rewarding_epoch_block_signing_reward( - epoch_id, - validator.validator.consensus_address, - validator.operator_account.to_string(), - reward_amount, - validator.voting_power_at_epoch_start, - validator.voting_power_ratio.to_string(), - validator.signed_blocks, - validator.ratio_signed.to_string(), - ) - .await?; + if let Some(signing) = reward.signing { + for validator in signing.validators { + let reward_amount = validator.reward_amount(&reward.signing_budget).to_string(); + self.manager + .insert_rewarding_epoch_block_signing_reward( + epoch_id, + validator.validator.consensus_address, + validator.operator_account.to_string(), + reward_amount, + validator.voting_power_at_epoch_start, + validator.voting_power_ratio.to_string(), + validator.signed_blocks, + validator.ratio_signed.to_string(), + ) + .await?; + } } // safety: we must have at least a single value here - let dkg_epoch_start = reward.credentials.dkg_epochs.first().unwrap(); - let dkg_epoch_end = reward.credentials.dkg_epochs.last().unwrap(); + let dkg_epoch_start = reward + .credentials + .as_ref() + .map(|c| *c.dkg_epochs.first().unwrap()) + .unwrap_or_default(); + let dkg_epoch_end = reward + .credentials + .as_ref() + .map(|c| *c.dkg_epochs.last().unwrap()) + .unwrap_or_default(); self.manager .insert_rewarding_epoch_credential_issuance( epoch_id, - *dkg_epoch_start, - *dkg_epoch_end, - reward.credentials.total_issued, + dkg_epoch_start, + dkg_epoch_end, + reward + .credentials + .as_ref() + .map(|c| c.total_issued) + .unwrap_or_default(), reward.credentials_budget.to_string(), ) .await?; - for api_runner in reward.credentials.api_runners { - let reward_amount = api_runner - .reward_amount(&reward.credentials_budget) - .to_string(); + if let Some(credentials) = reward.credentials { + for api_runner in credentials.api_runners { + let reward_amount = api_runner + .reward_amount(&reward.credentials_budget) + .to_string(); - self.manager - .insert_rewarding_epoch_credential_issuance_reward( - epoch_id, - api_runner.runner_account.to_string(), - reward_amount, - api_runner.api_runner, - api_runner.issued_credentials, - api_runner.issued_ratio.to_string(), - api_runner.validated_credentials, - ) - .await?; + self.manager + .insert_rewarding_epoch_credential_issuance_reward( + epoch_id, + api_runner.runner_account.to_string(), + reward_amount, + api_runner.api_runner, + api_runner.issued_credentials, + api_runner.issued_ratio.to_string(), + api_runner.validated_credentials, + ) + .await?; + } } Ok(()) From defd148d7392828446264b8f4cb5ac94899a64e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 18 Dec 2023 15:32:08 +0000 Subject: [PATCH 14/21] cli arguments + balance check --- Cargo.lock | 1 + .../validator-client/src/nyxd/coin.rs | 33 ++++++++++ nym-validator-rewarder/Cargo.toml | 1 + nym-validator-rewarder/src/cli/init.rs | 12 ++-- nym-validator-rewarder/src/cli/mod.rs | 52 +++++++++++++++- nym-validator-rewarder/src/cli/run.rs | 13 ++-- nym-validator-rewarder/src/config/mod.rs | 11 ++-- nym-validator-rewarder/src/config/override.rs | 62 +++++++++++++++++-- nym-validator-rewarder/src/error.rs | 9 ++- nym-validator-rewarder/src/rewarder/mod.rs | 18 ++++++ .../src/rewarder/nyxd_client.rs | 11 +++- 11 files changed, 193 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 83d13f5e18..e777744c3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7529,6 +7529,7 @@ dependencies = [ "clap 4.4.7", "cosmwasm-std", "futures", + "humantime 2.1.0", "humantime-serde", "nym-bin-common", "nym-coconut", diff --git a/common/client-libs/validator-client/src/nyxd/coin.rs b/common/client-libs/validator-client/src/nyxd/coin.rs index f780bd32f3..0fa175a243 100644 --- a/common/client-libs/validator-client/src/nyxd/coin.rs +++ b/common/client-libs/validator-client/src/nyxd/coin.rs @@ -8,6 +8,8 @@ use cosmwasm_std::{Fraction, Uint128}; use serde::{Deserialize, Serialize}; use std::fmt; use std::ops::Div; +use std::str::FromStr; +use thiserror::Error; #[derive(Serialize, Deserialize, Clone, Copy, Default, Debug, PartialEq, Eq)] pub struct MismatchedDenoms; @@ -126,6 +128,37 @@ impl From for Coin { } } +// unfortunately cosmwasm didn't re-export this correct so we just redefine its +#[derive(Error, Debug, PartialEq, Eq)] +pub enum CoinFromStrError { + #[error("Missing denominator")] + MissingDenom, + #[error("Missing amount or non-digit characters in amount")] + MissingAmount, + #[error("Invalid amount: {0}")] + InvalidAmount(#[from] std::num::ParseIntError), +} + +impl FromStr for Coin { + type Err = CoinFromStrError; + + fn from_str(s: &str) -> Result { + let pos = s + .find(|c: char| !c.is_ascii_digit()) + .ok_or(CoinFromStrError::MissingDenom)?; + let (amount, denom) = s.split_at(pos); + + if amount.is_empty() { + return Err(CoinFromStrError::MissingAmount); + } + + Ok(Coin { + amount: amount.parse::()?, + denom: denom.to_string(), + }) + } +} + pub trait CoinConverter { type Target; diff --git a/nym-validator-rewarder/Cargo.toml b/nym-validator-rewarder/Cargo.toml index 272b542ddc..c197889d34 100644 --- a/nym-validator-rewarder/Cargo.toml +++ b/nym-validator-rewarder/Cargo.toml @@ -26,6 +26,7 @@ url.workspace = true zeroize.workspace = true sha2 = "0.10.8" +humantime = "2.1.0" humantime-serde = "1.0" # internal diff --git a/nym-validator-rewarder/src/cli/init.rs b/nym-validator-rewarder/src/cli/init.rs index 946b50c476..fbfbff7f34 100644 --- a/nym-validator-rewarder/src/cli/init.rs +++ b/nym-validator-rewarder/src/cli/init.rs @@ -1,6 +1,7 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only +use crate::cli::ConfigOverridableArgs; use crate::config::{default_config_directory, default_data_directory, Config}; use crate::error::NymRewarderError; use std::path::PathBuf; @@ -24,11 +25,6 @@ pub struct Args { force: bool, } -#[derive(Debug, clap::Args)] -pub struct ConfigOverridableArgs { - // -} - fn init_paths() -> io::Result<()> { fs::create_dir_all(default_data_directory())?; fs::create_dir_all(default_config_directory()) @@ -46,8 +42,10 @@ pub(crate) fn execute(args: Args) -> Result<(), NymRewarderError> { init_paths().map_err(|source| NymRewarderError::PathInitialisationFailure { source })?; - Config::new(args.mnemonic) - .with_override(args.config_override) + let config = Config::new(args.mnemonic).with_override(args.config_override); + config.ensure_is_valid()?; + + config .save_to_path(&path) .map_err(|source| NymRewarderError::ConfigSaveFailure { path, source })?; diff --git a/nym-validator-rewarder/src/cli/mod.rs b/nym-validator-rewarder/src/cli/mod.rs index ba64c80e7f..c78bfd5c59 100644 --- a/nym-validator-rewarder/src/cli/mod.rs +++ b/nym-validator-rewarder/src/cli/mod.rs @@ -4,10 +4,13 @@ use crate::config::Config; use crate::error::NymRewarderError; use clap::{Parser, Subcommand}; +use humantime_serde::re::humantime; use nym_bin_common::bin_info; +use nym_validator_client::nyxd::Coin; use std::path::PathBuf; use std::sync::OnceLock; use tracing::{debug, error}; +use url::Url; pub mod build_info; pub mod init; @@ -45,6 +48,48 @@ impl Cli { } } +#[derive(Debug, clap::Args)] +pub struct ConfigOverridableArgs { + #[clap(long)] + pub disable_block_signing_rewarding: bool, + + #[clap(long)] + pub disable_block_scraper: bool, + + #[clap(long)] + pub disable_credential_issuance_rewarding: bool, + + #[clap(long)] + pub credential_monitor_run_interval: Option, + + #[clap(long)] + pub credential_monitor_min_validation: Option, + + #[clap(long)] + pub credential_monitor_sampling_rate: Option, + + #[clap(long)] + pub scraper_endpoint: Option, + + #[clap(long)] + pub nyxd_endpoint: Option, + + #[clap(long)] + pub epoch_budget: Option, + + #[clap(long)] + pub epoch_duration: Option, + + #[clap(long)] + pub block_signing_reward_ratio: Option, + + #[clap(long)] + pub credential_issuance_reward_ratio: Option, + + #[clap(long)] + pub credential_verification_reward_ratio: Option, +} + #[derive(Subcommand, Debug)] pub(crate) enum Commands { /// Initialise a validator rewarder with persistent config.toml file. @@ -66,17 +111,20 @@ fn try_load_current_config(custom_path: &Option) -> Result // SPDX-License-Identifier: GPL-3.0-only -use crate::cli::try_load_current_config; -use crate::config::Config; +use crate::cli::{try_load_current_config, ConfigOverridableArgs}; use crate::error::NymRewarderError; use crate::rewarder::Rewarder; -use bip39::Mnemonic; use std::path::PathBuf; #[derive(Debug, clap::Args)] pub struct Args { + #[command(flatten)] + config_override: ConfigOverridableArgs, + /// Specifies custom location for the configuration file of nym validators rewarder. + #[clap(long)] custom_config_path: Option, } pub(crate) async fn execute(args: Args) -> Result<(), NymRewarderError> { - // let config = try_load_current_config(&args.custom_config_path)?.with_override(args); - - let config = Config::new(Mnemonic::generate(24).unwrap()); + let config = + try_load_current_config(&args.custom_config_path)?.with_override(args.config_override); Rewarder::new(config).await?.run().await } diff --git a/nym-validator-rewarder/src/config/mod.rs b/nym-validator-rewarder/src/config/mod.rs index 5ff7bde1bc..f692c723de 100644 --- a/nym-validator-rewarder/src/config/mod.rs +++ b/nym-validator-rewarder/src/config/mod.rs @@ -220,9 +220,8 @@ pub struct RewardingRatios { /// The percent of the epoch reward being awarded for credential verification. pub credential_verification: f64, - - /// The percent of the epoch reward given to Nym. - pub nym: f64, + // /// The percent of the epoch reward given to Nym. + // pub nym: f64, } impl Default for RewardingRatios { @@ -231,16 +230,14 @@ impl Default for RewardingRatios { block_signing: 0.67, credential_issuance: 0.33, credential_verification: 0.0, - nym: 0.0, + // nym: 0.0, } } } impl RewardingRatios { pub fn ensure_is_valid(&self) -> Result<(), NymRewarderError> { - if self.block_signing + self.credential_verification + self.credential_issuance + self.nym - != 1.0 - { + if self.block_signing + self.credential_verification + self.credential_issuance != 1.0 { todo!() } Ok(()) diff --git a/nym-validator-rewarder/src/config/override.rs b/nym-validator-rewarder/src/config/override.rs index 4c1089b3c3..019c26c420 100644 --- a/nym-validator-rewarder/src/config/override.rs +++ b/nym-validator-rewarder/src/config/override.rs @@ -1,17 +1,67 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use crate::cli::{init, run}; +use crate::cli::ConfigOverridableArgs; use crate::config::Config; pub trait ConfigOverride { fn override_config(self, config: &mut Config); } -impl ConfigOverride for init::ConfigOverridableArgs { - fn override_config(self, config: &mut Config) {} -} +impl ConfigOverride for ConfigOverridableArgs { + fn override_config(self, config: &mut Config) { + if self.disable_block_signing_rewarding { + config.block_signing.enabled = false + } -impl ConfigOverride for run::Args { - fn override_config(self, config: &mut Config) {} + if self.disable_block_scraper { + config.nyxd_scraper.enabled = false + } + + if self.disable_credential_issuance_rewarding { + config.issuance_monitor.enabled = false + } + + if let Some(credential_monitor_run_interval) = self.credential_monitor_run_interval { + config.issuance_monitor.run_interval = credential_monitor_run_interval.into() + } + + if let Some(credential_monitor_min_validation) = self.credential_monitor_min_validation { + config.issuance_monitor.min_validate_per_issuer = credential_monitor_min_validation + } + + if let Some(credential_monitor_sampling_rate) = self.credential_monitor_sampling_rate { + config.issuance_monitor.sampling_rate = credential_monitor_sampling_rate + } + + if let Some(scraper_endpoint) = self.scraper_endpoint { + config.nyxd_scraper.websocket_url = scraper_endpoint + } + + if let Some(nyxd_endpoint) = self.nyxd_endpoint { + config.base.upstream_nyxd = nyxd_endpoint + } + + if let Some(epoch_budget) = self.epoch_budget { + config.rewarding.epoch_budget = epoch_budget + } + + if let Some(epoch_duration_secs) = self.epoch_duration { + config.rewarding.epoch_duration = epoch_duration_secs.into() + } + + if let Some(block_signing_reward_ratio) = self.block_signing_reward_ratio { + config.rewarding.ratios.block_signing = block_signing_reward_ratio; + } + + if let Some(credential_issuance_reward_ratio) = self.credential_issuance_reward_ratio { + config.rewarding.ratios.credential_issuance = credential_issuance_reward_ratio; + } + + if let Some(credential_verification_reward_ratio) = + self.credential_verification_reward_ratio + { + config.rewarding.ratios.credential_verification = credential_verification_reward_ratio; + } + } } diff --git a/nym-validator-rewarder/src/error.rs b/nym-validator-rewarder/src/error.rs index 03c3fc4d60..9fe43232bb 100644 --- a/nym-validator-rewarder/src/error.rs +++ b/nym-validator-rewarder/src/error.rs @@ -5,7 +5,7 @@ use nym_coconut::CoconutError; use nym_validator_client::nym_api::error::NymAPIError; use nym_validator_client::nyxd::error::NyxdError; use nym_validator_client::nyxd::tx::ErrorReport; -use nym_validator_client::nyxd::{AccountId, Hash}; +use nym_validator_client::nyxd::{AccountId, Coin, Hash}; use std::io; use std::path::PathBuf; use thiserror::Error; @@ -153,4 +153,11 @@ pub enum NymRewarderError { #[error("can't enable block signing rewarding without the block scraper")] BlockSigningRewardWithoutScraper, + + #[error("the current rewarder balance is insufficient to start the process. The epoch budget is: {epoch_budget} while we currently have {balance}. (the minimum is set to {minimum})")] + InsufficientRewarderBalance { + epoch_budget: Coin, + balance: Coin, + minimum: Coin, + }, } diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index 0193dd4b4e..365b06cfbd 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -109,6 +109,24 @@ impl Rewarder { None }; + if config.issuance_monitor.enabled || config.block_signing.enabled { + let balance = nyxd_client + .balance(&config.rewarding.epoch_budget.denom) + .await?; + let minimum = Coin::new( + config.rewarding.epoch_budget.amount * 100, + &config.rewarding.epoch_budget.denom, + ); + + if balance.amount < minimum.amount { + return Err(NymRewarderError::InsufficientRewarderBalance { + epoch_budget: config.rewarding.epoch_budget.clone(), + balance, + minimum, + }); + } + } + Ok(Rewarder { current_epoch, credential_issuance, diff --git a/nym-validator-rewarder/src/rewarder/nyxd_client.rs b/nym-validator-rewarder/src/rewarder/nyxd_client.rs index 2806a7cd55..1bcd4bdf94 100644 --- a/nym-validator-rewarder/src/rewarder/nyxd_client.rs +++ b/nym-validator-rewarder/src/rewarder/nyxd_client.rs @@ -14,7 +14,7 @@ use nym_validator_client::nyxd::module_traits::staking::{ QueryHistoricalInfoResponse, QueryValidatorsResponse, }; use nym_validator_client::nyxd::{ - AccountId, CosmWasmClient, Hash, PageRequest, StakingQueryClient, + AccountId, Coin, CosmWasmClient, Hash, PageRequest, StakingQueryClient, }; use nym_validator_client::DirectSigningHttpRpcNyxdClient; use std::ops::Deref; @@ -49,6 +49,15 @@ impl NyxdClient { self.inner.read().await.address() } + pub(crate) async fn balance(&self, denom: &str) -> Result { + let guard = self.inner.read().await; + let address = guard.address(); + Ok(guard + .get_balance(&address, denom.to_string()) + .await? + .unwrap_or(Coin::new(0, denom))) + } + pub(crate) async fn historical_info( &self, height: i64, From 6c1d14a4bca62fe400657ed202a085a8c7ac75f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 18 Dec 2023 15:40:01 +0000 Subject: [PATCH 15/21] clippy --- nym-validator-rewarder/src/cli/init.rs | 9 ++++++++- nym-validator-rewarder/src/config/mod.rs | 18 +++--------------- nym-validator-rewarder/src/error.rs | 18 ++++++++++++------ .../src/rewarder/credential_issuance/types.rs | 1 + nym-validator-rewarder/src/rewarder/mod.rs | 16 +++++++++------- .../src/rewarder/nyxd_client.rs | 15 ++++++++------- .../src/rewarder/storage/manager.rs | 2 ++ .../src/rewarder/storage/mod.rs | 2 ++ 8 files changed, 45 insertions(+), 36 deletions(-) diff --git a/nym-validator-rewarder/src/cli/init.rs b/nym-validator-rewarder/src/cli/init.rs index fbfbff7f34..071bc0af97 100644 --- a/nym-validator-rewarder/src/cli/init.rs +++ b/nym-validator-rewarder/src/cli/init.rs @@ -4,6 +4,7 @@ use crate::cli::ConfigOverridableArgs; use crate::config::{default_config_directory, default_data_directory, Config}; use crate::error::NymRewarderError; +use nym_network_defaults::NymNetworkDetails; use std::path::PathBuf; use std::{fs, io}; @@ -42,7 +43,13 @@ pub(crate) fn execute(args: Args) -> Result<(), NymRewarderError> { init_paths().map_err(|source| NymRewarderError::PathInitialisationFailure { source })?; - let config = Config::new(args.mnemonic).with_override(args.config_override); + let network = NymNetworkDetails::new_from_env(); + let nyxd = network.endpoints[0].nyxd_url(); + let Some(websocket) = network.endpoints[0].websocket_url() else { + return Err(NymRewarderError::UnavailableWebsocketUrl); + }; + + let config = Config::new(args.mnemonic, websocket, nyxd).with_override(args.config_override); config.ensure_is_valid()?; config diff --git a/nym-validator-rewarder/src/config/mod.rs b/nym-validator-rewarder/src/config/mod.rs index f692c723de..d859f8401e 100644 --- a/nym-validator-rewarder/src/config/mod.rs +++ b/nym-validator-rewarder/src/config/mod.rs @@ -9,8 +9,6 @@ use nym_config::{ must_get_home, read_config_from_toml_file, save_formatted_config_to_file, NymConfigTemplate, DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME, DEFAULT_DATA_DIR, NYM_DIR, }; -use nym_network_defaults::NymNetworkDetails; -use nym_validator_client::nyxd; use nym_validator_client::nyxd::Coin; use serde::{Deserialize, Serialize}; use std::io; @@ -92,9 +90,7 @@ impl NymConfigTemplate for Config { } impl Config { - pub fn new(mnemonic: bip39::Mnemonic) -> Self { - let network = NymNetworkDetails::new_from_env(); - + pub fn new(mnemonic: bip39::Mnemonic, websocket_url: Url, nyxd_url: Url) -> Self { Config { save_path: None, rewarding: Rewarding::default(), @@ -102,12 +98,10 @@ impl Config { issuance_monitor: IssuanceMonitor::default(), nyxd_scraper: NyxdScraper { enabled: true, - websocket_url: network.endpoints[0] - .websocket_url() - .expect("TODO: hardcoded websocket url is not available"), + websocket_url, }, base: Base { - upstream_nyxd: network.endpoints[0].nyxd_url(), + upstream_nyxd: nyxd_url, mnemonic, }, storage_paths: Default::default(), @@ -122,12 +116,6 @@ impl Config { } } - pub fn rpc_client_config(&self) -> nyxd::Config { - // TEMP - nyxd::Config::try_from_nym_network_details(&NymNetworkDetails::new_from_env()) - .expect("failed to create nyxd client config") - } - pub fn ensure_is_valid(&self) -> Result<(), NymRewarderError> { if self.block_signing.enabled && !self.nyxd_scraper.enabled { return Err(NymRewarderError::BlockSigningRewardWithoutScraper); diff --git a/nym-validator-rewarder/src/error.rs b/nym-validator-rewarder/src/error.rs index 9fe43232bb..30372125d1 100644 --- a/nym-validator-rewarder/src/error.rs +++ b/nym-validator-rewarder/src/error.rs @@ -154,10 +154,16 @@ pub enum NymRewarderError { #[error("can't enable block signing rewarding without the block scraper")] BlockSigningRewardWithoutScraper, - #[error("the current rewarder balance is insufficient to start the process. The epoch budget is: {epoch_budget} while we currently have {balance}. (the minimum is set to {minimum})")] - InsufficientRewarderBalance { - epoch_budget: Coin, - balance: Coin, - minimum: Coin, - }, + #[error("the current rewarder balance is insufficient to start the process. The epoch budget is: {} while we currently have {}. (the minimum is set to {})", .0.epoch_budget, .0.balance, .0.minimum)] + InsufficientRewarderBalance(Box), + + #[error("the scraper websocket endpoint hasn't been provided")] + UnavailableWebsocketUrl, +} + +#[derive(Debug)] +pub struct InsufficientBalance { + pub epoch_budget: Coin, + pub balance: Coin, + pub minimum: Coin, } diff --git a/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs b/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs index a4be44047d..0ec94cae88 100644 --- a/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs +++ b/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs @@ -109,6 +109,7 @@ impl MonitoringResults { let next_epoch = guard.epoch.next(); // safety: whenever the monitor results are constructed, we always have at least a single value there + #[allow(clippy::unwrap_used)] let latest_dkg_epoch = guard.dkg_epochs.pop().unwrap(); // only keep results from the latest dkg epoch (but after resetting the counters) diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index 365b06cfbd..a746d9ca33 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::config::Config; -use crate::error::NymRewarderError; +use crate::error::{InsufficientBalance, NymRewarderError}; use crate::rewarder::block_signing::types::EpochSigningResults; use crate::rewarder::block_signing::EpochSigning; use crate::rewarder::credential_issuance::types::CredentialIssuanceResults; @@ -83,7 +83,7 @@ impl Rewarder { None }; - let nyxd_client = NyxdClient::new(&config); + let nyxd_client = NyxdClient::new(&config)?; let storage = RewarderStorage::init(&config.storage_paths.reward_history).await?; let current_epoch = if let Some(last_epoch) = storage.load_last_rewarding_epoch().await? { last_epoch.next() @@ -119,11 +119,13 @@ impl Rewarder { ); if balance.amount < minimum.amount { - return Err(NymRewarderError::InsufficientRewarderBalance { - epoch_budget: config.rewarding.epoch_budget.clone(), - balance, - minimum, - }); + return Err(NymRewarderError::InsufficientRewarderBalance(Box::new( + InsufficientBalance { + epoch_budget: config.rewarding.epoch_budget.clone(), + balance, + minimum, + }, + ))); } } diff --git a/nym-validator-rewarder/src/rewarder/nyxd_client.rs b/nym-validator-rewarder/src/rewarder/nyxd_client.rs index 1bcd4bdf94..c5fa37418a 100644 --- a/nym-validator-rewarder/src/rewarder/nyxd_client.rs +++ b/nym-validator-rewarder/src/rewarder/nyxd_client.rs @@ -8,6 +8,7 @@ use nym_coconut_bandwidth_contract_common::events::{ COSMWASM_DEPOSITED_FUNDS_EVENT_TYPE, DEPOSIT_INFO, DEPOSIT_VALUE, }; use nym_coconut_dkg_common::types::Epoch; +use nym_network_defaults::NymNetworkDetails; use nym_validator_client::nyxd::contract_traits::{DkgQueryClient, PagedDkgQueryClient}; use nym_validator_client::nyxd::helpers::find_tx_attribute; use nym_validator_client::nyxd::module_traits::staking::{ @@ -16,7 +17,7 @@ use nym_validator_client::nyxd::module_traits::staking::{ use nym_validator_client::nyxd::{ AccountId, Coin, CosmWasmClient, Hash, PageRequest, StakingQueryClient, }; -use nym_validator_client::DirectSigningHttpRpcNyxdClient; +use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient}; use std::ops::Deref; use std::sync::Arc; use tokio::sync::RwLock; @@ -27,8 +28,9 @@ pub struct NyxdClient { } impl NyxdClient { - pub(crate) fn new(config: &Config) -> Self { - let client_config = config.rpc_client_config(); + pub(crate) fn new(config: &Config) -> Result { + let client_config = + nyxd::Config::try_from_nym_network_details(&NymNetworkDetails::new_from_env())?; let nyxd_url = config.base.upstream_nyxd.as_str(); let mnemonic = config.base.mnemonic.clone(); @@ -37,12 +39,11 @@ impl NyxdClient { client_config, nyxd_url, mnemonic, - ) - .expect("Failed to connect to nyxd!"); + )?; - NyxdClient { + Ok(NyxdClient { inner: Arc::new(RwLock::new(inner)), - } + }) } pub(crate) async fn address(&self) -> AccountId { diff --git a/nym-validator-rewarder/src/rewarder/storage/manager.rs b/nym-validator-rewarder/src/rewarder/storage/manager.rs index ddcb05049c..855c830fb5 100644 --- a/nym-validator-rewarder/src/rewarder/storage/manager.rs +++ b/nym-validator-rewarder/src/rewarder/storage/manager.rs @@ -68,6 +68,7 @@ impl StorageManager { Ok(()) } + #[allow(clippy::too_many_arguments)] pub(crate) async fn insert_rewarding_epoch_block_signing_reward( &self, epoch: i64, @@ -138,6 +139,7 @@ impl StorageManager { Ok(()) } + #[allow(clippy::too_many_arguments)] pub(crate) async fn insert_rewarding_epoch_credential_issuance_reward( &self, epoch: i64, diff --git a/nym-validator-rewarder/src/rewarder/storage/mod.rs b/nym-validator-rewarder/src/rewarder/storage/mod.rs index 36a2c23790..35b2160d8d 100644 --- a/nym-validator-rewarder/src/rewarder/storage/mod.rs +++ b/nym-validator-rewarder/src/rewarder/storage/mod.rs @@ -114,11 +114,13 @@ impl RewarderStorage { } // safety: we must have at least a single value here + #[allow(clippy::unwrap_used)] let dkg_epoch_start = reward .credentials .as_ref() .map(|c| *c.dkg_epochs.first().unwrap()) .unwrap_or_default(); + #[allow(clippy::unwrap_used)] let dkg_epoch_end = reward .credentials .as_ref() From a3c15416603b9cddc6f0f0c4457f8b70774f5e6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 18 Dec 2023 16:14:01 +0000 Subject: [PATCH 16/21] actually sending the rewards --- nym-validator-rewarder/src/rewarder/mod.rs | 10 +++------- .../src/rewarder/nyxd_client.rs | 18 ++++++++++++++---- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index a746d9ca33..5e4f2aad42 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -202,13 +202,9 @@ impl Rewarder { &self, amounts: Vec<(AccountId, Vec)>, ) -> Result { - let address = self.nyxd_client.address().await; - info!("here we ({address}) will be sending the following rewards:"); - for (target, amount) in amounts { - info!("{amount:?} to {target}") - } - - Ok(Hash::Sha256([0u8; 32])) + self.nyxd_client + .send_rewards(self.current_epoch, amounts) + .await } async fn handle_epoch_end(&mut self) { diff --git a/nym-validator-rewarder/src/rewarder/nyxd_client.rs b/nym-validator-rewarder/src/rewarder/nyxd_client.rs index c5fa37418a..b430136930 100644 --- a/nym-validator-rewarder/src/rewarder/nyxd_client.rs +++ b/nym-validator-rewarder/src/rewarder/nyxd_client.rs @@ -46,10 +46,6 @@ impl NyxdClient { }) } - pub(crate) async fn address(&self) -> AccountId { - self.inner.read().await.address() - } - pub(crate) async fn balance(&self, denom: &str) -> Result { let guard = self.inner.read().await; let address = guard.address(); @@ -59,6 +55,20 @@ impl NyxdClient { .unwrap_or(Coin::new(0, denom))) } + pub(crate) async fn send_rewards( + &self, + epoch: crate::rewarder::Epoch, + amounts: Vec<(AccountId, Vec)>, + ) -> Result { + self.inner + .write() + .await + .send_multiple(amounts, format!("sending rewards for {epoch:?}"), None) + .await + .map(|res| res.hash) + .map_err(Into::into) + } + pub(crate) async fn historical_info( &self, height: i64, From bd8f666405af46f25cdfdda830bacfd2b146d5d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 18 Dec 2023 16:14:07 +0000 Subject: [PATCH 17/21] config template --- Cargo.lock | 65 +++++++++++++++++++ nym-validator-rewarder/Cargo.toml | 1 + nym-validator-rewarder/src/cli/mod.rs | 2 +- nym-validator-rewarder/src/config/mod.rs | 12 +++- nym-validator-rewarder/src/config/template.rs | 50 ++++++++++++++ .../rewarder/credential_issuance/monitor.rs | 2 +- 6 files changed, 127 insertions(+), 5 deletions(-) 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() From 22541f5a7915019e42a97f816ac49b7104651011 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 18 Dec 2023 17:42:41 +0000 Subject: [PATCH 18/21] smoothing some rough edges --- .../migrations/01_initial.sql | 2 +- nym-validator-rewarder/src/cli/mod.rs | 5 +- nym-validator-rewarder/src/config/mod.rs | 16 +---- nym-validator-rewarder/src/config/override.rs | 4 -- nym-validator-rewarder/src/config/template.rs | 3 - nym-validator-rewarder/src/error.rs | 3 - .../rewarder/credential_issuance/monitor.rs | 10 +++- .../src/rewarder/credential_issuance/types.rs | 17 +++--- nym-validator-rewarder/src/rewarder/mod.rs | 59 +++++++++---------- .../src/rewarder/storage/manager.rs | 6 +- .../src/rewarder/storage/mod.rs | 11 ++-- 11 files changed, 56 insertions(+), 80 deletions(-) diff --git a/nym-validator-rewarder/migrations/01_initial.sql b/nym-validator-rewarder/migrations/01_initial.sql index b59fdfe383..b7b7b9f22f 100644 --- a/nym-validator-rewarder/migrations/01_initial.sql +++ b/nym-validator-rewarder/migrations/01_initial.sql @@ -41,7 +41,7 @@ CREATE TABLE epoch_credential_issuance rewarding_epoch_id INTEGER NOT NULL PRIMARY KEY REFERENCES rewarding_epoch (id), starting_dkg_epoch INTEGER NOT NULL, ending_dkg_epoch INTEGER NOT NULL, - total_issued_credentials INTEGER NOT NULL, + total_issued_partial_credentials INTEGER NOT NULL, budget TEXT NOT NULL ); diff --git a/nym-validator-rewarder/src/cli/mod.rs b/nym-validator-rewarder/src/cli/mod.rs index 0c6493f26f..7fe1dc8117 100644 --- a/nym-validator-rewarder/src/cli/mod.rs +++ b/nym-validator-rewarder/src/cli/mod.rs @@ -53,9 +53,6 @@ pub struct ConfigOverridableArgs { #[clap(long)] pub disable_block_signing_rewarding: bool, - #[clap(long)] - pub disable_block_scraper: bool, - #[clap(long)] pub disable_credential_issuance_rewarding: bool, @@ -63,7 +60,7 @@ pub struct ConfigOverridableArgs { pub credential_monitor_run_interval: Option, #[clap(long)] - pub credential_monitor_min_validation: Option, + pub credential_monitor_min_validation: Option, #[clap(long)] pub credential_monitor_sampling_rate: Option, diff --git a/nym-validator-rewarder/src/config/mod.rs b/nym-validator-rewarder/src/config/mod.rs index ed1efb97a6..9003d32ceb 100644 --- a/nym-validator-rewarder/src/config/mod.rs +++ b/nym-validator-rewarder/src/config/mod.rs @@ -31,7 +31,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_MIN_VALIDATE: usize = 10; const DEFAULT_MONITOR_SAMPLING_RATE: f64 = 0.10; /// Get default path to rewarder's config directory. @@ -100,10 +100,7 @@ impl Config { rewarding: Rewarding::default(), block_signing: Default::default(), issuance_monitor: IssuanceMonitor::default(), - nyxd_scraper: NyxdScraper { - enabled: true, - websocket_url, - }, + nyxd_scraper: NyxdScraper { websocket_url }, base: Base { upstream_nyxd: nyxd_url, mnemonic, @@ -121,10 +118,6 @@ impl Config { } pub fn ensure_is_valid(&self) -> Result<(), NymRewarderError> { - if self.block_signing.enabled && !self.nyxd_scraper.enabled { - return Err(NymRewarderError::BlockSigningRewardWithoutScraper); - } - self.rewarding.ratios.ensure_is_valid()?; Ok(()) } @@ -240,9 +233,6 @@ impl RewardingRatios { #[derive(Debug, Clone, Deserialize, Serialize)] pub struct NyxdScraper { - /// Specifies whether the chain scraper is enabled. - pub enabled: bool, - /// Url to the websocket endpoint of a validator, for example `wss://rpc.nymtech.net/websocket` pub websocket_url: Url, // TODO: debug with everything that's currently hardcoded in the scraper @@ -270,7 +260,7 @@ pub struct IssuanceMonitor { /// Defines the minimum number of credentials the monitor will validate /// regardless of the sampling rate - pub min_validate_per_issuer: u32, + pub min_validate_per_issuer: usize, /// The sampling rate of the issued credentials pub sampling_rate: f64, diff --git a/nym-validator-rewarder/src/config/override.rs b/nym-validator-rewarder/src/config/override.rs index 019c26c420..01a42ef739 100644 --- a/nym-validator-rewarder/src/config/override.rs +++ b/nym-validator-rewarder/src/config/override.rs @@ -14,10 +14,6 @@ impl ConfigOverride for ConfigOverridableArgs { config.block_signing.enabled = false } - if self.disable_block_scraper { - config.nyxd_scraper.enabled = false - } - if self.disable_credential_issuance_rewarding { config.issuance_monitor.enabled = false } diff --git a/nym-validator-rewarder/src/config/template.rs b/nym-validator-rewarder/src/config/template.rs index dbe95a5075..17ba1f9649 100644 --- a/nym-validator-rewarder/src/config/template.rs +++ b/nym-validator-rewarder/src/config/template.rs @@ -56,9 +56,6 @@ min_validate_per_issuer = {{ issuance_monitor.min_validate_per_issuer }} 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/error.rs b/nym-validator-rewarder/src/error.rs index 30372125d1..b6dae63537 100644 --- a/nym-validator-rewarder/src/error.rs +++ b/nym-validator-rewarder/src/error.rs @@ -151,9 +151,6 @@ pub enum NymRewarderError { on_chain: String, }, - #[error("can't enable block signing rewarding without the block scraper")] - BlockSigningRewardWithoutScraper, - #[error("the current rewarder balance is insufficient to start the process. The epoch budget is: {} while we currently have {}. (the minimum is set to {})", .0.epoch_budget, .0.balance, .0.minimum)] InsufficientRewarderBalance(Box), diff --git a/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs b/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs index f02cc93e82..681075bdc1 100644 --- a/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs +++ b/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs @@ -19,6 +19,7 @@ use nym_credentials::coconut::bandwidth::BandwidthVoucher; use nym_task::TaskClient; use nym_validator_client::nym_api::{IssuedCredential, IssuedCredentialBody, NymApiClientExt}; use nym_validator_client::nyxd::Hash; +use std::cmp::max; use std::collections::HashMap; use std::sync::OnceLock; use tokio::time::interval; @@ -205,11 +206,14 @@ impl CredentialIssuanceMonitor { let credential_range: Vec<_> = (first_id..first_id + total_issued).collect(); let issued = credential_range.len(); - let sampled = if issued <= self.config.min_validate_per_issuer as usize { + let sampled = if issued <= self.config.min_validate_per_issuer { credential_range } else { let mut rng = thread_rng(); - let sample_size = (issued as f64 * self.config.sampling_rate) as usize; + let sample_size = max( + self.config.min_validate_per_issuer, + (issued as f64 * self.config.sampling_rate) as usize, + ); credential_range .choose_multiple(&mut rng, sample_size) .copied() @@ -225,6 +229,7 @@ impl CredentialIssuanceMonitor { epoch_id: EpochId, issuer: CredentialIssuer, ) -> Result { + info!("checking the issuer's credentials..."); debug!("checking the issuer's credentials..."); let api_client = api_client(&issuer)?; @@ -284,6 +289,7 @@ impl CredentialIssuanceMonitor { } async fn check_issuers(&mut self) -> Result<(), NymRewarderError> { + info!("checking credential issuers"); let epoch = self.nyxd_client.dkg_epoch().await?; let issuers = self .nyxd_client diff --git a/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs b/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs index 0ec94cae88..e6f76a10ae 100644 --- a/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs +++ b/nym-validator-rewarder/src/rewarder/credential_issuance/types.rs @@ -157,23 +157,21 @@ pub(crate) struct MonitoringResultsInner { impl From for CredentialIssuanceResults { fn from(value: MonitoringResultsInner) -> Self { - // approximation! - // get the maximum number of issued credentials of all apis - // (we sum values if they cross dkg epochs) let total_issued = value .operators .values() .map(|o| { - o.per_epoch + let operator_issued: u32 = o + .per_epoch .values() .map(|e| e.issued_since_monitor_started) - .sum() + .sum(); + operator_issued }) - .max() - .unwrap_or_default(); + .sum(); CredentialIssuanceResults { - total_issued, + total_issued_partial_credentials: total_issued, dkg_epochs: value.dkg_epochs, api_runners: value .operators @@ -296,8 +294,7 @@ impl OperatorIssuing { } pub struct CredentialIssuanceResults { - // note: this is an approximation! - pub total_issued: u32, + pub total_issued_partial_credentials: u32, pub dkg_epochs: Vec, pub api_runners: Vec, } diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index 5e4f2aad42..f58b3ce63f 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -14,8 +14,6 @@ use nym_task::TaskManager; use nym_validator_client::nyxd::{AccountId, Coin, Hash}; use nyxd_scraper::NyxdScraper; use std::ops::Add; -use std::time::Duration; -use time::OffsetDateTime; use tokio::pin; use tokio::time::{interval_at, Instant}; use tracing::{error, info, instrument}; @@ -43,26 +41,28 @@ impl EpochRewards { let mut amounts = Vec::new(); if let Some(signing) = &self.signing { - let mut signing_amounts = signing.rewarding_amounts(&self.signing_budget); - amounts.append(&mut signing_amounts); + for signing_amount in signing.rewarding_amounts(&self.signing_budget) { + if signing_amount.1[0].amount != 0 { + amounts.push(signing_amount) + } + } } if let Some(credentials) = &self.credentials { - let mut credentials_amounts = credentials.rewarding_amounts(&self.credentials_budget); - amounts.append(&mut credentials_amounts); + for credential_amount in credentials.rewarding_amounts(&self.credentials_budget) { + if credential_amount.1[0].amount != 0 { + amounts.push(credential_amount) + } + } } amounts } +} - pub fn total_spent(&self) -> Coin { - let amount = self - .amounts() - .into_iter() - .map(|(_, amount)| amount[0].amount) - .sum(); - Coin::new(amount, &self.total_budget.denom) - } +pub fn total_spent(amounts: &[(AccountId, Vec)], denom: &str) -> Coin { + let amount = amounts.iter().map(|(_, amount)| amount[0].amount).sum(); + Coin::new(amount, denom) } pub struct Rewarder { @@ -77,12 +77,6 @@ pub struct Rewarder { impl Rewarder { pub async fn new(config: Config) -> Result { - let nyxd_scraper = if config.nyxd_scraper.enabled { - Some(NyxdScraper::new(config.scraper_config()).await?) - } else { - None - }; - let nyxd_client = NyxdClient::new(&config)?; let storage = RewarderStorage::init(&config.storage_paths.reward_history).await?; let current_epoch = if let Some(last_epoch) = storage.load_last_rewarding_epoch().await? { @@ -92,11 +86,10 @@ impl Rewarder { }; let epoch_signing = if config.block_signing.enabled { - // safety: our config has been validated at load time to ensure that if block signing is enabled, - // so is the scraper + let nyxd_scraper = NyxdScraper::new(config.scraper_config()).await?; + Some(EpochSigning { - #[allow(clippy::unwrap_used)] - nyxd_scraper: nyxd_scraper.unwrap(), + nyxd_scraper, nyxd_client: nyxd_client.clone(), }) } else { @@ -198,10 +191,12 @@ impl Rewarder { }) } + #[instrument(skip(self))] async fn send_rewards( &self, amounts: Vec<(AccountId, Vec)>, ) -> Result { + info!("sending rewards"); self.nyxd_client .send_rewards(self.current_epoch, amounts) .await @@ -218,10 +213,16 @@ impl Rewarder { } }; - let rewarding_result = self.send_rewards(rewards.amounts()).await; + let rewarding_amounts = rewards.amounts(); + let total_spent = total_spent( + &rewarding_amounts, + &self.config.rewarding.epoch_budget.denom, + ); + + let rewarding_result = self.send_rewards(rewarding_amounts).await; if let Err(err) = self .storage - .save_rewarding_information(rewards, rewarding_result) + .save_rewarding_information(rewards, total_spent, rewarding_result) .await { error!("failed to persist rewarding information: {err}") @@ -249,12 +250,6 @@ impl Rewarder { epoch_signing.nyxd_scraper.wait_for_startup_sync().await; } - // rewarding epochs last from :00 to :00 - // \/\/\/\/\/\/\/ TEMP TESTING!!! - self.current_epoch.end_time = OffsetDateTime::now_utc(); - self.current_epoch.start_time = self.current_epoch.end_time - Duration::from_secs(60 * 60); - // ^^^^^^^^^^^ TEMP TESTING!!! - let until_end = self.current_epoch.until_end(); info!( diff --git a/nym-validator-rewarder/src/rewarder/storage/manager.rs b/nym-validator-rewarder/src/rewarder/storage/manager.rs index 855c830fb5..5d5ab191f8 100644 --- a/nym-validator-rewarder/src/rewarder/storage/manager.rs +++ b/nym-validator-rewarder/src/rewarder/storage/manager.rs @@ -113,7 +113,7 @@ impl StorageManager { epoch: i64, starting_dkg_epoch: u32, ending_dkg_epoch: u32, - total_issued_credentials: u32, + total_issued_partial_credentials: u32, budget: String, ) -> Result<(), sqlx::Error> { sqlx::query!( @@ -122,7 +122,7 @@ impl StorageManager { rewarding_epoch_id, starting_dkg_epoch, ending_dkg_epoch, - total_issued_credentials, + total_issued_partial_credentials, budget ) VALUES (?, ?, ?, ?, ?) @@ -130,7 +130,7 @@ impl StorageManager { epoch, starting_dkg_epoch, ending_dkg_epoch, - total_issued_credentials, + total_issued_partial_credentials, budget, ) .execute(&self.connection_pool) diff --git a/nym-validator-rewarder/src/rewarder/storage/mod.rs b/nym-validator-rewarder/src/rewarder/storage/mod.rs index 35b2160d8d..aada9ef5dd 100644 --- a/nym-validator-rewarder/src/rewarder/storage/mod.rs +++ b/nym-validator-rewarder/src/rewarder/storage/mod.rs @@ -5,7 +5,7 @@ use crate::error::NymRewarderError; use crate::rewarder::epoch::Epoch; use crate::rewarder::storage::manager::StorageManager; use crate::rewarder::EpochRewards; -use nym_validator_client::nyxd::Hash; +use nym_validator_client::nyxd::{Coin, Hash}; use sqlx::ConnectOptions; use std::fmt::Debug; use std::path::Path; @@ -58,6 +58,7 @@ impl RewarderStorage { pub(crate) async fn save_rewarding_information( &self, reward: EpochRewards, + total_spent: Coin, rewarding_tx: Result, ) -> Result<(), NymRewarderError> { info!("persisting reward details"); @@ -72,7 +73,7 @@ impl RewarderStorage { .insert_rewarding_epoch( reward.epoch, reward.total_budget.to_string(), - reward.total_spent().to_string(), + total_spent.to_string(), reward_tx, reward_err, ) @@ -118,13 +119,13 @@ impl RewarderStorage { let dkg_epoch_start = reward .credentials .as_ref() - .map(|c| *c.dkg_epochs.first().unwrap()) + .and_then(|c| c.dkg_epochs.first().copied()) .unwrap_or_default(); #[allow(clippy::unwrap_used)] let dkg_epoch_end = reward .credentials .as_ref() - .map(|c| *c.dkg_epochs.last().unwrap()) + .and_then(|c| c.dkg_epochs.last().copied()) .unwrap_or_default(); self.manager @@ -135,7 +136,7 @@ impl RewarderStorage { reward .credentials .as_ref() - .map(|c| c.total_issued) + .map(|c| c.total_issued_partial_credentials) .unwrap_or_default(), reward.credentials_budget.to_string(), ) From 67701290d3fe45a40d7af96db0aac6aa404a1484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 18 Dec 2023 18:46:45 +0000 Subject: [PATCH 19/21] cargo fmt --- .../src/nyxd/cosmwasm_client/module_traits/mod.rs | 4 ++-- .../src/nyxd/cosmwasm_client/module_traits/slashing/mod.rs | 2 +- .../src/nyxd/cosmwasm_client/module_traits/slashing/query.rs | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/mod.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/mod.rs index 74df86a720..e27ad09f98 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/mod.rs @@ -1,8 +1,8 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -pub mod staking; pub mod slashing; +pub mod staking; pub use staking::query::StakingQueryClient; -// pub use slashing::query \ No newline at end of file +// pub use slashing::query diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/slashing/mod.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/slashing/mod.rs index f4a7b38548..de0f6e779a 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/slashing/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/slashing/mod.rs @@ -1,4 +1,4 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -pub mod query; \ No newline at end of file +pub mod query; diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/slashing/query.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/slashing/query.rs index 67bf4e9a2d..38dc36ebc3 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/slashing/query.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/module_traits/slashing/query.rs @@ -1,3 +1,2 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 - From 3f504d7500a1e9df278942170a4eb4aab3042293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 18 Dec 2023 19:08:39 +0000 Subject: [PATCH 20/21] fixed builds of other binaries --- explorer-api/src/main.rs | 2 +- gateway/src/node/mod.rs | 4 +++- mixnode/src/node/mod.rs | 2 +- nym-wallet/Cargo.lock | 2 +- nym-wallet/nym-wallet-types/src/network/qa.rs | 1 + nym-wallet/nym-wallet-types/src/network/sandbox.rs | 1 + nym-wallet/src-tauri/Cargo.toml | 2 +- service-providers/network-statistics/src/api/mod.rs | 2 +- 8 files changed, 10 insertions(+), 6 deletions(-) diff --git a/explorer-api/src/main.rs b/explorer-api/src/main.rs index 1c00c1548f..8cb98280af 100644 --- a/explorer-api/src/main.rs +++ b/explorer-api/src/main.rs @@ -79,7 +79,7 @@ impl ExplorerApi { self.wait_for_interrupt(shutdown).await } - async fn wait_for_interrupt(&self, shutdown: TaskManager) { + async fn wait_for_interrupt(&self, mut shutdown: TaskManager) { let _res = shutdown.catch_interrupt().await; log::info!("Stopping explorer API"); } diff --git a/gateway/src/node/mod.rs b/gateway/src/node/mod.rs index 44da516aea..497c6c6872 100644 --- a/gateway/src/node/mod.rs +++ b/gateway/src/node/mod.rs @@ -388,7 +388,9 @@ impl Gateway { )) } - async fn wait_for_interrupt(shutdown: TaskManager) -> Result<(), Box> { + async fn wait_for_interrupt( + mut shutdown: TaskManager, + ) -> Result<(), Box> { let res = shutdown.catch_interrupt().await; log::info!("Stopping nym gateway"); res diff --git a/mixnode/src/node/mod.rs b/mixnode/src/node/mod.rs index 5dca2113dc..1667b108fd 100644 --- a/mixnode/src/node/mod.rs +++ b/mixnode/src/node/mod.rs @@ -215,7 +215,7 @@ impl MixNode { }) } - async fn wait_for_interrupt(&self, shutdown: TaskManager) { + async fn wait_for_interrupt(&self, mut shutdown: TaskManager) { let _res = shutdown.catch_interrupt().await; log::info!("Stopping nym mixnode"); } diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index fdb976b948..d35a3c4c6a 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -3593,7 +3593,7 @@ dependencies = [ "bip39", "cfg-if", "colored 2.0.4", - "cosmrs 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", "dirs 4.0.0", "dotenvy", diff --git a/nym-wallet/nym-wallet-types/src/network/qa.rs b/nym-wallet/nym-wallet-types/src/network/qa.rs index f036b51c4d..85aa00bd5e 100644 --- a/nym-wallet/nym-wallet-types/src/network/qa.rs +++ b/nym-wallet/nym-wallet-types/src/network/qa.rs @@ -35,6 +35,7 @@ pub(crate) fn validators() -> Vec { vec![ValidatorDetails::new( "https://qa-validator.qa.nymte.ch/", Some("https://qa-nym-api.qa.nymte.ch/api"), + Some("wss://qa-validator.qa.nymte.ch/websocket"), )] } diff --git a/nym-wallet/nym-wallet-types/src/network/sandbox.rs b/nym-wallet/nym-wallet-types/src/network/sandbox.rs index 1186c07eac..2d1bc9e0fa 100644 --- a/nym-wallet/nym-wallet-types/src/network/sandbox.rs +++ b/nym-wallet/nym-wallet-types/src/network/sandbox.rs @@ -32,6 +32,7 @@ pub(crate) fn validators() -> Vec { vec![ValidatorDetails::new( "https://rpc.sandbox.nymtech.net", Some("https://sandbox-nym-api1.nymtech.net/api"), + Some("wss://rpc.sandbox.nymtech.net/websocket"), )] } diff --git a/nym-wallet/src-tauri/Cargo.toml b/nym-wallet/src-tauri/Cargo.toml index 1182ef2d1c..854aa1d57f 100644 --- a/nym-wallet/src-tauri/Cargo.toml +++ b/nym-wallet/src-tauri/Cargo.toml @@ -49,7 +49,7 @@ base64 = "0.13" zeroize = { version = "1.5", features = ["zeroize_derive", "serde"] } cosmwasm-std = "1.3.0" -cosmrs = "=0.15.0" +cosmrs = { git = "https://github.com/jstuczyn/cosmos-rust", branch ="nym-temp/all-validator-features" } nym-validator-client = { path = "../../common/client-libs/validator-client" } nym-crypto = { path = "../../common/crypto", features = ["asymmetric"] } diff --git a/service-providers/network-statistics/src/api/mod.rs b/service-providers/network-statistics/src/api/mod.rs index 74e47c7108..fc32cc8d7b 100644 --- a/service-providers/network-statistics/src/api/mod.rs +++ b/service-providers/network-statistics/src/api/mod.rs @@ -35,7 +35,7 @@ impl NetworkStatisticsAPI { pub async fn run(self) { let rocket_shutdown_handle = self.rocket.shutdown(); - let shutdown = TaskManager::new(10); + let mut shutdown = TaskManager::new(10); tokio::spawn(self.rocket.launch()); shutdown.catch_interrupt().await.ok(); From 9b2d224e54e64172e0745f46f840d7a922d33c2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 2 Jan 2024 12:59:11 +0000 Subject: [PATCH 21/21] clippy --- common/nymcoconut/benches/benchmarks.rs | 2 +- .../src/rewarder/credential_issuance/monitor.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/nymcoconut/benches/benchmarks.rs b/common/nymcoconut/benches/benchmarks.rs index 6bf582a244..966e676f42 100644 --- a/common/nymcoconut/benches/benchmarks.rs +++ b/common/nymcoconut/benches/benchmarks.rs @@ -255,7 +255,7 @@ fn bench_coconut(c: &mut Criterion) { b.iter(|| { verify_partial_blind_signature( ¶ms, - &blind_sign_request, + blind_sign_request.get_private_attributes_pedersen_commitments(), &public_attributes, random_blind_signature, partial_verification_key, diff --git a/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs b/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs index 681075bdc1..884a63b9fe 100644 --- a/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs +++ b/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs @@ -107,7 +107,7 @@ impl CredentialIssuanceMonitor { trace!("deposit exists"); // check if the deposit values match - let credential_value = issued_credential.credential.public_attributes.get(0); + let credential_value = issued_credential.credential.public_attributes.first(); let credential_info = issued_credential.credential.public_attributes.get(1); if credential_value != Some(&deposit_value) {